载入中...
搜索中...
未找到
PcgLoadingScreen.cpp
浏览该文件的文档.
2
4
5#include <cmath>
6#include <simplesquirrel/simplesquirrel.hpp>
7
8namespace eve::ui {
9namespace {
10
11bool validName(const std::string& value) { return !value.empty() && value.find('\0') == std::string::npos; }
12} // namespace
13
15 if (!std::isfinite(fadeOutSpeed) || fadeOutSpeed < 0.f)
16 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "fade-out speed must be finite and non-negative", {}, {},
17 "ui.pcgLoadingScreen"));
18 fadeOutSpeed_ = fadeOutSpeed;
19 return Result<void>::success();
20}
21
23 canvasVisible_ = true;
24 backgroundAlpha_ = 1.f;
25 progress_ = 0.f;
26}
27
29 if (!std::isfinite(progress)) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "load progress must be finite", {}, {},
30 "ui.pcgLoadingScreen"));
31 canvasVisible_ = true;
32 progress_ = progress;
33 if (progress >= 1.f) onLoadProgressEnded();
34 return Result<void>::success();
35}
36
38 fading_ = true;
39 progressVisible_ = false;
40 textVisible_ = false;
41}
42
44 timeoutOpen_ = true;
45 pendingMissingScenes_.clear();
46}
47
48Result<int> PcgLoadingScreen::addMissingScene(const std::string& terrainName, const std::string& impostorName) {
49 if (!timeoutOpen_)
51 "beginTimeout must be called before adding a missing scene", {}, {}, "ui.pcgLoadingScreen"));
52 if ((!terrainName.empty() && !validName(terrainName)) || (!impostorName.empty() && !validName(impostorName)))
54 "missing-scene names must not contain null characters", {}, {}, "ui.pcgLoadingScreen"));
55 pendingMissingScenes_.push_back({terrainName, impostorName, {}, {}});
56 return Result<int>::success(static_cast<int>(pendingMissingScenes_.size() - 1));
57}
58
59Result<void> PcgLoadingScreen::addReference(int sceneIndex, const std::string& objectName, bool impostor) {
60 if (!timeoutOpen_ || sceneIndex < 0 || static_cast<size_t>(sceneIndex) >= pendingMissingScenes_.size() ||
61 !validName(objectName))
62 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "an open timeout, valid scene index and nonempty object name are required", {}, {},
63 "ui.pcgLoadingScreen"));
64 auto& scene = pendingMissingScenes_[static_cast<size_t>(sceneIndex)];
65 (impostor ? scene.impostorReferences : scene.regularReferences).push_back(objectName);
66 return Result<void>::success();
67}
68
69Result<void> PcgLoadingScreen::addRegularReference(int sceneIndex, const std::string& objectName) {
70 return addReference(sceneIndex, objectName, false);
71}
72
73Result<void> PcgLoadingScreen::addImpostorReference(int sceneIndex, const std::string& objectName) {
74 return addReference(sceneIndex, objectName, true);
75}
76
78 if (!timeoutOpen_) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "beginTimeout must be called before endTimeout", {}, {},
79 "ui.pcgLoadingScreen"));
80 std::string message = "Pcg Loading Screen Timeout, closing down loading screen.\r\n";
81 message += "If you feel that there is no error but the terrain loading simply needs more time, try to increase the Timeout value in the Terrain Loader Manager.\r\n";
82 message += "The following scenes are still not loaded:\r\n";
83 for (const auto& scene : pendingMissingScenes_) {
84 if (!scene.regularReferences.empty()) {
85 message += "\r\n " + scene.terrainName + "\r\n Referencing Objects:\r\n";
86 for (const auto& name : scene.regularReferences) message += name + ", ";
87 }
88 if (!scene.impostorReferences.empty()) {
89 message += "\r\n " + scene.impostorName + "\r\n Referencing Objects:\r\n";
90 for (const auto& name : scene.impostorReferences) message += name + ", ";
91 }
92 message += "\r\n";
93 }
94 timeoutMessage_ = std::move(message);
95 pendingMissingScenes_.clear();
96 timeoutOpen_ = false;
98 return Result<void>::success();
99}
100
102 if (!std::isfinite(deltaTime) || deltaTime < 0.f)
103 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "frame delta time must be finite and non-negative", {}, {},
104 "ui.pcgLoadingScreen"));
105 if (fading_) {
106 backgroundAlpha_ -= deltaTime * fadeOutSpeed_;
107 if (backgroundAlpha_ <= 0.f) {
108 backgroundAlpha_ = 0.f;
109 canvasVisible_ = false;
110 fading_ = false;
111 }
112 }
113 return Result<void>::success();
114}
115
116void exposePcgLoadingScreenBindings(ssq::Table& table) {
117 auto c = table.addClass("PcgLoadingScreen", ssq::Class::Ctor<PcgLoadingScreen()>());
118 const auto vm = table.getHandle();
119 c.addFunc("configure", [vm](PcgLoadingScreen* self, float speed) {
120 return eve::script::projectResult(vm, self->configure(speed));
121 });
122 c.addFunc("onLoadProgressStarted", [](PcgLoadingScreen* self) { self->onLoadProgressStarted(); });
123 c.addFunc("onLoadProgressUpdated", [vm](PcgLoadingScreen* self, float progress) {
125 });
126 c.addFunc("onLoadProgressEnded", [](PcgLoadingScreen* self) { self->onLoadProgressEnded(); });
127 c.addFunc("beginTimeout", [](PcgLoadingScreen* self) { self->beginTimeout(); });
128 c.addFunc("addMissingScene", [vm](PcgLoadingScreen* self, const std::string& terrain,
129 const std::string& impostor) {
130 return eve::script::projectResult(vm, self->addMissingScene(terrain, impostor),
131 [](int value) { return eve::Value(value); });
132 });
133 c.addFunc("addRegularReference", [vm](PcgLoadingScreen* self, int index, const std::string& name) {
135 });
136 c.addFunc("addImpostorReference", [vm](PcgLoadingScreen* self, int index, const std::string& name) {
138 });
139 c.addFunc("endTimeout", [vm](PcgLoadingScreen* self) {
141 });
142 c.addFunc("tick", [vm](PcgLoadingScreen* self, float dt) {
143 return eve::script::projectResult(vm, self->tick(dt));
144 });
145 c.addFunc("getCanvasVisible", [](const PcgLoadingScreen* self) { return self->getCanvasVisible(); });
146 c.addFunc("getProgressVisible", [](const PcgLoadingScreen* self) { return self->getProgressVisible(); });
147 c.addFunc("getTextVisible", [](const PcgLoadingScreen* self) { return self->getTextVisible(); });
148 c.addFunc("getFading", [](const PcgLoadingScreen* self) { return self->getFading(); });
149 c.addFunc("getProgress", [](const PcgLoadingScreen* self) { return self->getProgress(); });
150 c.addFunc("getBackgroundAlpha", [](const PcgLoadingScreen* self) { return self->getBackgroundAlpha(); });
151 c.addFunc("getTimeoutMessage", [](const PcgLoadingScreen* self) { return self->getTimeoutMessage(); });
152}
153
154} // namespace eve::ui
double value
std::string terrain
HSQUIRRELVM vm
Definition ECS.cpp:20
std::string message
std::int32_t c
std::string name
std::weak_ptr< PrimitiveScene > scene
The single Squirrel projection for common Result, Status and Value.
uint32_t index
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
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Caller-owned loading-screen state driven by Pcg terrain load-progress events.
Result< void > tick(float deltaTime)
Advance background fade using explicit frame delta time.
void beginTimeout() noexcept
Start a transactional missing-scene diagnostic.
Result< void > endTimeout()
Publish the timeout warning and begin fade-out.
Result< int > addMissingScene(const std::string &terrainName, const std::string &impostorName)
Append one missing terrain scene and return its stable index in the pending diagnostic.
void onLoadProgressStarted() noexcept
Reset canvas, background alpha and progress when load tracking starts.
float getProgress() const noexcept
Return current progress without clamping Pcg's event value.
const std::string & getTimeoutMessage() const noexcept
Return the most recently published timeout warning.
void onLoadProgressEnded() noexcept
Hide progress/text and begin fading the background.
bool getTextVisible() const noexcept
Return whether the loading text is enabled.
Result< void > onLoadProgressUpdated(float progress)
Publish progress; values at least one automatically begin fade-out.
Result< void > addRegularReference(int sceneIndex, const std::string &objectName)
Append a regular referencing object name to a pending scene.
Result< void > configure(float fadeOutSpeed)
Set the alpha units removed per second.
Result< void > addImpostorReference(int sceneIndex, const std::string &objectName)
Append an impostor referencing object name to a pending scene.
bool getFading() const noexcept
Return whether fade-out is running.
float getBackgroundAlpha() const noexcept
Return current background alpha.
bool getCanvasVisible() const noexcept
Return whether the loading canvas is enabled.
bool getProgressVisible() const noexcept
Return whether the progress bar is active.
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
void exposePcgLoadingScreenBindings(ssq::Table &table)
Register Pcg loading-screen bindings.
WidgetDesc progress(float fraction, std::string id, std::string overlay)
Progress bar; fraction is clamped to [0,1].
Definition Widget.cpp:395