Cogs.Core
Field.h
1#pragma once
2
3#include "Attributes.h"
4
5namespace Cogs
6{
7 namespace Reflection
8 {
9 class Type;
10
17 template<typename T, typename U>
18 struct FieldWrapper : public T
19 {
25 template<typename ClassType, typename FieldType>
26 FieldWrapper(const Name& name, FieldType ClassType::* field) : T(name, field) {}
27
29 FieldWrapper & setDefault(U value);
30
32 FieldWrapper & setRange(U min, U max);
33
35 FieldWrapper& setStep(U step);
36 };
37
41 enum struct FieldFlags : uint16_t
42 {
44 Default = 0,
46 Pointer = 0x1,
48 Array = 0x2,
50 NoSerialize = 0x4,
52 NoCodeGen = 0x8
53 };
54
56 [[nodiscard]]
57 inline FieldFlags operator|(FieldFlags lhs, FieldFlags rhs) { return static_cast<FieldFlags>(static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs)); }
58
60 [[nodiscard]]
61 inline FieldFlags operator&(FieldFlags lhs, FieldFlags rhs) { return static_cast<FieldFlags>(static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs)); }
62
64 inline FieldFlags & operator|=(FieldFlags & lhs, FieldFlags rhs) { lhs = static_cast<FieldFlags>(static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs)); return lhs; }
65
69 class COGSFOUNDATION_API Field
70 {
71 public:
82 template<typename ClassType, typename FieldType>
83 Field(const Name& name, FieldType ClassType::* field);
84
98 template<typename FieldType>
99 Field(const Name& name, const FieldType& dummy, size_t off);
100
107 template<typename ClassType, typename FieldType>
108 static FieldWrapper<Field, FieldType> create(const Name& name, FieldType ClassType::* field);
109
111 Field(const Field & other) = default;
112
114 Field(Field && other) noexcept = default;
115
117 Field & operator=(const Field & other) = default;
118
120 Field & operator=(Field && other) noexcept = default;
121
128 template<typename FieldValueType>
129 [[nodiscard]]
130 FieldValueType * getPtr(void * container) const
131 {
132 if constexpr (!std::is_array<FieldValueType>()) {
133 assert(sizeof(FieldValueType) <= byteSize && "Pointer overflows field size.");
134 }
135
136 return static_cast<FieldValueType*>(static_cast<void*>(static_cast<char*>(container) + offset));
137 }
138
145 template<typename FieldValueType>
146 [[nodiscard]]
147 const FieldValueType * getPtr(const void * container) const
148 {
149 return static_cast<const FieldValueType*>(static_cast<const void*>(static_cast<const char*>(container) + offset));
150 }
151
153 [[nodiscard]]
154 const Name & getName() const { return name; }
155
157 [[nodiscard]]
158 TypeId getTypeId() const { return typeId; }
159
161 [[nodiscard]]
162 size_t getOffset() const { return offset; }
163
165 [[nodiscard]]
166 FieldFlags getFlags() const { return fieldFlags; }
167
169 [[nodiscard]]
170 bool isSet(FieldFlags flag) const { return (fieldFlags & flag) == flag; }
171
173 [[nodiscard]]
174 size_t getDimensions() const { return arrayDimensions; }
175
177 Field& setSerialize(bool serialize)
178 {
179 if (serialize) {
180 unsetFlag(FieldFlags::NoSerialize);
181 }
182 else {
183 fieldFlags |= FieldFlags::NoSerialize;
184 }
185
186 return *this;
187 }
188
190 Field& setCodeGen(bool codegen)
191 {
192 if (codegen) {
193 unsetFlag(FieldFlags::NoCodeGen);
194 }
195 else {
196 fieldFlags |= FieldFlags::NoCodeGen;
197 }
198
199 return *this;
200 }
201
207 template<typename T>
208 Field & add(T attribute)
209 {
210#if defined( __EMSCRIPTEN__ )
211 // Only add runtime attributes for Cogs.js, skip code-gen attributes.
212 if (!attribute.isRuntime())
213 return *this;
214#endif
215 return attributes.add(*this, attribute);
216 }
217
223 template<typename T>
224 [[nodiscard]]
225 const T * get() const
226 {
227 return attributes.get<T>();
228 }
229
230 private:
231 void unsetFlag(FieldFlags flag) { this->fieldFlags = this->fieldFlags & static_cast<FieldFlags>(~uint32_t(flag)); }
232
235
237 FieldFlags fieldFlags = FieldFlags::Default;
238
241
243 size_t offset;
244
246 size_t byteSize;
247
249 size_t arrayDimensions = 0;
250
253
255 };
256 }
257}
258
259#include "Field.inl"
Field definition describing a single data member of a data structure.
Definition: Field.h:70
const Name & getName() const
Get the name of the field.
Definition: Field.h:154
const T * get() const
Retrieve an attribute of the given type from storage, if present.
Definition: Field.h:225
Field & add(T attribute)
Adds the given attribute.
Definition: Field.h:208
TypeId typeId
Type id of the field.
Definition: Field.h:252
size_t getDimensions() const
Get the array dimensions of the field. Returns zero if the field is not an array.
Definition: Field.h:174
Field & setSerialize(bool serialize)
Mark if field shall be serializable, e.g. value saved generating Scene. Default = true.
Definition: Field.h:177
FieldFlags getFlags() const
Get the field flags.
Definition: Field.h:166
bool isSet(FieldFlags flag) const
Checks if the given flag(s) is set. Requires exact bit match if test of several bits.
Definition: Field.h:170
size_t getOffset() const
Get the fields offset from the start of the structure in bytes.
Definition: Field.h:162
Field(Field &&other) noexcept=default
Default move constructor.
Field(const Field &other)=default
Default copy constructor.
Name name
Name of the field.
Definition: Field.h:240
Attributes attributes
Attribute storage.
Definition: Field.h:234
size_t byteSize
Size of the field in bytes.
Definition: Field.h:246
TypeId getTypeId() const
Get the type id of the field.
Definition: Field.h:158
FieldValueType * getPtr(void *container) const
Get a pointer to this field on the given container.
Definition: Field.h:130
Field & setCodeGen(bool codegen)
Mark if field shall have plumbing code generated. Default = true.
Definition: Field.h:190
const FieldValueType * getPtr(const void *container) const
Get a const pointer to this field on the given container.
Definition: Field.h:147
Field & operator=(const Field &other)=default
Default copy assignment operator.
size_t offset
Offset of the field in bytes from the beginning of the container.
Definition: Field.h:243
Field & operator=(Field &&other) noexcept=default
Default move assignment operator.
FieldFlags
Field flags.
Definition: Field.h:42
@ NoSerialize
Skip Serialize field.
@ NoCodeGen
Do not add code generation of plumbing for this field.
@ Array
Field is an array.
uint16_t TypeId
Built in type used to uniquely identify a single type instance.
Definition: Name.h:48
FieldFlags & operator|=(FieldFlags &lhs, FieldFlags rhs)
Or assignment operator.
Definition: Field.h:64
FieldFlags operator&(FieldFlags lhs, FieldFlags rhs)
And operator.
Definition: Field.h:61
FieldFlags operator|(FieldFlags lhs, FieldFlags rhs)
Or operator.
Definition: Field.h:57
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
Provides scoped storage for a raw pointer and corresponding deletion logic.
Definition: Pointer.h:66
Attribute storage for structures.
Definition: Attributes.h:130
Convenience wrapper for adding attributes during field creation in a type safe manner.
Definition: Field.h:19
FieldWrapper & setStep(U step)
Convenience method for setting the valid value step of the field.
Definition: Field.inl:69
FieldWrapper(const Name &name, FieldType ClassType::*field)
Construct the field wrapper, forwarding arguments to the underlying field.
Definition: Field.h:26
FieldWrapper & setDefault(U value)
Convenience method for setting the default value of the field.
Definition: Field.inl:53
FieldWrapper & setRange(U min, U max)
Convenience method for setting the valid value range of the field.
Definition: Field.inl:61
Represents an unique name.
Definition: Name.h:70