Amerio.Stephane Posted January 8, 2019 Share Posted January 8, 2019 Hello, I'm trying to create a child node from a component, in a syncker master-slave configuration. I figured I should check for the Master state in my component init() and then create the node from a file and mark it for synchronisation: // 'ptr' is a member NodePtr void MyComponent::my_init() { const int syncker_index = Engine::get()->findPlugin("Syncker"); if (syncker_index != -1) { Syncker::ManagerInterface* syncker_manager = (Syncker::ManagerInterface*)Engine::get()->getPluginData(syncker_index); if (syncker_manager->isMasterInitialized()) { NodeReferencePtr ref = NodeReference::create("ig/entities/dummies/cuboid/Cuboid.node"); ref->release(); ptr = ref->detachReference(); syncker_manager->getMaster()->createNode(ptr); ptr->setPosition(Math::Vec3(0, 0, 10)); node->addChild(ptr); } } } The node is correctly created on the master, but it does not show up on the slave. Note the parent node (the one with the component property applied to) is created through Cigi, if that matters. What am I missing? Thanks Link to comment
alexander Posted January 9, 2019 Share Posted January 9, 2019 Hi Amerio.Stephane, What does "Cuboid.node" look like? Are there any errors in the console? Is it an ObjectMeshDynamic? This type of objects is not supported yet. Why do you use ref->release(); without grab() function? It is a memory leak. Best regards, Alexander Link to comment
Amerio.Stephane Posted January 9, 2019 Author Share Posted January 9, 2019 (edited) My bad, you are spot on! My cuboid was an ObjectMeshDynamic, but the warning message was lost in the scrolling. But after replacing it with a static mesh, the object is still not created on the slave, and there is no error message... (node attached) But you highlighted also my misunderstanding of the release/grab functions. How should the code be fixed exactly, knowing that I must keep a NodePtr as a member? (the whole Ptr/editor passing management is really obscure)cuboid.node Edited January 9, 2019 by Amerio.Stephane Link to comment
alexander Posted January 9, 2019 Share Posted January 9, 2019 But after replacing it with a static mesh, the object is still not created on the slave Mmm... Try to add this: syncker_manager->getMaster()->addSyncNode(node); // add this line! node->addChild(ptr); I think the "ptr" node was created, but could not attach to the parent node on slaves. How should the code be fixed exactly, knowing that I must keep a NodePtr as a member? Look at this new article: https://developer.unigine.com/en/docs/2.7.3/code/fundamentals/smartpointers Hope it helps to understand "smart" pointers. In your case, you can simply remove "ref->release();" line. Because after detachReference() call NodeReference is a simple dummy object with no nodes inside. It can be deleted at the end of the scope. Best regards, Alexander Link to comment
Amerio.Stephane Posted January 9, 2019 Author Share Posted January 9, 2019 I added addSyncNode but nothing changed (shouldn't createNode already flag it for synchronisation?) I removed release(), but ptr->isOwner() returns 0. Who is the owner then? Should I call grab()? Link to comment
alexander Posted January 10, 2019 Share Posted January 10, 2019 Hi Amerio.Stephane, Unfortunately, there is a small bug related to synchronization of the entity with id 0 (IG + CIGIConnector + Syncker). The point is that this entity is created before the initialization of the Syncker. We will fix this in the next release, but for now i can give you a small workaround. Look at the attached files (AppWorldLogic.cpp). Thanks!I added addSyncNode but nothing changed (shouldn't createNode already flag it for synchronisation?) Please note that we use addSyncNode to "node" pointer, but createNode to "ptr" pointer. Slaves don't know the real id of the parent node "node" (because it creates dynamically at runtime) and we need to use addSyncNode to pass the real id of this node to slaves.I removed release(), but ptr->isOwner() returns 0. Who is the owner then? No one. This is an orphan node. But when you call node->addChild(ptr) the owner of this node becomes the NodeReference (node->getPossessor()) in which you place the node. When a NodeReference dies it destroys all its nodes.Should I call grab()? No. Because it will lead to double delete (~MyComponent and ~NodeReference in IG plugin at world shutdown). Best regards, Alexander workaround.zip 1 Link to comment
Amerio.Stephane Posted January 10, 2019 Author Share Posted January 10, 2019 Thanks for the workaround ! I've seen in your code you skip the IG+cigi initialisation on the slave in SystemLogic, I added that too. Link to comment
Recommended Posts