kOS.Module.kOSProcessor.ProcessElectricity C# (CSharp) Method

ProcessElectricity() private method

private ProcessElectricity ( Part partObj, float time ) : void
partObj Part
time float
return void
        private void ProcessElectricity(Part partObj, float time)
        {
            if (ProcessorMode == ProcessorModes.OFF) return;

            double volumePower = 0;
            if (shared.VolumeMgr.CheckCurrentVolumeRange())
            {
                // If the current volume is in range, check the capacity and calculate power
                var volume = shared.VolumeMgr.CurrentVolume;
                if (volume.Name == "Archive")
                {
                    volumePower = ARCHIVE_EFFECTIVE_BYTES * ECPerBytePerSecond;
                }
                else
                {
                    volumePower = volume.Capacity * ECPerBytePerSecond;
                }
            }
            else
            {
                // if the volume isn't in range, assume it doesn't consume any power
                volumePower = 0;
            }

            if (ProcessorMode == ProcessorModes.STARVED)
            {
                // If the processor is STARVED, check to see if there is enough EC to turn it back on.
                var request = averagePower.Mean;  // use the average power draw as a baseline of the power needed to restart.
                if (request > 0)
                {
                    var available = partObj.RequestResource("ElectricCharge", request);
                    if (available / request > 0.5)
                    {
                        SetMode(ProcessorModes.READY);
                    }
                    // Since we're just checking to see if there is enough power to restart, return
                    // the consumed EC.  The actual demand value will be drawn on the next update after
                    // the cpu boots.  This should give the ship a chance to collect a little more EC
                    // before the cpu actually boots.
                    partObj.RequestResource("ElectricCharge", -available);
                }
                else
                {
                    // If there is no historical power request, simply turn the processor back on.  This
                    // should not be possible, since it means that some how the processor got set to
                    // the STARVED mode, even though no power was requested.
                    SetMode(ProcessorModes.READY);
                }
                RequiredPower = (float)request; // Make sure RequiredPower matches the average.
            }
            else
            {
                // Because the processor is not STARVED, evaluate the power requirement based on actual operation.
                // For EC drain purposes, always pretend atleast 1 instruction happened, so idle drain isn't quite zero:
                int instructions = System.Math.Max(shared.Cpu.InstructionsThisUpdate, 1);
                var request = volumePower * time + instructions * ECPerInstruction;
                if (request > 0)
                {
                    // only check the available EC if the request is greater than 0EC.  If the request value
                    // is zero, then available will always be zero and it appears that mono/.net treat
                    // "0 / 0" as equaling "0", which prevents us from checking the ratio.  Since getting
                    // "0" available of "0" requested is a valid state, the processor mode is only evaluated
                    // if request is greater than zero.
                    var available = partObj.RequestResource("ElectricCharge", request);
                    if (available / request < 0.5)
                    {
                        // 0.5 is an arbitrary ratio for triggering the STARVED mode.  It allows for some
                        // fluctuation away from the exact requested EC, ando adds some fuzzy math to how
                        // we deal with the descreet physics frames.  Essentially if there was enough power
                        // to run for half of a physics frame, the processor stays on.
                        SetMode(ProcessorModes.STARVED);
                    }
                }
                // Set RequiredPower to the average requested power.  This should help "de-bounce" the value
                // so that it doesn't fluctuate wildly (between 0.2 and 0.000001 in a single frame for example)
                RequiredPower = (float)averagePower.Update(request) / TimeWarp.fixedDeltaTime;
            }
        }