Jump to content

  • Log In with Google      Sign In   
  • Create Account


- - - - -

Problem returning reference to internal members


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 Champion_GaryOak   Members   -  Reputation: 105

Like
0Likes
Like

Posted 30 May 2014 - 01:27 AM

I've tried searching around google for this and couldn't find anything, so I apologize if this is a repeat.

 

I'm have a problem returning a reference to an internal class in AngelScript.

 

Basically I have a class like this:

 

class Engine
{
public:
    AudioSystem& getAudioSystem()
    {
        return m_audioSystem;
    }
private:
    AudioSystem m_audioSystem;
};
 
I instance the Engine class once for the whole program. I don't need to create/destroy Engine or AudioSystem from scripts, just access some functions
I'm exposing it like this:
 
     int r= state->RegisterObjectType("Engine", 0, asOBJ_REF | asOBJ_NOCOUNT);
     r = state->RegisterObjectMethod("Engine", "AudioSystem@ getAudioSystem()", asMETHODPR(Engine, getAudioSystem, (), AudioSystem&), asCALL_THISCALL); assert(r >= 0);

and AudioSystem like this

int result = state->RegisterObjectType("AudioSystem", 0, asOBJ_REF | asOBJ_NOCOUNT);
result = state->RegisterObjectMethod("AudioSystem", "bool addSound(const string &in, const string &in, const bool overwriteExisting = true, const bool useStoredPath = true, const bool isSoundEffect = false, const string extension = \".mp3\")",
		asMETHOD(AudioSystem, addSound), asCALL_THISCALL);

	result = state->RegisterObjectMethod("AudioSystem", "void playSound(const string &in, const int channel = 0, const bool loop = true, const float vol = 1.0)",
		asMETHOD(AudioSystem, playSound), asCALL_THISCALL);

My angelscript looks like this

 
void main()
{
	AudioSystem& as = engine.getAudioSystem();//.addSound("Dive into the Heart", "Dive into the Heart");
	as.addSound("Dive into the Heart", "Dive into the Heart");
	as.playSound("Dive into the Heart");
}
When I do this, I get an error
 
ERR | 'AudioSystem' is not declared
 
I tried playing around with handles in the angelscript, figuring I needed to use a @ handle not &. I changed it to
 
AudioSystem@ as = engine.getAudioSystem();
 
When I do this I get a nondescript error "Caught an exception from the application". So clearly I'm still doing something wrong. 
 
Lastly, I tried changing me expose from asMETHODPR to asMETHOD
r = state->RegisterObjectMethod("Engine", "AudioSystem@ getAudioSystem()", asMETHOD(Engine, getAudioSystem), asCALL_THISCALL); assert(r >= 0);

Doing this seems to let me go further - I get in to the as.addSound() function call, but the AudioSystem instance it get's called on is uninitialized and not the AudioSystem instance inside Engine. 

 

What am I doing wrong? Any help would be appreciated.

 

Thanks!


Edited by Champion_GaryOak, 30 May 2014 - 01:33 AM.


Sponsor:

#2 Andreas Jonsson   Moderators   -  Reputation: 3294

Like
0Likes
Like

Posted 30 May 2014 - 08:51 AM

The & cannot be used in variable declarations in AngelScript. Instead you should use the @ symbol.

 

I think your problem lies with how you've registered the global property 'engine'. I suspect that you're probably giving the wrong address to AngelScript, but unfortunately you didn't show us how you've declared the global instance of your Engine in your application nor how you're making the call to RegisterGlobalProperty.

 

Please show how you expose the global instance of your Engine to the script so we can verify if it is correct.


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

#3 Champion_GaryOak   Members   -  Reputation: 105

Like
0Likes
Like

Posted 30 May 2014 - 04:29 PM

I'm exposing it like this:

void registerEngine(asIScriptEngine* state, Engine* engine)
{
    //class definition export code here
    registerObjectToAngelScript<Engine>(state, "engine", "Engine", *engine, true, false);
}


template <class T>
int registerObjectToAngelScript(asIScriptEngine* scriptCtx, const std::string& index, const std::string& objType, T& object, const bool byPtr = true, const bool isConst = false)
{
	std::string objDeclaration((isConst ? "const " : "") + objType + " " + (byPtr ? "@" : "") + index);
	return scriptCtx->RegisterGlobalProperty(objDeclaration.c_str(), &object);
}

my objDeclaration sctring ends up looking like this:

objDeclaration: "Engine @engine"


#4 Andreas Jonsson   Moderators   -  Reputation: 3294

Like
0Likes
Like

Posted 30 May 2014 - 06:55 PM

Indeed. With this declaration you need to pass in a pointer to a pointer to the Engine when calling RegisterGlobalProperty. But from your code you seem to pass only a pointer to the 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

#5 Champion_GaryOak   Members   -  Reputation: 105

Like
0Likes
Like

Posted 30 May 2014 - 08:19 PM

Hm yea when I pass a pointer only, it gives me a new/incorrectly initialized instance of Engine, so I changed the registration to

template <class T>
int registerObjectToAngelScript(asIScriptEngine* scriptCtx, const std::string& index, const std::string& objType, T& object, const bool byPtr = true, const bool isConst = false)
{
	std::string objDeclaration((isConst ? "const " : "") + objType + " " + (byPtr ? "@" : "") + index);
	T* objPtr = &object;
	return scriptCtx->RegisterGlobalProperty(objDeclaration.c_str(), &objPtr);
}

to make a pointer to a pointer. Now though, the engine instance is null (or the equivalent, 0xcccccccc in visual studio). Maybe I misunderstood what you meant?



#6 Andreas Jonsson   Moderators   -  Reputation: 3294

Like
0Likes
Like

Posted 31 May 2014 - 08:06 AM

The problem now is that you're giving the pointer to a local variable. The variable will go out of scope as soon as your function returns turning the pointer invalid.

If you prefer not to register a pointer to a pointer to the Engine, you can also change the declaration to remove the @, and then pass a pointer to the Engine directly.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS