载入中...
搜索中...
未找到
EditorScriptProjection.h
浏览该文件的文档.
1#pragma once
2
3#include "common/Result.h"
7#include "common/Value.h"
9
10#include <simplesquirrel/simplesquirrel.hpp>
11
12#include <cstdint>
13#include <functional>
14#include <memory>
15#include <string>
16#include <utility>
17
18namespace eve::editor {
19
28[[nodiscard]] inline ssq::Table project(HSQUIRRELVM vm, const eve::Result<void>& result) {
29 return script::projectStatusResult(vm, result.status());
30}
31
40template <class T>
42[[nodiscard]] inline ssq::Table project(HSQUIRRELVM vm, const eve::Result<T>& result, Value value) {
43 if (!result.ok()) return script::projectStatusResult(vm, result.status());
45 return script::projectStatusResult(vm, result.status(), std::move(value));
46}
47
57[[nodiscard]] inline ssq::Table bindingFailure(HSQUIRRELVM vm, const char* source, DiagnosticCode code,
58 std::string message, std::string path = {}) {
61 vm, Status::failure(Diagnostic::error(code, std::move(message), std::move(path), {}, source ? source : "")));
62}
63
70template <class T>
72[[nodiscard]] inline ssq::Table projectHistoryRevision(HSQUIRRELVM vm, const eve::Result<T>& result) {
74 return project(vm, result, Value(result.ok() ? static_cast<std::int64_t>(result.value().afterRevision) : 0));
75}
76
84template <class T>
86[[nodiscard]] inline ssq::Table projectOwnedInstance(HSQUIRRELVM vm, std::unique_ptr<T> instance) {
87 auto object = script::makeOwnedSquirrelInstance<T>(vm, std::move(instance));
88 if (!object) return script::projectStatusResult(vm, object.status());
89 ssq::Object owned = std::move(object).takeValue();
91 result.set("value", owned);
92 result.set("ownership", std::string("owned"));
93 return result;
94}
95
105template <class T>
107[[nodiscard]] inline ssq::Table projectOwnedCreate(HSQUIRRELVM vm, const char* source, std::string emptyIdMessage,
108 const std::string& targetId) {
109 if (targetId.empty())
111 return bindingFailure(vm, source, DiagnosticCode::InvalidArgument, std::move(emptyIdMessage), "targetId");
112 return projectOwnedInstance<T>(vm, std::make_unique<T>(targetId));
113}
114
122template <class T>
124[[nodiscard]] inline auto addScriptClass(ssq::Table& table, const char* name) {
125 return table.addClass<T>(name, std::function<T*()>([]() -> T* { return nullptr; }), true);
126}
127
136public:
144 constexpr ScriptBind(HSQUIRRELVM vm, const char* source) noexcept : ctx_(vm, source) {}
145
152 [[nodiscard]] constexpr const script::BindContext& context() const noexcept { return ctx_; }
153
163 [[nodiscard]] constexpr HSQUIRRELVM vm() const noexcept { return ctx_.vm(); }
164
174 [[nodiscard]] constexpr const char* source() const noexcept { return ctx_.source(); }
175
183 [[nodiscard]] ssq::Table fail(DiagnosticCode code, std::string message, std::string path = {}) const {
184 return ctx_.fail(code, std::move(message), std::move(path));
185 }
186
195 template <class Fn>
197 [[nodiscard]] ssq::Table checked(bool ready, std::string nullMessage, Fn&& fn, std::string path = {}) const {
198 if (!ready) return fail(DiagnosticCode::InvalidArgument, std::move(nullMessage), std::move(path));
200 return project(vm(), std::forward<Fn>(fn)());
201 }
202
212 template <class T, class Fn>
214 [[nodiscard]] ssq::Table checked(T* self, std::string nullMessage, Fn&& fn, std::string path = {}) const {
216 return checked(self != nullptr, std::move(nullMessage), std::forward<Fn>(fn), std::move(path));
217 }
218
227 template <class T, class Fn>
229 [[nodiscard]] ssq::Table history(T* self, std::string nullMessage, Fn&& fn) const {
230 if (!self) return fail(DiagnosticCode::InvalidArgument, std::move(nullMessage));
232 return projectHistoryRevision(vm(), std::forward<Fn>(fn)());
233 }
234
242 template <class T>
244 [[nodiscard]] ssq::Table ownedCreate(std::string emptyIdMessage, const std::string& targetId) const {
245 return projectOwnedCreate<T>(vm(), source(), std::move(emptyIdMessage), targetId);
246 }
247
254 template <class T>
256 [[nodiscard]] ssq::Table ownedInstance(std::unique_ptr<T> instance) const {
257 return projectOwnedInstance<T>(vm(), std::move(instance));
258 }
259
260private:
262};
263
272template <class ScriptT>
274inline void registerEditorWorkspace(ssq::Class& cls, const ScriptBind& bind, const char* nullMessage) {
275 cls.addFunc("configureWorkspace", [bind, nullMessage](ScriptT* self, EditorWorkspace* workspace) {
276 return bind.checked(
277 self && workspace, nullMessage, [&] { return self->editor().configureWorkspace(*workspace); }, "workspace");
278 });
279}
280
288template <class EditorT>
290inline void registerDirectEditorWorkspace(ssq::Class& cls, const ScriptBind& bind, const char* nullMessage) {
291 cls.addFunc("configureWorkspace", [bind, nullMessage](EditorT* self, EditorWorkspace* workspace) {
292 return bind.checked(self && workspace, nullMessage, [&] { return self->configureWorkspace(*workspace); });
293 });
294}
295
304template <class ScriptT>
306inline void registerEditorHistory(ssq::Class& cls, const ScriptBind& bind, const char* nullMessage) {
307 cls.addFunc("undo", [bind, nullMessage](ScriptT* self) {
308 return bind.history(self, nullMessage, [&] { return self->editor().undo(); });
309 });
310 cls.addFunc("redo", [bind, nullMessage](ScriptT* self) {
311 return bind.history(self, nullMessage, [&] { return self->editor().redo(); });
312 });
313 cls.addFunc("canUndo", [](ScriptT* self) { return self && self->editor().canUndo(); });
314 cls.addFunc("canRedo", [](ScriptT* self) { return self && self->editor().canRedo(); });
315 cls.addFunc("getRevision", [](ScriptT* self) { return self ? static_cast<int>(self->editor().revision()) : 0; });
316}
317
326template <class ScriptT, class ModuleT>
328inline void registerEditorOwnedCreate(ssq::Class& moduleClass, const ScriptBind& bind, const char* emptyIdMessage) {
329 moduleClass.addFunc("create", [bind, emptyIdMessage](ModuleT*, const std::string& targetId) {
330 return bind.ownedCreate<ScriptT>(emptyIdMessage, targetId);
331 });
332}
333
334} // namespace eve::editor
double value
ActiveSource owned
struct SQVM * HSQUIRRELVM
HSQUIRRELVM vm
Definition ECS.cpp:20
HSQOBJECT cls
Definition ECS.cpp:21
std::string message
DiagnosticCode code
wgpu::PopErrorScopeStatus status
std::string name
std::uint64_t revision
std::string path
Definition PlayHost.cpp:110
std::uint32_t targetId
Move-only, checked operation results for the common layer.
Per-translation-unit VM + diagnostic-source helper for Squirrel bindings.
The single Squirrel projection for common Result, Status and Value.
Explicit Value/Owned/Borrowed semantics at the Squirrel boundary.
const UnitySourceAsset & source
Owning, renderer-independent dynamic values.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
const T & value() const &
Borrow the value from a const lvalue after checking success.
Definition Result.h:308
bool ok() const noexcept
Whether this result represents a non-failure outcome.
Definition Result.h:255
const Status & status() const noexcept
Inspect the structured operation status.
Definition Result.h:269
static Status failure(StatusCode code, Diagnostic diagnostic)
Construct a failed status with one diagnostic.
Definition Status.h:84
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
The canonical owning dynamic value used by data-facing protocols.
Definition Value.h:31
Composition model shared by project-specific developer and runtime editors.
Editor facade binder: common script::BindContext plus history/owned-create helpers.
ssq::Table history(T *self, std::string nullMessage, Fn &&fn) const
Null-self guard then project a history mutation that exposes afterRevision.
constexpr const script::BindContext & context() const noexcept
Underlying common binder (VM + source + fail/checked).
ssq::Table ownedCreate(std::string emptyIdMessage, const std::string &targetId) const
Create T(targetId) and project it as an owned script Result.
ssq::Table ownedInstance(std::unique_ptr< T > instance) const
Project an already-built instance as an owned script Result.
constexpr HSQUIRRELVM vm() const noexcept
Active Squirrel VM handle.
constexpr const char * source() const noexcept
Diagnostic source tag for this binder.
ssq::Table fail(DiagnosticCode code, std::string message, std::string path={}) const
Project a binding-layer argument failure.
ssq::Table checked(T *self, std::string nullMessage, Fn &&fn, std::string path={}) const
Null-self guard then project a void/Result<void> editor call.
ssq::Table checked(bool ready, std::string nullMessage, Fn &&fn, std::string path={}) const
Run fn and project its Result when ready; otherwise emit InvalidArgument.
constexpr ScriptBind(HSQUIRRELVM vm, const char *source) noexcept
Construct a binder for one expose() translation unit.
Pins the active VM and a stable diagnostic source for one expose() TU.
ssq::Table fail(DiagnosticCode code, std::string message, std::string path={}) const
Project a binding-layer argument failure.
constexpr const char * source() const noexcept
Diagnostic source tag for this binder.
constexpr HSQUIRRELVM vm() const noexcept
Active Squirrel VM handle.
void registerDirectEditorWorkspace(ssq::Class &cls, const ScriptBind &bind, const char *nullMessage)
Register configureWorkspace when the script class is the editor (no .editor()).
void registerEditorOwnedCreate(ssq::Class &moduleClass, const ScriptBind &bind, const char *emptyIdMessage)
Register module create(targetId) that builds an owned Script* wrapper.
ssq::Table projectHistoryRevision(HSQUIRRELVM vm, const eve::Result< T > &result)
Project an undo/redo (or similar) result whose payload exposes afterRevision.
ssq::Table projectOwnedInstance(HSQUIRRELVM vm, std::unique_ptr< T > instance)
Wrap an already-built owned C++ instance as a script Result {value, ownership}.
void registerEditorWorkspace(ssq::Class &cls, const ScriptBind &bind, const char *nullMessage)
Register configureWorkspace for a Script* wrapper that exposes editor().
void registerEditorHistory(ssq::Class &cls, const ScriptBind &bind, const char *nullMessage)
Register shared undo, redo, canUndo, canRedo, and getRevision methods.
ssq::Table projectOwnedCreate(HSQUIRRELVM vm, const char *source, std::string emptyIdMessage, const std::string &targetId)
Create a target-id editor wrapper and project it as an owned script Result.
ssq::Table project(HSQUIRRELVM vm, const eve::Result< void > &result)
Project a completed editing result that has no payload.
auto addScriptClass(ssq::Table &table, const char *name)
Register a script class whose default constructor returns null (factory-only types).
ssq::Table bindingFailure(HSQUIRRELVM vm, const char *source, DiagnosticCode code, std::string message, std::string path={})
Project a binding-layer argument failure with a stable diagnostic source.
ssq::Table projectStatusResult(HSQUIRRELVM vm, const Status &status)
Project a checked native status that carries no payload.
DiagnosticCode
Stable machine-readable diagnostic codes.
Definition Diagnostic.h:47
SettlementPipeline::Stage fn