&on_change: incooperate feedback of Jon.

This commit is contained in:
Johanna Amann 2020-02-06 14:40:38 -08:00
parent b1040f88c9
commit d6d2bbe878
3 changed files with 16 additions and 20 deletions

View file

@ -492,12 +492,12 @@ void Attributes::CheckAttr(Attr* a)
break; break;
} }
const Expr *change_func = a->AttrExpr(); const Expr* change_func = a->AttrExpr();
if ( change_func->Type()->Tag() != TYPE_FUNC || change_func->Type()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION ) if ( change_func->Type()->Tag() != TYPE_FUNC || change_func->Type()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION )
Error("&on_change attribute is not a function"); Error("&on_change attribute is not a function");
const FuncType *c_ft = change_func->Type()->AsFuncType(); const FuncType* c_ft = change_func->Type()->AsFuncType();
if ( c_ft->YieldType()->Tag() != TYPE_VOID ) if ( c_ft->YieldType()->Tag() != TYPE_VOID )
{ {
@ -505,7 +505,7 @@ void Attributes::CheckAttr(Attr* a)
break; break;
} }
const TableType *the_table = type->AsTableType(); const TableType* the_table = type->AsTableType();
if (the_table->IsUnspecifiedTable()) if (the_table->IsUnspecifiedTable())
break; break;

View file

@ -1479,11 +1479,9 @@ int TableVal::Assign(Val* index, HashKey* k, Val* new_val)
if ( change_func ) if ( change_func )
{ {
auto change_index = index->Ref(); Val* change_index = index ? index->Ref() : RecoverIndex(&k_copy);
if ( ! change_index ) Val* v = old_entry_val ? old_entry_val->Value() : new_val;
RecoverIndex(&k_copy); CallChangeFunc(change_index, v, old_entry_val ? ELEMENT_CHANGED : ELEMENT_NEW);
Val *v = old_entry_val ? old_entry_val->Value() : new_val;
CallChangeFunc(change_index, v, old_entry_val ? element_changed : element_new);
Unref(change_index); Unref(change_index);
} }
@ -1953,7 +1951,7 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
try try
{ {
Val* thefunc = change_func->Eval(0); IntrusivePtr<Val> thefunc{change_func->Eval(nullptr), false};
if ( ! thefunc ) if ( ! thefunc )
{ {
@ -1963,7 +1961,6 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
if ( thefunc->Type()->Tag() != TYPE_FUNC ) if ( thefunc->Type()->Tag() != TYPE_FUNC )
{ {
thefunc->Error("not a function"); thefunc->Error("not a function");
Unref(thefunc);
return; return;
} }
@ -1972,16 +1969,16 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
EnumVal* type = nullptr; EnumVal* type = nullptr;
switch ( tpe ) switch ( tpe )
{ {
case element_new: case ELEMENT_NEW:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_NEW); type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_NEW);
break; break;
case element_changed: case ELEMENT_CHANGED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_CHANGED); type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_CHANGED);
break; break;
case element_removed: case ELEMENT_REMOVED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_REMOVED); type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_REMOVED);
break; break;
case element_expired: case ELEMENT_EXPIRED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED); type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED);
} }
vl.append(type); vl.append(type);
@ -1994,7 +1991,6 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
in_change_func = true; in_change_func = true;
f->Call(&vl); f->Call(&vl);
Unref(thefunc);
} }
catch ( InterpreterException& e ) catch ( InterpreterException& e )
{ {
@ -2018,7 +2014,7 @@ Val* TableVal::Delete(const Val* index)
Modified(); Modified();
if ( change_func ) if ( change_func )
CallChangeFunc(index, va, element_removed); CallChangeFunc(index, va, ELEMENT_REMOVED);
return va; return va;
} }
@ -2040,10 +2036,10 @@ Val* TableVal::Delete(const HashKey* k)
Modified(); Modified();
if ( change_func ) if ( change_func && va )
{ {
auto index = table_hash->RecoverVals(k); auto index = table_hash->RecoverVals(k);
CallChangeFunc(index, va->Ref(), element_removed); CallChangeFunc(index, va->Ref(), ELEMENT_REMOVED);
Unref(index); Unref(index);
} }
@ -2345,7 +2341,7 @@ void TableVal::DoExpire(double t)
{ {
if ( ! idx ) if ( ! idx )
idx = RecoverIndex(k); idx = RecoverIndex(k);
CallChangeFunc(idx, v->Value(), element_expired); CallChangeFunc(idx, v->Value(), ELEMENT_EXPIRED);
} }
Unref(idx); Unref(idx);
Unref(v->Value()); Unref(v->Value());

View file

@ -847,7 +847,7 @@ protected:
double CallExpireFunc(Val *idx); double CallExpireFunc(Val *idx);
// Enum for the different kinds of changes an &on_change handler can see // Enum for the different kinds of changes an &on_change handler can see
enum OnChangeType { element_new, element_changed, element_removed, element_expired }; enum OnChangeType { ELEMENT_NEW, ELEMENT_CHANGED, ELEMENT_REMOVED, ELEMENT_EXPIRED };
// Calls &change_func. Does not take ownership of values. (Refs if needed). // Calls &change_func. Does not take ownership of values. (Refs if needed).
void CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe); void CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe);