"""Execute production input dispatch and recovery with native camera/editor doubles.""" from policy_harness import ROOT,body,run p=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Observer.c' s=body(p,'protected void ERR_UpdateRecoveryCamera(').replace('protected ','').replace('ERR_GameMode mode','ERR_GameMode* mode').replace('null','nullptr') for name in ('ERR_Actors','SCR_EditorManagerEntity','LogLevel'): s=s.replace(name+'.',name+'::') for name in ('SCR_EditorManagerEntity','CameraManager','CameraBase'): s=s.replace(name+' ',name+'* ') for name in ('mode','editor','manager'): s=s.replace(name+'.',name+'->') s=s.replace('GetGame().','GetGame()->').replace('GetWorld().','GetWorld()->') run(r'''#include struct Actor {bool alive=true,conscious=true;};using IEntity=Actor*; struct ERR_Actors {static bool Alive(IEntity a){return a&&a->alive;}static bool CanFight(IEntity a){return Alive(a)&&a->conscious;}}; struct ERR_GameMode {bool active=true;bool Active(){return active;}}; struct SCR_EditorManagerEntity {bool opened=false,canClose=true;int closes=0;static SCR_EditorManagerEntity* current;static SCR_EditorManagerEntity* GetInstance(){return current;}bool IsOpened(){return opened;}void Close(bool){closes++;if(canClose)opened=false;}} editor; SCR_EditorManagerEntity* SCR_EditorManagerEntity::current=&editor; struct CameraBase{} player,other; struct CameraManager {CameraBase* current=&other;int sets=0;void SetCamera(CameraBase* c){current=c;sets++;}CameraBase* CurrentCamera(){return current;}} manager; struct World {float now=0;float GetWorldTime(){return now;}} world; struct Game {World* GetWorld(){return &world;}CameraManager* GetCameraManager(){return &manager;}} game; Game* GetGame(){return &game;}namespace LogLevel {enum{WARNING};}int warnings=0;void Print(const char*,int){warnings++;} struct Controller { IEntity controlled=nullptr,m_ERRRecoveryBody=nullptr;float m_ERRRecoveryDeadline=-1;CameraBase* camera=&player; IEntity GetControlledEntity(){return controlled;}CameraBase* GetPlayerCamera(){return camera;} '''+s+r''' }; int main(){ ERR_GameMode mode;Actor body,replacement;Controller c;c.controlled=&body; // Healthy admins retain their camera: restoration belongs only to recovery. c.ERR_UpdateRecoveryCamera(&mode);assert(manager.sets==0&&editor.closes==0); body.conscious=false;c.ERR_UpdateRecoveryCamera(&mode);assert(c.m_ERRRecoveryBody==&body&&manager.sets==0); // Recovery works with NO observer-camera instance and a different active camera. editor.opened=true;body.conscious=true;c.ERR_UpdateRecoveryCamera(&mode); assert(editor.closes==1&&!editor.opened&&manager.current==&player&&!c.m_ERRRecoveryBody); manager.current=&other;c.ERR_UpdateRecoveryCamera(&mode);assert(manager.current==&other); // no permanent camera lock // An asynchronously closing editor retains the pending recovery; next tick completes. body.conscious=false;c.ERR_UpdateRecoveryCamera(&mode);body.conscious=true;editor.opened=true;editor.canClose=false; c.ERR_UpdateRecoveryCamera(&mode);assert(c.m_ERRRecoveryBody==&body); editor.canClose=true;c.ERR_UpdateRecoveryCamera(&mode);assert(!c.m_ERRRecoveryBody&&manager.current==&player); // Wait for late camera creation, then return once. body.conscious=false;c.ERR_UpdateRecoveryCamera(&mode);body.conscious=true;c.camera=nullptr; c.ERR_UpdateRecoveryCamera(&mode);assert(c.m_ERRRecoveryBody==&body); c.camera=&player;c.ERR_UpdateRecoveryCamera(&mode);assert(!c.m_ERRRecoveryBody); // Refused editor close is bounded, warning instead of permanently stealing input. body.conscious=false;c.ERR_UpdateRecoveryCamera(&mode);body.conscious=true;editor.opened=true;editor.canClose=false; c.ERR_UpdateRecoveryCamera(&mode);world.now=10001;c.ERR_UpdateRecoveryCamera(&mode);assert(!c.m_ERRRecoveryBody&&warnings==1); editor.opened=false;editor.canClose=true; // Changed possession / stopped round must not return a stale casualty's camera. body.conscious=false;c.ERR_UpdateRecoveryCamera(&mode);c.controlled=&replacement;int before=manager.sets; c.ERR_UpdateRecoveryCamera(&mode);assert(!c.m_ERRRecoveryBody&&manager.sets==before); c.controlled=&body;c.ERR_UpdateRecoveryCamera(&mode);mode.active=false;body.conscious=true; c.ERR_UpdateRecoveryCamera(&mode);assert(!c.m_ERRRecoveryBody&&manager.sets==before); } ''') assert 'm_InputResumeFrames = 2;' in body(p,'override bool EOnCameraInit(') input_body=body(p,'void Input(').replace('SCR_PlayerController controller = SCR_PlayerController.Cast(GetGame().GetPlayerController());','SCR_PlayerController* controller = &pc;').replace('controller.','controller->').replace('ERR_ObserverRules.','ERR_ObserverRules::') run(r'''#include struct ERR_ObserverRules { '''+body(p,'static int Cycle(')+body(p,'static bool Toggle(')+r''' }; struct SCR_PlayerController {int calls=0,direction=0,epi=0;void ERR_UseSelfEpinephrine(){epi++;}void ERR_CycleObserver(int d){calls++;direction=d;}} pc; struct Follow {bool m_LeftDown=false,m_RightDown=false,m_EnterDown=false,m_PlayerView=false,m_SpaceDown=false;int m_InputResumeFrames=0; '''+input_body+r''' }; int main(){ Follow initial;initial.m_InputResumeFrames=2; initial.Input(true,false,false,false,true);initial.Input(true,false,false,false,true);assert(pc.epi==0); initial.Input(true,false,false,false,false);initial.Input(true,false,false,false,true);assert(pc.epi==1);pc.epi=0; Follow epi; epi.Input(false,false,false,false,true); epi.Input(true,false,false,false,true); epi.Input(true,false,false,false,true);assert(pc.epi==0); epi.Input(true,false,false,false,false);epi.Input(true,false,false,false,true);assert(pc.epi==1); epi.Input(true,false,false,false,true);assert(pc.epi==1); epi.Input(true,false,false,false,false);epi.Input(true,false,false,false,true);assert(pc.epi==2); Follow f;f.Input(true,true,false,false);assert(pc.calls==1&&pc.direction==-1); f.Input(true,true,false,false);assert(pc.calls==1); f.Input(true,false,false,false);f.Input(true,false,true,false);assert(pc.calls==2&&pc.direction==1); f.Input(true,true,true,false);assert(pc.calls==2); f.Input(false,false,false,true);f.Input(true,false,false,true);assert(!f.m_PlayerView); // menu-held Enter f.Input(true,false,false,false);f.Input(true,false,false,true);assert(f.m_PlayerView); f.Input(true,false,false,true);assert(f.m_PlayerView); f.Input(true,false,false,false);f.Input(true,false,false,true);assert(!f.m_PlayerView); // Inactive chat context masks held keys as zero; submission must not become // a new camera press when the context resumes (including its first zero frame). f.Input(false,false,false,false); f.Input(true,false,false,false); f.Input(true,false,false,true);assert(!f.m_PlayerView); f.Input(true,false,false,true);assert(!f.m_PlayerView); f.Input(true,false,false,false); f.Input(true,false,false,true);assert(f.m_PlayerView); int before=pc.calls; f.Input(false,false,false,false); f.Input(true,false,false,false); f.Input(true,true,false,false);f.Input(true,true,false,false);assert(pc.calls==before); f.Input(true,false,false,false);f.Input(true,true,false,false);assert(pc.calls==before+1); } ''') # Execute the actual chat-manager state, capture helper, and pre-activation gate. # Chat contexts expire independently of widget focus; open panels are authoritative. def camera_ui_cpp(source): import re source=source.replace('override protected ', '').replace('super.', 'Base::').replace('null','nullptr') # Enforce initializes local booleans to false; C++ otherwise leaves them undefined. source=re.sub(r'\bbool (\w+);',r'bool \1=false;',source) source=source.replace('GetGame().', 'GetGame()->').replace('GetInputManager().', 'GetInputManager()->').replace('GetWorkspace().', 'GetWorkspace()->') for typ in ('SCR_ChatPanelManager','SCR_ChatPanel','EditBoxWidget','ERR_ObserverChatInput'): source=source.replace(typ+'.',typ+'::') source=source.replace('foreach (SCR_ChatPanel panel : m_aChatPanels)', 'for (SCR_ChatPanel panel : m_aChatPanels)') pointer_names=[] for typ in ('SCR_ChatPanelManager','SCR_ChatPanel','Widget','InputManager'): pointer_names+=re.findall(r'\b'+typ+r' (\w+)',source) source=re.sub(r'\b'+typ+r' (\w+)',typ+r'* \1',source) for name in pointer_names: source=re.sub(r'\b'+name+r'\.',name+'->',source) source=source.replace('FindHandler(SCR_ChatPanel)', 'FindHandler()') return source manager_method=camera_ui_cpp(body(p,'bool ERR_HasOpenChatPanel(')) capture=camera_ui_cpp(body(p,'static bool Capture(')) gate=camera_ui_cpp(body(p,'override protected bool IsDisabledByMenu(')) ui_prelude=r'''#include #include #include struct SCR_ChatPanel {bool open=false;bool IsOpen(){return open;}static SCR_ChatPanel*Cast(SCR_ChatPanel*p){return p;}}; struct Widget {Widget*parent=nullptr;bool edit=false;SCR_ChatPanel*handler=nullptr;Widget*GetParent(){return parent;}SCR_ChatPanel*FindHandler(){return handler;}}; struct EditBoxWidget {static Widget*Cast(Widget*w){return w&&w->edit?w:nullptr;}}; struct InputManager {bool chat=false;int renewals=0; bool IsContextActive(const char*name){assert(std::string(name)=="ChatContext");return chat;} void ActivateContext(const char*name,int durationMs){assert(std::string(name)=="ChatContext"&&durationMs==1);chat=true;renewals++;} void Expire(){chat=false;} } inputs; struct Workspace {Widget*focus=nullptr;Widget*GetFocusedWidget(){return focus;}} workspace; struct Game {InputManager*GetInputManager(){return &inputs;}Workspace*GetWorkspace(){return &workspace;}} game; Game*GetGame(){return &game;} struct SCR_ChatPanelManager {static SCR_ChatPanelManager*current;std::vectorm_aChatPanels; static SCR_ChatPanelManager*GetInstance(){return current;} '''+manager_method+r''' } chatManager; SCR_ChatPanelManager*SCR_ChatPanelManager::current=&chatManager; struct ERR_ObserverChatInput { '''+capture+r''' }; struct Base {bool menu=false;bool IsDisabledByMenu(){return menu;}}; ''' ui_tests=r''' int main(){ Camera c;SCR_ChatPanel registered,unregistered; chatManager.m_aChatPanels={nullptr,®istered}; assert(!chatManager.ERR_HasOpenChatPanel());assert(!c.IsDisabledByMenu());assert(inputs.renewals==0); // A dead observer can retain open chat after the native HUD stops renewing it. // No focus or previously active context is required for registered open chat. registered.open=true;assert(chatManager.ERR_HasOpenChatPanel()); assert(c.IsDisabledByMenu());assert(inputs.chat&&inputs.renewals==1); inputs.Expire();assert(c.IsDisabledByMenu());assert(inputs.chat&&inputs.renewals==2); // Native menus retain priority; a camera must not activate input behind them. inputs.Expire();c.menu=true;assert(c.IsDisabledByMenu());assert(!inputs.chat&&inputs.renewals==2);c.menu=false; registered.open=false;assert(!chatManager.ERR_HasOpenChatPanel());assert(!c.IsDisabledByMenu()); // An unregistered still-open panel is discoverable through focus ancestry. Widget panelWidget,child,edit,ordinary;panelWidget.handler=&unregistered;child.parent=&panelWidget; unregistered.open=true;workspace.focus=&child; assert(c.IsDisabledByMenu());assert(inputs.chat&&inputs.renewals==3); inputs.Expire();SCR_ChatPanelManager::current=nullptr; assert(c.IsDisabledByMenu());assert(inputs.chat&&inputs.renewals==4); // A closed panel cannot renew chat, even if it still owns focused widgets. unregistered.open=false;inputs.Expire();assert(!c.IsDisabledByMenu());assert(inputs.renewals==4); edit.edit=true;edit.parent=&panelWidget;workspace.focus=&edit; assert(c.IsDisabledByMenu());assert(!inputs.chat&&inputs.renewals==4); // Ordinary password/edit dialogs pause the camera without acquiring ChatContext. edit.parent=nullptr;child.parent=&edit;workspace.focus=&child; assert(c.IsDisabledByMenu());assert(!inputs.chat&&inputs.renewals==4); workspace.focus=&ordinary;assert(!c.IsDisabledByMenu());workspace.focus=nullptr; assert(!c.IsDisabledByMenu());SCR_ChatPanelManager::current=&chatManager; // A residual native chat context still blocks the camera until it expires. inputs.chat=true;assert(c.IsDisabledByMenu());assert(inputs.renewals==4); inputs.Expire();assert(!c.IsDisabledByMenu()); // Integrate Capture with the production input edge/release state machine. Follow f;registered.open=true;f.Input(!c.IsDisabledByMenu(),false,false,false); registered.open=false;inputs.Expire();f.Input(!c.IsDisabledByMenu(),false,false,false); f.Input(!c.IsDisabledByMenu(),false,false,true);f.Input(!c.IsDisabledByMenu(),false,false,true); assert(!f.m_PlayerView); // submitting/holding Enter cannot become a camera toggle f.Input(!c.IsDisabledByMenu(),false,false,false);f.Input(!c.IsDisabledByMenu(),false,false,true);assert(f.m_PlayerView); registered.open=true;f.Input(!c.IsDisabledByMenu(),false,false,false); registered.open=false;inputs.Expire();f.Input(!c.IsDisabledByMenu(),false,false,false); f.Input(!c.IsDisabledByMenu(),true,false,false);assert(pc.calls==0); f.Input(!c.IsDisabledByMenu(),false,false,false);f.Input(!c.IsDisabledByMenu(),true,false,false);assert(pc.calls==1); } ''' ui_follow=r''' struct ERR_ObserverRules { '''+body(p,'static int Cycle(')+body(p,'static bool Toggle(')+r''' }; struct SCR_PlayerController {int calls=0,direction=0,epi=0;void ERR_UseSelfEpinephrine(){epi++;}void ERR_CycleObserver(int d){calls++;direction=d;}} pc; struct Follow {bool m_LeftDown=false,m_RightDown=false,m_EnterDown=false,m_PlayerView=false,m_SpaceDown=false;int m_InputResumeFrames=0; '''+input_body+r''' }; ''' run(ui_prelude+'struct Camera:Base {\n'+gate+'\n};\n'+ui_follow+ui_tests) assert (ROOT/'addons/core/Prefabs/ERR/SpectatorCamera.et').read_text().startswith('ERR_ObserverCamera {') config=(ROOT/'addons/core/Configs/ERR/ObserverInput.conf').read_text() for key in ('KC_LEFT','KC_RIGHT','KC_RETURN','KC_NUMPADENTER'): assert f'keyboard:{key}' in config assert 'chimeraInputCommon.conf' in config and 'ActionContext/ManualCameraContext.conf' in config assert 'Debug.KeyState' not in p.read_text() print('PASS: actual open-chat capture/context renewal and camera/menu priority, text-entry isolation, held-key release; actual revival camera handoff with editor close/retry, missing camera, replacement body and stopped round')