Creating a node from a component


photo

Recommended Posts

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 post

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 post

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 by Amerio.Stephane
Link to post

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 post

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 post

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

bug.png

workaround.zip

  • Like 1
Link to post

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 post