Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
59 lines
4.2 KiB
Python
59 lines
4.2 KiB
Python
"""Actual authored map element updates avoid repeated text/texture loads while panning."""
|
|
from pathlib import Path
|
|
import os
|
|
from policy_harness import ROOT, body, run
|
|
root=Path(os.environ.get('ERR_OBJECTIVE_MAP_ROOT',ROOT))
|
|
p=root/'addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveMapPresentation.c'
|
|
# Native Enforce requires the inherited override argument name, not only its type.
|
|
assert 'override void HandlerAttached(Widget w)' in p.read_text()
|
|
assert 'super.HandlerAttached(w);' in body(p,'override void HandlerAttached(')
|
|
s=body(p,'void SetObjective(').replace('ResourceName','string')
|
|
for n in ['m_ERRText','m_ERRImage']:s=s.replace(n+'.',n+'->')
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
using string=std::string;
|
|
struct vector{int x=0,z=0;};
|
|
struct TextWidget{string text;int sets=0;void SetText(string t){text=t;sets++;}};
|
|
struct ImageWidget{string source,icon;int loads=0;bool succeeds=true,visible=true;bool LoadImageFromSet(int,string s,string i){source=s;icon=i;loads++;return succeeds;}void SetVisible(bool v){visible=v;}};
|
|
struct Element{vector m_ERRPosition;TextWidget*m_ERRText=nullptr;ImageWidget*m_ERRImage=nullptr;bool m_ERRTextReady=false,m_ERRImageReady=false;string m_ERRLastText,m_ERRLastIcon;
|
|
'''+s+r'''
|
|
};
|
|
int main(){
|
|
TextWidget text;ImageWidget image;Element e;e.m_ERRText=&text;e.m_ERRImage=ℑ
|
|
e.SetObjective({250,750},"Unknown location (500 m area)","mark-question");assert(text.sets==1&&image.loads==1&&image.source.find("UI/Textures/ERR/SiteMarkers.imageset")!=string::npos);
|
|
for(int i=0;i<500;i++)e.SetObjective({i,750},"Unknown location (500 m area)","mark-question");
|
|
assert(text.sets==1&&image.loads==1&&e.m_ERRPosition.x==499);
|
|
e.SetObjective({612,734},"Radio station","radio");assert(text.sets==2&&image.loads==2&&image.icon=="radio"&&image.source.find("UI/Textures/ERR/SiteMarkers.imageset")!=string::npos);
|
|
e.SetObjective({612,734},"Changed label","radio");assert(text.sets==3&&image.loads==2);
|
|
e.SetObjective({612,734},"Changed label","supplies");assert(text.sets==3&&image.loads==3);
|
|
// Failed lookup hides the untextured rectangle and retries the same icon next update.
|
|
image.succeeds=false;e.SetObjective({612,734},"Unknown", "mark-question");
|
|
assert(!e.m_ERRImageReady&&!image.visible&&image.loads==4);
|
|
image.succeeds=true;e.SetObjective({612,734},"Unknown", "mark-question");
|
|
assert(e.m_ERRImageReady&&image.visible&&image.loads==5&&image.icon=="mark-question");
|
|
// Each new widget initializes even for the same data; caches are instance-owned.
|
|
TextWidget nextText;ImageWidget nextImage;Element next;next.m_ERRText=&nextText;next.m_ERRImage=&nextImage;
|
|
next.SetObjective({612,734},"Changed label","supplies");assert(nextText.sets==1&&nextImage.loads==1&&text.sets==4);
|
|
Element delayed;delayed.SetObjective({1,2},"", "mark-question");assert(!delayed.m_ERRTextReady&&!delayed.m_ERRImageReady&&delayed.m_ERRPosition.z==2);
|
|
delayed.m_ERRText=&nextText;delayed.SetObjective({3,4},"", "mark-question");assert(nextText.text.empty()&&delayed.m_ERRTextReady&&!delayed.m_ERRImageReady);
|
|
int sets=nextText.sets;delayed.m_ERRImage=&nextImage;delayed.SetObjective({5,6},"", "mark-question");assert(nextText.sets==sets&&delayed.m_ERRImageReady&&nextImage.loads==2);
|
|
}
|
|
''')
|
|
print('PASS: actual map element initializes each widget, retries missing widgets, updates position and changes only stale text/icon data; no native image-load claim')
|
|
|
|
# All generated marker names must survive resource tokenization unchanged. A
|
|
# hyphenated bare identifier can lose the suffix while other atlas entries work.
|
|
import ast, re
|
|
atlas=(root/'addons/core/UI/Textures/ERR/SiteMarkers.imageset').read_text()
|
|
names=[]
|
|
for token in re.findall(r'ImageSetDefClass\s+([^\n{]+)\s*\{', atlas):
|
|
token=token.strip()
|
|
assert re.fullmatch(r'"[^"\n]+"|[A-Za-z_][A-Za-z_0-9]*', token), token
|
|
names.append(token.strip('"'))
|
|
module=ast.parse((root/'tools/generate_map_icons.py').read_text())
|
|
symbols=next(ast.literal_eval(n.value) for n in module.body if isinstance(n,ast.Assign) and any(isinstance(t,ast.Name) and t.id=='SYMBOLS' for t in n.targets))
|
|
assert names==[symbol[2] for symbol in symbols]
|
|
assert 'mark-question' in names
|
|
print('PASS: all atlas identifiers, including the quoted question mark, match the generator')
|