Jump to content

Export classes under namespaces


photo

Recommended Posts

Hi,

 

1. Is it possible to export custom class under custom namespaces, or is it allowed only for variables & functions? I was getting error while doing this:

 

C++ -

-----

 

class TestClass {

 

};

 

Interpreter::addExternLibrary( "Foo" );

 

ExternClass<TestClass> testClass = MakeExternClass<TestClass>();

Interpreter::addExternClass( "Foo.TestClass", testClass );

 

 

Unigine Script -

------------------

 

Foo.TestClass obj = new Foo.TestClass(); // Throwing this error - unknown symbol '.' found, expecting symbol '('

 

Also, 'using Foo' at file start was throwing error saying 'namespace Foo was not found'.

 

2. How do I export an enum constant? Or is it better to write a similar one in Unigine Script?

 

Thanks!

Link to comment

Hi,

1. You are right, only custom variables and functions can be registered with a library prefix. For example:

namespace Foo {
   void foo(){
      Log::message("Foo::foo() has been called\n");
};

Interpreter::addExternLibrary("Foo");
Interpreter::addExternFunction("Foo.foo",MakeExternFunction(&Foo::foo));

2. You can export each constant of enum as an extern variable. For example:

 

C++ side:

enum color {
    RED = 0,
    GREEN,
    BLUE
};
	
Interpreter::addExternVariable("enum_color_red",MakeExternConstant<int>(color::RED));
Interpreter::addExternVariable("enum_color_green",MakeExternConstant<int>(color::GREEN));
Interpreter::addExternVariable("enum_color_blue",MakeExternConstant<int>(color::BLUE));

UnigineScript side:

if (current_color == enum_color_red) {
    log.message("Red color\n");
}

So, if you need to store these constants in a single enum, you'd better write it in UnigineScript.

Link to comment

Thanks for the quick and precise reply. I was writing a plugin for KDIS network message protocol when came across these.

 

1. Is clear. Kindly edit the document to reflect this. Currently it is -

Namespace Export Example

  1. In order to use a library namespace, a library should be registered first via Unigine::Interpreter::addExternLibrary().
  2. After that, you can use a library namespace to register your variables, functions, classes, etc.

 

 

2. Initially I'd decided to use the method you suggested, but since the list of enums is huge I'm now just passing int from script side and reading them as enum constants at engine side.

 

On the same line, there are constructor functions that accept way more than 9 arguments. How do I make extern functions out of these?

Link to comment

Hey Santosh!

 

You can't export constructors that take more than 9 arguments. Also, passing a lot of data as arugments to a single function is bad practice which may lead to a wrong software design, so I suggest you to group these parameters into a struct which you can export to the script (also bad practice, just look at Win API ;) ) or just add a bunch of set/get functions.

Link to comment

You're right Andrey, unfortunately the plugin software is written that way! Yes I will get around to writing a bunch of get/set functions to set those initial values.

 

What if I need to return multiple values? Many of the plugin functions accept references as parameters. But this is not compatible with UnigineScript?

 

C++

-----

 

// Accepts a, b and c. Calculates d, e and f.

void geodeticToGeocentric( double a, double b, double c, double& d, double& e, double& f ) {

   // Code

}

 

UnigineScript

-----------------

 

double a = 5.0, b = 10.0, c = 15.0;

double d = 0.0, e = 0.0, f = 0.0;

geodeticToGeocentric( a, b, c, d, e, f );          // Throwing error 'can't convert param 4 from double to double*

log.message( "d =" + d + " e = " + e + " f = " + f + "\n" );

 

I can write a wrapper function that accepts the double values and passes them to actual function as references,  but its not of use since I won't receive back the updated parameter values.

Link to comment

Hi Santosh!

 

Your C++ function could accept array as Unigine::Variable and fill it with the data as we did in 1.0 sdk in engine.world.getIntersection (no old docs, sorry) functions. But in your case (coordinate conversion) you can just return vec3 or dvec3.

Link to comment
Thanks for the document link Den. I'm aware of the return var used in engine.world.getIntersection(), but not how its handled on c++ side. Could you guide me with a sample code on how a variable array can be passed from Script and filled in c++ using Unigine::Variable?

 

There are a bunch of issues coming up with related to exporting of overloaded functions. I fear document is only partially helpful.

 

1. Exporting overloaded global functions (same name, same arg count, varying in return type, arg type) - Compiles to dll fine, but throws error at application run : 'function xxxxxxxxxxxxxxxx with 3 arguments already defined'.

 

2. Exporting overloaded class member functions (same name, varying in return type, arg type) - No option to declare return/arg type for class member functions? Leads to error at compile - 'addFunction : ambiguous call to overloaded function'

 

Thanks again for the patience.

Link to comment

Hey Santosh!

 

We have a C++ sample located in <sdkroot>/source/samples/Api/Scripts/Arrays, it contains everything you need to know about arrays.

 

1. From UnigineScript perspective there's no difference between these two functions, because they're look like that:

// C++
int func(int a,int b);
float func(int a,int b);

// After they being wrapped, they both will look like this
// No difference
Unigine::Variable func(Unigine::Variable a,Unigine::Variable b);

It's better to export one function which will take Unigine::Variable as its arguments and check their type, just like we did, for example, in Image::get2D function:

vec4 image_get_2d(Image *image,const Variable &x,const Variable &y) {
	if(x.isInt() && y.isInt()) // return exact pixel
	if(x.isFloat() && y.isFloat()) // return interpolated pixel
	Interpreter::error("Image::get2D(): unknown type of arguments (%s,%s)\n",x.getTypeName().get(),y.getTypeName().get());
	return vec4_zero;
}

2. Just do the trick I mentioned above. ;)

Link to comment
×
×
  • Create New...