Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
"""Execute production item-station lifecycle with modeled native subscriptions."""
|
||||
from policy_harness import ROOT, body, run
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_ItemStationLifecycle.c'
|
||||
code='\n'.join(body(p,x) for x in ['override void OnPostInit(', 'protected override void DelayedInit(', 'protected override void AddRemoveOnDamageStateChanged(', 'override void OnDelete('])
|
||||
code=code.replace('protected ','').replace('override ','').replace('IEntity owner','IEntity* owner')
|
||||
for name in ['owner','m_ERRItemStationManager','m_ERRItemStationResource']:
|
||||
code=code.replace(name+'.',name+'->')
|
||||
for name in ['SCR_Global','ERR_GameMode','ERR_TerrainTakeoverSettings','SCR_EntityCatalogManagerComponent','SCR_SupportStationManagerComponent']:
|
||||
code=code.replace(name+'.',name+'::')
|
||||
code=code.replace('GetGame().','GetGame()->').replace('Remove(DelayedInit)','Remove(0)').replace('Remove(TEMP_OnInteractorReplicated)','Remove(1)')
|
||||
for method in ['OnPostInit','DelayedInit','OnDelete','AddRemoveOnDamageStateChanged']:
|
||||
code=code.replace('super.'+method,'Native'+method)
|
||||
run(r'''
|
||||
#include <cassert>
|
||||
#define null nullptr
|
||||
namespace SCR_Global{bool editing=false;bool IsEditMode(){return editing;}}
|
||||
namespace ERR_GameMode{bool present=true;bool Get(){return present;}}
|
||||
namespace ERR_TerrainTakeoverSettings{bool enabled=true;bool Enabled(){return enabled;}}
|
||||
namespace SCR_EntityCatalogManagerComponent{bool present=true;bool GetInstance(){return present;}}
|
||||
struct Queue{int cancelled=0;void Remove(int){cancelled++;}};
|
||||
struct Game{int world=1;Queue queue;int GetWorld(){return world;}Queue& GetCallqueue(){return queue;}}game;
|
||||
Game* gamePtr=&game;Game* GetGame(){return gamePtr;}
|
||||
struct Event{int subscribed=0,removed=0;void Remove(int){subscribed=0;removed++;}};
|
||||
struct Resource{Event event;Event& TEMP_GetOnInteractorReplicated(){return event;}};
|
||||
struct Manager{int removed=0;void RemoveSupportStation(void*){removed++;}}oldManager,newManager;
|
||||
namespace SCR_SupportStationManagerComponent{Manager* current=&oldManager;Manager* GetInstance(){return current;}}
|
||||
struct IEntity{int world=1;int GetWorld(){return world;}};
|
||||
struct Station{
|
||||
bool m_ERRItemStationScoped=false,m_ERRItemStationInitializing=false,m_ERRItemStationInitialized=false,m_ERRItemStationDeleted=false;
|
||||
Resource* m_ERRItemStationResource=nullptr;Manager* m_ERRItemStationManager=nullptr;
|
||||
bool m_ResourceConsumer=false,m_ResourceGenerator=false,range=false,invalid=false;
|
||||
Resource resource;int initCalls=0,errors=0,deleteCalls=0,damageAdded=0,damageRemoved=0;
|
||||
Resource* GetResourceComponent(){return &resource;}bool UsesRange(){return range;}
|
||||
void NativeOnPostInit(IEntity*){}
|
||||
void NativeDelayedInit(IEntity* owner){initCalls++;if(!SCR_EntityCatalogManagerComponent::present||invalid){errors++;return;}m_ResourceConsumer=true;resource.event.subscribed++;AddRemoveOnDamageStateChanged(owner,true);}
|
||||
void NativeOnDelete(IEntity*){deleteCalls++;}
|
||||
void NativeAddRemoveOnDamageStateChanged(IEntity*,bool subscribe){if(subscribe)damageAdded++;else damageRemoved++;}
|
||||
'''+code+r'''
|
||||
};
|
||||
int main(){
|
||||
IEntity main,preview{2};
|
||||
// Live initialization validates normally and records both subscriptions.
|
||||
Station live;live.range=true;live.OnPostInit(&main);live.DelayedInit(&main);
|
||||
assert(live.m_ERRItemStationInitialized&&live.damageAdded==1&&live.resource.event.subscribed==1);
|
||||
// Destroy the catalog and replace the global manager before cleanup.
|
||||
SCR_EntityCatalogManagerComponent::present=false;SCR_SupportStationManagerComponent::current=&newManager;
|
||||
live.OnDelete(&main);live.OnDelete(&main);assert(!live.deleteCalls&&live.damageRemoved==1&&live.resource.event.removed==1);
|
||||
assert(oldManager.removed==1&&newManager.removed==0&&!live.m_ERRItemStationResource&&!live.m_ERRItemStationManager);
|
||||
live.DelayedInit(&main);assert(live.initCalls==1); // Late queued init cannot resurrect subscriptions.
|
||||
// Delete before the scheduled initialization: no subscription and no startup revalidation.
|
||||
Station unborn;unborn.OnPostInit(&main);unborn.OnDelete(&main);unborn.DelayedInit(&main);
|
||||
assert(unborn.initCalls==0&&unborn.damageRemoved==0&&unborn.errors==0);
|
||||
// A catalog-less preload object is not a live station and requires no validation.
|
||||
Station preload;preload.OnPostInit(&preview);preload.DelayedInit(&preview);preload.OnDelete(&preview);
|
||||
assert(!preload.initCalls&&!preload.errors&&!preload.damageRemoved);
|
||||
// Missing catalogs in the MAIN world remain a real validation error.
|
||||
Station broken;broken.OnPostInit(&main);broken.DelayedInit(&main);assert(broken.errors==1&&!broken.m_ERRItemStationInitialized);
|
||||
broken.OnDelete(&main);assert(!broken.damageRemoved);
|
||||
// Non-range stations also detach the resource event, which native teardown skipped.
|
||||
SCR_EntityCatalogManagerComponent::present=true;Station portable;portable.OnPostInit(&main);portable.DelayedInit(&main);portable.OnDelete(&main);
|
||||
assert(portable.resource.event.removed==1&&newManager.removed==0);
|
||||
Station badType;badType.invalid=true;badType.OnPostInit(&main);badType.DelayedInit(&main);badType.OnDelete(&main);assert(badType.errors==1&&!badType.damageRemoved);
|
||||
// Opted-out unrelated modes and editor mode keep their original lifecycle.
|
||||
ERR_GameMode::present=false;ERR_TerrainTakeoverSettings::enabled=false;
|
||||
Station unrelated;unrelated.OnPostInit(&main);unrelated.OnDelete(&main);assert(unrelated.deleteCalls==1);
|
||||
ERR_TerrainTakeoverSettings::enabled=true;SCR_Global::editing=true;
|
||||
Station editing;editing.OnPostInit(&preview);editing.OnDelete(&preview);assert(editing.deleteCalls==1);
|
||||
}
|
||||
''')
|
||||
print('PASS: catalog-independent cleanup removes original subscriptions once, handles never-initialized/preload items, preserves live validation and opted-out/editor behavior')
|
||||
Reference in New Issue
Block a user