A few questions about fundamentals
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
The next one.
I coudn't figure out the proper way to create an object inside script to return it out.
I'd like to see correct script-side example for something like this:
PhysicalParamsHolder& test4()
{
int id = GetTypeIdByDecl("PhysicalParamsHolder");
PhysicalParamsHolder& pph = CreateScriptObject(id);
pph.setVisual(100);
return pph;
}
(PhysicalParamsHolder is refcounted with factory_func as in manual)
PhysicalParamsHolder@ test4() // Return a handle to PPH
{
PhysicalParamsHolder pph;
pph.setVisual(100);
return pph;
}
You may think of object handles as smart pointers. This article explains how they work on the application side, and this article explains how they work on the script side.
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
PhysicalParamsHolder@ test4() // Return a handle to PPH
{
PhysicalParamsHolder pph;
pph.setVisual(100);
return pph;
}
You may think of object handles as smart pointers. This article explains how they work on the application side, and this article explains how they work on the script side.
Regards,
Andreas
[font="arial, verdana, tahoma, sans-serif"]Ok. Works fine.
Uhmmm, some more qs about handles. I want to make clear all the cases when I should explicitly call addRef/release. Just made a test
asWrapper.execute(*ch->context);
PhysicalParamsHolder* ph = *(PhysicalParamsHolder**) (ch->context->GetAddressOfReturnValue());
ph->addRef();
fid = asWrapper.getFucnId("test5", "modA");
asWrapper.setupScriptContext(*ch->context, fid);
ch->context->SetArgAddress(0, ph);
asWrapper.execute(*ch->context);
Without ph->addRef(); it crashes.
I suppose because of on the next call to setupScriptContext an implicit release() is called for PhysicalParamsHolder;
So, I personally have to intervene in reference handling if I want to keep holders alive out of their scope. Other cases?
Is there a case where I have to do it from scripts?
The articles I linked to in the previous post should explain most of the situations where you will need to manually call addref and release from the application side.
From the script side, there is no way to call the addref and release behaviours manually. It is all taken care of by the script engine.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
The next ones.
1 - What do you think about shared_ptr+proxy / intrusive_ptr strategies? Currently in my project I use shared_ptr+proxy.
But after being writing another ProxyEntity to pass it to AS I became kinda annoyed. Maybe there's a sense to switch to intrusive,
while it's not too late, but I am hesitant, because it demands a lot of reworking and I'm afraid I will have to do addRef/release through
mutexes for it properly to work and MT-environment.
2 - I am not sure I have a right to complain, but is it possible to extend error handling a little further?
To be more concrete - I often get "Failed to prepare the context" and it literally may be anything. The last one happend cause I did a mistake registering enums(registered the same value twice). I spent a lot of time on commenting/uncommenting code to catch that mistake,
when I'd like to get messagelike "Enum X duplicate value attempt". I'd find it more valuable than even new features. So...?
3 - Another issue I'd like to ask. I just tried to create ObjectHolder on stack and pass it to AS, ObjHolder oh; setArg(as &oh); The script itself worked well, but in the end of execution it crashed severly. So I switched to heap-allocated holder and everything's fine. Can you explain what's going on there?
If you use shared_ptr you will be forced to implement wrappers for all methods you want to expose to the script. This is not necessarily a bad thing, I do this in my own game engine. In the wrappers I also add logic to shield the script from objects that have been destroyed from the game engine itself. This makes it a lot easier for me to manage the memory in the game engine, as I don't have to worry about release all references to the object before I destroy it.
On the error handling side, it looks like you're not checking the return codes while registering the actual interface. RegisterEnumValue for example returns an error if you attempt to register the same name twice. Always check the return codes. At the very least add an assert so you can validate the registration in debug mode.
Please elaborate on the ObjectHolder problem. How did you implement this class? And how was it used when the application crashed? You may have encountered a bug in the script library, but I need more detail to determine what's going on.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
shared_ptr+proxy works great in C++ as the shared_ptr object can overload the -> operator to give the actual pointer to the class allowing you to call the class methods directly without awkward syntax.
Wow, may be a code example?
On the error handling side, it looks like you're not checking the return codes while registering the actual interface. RegisterEnumValue for example returns an error if you attempt to register the same name twice. Always check the return codes. At the very least add an assert so you can validate the registration in debug mode.
Damn, I feel ashamed. I forgot to to assign value for assertion checker... Where can I read about return codes in detail?
Please elaborate on the ObjectHolder problem. How did you implement this class? And how was it used when the application crashed? You may have encountered a bug in the script library, but I need more detail to determine what's going on.
ObjectHolders are mostly non-instansiable references. AddRef/Release only
The calling code looks like this
method(boost::shared_ptr<Event> e, boost::shared_ptr<IEntity> reciever)
{
EventHolder eventH(e);
EntityHolder entH(reciever);
asIScriptContext* ctx = reciever->getScriptContext()->context;
asWrapper::Instance()->setupScriptContext(*ctx, mFuncId);
ctx->SetArgAddress(0, &eventH);
ctx->SetArgAddress(1, &entH);
asWrapper::Instance()->execute(*ctx);
}
It crashes after script execution goes to the end, unless you change it to a form of EventHolder* eventH = new EventHolder(e);
I did Print( event.getRefCount() ) at the end of script and it's == 1
e->property;
receiver->Method();
I'm sure you already knew that.
The manual is a good place to look for details about return values.

What is the signature of the script function called with this code? The SetArgAddress() method doesn't increase the ref count so if the script function takes a handle the reference will be decreased at the end of the function thus deleting the object. If the script function takes a reference, then the reference will not be decreased and all is fine. The SetArgObject() is probably a better choice for you, as it has the intelligence to increase the ref count for object handles, or copy the object if the function takes the object by value.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
The boost::shared_ptr implements the operator-> overload, so in your case you can access the members of the Event of IEntity objects directly with:
e->property;
receiver->Method();
I'm sure you already knew that.
[size=2]
[size="1"]I mean... Ahh, I guess I'm drunk. it's Ok, I'll try that.
[size=2]
What is the signature of the script function called with this code? The SetArgAddress() method doesn't increase the ref count so if the script function takes a handle the reference will be decreased at the end of the function thus deleting the object. If the script function takes a reference, then the reference will not be decreased and all is fine. The SetArgObject() is probably a better choice for you, as it has the intelligence to increase the ref count for object handles, or copy the object if the function takes the object by value.
void func(EventHolder@ eh, IEntityHolder@ receiver) so the trouble is with the method... Yes I confirm. It works via [size=2]SetArgObject. Thank you.