// Called during shutdown void OnDestroy() { // Flag the program as shutting down, wait for the reader to exit, then free the Rust memory running = false; while (stateReaderThread.IsAlive) { } FFIBridge.destroySim(sim); }
// Function to be fun off of the main thread that will tight loop the fungine and collect the states back from it private void StateReader() { sim = FFIBridge.newSim(boidCount); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); float timeStep = 0; while (running) { // Check for player input if (player != null) { FFIBridge.addMovement(sim, playerId, player.forwardSpeed, player.straffeSpeed, player.mouseInput); } // Step the engine forward once UIntPtr result = FFIBridge.step(sim, timeStep); Dictionary <UInt64, ReturnObj> newState = new Dictionary <UInt64, ReturnObj>(); UInt64 gathererCount; if (Environment.ProcessorCount < 2) { gathererCount = 1; } else { gathererCount = (UInt64)Environment.ProcessorCount - 1; } var taskCount = (UInt64)result / gathererCount; Task <Dictionary <UInt64, ReturnObj> >[] gatheredStates = new Task <Dictionary <UInt64, ReturnObj> > [gathererCount]; for (UInt64 i = 0; i < gathererCount; i++) { UInt64 start = (i * taskCount); UInt64 end = (taskCount * (i + 1)); if (i == gathererCount - 1) { end = (uint)result; } gatheredStates[i] = Task.Run(() => stateGatherer(sim, start, end)); } Task.WaitAll(gatheredStates); newState = gatheredStates.Select(t => t.Result).SelectMany(dict => dict) .ToDictionary(pair => pair.Key, pair => pair.Value); states = newState; engineSteps++; long elaspsedTime = stopWatch.ElapsedMilliseconds; if (elaspsedTime < 10) { Thread.Sleep((int)(10 - elaspsedTime)); } timeStep = stopWatch.ElapsedMilliseconds / 1000.0f; stopWatch.Restart(); } UnityEngine.Debug.Log("Closing state reader thread..."); }
// Gather object states from the fungine private Dictionary <UInt64, ReturnObj> stateGatherer(UIntPtr sim, UInt64 start, UInt64 end) { Dictionary <UInt64, ReturnObj> states = new Dictionary <UInt64, ReturnObj>(); for (UInt64 i = start; i < end; i++) { ReturnObj b = FFIBridge.getObj(sim, (UIntPtr)i); states.Add(b.id, b); } return(states); }