🎉 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!

Issue with object instances

Started by
4 comments, last by WitchLord 18 years, 8 months ago
Okay, I am sure like my last "problem" I am totally at fault and simply missing something, but let me lay out this problem. Please note, this is all very preliminary code. I am just trying to rig things up to work, I will clean it all up later. So, I have a class called "Entity" that will represent an entity in my game world. This could be a monster, a sword, anything that has to interact with the game world on more than a simple geometric level. Currently this class has only a single method, GetId, which returns a long. I register it with Angel like so:

void Entity::RegisterForScripting(asIScriptEngine *engine)
{
	int r = engine->RegisterObjectType("Entity", 0, asOBJ_CLASS); assert(r >= 0);
	r = engine->RegisterObjectMethod("Entity", "int GetId()", asMETHOD(Entity, GetId), asCALL_THISCALL); assert(r >= 0);
}

Simple enough, right? :) Now, I have a simple script method that does the following:

void OnLoad(Entity obj)
{
	Log("Entity ID: " + obj.GetId());
}

Again, very simple stuff. I invoke the method using the following (extremely messy/ugly) code block:

asIScriptContext *ctx;
Entity *entity = new Entity();
long eid = entity->GetId(); // returns 0;
ctx = m_ScriptEngine->CreateContext();
int id = m_ScriptEngine->GetFunctionIDByDecl(NULL, "void OnLoad(Entity obj)");
ctx->Prepare(id);
ctx->SetArgObject(0, entity);
id = ctx->Execute();

As you can see from the comment on the third line, calling GetId on that instance of Entity returns 0. This is the correct return. Now, when I invoke the script method GetId returns -33686019. It's as if AngelScript is calling GetId on an uninitialized version of the Entity instance I hand it. Am I simply missing something here? Should I be using an object handle to the entity, rather than simply passing the object like I am currently?
Matt Holmes[ aka Calefaction ]Wildfire Games - General Programmerhttp://www.wildfiregames.com
Advertisement
You've got a couple of problems in this code.

1. You register your object type with a size of 0. Although, perfectly legal, it means that AngelScript will not be able to make copies of this type, which in turn means that you cannot pass this object type around by value.

2. You didn't verify the return code from SetArgObject(). AngelScript should have returned an error code, since it isn't able to copy your entity object into the script argument. (I cannot guarantee that the method actually does return an error but if it doesn't it would be bug on my part).

You have two ways of solving it: Either register the type with its true size. Or make the script function take the entity by reference (∈), or even better as a handle (@).

If you want the entity type to support handles you need to register the ADDREF and RELEASE behaviours.

Regards,
Andreas

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

I tried re-writing the script as "void OnLoad(Entity ∈ obj)" and the compiler complained that I couldn't define a parameter of type Entity&.

I will probably just register the ADDREF/RELEASE behaviours, as using handles is a "good thing (tm)".

EDIT: I have the size as 0 because I don't want scripters to be able to create entity objects from inside the script. Entities will be managed by the game engine internally.
Matt Holmes[ aka Calefaction ]Wildfire Games - General Programmerhttp://www.wildfiregames.com
As a side note, I got this working using object handles...but I would still be curious why I was getting errors when trying to pass an Entity reference to the function (as stated above).

Also, my AddRef/Release methods are completely blank, absolute dummies. I want it to be this way, but is this "bad" for AS? Will it break anything internally? I will be managing all of the Entity referencing internally, I just don't want to pass object copies around (I want C++ reference functionality basically).
Matt Holmes[ aka Calefaction ]Wildfire Games - General Programmerhttp://www.wildfiregames.com
perhaps register a smart_ptr for the objects.
Hmm, I forgot about that. AngelScript complains about the reference, because if it is going to call the function it has to be able to make a copy of the object. Parameter references are something that I'm not satisfied with in AngelScript (like many other, I'd guess) and I'm looking for ways to improve them.

Registering AddRef and Release behaviours as dummy functions is no problem for AngelScript. You'll just have to be careful when you delete the objects to make sure that a reference isn't stored somewhere by the scripting engine. If you intend to use common C++ reference counting anyway, then you might just let the AddRef and Release behaviours do their work as well. That way AngelScript will be able to use the same reference counting as you yourself uses in your application.




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