Jump to content

[SOLVED] Dynamically injecting script


photo

Recommended Posts

Hi,

 

At the moment we're looking at trying to dynamically including a script file containing a class/functions for use throughout our world script. WorldExpression/Expression seem to come close but I'm not sure that it provides the functionality that we're looking for. So if we have a class CameraTester that is defined in a file CameraTester.cpp, rather than having to include it via #include statically we want some way of including it and compiling it dynamically. An example usage would be something like this

 

string s = new string("#include <common/scripts/CameraTester.cpp>");

 

.. Some sort of construct to inject the code dynamically - I tried

WorldExpression we = new WorldExpression(vec3(100.0f));

engine.editor.addNode(we);

we.setExpression(s);

 

.. Post injection can use the code as if we #included statically

 

CameraTester c = new CameraTester();

 

.. and so on;

 

Is this possible in Unigine at the moment?

Link to comment

Yes, it is possible. Take a look at data/samples/worlds/expression_01.cpp.

The point is include directive should be enclosed in braces, plus it must be a separate line delimited by new-line characters:

 

expression.setExpression("{\n#include <samples/worlds/expression_01.h>\n}");

Link to comment

OK I've tried this with enclosed braces and it doesn't work. And from what I can see in the documentation WorldExpression isn't going to work, unless I've missed something.

 

My call to expression.setExpression("{\n#include <common/scripts/CameraTester.cpp>\n}"); is intended such that it exposes the classes and functions defined within CameraTester.cpp for future use throughout the script - and future code that uses it should be somewhere in my world script without the need to create more world expression nodes to use it.

 

If I define the code fragment as follows:

 

WorldExpression we;

 

int init()

{

WorldExpression we = new WorldExpression(vec3(100.0f));

engine.editor.addNode(we);

we.setExpression("{\n#include <common/scripts/CameraTester.cpp>\n}");

we.setHidden(1);

 

// At this point I want all classes and functions defined in CameraTester.cpp available to me. Call a function that has only been defined in CameraTester.cpp

CameraTester::init();

 

If I do this - I get an error from Unigine - "unknown token CameraTester::init()". Let me know your thoughts.

Link to comment

Just my personal thought, but trying to use WorldExpression for injecting new/alternative classes for your world script environment does not sound like a workable/wise solution at all (actually I would call it a total misuse :-).

 

Maybe you should better try to include your variable class code via some #ifdef -> #include approach controlled by extern_define at programm startup as discussed in this thread. Sounds like a much cleaner solution.

Link to comment

Agreed this is a total misuse :) But my initial question in the thread was related to whether it was possible or not and I cited WorldExpression as something that comes close but doesn't quite do the job. Since we have a large number of CPP files and the #inclusion of those files depends on run time data (from an external data source) we'd like to be able to control this at run time. As it currently stands, prior to world load we'll be reading our run time data source and auto generating a common cpp that's sole purpose is to #include a bunch of scripts that we rely on during our world execution. Then we'll load our world which will load the common cpp. Not ideal.

Link to comment

WorldExpression has its own scope, while Expression has a global scope and allows for using added classes/functions throughout all scripts. If define approach is not suitable for you, give this one a go. You sure know this, but just in case: please keep in mind that there's an associated memory penalty and creating hundreds of expressions is better to be avoided.

Link to comment

Yep, the memory penalty is something that we'll keep in mind with our usage.

So I tried this out:

 

Expression e = new Expression("{\n#include <common/scripts/CameraTester.cpp>\n}");

CameraTester::init();

 

No luck. I also tried embedding this call to CameraTester::init within a call to run and no luck either. The expression definitely compiles OK because if I remove the call to CameraTester::init() no errors are reported in the log file. Thoughts?

Link to comment

After reconsulting with our developers, i'm taking back my words about Expression scoping. A bit of misunderstanding on our side, sorry.

You can access wold functions from inside Expression, but it does not work the other way round: it is not possible to include scripts in Expression and use them throughout the world script. So it turned out to be not possible in the end :(

Link to comment
  • 2 years later...
×
×
  • Create New...