realXtend / tundra

realXtend Tundra SDK, a 3D virtual world application platform.
www.realxtend.org
Apache License 2.0
84 stars 70 forks source link

Server not sending all parents before children in initial scene sync #775

Open jonnenauha opened 10 years ago

jonnenauha commented 10 years ago

While I was implementing the drag and drop Entity parenting in scene struct windows, I noticed this bug. Making a mental note here to fix it later. Also asking for input from @cadaver as you know the sync manager code best and authored Entity parenting.

How to reproduce

  1. Login to a server with a client.
  2. Create two Entities.
  3. Parent the smaller id Entity to the bigger entity Id. (eg. Entity #1 to Entity #2).
  4. Logout and login back.
  5. You should see a warning on the console (client side) Failed to find parent Entity #2 for Entity

I looked at the code of the SyncManager server state processing. It looks like the initial scene sync is done in the order of creation (essentially ascending by id). This is not good enough anymore as we have parenting. The result on the client is that scene struct and actually even the code Entity::Parent() will lie to the user. The parents creation is not monitored if it fails to be found during creation. I think this is good because we dont want the mess/complexity of EC_Placeable::parentRef monitoring.

Proposed solution

It's quite simple really if I'm not missing something. Don't send the new Entity messages while processing the state (looping dirty new ents). Instead make a list and insert each item to the correct place as per parenting hierarchy. It might be even faster to create two lists, one for root Entities and after those Entities that have children. Then a secondary list that has any parented Entities.

After all new ents have been processed, loop the list (or the two lists) and send them to the client in the correct order.

@cadaver I see that the initial sync is the only place where problems might occur would you agree? Do you see any problems coming from changing the order of initial sync entities?

Edit: If you save the scene after pareting to txml/tbin Restart the server with that scene description, it will get fixed. Thanks to the proper hierarchy in the scene descs now, the parent will always get created before the children. Hence getting a smaller id and getting added to the client states prior to the children. I think this is even the case (order of the client sync state) even if new ids are not generated for the scene as the CreateEntity is emitted first for the parent, but I didnt check.

jonnenauha commented 10 years ago

From the IRC discussions it seems the best approach would be to take a copy of the client sync states dirty entity queue, sort it so that parents are before children and then run the same loop that currently sends the messages with that sorted list.