forked from OctaForge/libcubescript
initial support for "threads"
parent
bd008ffb46
commit
fb78b4acdd
|
@ -352,6 +352,32 @@ struct OSTD_EXPORT cs_state {
|
|||
cs_state(cs_alloc_cb func = cs_default_alloc, void *data = nullptr);
|
||||
virtual ~cs_state();
|
||||
|
||||
cs_state(cs_state const &) = delete;
|
||||
cs_state(cs_state &&s) {
|
||||
swap(s);
|
||||
}
|
||||
|
||||
cs_state &operator=(cs_state const &) = delete;
|
||||
cs_state &operator=(cs_state &&s) {
|
||||
swap(s);
|
||||
s.destroy();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void destroy();
|
||||
|
||||
void swap(cs_state &s) {
|
||||
std::swap(p_state, s.p_state);
|
||||
std::swap(p_callstack, s.p_callstack);
|
||||
std::swap(identflags, s.identflags);
|
||||
std::swap(p_pstate, s.p_pstate);
|
||||
std::swap(p_inloop, s.p_inloop);
|
||||
std::swap(p_owner, s.p_owner);
|
||||
std::swap(p_callhook, s.p_callhook);
|
||||
}
|
||||
|
||||
cs_state new_thread();
|
||||
|
||||
cs_hook_cb set_call_hook(cs_hook_cb func);
|
||||
cs_hook_cb const &get_call_hook() const;
|
||||
cs_hook_cb &get_call_hook();
|
||||
|
@ -463,12 +489,15 @@ struct OSTD_EXPORT cs_state {
|
|||
virtual void print_var(cs_var *v);
|
||||
|
||||
private:
|
||||
OSTD_LOCAL cs_state(cs_shared_state *s);
|
||||
|
||||
cs_ident *add_ident(cs_ident *id);
|
||||
|
||||
void *alloc(void *ptr, size_t olds, size_t news);
|
||||
OSTD_LOCAL void *alloc(void *ptr, size_t olds, size_t news);
|
||||
|
||||
cs_gen_state *p_pstate = nullptr;
|
||||
int p_inloop = 0;
|
||||
bool p_owner = false;
|
||||
|
||||
char p_errbuf[512];
|
||||
|
||||
|
|
|
@ -311,6 +311,7 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
func(data, nullptr, 0, sizeof(cs_shared_state))
|
||||
);
|
||||
new (p_state) cs_shared_state();
|
||||
p_owner = true;
|
||||
/* set up allocator, from now we can call into alloc() */
|
||||
p_state->allocf = func;
|
||||
p_state->aptr = data;
|
||||
|
@ -414,8 +415,12 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
cs_init_lib_base(*this);
|
||||
}
|
||||
|
||||
cs_state::~cs_state() {
|
||||
if (!p_state) {
|
||||
OSTD_EXPORT cs_state::~cs_state() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
OSTD_EXPORT void cs_state::destroy() {
|
||||
if (!p_state || !p_owner) {
|
||||
return;
|
||||
}
|
||||
for (auto &p: p_state->idents) {
|
||||
|
@ -430,17 +435,25 @@ cs_state::~cs_state() {
|
|||
p_state->destroy(p_state);
|
||||
}
|
||||
|
||||
cs_hook_cb cs_state::set_call_hook(cs_hook_cb func) {
|
||||
cs_state::cs_state(cs_shared_state *s):
|
||||
p_state(s), p_owner(false)
|
||||
{}
|
||||
|
||||
OSTD_EXPORT cs_state cs_state::new_thread() {
|
||||
return cs_state{p_state};
|
||||
}
|
||||
|
||||
OSTD_EXPORT cs_hook_cb cs_state::set_call_hook(cs_hook_cb func) {
|
||||
auto hk = std::move(p_callhook);
|
||||
p_callhook = std::move(func);
|
||||
return hk;
|
||||
}
|
||||
|
||||
cs_hook_cb const &cs_state::get_call_hook() const {
|
||||
OSTD_EXPORT cs_hook_cb const &cs_state::get_call_hook() const {
|
||||
return p_callhook;
|
||||
}
|
||||
|
||||
cs_hook_cb &cs_state::get_call_hook() {
|
||||
OSTD_EXPORT cs_hook_cb &cs_state::get_call_hook() {
|
||||
return p_callhook;
|
||||
}
|
||||
|
||||
|
@ -448,7 +461,7 @@ void *cs_state::alloc(void *ptr, size_t os, size_t ns) {
|
|||
return p_state->alloc(ptr, os, ns);
|
||||
}
|
||||
|
||||
void cs_state::clear_override(cs_ident &id) {
|
||||
OSTD_EXPORT void cs_state::clear_override(cs_ident &id) {
|
||||
if (!(id.get_flags() & CS_IDF_OVERRIDDEN)) {
|
||||
return;
|
||||
}
|
||||
|
@ -483,13 +496,13 @@ void cs_state::clear_override(cs_ident &id) {
|
|||
id.p_flags &= ~CS_IDF_OVERRIDDEN;
|
||||
}
|
||||
|
||||
void cs_state::clear_overrides() {
|
||||
OSTD_EXPORT void cs_state::clear_overrides() {
|
||||
for (auto &p: p_state->idents) {
|
||||
clear_override(*(p.second));
|
||||
}
|
||||
}
|
||||
|
||||
cs_ident *cs_state::add_ident(cs_ident *id) {
|
||||
OSTD_EXPORT cs_ident *cs_state::add_ident(cs_ident *id) {
|
||||
if (!id) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -499,7 +512,7 @@ cs_ident *cs_state::add_ident(cs_ident *id) {
|
|||
return p_state->identmap.back();
|
||||
}
|
||||
|
||||
cs_ident *cs_state::new_ident(ostd::string_range name, int flags) {
|
||||
OSTD_EXPORT cs_ident *cs_state::new_ident(ostd::string_range name, int flags) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id) {
|
||||
if (cs_check_num(name)) {
|
||||
|
@ -512,7 +525,7 @@ cs_ident *cs_state::new_ident(ostd::string_range name, int flags) {
|
|||
return id;
|
||||
}
|
||||
|
||||
cs_ident *cs_state::force_ident(cs_value &v) {
|
||||
OSTD_EXPORT cs_ident *cs_state::force_ident(cs_value &v) {
|
||||
switch (v.get_type()) {
|
||||
case cs_value_type::Ident:
|
||||
return v.get_ident();
|
||||
|
@ -530,7 +543,7 @@ cs_ident *cs_state::force_ident(cs_value &v) {
|
|||
return p_state->identmap[DummyIdx];
|
||||
}
|
||||
|
||||
cs_ident *cs_state::get_ident(ostd::string_range name) {
|
||||
OSTD_EXPORT cs_ident *cs_state::get_ident(ostd::string_range name) {
|
||||
auto id = p_state->idents.find(name);
|
||||
if (id != p_state->idents.end()) {
|
||||
return id->second;
|
||||
|
@ -538,7 +551,7 @@ cs_ident *cs_state::get_ident(ostd::string_range name) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
cs_alias *cs_state::get_alias(ostd::string_range name) {
|
||||
OSTD_EXPORT cs_alias *cs_state::get_alias(ostd::string_range name) {
|
||||
auto id = get_ident(name);
|
||||
if (!id || !id->is_alias()) {
|
||||
return nullptr;
|
||||
|
@ -546,23 +559,23 @@ cs_alias *cs_state::get_alias(ostd::string_range name) {
|
|||
return static_cast<cs_alias *>(id);
|
||||
}
|
||||
|
||||
bool cs_state::have_ident(ostd::string_range name) {
|
||||
OSTD_EXPORT bool cs_state::have_ident(ostd::string_range name) {
|
||||
return p_state->idents.find(name) != p_state->idents.end();
|
||||
}
|
||||
|
||||
cs_ident_r cs_state::get_idents() {
|
||||
OSTD_EXPORT cs_ident_r cs_state::get_idents() {
|
||||
return cs_ident_r(
|
||||
p_state->identmap.data(),
|
||||
p_state->identmap.data() + p_state->identmap.size()
|
||||
);
|
||||
}
|
||||
|
||||
cs_const_ident_r cs_state::get_idents() const {
|
||||
OSTD_EXPORT cs_const_ident_r cs_state::get_idents() const {
|
||||
auto ptr = const_cast<cs_ident const **>(p_state->identmap.data());
|
||||
return cs_const_ident_r(ptr, ptr + p_state->identmap.size());
|
||||
}
|
||||
|
||||
cs_ivar *cs_state::new_ivar(
|
||||
OSTD_EXPORT cs_ivar *cs_state::new_ivar(
|
||||
ostd::string_range n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags
|
||||
) {
|
||||
return add_ident(
|
||||
|
@ -570,7 +583,7 @@ cs_ivar *cs_state::new_ivar(
|
|||
)->get_ivar();
|
||||
}
|
||||
|
||||
cs_fvar *cs_state::new_fvar(
|
||||
OSTD_EXPORT cs_fvar *cs_state::new_fvar(
|
||||
ostd::string_range n, cs_float m, cs_float x, cs_float v, cs_var_cb f, int flags
|
||||
) {
|
||||
return add_ident(
|
||||
|
@ -578,7 +591,7 @@ cs_fvar *cs_state::new_fvar(
|
|||
)->get_fvar();
|
||||
}
|
||||
|
||||
cs_svar *cs_state::new_svar(
|
||||
OSTD_EXPORT cs_svar *cs_state::new_svar(
|
||||
ostd::string_range n, cs_string v, cs_var_cb f, int flags
|
||||
) {
|
||||
return add_ident(
|
||||
|
@ -586,7 +599,7 @@ cs_svar *cs_state::new_svar(
|
|||
)->get_svar();
|
||||
}
|
||||
|
||||
void cs_state::reset_var(ostd::string_range name) {
|
||||
OSTD_EXPORT void cs_state::reset_var(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id) {
|
||||
throw cs_error(*this, "variable %s does not exist", name);
|
||||
|
@ -597,14 +610,14 @@ void cs_state::reset_var(ostd::string_range name) {
|
|||
clear_override(*id);
|
||||
}
|
||||
|
||||
void cs_state::touch_var(ostd::string_range name) {
|
||||
OSTD_EXPORT void cs_state::touch_var(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (id && id->is_var()) {
|
||||
static_cast<cs_var *>(id)->changed(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void cs_state::set_alias(ostd::string_range name, cs_value v) {
|
||||
OSTD_EXPORT void cs_state::set_alias(ostd::string_range name, cs_value v) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (id) {
|
||||
switch (id->get_type()) {
|
||||
|
@ -639,7 +652,7 @@ void cs_state::set_alias(ostd::string_range name, cs_value v) {
|
|||
}
|
||||
}
|
||||
|
||||
void cs_state::print_var(cs_var *v) {
|
||||
OSTD_EXPORT void cs_state::print_var(cs_var *v) {
|
||||
ostd::writeln(v->to_printable());
|
||||
}
|
||||
|
||||
|
@ -723,7 +736,7 @@ static inline void cs_override_var(cs_state &cs, cs_var *v, int &vflags, SF sf)
|
|||
}
|
||||
}
|
||||
|
||||
void cs_state::set_var_int(
|
||||
OSTD_EXPORT void cs_state::set_var_int(
|
||||
ostd::string_range name, cs_int v, bool dofunc, bool doclamp
|
||||
) {
|
||||
cs_ident *id = get_ident(name);
|
||||
|
@ -745,7 +758,7 @@ void cs_state::set_var_int(
|
|||
}
|
||||
}
|
||||
|
||||
void cs_state::set_var_float(
|
||||
OSTD_EXPORT void cs_state::set_var_float(
|
||||
ostd::string_range name, cs_float v, bool dofunc, bool doclamp
|
||||
) {
|
||||
cs_ident *id = get_ident(name);
|
||||
|
@ -767,7 +780,7 @@ void cs_state::set_var_float(
|
|||
}
|
||||
}
|
||||
|
||||
void cs_state::set_var_str(
|
||||
OSTD_EXPORT void cs_state::set_var_str(
|
||||
ostd::string_range name, ostd::string_range v, bool dofunc
|
||||
) {
|
||||
cs_ident *id = get_ident(name);
|
||||
|
@ -785,7 +798,8 @@ void cs_state::set_var_str(
|
|||
}
|
||||
}
|
||||
|
||||
std::optional<cs_int> cs_state::get_var_int(ostd::string_range name) {
|
||||
OSTD_EXPORT std::optional<cs_int>
|
||||
cs_state::get_var_int(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id || id->is_ivar()) {
|
||||
return std::nullopt;
|
||||
|
@ -793,7 +807,8 @@ std::optional<cs_int> cs_state::get_var_int(ostd::string_range name) {
|
|||
return static_cast<cs_ivar *>(id)->get_value();
|
||||
}
|
||||
|
||||
std::optional<cs_float> cs_state::get_var_float(ostd::string_range name) {
|
||||
OSTD_EXPORT std::optional<cs_float>
|
||||
cs_state::get_var_float(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id || id->is_fvar()) {
|
||||
return std::nullopt;
|
||||
|
@ -801,7 +816,8 @@ std::optional<cs_float> cs_state::get_var_float(ostd::string_range name) {
|
|||
return static_cast<cs_fvar *>(id)->get_value();
|
||||
}
|
||||
|
||||
std::optional<cs_string> cs_state::get_var_str(ostd::string_range name) {
|
||||
OSTD_EXPORT std::optional<cs_string>
|
||||
cs_state::get_var_str(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id || id->is_svar()) {
|
||||
return std::nullopt;
|
||||
|
@ -809,7 +825,8 @@ std::optional<cs_string> cs_state::get_var_str(ostd::string_range name) {
|
|||
return cs_string(static_cast<cs_svar *>(id)->get_value());
|
||||
}
|
||||
|
||||
std::optional<cs_int> cs_state::get_var_min_int(ostd::string_range name) {
|
||||
OSTD_EXPORT std::optional<cs_int>
|
||||
cs_state::get_var_min_int(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id || id->is_ivar()) {
|
||||
return std::nullopt;
|
||||
|
@ -817,7 +834,8 @@ std::optional<cs_int> cs_state::get_var_min_int(ostd::string_range name) {
|
|||
return static_cast<cs_ivar *>(id)->get_val_min();
|
||||
}
|
||||
|
||||
std::optional<cs_int> cs_state::get_var_max_int(ostd::string_range name) {
|
||||
OSTD_EXPORT std::optional<cs_int>
|
||||
cs_state::get_var_max_int(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id || id->is_ivar()) {
|
||||
return std::nullopt;
|
||||
|
@ -825,7 +843,8 @@ std::optional<cs_int> cs_state::get_var_max_int(ostd::string_range name) {
|
|||
return static_cast<cs_ivar *>(id)->get_val_max();
|
||||
}
|
||||
|
||||
std::optional<cs_float> cs_state::get_var_min_float(ostd::string_range name) {
|
||||
OSTD_EXPORT std::optional<cs_float>
|
||||
cs_state::get_var_min_float(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id || id->is_fvar()) {
|
||||
return std::nullopt;
|
||||
|
@ -833,7 +852,8 @@ std::optional<cs_float> cs_state::get_var_min_float(ostd::string_range name) {
|
|||
return static_cast<cs_fvar *>(id)->get_val_min();
|
||||
}
|
||||
|
||||
std::optional<cs_float> cs_state::get_var_max_float(ostd::string_range name) {
|
||||
OSTD_EXPORT std::optional<cs_float>
|
||||
cs_state::get_var_max_float(ostd::string_range name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (!id || id->is_fvar()) {
|
||||
return std::nullopt;
|
||||
|
@ -841,7 +861,7 @@ std::optional<cs_float> cs_state::get_var_max_float(ostd::string_range name) {
|
|||
return static_cast<cs_fvar *>(id)->get_val_max();
|
||||
}
|
||||
|
||||
std::optional<cs_string>
|
||||
OSTD_EXPORT std::optional<cs_string>
|
||||
cs_state::get_alias_val(ostd::string_range name) {
|
||||
cs_alias *a = get_alias(name);
|
||||
if (!a) {
|
||||
|
@ -874,7 +894,7 @@ cs_int cs_clamp_var(cs_state &cs, cs_ivar *iv, cs_int v) {
|
|||
);
|
||||
}
|
||||
|
||||
void cs_state::set_var_int_checked(cs_ivar *iv, cs_int v) {
|
||||
OSTD_EXPORT void cs_state::set_var_int_checked(cs_ivar *iv, cs_int v) {
|
||||
if (iv->get_flags() & CS_IDF_READONLY) {
|
||||
throw cs_error(
|
||||
*this, "variable '%s' is read only", iv->get_name()
|
||||
|
@ -891,7 +911,7 @@ void cs_state::set_var_int_checked(cs_ivar *iv, cs_int v) {
|
|||
iv->changed(*this);
|
||||
}
|
||||
|
||||
void cs_state::set_var_int_checked(cs_ivar *iv, cs_value_r args) {
|
||||
OSTD_EXPORT void cs_state::set_var_int_checked(cs_ivar *iv, cs_value_r args) {
|
||||
cs_int v = args[0].force_int();
|
||||
if ((iv->get_flags() & CS_IDF_HEX) && (args.size() > 1)) {
|
||||
v = (v << 16) | (args[1].force_int() << 8);
|
||||
|
@ -917,7 +937,7 @@ cs_float cs_clamp_fvar(cs_state &cs, cs_fvar *fv, cs_float v) {
|
|||
return v;
|
||||
}
|
||||
|
||||
void cs_state::set_var_float_checked(cs_fvar *fv, cs_float v) {
|
||||
OSTD_EXPORT void cs_state::set_var_float_checked(cs_fvar *fv, cs_float v) {
|
||||
if (fv->get_flags() & CS_IDF_READONLY) {
|
||||
throw cs_error(
|
||||
*this, "variable '%s' is read only", fv->get_name()
|
||||
|
@ -934,7 +954,9 @@ void cs_state::set_var_float_checked(cs_fvar *fv, cs_float v) {
|
|||
fv->changed(*this);
|
||||
}
|
||||
|
||||
void cs_state::set_var_str_checked(cs_svar *sv, ostd::string_range v) {
|
||||
OSTD_EXPORT void cs_state::set_var_str_checked(
|
||||
cs_svar *sv, ostd::string_range v
|
||||
) {
|
||||
if (sv->get_flags() & CS_IDF_READONLY) {
|
||||
throw cs_error(
|
||||
*this, "variable '%s' is read only", sv->get_name()
|
||||
|
@ -948,7 +970,7 @@ void cs_state::set_var_str_checked(cs_svar *sv, ostd::string_range v) {
|
|||
sv->changed(*this);
|
||||
}
|
||||
|
||||
cs_command *cs_state::new_command(
|
||||
OSTD_EXPORT cs_command *cs_state::new_command(
|
||||
ostd::string_range name, ostd::string_range args, cs_command_cb func
|
||||
) {
|
||||
int nargs = 0;
|
||||
|
|
Loading…
Reference in New Issue