add a variable value change trigger callback

master
Daniel Kolesa 2021-04-04 04:30:36 +02:00
parent bab8633a05
commit 529e34d268
5 changed files with 53 additions and 9 deletions

View File

@ -261,7 +261,9 @@ protected:
struct LIBCUBESCRIPT_EXPORT integer_var: global_var {
integer_type get_value() const;
void set_value(state &cs, integer_type val, bool do_write = true);
void set_value(
state &cs, integer_type val, bool do_write = true, bool trigger = true
);
void set_raw_value(integer_type val);
protected:
@ -270,7 +272,9 @@ protected:
struct LIBCUBESCRIPT_EXPORT float_var: global_var {
float_type get_value() const;
void set_value(state &cs, float_type val, bool do_write = true);
void set_value(
state &cs, float_type val, bool do_write = true, bool trigger = true
);
void set_raw_value(float_type val);
protected:
@ -279,7 +283,9 @@ protected:
struct LIBCUBESCRIPT_EXPORT string_var: global_var {
string_ref get_value() const;
void set_value(state &cs, string_ref val, bool do_write = true);
void set_value(
state &cs, string_ref val, bool do_write = true, bool trigger = true
);
void set_raw_value(string_ref val);
protected:
@ -366,6 +372,7 @@ struct LIBCUBESCRIPT_EXPORT state {
var_type vtp = var_type::DEFAULT
);
void reset_var(std::string_view name);
void touch_var(std::string_view name);
template<typename F>
command *new_command(

View File

@ -82,6 +82,17 @@ command_impl::command_impl(
p_cargs{args}, p_cb_cftv{std::move(f)}, p_numargs{nargs}
{}
void var_changed(thread_state &ts, ident *id) {
auto *cid = ts.pstate->get_ident("//var_changed");
if (!cid || !cid->is_command()) {
return;
}
auto *cimp = static_cast<command_impl *>(cid);
any_value val{*ts.pstate};
val.set_ident(id);
cimp->call(*ts.pstate, std::span<any_value>{&val, 1}, val);
}
void ivar_impl::save_val() {
p_override = p_storage;
}
@ -351,7 +362,7 @@ LIBCUBESCRIPT_EXPORT integer_type integer_var::get_value() const {
}
LIBCUBESCRIPT_EXPORT void integer_var::set_value(
state &cs, integer_type val, bool do_write
state &cs, integer_type val, bool do_write, bool trigger
) {
if (is_read_only()) {
throw error{
@ -363,6 +374,9 @@ LIBCUBESCRIPT_EXPORT void integer_var::set_value(
}
save(cs);
set_raw_value(val);
if (trigger) {
var_changed(*cs.thread_pointer(), this);
}
}
LIBCUBESCRIPT_EXPORT void integer_var::set_raw_value(integer_type val) {
@ -374,7 +388,7 @@ LIBCUBESCRIPT_EXPORT float_type float_var::get_value() const {
}
LIBCUBESCRIPT_EXPORT void float_var::set_value(
state &cs, float_type val, bool do_write
state &cs, float_type val, bool do_write, bool trigger
) {
if (is_read_only()) {
throw error{
@ -386,6 +400,9 @@ LIBCUBESCRIPT_EXPORT void float_var::set_value(
}
save(cs);
set_raw_value(val);
if (trigger) {
var_changed(*cs.thread_pointer(), this);
}
}
LIBCUBESCRIPT_EXPORT void float_var::set_raw_value(float_type val) {
@ -397,7 +414,7 @@ LIBCUBESCRIPT_EXPORT string_ref string_var::get_value() const {
}
LIBCUBESCRIPT_EXPORT void string_var::set_value(
state &cs, string_ref val, bool do_write
state &cs, string_ref val, bool do_write, bool trigger
) {
if (is_read_only()) {
throw error{
@ -409,6 +426,9 @@ LIBCUBESCRIPT_EXPORT void string_var::set_value(
}
save(cs);
set_raw_value(std::move(val));
if (trigger) {
var_changed(*cs.thread_pointer(), this);
}
}
LIBCUBESCRIPT_EXPORT void string_var::set_raw_value(string_ref val) {

View File

@ -77,8 +77,12 @@ struct var_impl: ident_impl {
var_impl(ident_type tp, string_ref name, int flags);
virtual void save_val() = 0;
void changed(thread_state &ts);
};
void var_changed(thread_state &ts, ident *id);
struct ivar_impl: var_impl, integer_var {
ivar_impl(string_ref n, integer_type v, int flags);

View File

@ -303,7 +303,7 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
case ident_type::IVAR: {
ivar_impl &iv = static_cast<ivar_impl &>(id);
iv.set_raw_value(iv.p_override);
//iv.changed(*this);
var_changed(*p_tstate, &id);
static_cast<ivar_impl *>(
static_cast<integer_var *>(&iv)
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
@ -312,7 +312,7 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
case ident_type::FVAR: {
fvar_impl &fv = static_cast<fvar_impl &>(id);
fv.set_raw_value(fv.p_override);
//fv.changed(*this);
var_changed(*p_tstate, &id);
static_cast<fvar_impl *>(
static_cast<float_var *>(&fv)
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
@ -321,7 +321,7 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
case ident_type::SVAR: {
svar_impl &sv = static_cast<svar_impl &>(id);
sv.set_raw_value(sv.p_override);
//sv.changed(*this);
var_changed(*p_tstate, &id);
static_cast<svar_impl *>(
static_cast<string_var *>(&sv)
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
@ -401,6 +401,13 @@ LIBCUBESCRIPT_EXPORT void state::reset_var(std::string_view name) {
clear_override(*id);
}
LIBCUBESCRIPT_EXPORT void state::touch_var(std::string_view name) {
ident *id = get_ident(name);
if (id && id->is_var()) {
var_changed(*p_tstate, id);
}
}
LIBCUBESCRIPT_EXPORT void state::set_alias(
std::string_view name, any_value v
) {

View File

@ -380,6 +380,12 @@ int main(int argc, char **argv) {
}
});
gcs.new_command("//var_changed", "$", [](auto &, auto args, auto &) {
std::printf(
"changed var trigger: %s\n", args[0].get_ident()->get_name().data()
);
});
gcs.new_command("exec", "s", [](auto &css, auto args, auto &) {
auto file = args[0].get_str();
cs::any_value val{css};