solarsystemInterferenceState.py (6308B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\solarsysteminterference\solarsystemInterferenceState.py 2 from carbon.common.lib.const import SEC 3 from solarsysteminterference.const import INTERFERENCE_BAND_NONE, INTERFERENCE_BAND_LOW, INTERFERENCE_BAND_MEDIUM, INTERFERENCE_BAND_HIGH, INTERFERENCE_BAND_HIGH_THRESHOLD, INTERFERENCE_BAND_MEDIUM_THRESHOLD 4 5 class SolarsystemInterferenceState(object): 6 7 def __init__(self, interferenceLevel, lastDecayTickTimestamp, interferenceDecreasePerDecayTick, decayTickPeriod, maxInterferenceLevel, quiescentInterferenceLevel): 8 if interferenceDecreasePerDecayTick <= 0: 9 raise ValueError('interferenceDecreasePerDecayTick must be greater than 0') 10 if decayTickPeriod <= 0: 11 raise ValueError('decayTickPeriod must be greater than 0') 12 if maxInterferenceLevel <= quiescentInterferenceLevel: 13 raise ValueError('maxInterferenceLevel must be greater than quiescentInterferenceLevel') 14 if interferenceLevel > maxInterferenceLevel: 15 raise ValueError('interferenceLevel (%.2f) must be less than or equal to maxInterferenceLevel (%.2f)' % (interferenceLevel, maxInterferenceLevel)) 16 if interferenceLevel < quiescentInterferenceLevel: 17 raise ValueError('interferenceLevel (%.2f) must be greater than or equal to quiescentInterferenceLevel (%.2f)' % (interferenceLevel, quiescentInterferenceLevel)) 18 self._interferenceLevel = interferenceLevel 19 self._lastDecayTickTimestamp = lastDecayTickTimestamp 20 self._interferenceDecreasePerDecayTick = interferenceDecreasePerDecayTick 21 self._decayTickPeriod = decayTickPeriod 22 self._maxInterferenceLevel = maxInterferenceLevel 23 self._quiescentInterferenceLevel = quiescentInterferenceLevel 24 25 def __repr__(self): 26 return 'SolarsystemInterferenceState(interferenceLevel=%r, lastDecayTickTimestamp=%r, interferenceDecreasePerDecayTick=%r, decayTickPeriod=%r, maxInterferenceLevel=%r, quiescentInterferenceLevel=%r)' % (self._interferenceLevel, 27 self._lastDecayTickTimestamp, 28 self._interferenceDecreasePerDecayTick, 29 self._decayTickPeriod, 30 self._maxInterferenceLevel, 31 self._quiescentInterferenceLevel) 32 33 def __eq__(self, other): 34 if other is None: 35 return False 36 return self._interferenceLevel == other._interferenceLevel and self._lastDecayTickTimestamp == other._lastDecayTickTimestamp and self._interferenceDecreasePerDecayTick == other._interferenceDecreasePerDecayTick and self._decayTickPeriod == other._decayTickPeriod and self._maxInterferenceLevel == other._maxInterferenceLevel and self._quiescentInterferenceLevel == other._quiescentInterferenceLevel 37 38 @property 39 def interferenceLevel(self): 40 return self._interferenceLevel 41 42 @property 43 def lastDecayTickTimestamp(self): 44 return self._lastDecayTickTimestamp 45 46 @property 47 def interferenceDecreasePerDecayTick(self): 48 return self._interferenceDecreasePerDecayTick 49 50 @property 51 def decayTickPeriod(self): 52 return self._decayTickPeriod 53 54 @property 55 def maxInterferenceLevel(self): 56 return self._maxInterferenceLevel 57 58 @property 59 def quiescentInterferenceLevel(self): 60 return self._quiescentInterferenceLevel 61 62 @property 63 def isAtQuiescentLevel(self): 64 return self._interferenceLevel <= self._quiescentInterferenceLevel 65 66 @property 67 def interferenceRange(self): 68 return self._maxInterferenceLevel - self._quiescentInterferenceLevel 69 70 @property 71 def normalisedInterferenceLevel(self): 72 return (self._interferenceLevel - self._quiescentInterferenceLevel) / self.interferenceRange 73 74 @property 75 def interferenceBand(self): 76 if self.isAtQuiescentLevel: 77 return INTERFERENCE_BAND_NONE 78 normalisedInterferenceLevel = self.normalisedInterferenceLevel 79 if normalisedInterferenceLevel > INTERFERENCE_BAND_HIGH_THRESHOLD: 80 return INTERFERENCE_BAND_HIGH 81 if normalisedInterferenceLevel > INTERFERENCE_BAND_MEDIUM_THRESHOLD: 82 return INTERFERENCE_BAND_MEDIUM 83 return INTERFERENCE_BAND_LOW 84 85 def CanAffordCost(self, solarsystemInterferenceCost): 86 return self._interferenceLevel + solarsystemInterferenceCost <= self._maxInterferenceLevel 87 88 89 def _GetDecayResult(state, timestamp): 90 timeDelta = timestamp - state.lastDecayTickTimestamp 91 if timeDelta < 0: 92 raise ValueError('_GetDecayResult cannot be calculated for negative timeDelta') 93 numDecayTicks = timeDelta / (state.decayTickPeriod * SEC) 94 interferenceDecrease = numDecayTicks * state.interferenceDecreasePerDecayTick 95 newInterferenceLevel = max(state.quiescentInterferenceLevel, state.interferenceLevel - interferenceDecrease) 96 newDecayTickTimestamp = state.lastDecayTickTimestamp + numDecayTicks * state.decayTickPeriod * SEC 97 return (newInterferenceLevel, newDecayTickTimestamp) 98 99 100 def GetNewState(originalState, newInterferenceLevel, newDecayTickTimestamp): 101 return SolarsystemInterferenceState(newInterferenceLevel, newDecayTickTimestamp, originalState.interferenceDecreasePerDecayTick, originalState.decayTickPeriod, originalState.maxInterferenceLevel, originalState.quiescentInterferenceLevel) 102 103 104 def CalculateStateAtTime(state, timestamp): 105 if state.isAtQuiescentLevel: 106 return state 107 if timestamp < state.lastDecayTickTimestamp: 108 return state 109 newInterferenceLevel, newDecayTickTimestamp = _GetDecayResult(state, timestamp) 110 return GetNewState(state, newInterferenceLevel, newDecayTickTimestamp) 111 112 113 def CalculateStateAfterAddingInterferenceAtTime(state, interferenceIncrease, timestamp): 114 if interferenceIncrease <= 0.0: 115 raise ValueError('interferenceIncrease must be greater-than 0') 116 newInterferenceLevel, newDecayTickTimestamp = _GetDecayResult(state, timestamp) 117 stateAtTime = GetNewState(state, newInterferenceLevel, newDecayTickTimestamp) 118 if not stateAtTime.CanAffordCost(interferenceIncrease): 119 raise ExcessInterferenceError('Too much interference') 120 return GetNewState(state, newInterferenceLevel + interferenceIncrease, newDecayTickTimestamp) 121 122 123 class ExcessInterferenceError(Exception): 124 pass