Click to See Complete Forum and Search --> : Native Event Handling and Properties...


JamesSchumacher
August 6th, 2007, 12:45 PM
I have already come up with a solution in portable C++ to handle dynamic event handling, and yesterday I came up with a solution for native properties as well. Consider the following.

First of all, an abstract base class for delegates called IDelegate.


class IDelegate
{
public:
virtual void Invoke(void * lpArgs) = 0;
};


Since we define an IDelegate interface, in Invoke whatever args in a structure pointer that are passed can be passed to a callback as the pointer, or spread the args out onto the stack. It all depends on the implementation of invoke. With keeping one argument type in mind, just pass the pointer, we can define a templates to handle member functions of any type, and static member (or global functions) as well.


template <typename Type,typename ArgType> class TDelegate : public IDelegate
{
public:
TDelegate(Type * pObject,void (Type::*MemberCallback)(ArgType *));
TDelegate(void (__stdcall * _GlobalCallback)(ArgType *));
virtual ~TDelegate();
virtual void Invoke(void * lpArgs)
{
if (Callback != 0)
{
if (CallbackObject != 0)
{
(*CallbackObject->Callback)(reinterpret_cast<ArgType *>(lpArgs));
}
else
{
(*GlobalCallback)(reinterpret_cast<ArgType *>(lpArgs));
}
}
}
protected:
Type * CallbackObject;
union
{
void (Type::*Callback)(ArgType *);
void (__stdcall * GlobalCallback)(ArgType *);
};
};


A property is a way to update variables while running a bit of code as well. We could define a template in order to wrap a variable type, and have an assignment operator definition for the template parameter, and a cast operator to cast the template object to the desired type, but in order to create 'code' that would run during this, you would need a template specialization. I found a workaround. We can use a delegate. This way, the variable could be stored in the class, and the template just stores an IDelegate pointer. The defining class could even dynamically adjust what the property updates.


template <typename Type> class TProperty
{
public:
TProperty(IDelegate * pGetter,IDelegate * pSetter);
virtual ~TProperty();
const Type & operator = (const Type &);
operator const Type &() const throw();
operator Type & () throw();
protected:
IDelegate * GetterDelegate;
IDelegate * SetterDelegate;
};


Imagine that. ;) The reference returns are solved by passing the delegate a structure variable that will retrieve pointers to the objects in which can be dereferenced by the cast operators.