diff --git a/api/icsneocpp/event.cpp b/api/icsneocpp/event.cpp index befdd312..9ad080dd 100644 --- a/api/icsneocpp/event.cpp +++ b/api/icsneocpp/event.cpp @@ -4,10 +4,10 @@ using namespace icsneo; -APIEvent::APIEvent(Type type, APIEvent::Severity severity, const Device* device) : eventStruct({}) { - this->device = device; - if(device) { - serial = device->getSerial(); +APIEvent::APIEvent(Type type, APIEvent::Severity severity, std::weak_ptr device) : eventStruct({}), device(device) { + auto shared = device.lock(); + if(shared) { + serial = shared->getSerial(); eventStruct.serial[serial.copy(eventStruct.serial, sizeof(eventStruct.serial))] = '\0'; } @@ -27,9 +27,10 @@ void APIEvent::downgradeFromError() noexcept { } bool APIEvent::isForDevice(std::string filterSerial) const noexcept { - if(!device || filterSerial.length() == 0) + auto shared = device.lock(); + if(!shared || filterSerial.length() == 0) return false; - return device->getSerial() == filterSerial; + return shared->getSerial() == filterSerial; } // API Errors @@ -467,8 +468,9 @@ const char* APIEvent::DescriptionForType(Type type) { std::string APIEvent::describe() const noexcept { std::stringstream ss; - if(device) - ss << *device; // Makes use of device.describe() + auto shared = device.lock(); + if(shared) + ss << *shared; // Makes use of device.describe() else ss << "API"; diff --git a/include/icsneo/api/event.h b/include/icsneo/api/event.h index ac14a628..6cb688bf 100644 --- a/include/icsneo/api/event.h +++ b/include/icsneo/api/event.h @@ -19,6 +19,7 @@ typedef struct { #include #include #include +#include namespace icsneo { @@ -185,19 +186,25 @@ public: Error = 0x30 }; - APIEvent() : eventStruct({}), serial(), timepoint(), device(nullptr) {} - APIEvent(APIEvent::Type event, APIEvent::Severity severity, const Device* device = nullptr); + APIEvent() : eventStruct({}), serial(), timepoint() {} + APIEvent(APIEvent::Type event, APIEvent::Severity severity, std::weak_ptr device = {}); const neoevent_t* getNeoEvent() const noexcept { return &eventStruct; } Type getType() const noexcept { return Type(eventStruct.eventNumber); } Severity getSeverity() const noexcept { return Severity(eventStruct.severity); } std::string getDescription() const noexcept { return std::string(eventStruct.description); } - const Device* getDevice() const noexcept { return device; } // Will return nullptr if this is an API-wide event + const Device* getDevice() const noexcept { // Will return nullptr if this is an API-wide event + auto shared = device.lock(); + return (shared) ? shared.get() : nullptr; + } EventTimePoint getTimestamp() const noexcept { return timepoint; } void downgradeFromError() noexcept; - bool isForDevice(const Device* forDevice) const noexcept { return forDevice == device; } + bool isForDevice(const Device* forDevice) const noexcept { + auto shared = device.lock(); + return shared && (shared.get() == forDevice); + } bool isForDevice(std::string serial) const noexcept; // As opposed to getDescription, this will also add text such as "neoVI FIRE 2 CY2468 Error: " to fully describe the problem @@ -213,7 +220,7 @@ private: neoevent_t eventStruct; std::string serial; EventTimePoint timepoint; - const Device* device; + std::weak_ptr device; void init(APIEvent::Type event, APIEvent::Severity); }; diff --git a/include/icsneo/api/eventmanager.h b/include/icsneo/api/eventmanager.h index 5d5725d2..b176c5c7 100644 --- a/include/icsneo/api/eventmanager.h +++ b/include/icsneo/api/eventmanager.h @@ -56,7 +56,7 @@ public: APIEvent getLastError(); void add(APIEvent event); - void add(APIEvent::Type type, APIEvent::Severity severity, const Device* forDevice = nullptr) { + void add(APIEvent::Type type, APIEvent::Severity severity, std::weak_ptr forDevice = {}) { add(APIEvent(type, severity, forDevice)); } diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index 59cc9e99..dbcb26c3 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -87,7 +87,7 @@ class DeviceExtension; typedef uint64_t MemoryAddress; -class Device { +class Device : public std::enable_shared_from_this { public: virtual ~Device(); @@ -930,7 +930,7 @@ protected: virtual device_eventhandler_t makeEventHandler() { return [this](APIEvent::Type type, APIEvent::Severity severity) { - EventManager::GetInstance().add(type, severity, this); + EventManager::GetInstance().add(type, severity, weak_from_this()); }; }