You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Right now there are some problems about how ThreadingHost work:
You need to implement an update method for updating on a created thread Listen() and on an existing thread ListenOnThread(), which can be seen as problematic on MainThreadHost (since that for now it can only be updated if it was called via ListenOnThread), and this is also problematic for applications that could be fully run on existing threads...
ThreadingHost is somewhat a singleton, you can have only one instance, which isn't really problematic imo, but if you have want to have one server and one client simulation, you'll need to inject two Instance, and if you want to have them multithreaded or different update frequency is impossible for now.
Proposed solution
Remove all listening functions in ThreadingHost and remove all static variables.
Add a new Listen-type method called Start(ThreadUpdaterBase, IKey[])
The ThreadUpdaterBase will possess a way to update applications via a method calleed Update() and can contain multiple applications of the same type (which can be retrieved via a key).
Example:
ThreadUpdaterBasemainThreadUpdater;ThreadUpdaterBasesimulationThreadUpdater;voidInit(){mainThreadUpdater=newThreadUpdater(Thread.CurrentThread);varmainThreadHost=newMainThreadHost();mainThreadHost.Start(mainThreadUpdater,newPrincipalHostKey<MainThreadHost>());// By default, this method will automatically call for us ThreadUpdaterBase.Update()simulationThreadUpdater=ThreadUpdaterHelper.FromNewThread(thread =>newThreadUpdater(thread),default(CancellationToken));varclientSimuHost=newSimulationThreadHost();clientSimuHost.Start(simulationThreadUpdater,newClientSimulationKey());varserverSimuHost=newSimulationThreadHost();serverSimuHost.Start(simulationThreadUpdater,newServerSimulationKey(),newPrincipalHostKey<ServerSimulationKey>());Debug.Assert(mainThreadUpdater.GetListener<PrincipalHostKey<MainThreadHost>,MainThreadHost>()==mainThreadHost);}voidUpdate(){// Since mainThreadUpdater is in the same thread as where this method is called and that we manually created it, we need to manually call mainThreadUpdaterif(mainThreadUpdater.IsSameThread)mainThreadUpdater.Update();// Synchronizing a ThreadUpdater that exist in another thread (aka just locking)using(simulationThreadUpdater.SynchronizeThread()){// Synchronized!}// Or maybe just scheduling some actions?if(SimulationThreadHostisISchedulerscheduler){varStartTick=Environment.Tickcount;scheduler.Schedule(()=>System.Console.WriteLine($"Hello world! {Environment.Tickcount} - {StartTick}"));}}classThreadUpdater:ThreadUpdaterBase,IScheduler{privateList<IListener>listeners;protectedoverridevoidOnListenerAdded(IListenerlistener){listener.OnConfirmAdd(this);}protectedoverridevoidOnUpdate(){listeners.ForEach(listener =>listener.Update());}// implementing some schedulers actions....}classPrincipalHostKey<T>:IKey{publicvoidThrowIfNotValid(IDictionary<IKey,object>map,objecttoInsert){if(toInsert.GetType()!=typeof(T))thrownewException();foreach(varkeyinmap.Keys){if(key==typeof(PrincipalHostKey<T>))thrownewException($"A principal '{typeof(T)}' host has already been found in the map");}}}
The text was updated successfully, but these errors were encountered:
This is now completed and will be pushed to the next version of GameHost. But there is a now a preferred format to call this, which is more ECS friendly
varworld=global.World;varmainThreadUpdater=world.CreateEntity();mainThreadUpdater.Set<ListenerCollectionBase>(newListenerCollection());varotherThreadUpdater=world.CreateEntity();otherThreadUpdater.Set<ListenerCollectionBase>(newThreadListenerCollection(ccsource.Token));varmainAppEntity=world.CreateEntity();// will be called on this thread (aka where mainThreadUpdater exist)mainAppEntity.Set<IListener>(newMainOpApplication());mainAppEntity.Set(newListenerCollectionTarget(mainThreadUpdater));varonOtherThreadAppEntity=world.CreateEntity();// will be called on another threadonOtherThreadAppEntity.Set<IListener>(newMainOpApplication());onOtherThreadAppEntity.Set(newListenerCollectionTarget(otherThreadUpdater));while(!Environment.HasShutdownStarted){global.Loop();}ccsource.Cancel();
also an important feature that got added (but will be used rarely) is for applications being able to switch current thread on the fly. Since it's done in the background it shouldn't cause any issue. This can be interesting for benchmarking or when an application enable a feature that need to be executed on a special thread.
Problems
Right now there are some problems about how ThreadingHost work:
Listen()
and on an existing threadListenOnThread()
, which can be seen as problematic on MainThreadHost (since that for now it can only be updated if it was called via ListenOnThread), and this is also problematic for applications that could be fully run on existing threads...Instance
, and if you want to have them multithreaded or different update frequency is impossible for now.Proposed solution
Listen
-type method calledStart(ThreadUpdaterBase, IKey[])
The
ThreadUpdaterBase
will possess a way to update applications via a method calleedUpdate()
and can contain multiple applications of the same type (which can be retrieved via a key).Example:
The text was updated successfully, but these errors were encountered: