christian.wolf2 Posted June 26, 2017 Share Posted June 26, 2017 Hi, I am currently trying to export some classes from my C++ plugin to UnigineScript, inherit a class in UnigineScript and set it as variable in one of their base class. The C++ classes are defined as following: class Task { protected: Task* parent; //pointer to the parent of this task virtual int addChildToTask(Task* newChild) { return 0; }; public: Task(); ~Task(); virtual int addChild(Task* newChild) //adds an Child to this task { addChildToTask(newChild); } }; class Sequence : public Task { protected: vector<Task*> children; virtual int addChildToTask(Task* newChild) { children.push_back(newChild); } }; class LeafTask : public Task { public: virtual void executeLeafTask(); }; I exported all classes using "MakeExternClass" without any problems. In Unigine I inherit the LeafClass and tried to use my external classes: class CustomLeafTask : public LeafTask { (...) public: void executeLeafTask(); }; (...) //later in an world file: init() { CustomLeafTask myLeaf = new CustomLeafTask(); Sequence innerSequence = new Sequence(); innerSequence.addChild(CustomLeafTask::cast(myLeaf.extern)); //use ::cast and .extern to use Unigine-Script class in extern plugin class - OK! Sequence outerSequence = new Sequence(); outerSequence.addChild(innerSequence); //crash "can't convert extern class to class Task* __ptr64" } The error occurs only, if I used the derived class I declared in UnigineScript. If I used the standard "Leaf-Class" the problem never appears. Using ::cast or .extern for the innerSequence aren't allowed because it is not defined. Is this behavior intended and are there any solutions for that? Thanks in advance! Christian Link to comment
unclebob Posted July 17, 2017 Share Posted July 17, 2017 Hi Christian! It seems like a bug to me. Could you please show the export part of your code? Are you sure you don't forget to call interpreter->addBaseClass for all derived C++ classes? Link to comment
christian.wolf2 Posted July 19, 2017 Author Share Posted July 19, 2017 On 17.7.2017 at 0:24 PM, unclebob said: Are you sure you don't forget to call interpreter->addBaseClass for all derived C++ classes? Hi Bob, actually not, because there aren't any hints in the documentation. :) I will try to implement that, can you please describe me how and when do I have to you use the addBaseClass()? Only if I use the function of the derived class without overwriting them or every time I derived a class from a base one regardeless of their use of a specific function? Link to comment
unclebob Posted July 21, 2017 Share Posted July 21, 2017 Hi Christian! It's quite simple. Here's code sample: // C++ part class A { public: virtual void baseMethod() const { Unigine::Log::message("A::baseMethod\n"); } }; class B : public A { public: void baseMethod() const override { Unigine::Log::message("B::baseMethod\n"); } void derivedMethod() const { Unigine::Log::message("B::derivedMethod\n"); } }; void extendInterpreter() { auto a_class = Unigine::MakeExternClass<A>(); a_class->addConstructor(); a_class->addFunction("baseMethod", &A::baseMethod); auto b_class = Unigine::MakeExternClass<B>(); b_class->addConstructor(); b_class->addFunction("derivedMethod", &B::derivedMethod); b_class->addBaseClass(a_class); Unigine::Interpreter::addExternClass("A", a_class); Unigine::Interpreter::addExternClass("B", b_class); } // UnigineScript part int init() { A foo = new A(); foo.baseMethod(); log.message("--\n"); B bar = new B(); bar.baseMethod(); bar.derivedMethod(); log.message("--\n"); A baz = new B(); baz.baseMethod(); B(baz).derivedMethod(); log.message("--\n"); B qux = baz; qux.baseMethod(); qux.derivedMethod(); log.message("--\n"); return 1; } Link to comment
christian.wolf2 Posted August 8, 2017 Author Share Posted August 8, 2017 Hi Bob, sorry for my late reply. Indeed, your solution works for me, so thank you for that. Now, I am struggeling adding an UnigineScript-class I derived, to my C++ class. In my upper example I use the following function, which I exported it to UnigineScript: virtual int addChildToTask(Task* newChild) { children.push_back(newChild); } In my UnigineScript I used the function: innerSequence.addChild(CustomLeafTask::cast(myLeaf.extern)); //use ::cast and .extern to use Unigine-Script class in extern plugin class - OK! Unfortunately, the given (derived) task is always NULL if I add a Log-line in my C++ function (befor children.push_back()). Link to comment
christian.wolf2 Posted October 15, 2017 Author Share Posted October 15, 2017 (edited) Hi, are there any update to this? I added a short sample project to this post. Simply, create A as base class, Class B and C inherit from A. B has a vector, where I want to add childs as A class. The .dll file is imported as a plugin module to a sample project. I inherit a new class D in UnigineScript from C class. After that I want to add this class new D class to a B class. Even if I use the .extern classifier, the inherited object is NULL. inheritance_example.rar Edited October 15, 2017 by christian.wolf2 Link to comment
silent Posted October 19, 2017 Share Posted October 19, 2017 Hi Christian, Thanks for the test scene, I've send it to the dev team. Hope to get answer soon. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
moroz Posted October 19, 2017 Share Posted October 19, 2017 Hi Christian, You have to call ancestor constructor in inherited class. Example: class D : C { public: D() : C() {} ~D() {} }; For details see this : https://developer.unigine.com/en/docs/2.5/code/uniginescript/language/oop#inheritance_c But there is some problems. This way of constructor definition doesn't work: void D::__D__() : C() { } We will try to improve script behavior in this case, but for now it will work only that way. Link to comment
christian.wolf2 Posted November 6, 2017 Author Share Posted November 6, 2017 Hi moroz, thanks for the detailed feedback. I need indeed the improvement for the script behavior. So thanks for adding that. Do you already know, when it will be released? Link to comment
silent Posted November 7, 2017 Share Posted November 7, 2017 Hi Christian, For now it's have lowest priority, so probably not this year. Sorry for the inconvenience. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
christian.wolf2 Posted November 8, 2017 Author Share Posted November 8, 2017 Hi silent, thanks for the info. Do you know if of there are any workaround? I am currently working on a plugin where the user needs to be able to extend the classes I exported from C++. I'm not getting confident with the idea of adapt the system completely as UnigineScript. (I can P.M. you if you want to have more details about it) Thanks a lot anyway Christian Link to comment
Recommended Posts