51 lines
3.4 KiB
Python
51 lines
3.4 KiB
Python
"""Exercise production executor journey initialization, retry stability and leader inheritance."""
|
|
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::StartAction(')
|
|
b=s.index(' record.StopAtNode = false;',a)
|
|
method=s[a:b]+' return true;\n}\n'
|
|
code=r'''
|
|
#include "ClientlessTravelCost.h"
|
|
#include <cassert>
|
|
#include <cstdlib>
|
|
#include <unordered_map>
|
|
using uint32=unsigned;
|
|
#define TC_LOG_INFO(...) ((void)0)
|
|
struct Guid{unsigned id;unsigned GetCounter()const{return id;}};
|
|
struct Group{unsigned leader=29;Guid GetLeaderGUID(){return {leader};}}group;
|
|
struct Player{unsigned id=29;Guid GetGUID(){return {id};}Group*GetGroup(){return &group;}};
|
|
struct ClientlessAction{std::string Name="travel_to_node";std::unordered_map<std::string,std::string>Parameters{{"node","destination"}};};
|
|
enum class ClientlessActionExecutionState{Idle,Completed,Failed,SelectingTarget};
|
|
struct Graph{unsigned draws=0;auto NewJourneyCosts(){return ClientlessTravelCost::Sample({},++draws,.2f);}}graph;auto sClientlessTravelGraphMgr=&graph;
|
|
struct ClientlessActionExecutorMgr{
|
|
struct Record{ClientlessTravelCost::Profile JourneyCosts;std::string JourneyCostKey;bool HasJourneyCosts=false;struct{ClientlessActionExecutionState State=ClientlessActionExecutionState::Idle;}Status;};
|
|
std::unordered_map<unsigned,Record>_records;
|
|
bool StartAction(Player*,ClientlessAction const&,Record&);
|
|
};
|
|
'''+method+r'''
|
|
int main(){
|
|
ClientlessActionExecutorMgr m;Player leader;ClientlessAction action;auto& r=m._records[29];
|
|
m.StartAction(&leader,action,r);auto original=r.JourneyCosts;assert(graph.draws==1);
|
|
r.Status.State=ClientlessActionExecutionState::Failed;m.StartAction(&leader,action,r);
|
|
assert(graph.draws==1&&r.JourneyCosts.Factors==original.Factors);
|
|
r.Status.State=ClientlessActionExecutionState::SelectingTarget;m.StartAction(&leader,action,r);assert(graph.draws==1);
|
|
action.Parameters["node"]="another-destination";m.StartAction(&leader,action,r);assert(graph.draws==2);
|
|
r.Status.State=ClientlessActionExecutionState::Completed;m.StartAction(&leader,action,r);assert(graph.draws==3);
|
|
Player follower;follower.id=31;action.Parameters["route_source"]="29";auto& peer=m._records[31];
|
|
// Preferences are already inherited before a shared route is available.
|
|
m.StartAction(&follower,action,peer);assert(graph.draws==3&&peer.JourneyCosts.Factors==r.JourneyCosts.Factors);
|
|
action.Parameters.erase("route_source");peer.Status.State=ClientlessActionExecutionState::SelectingTarget;
|
|
m.StartAction(&follower,action,peer);assert(graph.draws==3&&peer.JourneyCosts.Seed==r.JourneyCosts.Seed);
|
|
// A forged/stale source from another group is not inherited.
|
|
group.leader=99;action.Parameters["route_source"]="29";peer.Status.State=ClientlessActionExecutionState::Completed;
|
|
m.StartAction(&follower,action,peer);assert(graph.draws==4&&peer.JourneyCosts.Seed!=r.JourneyCosts.Seed);
|
|
}
|
|
'''
|
|
with tempfile.TemporaryDirectory(prefix='vcore-journey-costs-') as d:
|
|
p=Path(d);(p/'test.cpp').write_text(code)
|
|
subprocess.run(['c++','-std=c++17','-I'+str(root/'src/server/game/World'),str(p/'test.cpp'),'-o',str(p/'test')],check=True)
|
|
subprocess.run([str(p/'test')],check=True)
|
|
print('Production journey initialization: new trip/new draw, stable retries, delayed leader route and group-safe modal inheritance passed.')
|