/// <summary> /// Play back all recorded operations against an entity manager. /// </summary> /// <param name="mgr">The entity manager that will receive the operations</param> public void Playback(EntityManager mgr) { if (mgr == null) { throw new NullReferenceException($"{nameof(mgr)} cannot be null"); } EnforceSingleThreadOwnership(); var head = m_Data->m_Head; var lastEntity = new Entity(); while (head != null) { var off = 0; var buf = ((byte *)head) + sizeof(Chunk); while (off < head->Used) { var header = (BasicCommand *)(buf + off); switch ((Command)header->CommandType) { case Command.DestroyEntity: { mgr.DestroyEntity(((EntityCommand *)header)->Entity); } break; case Command.RemoveComponent: { var cmd = (EntityComponentCommand *)header; var entity = cmd->Header.Entity == Entity.Null ? lastEntity : cmd->Header.Entity; mgr.RemoveComponent(entity, TypeManager.GetType(cmd->ComponentTypeIndex)); } break; case Command.CreateEntity: { var cmd = (CreateCommand *)header; if (cmd->Archetype.Valid) { lastEntity = mgr.CreateEntity(cmd->Archetype); } else { lastEntity = mgr.CreateEntity(); } break; } case Command.AddComponent: { var cmd = (EntityComponentCommand *)header; var componentType = (ComponentType)TypeManager.GetType(cmd->ComponentTypeIndex); var entity = cmd->Header.Entity == Entity.Null ? lastEntity : cmd->Header.Entity; mgr.AddComponent(entity, componentType); mgr.SetComponentDataRaw(entity, cmd->ComponentTypeIndex, (cmd + 1), cmd->ComponentSize); } break; case Command.SetComponent: { var cmd = (EntityComponentCommand *)header; var entity = cmd->Header.Entity == Entity.Null ? lastEntity : cmd->Header.Entity; mgr.SetComponentDataRaw(entity, cmd->ComponentTypeIndex, (cmd + 1), cmd->ComponentSize); } break; case Command.AddSharedComponentData: { var cmd = (EntitySharedComponentCommand *)header; var entity = cmd->Header.Entity == Entity.Null ? lastEntity : cmd->Header.Entity; mgr.AddSharedComponentDataBoxed(entity, cmd->ComponentTypeIndex, cmd->HashCode, cmd->GetBoxedObject()); } break; case Command.SetSharedComponentData: { var cmd = (EntitySharedComponentCommand *)header; var entity = cmd->Header.Entity == Entity.Null ? lastEntity : cmd->Header.Entity; mgr.SetSharedComponentDataBoxed(entity, cmd->ComponentTypeIndex, cmd->HashCode, cmd->GetBoxedObject()); } break; } off += header->TotalSize; } head = head->Next; } }