pass old and new values to var_changed
parent
7febb8f5b1
commit
03325af1e6
|
@ -343,8 +343,10 @@ struct LIBCUBESCRIPT_EXPORT state {
|
|||
* and `s`) which also print to standard output (`name = value`).
|
||||
*
|
||||
* For `//var_changed`, there is no default handler. The arg list must be
|
||||
* just `$`. This will be called whenever a value of an integer, float
|
||||
* or string builtin variable changes.
|
||||
* `$aa`. This will be called whenever the value of a builtin variable of
|
||||
* any type changes, and will be passed the variable as its first argument,
|
||||
* the previous value as the second argument and the new value as the third
|
||||
* argument (mainly for convenience).
|
||||
*
|
||||
* For these builtins, `$` will refer to the variable ident, not to the
|
||||
* builtin command.
|
||||
|
|
|
@ -82,15 +82,31 @@ command_impl::command_impl(
|
|||
p_cargs{args}, p_cb_cftv{std::move(f)}, p_numargs{nargs}
|
||||
{}
|
||||
|
||||
void var_changed(thread_state &ts, ident *id) {
|
||||
void var_changed(thread_state &ts, ident *id, any_value &oldval) {
|
||||
auto *cid = ts.istate->cmd_var_changed;
|
||||
if (!cid) {
|
||||
return;
|
||||
}
|
||||
auto *cimp = static_cast<command_impl *>(cid);
|
||||
any_value val{};
|
||||
val.set_ident(*id);
|
||||
cimp->call(ts, span_type<any_value>{&val, 1}, val);
|
||||
any_value val[3] = {};
|
||||
val[0].set_ident(*id);
|
||||
val[1] = std::move(oldval);
|
||||
switch (id->get_type()) {
|
||||
case ident_type::IVAR:
|
||||
val[2].set_integer(static_cast<integer_var *>(id)->get_value());
|
||||
break;
|
||||
case ident_type::FVAR:
|
||||
val[2].set_float(static_cast<float_var *>(id)->get_value());
|
||||
break;
|
||||
case ident_type::SVAR:
|
||||
val[2].set_string(static_cast<string_var *>(id)->get_value());
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
cimp->call(ts, span_type<any_value>{
|
||||
static_cast<any_value *>(val), 3
|
||||
}, val[0]);
|
||||
}
|
||||
|
||||
void ivar_impl::save_val() {
|
||||
|
@ -311,9 +327,12 @@ LIBCUBESCRIPT_EXPORT void integer_var::set_value(
|
|||
return;
|
||||
}
|
||||
save(cs);
|
||||
auto oldv = get_value();
|
||||
set_raw_value(val);
|
||||
if (trigger) {
|
||||
var_changed(state_p{cs}.ts(), this);
|
||||
any_value v;
|
||||
v.set_integer(oldv);
|
||||
var_changed(state_p{cs}.ts(), this, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,9 +382,12 @@ LIBCUBESCRIPT_EXPORT void float_var::set_value(
|
|||
return;
|
||||
}
|
||||
save(cs);
|
||||
auto oldv = get_value();
|
||||
set_raw_value(val);
|
||||
if (trigger) {
|
||||
var_changed(state_p{cs}.ts(), this);
|
||||
any_value v;
|
||||
v.set_float(oldv);
|
||||
var_changed(state_p{cs}.ts(), this, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,9 +417,12 @@ LIBCUBESCRIPT_EXPORT void string_var::set_value(
|
|||
return;
|
||||
}
|
||||
save(cs);
|
||||
auto oldv = get_value();
|
||||
set_raw_value(std::move(val));
|
||||
if (trigger) {
|
||||
var_changed(state_p{cs}.ts(), this);
|
||||
any_value v;
|
||||
v.set_string(oldv);
|
||||
var_changed(state_p{cs}.ts(), this, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ struct var_impl: ident_impl {
|
|||
void changed(thread_state &ts);
|
||||
};
|
||||
|
||||
void var_changed(thread_state &ts, ident *id);
|
||||
void var_changed(thread_state &ts, ident *id, any_value &oldval);
|
||||
|
||||
struct ivar_impl: var_impl, integer_var {
|
||||
ivar_impl(string_ref n, integer_type v, int flags);
|
||||
|
|
|
@ -350,27 +350,33 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
|
|||
return;
|
||||
}
|
||||
case ident_type::IVAR: {
|
||||
any_value oldv;
|
||||
ivar_impl &iv = static_cast<ivar_impl &>(id);
|
||||
oldv.set_integer(iv.get_value());
|
||||
iv.set_raw_value(iv.p_override);
|
||||
var_changed(*p_tstate, &id);
|
||||
var_changed(*p_tstate, &id, oldv);
|
||||
static_cast<ivar_impl *>(
|
||||
static_cast<integer_var *>(&iv)
|
||||
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
|
||||
return;
|
||||
}
|
||||
case ident_type::FVAR: {
|
||||
any_value oldv;
|
||||
fvar_impl &fv = static_cast<fvar_impl &>(id);
|
||||
oldv.set_float(fv.get_value());
|
||||
fv.set_raw_value(fv.p_override);
|
||||
var_changed(*p_tstate, &id);
|
||||
var_changed(*p_tstate, &id, oldv);
|
||||
static_cast<fvar_impl *>(
|
||||
static_cast<float_var *>(&fv)
|
||||
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
|
||||
return;
|
||||
}
|
||||
case ident_type::SVAR: {
|
||||
any_value oldv;
|
||||
svar_impl &sv = static_cast<svar_impl &>(id);
|
||||
oldv.set_string(sv.get_value());
|
||||
sv.set_raw_value(sv.p_override);
|
||||
var_changed(*p_tstate, &id);
|
||||
var_changed(*p_tstate, &id, oldv);
|
||||
static_cast<svar_impl *>(
|
||||
static_cast<string_var *>(&sv)
|
||||
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
|
||||
|
@ -578,9 +584,25 @@ LIBCUBESCRIPT_EXPORT void state::reset_value(std::string_view name) {
|
|||
|
||||
LIBCUBESCRIPT_EXPORT void state::touch_value(std::string_view name) {
|
||||
auto id = get_ident(name);
|
||||
if (id && id->get().is_var()) {
|
||||
var_changed(*p_tstate, &id->get());
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
auto &idr = id->get();
|
||||
any_value v;
|
||||
switch (idr.get_type()) {
|
||||
case ident_type::IVAR:
|
||||
v.set_integer(static_cast<integer_var &>(idr).get_value());
|
||||
break;
|
||||
case ident_type::FVAR:
|
||||
v.set_float(static_cast<float_var &>(idr).get_value());
|
||||
break;
|
||||
case ident_type::SVAR:
|
||||
v.set_string(static_cast<string_var &>(idr).get_value());
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
var_changed(*p_tstate, &idr, v);
|
||||
}
|
||||
|
||||
static char const *allowed_builtins[] = {
|
||||
|
|
|
@ -347,10 +347,12 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
});
|
||||
|
||||
gcs.new_command("//var_changed", "$", [](auto &css, auto args, auto &) {
|
||||
gcs.new_command("//var_changed", "$aa", [](auto &css, auto args, auto &) {
|
||||
std::printf(
|
||||
"changed var trigger: %s\n",
|
||||
args[0].get_ident(css).get_name().data()
|
||||
"changed var trigger: %s (was: '%s', now: '%s')\n",
|
||||
args[0].get_ident(css).get_name().data(),
|
||||
args[1].get_string(css).data(),
|
||||
args[2].get_string(css).data()
|
||||
);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue