diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-05 00:15:24 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-05 00:15:24 +0100 |
commit | 9b1db73f776309668b1f5fa20dece1849c8d035b (patch) | |
tree | 81f411906de269f22fa38a144eb65bcc8143df7c /src/core/managed/Manager.cpp | |
parent | 0abccb029e55326f9de99563e38ed4c9a87eb4d1 (diff) |
Using weak references for storing the owner in events.
Diffstat (limited to 'src/core/managed/Manager.cpp')
-rw-r--r-- | src/core/managed/Manager.cpp | 88 |
1 files changed, 47 insertions, 41 deletions
diff --git a/src/core/managed/Manager.cpp b/src/core/managed/Manager.cpp index d92bbb5..a74ebc5 100644 --- a/src/core/managed/Manager.cpp +++ b/src/core/managed/Manager.cpp @@ -21,6 +21,8 @@ #include "Managed.hpp" #include "Manager.hpp" +//#define MANAGER_DEBUG_PRINT + #if defined(MANAGER_DEBUG_PRINT) || defined(MANAGER_GRAPHVIZ_EXPORT) #include <iostream> #include <fstream> @@ -473,15 +475,10 @@ bool Manager::deleteData(Managed *ref, const std::string &key) EventId Manager::registerEvent(Managed *ref, EventType type, EventHandler handler, Managed *owner, void *data) { - // Add a reference from the reference object to the owner object - if (owner) { - addRef(owner, ref); - } - // Create a event handler descriptor and store it along with the auto &vec = events.emplace(ref, std::vector<EventHandlerDescriptor>{}) .first->second; - const EventHandlerDescriptor descr(type, handler, owner, data); + const EventHandlerDescriptor descr(type, handler, getUid(owner), data); for (size_t i = 0; i < vec.size(); i++) { if (!vec[i].handler) { vec[i] = descr; @@ -498,16 +495,11 @@ bool Manager::unregisterEvent(Managed *ref, EventId id) if (eventsIt != events.end()) { auto &vec = eventsIt->second; if (id < vec.size() && vec[id].handler) { - // Delete the reference from the reference object to the handler - EventHandlerDescriptor &descr = vec[id]; - if (descr.owner) { - deleteRef(descr.owner, ref); - } - // Remove the handler from the list by resetting handler and owner // to nullptr + EventHandlerDescriptor &descr = vec[id]; descr.handler = nullptr; - descr.owner = nullptr; + descr.ownerUid = 0; return true; } } @@ -519,19 +511,15 @@ bool Manager::unregisterEvent(Managed *ref, EventType type, { auto eventsIt = events.find(ref); if (eventsIt != events.end()) { + const ManagedUid ownerUid = getUid(owner); auto &vec = eventsIt->second; for (EventHandlerDescriptor &descr : vec) { if (descr.type == type && descr.handler == handler && - descr.owner == owner && descr.data == data) { - // Delete the reference from the reference object to the handler - if (descr.owner) { - deleteRef(descr.owner, ref); - } - + descr.ownerUid == ownerUid && descr.data == data) { // Remove the handler from the list by resetting handler and // owner to nullptr descr.handler = nullptr; - descr.owner = nullptr; + descr.ownerUid = 0; return true; } } @@ -544,12 +532,27 @@ bool Manager::triggerEvent(Managed *ref, Event &ev) bool hasHandler = false; auto eventsIt = events.find(ref); if (eventsIt != events.end()) { - for (EventHandlerDescriptor &descr : eventsIt->second) { + std::vector<EventHandlerDescriptor> descrs = eventsIt->second; + for (auto it = descrs.begin(); it != descrs.end();) { + const EventHandlerDescriptor &descr = *it; if (descr.type == ev.type && descr.handler) { + // Resolve the given owner uid to a managed pointer -- erase the + // event handler if the owner no longer exists + Managed *owner = nullptr; + if (descr.ownerUid != 0) { + owner = getManaged(descr.ownerUid); + if (!owner) { + it = descrs.erase(it); + continue; + } + } + + // Call the event handler ev.sender = ref; - descr.handler(ev, descr.owner, descr.data); + descr.handler(ev, owner, descr.data); hasHandler = true; } + it++; } } return hasHandler; @@ -560,7 +563,7 @@ bool Manager::triggerEvent(Managed *ref, Event &ev) // Note: This is just an ugly hack used for development. Do not complain. You // have been warned. -enum class EdgeType { NORMAL, EVENT, DATA, AGGREGATE }; +enum class EdgeType { NORMAL, DATA, AGGREGATE }; void Manager::exportGraphviz(const char *filename) { @@ -660,16 +663,6 @@ void Manager::exportGraphviz(const char *filename) std::string port = ""; EdgeType et = EdgeType::NORMAL; - // Check whether an event with the given target node exists - for (auto it = eventData.begin(); it != eventData.end(); it++) { - if (it->handler && it->owner == e.first) { - et = EdgeType::EVENT; - port = std::string(":ev_") + - std::string(it->getEventTypeName()); - eventData.erase(it); - break; - } - } if (et == EdgeType::NORMAL) { for (auto it = storeData.begin(); it != storeData.end(); it++) { @@ -690,10 +683,11 @@ void Manager::exportGraphviz(const char *filename) << " -> n" << std::hex << std::noshowbase << pTar << " ["; int c = edgeCount; switch (et) { - case EdgeType::EVENT: - fs << "weight=5,penwidth=1,color=darkolivegreen4,"; - c = 1; - break; + /* case EdgeType::EVENT: + fs << + "weight=5,penwidth=1,color=darkolivegreen4,"; + c = 1; + break;*/ case EdgeType::DATA: fs << "weight=5,penwidth=1,color=orangered2,"; c = 1; @@ -713,15 +707,27 @@ void Manager::exportGraphviz(const char *filename) } } + // Create edges for all events + for (auto &d : eventData) { + Managed *owner = getManaged(d.ownerUid); + if (!owner) { + continue; + } + uintptr_t pTar = reinterpret_cast<uintptr_t>(owner); + fs << "\tn" << std::hex << std::noshowbase << p << ":ev_" << d.getEventTypeName() << " -> n" + << std::hex << std::noshowbase << pTar + << " [weight=0,penwidth=1,color=darkolivegreen4,style=dashed]" + << std::endl; + } + // Display root edges if (objectDescr.rootRefCount > 0) { fs << "\tr" << std::hex << std::noshowbase << p << " [shape=\"point\",width=0.1]" << std::endl; fs << "\tr" << std::hex << std::noshowbase << p << " -> n" - << std::hex << std::noshowbase << p - << " [weight=10,style=\"dashed\",headlabel=" - "\"" << std::dec << objectDescr.rootRefCount << "\"]" - << std::endl; + << std::hex << std::noshowbase << p << " [weight=1000,headlabel=" + "\"" << std::dec + << objectDescr.rootRefCount << "\"]" << std::endl; } idx++; |