summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/managed/Events.hpp17
-rw-r--r--src/core/managed/Manager.cpp88
-rw-r--r--src/core/managed/Manager.hpp13
3 files changed, 62 insertions, 56 deletions
diff --git a/src/core/managed/Events.hpp b/src/core/managed/Events.hpp
index 768f0aa..a69c363 100644
--- a/src/core/managed/Events.hpp
+++ b/src/core/managed/Events.hpp
@@ -28,6 +28,8 @@
#ifndef _OUSIA_EVENTS_HPP_
#define _OUSIA_EVENTS_HPP_
+#include <cstdint>
+
#include <string>
namespace ousia {
@@ -147,9 +149,9 @@ struct EventHandlerDescriptor {
EventHandler handler;
/**
- * Owner object.
+ * Weak reference to the owner object.
*/
- Managed *owner;
+ uint64_t ownerUid;
/**
* User defined data.
@@ -162,15 +164,15 @@ struct EventHandlerDescriptor {
* @param type is the event type for which the handler is registered.
* @param handler is the function pointer which is going to be called once
* the associated event handler has fired.
- * @param owner is a user-specified object which owns the method that is
+ * @param ownerUid is a user-specified object which owns the method that is
* going to be called. This can be used to make sure that the method which
* handles the events has access to its owned object as long as the event
* handler lives.
* @param data is some arbitrary user defined data.
*/
- EventHandlerDescriptor(EventType type, EventHandler handler, Managed *owner,
- void *data)
- : type(type), handler(handler), owner(owner), data(data)
+ EventHandlerDescriptor(EventType type, EventHandler handler,
+ uint64_t ownerUid, void *data)
+ : type(type), handler(handler), ownerUid(ownerUid), data(data)
{
}
@@ -182,7 +184,8 @@ struct EventHandlerDescriptor {
/**
* Returns the name of the current event type.
*/
- const char *getEventTypeName() const {
+ const char *getEventTypeName() const
+ {
return getEventTypeName(this->type);
}
};
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++;
diff --git a/src/core/managed/Manager.hpp b/src/core/managed/Manager.hpp
index eb4594a..761603b 100644
--- a/src/core/managed/Manager.hpp
+++ b/src/core/managed/Manager.hpp
@@ -375,10 +375,9 @@ public:
* registered.
* @param type is the event type that should be registered.
* @param handler is the callback function.
- * @param owner is a managed object that owns the event handler. A reference
- * from the the reference object to the owner is added. The argument may be
- * nullptr in which case no reference is added. The owner is passed to the
- * event handler as second parameter.
+ * @param owner is a managed object that owns the event handler. May be
+ * nullptr. The owner is only referenced via a weak reference. If the owner
+ * is freed, the event handler will no longer be called.
* @param data is some user defined data.
* @return a numeric event id, which is unique for the given reference
* object. The event id must be used when unregistering event handlers.
@@ -405,10 +404,8 @@ public:
* registered.
* @param type is the event type that should be registered.
* @param handler is the callback function.
- * @param owner is a managed object that owns the event handler. A reference
- * from the the reference object to the owner is added. The argument may be
- * nullptr in which case no reference is added. The owner is passed to the
- * event handler as second parameter.
+ * @param owner is a managed object that owns the event handler. May be
+ * nullptr.
* @param data is some user defined data.
* @return true if the operation was successful, false if either the
* reference object or and event with the given signature do not exist.