[libavg-devel] Dynamic Node Creation Enhancements

Ulrich von Zadow uzadow at libavg.de
Mon Feb 11 21:54:29 CET 2008


Nick Hebner wrote:
> On Feb 11, 2008 2:55 AM, Ulrich von Zadow <uzadow at libavg.de> wrote:
> 
>> Nick Hebner wrote:
>>
>>>> 2. Store the offset of the member variable directly, like so:
>>>>
>>>>   NodeDefinition(...)
>>>>   .addArg("enablecrop", "true", (void*)&m_bEnableCrop-(void*)this)
>>>>
>>>> This isn't really nice either (though we could probably hide the void *
>>>> casting ugliness in a base class), and we need a this pointer in a
>>>> static function, so we'd probably need a temporary bogus object as
>> well.
>>>> Still, maybe there are more people who will read and understand that
>>>> kind of code than there are people willing to understand template
>>>> trickery.
>>> Hmm, I don't really like the idea of having to use a bogus object
>> instance
>>> for some reason... We may be able to clean it up though as you say.
>> I don't think we can avoid the bogus object instance (and I don't like
>> it either), but we can hide it in the base class.
> 
> Maybe, I am just not seeing it, but how would we hide it in a base class?
> Wouldn't we need an instance of the derived object to have access to its
> members?

Ok, you're right. I had some vague thoughts in the back of my head that 
involved member functions templated on the Node type but all of those 
ideas basically result in NodeDefinition<T>, which leads to option 1) 
again - and I think we've dismissed that ;-).

>>> We would also have to store the type of the argument so that it can be
>>> set correctly.
>> True.
>>
>> I think the interface could look like this:
>>
>>   NodeDefinition::addArg(const string& sName, int* pMember,
>>                void* pThis, const int& Default);
>>
>> We'd overload addArg() for string, int, double and bool. Default would
>> be type-safe too.
> 
> I was thinking of just using macros to get the offset:
> 
> #define MEMBER_OFFSET(instance, member) ((void*)instance -
> (void*)(&instance->member))
> 
> And simply passing this offset to addArg():
> 
> NodeDefinition::addArg(const string& sName, const int& Default, int
> MemberOffset = -1);
> 
> Either way works for me.

Compare the two calls:

   addArg("x", 0, MEMBER_OFFSET(this, m_RelViewport.tl.x));

and

   addArg("x", &m_RelViewport.tl.x, this, 0);

Actually, I think putting the default in front so the later args can be 
optional is best:

   addArg("x", 0, &m_RelViewport.tl.x, this);

>>> So in the end, I agree that this would be a pretty cool feature, but I
>> am
>>> not sure that it can be implemented without sacrificing some code
>>> readability/design. Please prove me wrong if you see ways around these
>>> issues, however.
>> True, the actual implementation in NodeDefinition (or whereever it goes
>> in the end) would contain some code that needs explanation. However, I
>> think we can hide the messiness under the hood and provide a clean
>> interface for all the node classes, reducing boilerplate code there.
> 
> 
> Ok, well I am willing to give it a go. I will try to have another patch
> ready later today.

Wow.

>> (There is also the possibility of a largely generic Node::save() method
>> that writes out an avg file :-)).
> 
> Hmm... this is true. That would be pretty nice.
> 
>>>>> The dynamic nature of the DTD is very
>>>> flexible,
>>>>> and has been designed with the idea of node plugins in mind, however,
>> it
>>>> is
>>>>> now less visible then before. It would be nice to make the full DTD
>>>>> available to the designer (should we add a Player::getDTD() that
>> returns
>>>> the
>>>>> current DTD string in python?).
>>>> I think the most important thing here is to have an executable that
>> runs
>>>> as part of the make process and generates the dtd. (Granted, we don't
>>>> have that now either.)
>>> The problem that I see with this is when we have node plugins that
>> register
>>> with the player at runtime, the dtd will be different from the one
>> generated
>>> at compile time. I think that we need to keep dtd generation a runtime
>>> process.
>> Ok, I see your point. Still, having a default dtd lying around would be
>> great for things like xslt transforms.
> 
> I dont even know what that means, but it sure sounds cool.  :)

xslt (extensible stylesheet language transformations) is a way to 
translate one xml document into another. Things like the svg <-> avg 
conversion that Frederik is working on, for instance :-). When working 
on these transformations, it helps a lot to have a dtd that verifies the 
document you've just generated.

>> At runtime, we obviously need to
>> use a different one.
>>
>>>> Just something to keep in mind for the future: I'd like to keep the
>>>> amount of python-specific code in src/player/ to a minimum to allow for
>>>> people who want to use libavg without python.
>>> Should we start wrapping python stuff with configuration #ifdefs?
>> In theory, there should be no dependency from src/player to python at
>> all. The python-specific stuff should go to src/python...
> 
> Ah, I see. So, should we do anything about this now?

No - unless you really want to ;-).

Cheers,

   Uli

-- 

Ulrich von Zadow | +49-172-7872715
Jabber: cocacoder at jabber.berlin.ccc.de
Skype: uzadow



More information about the libavg-devel mailing list