Jump to content

engine.runWorld and Unigine::Variable usage


photo

Recommended Posts

Hello,

 

Here is what I am trying to do:

// Unigine Script
namespace Character{
Custom::CustomCharacter character;

Controls getControls(){
	return character.getControls();
}
}

There exists a character object, which is defined in the provided High level Character scripts.

I implement a simple getControls method that I wish to call from C++ to acquire the Controls object for usage in C++.

 

I attempt to do so using the following code:

//C++
Unigine::Variable controlsVariable = engine->runWorld("Character::getControls");
// Not sure how to use this, but based on docs I made the following guess:
if(controlsVariable.getType() == Unigine::Variable::EXTERN_CLASS){
  std::type_info const& externClassType = controlsVariable.getExternClassType();
   BOOST_LOG_TRIVIAL(debug) << externClassType.name();
   // the above getExternClassType() crashes
   void* controlsPtr = controlsVariable.getExternClassObject(typeid(Unigine::Controls));
   // is this how I get the object? Also crashes.
}

 

Thanks for your help! :)

Link to comment

You should add pushWorld()/popWorld() functions around piece of code which works on extern classes:

 

if(controlsVariable.getType() == Unigine::Variable::EXTERN_CLASS){

  engine->pushWorld();

  std::type_info const& externClassType = controlsVariable.getExternClassType();
   BOOST_LOG_TRIVIAL(debug) << externClassType.name();
   // the above getExternClassType() crashes
   void* controlsPtr = controlsVariable.getExternClassObject(typeid(Unigine::Controls));
   // is this how I get the object? Also crashes.

  engine->popWorld();
}

 

This functions setup world script runtime.

 

You can skip it in case of calling c++ functions from the script.

Link to comment

Great! Thanks, that did the trick!

 

Some questions to clarify my understanding of this:

 

1) What is the purpose of push/pop world? I notice there is a push/pop system/editor, as well?

 

2) I did not quite understand what you meant by "this function setup world script runtime"

Could you elaborate on this in more detail?

 

3) Is it safe for me to place a push/pop for world, system, and editor, at the start and end of my main loop?

I see that I should check isWorldLoaded() and isEditorLoaded() before using those, for system, that is unnecessary because... system is always loaded if engine is running?

 

Thanks!

Link to comment

When script is working they sets own runtime. And all script functions regarding to extern classes can be called without any problems.

 

For example: we have some world script function which calls C++ function and we can use getExternClassObject() function on C++ side.

 

You initiate call of script function on C++ side. And there is no script runtime in this case and getExternClassObject() is not safe.

 

pushWorld()/popWorld() functions setup script runtime in same way as world script when it calls C++ function.

 

You are right system script is always loaded when engine is running because of this there is no isSystemLoaded() function.

 

It's more safe to check world script by isWorldLoaded() function before using runWorld() and push/popWorld() functions.

Link to comment

void setUserClass(int type, int number, int instance) 
int getUserClassType() 
int getUserClassNumber() 
int getUserClassInstance() 

 

How are these function used?

I can't find any example usage, and am not very clear on what constitutes a User Class versus an Extern Class.

I have used Extern Class for Unigine API defined classes. Is a User Class a unigine script class defined by user? Or, a C++ class defined by user?

Link to comment

void setUserClass(int type, int number, int instance) 
int getUserClassType() 
int getUserClassNumber() 
int getUserClassInstance() 

 

How are these function used?

I can't find any example usage, and am not very clear on what constitutes a User Class versus an Extern Class.

I have used Extern Class for Unigine API defined classes. Is a User Class a unigine script class defined by user? Or, a C++ class defined by user?

 

User class is a class defined by user on script side.

Extern class is class defined on C++ side through API or by engine.

 

This functions are used in internal class management by script system.

Link to comment
  • 2 weeks later...

So, I am having some more troubles with the C++ /Unigine interfacing.

 

// Unigine Script
Custom::CustomCharacter nameToCharacterMap []; // a mapping : name -> character

void CreateCharacter(string name, string characterFile){
nameToCharacterMap[name] = new Custom::CustomCharacter(characterFile);
}
Controls GetCharacterControls(string name){
Custom::CustomCharacter character = nameToCharacterMap.find(name);
return character.getControls();
}

// C++

 

engine->runWorld("Character::CreateCharacter", Variable("Uninitialized"), Variable("demos/genesis/agent.character"));

Variable controlsVariable = Engine::get()->runWorld("Character::GetCharacterControls", Variable("Uninitialized"));  // <- Crash Here

 

Giving me an error of:

Variable::operator==(): bad operands user class and string
Stack dump:
0x0000 string: "Uninitialized"
Call stack:
00: 0x000072ae Character::GetCharacterControls()
Disassemble:
calluaf nameToCharacterMap.find
popv    character
pushv   character
callucf Character.getControls

 

As far as I can gather, this just says that when I try to find the character value using the key, the comparison is somehow between a user class and string. The interface for runWorld only takes Variable objects. Yet, I would like to use unigine script string as the key to the map.

 

Overall, I'm just confused on how to work with passing variables into UnigineScript.

 

 

 

Thanks for your help!

Link to comment

Not sure, but maybe you should use pushWorld()/popWorld() to setup propper script environment when assigning variables

 

engine->pushWorld();

  engine->runWorld("Character::CreateCharacter", Variable("Uninitialized"), Variable("demos/genesis/agent.character"));

  Variable controlsVariable = Engine::get()->runWorld("Character::GetCharacterControls", Variable("Uninitialized"));  // <- Crash Here

engine->popWorld();

Link to comment

Not sure, but maybe you should use pushWorld()/popWorld() to setup propper script environment when assigning variables

 

 

Hi Ulf,

 

Thank you for the suggestion, however I already have push/pop in place ;) Though, they are in place for extern class usage elsewhere in the block of code. I only included the relevant code here. From the responses earlier in this thread, I do not think push/pop is needed for this particular line since I am not working with any extern classes. And, I don't see any push/pop in the callbacks usage example in the docs.

Link to comment

I am not clear on exactly what the problem was before. However, by changing to using a vector and consequently integer indices as the key to retrieve a character, I have bypassed whatever problem it was.

 

Are there any restrictions against using strings as keys to a map?

Link to comment
×
×
  • Create New...