Skip to content
Flecs v4.1
impl.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/mixins/script/impl.hpp
3 * @brief Script implementation.
4 */
5
6#pragma once
7
8#include "builder.hpp"
9
10namespace flecs
11{
12
14 ecs_entity_t e = ecs_script_init(world_, &desc_);
15 return flecs::entity(world_, e);
16}
17
18inline flecs::entity function_builder::build() const {
19 ecs_entity_t e = is_method_
20 ? ecs_method_init(world_, &desc_)
21 : ecs_function_init(world_, &desc_);
22 return flecs::entity(world_, e);
23}
24
25template <typename T>
26inline flecs::entity world::const_var(const char *name, const T& value,
27 flecs::entity_t parent) const
28{
29 ecs_const_var_desc_t desc = {};
30 desc.name = name;
31 desc.parent = parent ? parent : ecs_get_scope(world_);
32 desc.type = _::type<T>::id(world_);
33 desc.value = const_cast<T*>(&value);
35}
36
37template <typename T>
38inline flecs::entity world::mut_var(const char *name, const T& value,
39 flecs::entity_t parent) const
40{
41 ecs_mut_var_desc_t desc = {};
42 desc.name = name;
43 desc.parent = parent ? parent : ecs_get_scope(world_);
44 desc.type = _::type<T>::id(world_);
45 desc.value = const_cast<T*>(&value);
47}
48
49template <typename T>
50inline int world::set_mut_var(const char *name, const T& value) const {
52 world_, 0, name, "::", "::", false);
53 if (!var) {
54 return -1;
55 }
56 char *path = ecs_get_path(world_, var);
57 int result = ecs_mut_var_set_w_type(world_, path,
58 _::type<T>::id(world_), ECS_SIZEOF(T), &value);
59 ecs_os_free(path);
60 return result;
61}
62
63namespace _ {
64
65 inline ecs_value_t get_const_var(const flecs::world_t *world, const char *name) {
67 world, 0, name, "::", "::", false);
68 if (!v) {
69 ecs_warn("unresolved const variable '%s', returning default", name);
70 return {};
71 }
72
73 ecs_value_t value = ecs_const_var_get(world, v);
74 if (value.ptr == nullptr) {
75 ecs_warn("entity '%s' is not a const variable, returning default",
76 name);
77 return {};
78 }
79
80 return value;
81 }
82
83 template <bool Mutable, typename T>
84 inline std::conditional_t<std::is_arithmetic_v<T>, T, const T&>
85 get_script_var(flecs::world_t *world, const char *name, const T& default_value) {
87 world, 0, name, "::", "::", false);
88 const char *kind = Mutable ? "mut" : "const";
89 if (!id) {
90 ecs_warn("unresolved %s variable '%s', returning default", kind, name);
91 return default_value;
92 }
93
94 ecs_value_t value;
95 if constexpr (Mutable) {
96 value = ecs_mut_var_get(world, id);
97 } else {
98 value = ecs_const_var_get(world, id);
99 }
100 if (!value.ptr) {
101 ecs_warn("entity '%s' is not a %s variable, returning default", name, kind);
102 return default_value;
103 }
104
105 flecs::id_t type = _::type<T>::id(world);
106 if (type == value.type) {
107 return *static_cast<const T*>(value.ptr);
108 }
109
110 if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>) {
111 ecs_meta_cursor_t cur = ecs_meta_cursor(world, value.type, value.ptr);
112 if constexpr (std::is_same_v<T, char>) {
113 return ecs_meta_get_char(&cur);
114 } else if constexpr (std::is_floating_point_v<T>) {
115 return static_cast<T>(ecs_meta_get_float(&cur));
116 } else if constexpr (std::is_signed_v<T>) {
117 return static_cast<T>(ecs_meta_get_int(&cur));
118 } else {
119 return static_cast<T>(ecs_meta_get_uint(&cur));
120 }
121 } else {
122 char *requested_type = ecs_get_path(world, type);
123 char *var_type = ecs_get_path(world, value.type);
124 ecs_warn("cannot cast %s variable '%s' from type '%s' to '%s', "
125 "returning default", kind, name, var_type, requested_type);
126 ecs_os_free(requested_type);
127 ecs_os_free(var_type);
128 return default_value;
129 }
130 }
131
132 inline const char* get_const_string(
133 const flecs::world_t *world, const char *name, ecs_value_t value, const char *default_value)
134 {
135 if (value.type == flecs::String) {
136 return *(static_cast<const char**>(value.ptr));
137 }
138
140 ECS_CONST_CAST(flecs::world_t*, world), value.type, value.ptr);
141 const char *result = ecs_meta_get_string(&cur);
142 if (!result) {
143 char *var_type = ecs_get_path(world, value.type);
144 ecs_warn("cannot cast const variable '%s' from type '%s' to "
145 "'flecs::string', returning default", name, var_type);
146 ecs_os_free(var_type);
147 return default_value;
148 }
149
150 return result;
151 }
152}
153
154template <typename T>
155inline T world::get_const_var(const char *name, const T& default_value) const {
156 return _::get_script_var<false>(world_, name, default_value);
157}
158
159template <typename T>
160void world::get_const_var(const char *name, T& out, const T& default_value) const {
161 out = _::get_script_var<false>(world_, name, default_value);
162}
163
164template <typename T>
165inline T world::get_mut_var(const char *name, const T& default_value) const {
166 return _::get_script_var<true>(world_, name, default_value);
167}
168
169template <typename T>
170void world::get_mut_var(const char *name, T& out, const T& default_value) const {
171 out = _::get_script_var<true>(world_, name, default_value);
172}
173
174
175template <>
176inline const char* world::get_const_var<const char*>(
177 const char *name,
178 const char* const& default_value) const
179{
180 ecs_value_t value = flecs::_::get_const_var(world_, name);
181 if (!value.ptr) {
182 return default_value;
183 }
184
185 return flecs::_::get_const_string(world_, name, value, default_value);
186}
187
188template <>
190 const char *name,
191 const char*& out,
192 const char* const& default_value) const
193{
194 ecs_value_t value = flecs::_::get_const_var(world_, name);
195 if (!value.ptr) {
196 out = default_value;
197 return;
198 }
199
200 out = flecs::_::get_const_string(world_, name, value, default_value);
201}
202
203
204namespace script {
205namespace _ {
206
207inline void init(flecs::world& world) {
208 world.component<Script>("flecs::script::Script");
209}
210
211}
212}
213
214}
struct ecs_value_t ecs_value_t
Value of a dynamic type.
#define ecs_warn(...)
Warning macro.
Definition log.h:314
struct ecs_meta_cursor_t ecs_meta_cursor_t
Type that enables iterating and populating a value using reflection data.
FLECS_API ecs_meta_cursor_t ecs_meta_cursor(const ecs_world_t *world, ecs_entity_t type, void *ptr)
Create meta cursor.
FLECS_API const char * ecs_meta_get_string(const ecs_meta_cursor_t *cursor)
Get field value as string.
FLECS_API double ecs_meta_get_float(const ecs_meta_cursor_t *cursor)
Get field value as float.
FLECS_API uint64_t ecs_meta_get_uint(const ecs_meta_cursor_t *cursor)
Get field value as unsigned integer.
FLECS_API char ecs_meta_get_char(const ecs_meta_cursor_t *cursor)
Get field value as char.
FLECS_API int64_t ecs_meta_get_int(const ecs_meta_cursor_t *cursor)
Get field value as signed integer.
FLECS_API ecs_value_t ecs_mut_var_get(const ecs_world_t *world, ecs_entity_t var)
Return the value for a mut variable.
FLECS_API int ecs_mut_var_set_w_type(ecs_world_t *world, const char *name, ecs_entity_t type, ecs_size_t size, const void *value)
Set the value of a mut variable.
FLECS_API ecs_entity_t ecs_function_init(ecs_world_t *world, const ecs_function_desc_t *desc)
Create new function.
FLECS_API ecs_entity_t ecs_mut_var_init(ecs_world_t *world, ecs_mut_var_desc_t *desc)
Create a mut variable that can be accessed by scripts.
struct ecs_mut_var_desc_t ecs_mut_var_desc_t
Used with ecs_mut_var_init().
FLECS_API ecs_entity_t ecs_script_init(ecs_world_t *world, const ecs_script_desc_t *desc)
Load managed script.
FLECS_API ecs_value_t ecs_const_var_get(const ecs_world_t *world, ecs_entity_t var)
Return the value for a const variable.
FLECS_API ecs_entity_t ecs_method_init(ecs_world_t *world, const ecs_function_desc_t *desc)
Create new method.
FLECS_API ecs_entity_t ecs_const_var_init(ecs_world_t *world, ecs_const_var_desc_t *desc)
Create a const variable that can be accessed by scripts.
ecs_id_t ecs_entity_t
An entity identifier.
Definition flecs.h:395
T get_const_var(const char *name, const T &default_value={}) const
Get the value of an exported script variable.
Definition impl.hpp:155
T get_mut_var(const char *name, const T &default_value={}) const
Get the value of an exported script mut variable.
Definition impl.hpp:165
flecs::component< T > component(Args &&... args) const
Find or register a component.
Definition impl.hpp:11
ecs_id_t id_t
ID type.
Definition c_types.hpp:20
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
ecs_world_t world_t
World type.
Definition c_types.hpp:18
#define ecs_get_path(world, child)
Get path from root.
Definition flecs_c.h:594
ecs_entity_t ecs_get_scope(const ecs_world_t *world)
Get the current scope.
ecs_entity_t ecs_lookup_path_w_sep(const ecs_world_t *world, ecs_entity_t parent, const char *path, const char *sep, const char *prefix, bool recursive)
Look up an entity from a path.
Script builder.
Int to enum.
Definition component.hpp:18
Used with ecs_const_var_init().
Definition script.h:1141
ecs_entity_t parent
Variable parent (namespace).
Definition script.h:1146
const char * name
Variable name.
Definition script.h:1143
ecs_entity_t type
Variable type.
Definition script.h:1149
void * value
Pointer to value of variable.
Definition script.h:1153
void * value
Pointer to value of variable.
Definition script.h:1246
ecs_entity_t type
Variable type.
Definition script.h:1242
const char * name
Variable name.
Definition script.h:1236
ecs_entity_t parent
Variable parent (namespace).
Definition script.h:1239
Value of a dynamic type.
Definition flecs.h:1068
void * ptr
Pointer to value.
Definition flecs.h:1070
Entity.
Definition entity.hpp:30
flecs::entity run() const
Run the script and return the script entity.
Definition impl.hpp:13
world_t * world_
Pointer to the underlying C world.
Definition world.hpp:1009
flecs::entity entity(Args &&... args) const
Create an entity.