From 529e34d268a57461c2af958ed953de94e2042016 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Sun, 4 Apr 2021 04:30:36 +0200 Subject: [PATCH] add a variable value change trigger callback --- include/cubescript/cubescript.hh | 13 ++++++++++--- src/cs_ident.cc | 26 +++++++++++++++++++++++--- src/cs_ident.hh | 4 ++++ src/cs_state.cc | 13 ++++++++++--- tools/repl.cc | 6 ++++++ 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 3ceac87..342617f 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -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 command *new_command( diff --git a/src/cs_ident.cc b/src/cs_ident.cc index 10f268e..8ba778f 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -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(cid); + any_value val{*ts.pstate}; + val.set_ident(id); + cimp->call(*ts.pstate, std::span{&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) { diff --git a/src/cs_ident.hh b/src/cs_ident.hh index 0009168..c96a21a 100644 --- a/src/cs_ident.hh +++ b/src/cs_ident.hh @@ -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); diff --git a/src/cs_state.cc b/src/cs_state.cc index c268671..999113b 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -303,7 +303,7 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) { case ident_type::IVAR: { ivar_impl &iv = static_cast(id); iv.set_raw_value(iv.p_override); - //iv.changed(*this); + var_changed(*p_tstate, &id); static_cast( static_cast(&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(id); fv.set_raw_value(fv.p_override); - //fv.changed(*this); + var_changed(*p_tstate, &id); static_cast( static_cast(&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(id); sv.set_raw_value(sv.p_override); - //sv.changed(*this); + var_changed(*p_tstate, &id); static_cast( static_cast(&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 ) { diff --git a/tools/repl.cc b/tools/repl.cc index 148501f..4dc9b7c 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -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};