docs(parity): mirror 40250 layout for the logic layer; evaluate embedded Python UI
- SKILL.md: logic units port into extension/src/port/<Lib>/<File>, platform adapters under extension/src/platform; legacy GDScript owners are migration sources; python layer frozen until the embedding decision - port_map.py: logic/python/platform layers with per-layer progress, queue --layer, LEGACY layout check; inventory adds EterBase, EterPythonLib, ScriptLib, SpeedTreeLib, SphereLib, EterImageLib - py_embed_spike.py + docs/PYTHON-EMBED-EVAL.md: the 40250 system.py bootstrap loads 67/74 root modules unchanged under CPython 2.7 with stub natives Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python2.7
|
||||
"""Embedded-Python feasibility spike (Python 2.7 only; see docs/PYTHON-EMBED-EVAL.md).
|
||||
|
||||
Emulates CPythonLauncher::Create + system.py bootstrap: stub native modules (every call returns 0),
|
||||
a directory-backed `pack` module over the 40250 Eternexus tree, then imports every root module
|
||||
through system.py's own `__pack_import`. Reports loaded/failed modules to --out (default
|
||||
py_embed_spike.txt); system.py redirects stdout, so nothing useful is printed.
|
||||
|
||||
python2.7 py_embed_spike.py [--out FILE] (reference root: MT_40250_SOURCE or audit manifest)
|
||||
"""
|
||||
import sys, types, os, glob, traceback, json
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
REPO = os.path.abspath(os.path.join(HERE, "../../../.."))
|
||||
_ref = os.environ.get("MT_40250_SOURCE") or json.load(open(os.path.join(REPO, "audit/manifest.json")))["reference_root"]
|
||||
E = os.path.normpath(os.path.join(REPO, _ref, "../../Client/Eternexus"))
|
||||
OUT = sys.argv[sys.argv.index("--out") + 1] if "--out" in sys.argv else "py_embed_spike.txt"
|
||||
FILES = {}
|
||||
for p in glob.glob(E + "/root/*"): FILES[os.path.basename(p).lower()] = p
|
||||
for base, pre in ((E + "/locale_en/locale/en", "locale/en/"), (E + "/uiscript/uiscript", "uiscript/")):
|
||||
for d, _, fs in os.walk(base):
|
||||
for f in fs:
|
||||
full = os.path.join(d, f)
|
||||
FILES[(pre + os.path.relpath(full, base)).lower()] = full
|
||||
LOG = open(OUT, "w")
|
||||
MISSING = {}
|
||||
class Stub(types.ModuleType):
|
||||
def __getattr__(self, name):
|
||||
if name.startswith("__"): raise AttributeError(name)
|
||||
key = "%s.%s" % (self.__name__, name)
|
||||
def f(*a, **k):
|
||||
MISSING[key] = MISSING.get(key, 0) + 1
|
||||
return 0
|
||||
setattr(self, name, f); return f
|
||||
NATIVE = "app net player chr chrmgr wndMgr grp grpImage grpText grpThing item skill snd chat background miniMap ime systemSetting guild safebox shop exchange quest messenger textTail nonplayer effect event eventMgr fly dbg profiler ServerStateChecker udp".split()
|
||||
for n in NATIVE: sys.modules[n] = Stub(n)
|
||||
pack = types.ModuleType("pack")
|
||||
def norm(n): return n.replace("\\", "/").lower().lstrip("/")
|
||||
pack.Exist = lambda n: norm(n) in FILES
|
||||
pack.Get = lambda n: open(FILES[norm(n)], "rb").read()
|
||||
sys.modules["pack"] = pack
|
||||
sys.modules["dbg"].Trace = sys.modules["dbg"].TraceError = lambda *a: None
|
||||
sys.modules["dbg"].LogBox = lambda m: LOG.write("LOGBOX: %s\n" % m)
|
||||
sys.modules["app"].Loop = lambda: LOG.write("app.Loop reached\n")
|
||||
STR = {"app.GetLocalePath": "locale/en", "app.GetLocaleName": "en", "app.GetLocaleServiceName": "en",
|
||||
"app.GetLocalePathCommon": "locale/common"}
|
||||
for k, v in STR.items():
|
||||
m, f = k.split(".")
|
||||
setattr(sys.modules[m], f, (lambda v: lambda *a: v)(v))
|
||||
import __builtin__
|
||||
__builtin__.TRUE = 1; __builtin__.FALSE = 0 # CPythonLauncher::Create
|
||||
import __main__
|
||||
__main__.__DEBUG__ = 0
|
||||
__main__.__COMMAND_LINE__ = ""
|
||||
src = pack.Get("system.py")
|
||||
try:
|
||||
exec compile(src, "system.py", "exec") in __main__.__dict__
|
||||
except BaseException:
|
||||
LOG.write("system.py raised:\n" + traceback.format_exc())
|
||||
ok, bad = [], []
|
||||
_pimp = __main__.__dict__["__pack_import"]
|
||||
for name in sorted(FILES):
|
||||
if not name.endswith(".py") or "/" in name: continue
|
||||
mod = name[:-3]
|
||||
real = [m for m in sys.modules if m.lower() == mod]
|
||||
if real: ok.append(mod); continue
|
||||
try:
|
||||
_pimp(mod); ok.append(mod)
|
||||
except BaseException as e:
|
||||
bad.append((mod, "%s: %s" % (type(e).__name__, str(e)[:100])))
|
||||
LOG.write("modules loaded %d, failed %d\n" % (len(ok), len(bad)))
|
||||
for m, e in bad: LOG.write(" FAIL %s %s\n" % (m, e))
|
||||
LOG.write("native functions called during bootstrap: %d\n" % len(MISSING))
|
||||
LOG.write(" " + " ".join(sorted(MISSING)) + "\n")
|
||||
LOG.close()
|
||||
Reference in New Issue
Block a user