//-------------update------------ /** 'update' the scheduler. You should NEVER call this method, unless you know what you are doing. */ public void update(float dt){ if (_paused) return; updateHashLocked = true; if (!FloatUtils.EQ(_timeScale , 1.0f)) dt *= _timeScale; // Iterate all over the Updates selectors // updates with priority < 0 { for( utNode<tListEntry> tmp = updatesNeg.head; tmp != null ; tmp = tmp.next ) { utNode<tListEntry> entry = tmp; if(! entry.obj.paused && !entry.obj.markedForDeletion){ entry.obj.impMethod.Invoke(dt); } } } // updates with priority == 0 { for( utNode<tListEntry> tmp = updates0.head; tmp != null ; tmp = tmp.next ) { utNode<tListEntry> entry = tmp; if(! entry.obj.paused && !entry.obj.markedForDeletion) entry.obj.impMethod.Invoke(dt); } } // updates with priority > 0 { for( utNode<tListEntry> tmp = updatesPos.head; tmp != null ; tmp = tmp.next ) { utNode<tListEntry> entry = tmp; if(! entry.obj.paused && !entry.obj.markedForDeletion) entry.obj.impMethod.Invoke(dt); } } // Iterate all over the custom selectors (CCTimers) if(hashForTimers.Any()){ var enumerator = new Dictionary<int, tHashTimerEntry>(hashForTimers).GetEnumerator(); while (enumerator.MoveNext()) { var elt = enumerator.Current.Value; currentTarget = elt; currentTargetSalvaged = false; if( ! currentTarget.paused){ for(elt.timerIndex = 0; elt.timerIndex < elt.timers.Count; elt.timerIndex ++ ){ elt.currentTimer = elt.timers[elt.timerIndex]; elt.currentTimerSalvaged = false; elt.currentTimer.update(dt); elt.currentTimer = null; } } if(currentTargetSalvaged && currentTarget.timers.Count == 0) removeHashElement(currentTarget); } } for (utNode<tListEntry> tmp = updatesNeg.head; tmp != null; tmp = tmp.next) { utNode<tListEntry> entry = tmp; if(entry.obj.markedForDeletion){ removeUpdatesFromHash(entry); } } for (utNode<tListEntry> tmp = updates0.head; tmp != null; tmp = tmp.next) { utNode<tListEntry> entry = tmp; if(entry.obj.markedForDeletion){ removeUpdatesFromHash(entry); } } for (utNode<tListEntry> tmp = updatesPos.head; tmp != null; tmp = tmp.next) { utNode<tListEntry> entry = tmp; if(entry.obj.markedForDeletion){ removeUpdatesFromHash(entry); } } updateHashLocked = false; currentTarget = null; }
private void CacheVessels() { if (!isReady) return; if (!tfScenario.SettingsEnabled) return; // build a list of vessels to process based on setting if (knownVessels == null) knownVessels = new Dictionary<Guid, double>(); // iterate through our cached vessels and delete ones that are no longer valid vesselsToDelete.Clear(); knownVesselsEnumerator = knownVessels.GetEnumerator(); while (knownVesselsEnumerator.MoveNext()) { KeyValuePair<Guid, double> entry = knownVesselsEnumerator.Current; Vessel vessel = null; for (int i = 0; i < FlightGlobals.Vessels.Count; i++) { if (FlightGlobals.Vessels[i].id == entry.Key) vessel = FlightGlobals.Vessels[i]; } if (vessel == null) vesselsToDelete.Add(entry.Key); else { if (vessel.vesselType == VesselType.Debris) vesselsToDelete.Add(entry.Key); } } for (int i = 0; i < vesselsToDelete.Count; i++) { knownVessels.Remove(vesselsToDelete[i]); } // Build our cached list of vessels. The reason we do this is so that we can store an internal "missionStartTime" for each vessel because the game // doesn't consider a vessel launched, and does not start the mission clock, until the player activates the first stage. This is fine except it // makes things like engine test stands impossible, so we instead cache the vessel the first time we see it and use that time as the missionStartTime if (!tfScenario.userSettings.processAllVessels) { if (FlightGlobals.ActiveVessel == null || knownVessels.ContainsKey(FlightGlobals.ActiveVessel.id)) return; knownVessels.Add(FlightGlobals.ActiveVessel.id, Planetarium.GetUniversalTime()); InitializeParts(FlightGlobals.ActiveVessel); } else { for (int i = 0; i < FlightGlobals.Vessels.Count; i++) { Vessel vessel = FlightGlobals.Vessels[i]; if (vessel.vesselType != VesselType.Lander && vessel.vesselType != VesselType.Probe && vessel.vesselType != VesselType.Rover && vessel.vesselType != VesselType.Ship && vessel.vesselType != VesselType.Station) continue; if (knownVessels.ContainsKey(vessel.id)) continue; knownVessels.Add(vessel.id, Planetarium.GetUniversalTime()); InitializeParts(vessel); } } }
// This method simply scans through the Master Status list every now and then and removes vessels and parts that no longer exist private void VerifyMasterStatus() { if (!isReady) return; if (!tfScenario.SettingsEnabled) return; // iterate through our cached vessels and delete ones that are no longer valid vesselsToDelete.Clear(); masterStatusEnumerator = masterStatus.GetEnumerator(); while (masterStatusEnumerator.MoveNext()) { KeyValuePair<Guid, MasterStatusItem> entry = masterStatusEnumerator.Current; Vessel vessel = null; for (int i = 0; i < FlightGlobals.Vessels.Count; i++) { if (FlightGlobals.Vessels[i].id == entry.Key) vessel = FlightGlobals.Vessels[i]; } if (vessel == null) { vesselsToDelete.Add(entry.Key); } else { if (vessel.vesselType == VesselType.Debris) { vesselsToDelete.Add(entry.Key); } } } for (int i = 0; i < vesselsToDelete.Count; i++) { masterStatus.Remove(vesselsToDelete[i]); } // iterate through the remaining vessels and check for parts that no longer exist partsToDelete.Clear(); masterStatusEnumerator = masterStatus.GetEnumerator(); while (masterStatusEnumerator.MoveNext()) { KeyValuePair<Guid, MasterStatusItem> entry = masterStatusEnumerator.Current; Vessel vessel = null; for (int i = 0; i < FlightGlobals.Vessels.Count; i++) { if (FlightGlobals.Vessels[i].id == entry.Key) vessel = FlightGlobals.Vessels[i]; } for (int i = 0; i < masterStatus[entry.Key].allPartsStatus.Count; i++) { PartStatus partStatus = masterStatus[entry.Key].allPartsStatus[i]; Part part = null; for (int j = 0; j < vessel.Parts.Count; j++) { if (vessel.Parts[j].flightID == partStatus.partID) part = vessel.Parts[j]; } if (part == null) { partsToDelete.Add(partStatus); } } for (int i = 0; i < partsToDelete.Count; i++) { PartStatus oldPartStatus = partsToDelete[i]; if (oldPartStatus.lastSeen < Planetarium.GetUniversalTime() - partDecayTime) masterStatus[entry.Key].allPartsStatus.Remove(oldPartStatus); } } }
internal override void Update() { if (!isReady) return; if (!tfScenario.SettingsEnabled) return; if (masterStatus == null) masterStatus = new Dictionary<Guid, MasterStatusItem>(); currentUTC = Planetarium.GetUniversalTime(); // ensure out vessel list is up to date Profiler.BeginSample("CacheVessels"); CacheVessels(); Profiler.EndSample(); if (currentUTC >= lastMasterStatusUpdate + tfScenario.userSettings.masterStatusUpdateFrequency) { lastMasterStatusUpdate = currentUTC; Profiler.BeginSample("VerifyMasterStatus"); VerifyMasterStatus(); Profiler.EndSample(); } // process vessels Profiler.BeginSample("ProcessVessels"); knownVesselsEnumerator = knownVessels.GetEnumerator(); while (knownVesselsEnumerator.MoveNext()) { KeyValuePair<Guid, double> entry = knownVesselsEnumerator.Current; Vessel vessel = null; Profiler.BeginSample("FindVessel"); for (int i = 0; i < FlightGlobals.Vessels.Count; i++) { if (FlightGlobals.Vessels[i].id == entry.Key) vessel = FlightGlobals.Vessels[i]; } Profiler.EndSample(); if (vessel == null) continue; if (vessel.loaded) { Profiler.BeginSample("ProcessParts"); List<Part> parts = vessel.Parts; for (int j = 0; j < parts.Count; j++) { // Each KSP part can be composed of N virtual parts Profiler.BeginSample("Reset Core List"); cores.Clear(); Profiler.EndSample(); Profiler.BeginSample("Get Cores"); for (int k = 0; k < parts[j].Modules.Count; k++) { ITestFlightCore core = parts[j].Modules[k] as ITestFlightCore; if (core != null && core.TestFlightEnabled) cores.Add(core.Alias); } Profiler.EndSample(); //cores = TestFlightInterface.GetActiveCores(vessel.parts[j]); if (cores == null || cores.Count <= 0) continue; Profiler.BeginSample("ProcessCores"); for (int k = 0; k < cores.Count; k++) { ITestFlightCore core = TestFlightUtil.GetCore(vessel.parts[j], cores[k]); if (core == null) continue; // Poll for flight data and part status if (!(currentUTC >= lastDataPoll + tfScenario.userSettings.masterStatusUpdateFrequency)) continue; // Update or Add part status in Master Status if (masterStatus.ContainsKey(vessel.id)) { Profiler.BeginSample("MasterStatus Existing Vessel"); // Vessel is already in the Master Status, so check if part is in there as well int existingPartIndex = -1; Profiler.BeginSample("Find Part"); for (int msIndex = 0; msIndex < masterStatus[vessel.id].allPartsStatus.Count; msIndex++) { if (masterStatus[vessel.id].allPartsStatus[msIndex].partID != vessel.parts[j].flightID) continue; existingPartIndex = msIndex; break; } Profiler.EndSample(); if (existingPartIndex > -1) { Profiler.BeginSample("Existing Part"); //PartStatus partStatus = masterStatus[vessel.id].allPartsStatus[existingPartIndex]; PartStatus partStatus = new PartStatus(); partStatus.lastSeen = currentUTC; partStatus.flightCore = core; partStatus.partName = core.Title; partStatus.partID = vessel.parts[j].flightID; Profiler.BeginSample("Part - GetPartStatus"); partStatus.partStatus = core.GetPartStatus(); Profiler.EndSample(); // get any failures Profiler.BeginSample("Part - GetActiveFailures"); partStatus.failures = core.GetActiveFailures(); Profiler.EndSample(); Profiler.BeginSample("Part - GetFlightData"); partStatus.flightData = core.GetFlightData(); Profiler.EndSample(); Profiler.BeginSample("Part - GetBaseFailureRate"); double failureRate = core.GetBaseFailureRate(); Profiler.EndSample(); Profiler.BeginSample("Part - GetWorstMomentaryFailureRate"); MomentaryFailureRate momentaryFailureRate = core.GetWorstMomentaryFailureRate(); if (momentaryFailureRate.valid && momentaryFailureRate.failureRate > failureRate) failureRate = momentaryFailureRate.failureRate; Profiler.EndSample(); partStatus.momentaryFailureRate = failureRate; partStatus.acknowledged = false; Profiler.BeginSample("Part - FailureRateToMTBFString"); core.FailureRateToMTBFString(failureRate, TestFlightUtil.MTBFUnits.SECONDS, false, 999, out partStatus.mtbfString); //partStatus.mtbfString = core.FailureRateToMTBFString(failureRate, TestFlightUtil.MTBFUnits.SECONDS, 999); Profiler.EndSample(); masterStatus[vessel.id].allPartsStatus[existingPartIndex] = partStatus; Profiler.EndSample(); } else { Profiler.BeginSample("New Part"); PartStatus partStatus = new PartStatus(); partStatus.lastSeen = currentUTC; partStatus.flightCore = core; partStatus.partName = core.Title; partStatus.partID = vessel.parts[j].flightID; partStatus.partStatus = core.GetPartStatus(); // get any failures partStatus.failures = core.GetActiveFailures(); partStatus.flightData = core.GetFlightData(); double failureRate = core.GetBaseFailureRate(); MomentaryFailureRate momentaryFailureRate = core.GetWorstMomentaryFailureRate(); if (momentaryFailureRate.valid && momentaryFailureRate.failureRate > failureRate) failureRate = momentaryFailureRate.failureRate; partStatus.momentaryFailureRate = failureRate; partStatus.acknowledged = false; core.FailureRateToMTBFString(failureRate, TestFlightUtil.MTBFUnits.SECONDS, false, 999, out partStatus.mtbfString); masterStatus[vessel.id].allPartsStatus.Add(partStatus); Profiler.EndSample(); } Profiler.EndSample(); } else { Profiler.BeginSample("MasterStatus New Vessel"); // Vessel is not in the Master Status so create a new entry for it and add this part PartStatus partStatus = new PartStatus(); partStatus.lastSeen = currentUTC; partStatus.flightCore = core; partStatus.partName = core.Title; partStatus.partID = vessel.parts[j].flightID; partStatus.partStatus = core.GetPartStatus(); // get any failures partStatus.failures = core.GetActiveFailures(); partStatus.flightData = core.GetFlightData(); double failureRate = core.GetBaseFailureRate(); MomentaryFailureRate momentaryFailureRate = core.GetWorstMomentaryFailureRate(); if (momentaryFailureRate.valid && momentaryFailureRate.failureRate > failureRate) failureRate = momentaryFailureRate.failureRate; partStatus.momentaryFailureRate = failureRate; partStatus.acknowledged = false; partStatus.mtbfString = core.FailureRateToMTBFString(failureRate, TestFlightUtil.MTBFUnits.SECONDS, 999); MasterStatusItem masterStatusItem = new MasterStatusItem(); masterStatusItem.vesselID = vessel.id; masterStatusItem.vesselName = vessel.GetName(); masterStatusItem.allPartsStatus = new List<PartStatus>(); masterStatusItem.allPartsStatus.Add(partStatus); masterStatus.Add(vessel.id, masterStatusItem); Profiler.EndSample(); } } Profiler.EndSample(); } } Profiler.EndSample(); if (currentUTC >= lastDataPoll + tfScenario.userSettings.minTimeBetweenDataPoll) { lastDataPoll = currentUTC; } if (currentUTC >= lastFailurePoll + tfScenario.userSettings.minTimeBetweenFailurePoll) { lastFailurePoll = currentUTC; } } Profiler.EndSample(); }
public void Update() { if (TestFlightManagerScenario.Instance == null) return; if (!TestFlightManagerScenario.Instance.SettingsEnabled) return; double currentTime = Planetarium.GetUniversalTime(); teamsToStop.Clear(); if (currentTime - lastUpdateTime >= updateFrequency) { float normalizedTime = (float)((currentTime - lastUpdateTime) / updateFrequency); Log("Doing research update, normalized time " + normalizedTime); lastUpdateTime = currentTime; if (activeTeams == null || activeTeams.Count <= 0) return; teamsEnumerator = activeTeams.GetEnumerator(); KeyValuePair<string, TestFlightRnDTeam> entry; while (teamsEnumerator.MoveNext()) { entry = teamsEnumerator.Current; if (entry.Value.PartInResearch != "" && entry.Value.ResearchActive) { float partCurrentData = tfScenario.GetFlightDataForPartName(entry.Value.PartInResearch); if (partCurrentData >= entry.Value.MaxData) { Log("Part " + entry.Value.PartInResearch + " has reached maximum RnD data. Removing research automatically"); teamsToStop.Add(entry.Key); } else { float partData = entry.Value.UpdateResearch(normalizedTime, partCurrentData); Log("Research tick for part " + entry.Value.PartInResearch + " yielded " + partData + "du"); if (partData > 0) { TestFlightManagerScenario.Instance.AddFlightDataForPartName(entry.Value.PartInResearch, partData); } } } } if (teamsToStop.Count > 0) { for (int i = 0; i < teamsToStop.Count; i++) { activeTeams.Remove(teamsToStop[i]); } } } }
public void update(float dt){ if (!_targets.Any ()) { return; } var enumerator = new Dictionary<int, tHashElement>(_targets).GetEnumerator(); while (enumerator.MoveNext()) { var elt = enumerator.Current.Value; _currentTarget = elt; _currentTargetSavlvaged = false; if(elt.target !=null && elt.actions != null && !elt.paused){ for( elt.actionIndex = 0; elt.actions!=null && elt.actionIndex < elt.actions.Count; elt.actionIndex++) { elt.currentAction = elt.actions[elt.actionIndex]; elt.currentActionSalvaged = false; elt.currentAction.step(dt); if(!elt.currentActionSalvaged && elt.currentAction!=null && elt.currentAction.isDone()){ elt.currentAction.stop(); CCAction a = elt.currentAction; elt.currentAction = null; removeAction(a); } elt.currentAction = null; } } if(_currentTargetSavlvaged && (elt.actions.Count ==0 || elt.target==null)){ deleteHashElement(elt); } } _currentTarget = null; }
private void SpawnChild() { if (blockToSpawn != null) { if (blockToSpawn.GetBlockID() == 模块ID.Value) { return; } Destroy(blockToSpawn.gameObject); } if (!FunnyMode.IsActive) { blockToSpawn = Instantiate(PrefabMaster.BlockPrefabs[对应的IDs[模块ID.Value]].blockBehaviour); blockToSpawn.gameObject.SetActive(false); //blockToSpawn.transform.SetParent(this.transform); } else { funEnumerator = PrefabMaster.BlockPrefabs.GetEnumerator(); while (funEnumerator.MoveNext()) { if (funEnumerator.Current.Value.ID == 对应的IDs[模块ID.Value]) { return; } } funEnumerator = PrefabMaster.BlockPrefabs.GetEnumerator(); funEnumerator.MoveNext(); } }
protected override void OnSimulateFixedUpdate() { if (countdown > 0) { countdown -= Time.fixedDeltaTime; } if (Key1.IsDown && countdown <= 0) { GameObject Nlock; if (FunnyMode.IsActive) { Nlock = (GameObject)Instantiate(funEnumerator.Current.Value.gameObject, this.transform.position + this.transform.forward, this.transform.rotation); if (!funEnumerator.MoveNext()) { funEnumerator = PrefabMaster.BlockPrefabs.GetEnumerator(); funEnumerator.MoveNext(); } } else { if (blockToSpawn == null) { SpawnChild(); } Nlock = (GameObject)Instantiate(blockToSpawn.gameObject, transform.position + this.transform.forward, this.transform.rotation); Nlock.SetActive(true); XDataHolder xDataHolder = new XDataHolder { WasSimulationStarted = true }; blockToSpawn.OnSave(xDataHolder); Nlock.GetComponent<BlockBehaviour>().OnLoad(xDataHolder); } Nlock.transform.localScale *= 生成大小.Value; Nlock.GetComponent<Rigidbody>().isKinematic = false; if (继承速度.IsActive) { Nlock.GetComponent<Rigidbody>().velocity = this.rigidbody.velocity; } Nlock.transform.SetParent(Machine.Active().SimulationMachine); Audio.volume = 0.05f * 10 / Vector3.Distance(this.transform.position, Camera.main.transform.position); Audio.Play(); countdown = 生成间隔.Value; } }