Jump to content
  • Advertisement
Sign in to follow this  
DarkPizzaX

Question about inheritance

This topic is 1182 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

I haven't had too much experience with AngelScript, so forgive me if I'm off about something.

 

But anyways, to explain my question/situation I basically have a class that fundementally is something like this (of course, this is just an example):

class Behaviors
{
    public:
        void Behavior1(int v)
        {
            val *= v;
        }

        int Behavior2()
        {
            return val;
        }
    
    private:
        int val;
};

Now, the class is getting really messy (and there's behavior that it contains that I'd prefer scripted anyways) so I'm trying to get the class to work off of components instead.

 

So I'm effectively trying to achieve something like this:

struct IBehavior1
{
    virtual void Behavior1(int v)=0;
};

struct IBehavior2
{
    virtual int Behavior2()=0;
};

struct Behavior1Impl : IBehavior1
{
    Behavior& behavior;
    Behavior1Impl(Behavior& b) : behavior(b) { }
    void Behavior1(int v) { behavior.val *= v; }
};

struct Behavior2Impl : IBehavior1
{
    Behavior& behavior;
    Behavior2Impl(Behavior& b) : behavior(b) { }
    int Behavior2() { return behavior.val; }
};

class Behavior
{
    friend struct Behavior1;
    friend struct Behavior2;

    public:
        Behavior() { behavior1 = static_cast<Behavior1*>(new Behavior1Impl(*this)); behavior2 = static_cast<Behavior2*>(new Behavior2Imp(*this)); }
        ~Behavior() { delete behavior1; delete behavior2; }
        void Behavior1(int v) { behavior1->Behavior1(v); }
        int Behavior2() { return behavior2->Behavior2(); }

    private:
        int val;

        IBehavior1 *behavior1;
        IBehavior2 *behavior2;
};

What I want to do is replace, what is equivalent to this example's "Behavior1Impl" and "Behavior2Impl", with a scripted class, that implements the behavior of the components but is invisible to the container that it's scripted. Sorry if the example I gave is confusing.

 

I looked at the AngelScript documents and it has not made it clear to me what's required in order achieve something like this. Or even what I want to do is possible.

 

Any information regarding this would be appreciated.

Share this post


Link to post
Share on other sites
Advertisement

If I understood you correctly, you want to implement a way to allow individual components to be implemented through script, but have this implemented abstracted in a way that it is transparent to the container that holds those components. Am I right?

 

There are many ways in which you can accomplish this, but on a high level you'd need something like this:

 

  • Register the interface that the script should be allowed to use to implement the behavior, e.g. application functions that can be called, properties of the component inspected and manipulated, etc.
  • Implement a behavior class deriving IBehavior1 or IBehavior2.
  • When the behavior class is instantiated it should make preparations that will be needed to respond to calls later on, for example, compile the script (if it is the first time), cache the script function pointers, instantiate the script class, etc.
  • When the behavior class is invoked by the container, the behavior class should forward the call to the corresponding script function (either a global function or member of a script class), and then return the result to the caller.

 

Take a look at the game sample in the SDK. While it doesn't work exactly as you want, it comes quite close. You might think of the CGameObj that is in the code as the behavior class that uses scripts to implement the actual logic of the behavior.

Share this post


Link to post
Share on other sites

Having been trying to get it to work (thanks for the info, btw) it raised two more questions:

 

1. According to the docs, to create a class instance I should be able to simply call asIScriptFunction *factory = type->GetFactoryByDecl("MyClass @MyClass()"); (with MyClass being replaced with whatever script class I have) prepare and execute the function, then I can retrieve it as an asIScriptObject*. Unfortunately, it fails to find the factory function (returns NULL). My script class doesn't have any special constructors. I'm not quite sure what I'm doing wrong.

 

2. How do you register a C++ constructor for a value/pod type? I need a type from another library to be able to used but I'd like to use the various constructors the type has in the script.

Edited by DarkPizzaX

Share this post


Link to post
Share on other sites

I'm sure andreas will give a better answer but:

 

1. You have to create the class instance using asIScriptEngine::CreateScriptObject, you pass it a copy of asIScriptObject that you can obtain by using GetObjectType functions. Then you can prepare a method inside of the class for execution, then use SetObject in asIScriptContext before executing:

asIObjectType *objType  = module->GetObjectTypeByName("MyClass");
asIScriptFunction *func = objType->GetMethodByDecl("void foo()");

void *obj = context->CreateScriptObject(objType);
context->Prepare(func);
context->SetObject(obj);
context->Execute();

context would be a instance of asIScriptContext.

 

2. This is explained and has examples in the documentation, see http://angelcode.com/angelscript/sdk/docs/manual/doc_register_val_type.html#doc_reg_val_1

Edited by dkrusu

Share this post


Link to post
Share on other sites

GetFactoryByDecl("MyClass @MyClass()"); should work even if you don't declare any constructors in your script class. The default constructor is generated automatically if is not implemented explicitly. Did you perhaps type the name of the script class incorrectly?

 

Since you do not have any specific constructor anyway, you can also follow dkrusu's tip and use the asIScriptEngine::CreateScriptObject(objType) to create the script class. 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!