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

Pass handle as parameter to another object

Started by
3 comments, last by WitchLord 16 years, 6 months ago
Hello everyone, How can I pass a handle to another object in AS using registered application classes? I spent 5 days trying to make that happen without any luck. I tried different methodology: the famous try-and-error, reading the manual and trying to understand concepts to do it, reviewing the examples, search the internet and this forum for a similar problem, and using try-and-error again. After that I give up and decided that I must ask in this forum. for a clear picture of what I am trying to archive, this is a simplified example: class definition:

class A {
	public
		A(const std::string &name, int size) {
			refCount = 1;
			anotherObject = new AnotherClass(name, size, true);
		}
		
		...
		...
		
		void addReference() {
			++refCount;
		}
		
		void releaseReference() {
			if(--refCount == 0)
				delete this;
		}
		
		AnotherClass *anotherObject;
		
	private:
		int refCount;
}

A *A_Factory(const std::string &name, int size) {
	return new A(name,size);
}

class B {
	public
		B(A *aObject, int size) {
			refCount = 1;
			yetAnotherObject = new YetAnotherClass(aObject->anotherObject, size, 10);
		}
		
		...
		...
		
		void addReference() {
			++refCount;
		}
		
		void releaseReference() {
			if(--refCount == 0)
				delete this;
		}
		
	private:
		int refCount;
		
		YetAnotherClass *yetAnotherObject;
}

B *B_Factory(A *aObject, int size) {
	return new B(aObject, size);
}


Registration of the classes

r = engine->RegisterObjectType     ("A", 0, asOBJ_REF); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("A", asBEHAVE_FACTORY, "A@ f(const string &in, int)", asFUNCTION(A_Factory), asCALL_CDECL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("A", asBEHAVE_ADDREF, "void f()", asMETHOD(A,addReference), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("A", asBEHAVE_RELEASE, "void f()", asMETHOD(A,releaseReference), asCALL_THISCALL); assert( r >= 0 );
// registeration  of other methods for Class A

r = engine->RegisterObjectType     ("B", 0, asOBJ_REF); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("B", asBEHAVE_FACTORY, "B@ f(A &in, int)", asFUNCTION(B_Factory), asCALL_CDECL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("B", asBEHAVE_ADDREF, "void f()", asMETHOD(A,addReference), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("B", asBEHAVE_RELEASE, "void f()", asMETHOD(A,releaseReference), asCALL_THISCALL); assert( r >= 0 );
// registeration  of other methods for Class B


AngleScript example - an example of the wanted usage of the classes

int main() {
	A @a = A("apple",5);
	B @b = B(a,50);
	
	b.callSomeMemberMethod();
}


Of course this example is one logical combination of the several try-and-error combinations. Could someone please help on this. Thank you. Best Regards, Edit: change BBCode to use C syntax highlighting
Advertisement
After an additional round of experiments, I was able to stop the engine from crashing by doing a simple modification the code for registration.

This is the code of registration after modification (substitute ∈ with @ in the factory function definition for class B)

r = engine->RegisterObjectType     ("B", 0, asOBJ_REF); assert( r >= 0 );r = engine->RegisterObjectBehaviour("B", asBEHAVE_FACTORY, "B@ f(A @, int)", asFUNCTION(B_Factory), asCALL_CDECL); assert( r >= 0 );r = engine->RegisterObjectBehaviour("B", asBEHAVE_ADDREF, "void f()", asMETHOD(A,addReference), asCALL_THISCALL); assert( r >= 0 );r = engine->RegisterObjectBehaviour("B", asBEHAVE_RELEASE, "void f()", asMETHOD(A,releaseReference), asCALL_THISCALL); assert( r >= 0 );// registeration  of other methods for Class B


However, the application doesn't do what it supposed to do. Maybe I am doing something wrong or missing some important things.

I am seeking your gaudiness

EDIT:

After 5 days of struggling, I got it to work :)
After the previous modification the code for AS was working. The resaon why I said "the application doesn't do what it supposed to do" is because I was implementing the internal logic of the class in a wrong way.
The solution for binding was using @ instead of &in. this is the solution

However, I know that I maybe doing it wrong even though it is working (for example not taking good care of the reference counter or something). So if there is any problem in my way, I will be grateful if you let me know about it.

Thank you and sorry if I bothered you with my post

[Edited by - ForeignKey on December 19, 2007 10:10:52 AM]
Since the factory method for B is now receiving a handle to an A object, but doesn't store it for later use, you should make sure to release the handle before returning.

You can avoid need to manually release the handle by registering the factory with either of "B@ f(A @+, int)" or "B@ f(A &, int)".

The first alternative tells AngelScript to automatically release the handle after the function returns. The second alternative tells AngelScript to pass in a reference of the object for modification (which is basically the same as a handle, except that it is guaranteed to not be null).

Note that the second alternative is not the same as "B@ f(A ∈, int)", which tells AngelScript to pass in a reference to a copy of the object. The in directive means that any changes made to the reference won't reflect on the original object, thus the copy.

---

Now, I'd like to ask for some suggestions on how I can improve AngelScript to help lessen the trial-and-error that you needed to get this right?

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

Thank you very much WitchLord. Everything is clear for me now.

Quote: Now, I'd like to ask for some suggestions on how I can improve AngelScript to help lessen the trial-and-error that you needed to get this right?


Maybe more documentation :)
Or maybe at least more examples with the SDK on different kind of situations.
Or gathering articles from experts of this great community and populate the Wiki.
I know that you are quite busy, but you should let others help you on that.

I won't say easier binding system, since I know that you are willing to make the binding system as easy as possible and I appreciate that.

But I have to admit, I was able to do the other regaler binding (currently 15+ classes has been binded for my app) by the help of the manual and without any problem.

One more thing, thanks for your tremendous efforts on making this great scripting language and thanks for every millisecond you spent developing it. I have tried different scripting languages but found that AS is the ideal choice. And thank you for being here to help everyone else.
I'll definitely try to expand the documentation, though I can't say I'm that good at antecipating what users need to know.

The wiki is open for everyone to modify, though unfortunately not many have picked up the idea of adding information to it. If you feel like writing something there, then please feel free to do so.

I'm happy you like AS, despite your difficulties in binding this class.

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