diff --git a/MMCore/CoreCallback.cpp b/MMCore/CoreCallback.cpp index b11f91cb0..5b3974812 100644 --- a/MMCore/CoreCallback.cpp +++ b/MMCore/CoreCallback.cpp @@ -124,21 +124,6 @@ CoreCallback::GetImageProcessor(const MM::Device*) } -MM::State* -CoreCallback::GetStateDevice(const MM::Device*, const char* label) -{ - try - { - return core_->deviceManager_->GetDeviceOfType(label)-> - GetRawPtr(); - } - catch (const CMMError&) - { - return 0; - } -} - - MM::SignalIO* CoreCallback::GetSignalIODevice(const MM::Device*, const char* label) { @@ -153,19 +138,6 @@ CoreCallback::GetSignalIODevice(const MM::Device*, const char* label) } -MM::AutoFocus* -CoreCallback::GetAutoFocus(const MM::Device*) -{ - std::shared_ptr autofocus = - core_->currentAutofocusDevice_.lock(); - if (autofocus) - { - return autofocus->GetRawPtr(); - } - return 0; -} - - MM::Hub* CoreCallback::GetParentHub(const MM::Device* caller) const { @@ -245,16 +217,12 @@ CoreCallback::AddCameraMetadata(const MM::Device* caller, const Metadata* pMd) int CoreCallback::InsertImage(const MM::Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, const char* serializedMetadata, const bool doProcess) { - Metadata md; - md.Restore(serializedMetadata); - return InsertImage(caller, buf, width, height, byteDepth, &md, doProcess); -} + Metadata origMd; + origMd.Restore(serializedMetadata); -int CoreCallback::InsertImage(const MM::Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, const Metadata* pMd, bool doProcess) -{ try { - Metadata md = AddCameraMetadata(caller, pMd); + Metadata md = AddCameraMetadata(caller, &origMd); if(doProcess) { @@ -277,16 +245,12 @@ int CoreCallback::InsertImage(const MM::Device* caller, const unsigned char* buf int CoreCallback::InsertImage(const MM::Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, unsigned nComponents, const char* serializedMetadata, const bool doProcess) { - Metadata md; - md.Restore(serializedMetadata); - return InsertImage(caller, buf, width, height, byteDepth, nComponents, &md, doProcess); -} + Metadata origMd; + origMd.Restore(serializedMetadata); -int CoreCallback::InsertImage(const MM::Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, unsigned nComponents, const Metadata* pMd, bool doProcess) -{ try { - Metadata md = AddCameraMetadata(caller, pMd); + Metadata md = AddCameraMetadata(caller, &origMd); if(doProcess) { @@ -307,20 +271,6 @@ int CoreCallback::InsertImage(const MM::Device* caller, const unsigned char* buf } } -int CoreCallback::InsertImage(const MM::Device* caller, const ImgBuffer & imgBuf) -{ - Metadata md = imgBuf.GetMetadata(); - unsigned char* p = const_cast(imgBuf.GetPixels()); - MM::ImageProcessor* ip = GetImageProcessor(caller); - if( NULL != ip) - { - ip->Process(p, imgBuf.Width(), imgBuf.Height(), imgBuf.Depth()); - } - - return InsertImage(caller, imgBuf.GetPixels(), imgBuf.Width(), - imgBuf.Height(), imgBuf.Depth(), &md); -} - void CoreCallback::ClearImageBuffer(const MM::Device* /*caller*/) { core_->cbuf_->Clear(); @@ -336,35 +286,6 @@ bool CoreCallback::InitializeImageBuffer(unsigned channels, unsigned slices, return core_->cbuf_->Initialize(channels, w, h, pixDepth); } -int CoreCallback::InsertMultiChannel(const MM::Device* caller, - const unsigned char* buf, - unsigned numChannels, - unsigned width, - unsigned height, - unsigned byteDepth, - Metadata* pMd) -{ - try - { - Metadata md = AddCameraMetadata(caller, pMd); - - MM::ImageProcessor* ip = GetImageProcessor(caller); - if( NULL != ip) - { - ip->Process( const_cast(buf), width, height, byteDepth); - } - if (core_->cbuf_->InsertMultiChannel(buf, numChannels, width, height, byteDepth, &md)) - return DEVICE_OK; - else - return DEVICE_BUFFER_OVERFLOW; - } - catch (CMMError& /*e*/) - { - return DEVICE_INCOMPATIBLE_IMAGE; - } - -} - int CoreCallback::AcqFinished(const MM::Device* caller, int /*statusCode*/) { std::shared_ptr camera; @@ -814,27 +735,6 @@ int CoreCallback::GetSerialAnswer(const MM::Device*, const char* portName, unsig return DEVICE_OK; } -const char* CoreCallback::GetImage() -{ - try - { - core_->snapImage(); - return (const char*) core_->getImage(); - } - catch (...) - { - return 0; - } -} - -int CoreCallback::GetImageDimensions(int& width, int& height, int& depth) -{ - width = core_->getImageWidth(); - height = core_->getImageHeight(); - depth = core_->getBytesPerPixel(); - return DEVICE_OK; -} - int CoreCallback::GetFocusPosition(double& pos) { std::shared_ptr focus = core_->currentFocusDevice_.lock(); @@ -846,36 +746,6 @@ int CoreCallback::GetFocusPosition(double& pos) return DEVICE_CORE_FOCUS_STAGE_UNDEF; } -int CoreCallback::SetFocusPosition(double pos) -{ - std::shared_ptr focus = core_->currentFocusDevice_.lock(); - if (focus) - { - int ret = focus->SetPositionUm(pos); - if (ret != DEVICE_OK) - return ret; - core_->waitForDevice(focus); - return DEVICE_OK; - } - return DEVICE_CORE_FOCUS_STAGE_UNDEF; -} - - -int CoreCallback::MoveFocus(double velocity) -{ - std::shared_ptr focus = core_->currentFocusDevice_.lock(); - if (focus) - { - mm::DeviceModuleLockGuard g(focus); - int ret = focus->Move(velocity); - if (ret != DEVICE_OK) - return ret; - return DEVICE_OK; - } - return DEVICE_CORE_FOCUS_STAGE_UNDEF; -} - - int CoreCallback::GetXYPosition(double& x, double& y) { std::shared_ptr xyStage = @@ -889,120 +759,6 @@ int CoreCallback::GetXYPosition(double& x, double& y) return DEVICE_CORE_FOCUS_STAGE_UNDEF; } -int CoreCallback::SetXYPosition(double x, double y) -{ - std::shared_ptr xyStage = - core_->currentXYStageDevice_.lock(); - if (xyStage) - { - int ret = xyStage->SetPositionUm(x, y); - if (ret != DEVICE_OK) - return ret; - core_->waitForDevice(xyStage); - return DEVICE_OK; - } - return DEVICE_CORE_FOCUS_STAGE_UNDEF; -} - -int CoreCallback::MoveXYStage(double vx, double vy) -{ - std::shared_ptr xyStage = - core_->currentXYStageDevice_.lock(); - if (xyStage) - { - mm::DeviceModuleLockGuard g(xyStage); - int ret = xyStage->Move(vx, vy); - if (ret != DEVICE_OK) - return ret; - return DEVICE_OK; - } - return DEVICE_CORE_FOCUS_STAGE_UNDEF; -} - -int CoreCallback::SetExposure(double expMs) -{ - try - { - core_->setExposure(expMs); - } - catch (...) - { - // TODO: log - return DEVICE_CORE_EXPOSURE_FAILED; - } - - return DEVICE_OK; -} - -int CoreCallback::GetExposure(double& expMs) -{ - try - { - expMs = core_->getExposure(); - } - catch (...) - { - // TODO: log - return DEVICE_CORE_EXPOSURE_FAILED; - } - - return DEVICE_OK; -} - -int CoreCallback::SetConfig(const char* group, const char* name) -{ - try - { - core_->setConfig(group, name); - core_->waitForConfig(group, name); - } - catch (...) - { - // TODO: log - return DEVICE_CORE_CONFIG_FAILED; - } - - return DEVICE_OK; -} - -int CoreCallback::GetCurrentConfig(const char* group, int bufLen, char* name) -{ - try - { - std::string cfgName = core_->getCurrentConfig(group); - strncpy(name, cfgName.c_str(), bufLen); - } - catch (...) - { - // TODO: log - return DEVICE_CORE_CONFIG_FAILED; - } - - return DEVICE_OK; -} - -int CoreCallback::GetChannelConfig(char* channelConfigName, const unsigned int channelConfigIterator) -{ - if (0 == channelConfigName) - return DEVICE_CORE_CHANNEL_PRESETS_FAILED; - try - { - channelConfigName[0] = 0; - - std::vector cfgs = core_->getAvailableConfigs(core_->getChannelGroup().c_str()); - if( channelConfigIterator < cfgs.size()) - { - strncpy( channelConfigName, cfgs.at(channelConfigIterator).c_str(), MM::MaxStrLength); - } - } - catch (...) - { - return DEVICE_CORE_CHANNEL_PRESETS_FAILED; - } - - return DEVICE_OK; -} - int CoreCallback::GetDeviceProperty(const char* deviceName, const char* propName, char* value) { try @@ -1033,42 +789,6 @@ int CoreCallback::SetDeviceProperty(const char* deviceName, const char* propName return DEVICE_OK; } -void CoreCallback::NextPostedError(int& errorCode, char* pMessage, int maxlen, int& messageLength) -{ - MMThreadGuard g(*(core_->pPostedErrorsLock_)); - errorCode = 0; - messageLength = 0; - if( 0 < core_->postedErrors_.size()) - { - std::pair< int, std::string> nextError = core_->postedErrors_.front(); - core_->postedErrors_.pop_front(); - errorCode = nextError.first; - if( 0 != pMessage) - { - if( 0 < maxlen ) - { - *pMessage = 0; - messageLength = std::min( maxlen, (int) nextError.second.length()); - strncpy(pMessage, nextError.second.c_str(), messageLength); - } - } - } - return ; -} - -void CoreCallback::PostError(const int errorCode, const char* pMessage) -{ - MMThreadGuard g(*(core_->pPostedErrorsLock_)); - core_->postedErrors_.push_back(std::make_pair(errorCode, std::string(pMessage))); -} - -void CoreCallback::ClearPostedErrors() -{ - MMThreadGuard g(*(core_->pPostedErrorsLock_)); - core_->postedErrors_.clear(); -} - - static long long SteadyMicroseconds() { using namespace std::chrono; diff --git a/MMCore/CoreCallback.h b/MMCore/CoreCallback.h index a40b1755a..91d06bd45 100644 --- a/MMCore/CoreCallback.h +++ b/MMCore/CoreCallback.h @@ -84,35 +84,17 @@ class CoreCallback : public MM::Core void Sleep(const MM::Device* caller, double intervalMs); // continuous acquisition support - /*Deprecated*/ int InsertImage(const MM::Device* caller, const ImgBuffer& imgBuf); // Note: _not_ mm::ImgBuffer int InsertImage(const MM::Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, const char* serializedMetadata, const bool doProcess = true); int InsertImage(const MM::Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, unsigned nComponents, const char* serializedMetadata, const bool doProcess = true); - - /*Deprecated*/ int InsertImage(const MM::Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, const Metadata* pMd = 0, const bool doProcess = true); - /*Deprecated*/ int InsertImage(const MM::Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, unsigned nComponents, const Metadata* pMd = 0, const bool doProcess = true); - - /*Deprecated*/ int InsertMultiChannel(const MM::Device* caller, const unsigned char* buf, unsigned numChannels, unsigned width, unsigned height, unsigned byteDepth, Metadata* pMd = 0); - /*Deprecated*/ void ClearImageBuffer(const MM::Device* caller); bool InitializeImageBuffer(unsigned channels, unsigned slices, unsigned int w, unsigned int h, unsigned int pixDepth); int AcqFinished(const MM::Device* caller, int statusCode); int PrepareForAcq(const MM::Device* caller); - // autofocus support - const char* GetImage(); - int GetImageDimensions(int& width, int& height, int& depth); + // Deprecated int GetFocusPosition(double& pos); - int SetFocusPosition(double pos); - int MoveFocus(double v); - int SetXYPosition(double x, double y); int GetXYPosition(double& x, double& y); - int MoveXYStage(double vX, double vY); - int SetExposure(double expMs); - int GetExposure(double& expMs); - int SetConfig(const char* group, const char* name); - int GetCurrentConfig(const char* group, int bufLen, char* name); - int GetChannelConfig(char* channelConfigName, const unsigned int channelConfigIterator); // notification handlers int OnPropertiesChanged(const MM::Device* caller); @@ -123,17 +105,10 @@ class CoreCallback : public MM::Core int OnSLMExposureChanged(const MM::Device* device, double newExposure); int OnMagnifierChanged(const MM::Device* device); - - void NextPostedError(int& errorCode, char* pMessage, int maxlen, int& messageLength); - void PostError(const int errorCode, const char* pMessage); - void ClearPostedErrors(); - - - MM::ImageProcessor* GetImageProcessor(const MM::Device* caller); - MM::State* GetStateDevice(const MM::Device* caller, const char* label); + // Deprecated MM::SignalIO* GetSignalIODevice(const MM::Device* caller, const char* label); - MM::AutoFocus* GetAutoFocus(const MM::Device* caller); + MM::Hub* GetParentHub(const MM::Device* caller) const; void GetLoadedDeviceOfType(const MM::Device* caller, MM::DeviceType devType, char* deviceName, const unsigned int deviceIterator); @@ -143,6 +118,7 @@ class CoreCallback : public MM::Core MMThreadLock* pValueChangeLock_; Metadata AddCameraMetadata(const MM::Device* caller, const Metadata* pMd); + MM::ImageProcessor* GetImageProcessor(const MM::Device* caller); int OnConfigGroupChanged(const char* groupName, const char* newConfigName); int OnPixelSizeChanged(double newPixelSizeUm); diff --git a/MMCore/MMCore.cpp b/MMCore/MMCore.cpp index f4198d81f..579b1d0f1 100644 --- a/MMCore/MMCore.cpp +++ b/MMCore/MMCore.cpp @@ -131,12 +131,10 @@ CMMCore::CMMCore() : pixelSizeGroup_(0), cbuf_(0), pluginManager_(new CPluginManager()), - deviceManager_(new mm::DeviceManager()), - pPostedErrorsLock_(NULL) + deviceManager_(new mm::DeviceManager()) { configGroups_ = new ConfigGroupCollection(); pixelSizeGroup_ = new PixelSizeConfigGroup(); - pPostedErrorsLock_ = new MMThreadLock(); InitializeErrorMessages(); @@ -186,7 +184,6 @@ CMMCore::~CMMCore() delete properties_; delete cbuf_; delete pixelSizeGroup_; - delete pPostedErrorsLock_; LOG_INFO(coreLogger_) << "Core session ended"; } @@ -2746,19 +2743,6 @@ void* CMMCore::getImage() MMCORE_LEGACY_THROW(CMMError) throw CMMError(getCoreErrorText(MMERR_InvalidImageSequence).c_str(), MMERR_InvalidImageSequence); } - // scope for the thread guard - { - MMThreadGuard g(*pPostedErrorsLock_); - - if(0 < postedErrors_.size()) - { - std::pair< int, std::string> toThrow(postedErrors_[0]); - // todo, process the collection of posted errors. - postedErrors_.clear(); - throw CMMError( toThrow.second.c_str(), toThrow.first); - } - } - void* pBuf(0); try { mm::DeviceModuleLockGuard guard(camera); @@ -2866,12 +2850,6 @@ long CMMCore::getImageBufferSize() */ void CMMCore::startSequenceAcquisition(long numImages, double intervalMs, bool stopOnOverflow) MMCORE_LEGACY_THROW(CMMError) { - // scope for the thread guard - { - MMThreadGuard g(*pPostedErrorsLock_); - postedErrors_.clear(); - } - std::shared_ptr camera = currentCameraDevice_.lock(); if (camera) { @@ -3124,21 +3102,6 @@ bool CMMCore::isSequenceRunning(const char* label) MMCORE_LEGACY_THROW(CMMError) */ void* CMMCore::getLastImage() MMCORE_LEGACY_THROW(CMMError) { - - // scope for the thread guard - { - MMThreadGuard g(*pPostedErrorsLock_); - - if(0 < postedErrors_.size()) - { - std::pair< int, std::string> toThrow(postedErrors_[0]); - // todo, process the collection of posted errors. - postedErrors_.clear(); - throw CMMError( toThrow.second.c_str(), toThrow.first); - - } - } - unsigned char* pBuf = const_cast(cbuf_->GetTopImage()); if (pBuf != 0) return pBuf; diff --git a/MMCore/MMCore.h b/MMCore/MMCore.h index 0f3f3f2b0..ffc706e60 100644 --- a/MMCore/MMCore.h +++ b/MMCore/MMCore.h @@ -726,9 +726,6 @@ class CMMCore mutable MMThreadLock stateCacheLock_; mutable Configuration stateCache_; // Synchronized by stateCacheLock_ - MMThreadLock* pPostedErrorsLock_; - mutable std::deque > postedErrors_; - // True while interpreting the config file (but not while rolling back on // failure): bool isLoadingSystemConfiguration_ = false; diff --git a/MMDevice/DeviceBase.h b/MMDevice/DeviceBase.h index d73054a3f..a17d1290f 100644 --- a/MMDevice/DeviceBase.h +++ b/MMDevice/DeviceBase.h @@ -96,11 +96,6 @@ class CDeviceBase : public T typedef MM::Action CPropertyAction; typedef MM::ActionEx CPropertyActionEx; - /** - * Returns the library handle (for use only by the calling code). - */ - virtual HDEVMODULE GetModuleHandle() const {return module_;} - /** * Assigns a name for the module (for use only by the calling code). */ @@ -133,11 +128,6 @@ class CDeviceBase : public T CDeviceUtils::CopyLimitedString(name, description_.c_str()); } - /** - * Sets the library handle (for use only by the calling code). - */ - virtual void SetModuleHandle(HDEVMODULE hModule) {module_ = hModule;} - /** * Sets the device label (for use only by the calling code). * Labels are usually manipulated by the parent application and used @@ -809,7 +799,7 @@ class CDeviceBase : public T protected: - CDeviceBase() : module_(0), delayMs_(0), usesDelay_(false), callback_(0) + CDeviceBase() : delayMs_(0), usesDelay_(false), callback_(0) { InitializeDefaultErrorMessages(); } @@ -1250,7 +1240,6 @@ class CDeviceBase : public T MM::PropertyCollection properties_; - HDEVMODULE module_; std::string label_; std::string moduleName_; std::string description_; diff --git a/MMDevice/MMDevice.h b/MMDevice/MMDevice.h index 95a4e1fbf..3ff5d27e4 100644 --- a/MMDevice/MMDevice.h +++ b/MMDevice/MMDevice.h @@ -28,7 +28,7 @@ // Header version // If any of the class definitions changes, the interface version // must be incremented -#define DEVICE_INTERFACE_VERSION 73 +#define DEVICE_INTERFACE_VERSION 74 /////////////////////////////////////////////////////////////////////////////// // N.B. @@ -52,17 +52,6 @@ #include #include -// To be removed once the deprecated Get/SetModuleHandle() is removed: -#ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #include - - typedef HMODULE HDEVMODULE; -#else - typedef void* HDEVMODULE; -#endif - -class ImgBuffer; namespace MM { @@ -266,9 +255,6 @@ namespace MM { virtual void SetDelayMs(double delay) = 0; virtual bool UsesDelay() = 0; - MM_DEPRECATED(virtual HDEVMODULE GetModuleHandle() const) = 0; - MM_DEPRECATED(virtual void SetModuleHandle(HDEVMODULE hLibraryHandle)) = 0; - virtual void SetLabel(const char* label) = 0; virtual void GetLabel(char* name) const = 0; virtual void SetModuleName(const char* moduleName) = 0; @@ -1585,9 +1571,6 @@ namespace MM { virtual int AcqFinished(const Device* caller, int statusCode) = 0; virtual int PrepareForAcq(const Device* caller) = 0; - /// \deprecated Use the other overloads instead. - MM_DEPRECATED(virtual int InsertImage(const Device* caller, const ImgBuffer& buf)) = 0; - /** * Cameras must call this function during sequence acquisition to send * each frame to the Core. @@ -1617,57 +1600,23 @@ namespace MM { */ virtual int InsertImage(const Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, unsigned nComponents, const char* serializedMetadata, const bool doProcess = true) = 0; - /// \deprecated Use the other overloads instead. - MM_DEPRECATED(virtual int InsertImage(const Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, const Metadata* md = 0, const bool doProcess = true)) = 0; - // TODO Upon removing the above deprecated overload, add a default - // argument `= nullptr` to `serializedMetadata` in the following - // overload. That allows existing device adapters to compile. - /** * Same as the overload with the added nComponents parameter. * * Assumes nComponents == 1 (grayscale). */ - virtual int InsertImage(const Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, const char* serializedMetadata, const bool doProcess = true) = 0; + virtual int InsertImage(const Device* caller, const unsigned char* buf, unsigned width, unsigned height, unsigned byteDepth, const char* serializedMetadata = nullptr, const bool doProcess = true) = 0; MM_DEPRECATED(virtual void ClearImageBuffer(const Device* caller)) = 0; virtual bool InitializeImageBuffer(unsigned channels, unsigned slices, unsigned int w, unsigned int h, unsigned int pixDepth) = 0; - /// \deprecated Use InsertImage() instead. - MM_DEPRECATED(virtual int InsertMultiChannel(const Device* caller, const unsigned char* buf, unsigned numChannels, unsigned width, unsigned height, unsigned byteDepth, Metadata* md = 0)) = 0; - - // Formerly intended for use by autofocus - MM_DEPRECATED(virtual const char* GetImage()) = 0; - MM_DEPRECATED(virtual int GetImageDimensions(int& width, int& height, int& depth)) = 0; + // These functions violate the separation between device adapters and + // will be removed as soon as we remove all uses. Never use in new code. MM_DEPRECATED(virtual int GetFocusPosition(double& pos)) = 0; - MM_DEPRECATED(virtual int SetFocusPosition(double pos)) = 0; - MM_DEPRECATED(virtual int MoveFocus(double velocity)) = 0; - MM_DEPRECATED(virtual int SetXYPosition(double x, double y)) = 0; MM_DEPRECATED(virtual int GetXYPosition(double& x, double& y)) = 0; - MM_DEPRECATED(virtual int MoveXYStage(double vX, double vY)) = 0; - MM_DEPRECATED(virtual int SetExposure(double expMs)) = 0; - MM_DEPRECATED(virtual int GetExposure(double& expMs)) = 0; - MM_DEPRECATED(virtual int SetConfig(const char* group, const char* name)) = 0; - MM_DEPRECATED(virtual int GetCurrentConfig(const char* group, int bufLen, char* name)) = 0; - MM_DEPRECATED(virtual int GetChannelConfig(char* channelConfigName, const unsigned int channelConfigIterator)) = 0; - - // Direct (and dangerous) access to specific device types - MM_DEPRECATED(virtual MM::ImageProcessor* GetImageProcessor(const MM::Device* caller)) = 0; - MM_DEPRECATED(virtual MM::AutoFocus* GetAutoFocus(const MM::Device* caller)) = 0; - - virtual MM::Hub* GetParentHub(const MM::Device* caller) const = 0; - - // More direct (and dangerous) access to specific device types - MM_DEPRECATED(virtual MM::State* GetStateDevice(const MM::Device* caller, const char* deviceName)) = 0; MM_DEPRECATED(virtual MM::SignalIO* GetSignalIODevice(const MM::Device* caller, const char* deviceName)) = 0; - // Asynchronous error handling (never implemented) - /// \deprecated Not sure what this was meant to do. - MM_DEPRECATED(virtual void NextPostedError(int& /*errorCode*/, char* /*pMessage*/, int /*maxlen*/, int& /*messageLength*/)) = 0; - /// \deprecated Better handling of asynchronous errors to be developed. - MM_DEPRECATED(virtual void PostError(const int, const char*)) = 0; - /// \deprecated Better handling of asynchronous errors to be developed. - MM_DEPRECATED(virtual void ClearPostedErrors(void)) = 0; + virtual MM::Hub* GetParentHub(const MM::Device* caller) const = 0; }; } // namespace MM