1 | #pragma once |
2 | |
3 | #include <array> |
4 | #include <type_traits> |
5 | #include <basis/seadRawPrint.h> |
6 | #include <basis/seadTypes.h> |
7 | #include <gfx/seadColor.h> |
8 | #include <hostio/seadHostIOCurve.h> |
9 | #include <hostio/seadHostIOReflexible.h> |
10 | #include <math/seadQuat.h> |
11 | #include <math/seadVector.h> |
12 | #include <prim/seadSafeString.h> |
13 | #include "utility/aglResParameter.h" |
14 | |
15 | namespace sead { |
16 | class Heap; |
17 | class XmlElement; |
18 | } // namespace sead |
19 | |
20 | namespace agl::utl { |
21 | |
22 | class IParameterObj; |
23 | |
24 | class ParameterBase { |
25 | public: |
26 | enum class ParameterType { |
27 | Bool = 0, |
28 | F32 = 1, |
29 | Int = 2, |
30 | Vec2 = 3, |
31 | Vec3 = 4, |
32 | Vec4 = 5, |
33 | Color = 6, |
34 | String32 = 7, |
35 | String64 = 8, |
36 | Curve1 = 9, |
37 | Curve2 = 10, |
38 | Curve3 = 11, |
39 | Curve4 = 12, |
40 | BufferInt = 13, |
41 | BufferF32 = 14, |
42 | String256 = 15, |
43 | Quat = 16, |
44 | U32 = 17, |
45 | BufferU32 = 18, |
46 | BufferBinary = 19, |
47 | StringRef = 20, |
48 | Special = 21, |
49 | }; |
50 | |
51 | ParameterBase(); |
52 | ParameterBase(const sead::SafeString& name, const sead::SafeString& label, |
53 | IParameterObj* param_obj); |
54 | ParameterBase(const sead::SafeString& name, const sead::SafeString& label, |
55 | const sead::SafeString& meta, IParameterObj* param_obj); |
56 | virtual ~ParameterBase() { ; } |
57 | |
58 | void initializeListNode(const sead::SafeString& name, const sead::SafeString& label, |
59 | const sead::SafeString& meta, IParameterObj* param_obj); |
60 | |
61 | u32 getNameHash() const { return mNameHash; } |
62 | sead::SafeString getParameterName() const; |
63 | sead::SafeString getName() const { return getParameterName(); } |
64 | sead::SafeString getLabel() const; |
65 | sead::SafeString getMeta() const; |
66 | |
67 | ParameterBase* getNext() const { return mNext; } |
68 | |
69 | static const char* getTagName(); |
70 | static const char* getAttributeNameString(); |
71 | static const char* getAttributeTypeString(); |
72 | static const char* getAttributeValueString(); |
73 | static const char* getParameterTypeName(ParameterType type); |
74 | |
75 | bool isSafeType(ParameterType type) const; |
76 | bool verifyType(ParameterType type) const; |
77 | |
78 | virtual bool copy(const ParameterBase& other); |
79 | virtual void copyUnsafe(const ParameterBase& other); |
80 | virtual bool copyLerp(const ParameterBase& param1, const ParameterBase& param2, f32 t); |
81 | |
82 | #ifdef SEAD_DEBUG |
83 | virtual void genMessageParameter(sead::hostio::Context* context); |
84 | void genMessageParameter(sead::hostio::Context* context, const sead::SafeString&); |
85 | virtual void listenPropertyEventParameter(sead::hostio::Reflexible* reflexible, |
86 | const sead::hostio::PropertyEvent* event); |
87 | #endif |
88 | |
89 | virtual void writeToXML(sead::XmlElement* element, sead::Heap* heap); |
90 | virtual bool readFromXML(const sead::XmlElement& element, bool x); |
91 | |
92 | virtual ParameterType getParameterType() const = 0; |
93 | virtual const void* ptr() const = 0; |
94 | virtual void* ptr() = 0; |
95 | virtual const void* typePtr() const = 0; |
96 | virtual void* typePtr() = 0; |
97 | virtual u32 size() const = 0; |
98 | virtual u32 calcBinarizeSize() const { return size(); } |
99 | virtual ParameterBase* clone(sead::Heap* heap, IParameterObj* obj) const = 0; |
100 | |
101 | void applyResource(ResParameter res); |
102 | void applyResource(ResParameter res, f32 t); |
103 | void applyString(const sead::SafeString& string, bool x); |
104 | virtual void postApplyResource_(const void*, size_t) {} |
105 | void createByTypeName(const sead::SafeString& a, const sead::SafeString& b); |
106 | |
107 | virtual bool isBinary() const { return false; } |
108 | virtual bool isBinaryInternalBuffer() const { return true; } |
109 | bool isInterpolatable() const; |
110 | size_t binarize(void* binary) const; |
111 | bool makeZero(); |
112 | |
113 | static u32 calcHash(const sead::SafeString& key); |
114 | |
115 | template <typename T> |
116 | T* ptrT() { |
117 | return static_cast<T*>(ptr()); |
118 | } |
119 | |
120 | template <typename T> |
121 | const T* ptrT() const { |
122 | return static_cast<const T*>(ptr()); |
123 | } |
124 | |
125 | protected: |
126 | friend class IParameterObj; |
127 | |
128 | template <typename T> |
129 | void copyLerp_(const ParameterBase& param1, const ParameterBase& param2, f32 t); |
130 | |
131 | u32 mNameHash; |
132 | ParameterBase* mNext; |
133 | |
134 | #ifdef SEAD_DEBUG |
135 | const char* mName; |
136 | const char* mLabel; |
137 | const char* mMeta; |
138 | #endif |
139 | }; |
140 | |
141 | using ParameterType = ParameterBase::ParameterType; |
142 | |
143 | template <typename T> |
144 | class Parameter : public ParameterBase { |
145 | public: |
146 | Parameter() = default; |
147 | |
148 | explicit Parameter(const T& value) : mValue(value) {} |
149 | |
150 | Parameter(const T& value, const sead::SafeString& name, IParameterObj* obj) { |
151 | initializeParameter(value, name, name, obj); |
152 | } |
153 | |
154 | Parameter(const T& value, const sead::SafeString& name, const sead::SafeString& label, |
155 | IParameterObj* obj) { |
156 | initializeParameter(value, name, label, obj); |
157 | } |
158 | |
159 | Parameter(const T& value, const sead::SafeString& name, const sead::SafeString& label, |
160 | const sead::SafeString& meta, IParameterObj* obj) { |
161 | initializeParameter(value, name, label, meta, obj); |
162 | } |
163 | |
164 | ~Parameter() override { ; } |
165 | |
166 | ParameterType getParameterType() const override { |
167 | if constexpr (std::is_pointer<T>()) |
168 | return ParameterType::Special; |
169 | else if constexpr (std::is_same<T, bool>()) |
170 | return ParameterType::Bool; |
171 | else if constexpr (std::is_same<T, f32>()) |
172 | return ParameterType::F32; |
173 | else if constexpr (std::is_same<T, s32>()) |
174 | return ParameterType::Int; |
175 | else if constexpr (std::is_same<T, sead::Vector2f>()) |
176 | return ParameterType::Vec2; |
177 | else if constexpr (std::is_same<T, sead::Vector3f>()) |
178 | return ParameterType::Vec3; |
179 | else if constexpr (std::is_same<T, sead::Vector4f>()) |
180 | return ParameterType::Vec4; |
181 | else if constexpr (std::is_same<T, sead::Color4f>()) |
182 | return ParameterType::Color; |
183 | else if constexpr (std::is_same<T, sead::FixedSafeString<32>>()) |
184 | return ParameterType::String32; |
185 | else if constexpr (std::is_same<T, sead::FixedSafeString<64>>()) |
186 | return ParameterType::String64; |
187 | // TODO: curve1-4 |
188 | else if constexpr (std::is_same<T, sead::FixedSafeString<256>>()) |
189 | return ParameterType::String256; |
190 | else if constexpr (std::is_same<T, sead::Quatf>()) |
191 | return ParameterType::Quat; |
192 | else if constexpr (std::is_same<T, u32>()) |
193 | return ParameterType::U32; |
194 | else if constexpr (std::is_same<T, sead::SafeString>()) |
195 | return ParameterType::StringRef; |
196 | else |
197 | static_assert(!std::is_same<T, T>(), "Unknown type" ); |
198 | } |
199 | |
200 | const void* ptr() const override { |
201 | if constexpr (std::is_base_of<sead::SafeString, T>()) { |
202 | return mValue.cstr(); |
203 | } else { |
204 | return &mValue; |
205 | } |
206 | } |
207 | |
208 | void* ptr() override { |
209 | if constexpr (std::is_same<T, sead::SafeString>()) { |
210 | SEAD_ASSERT_MSG(false, "Can't access." ); |
211 | return nullptr; |
212 | } else if constexpr (std::is_base_of<sead::BufferedSafeString, T>()) { |
213 | return mValue.getBuffer(); |
214 | } else { |
215 | return &mValue; |
216 | } |
217 | } |
218 | |
219 | const void* typePtr() const override { return &mValue; } |
220 | void* typePtr() override { return &mValue; } |
221 | |
222 | u32 size() const override { |
223 | if constexpr (std::is_same<T, sead::SafeString>()) |
224 | return 8; |
225 | else if constexpr (std::is_same<T, sead::FixedSafeString<32>>()) |
226 | return 32; |
227 | else if constexpr (std::is_same<T, sead::FixedSafeString<64>>()) |
228 | return 64; |
229 | else if constexpr (std::is_same<T, sead::FixedSafeString<256>>()) |
230 | return 256; |
231 | else |
232 | return sizeof(T); |
233 | } |
234 | |
235 | u32 calcBinarizeSize() const override { |
236 | if constexpr (std::is_base_of<sead::SafeString, T>()) { |
237 | return mValue.calcLength() + 1; |
238 | } else { |
239 | return size(); |
240 | } |
241 | } |
242 | |
243 | ParameterBase* clone(sead::Heap* heap, IParameterObj* obj) const override { |
244 | return new (heap) Parameter<T>(mValue, getName(), getLabel(), getMeta(), obj); |
245 | } |
246 | |
247 | void initializeParameter(const T& value, const sead::SafeString& name, |
248 | const sead::SafeString& label, IParameterObj* obj) { |
249 | initializeListNode(name, label, "" , obj); |
250 | mValue = value; |
251 | |
252 | if constexpr (std::is_same<T, sead::SafeString>()) { |
253 | SEAD_ASSERT_MSG(!sead::MemUtil::isStack(value.cstr()), "%p is in stack" , value.cstr()); |
254 | } |
255 | } |
256 | |
257 | void initializeParameter(const T& value, const sead::SafeString& name, |
258 | const sead::SafeString& label, const sead::SafeString& meta, |
259 | IParameterObj* obj) { |
260 | initializeListNode(name, label, meta, obj); |
261 | mValue = value; |
262 | |
263 | if constexpr (std::is_same<T, sead::SafeString>()) { |
264 | SEAD_ASSERT_MSG(!sead::MemUtil::isStack(value.cstr()), "%p is in stack" , value.cstr()); |
265 | } |
266 | } |
267 | |
268 | /// Alias of initializeParameter. |
269 | void init(const T& value, const sead::SafeString& name, IParameterObj* obj) { |
270 | initializeParameter(value, name, name, obj); |
271 | } |
272 | |
273 | /// Alias of initializeParameter. |
274 | void init(const T& value, const sead::SafeString& name, const sead::SafeString& label, |
275 | IParameterObj* obj) { |
276 | initializeParameter(value, name, label, obj); |
277 | } |
278 | |
279 | /// Alias of initializeParameter. |
280 | void init(const T& value, const sead::SafeString& name, const sead::SafeString& label, |
281 | const sead::SafeString& meta, IParameterObj* obj) { |
282 | initializeParameter(value, name, label, meta, obj); |
283 | } |
284 | |
285 | T& ref() { return mValue; } |
286 | const T& ref() const { return mValue; } |
287 | |
288 | T& operator*() { return mValue; } |
289 | const T& operator*() const { return mValue; } |
290 | T* operator->() { return &mValue; } |
291 | const T* operator->() const { return &mValue; } |
292 | |
293 | Parameter& operator=(const T& value) { |
294 | mValue = value; |
295 | return *this; |
296 | } |
297 | |
298 | protected: |
299 | T mValue; |
300 | }; |
301 | |
302 | template <typename T> |
303 | class ParameterBuffer : public Parameter<T*> { |
304 | public: |
305 | ParameterBuffer(sead::Heap* heap, s32 num) { |
306 | SEAD_ASSERT(!isBinaryInternalBuffer()); |
307 | this->mValue = new (heap) T[num]; |
308 | mBufferSize = num; |
309 | mBufferAllocated = true; |
310 | |
311 | for (s32 i = 0; i < num; ++i) |
312 | this->mValue[i] = {}; |
313 | } |
314 | |
315 | ~ParameterBuffer() override { freeBuffer(); } |
316 | |
317 | void freeBuffer() { |
318 | if (!mBufferAllocated) |
319 | return; |
320 | |
321 | if (this->mValue) |
322 | delete[] this->mValue; |
323 | mBufferAllocated = false; |
324 | } |
325 | |
326 | ParameterType getParameterType() const override { |
327 | if constexpr (std::is_same<T, s32>()) |
328 | return ParameterType::BufferInt; |
329 | else if constexpr (std::is_same<T, f32>()) |
330 | return ParameterType::BufferF32; |
331 | else if constexpr (std::is_same<T, u32>()) |
332 | return ParameterType::BufferU32; |
333 | else if constexpr (std::is_same<T, u8>()) |
334 | return ParameterType::BufferBinary; |
335 | else |
336 | static_assert(!std::is_same<T, T>(), "Unknown type" ); |
337 | } |
338 | |
339 | const void* ptr() const override { return this->mValue; } |
340 | void* ptr() override { return this->mValue; } |
341 | u32 size() const override { return sizeof(T) * mBufferSize; } |
342 | |
343 | void postApplyResource_(const void* data, size_t size) override { |
344 | if (isBinaryInternalBuffer()) |
345 | return; |
346 | this->mValue = data; |
347 | mBufferSize = size / sizeof(T); |
348 | } |
349 | |
350 | bool isBinary() const override { return true; } |
351 | bool isBinaryInternalBuffer() const override { return mBufferAllocated; } |
352 | |
353 | protected: |
354 | s32 mBufferSize; |
355 | bool mBufferAllocated; |
356 | }; |
357 | |
358 | class ParameterDirection3f : public Parameter<sead::Vector3f> { |
359 | public: |
360 | ~ParameterDirection3f() override = default; |
361 | |
362 | #ifdef SEAD_DEBUG |
363 | void genMessageParameter(sead::hostio::Context* context) override; |
364 | void listenPropertyEventParameter(sead::hostio::Reflexible* reflexible, |
365 | const sead::hostio::PropertyEvent* event) override; |
366 | #endif |
367 | }; |
368 | |
369 | template <u32 N> |
370 | class ParameterCurve : public ParameterBase { |
371 | public: |
372 | ParameterCurve(const sead::SafeString& name, const sead::SafeString& label, |
373 | IParameterObj* param_obj); |
374 | |
375 | void reset(); |
376 | |
377 | bool copy(const ParameterBase& other) override; |
378 | void copyUnsafe(const ParameterBase& other) override; |
379 | |
380 | void writeToXML(sead::XmlElement* element, sead::Heap* heap) override; |
381 | bool readFromXML(const sead::XmlElement& element, bool x) override; |
382 | |
383 | ParameterType getParameterType() const override; |
384 | |
385 | const void* ptr() const override { return mCurveData.data(); } |
386 | void* ptr() override { return mCurveData.data(); } |
387 | const void* typePtr() const override { return mCurveData.data(); } |
388 | void* typePtr() override { return mCurveData.data(); } |
389 | u32 size() const override { return sizeof(mCurveData); } |
390 | |
391 | ParameterBase* clone(sead::Heap* heap, IParameterObj* obj) const override; |
392 | |
393 | void postApplyResource_(const void*, size_t size) override; |
394 | |
395 | #ifdef SEAD_DEBUG |
396 | void genMessageParameter(sead::hostio::Context* context) override; |
397 | virtual void genMessageParameterUnit(sead::hostio::Context* context, s32, |
398 | const sead::SafeString&, const sead::SafeString&); |
399 | #endif |
400 | |
401 | static constexpr u32 cUnitCurveParamNum = 30; |
402 | |
403 | protected: |
404 | std::array<sead::hostio::Curve<f32>, N> mCurves; |
405 | std::array<sead::hostio::CurveData, N> mCurveData; |
406 | }; |
407 | |
408 | inline ResParameter getResParameter(const agl::utl::ResParameterObj& obj, |
409 | const sead::SafeString& name) { |
410 | const s32 idx = obj.searchIndex(ParameterBase::calcHash(name)); |
411 | if (idx == -1) |
412 | return {}; |
413 | |
414 | return obj.getResParameter(idx); |
415 | } |
416 | |
417 | inline ResParameterObj getResParameterObj(const agl::utl::ResParameterList& list, |
418 | const sead::SafeString& name) { |
419 | const s32 idx = list.searchObjIndex(ParameterBase::calcHash(name)); |
420 | if (idx == -1) |
421 | return {}; |
422 | |
423 | return list.getResParameterObj(idx); |
424 | } |
425 | |
426 | inline ResParameterList getResParameterList(const agl::utl::ResParameterList& list, |
427 | const sead::SafeString& name) { |
428 | const s32 idx = list.searchListIndex(ParameterBase::calcHash(name)); |
429 | if (idx == -1) |
430 | return {}; |
431 | |
432 | return list.getResParameterList(idx); |
433 | } |
434 | |
435 | } // namespace agl::utl |
436 | |
437 | #define AGL_UTILS_PARAMETER_H_ |
438 | #include "utility/aglParameterCurve.hpp" |
439 | #undef AGL_UTILS_PARAMETER_H_ |
440 | |