🎉 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 a block of memory (AngelScript newb)

Started by
2 comments, last by Raptisoft 6 years, 1 month ago

Hi everyone, I'm trying to do something pretty simple.  I'm using the generic interface for max portability.

In the script:


class TestClass
{
    int        mInt;
    float    mFloat;
};

void Main()
{
    TestClass@ aTC=GetTestClassInstance();
}


On the C++ side:


class TestClass
{
public:
    int        mInt;
    float    mFloat;
};

void GetTestClassInstance(ScriptParams aParams)
{
    TestClass* aTest=new TestClass;
    aTest->mInt=11;
    aTest->mFloat=3.33f;
    aParams->Return(aTest);
}

gEngine->RegisterGlobalFunction("TestClass@ GetTestClassInstance()", asFUNCTION(GetTestClassInstance), asCALL_GENERIC);

So, what I'm expecting is I allocate that block of memory, AngelScript receives it, and then maps its own definition of TestClass to it.

However, I just get invalid declaration when I try to register that global function-- I assume because it doesn't know what TestClass@ is without my having loaded the script.

What would be the correct way to do this?
 

 

Advertisement

It sounds like you want to register TestClass in the application interface. In which case, take a look at the documentation here: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_register_type.html

Basically, you would do something like this in C++: (untested)


class TestClass
{
private:
	int mRefCount = 0;

public:
	int mInt;
	float mFloat;

public:
	void AddRef() { mRefCount++; }
	void Release()
	{
		if (--mRefCount == 0) {
			delete this;
		}
	}
};

static TestClass* GetTestClassInstance()
{
	TestClass* ret = new TestClass;
	ret->mInt = 11;
	ret->mFloat = 3.33f;
	return ret;
}

void RegisterTestClass()
{
	int r;

	// Register TestClass
	r = gEngine->RegisterObjectType("TestClass", sizeof(TestClass), asOBJ_REF); assert(r >= 0);
	r = gEngine->RegisterObjectBehaviour("TestClass", asBEHAVE_ADDREF, "void f()", asMETHOD(TestClass, AddRef), asCALL_THISCALL); assert(r >= 0);
	r = gEngine->RegisterObjectBehaviour("TestClass", asBEHAVE_RELEASE, "void f()", asMETHOD(TestClass, Release), asCALL_THISCALL); assert(r >= 0);

	r = gEngine->RegisterObjectProperty("TestClass", "int mInt", asOFFSET(TestClass, mInt)); assert(r >= 0);
	r = gEngine->RegisterObjectProperty("TestClass", "float mInt", asOFFSET(TestClass, mFloat)); assert(r >= 0);

	// Register function to get test class instance
	r = gEngine->RegisterGlobalFunction("TestClass@ GetTestClassInstance()", asFUNCTION(GetTestClassInstance), asCALL_CDECL); assert(r >= 0);
}

And then just call GetTestClassInstance() in your script, you don't have to write the entire class structure in your script, it will already be registered by the application.

Note that I've added the AddRef/Release methods, which are called by the ADDREF and RELEASE behaviors, since I'm guessing you want to do it with handles.

I've also used asCALL_CDECL above for the global function (we've never really had any compatibility issues, so we just never really bother with generic calling convention). Also, what's ScriptParams in your example? I assume it's something that implements asIScriptGeneric?

As for your question on the "block of memory", yes, if you're using handles, then you basically just give Angelscript and pointer and it'll pass that along just like in C++. It will then know which offsets to use for properties from RegisterObjectProperty. It's not "mapping" on top of a type defined in scripts.

Make sure you read the documentation though, it explains it much better than I ever could explain it.

Ah, thank you... shows you where I was coming from, I was expecting MUCH less sophisticated behavior-- just applying a structure pointer to a block of memory.

This topic is closed to new replies.

Advertisement