载入中...
搜索中...
未找到
ProcgenCapabilities.cpp
浏览该文件的文档.
1#include "common/Capability.h"
3#include "procgen/Procgen.h"
4
5#include <cstdint>
6#include <cstdlib>
7#include <string>
8#include <utility>
9#include <vector>
10
11namespace eve::procgen {
12namespace {
13
14class ProcgenQueryImpl final : public eve::IProcgenQuery {
15public:
16 Procgen *pg() { return eve::ModuleManager::getInstance<Procgen>("Procgen"); }
17
18 std::vector<std::string> algorithms() override {
19 std::vector<std::string> out;
20 if (auto *p = pg())
21 for (int i = 0; i < p->getAlgorithmCount(); ++i) out.push_back(p->getAlgorithmId(i));
22 return out;
23 }
24
25 std::vector<std::string> meshRecipes() override {
26 std::vector<std::string> out;
27 if (auto *p = pg())
28 for (int i = 0; i < p->getMeshRecipeCount(); ++i)
29 out.push_back(p->getMeshRecipeId(i));
30 return out;
31 }
32
33 std::vector<std::string> textureRecipes() override {
34 std::vector<std::string> out;
35 if (auto *p = pg())
36 for (int i = 0; i < p->getTextureRecipeCount(); ++i)
37 out.push_back(p->getTextureRecipeId(i));
38 return out;
39 }
40
41 std::vector<std::string> pbrRecipes() override {
42 std::vector<std::string> out;
43 if (auto *p = pg())
44 for (int i = 0; i < p->getPbrRecipeCount(); ++i) out.push_back(p->getPbrRecipeId(i));
45 return out;
46 }
47
48 std::string generateMap(const std::string &algorithm, int width, int height, uint32_t seed,
49 const std::vector<std::pair<std::string, std::string>> &params,
50 std::string *err) override {
51 auto *p = pg();
52 if (!p) {
53 if (err) *err = "Procgen module not available";
54 return {};
55 }
56 auto parResult = Procgen::newParamsHandle();
57 if (!parResult) {
58 if (err) *err = "parameter allocation failed";
59 return {};
60 }
61 const auto parRef = std::move(parResult).takeValue();
62 auto parView = Procgen::resolve(parRef);
63 if (!parView.isBound()) {
64 Procgen::release(parRef).ignore("release failed after stale parameter lookup");
65 if (err) *err = "parameter handle became stale";
66 return {};
67 }
68 auto *par = parView.get();
69 par->setSize(width, height);
70 par->setSeed(seed);
71 for (const auto &kv : params) {
72 if (kv.second.find_first_not_of("0123456789-") == std::string::npos)
73 par->setInt(kv.first, std::atoi(kv.second.c_str()));
74 else
75 par->setString(kv.first, kv.second);
76 }
77 auto gridResult = p->generateHandle(algorithm, parRef);
78 if (!gridResult) {
79 Procgen::release(parRef).ignore("release failed after map generation failure");
80 if (err) *err = "generate failed: " + gridResult.status().describe();
81 return {};
82 }
83 auto jsonResult = p->gridToJson(std::move(gridResult).takeValue());
84 if (!jsonResult) {
85 Procgen::release(parRef).ignore("release failed after map serialization failure");
86 if (err) *err = "serialization failed: " + jsonResult.status().describe();
87 return {};
88 }
89 std::string json = std::move(jsonResult).takeValue();
90 Procgen::release(parRef).ignore("release failed after map generation");
91 return json;
92 }
93
94 std::string buildMesh(const std::string &recipe, uint32_t seed, int width, int height,
95 int depth, std::string *err) override {
96 auto *p = pg();
97 if (!p) {
98 if (err) *err = "Procgen module not available";
99 return {};
100 }
101 auto parResult = Procgen::newParamsHandle();
102 if (!parResult) {
103 if (err) *err = "parameter allocation failed";
104 return {};
105 }
106 const auto parRef = std::move(parResult).takeValue();
107 auto parView = Procgen::resolve(parRef);
108 if (!parView.isBound()) {
109 Procgen::release(parRef).ignore("release failed after stale parameter lookup");
110 if (err) *err = "parameter handle became stale";
111 return {};
112 }
113 auto *par = parView.get();
114 par->setSeed(seed);
115 if (width > 0) par->setInt("width", width);
116 if (height > 0) par->setInt("height", height);
117 if (depth > 0) par->setInt("depth", depth);
118 auto meshResult = p->buildMeshHandle(recipe, parRef);
119 if (!meshResult) {
120 Procgen::release(parRef).ignore("release failed after mesh generation failure");
121 if (err) *err = "build failed: " + meshResult.status().describe();
122 return {};
123 }
124 const auto meshRef = std::move(meshResult).takeValue();
125 auto mesh = p->resolveMeshBuild(meshRef);
126 if (!mesh.isBound()) {
127 p->releaseMeshBuild(meshRef).ignore("release failed after stale mesh lookup");
128 Procgen::release(parRef).ignore("release failed after stale mesh lookup");
129 if (err) *err = "build failed: mesh handle became stale";
130 return {};
131 }
132 std::string json = "{\"vertices\":" + std::to_string(mesh->getVertexCount()) +
133 ",\"triangles\":" + std::to_string(mesh->getIndexCount() / 3) + "}";
134 p->releaseMeshBuild(meshRef).ignore("release mesh after capability query");
135 Procgen::release(parRef).ignore("release failed after mesh generation");
136 return json;
137 }
138};
139
140} // namespace
141
143 static ProcgenQueryImpl impl;
144 eve::cap::provide<eve::IProcgenQuery>(&impl);
145}
146
147} // namespace eve::procgen
void * impl
glm::vec4 p[6]
std::uint32_t height
std::uint32_t width
std::uint32_t seed
Definition PointSet.cpp:807
Mesh * mesh
std::uint32_t depth
Procedural generation query surface (provided by the procgen module).
void ignore(std::string_view reason={}) const noexcept
Explicitly discard this result after documenting the reason.
Definition Result.h:537
static eve::script::Borrowed< Params > resolve(ProcgenParamsHandleRef reference) noexcept
Resolves parameters as a non-owning observation.
Definition Procgen.cpp:403
static eve::Result< ProcgenParamsHandleRef > newParamsHandle()
Allocates module-owned generation parameters.
Definition Procgen.cpp:398
static eve::Result< void > release(ProcgenParamsHandleRef reference)
Releases module-owned parameters.
Definition Procgen.cpp:409
std::vector< ParamSpec > params
void registerProcgenCapabilities()
Registers procgen capabilities.