Description
References for nodes can reach the backend before the nodes themselves. Some cases have already covered in other bug reports, such as when nodes are used in components or properties (see QTBUG-73986 and QTBUG-72236). However, it seems like this is a general issue that occurs also when nodes are referenced by other nodes in simple setters. The pattern that triggers this appears to be along the lines of:
auto root = new Node(); auto nodeA = new Node(root); // assume that processEvents is run and nodeA gets a backend node auto dummyParent = new Node(root); auto nodeB = new Node(root); auto nodeC = new Node(dummyParent); // this line does not result in a scene change event because nodeB // has not yet been been created on the backend nodeB->setSomething(nodeC); // this line results in a scene change event because nodeB // already exists nodeA->setSomething(nodeB);
In the above case, the backend will receive the creation of nodeB with the correspoding property set to nodeC before nodeC has been created. If we are very unfortunate, we get a scene change batch in the middle of everything, resulting in a whole frame where nodeB refers to a non-existent nodeC.
As far as I can see, every setter that takes a subclass of QNode* in Qt 3D needs to be updated to ensure that the node and any ancestors are created on the backend before the node is set as a property.
Alternatively, all events need to be batched in the order they occur and any communication in initializeFromPeer must be dropped in favor of sending scene change events for everything.