private IEnumerator Transmit() { var msg = new ScreenMessage(String.Format("[{0}]: Starting Transmission...", part.partInfo.title), 4f, ScreenMessageStyle.UPPER_LEFT); var msg_status = new ScreenMessage(String.Empty, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(msg); mBusy = true; while (mQueue.Any()) { RnDCommsStream commStream = null; var science_data = mQueue[0]; var data_amount = science_data.dataAmount; mQueue.RemoveAt(0); var subject = ResearchAndDevelopment.GetSubjectByID(science_data.subjectID); int packets = Mathf.CeilToInt(science_data.dataAmount / PacketSize); if (ResearchAndDevelopment.Instance != null) { // pre calculate the time interval - fix for x64 systems // workaround for issue #136 float time1 = Time.time; yield return(new WaitForSeconds(PacketInterval)); // get the delta time float x64PacketInterval = (Time.time - time1); RTLog.Notify("Changing RnDCommsStream timeout from {0} to {1}", PacketInterval, x64PacketInterval); commStream = new RnDCommsStream(subject, science_data.dataAmount, x64PacketInterval, science_data.transmitValue, ResearchAndDevelopment.Instance); } //StartCoroutine(SetFXModules_Coroutine(modules_progress, 0.0f)); float power = 0; while (packets > 0) { power += part.RequestResource("ElectricCharge", PacketResourceCost - power); if (power >= PacketResourceCost * 0.95) { float frame = Math.Min(PacketSize, data_amount); power -= PacketResourceCost; GUI_Status = "Uploading Data..."; data_amount -= frame; packets--; float progress = (science_data.dataAmount - data_amount) / science_data.dataAmount; //StartCoroutine(SetFXModules_Coroutine(modules_progress, progress)); msg_status.message = String.Format("[{0}]: Uploading Data... {1}", part.partInfo.title, progress.ToString("P0")); RTLog.Notify("[Transmitter]: Uploading Data... ({0}) - {1} Mits/sec. Packets to go: {2} - Files to Go: {3}", science_data.title, (PacketSize / PacketInterval).ToString("0.00"), packets, mQueue.Count); ScreenMessages.PostScreenMessage(msg_status, true); if (commStream != null) { commStream.StreamData(frame); } } else { msg.message = String.Format("<b><color=orange>[{0}]: Warning! Not Enough {1}!</color></b>", part.partInfo.title, RequiredResource); ScreenMessages.PostScreenMessage(msg, true); GUI_Status = String.Format("{0}/{1} {2}", power, PacketResourceCost, RequiredResource); } yield return(new WaitForSeconds(PacketInterval)); } yield return(new WaitForSeconds(PacketInterval * 2)); } mBusy = false; msg.message = String.Format("[{0}]: Done!", part.partInfo.title); ScreenMessages.PostScreenMessage(msg, true); GUI_Status = "Idle"; yield break; }
private IEnumerator Transmit(Callback callback = null) { RTLog.Notify("ModuleRTDataTransmitter::Transmit"); var msg = new ScreenMessage(String.Format("[{0}]: Starting Transmission...", part.partInfo.title), 4f, ScreenMessageStyle.UPPER_LEFT); var msgStatus = new ScreenMessage(String.Empty, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(msg); isBusy = true; while (scienceDataQueue.Any()) { var scienceData = scienceDataQueue[0]; var dataAmount = scienceData.dataAmount; scienceDataQueue.RemoveAt(0); bool aborted = false; var subject = ResearchAndDevelopment.GetSubjectByID(scienceData.subjectID); if (subject == null) { subject = new ScienceSubject("", "", 1, 0, 0); } int packets = Mathf.CeilToInt(scienceData.dataAmount / PacketSize); RnDCommsStream commStream = null; if (ResearchAndDevelopment.Instance != null && !scienceData.triggered) { // pre-calculate the time interval - fix for x64 systems // workaround for issue #136 //float time1 = Time.time; //yield return new WaitForSeconds(PacketInterval); // get the delta time //float x64PacketInterval = (Time.time - time1); //RTLog.Notify("Changing RnDCommsStream timeout from {0} to {1}", PacketInterval, x64PacketInterval); //(porting to 1.2): check if scienceData.baseTransmitValue alone or with scienceData.transmitBonus //commStream = new RnDCommsStream(subject, scienceData.dataAmount, x64PacketInterval, commStream = new RnDCommsStream(subject, scienceData.dataAmount, PacketInterval, scienceData.baseTransmitValue, false, ResearchAndDevelopment.Instance); } //StartCoroutine(SetFXModules_Coroutine(modules_progress, 0.0f)); float power = 0; timeElapsed = 0; while (packets > 0) { if (timeElapsed >= PacketInterval) { timeElapsed -= PacketInterval; power += part.RequestResource("ElectricCharge", PacketResourceCost - power); if (power >= PacketResourceCost * 0.95) { GUIStatus = "Uploading Data..."; // remove some power due to transmission power -= PacketResourceCost; // transmitted size float frame = Math.Min(PacketSize, dataAmount); // subtract current packet size from data left to transmit // and clamp it to 1 digit precision to avoid large float precision error (#667) dataAmount -= frame; dataAmount = (float)Math.Round(dataAmount, 1); packets--; float progress = (scienceData.dataAmount - dataAmount) / scienceData.dataAmount; msgStatus.message = String.Format("[{0}]: Uploading Data... {1:P0}", part.partInfo.title, progress); ScreenMessages.PostScreenMessage(msgStatus); RTLog.Notify("[Transmitter]: Uploading Data... ({0}) - {1} Mits/sec. Packets to go: {2} - Other experiments waiting to transfer: {3}", scienceData.title, (PacketSize / PacketInterval).ToString("0.00"), packets, scienceDataQueue.Count); // if we've a defined callback parameter so skip to stream each packet if (commStream != null) { RTLog.Notify( "[Transmitter]: PacketSize: {0}; Transmitted size (frame): {1}; Data left to transmit (dataAmount): {2}; Packets left (packets): {3}", PacketSize, frame, dataAmount, packets); // use try / catch to prevent NRE spamming in KSP code when RT is used with other mods. try { // check if it's the last packet to send if (packets == 0) { // issue #667, issue #714 ; floating point error in RnDCommsStream.StreamData method when adding to dataIn private field // e.g scienceData.dataAmount is 10 but in the end RnDCommsStream.dataIn will be 9.999999, so the science never // gets registered to the ResearchAndDevelopment center. // Let's just go ahead and send the full amount so there's no question if we sent it all // KSP will clamp the final size to PacketSize anyway. frame = scienceData.dataAmount; } commStream.StreamData(frame, vessel.protoVessel); } catch (NullReferenceException nre) { RTLog.Notify("[Transmitter] A problem occurred during science transmission: {0}", RTLogLevel.LVL2, nre); } } else { RTLog.Notify("[Transmitter]: [DEBUG] commstream is null and no callback"); } } else { // not enough power msg.message = String.Format("<b><color=orange>[{0}]: Warning! Not Enough {1}!</color></b>", part.partInfo.title, RequiredResource); ScreenMessages.PostScreenMessage(msg); aborted = true; GUIStatus = String.Format("{0}/{1} {2}", power, PacketResourceCost, RequiredResource); } } yield return(new WaitForFixedUpdate()); } // effectively inform the game that science has been transmitted if (scienceData.triggered) { GameEvents.OnTriggeredDataTransmission.Fire(scienceData, vessel, aborted); } yield return(new WaitForSeconds(PacketInterval * 2)); } isBusy = false; msg.message = String.Format("[{0}]: Done!", part.partInfo.title); ScreenMessages.PostScreenMessage(msg); if (callback != null) { callback.Invoke(); } GUIStatus = "Idle"; }
private IEnumerator Transmit(Callback callback = null) { RTLog.Notify("ModuleRTDataTransmitter::Transmit"); var msg = new ScreenMessage(String.Format("[{0}]: Starting Transmission...", part.partInfo.title), 4f, ScreenMessageStyle.UPPER_LEFT); var msgStatus = new ScreenMessage(String.Empty, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(msg); isBusy = true; while (scienceDataQueue.Any()) { var scienceData = scienceDataQueue[0]; var dataAmount = scienceData.dataAmount; scienceDataQueue.RemoveAt(0); scienceData.triggered = true; var subject = ResearchAndDevelopment.GetSubjectByID(scienceData.subjectID); if (subject == null) subject = new ScienceSubject("", "", 1, 0, 0); int packets = Mathf.CeilToInt(scienceData.dataAmount / PacketSize); RnDCommsStream commStream = null; if (ResearchAndDevelopment.Instance != null) { // pre-calculate the time interval - fix for x64 systems // workaround for issue #136 float time1 = Time.time; yield return new WaitForSeconds(PacketInterval); // get the delta time float x64PacketInterval = (Time.time - time1); RTLog.Notify("Changing RnDCommsStream timeout from {0} to {1}", PacketInterval, x64PacketInterval); //TODO (porting to 1.2): check if scienceData.baseTransmitValue alone or with scienceData.transmitBonus commStream = new RnDCommsStream(subject, scienceData.dataAmount, x64PacketInterval, scienceData.baseTransmitValue, false, ResearchAndDevelopment.Instance); } //StartCoroutine(SetFXModules_Coroutine(modules_progress, 0.0f)); float power = 0; while (packets > 0) { power += part.RequestResource("ElectricCharge", PacketResourceCost - power); if (power >= PacketResourceCost * 0.95) { GUIStatus = "Uploading Data..."; // remove some power due to transmission power -= PacketResourceCost; // transmitted size float frame = Math.Min(PacketSize, dataAmount); // subtract current packet size from data left to transmit // and clamp it to 1 digit precision to avoid large float precision error (#667) dataAmount -= frame; dataAmount = (float)Math.Round(dataAmount, 1); packets--; float progress = (scienceData.dataAmount - dataAmount) / scienceData.dataAmount; msgStatus.message = String.Format("[{0}]: Uploading Data... {1:P0}", part.partInfo.title, progress); ScreenMessages.PostScreenMessage(msgStatus); RTLog.Notify("[Transmitter]: Uploading Data... ({0}) - {1} Mits/sec. Packets to go: {2} - Other experiments waiting to transfer: {3}", scienceData.title, (PacketSize / PacketInterval).ToString("0.00"), packets, scienceDataQueue.Count); // if we've a defined callback parameter so skip to stream each packet if (commStream != null && callback == null) { RTLog.Notify( "[Transmitter]: PacketSize: {0}; Transmitted size (frame): {1}; Data left to transmit (dataAmount): {2}; Packets left (packets): {3}", PacketSize, frame, dataAmount, packets); // use try / catch to prevent NRE spamming in KSP code when RT is used with other mods. try { commStream.StreamData(frame, vessel.protoVessel); } catch (NullReferenceException nre) { RTLog.Notify("A problem occurred during science transmission: {0}", RTLogLevel.LVL2, nre); } // TODO: remove this when fixed in stock // Fix a problem in stock KSP (discovered in 1.1.3, and still here in 1.2.1) // issue #667 ; floating point error in RnDCommsStream.StreamData method when adding to dataIn private field // e.g scienceData.dataAmount is 10 but in the end RnDCommsStream.dataIn will be 9.999999, so the science never // gets registered to the ResearchAndDevelopment center. if (packets == 0) // check that we have no packet left to send. { // get the private field (dataIn) in RnDCommsStream. This field is subject to floating point rounding error // We handle this problem on our side. var dataIn = RTUtil.GetInstanceField(typeof(RnDCommsStream), commStream, "dataIn"); if (dataIn != null) { // check if we have a delta (e.g. 10 - 9.999999999 will give us a tiny delta) var delta = scienceData.dataAmount - (float) dataIn; RTLog.Notify("[Transmitter]: delta: {0}", delta); // the delta must be positive and less than this constant to push / transmit the remaining size. // This prevent us pushing packets with too much leftover to transmit (e.g if there was a connection loss). if ((delta > 0f) && (delta <= PacketRemainingSize)) { try { // we have a delta, try to send the remaining little bit of science commStream.StreamData(delta, vessel.protoVessel); } catch (NullReferenceException nre) { RTLog.Notify("A problem occurred during science transmission (delta): {0}", RTLogLevel.LVL2, nre); } } } else { RTLog.Notify("[Transmitter]: dataIn is null."); } } // end stock fix } else { RTLog.Notify("[Transmitter]: [DEBUG] commstream is null and no callback"); } } else { // not enough power msg.message = String.Format("<b><color=orange>[{0}]: Warning! Not Enough {1}!</color></b>", part.partInfo.title, RequiredResource); ScreenMessages.PostScreenMessage(msg); GUIStatus = String.Format("{0}/{1} {2}", power, PacketResourceCost, RequiredResource); } yield return new WaitForSeconds(PacketInterval); } // effectively inform the game that science has been transmitted GameEvents.OnTriggeredDataTransmission.Fire(scienceData, vessel, false); yield return new WaitForSeconds(PacketInterval * 2); } isBusy = false; msg.message = String.Format("[{0}]: Done!", part.partInfo.title); ScreenMessages.PostScreenMessage(msg); if (callback != null) callback.Invoke(); GUIStatus = "Idle"; }
private IEnumerator Transmit() { var msg = new ScreenMessage(String.Format("[{0}]: Starting Transmission...", part.partInfo.title), 4f, ScreenMessageStyle.UPPER_LEFT); var msg_status = new ScreenMessage(String.Empty, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(msg); mBusy = true; while (mQueue.Any()) { RnDCommsStream commStream = null; var science_data = mQueue[0]; var data_amount = science_data.dataAmount; mQueue.RemoveAt(0); var subject = ResearchAndDevelopment.GetSubjectByID(science_data.subjectID); int packets = Mathf.CeilToInt(science_data.dataAmount / PacketSize); if (ResearchAndDevelopment.Instance != null) { commStream = new RnDCommsStream(subject, science_data.dataAmount, PacketInterval, science_data.transmitValue, ResearchAndDevelopment.Instance); } //StartCoroutine(SetFXModules_Coroutine(modules_progress, 0.0f)); float power = 0; while (packets > 0) { power += part.RequestResource("ElectricCharge", PacketResourceCost - power); if (power >= PacketResourceCost * 0.95) { float frame = Math.Min(PacketSize, data_amount); power -= PacketResourceCost; GUI_Status = "Uploading Data..."; data_amount -= frame; packets--; float progress = (science_data.dataAmount - data_amount) / science_data.dataAmount; //StartCoroutine(SetFXModules_Coroutine(modules_progress, progress)); msg_status.message = String.Format("[{0}]: Uploading Data... {1}", part.partInfo.title, progress.ToString("P0")); RTLog.Notify("[Transmitter]: Uploading Data... ({0}) - {1} Mits/sec. Packets to go: {2} - Files to Go: {3}", science_data.title, (PacketSize / PacketInterval).ToString("0.00"), packets, mQueue.Count); ScreenMessages.PostScreenMessage(msg_status, true); if (commStream != null) { commStream.StreamData(frame); } } else { msg.message = String.Format("<b><color=orange>[{0}]: Warning! Not Enough {1}!</color></b>", part.partInfo.title, RequiredResource); ScreenMessages.PostScreenMessage(msg, true); GUI_Status = String.Format("{0}/{1} {2}", power, PacketResourceCost, RequiredResource); } yield return new WaitForSeconds(PacketInterval); } yield return new WaitForSeconds(PacketInterval * 2); } mBusy = false; msg.message = String.Format("[{0}]: Done!", part.partInfo.title); ScreenMessages.PostScreenMessage(msg, true); GUI_Status = "Idle"; yield break; }
private IEnumerator Transmit(Callback callback = null) { RTLog.Notify("ModuleRTDataTransmitter::Transmit"); var msg = new ScreenMessage(String.Format("[{0}]: Starting Transmission...", part.partInfo.title), 4f, ScreenMessageStyle.UPPER_LEFT); var msgStatus = new ScreenMessage(String.Empty, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(msg); isBusy = true; while (scienceDataQueue.Any()) { var scienceData = scienceDataQueue[0]; var dataAmount = scienceData.dataAmount; scienceDataQueue.RemoveAt(0); scienceData.triggered = true; var subject = ResearchAndDevelopment.GetSubjectByID(scienceData.subjectID); if (subject == null) { subject = new ScienceSubject("", "", 1, 0, 0); } int packets = Mathf.CeilToInt(scienceData.dataAmount / PacketSize); RnDCommsStream commStream = null; if (ResearchAndDevelopment.Instance != null) { // pre-calculate the time interval - fix for x64 systems // workaround for issue #136 float time1 = Time.time; yield return(new WaitForSeconds(PacketInterval)); // get the delta time float x64PacketInterval = (Time.time - time1); RTLog.Notify("Changing RnDCommsStream timeout from {0} to {1}", PacketInterval, x64PacketInterval); //TODO (porting to 1.2): check if scienceData.baseTransmitValue alone or with scienceData.transmitBonus commStream = new RnDCommsStream(subject, scienceData.dataAmount, x64PacketInterval, scienceData.baseTransmitValue, false, ResearchAndDevelopment.Instance); } //StartCoroutine(SetFXModules_Coroutine(modules_progress, 0.0f)); float power = 0; while (packets > 0) { power += part.RequestResource("ElectricCharge", PacketResourceCost - power); if (power >= PacketResourceCost * 0.95) { GUIStatus = "Uploading Data..."; // remove some power due to transmission power -= PacketResourceCost; // transmitted size float frame = Math.Min(PacketSize, dataAmount); // subtract current packet size from data left to transmit // and clamp it to 1 digit precision to avoid large float precision error (#667) dataAmount -= frame; dataAmount = (float)Math.Round(dataAmount, 1); packets--; float progress = (scienceData.dataAmount - dataAmount) / scienceData.dataAmount; msgStatus.message = String.Format("[{0}]: Uploading Data... {1:P0}", part.partInfo.title, progress); ScreenMessages.PostScreenMessage(msgStatus); RTLog.Notify("[Transmitter]: Uploading Data... ({0}) - {1} Mits/sec. Packets to go: {2} - Other experiments waiting to transfer: {3}", scienceData.title, (PacketSize / PacketInterval).ToString("0.00"), packets, scienceDataQueue.Count); // if we've a defined callback parameter so skip to stream each packet if (commStream != null && callback == null) { RTLog.Notify( "[Transmitter]: PacketSize: {0}; Transmitted size (frame): {1}; Data left to transmit (dataAmount): {2}; Packets left (packets): {3}", PacketSize, frame, dataAmount, packets); // use try / catch to prevent NRE spamming in KSP code when RT is used with other mods. try { commStream.StreamData(frame, vessel.protoVessel); } catch (NullReferenceException nre) { RTLog.Notify("A problem occurred during science transmission: {0}", RTLogLevel.LVL2, nre); } // TODO: remove this when fixed in stock // Fix a problem in stock KSP (discovered in 1.1.3, and still here in 1.2.1) // issue #667 ; floating point error in RnDCommsStream.StreamData method when adding to dataIn private field // e.g scienceData.dataAmount is 10 but in the end RnDCommsStream.dataIn will be 9.999999, so the science never // gets registered to the ResearchAndDevelopment center. if (packets == 0) // check that we have no packet left to send. { // get the private field (dataIn) in RnDCommsStream. This field is subject to floating point rounding error // We handle this problem on our side. var dataIn = RTUtil.GetInstanceField(typeof(RnDCommsStream), commStream, "dataIn"); if (dataIn != null) { // check if we have a delta (e.g. 10 - 9.999999999 will give us a tiny delta) var delta = scienceData.dataAmount - (float)dataIn; RTLog.Notify("[Transmitter]: delta: {0}", delta); // the delta must be positive and less than this constant to push / transmit the remaining size. // This prevent us pushing packets with too much leftover to transmit (e.g if there was a connection loss). if ((delta > 0f) && (delta <= PacketRemainingSize)) { try { // we have a delta, try to send the remaining little bit of science commStream.StreamData(delta, vessel.protoVessel); } catch (NullReferenceException nre) { RTLog.Notify("A problem occurred during science transmission (delta): {0}", RTLogLevel.LVL2, nre); } } } else { RTLog.Notify("[Transmitter]: dataIn is null."); } } // end stock fix } else { RTLog.Notify("[Transmitter]: [DEBUG] commstream is null and no callback"); } } else { // not enough power msg.message = String.Format("<b><color=orange>[{0}]: Warning! Not Enough {1}!</color></b>", part.partInfo.title, RequiredResource); ScreenMessages.PostScreenMessage(msg); GUIStatus = String.Format("{0}/{1} {2}", power, PacketResourceCost, RequiredResource); } yield return(new WaitForSeconds(PacketInterval)); } // effectively inform the game that science has been transmitted GameEvents.OnTriggeredDataTransmission.Fire(scienceData, vessel, false); yield return(new WaitForSeconds(PacketInterval * 2)); } isBusy = false; msg.message = String.Format("[{0}]: Done!", part.partInfo.title); ScreenMessages.PostScreenMessage(msg); if (callback != null) { callback.Invoke(); } GUIStatus = "Idle"; }
private IEnumerator Transmit(Callback callback = null) { var msg = new ScreenMessage(String.Format("[{0}]: Starting Transmission...", part.partInfo.title), 4f, ScreenMessageStyle.UPPER_LEFT); var msgStatus = new ScreenMessage(String.Empty, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(msg); isBusy = true; while (scienceDataQueue.Any()) { RnDCommsStream commStream = null; var scienceData = scienceDataQueue[0]; var dataAmount = scienceData.dataAmount; scienceDataQueue.RemoveAt(0); var subject = ResearchAndDevelopment.GetSubjectByID(scienceData.subjectID); int packets = Mathf.CeilToInt(scienceData.dataAmount / PacketSize); if (ResearchAndDevelopment.Instance != null) { // pre calculate the time interval - fix for x64 systems // workaround for issue #136 float time1 = Time.time; yield return new WaitForSeconds(PacketInterval); // get the delta time float x64PacketInterval = (Time.time - time1); RTLog.Notify("Changing RnDCommsStream timeout from {0} to {1}", PacketInterval, x64PacketInterval); commStream = new RnDCommsStream(subject, scienceData.dataAmount, x64PacketInterval, scienceData.transmitValue, false, ResearchAndDevelopment.Instance); } //StartCoroutine(SetFXModules_Coroutine(modules_progress, 0.0f)); float power = 0; while (packets > 0) { power += part.RequestResource("ElectricCharge", PacketResourceCost - power); if (power >= PacketResourceCost * 0.95) { float frame = Math.Min(PacketSize, dataAmount); power -= PacketResourceCost; GUIStatus = "Uploading Data..."; dataAmount -= frame; packets--; float progress = (scienceData.dataAmount - dataAmount) / scienceData.dataAmount; //StartCoroutine(SetFXModules_Coroutine(modules_progress, progress)); msgStatus.message = String.Format("[{0}]: Uploading Data... {1}", part.partInfo.title, progress.ToString("P0")); RTLog.Notify("[Transmitter]: Uploading Data... ({0}) - {1} Mits/sec. Packets to go: {2} - Files to Go: {3}", scienceData.title, (PacketSize / PacketInterval).ToString("0.00"), packets, scienceDataQueue.Count); ScreenMessages.PostScreenMessage(msgStatus, true); // if we've a defined callback parameter so skip to stream each packet if (commStream != null && callback == null) { commStream.StreamData(frame, vessel.protoVessel); } } else { msg.message = String.Format("<b><color=orange>[{0}]: Warning! Not Enough {1}!</color></b>", part.partInfo.title, RequiredResource); ScreenMessages.PostScreenMessage(msg, true); GUIStatus = String.Format("{0}/{1} {2}", power, PacketResourceCost, RequiredResource); } yield return new WaitForSeconds(PacketInterval); } yield return new WaitForSeconds(PacketInterval * 2); } isBusy = false; msg.message = String.Format("[{0}]: Done!", part.partInfo.title); ScreenMessages.PostScreenMessage(msg, true); if (callback != null) callback.Invoke(); GUIStatus = "Idle"; }