void ThreadProc() { Thread.CurrentThread.Name = "Entity creation thread"; HkBaseSystem.InitThread("Entity creation thread"); ProfilerShort.Autocommit = false; MyEntityIdentifier.InitPerThreadStorage(2048); Item item; while (!m_exitting) { if (ConsumeWork(out item)) { if (item.ObjectBuilder != null) { if (item.Result == null) { item.Result = MyEntities.CreateFromObjectBuilderNoinit(item.ObjectBuilder); } item.Result.SentFromServer = true; item.InScene = (item.ObjectBuilder.PersistentFlags & MyPersistentEntityFlags2.InScene) == MyPersistentEntityFlags2.InScene; item.ObjectBuilder.PersistentFlags &= ~MyPersistentEntityFlags2.InScene; item.Result.DebugAsyncLoading = true; MyEntities.InitEntity(item.ObjectBuilder, ref item.Result); if (item.Result != null) { if (item.SubgridBuilders != null) { item.SubGrids = new List <MyEntity>(); foreach (var subGridbulider in item.SubgridBuilders) { MyEntity subGrid = MyEntities.CreateFromObjectBuilderNoinit(subGridbulider); subGridbulider.PersistentFlags &= ~MyPersistentEntityFlags2.InScene; item.Result.DebugAsyncLoading = true; MyEntities.InitEntity(subGridbulider, ref subGrid); item.SubGrids.Add(subGrid); } item.SubgridBuilders.Clear(); item.SubgridBuilders = null; } item.EntityIds = new List <IMyEntity>(); MyEntityIdentifier.GetPerThreadEntities(item.EntityIds); MyEntityIdentifier.ClearPerThreadEntities(); m_resultQueue.Enqueue(item); } } else { if (item.Result != null) { item.Result.DebugAsyncLoading = true; } // This is ok, just invoking action asynchronously m_resultQueue.Enqueue(item); } } ProfilerShort.Commit(); } MyEntityIdentifier.DestroyPerThreadStorage(); HkBaseSystem.QuitThread(); ProfilerShort.DestroyThread(); }
public bool ConsumeResult() { Item result; if (m_resultQueue.TryDequeue(out result)) { if (result.Result != null) { result.Result.DebugAsyncLoading = false; } bool conflictFound = false; if (result.EntityIds != null) { while (MyEntities.HasEntitiesToDelete()) { MyEntities.DeleteRememberedEntities(); } foreach (var id in result.EntityIds) { IMyEntity entity; if (MyEntityIdentifier.TryGetEntity(id.EntityId, out entity)) { MyLog.Default.WriteLine("Entity found ! id : " + id.EntityId.ToString() + " existing : " + entity.ToString() + " adding: " + id.ToString()); conflictFound = true; // Debug.Fail("double entity add !!"); } } if (conflictFound == false) { foreach (var id in result.EntityIds) { MyEntityIdentifier.AddEntityWithId(id); } } result.EntityIds.Clear(); } if (conflictFound == false) { if (result.AddToScene) { MyEntities.Add(result.Result, result.InScene); if (result.SubGrids != null) { foreach (var subGrid in result.SubGrids) { MyEntities.Add(subGrid, result.InScene); } result.SubGrids.Clear(); result.SubGrids = null; } } if (result.DoneHandler != null) { result.DoneHandler(result.Result); } } else { if (result.DoneHandler != null) { result.DoneHandler(null); } } return(true); } return(false); }
public bool ConsumeResult(MyTimeSpan timestamp) { Item item; if (!this.m_resultQueue.TryDequeue(out item)) { return(false); } if (item.Result != null) { item.Result.DebugAsyncLoading = false; } bool flag = false; if (item.EntityIds != null) { while (true) { if (!MyEntities.HasEntitiesToDelete()) { List <IMyEntity> .Enumerator enumerator; using (enumerator = item.EntityIds.GetEnumerator()) { while (enumerator.MoveNext()) { IMyEntity entity; if (!MyEntityIdentifier.TryGetEntity(enumerator.Current.EntityId, out entity, false)) { continue; } flag = true; } } if (!flag) { using (enumerator = item.EntityIds.GetEnumerator()) { while (enumerator.MoveNext()) { MyEntityIdentifier.AddEntityWithId(enumerator.Current); } } } item.EntityIds.Clear(); break; } MyEntities.DeleteRememberedEntities(); } } if (flag) { if (item.DoneHandler != null) { item.DoneHandler(null); } } else { if (item.AddToScene) { MyEntities.Add(item.Result, item.InScene); } if (item.DoneHandler != null) { item.DoneHandler(item.Result); } } return(true); }
private unsafe void ThreadProc() { Thread.CurrentThread.Name = "Entity creation thread"; HkBaseSystem.InitThread("Entity creation thread"); MyEntityIdentifier.InEntityCreationBlock = true; MyEntityIdentifier.InitPerThreadStorage(0x800); while (!this.m_exitting) { Item item; if (!this.ConsumeWork(out item)) { continue; } if (item.ReleaseMatrices != null) { foreach (Item item2 in this.m_waitingItems) { if (item2.WaitGroup == item.WaitGroup) { MatrixD xd; if (item.ReleaseMatrices.TryGetValue(item2.Result.EntityId, out xd)) { item2.Result.PositionComp.WorldMatrix = xd; } this.m_waitingItems.Remove(item2, false); this.m_resultQueue.Enqueue(item2); } } this.m_waitingItems.ApplyRemovals(); continue; } if (item.ObjectBuilder == null) { if (item.Result != null) { item.Result.DebugAsyncLoading = true; } if (item.WaitGroup == 0) { this.m_resultQueue.Enqueue(item); } else { this.m_waitingItems.Add(item); this.m_waitingItems.ApplyAdditions(); } continue; } if (item.Result == null) { Item *itemPtr1 = (Item *)ref item; itemPtr1->Result = MyEntities.CreateFromObjectBuilderNoinit(item.ObjectBuilder); } Item *itemPtr2 = (Item *)ref item; itemPtr2->InScene = (item.ObjectBuilder.PersistentFlags & MyPersistentEntityFlags2.InScene) == MyPersistentEntityFlags2.InScene; item.ObjectBuilder.PersistentFlags &= ~MyPersistentEntityFlags2.InScene; item.Result.DebugAsyncLoading = true; MyEntities.InitEntity(item.ObjectBuilder, ref item.Result); if (item.Result != null) { item.Result.Render.FadeIn = item.FadeIn; item.EntityIds = new List <IMyEntity>(); MyEntityIdentifier.GetPerThreadEntities(item.EntityIds); MyEntityIdentifier.ClearPerThreadEntities(); if (item.WaitGroup == 0) { this.m_resultQueue.Enqueue(item); } else { this.m_waitingItems.Add(item); this.m_waitingItems.ApplyAdditions(); } } } MyEntityIdentifier.DestroyPerThreadStorage(); HkBaseSystem.QuitThread(); }
/// <summary> /// Every object must have this method, but not every phys object must necessarily have something to cleanup /// <remarks> /// </remarks> /// </summary> public void Delete() { Close(); BeforeDelete(); GameLogic.Close(); //doesnt work in parallel update //Debug.Assert(MySandboxGame.IsMainThread(), "Entity.Close() called not from Main Thread!"); Debug.Assert(MyEntities.UpdateInProgress == false, "Do not close entities directly in Update*, use MarkForClose() instead"); Debug.Assert(MyEntities.CloseAllowed == true, "Use MarkForClose()"); Debug.Assert(!Closed, "Close() called twice!"); //Children has to be cleared after close notification is send while (Hierarchy.Children.Count > 0) { MyHierarchyComponentBase compToRemove = Hierarchy.Children[Hierarchy.Children.Count - 1]; Debug.Assert(compToRemove.Parent != null, "Entity has no parent but is part of children collection"); compToRemove.Container.Entity.Delete(); Hierarchy.Children.Remove(compToRemove); } //OnPositionChanged = null; CallAndClearOnClosing(); MyDecals.RemoveModelDecals(this); MyEntities.RemoveName(this); MyEntities.RemoveFromClosedEntities(this); if (m_physics != null) { m_physics.Close(); Physics = null; RaisePhysicsChanged(); } MyEntities.UnregisterForUpdate(this, true); if (Parent == null) //only root objects are in entities list { MyEntities.Remove(this); } else { Parent.Hierarchy.Children.Remove(this.Hierarchy); //remove children first if (Parent.InScene) { OnRemovedFromScene(this); } MyEntities.RaiseEntityRemove(this); } if (this.EntityId != 0) { MyEntityIdentifier.RemoveEntity(this.EntityId); } //this.EntityId = 0; Debug.Assert(this.Hierarchy.Children.Count == 0); CallAndClearOnClose(); Components.Clear(); ClearDebugRenderComponents(); Closed = true; }
public virtual void Init(MyObjectBuilder_CubeBlock builder, MyCubeGrid cubeGrid) { //objectBuilder.PersistentFlags |= MyPersistentEntityFlags2.CastShadows; // Ensure that if we went from not serializing to serializing, we have a valid entity id. if (builder.EntityId == 0) { EntityId = MyEntityIdentifier.AllocateId(); } else if (builder.EntityId != 0) { EntityId = builder.EntityId; } NumberInGrid = cubeGrid.BlockCounter.GetNextNumber(builder.GetId()); Render.ColorMaskHsv = builder.ColorMaskHSV; if (BlockDefinition.ContainsComputer()) { m_IDModule = new MyIDModule(); if (MySession.Static.Settings.ResetOwnership && Sync.IsServer) { m_IDModule.Owner = 0; m_IDModule.ShareMode = MyOwnershipShareModeEnum.None; } else { if ((int)builder.ShareMode == -1) { builder.ShareMode = MyOwnershipShareModeEnum.None; } var ownerType = MyEntityIdentifier.GetIdObjectType(builder.Owner); if (builder.Owner != 0 && ownerType != MyEntityIdentifier.ID_OBJECT_TYPE.NPC && ownerType != MyEntityIdentifier.ID_OBJECT_TYPE.SPAWN_GROUP) { System.Diagnostics.Debug.Assert(ownerType == MyEntityIdentifier.ID_OBJECT_TYPE.IDENTITY, "Old save detected, reseting owner to Nobody, please resave."); if (!Sync.Players.HasIdentity(builder.Owner)) { builder.Owner = 0; //reset, it was old version } } m_IDModule.Owner = builder.Owner; m_IDModule.ShareMode = builder.ShareMode; } } if (MyFakes.ENABLE_SUBBLOCKS) { if (builder.SubBlocks != null) { foreach (var subblockInfo in builder.SubBlocks) { m_subBlockIds.Add(subblockInfo.SubGridName, new MySubBlockLoadInfo() { GridId = subblockInfo.SubGridId, SubBlockPosition = subblockInfo.SubBlockPosition }); } m_subBlocksLoaded = m_subBlockIds.Count > 0; if (BlockDefinition.SubBlockDefinitions != null && BlockDefinition.SubBlockDefinitions.Count > 0 && m_subBlockIds.Count == 0) { m_subBlocksInitialized = true; m_subBlocksLoaded = true; } // Set update flag for InitSubBlocks NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; } } base.Init(null); base.Render.PersistentFlags |= MyPersistentEntityFlags2.CastShadows; Init(); AddDebugRenderComponent(new MyDebugRenderComponentCubeBlock(this)); }