Merge remote-tracking branch 'remotes/origin/topic/robin/gh59-when'

Fixed a few small bugs - Modifiable had an uninitialized member and the
Registry looped over a map while deleting elements from it.

Fixes GH-319

* remotes/origin/topic/robin/gh59-when:
  Renaming src/StateAccess.{h,cc} to src/Notifier.{h,cc}.
  Clean up new code.
  Remove MutableVal class.
  Redo API for notifiers.
  Remove most of MutableVal (but not the class itelf yet)
  Remove enum Opcode.
  Remove StateAccess class.
  Redo NotfifierRegistry to no longer rely on StateAccess.
  Add new test for when-statement watching global variables.
  Couple of compile fixes.
This commit is contained in:
Johanna Amann 2019-06-20 14:15:37 -07:00
commit b1be8abe4e
22 changed files with 365 additions and 1422 deletions

72
src/Notifier.cc Normal file
View file

@ -0,0 +1,72 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "DebugLogger.h"
#include "Notifier.h"
notifier::Registry notifier::registry;
notifier::Receiver::Receiver()
{
DBG_LOG(DBG_NOTIFIERS, "creating receiver %p", this);
}
notifier::Receiver::~Receiver()
{
DBG_LOG(DBG_NOTIFIERS, "deleting receiver %p", this);
}
notifier::Registry::~Registry()
{
while ( registrations.begin() != registrations.end() )
Unregister(registrations.begin()->first);
}
void notifier::Registry::Register(Modifiable* m, notifier::Receiver* r)
{
DBG_LOG(DBG_NOTIFIERS, "registering object %p for receiver %p", m, r);
registrations.insert({m, r});
++m->num_receivers;
}
void notifier::Registry::Unregister(Modifiable* m, notifier::Receiver* r)
{
DBG_LOG(DBG_NOTIFIERS, "unregistering object %p from receiver %p", m, r);
auto x = registrations.equal_range(m);
for ( auto i = x.first; i != x.second; i++ )
{
if ( i->second == r )
{
--i->first->num_receivers;
registrations.erase(i);
break;
}
}
}
void notifier::Registry::Unregister(Modifiable* m)
{
DBG_LOG(DBG_NOTIFIERS, "unregistering object %p from all notifiers", m);
auto x = registrations.equal_range(m);
for ( auto i = x.first; i != x.second; i++ )
--i->first->num_receivers;
registrations.erase(x.first, x.second);
}
void notifier::Registry::Modified(Modifiable* m)
{
DBG_LOG(DBG_NOTIFIERS, "object %p has been modified", m);
auto x = registrations.equal_range(m);
for ( auto i = x.first; i != x.second; i++ )
i->second->Modified(m);
}
notifier::Modifiable::~Modifiable()
{
if ( num_receivers )
registry.Unregister(this);
}