载入中...
搜索中...
未找到
SkyScriptBindings.cpp
浏览该文件的文档.
2#include <functional>
3#include <optional>
4#include <stdexcept>
7#include "daynight/DayNight.h"
10#include "graphics/Graphics.h"
12
13namespace eve::daynight {
14namespace {
15Result<void> invalid(const char* message) {
17}
18Value frameValue(const SkyRuntimeFrame& frame) {
19 const auto& weather = frame.simulation.weather;
20 return Value::object(
21 {{"hour", frame.simulation.hour},
22 {"elapsedSeconds", frame.simulation.elapsedSeconds},
23 {"cloudTime", frame.cloudTime},
24 {"wispsMorphPhase", double(frame.wispsMorphPhase)},
25 {"cloudTravelXZ", Value::array({frame.simulation.cloudTravelXZ[0], frame.simulation.cloudTravelXZ[1]})},
26 {"weather", Value::object({{"cloudCoverage", weather.cloudCoverage},
27 {"fog", weather.fog},
28 {"rain", weather.rain},
29 {"snow", weather.snow},
30 {"windXZ", Value::array({weather.windXZ[0], weather.windXZ[1]})}})},
31 {"sunDirection", Value::array({frame.sunDirection[0], frame.sunDirection[1], frame.sunDirection[2]})},
32 {"sunIrradiance", Value::array({frame.sunIrradiance[0], frame.sunIrradiance[1], frame.sunIrradiance[2]})}});
33}
34} // namespace
35void exposeSkyScriptBindings(ssq::Table& table, ssq::Class& daynightClass) {
36 const auto vm = table.getHandle();
37 auto cls =
38 table.addClass<SkyRuntime>("SkyRuntime", std::function<SkyRuntime*()>([]() -> SkyRuntime* {
39 throw std::runtime_error("Use daynight.prepareSky(graphics, profileJson)");
40 }),
41 false);
42 daynightClass.addFunc("prepareSky", [vm](DayNight*, graphics::Graphics* graphics, const std::string& profileJson) {
43 if (!graphics || profileJson.size() > 65536)
45 vm, invalid("Sky preparation requires graphics and at most 64 KiB of profile JSON"));
46 auto document = Value::fromJson(profileJson);
47 if (!document) return script::projectStatusResult(vm, document.status());
48 auto profile = SkyProfile::decode(document.value());
49 if (!profile) return script::projectStatusResult(vm, profile.status());
50 std::optional<graphics::SkyWispsAsset> wisps;
51 if (profile.value().proceduralSeed() || !profile.value().wispsAsset().empty()) {
52 auto loaded = profile.value().proceduralSeed()
53 ? graphics::SkyWispsAsset::generate(*profile.value().proceduralSeed())
54 : graphics::SkyWispsAsset::load(profile.value().wispsAsset());
55 if (!loaded) return script::projectStatusResult(vm, loaded.status());
56 wisps.emplace(std::move(loaded).takeValue());
57 }
58 auto prepared = SkyRuntime::prepare(*graphics, profile.value().settings(), profile.value().atmosphere(),
59 wisps ? &wisps->layer() : nullptr);
60 if (!prepared) return script::projectStatusResult(vm, prepared.status());
61 auto owned = script::makeOwnedSquirrelInstance(vm, std::move(prepared).takeValue());
62 if (!owned) return script::projectStatusResult(vm, owned.status());
63 auto result = script::projectStatusResult(vm, Status::success(), std::move(owned).takeValue());
64 result.set("ownership", std::string("owned"));
65 result.set("assetSource",
66 std::string(profile.value().proceduralSeed() ? "procedural-v1"
67 : (wisps ? "external-pack" : "atmosphere-only")));
68 return result;
69 });
70 cls.addFunc("attach", [vm](SkyRuntime* sky) {
71 return script::projectResult(vm, sky ? sky->attach() : invalid("Sky runtime must not be null"));
72 });
73 cls.addFunc("detach", [vm](SkyRuntime* sky) {
74 if (!sky) return script::projectResult(vm, invalid("Sky runtime must not be null"));
75 sky->detach();
77 });
78 cls.addFunc("advanceSeconds", [vm](SkyRuntime* sky, float seconds) {
79 if (!sky) return script::projectResult(vm, invalid("Sky runtime must not be null"));
80 auto duration = Duration::fromSeconds(seconds);
81 if (!duration) return script::projectStatusResult(vm, duration.status());
82 return script::projectResult(vm, sky->advance(duration.value()));
83 });
84 cls.addFunc("frame", [vm](SkyRuntime* sky) {
85 if (!sky) return script::projectResult(vm, invalid("Sky runtime must not be null"));
86 return script::projectStatusResult(vm, Status::success(), frameValue(sky->frame()));
87 });
88}
89} // namespace eve::daynight
float duration
ActiveSource owned
HSQUIRRELVM vm
Definition ECS.cpp:20
HSQOBJECT cls
Definition ECS.cpp:21
std::string message
The single Squirrel projection for common Result, Status and Value.
Explicit Value/Owned/Borrowed semantics at the Squirrel boundary.
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
static Result< Duration > fromSeconds(double seconds)
Convert finite seconds to the nearest nanosecond.
Definition Time.cpp:16
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
static Result< Value > fromJson(std::string_view json)
Parse one strict JSON value into an owning Value.
Definition Value.cpp:57
static Value array(Array value)
Compatibility factory for an array value.
Definition Value.h:112
static Value object(Object value)
Compatibility factory for an object value.
Definition Value.h:114
DayNight module — a time-of-day cycle that drives the sun, sky and light.
Definition DayNight.h:94
static Result< SkyProfile > decode(const Value &document)
Validate a complete profile without creating GPU resources or changing any runtime.
Owns independent sky simulation and its prepared atmospheric contributor.
Definition SkyRuntime.h:46
static Result< std::unique_ptr< SkyRuntime > > prepare(graphics::Graphics &graphics, const SkyRuntimeSettings &settings, const graphics::SkyAtmosphereParameters &atmosphere, const graphics::SkyWispsLayer *wisps=nullptr)
Validate settings and prepare all atmospheric resources before publication.
Result< void > attach()
Attach the prepared main-view and reflection contributors, idempotently.
Result< void > advance(Duration duration)
Advance one simulation clock and atomically publish solar lighting/cloud phase; invalid time preserve...
SkyRuntimeFrame frame() const noexcept
Copy current simulation and solar lighting without advancing either.
void detach() noexcept
Unregister both contributors; simulation and prepared resources remain owned.
static Result< SkyWispsAsset > generate(uint32_t seed)
Generate a complete independent sky using a named procedural-v1 seed.
static Result< SkyWispsAsset > load(const std::string &manifestPath)
Read and decode the complete asset before publishing owned data.
std::variant< std::monostate, std::int64_t, double, std::string, bool > Value
Definition Database.h:26
void exposeSkyScriptBindings(ssq::Table &table, ssq::Class &daynightClass)
Register independent sky bindings on the VM/graphics owner thread.
Result< int > invalid(std::string message)
Invalid.
ssq::Table projectStatusResult(HSQUIRRELVM vm, const Status &status)
Project a checked native status that carries no payload.
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
eve::Result< ssq::Object > makeOwnedSquirrelInstance(HSQUIRRELVM vm, Owned< T > object)
Creates a Squirrel instance that owns a C++ wrapper through a release hook.