40 lines
2.4 KiB
Python
40 lines
2.4 KiB
Python
"""Execute the production report ledger; native scheduler coverage is separate."""
|
|
from pathlib import Path
|
|
from policy_harness import body, run
|
|
r=Path(__file__).resolve().parents[1]
|
|
p=r/'addons/ai/Scripts/Game/ERR/ERR_MortarReportLedger.c'
|
|
a=body(p,'bool Available(').replace('m_Attempts.', 'm_Attempts.')
|
|
c=body(p,'bool Claim(')
|
|
run('''#include <cassert>
|
|
#include <map>
|
|
#include <iterator>
|
|
struct Entries {std::map<int,float> entries; int Count(){return entries.size();}
|
|
int GetKey(int i){return std::next(entries.begin(),i)->first;}
|
|
float GetElement(int i){return std::next(entries.begin(),i)->second;}
|
|
void Remove(int key){entries.erase(key);} bool Contains(int key){return entries.count(key);}
|
|
void Insert(int key,float time){entries.emplace(key,time);}};
|
|
struct ERR_MortarPrediction {static constexpr float MAX_REPORT_AGE_MS=60000;};
|
|
struct Ledger {Entries m_Attempts;
|
|
'''+a.replace('ERR_MortarPrediction.', 'ERR_MortarPrediction::')+c+'''};
|
|
int main(){
|
|
Ledger a; assert(a.Available(1,0,0));assert(a.Available(1,0,10)); // unavailable radio must not claim
|
|
assert(a.Claim(1,0,100));assert(!a.Available(1,0,200));assert(!a.Claim(1,0,50000));
|
|
assert(!a.Claim(1,10000,50000)); // rewritten timestamp cannot refresh same message
|
|
assert(a.Claim(2,200,300));assert(!a.Claim(1,0,60000)); // A/B/A replay
|
|
assert(!a.Available(1,0,60001));assert(a.Claim(3,60001,60001));
|
|
assert(a.m_Attempts.Count()==2);assert(a.Claim(4,60300,60300));assert(a.m_Attempts.Count()==2);
|
|
assert(!a.Claim(0,0,0));assert(!a.Claim(-1,0,0));assert(!a.Claim(5,-1,0));
|
|
assert(!a.Claim(5,100,99));assert(!a.Claim(5,0,60001));
|
|
Ledger bounded;for(int i=1;i<=128;i++)assert(bounded.Claim(i,0,0));
|
|
assert(!bounded.Claim(129,1,1));assert(bounded.Claim(130,60001,60001));assert(bounded.m_Attempts.Count()==1);
|
|
Ledger nextRound;assert(nextRound.Claim(1,0,0));
|
|
}
|
|
''')
|
|
b=r/'addons/ai/Scripts/Game/ERR/ERR_MortarBattery.c';s=r/'addons/ai/Scripts/Game/ERR/ERR_MortarSystem.c'
|
|
request=body(b,'bool BeginRequest(')
|
|
assert request.index('m_ReportLedger.Claim(')<request.index('Cancel(')<request.index('OrderId++')
|
|
assert 'm_ReportLedger' not in body(b,'void Cancel(')
|
|
tick=body(s,'void Tick(')
|
|
assert tick.index('battery.CanRequest(report, now)')<tick.index('m_HQ.Downlink(')<tick.index('selected.BeginRequest(')
|
|
print('PASS: actual mortar report ledger prevents duplicate response after cancellation, expiry and interleaved reports; native scheduler separate')
|