- system.py runs app.Loop() on the script fiber; each UIUpdate is one CPythonApplication::Process(). Logo -> Login, popup ESC/click and app.Exit teardown (launcher cleared first, as in 40250 Main) work. - Image commands are base-texture quads with UVs (a .sub shares its parent texture); ImageInstance/ExpandedImageInstance OnRender and SetRenderingRect ported verbatim, so scale/rotation/rendering rect are drawn. - CGraphicBase::GetColor / grp.GenerateColor ported (ThinBoard background). - port.app_loop test, python_host_test app-loop checks, MT_TEST_MODE=python_ui. - TODO: .fnt/CGraphicText font pipeline, ExpandedImage blend modes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
3.2 KiB
C++
63 lines
3.2 KiB
C++
#pragma once
|
|
// Starting the script layer inside a host process (docs/PORT-PLAN.md 批次 2P step 4).
|
|
//
|
|
// 40250 runs the interpreter on Main()'s stack (UserInterface/UserInterface.cpp:419-434): construct
|
|
// CPythonLauncher, Create(), RunMainScript(), Clear(), all inside one WinMain. Godot owns the process
|
|
// here and calls in from GDScript, so the launcher has to outlive the call that starts it — that split
|
|
// (Start / RunMainScript / Stop) is the only difference from the original control flow.
|
|
//
|
|
// It lives under platform/ScriptLib rather than platform/UserInterface because it is only buildable
|
|
// with the embedded interpreter, and that is the directory both port_logic and port_platform drop when
|
|
// `mtpython` is absent (extension/src/port/CMakeLists.txt).
|
|
//
|
|
// godot-free, like everything else under platform/: extension/src/python_host_node.cpp is what GDScript
|
|
// talks to.
|
|
|
|
#include <string>
|
|
|
|
namespace PythonBoot
|
|
{
|
|
// PythonHost::Configure() -> CPythonLauncher -> Create() -> PythonHost::InstallStdLib(stdlib_path).
|
|
// An empty stdlib_path means PythonHost::DefaultStdLibPath(). Starting twice is a no-op that succeeds.
|
|
// On failure *error is set and the interpreter is shut down again, so the next attempt starts clean.
|
|
// The packs must already be registered (platform/PackBackend.h), as 40250 registers them in Main()
|
|
// before the launcher exists.
|
|
bool Start(const char* stdlib_path, std::string* error);
|
|
bool IsRunning();
|
|
|
|
// 40250: RunMainScript(CPythonLauncher&, const char*) — the module initializers, __DEBUG__,
|
|
// __COMMAND_LINE__ and RunFile("system.py"). 2V0-e registers temporary observable gameplay modules;
|
|
// they are replaced by the real modules in later 2V slices.
|
|
// False leaves *error set to what the launcher reported through LogBox (platform/EterBase/LogBox.h).
|
|
//
|
|
// PORT: system.py runs on a script thread. RunMainScript returns once prototype.RunApp() has reached
|
|
// app.Loop() (IsAppLooping) or the script has ended; from then on every AppFrame() runs exactly one
|
|
// CPythonApplication::Process() while the host thread waits, so the two never run concurrently.
|
|
bool RunMainScript(const char* lpCmdLine, std::string* error);
|
|
bool IsAppLooping();
|
|
bool AppFrame();
|
|
|
|
// Used by the platform CPythonApplication: Loop() calls AppLoopWait() before each Process() and stops
|
|
// when it returns false; Exit()/Abort() call AppRequestQuit() (40250: PostQuitMessage).
|
|
bool AppLoopWait();
|
|
void AppRequestQuit();
|
|
|
|
// CPythonLauncher::RunLine, with the reported text handed back rather than only shown. The host's own
|
|
// check uses it to prove the interpreter and the standard library work in-process on a device that has
|
|
// no 40250 packs, which is where RunMainScript cannot run at all.
|
|
bool RunLine(const char* source, std::string* error);
|
|
|
|
// Forward physical Godot input to the original 40250 window manager. Coordinates
|
|
// are viewport pixels; SetUISize also establishes its logical resolution.
|
|
void SetUISize(int width, int height);
|
|
void UIMouseMove(int x, int y);
|
|
void UIMouseButton(int button, bool pressed, int x, int y);
|
|
void UIKey(int key, bool pressed);
|
|
// While IsAppLooping(), UIUpdate is AppFrame() and UIRender keeps the commands that Process() drew.
|
|
void UIUpdate();
|
|
void UIRender();
|
|
|
|
// 40250 Main() calls Clear() and lets the launcher leave scope.
|
|
void Stop();
|
|
}
|