Sign in to follow this  

Squirrel Plus and Polymorphism...

This topic is 4379 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all, I am trying to replace an already existing Lua scripting system with Squirrel Plus. However, I immediatly encountered some major difficulties. The game engine is set up with an abstract interface. Plugins then provide implementations for those interfaces like in the following:
// Interface (abstract)
class ILight
{
    virtual void doSomething(void) = 0;
};

// In plugin
class OpenGLLight : public ILight
{
    virtual void doSomething(void)
    {
       ...
    }
};
The engine using Luabind binds the abstract interface, not the implementation, and passes instances of the derived classes to the script. In other words:
// Global function that returns instance of a light depending on the plugin loaded
static ILight* CreateLight(void)
{
    if (usingOpenGL)
        return new OpenGLLight;
    ...
}
That function is then binded to Squirrel. And in Squirrel I can then do:
light  = CreateLight();
light.doSomething();
I am lost on how to do this not only in Squirrel but Luabind as well. I would bypass the interfaces completely and bind the implementations but I can't do that with the current engine design. How would I go about doing this? I tried binding the interface but I recieved a "cannot instantiate abstract class" linker error which I expected. How this engine manages to do this with Luabind is a mystery to me. It apperantly uses something called "abstract binder mechanism". I Googled for it and found nothing. Thanks in advance.

Share this post


Link to post
Share on other sites
take a look at the DXSquirrel sample in SQPlus. Check the binding for ID3DXMeshBase and ID3DXMesh.

check this out for a non AddRef()/Release() approach:


_MEMBER_FUNCTION_IMPL(BaseLight,constructor)
{
StackHandler sa(v);
return sa.ThrowError(_T("BaseLight cannot be constructed directly(is pure)"));
}

_MEMBER_FUNCTION_IMPL(BaseLight,doSomething)
{
StackHandler sa(v);
_CHECK_SELF(ILight,BaseLight)
self->doSomething(sa.GetInt(2));
return 0;
}

_BEGIN_CLASS(BaseLight)
_MEMBER_FUNCTION(BaseLight,constructor,NULL,NULL)
_MEMBER_FUNCTION(BaseLight,doSomething,2,_T("xn")) //takes 2 params (this and a number)
_END_CLASS(BaseLight)

_IMPL_NATIVE_CONSTRUCTION(OglLight)

_MEMBER_FUNCTION_IMPL(OglLight,constructor)
{
OpenGLLight *newinstace = new OpenGLLight();
//squirrel will automagically call delete the class when needed
return construct_OglLight(newinstace);
}

_BEGIN_CLASS(OglLight)
_MEMBER_FUNCTION(OglLight,constructor,0,NULL)
_END_CLASS_INHERITANCE(OglLight,BaseLight)


ciao

Alberto

Share this post


Link to post
Share on other sites
Well at first glance it looked perfect. The problem I have however, is that the scripting system is a plugin as well. All of the bindings are in plugins. The binding plugins aren't specific to an implementation since they bind the interface classes only, not the implementation. And the plugins that contain the implementations can't contain any binding code for a specific scripting language. Thats my problem. Well I guess I can sway away from the current way of doing things and make a set of plugins that bind specific implementations to Squirrel, however this means I need to write a binder for every implementation.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zazu
Well at first glance it looked perfect. The problem I have however, is that the scripting system is a plugin as well. All of the bindings are in plugins. The binding plugins aren't specific to an implementation since they bind the interface classes only, not the implementation. And the plugins that contain the implementations can't contain any binding code for a specific scripting language. Thats my problem. Well I guess I can sway away from the current way of doing things and make a set of plugins that bind specific implementations to Squirrel, however this means I need to write a binder for every implementation.


Well if the only difference beween implementations is the contructor, then you should just have some function in you plugin to enumerate implementation name and a class factory. you could even have some sort of symbolic way to describe parameters, and pass an array of them to you object factory. Then you can dyncamically inherit from your base class and implement the contructor engine side(the plugin doesn't even have to be dependent on squirrel).

something like

typedef void *(*CONTRUCTOBJECT)(PARAMSARRAY *a);

struct AutomationDesc {
char *classname;
char *basename;
ContructionParamsType *params;
int nparams;
CONTRUCTOBJECT func;
}

BOOL GetAutomationDesc(AutomationDesc *desc)


just an idea
Alberto

Share this post


Link to post
Share on other sites
Quote:
Original post by fagiano

Well if the only difference beween implementations is the contructor, then you should just have some function in you plugin to enumerate implementation name and a class factory. you could even have some sort of symbolic way to describe parameters, and pass an array of them to you object factory. Then you can dyncamically inherit from your base class and implement the contructor engine side(the plugin doesn't even have to be dependent on squirrel).

something like

typedef void *(*CONTRUCTOBJECT)(PARAMSARRAY *a);

struct AutomationDesc {
char *classname;
char *basename;
ContructionParamsType *params;
int nparams;
CONTRUCTOBJECT func;
}

BOOL GetAutomationDesc(AutomationDesc *desc)


just an idea
Alberto



Actually something like this might take place already... I don't really know what those mysterious macros do. I will dig deeper into the macro mechanics today. I am a little confused with the concept of dynamic inherientance in C++, but it may become clearer when I look at the source code. Thanks again.

Share this post


Link to post
Share on other sites

This topic is 4379 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this