51 lines
2.6 KiB
Python
51 lines
2.6 KiB
Python
"""Exercise the production executor's safe-node stopping guard."""
|
|
from pathlib import Path
|
|
import subprocess,tempfile
|
|
root=Path(__file__).resolve().parents[2]
|
|
s=(root/'src/server/game/World/ClientlessActionExecutorMgr.cpp').read_text()
|
|
a=s.index('bool ClientlessActionExecutorMgr::RequestStopAtNode(')
|
|
b=s.index('\n}\n',a)+3
|
|
request=s[a:b]
|
|
a=s.index('bool ClientlessActionExecutorMgr::StartRouteStep(')
|
|
b=s.index(' if (record.RouteStep >= record.Route.size())',a)
|
|
guard=s[a:b]+' return false;\n}\n'
|
|
code=r'''
|
|
#include <cassert>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
using uint32=uint32_t;
|
|
enum class ClientlessActionExecutionState{Moving,Completed};
|
|
struct Player {bool transport=false,taxi=false,flying=false,teleport=false;bool GetTransport(){return transport;}bool IsInFlight(){return taxi;}bool IsFlying(){return flying;}bool IsBeingTeleported(){return teleport;}};
|
|
struct Record {
|
|
bool Active=true,StopAtNode=false,RescueActive=false;std::size_t RouteStep=1;
|
|
struct Step{std::string NodeKey;};std::vector<Step> Route{{"goldshire"}};
|
|
struct{ClientlessActionExecutionState State=ClientlessActionExecutionState::Moving;std::string Detail;}Status;
|
|
};
|
|
class ClientlessActionExecutorMgr {public:
|
|
std::unordered_map<uint32,Record> _records{{26,{}}};
|
|
bool RequestStopAtNode(uint32);bool StartRouteStep(Player*,uint32,Record&);
|
|
};
|
|
'''
|
|
code+=request+guard+r'''
|
|
int main(){
|
|
ClientlessActionExecutorMgr mgr;Player p;auto& r=mgr._records[26];
|
|
assert(mgr.RequestStopAtNode(26));assert(r.Active); // never cancels transit on request
|
|
p.transport=true;assert(!mgr.StartRouteStep(&p,26,r));assert(r.Active);p.transport=false;
|
|
p.taxi=true;assert(!mgr.StartRouteStep(&p,26,r));p.taxi=false;
|
|
p.flying=true;assert(!mgr.StartRouteStep(&p,26,r));p.flying=false;
|
|
p.teleport=true;assert(!mgr.StartRouteStep(&p,26,r));p.teleport=false;
|
|
assert(mgr.StartRouteStep(&p,26,r));assert(!r.Active&&r.Status.State==ClientlessActionExecutionState::Completed);
|
|
assert(!mgr.RequestStopAtNode(26)&&!mgr.RequestStopAtNode(99));
|
|
r.Active=true;r.Route[0].NodeKey="virtual_ground_exit";
|
|
assert(mgr.StartRouteStep(&p,26,r)); // finish at a safe road boundary before a stale flight
|
|
r.Active=true;r.Route[0].NodeKey="flight_location";assert(!mgr.StartRouteStep(&p,26,r));
|
|
}
|
|
'''
|
|
with tempfile.TemporaryDirectory(prefix='vcore-graph-handover-') as folder:
|
|
cpp=Path(folder)/'test.cpp';binary=Path(folder)/'test';cpp.write_text(code)
|
|
subprocess.run(['c++','-std=c++17',str(cpp),'-o',str(binary)],check=True)
|
|
subprocess.run([str(binary)],check=True)
|
|
print('Production graph handover waits for ship/taxi/flight/teleport and stops at safe road/node boundaries.')
|