🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Passing Script Objects Back To Scripts

Started by
3 comments, last by WitchLord 10 years, 5 months ago
I've been following the examples shown in the sample game to get my code working and so far it has all been going good. However I'm trying to work out how to pass script objects back to scripts from c++. I've read a number of forum posts, but haven't been able to solve my problem.

I registered an interface, which I then inherit from in script like this.


class testComponent : IComponent
{
   testComponent(Component @component)
   {
      @self = component;
      value = 0.0f;
   }

   Component @self;
   float value;
};

I then create instances of this component in c++ and store a pointer to the asIScriptObject from the testComponent script.

Then I have another script file where I want to use the instances of these components, which I'm doing like this.


#include "testComponent.as"

class testSystem : ISystem
{
   testSystem( System @system )
   {
      @self = system;
   }

   void update(Entity @entity)
   {
      asIScriptObject @component = entity.component("testComponent");

      testComponent @tc = component;

      // This is what I want to be able to do...
      tc.value = 1.0f;
   }

   System @self;
};

I've registered the "component" method, which returns the component's asIScriptObject, like this.


engine->RegisterObjectMethod("Entity", "asIScriptObject @component(const string &in)", asMETHOD(Entity, component), asCALL_THISCALL);

All of it works great except for the "testComponent @tc = component;" line in the testSystem script, which gives the following error.


Can't implicitly convert from 'asIScriptObject@&' to 'testComponent@&'.

I've also tried using cast as well, but still the same error. How do I cast the asIScriptObject back to the original script object that created it so I can use that object in script?
Advertisement
Your component method needs to be registered with the following signature:

"IComponent @component(const string &in)"

And your script should call it like this:

"testComponent @tc = cast<testComponent>(entity.component('test'));"

asIScriptObject is just the C++ interface used to interact with the script objects. The script language doesn't know about this or the other C++ interfaces.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

OK, that makes sense, however I cannot seem to cast an asIScriptObject to an IComponent object in c++, therefore the "components" function always returns NULL. Here is what my "components" function looks like.


IComponent *Entity::component(const string &type)
{
   asIScriptObject *script = components.getScript(type);
   IComponent *c = dynamic_cast<IComponent*>(script);
   return c;
}

I've stepped through the code to ensure "script" is valid, and that it is of "testComponent" objType, which is an IComponent. How do I return an IComponent object from an asIScriptObject object, or am I supposed to get the IComponent object from somewhere else?
Ignore my previous post. According to the documentation, I think my "component" function is actually supposed to return an asIScriptObject pointer and increase its refCount like this.


asIScriptObject *Entity::component(const string& type)
{
   asIScriptObject *script = components.getScript(type);
   script->AddRef();
   return script;
}

I have this registered like this.


engine->RegisterObjectMethod("Entity", "IComponent @component(const string &in)", asMETHOD(Entity, component), asCALL_THISCALL);

I then do this in my script.


#include "testComponent.as"

class testSystem : ISystem
{
   testSystem(System @system)
   {
      @self = system;
   }

   void update(Entity @entity)
   {
      testComponent @tc = cast<testComponent>(entity.component("testComponent"));

      // Why is tc null??
      tc.value = 1.0f;
   }

   System @self;
};

However, I get a runtime script exception that says, "Null pointer access" when I try to us tc. I have checked to ensure that the "component" method is returning a valid asIScriptObject pointer that is an IComponent of type "testComponent".

Why would tc be Null?
Are you using multiple modules? Classes from different modules are not considered equal even if they have been built from the same source code, unless they have been declared as shared.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement