diff --git a/DeviceAdapters/ASIStage/ASIZStage.h b/DeviceAdapters/ASIStage/ASIZStage.h index f9a5cfefe..c37b19a19 100644 --- a/DeviceAdapters/ASIStage/ASIZStage.h +++ b/DeviceAdapters/ASIStage/ASIZStage.h @@ -37,6 +37,8 @@ class ZStage : public CStageBase, public ASIBase bool IsContinuousFocusDrive() const { return false; } + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface int OnPort(MM::PropertyBase* pProp, MM::ActionType eAct); int OnAxis(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/CNCMicroscope/RAMPSStage/XYStage.h b/DeviceAdapters/CNCMicroscope/RAMPSStage/XYStage.h index c8d671de3..9c007484a 100644 --- a/DeviceAdapters/CNCMicroscope/RAMPSStage/XYStage.h +++ b/DeviceAdapters/CNCMicroscope/RAMPSStage/XYStage.h @@ -66,6 +66,7 @@ class RAMPSXYStage : public CXYStageBase int IsXYStageSequenceable(bool& isSequenceable) const; + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } // action interface // ---------------- diff --git a/DeviceAdapters/CNCMicroscope/RAMPSStage/ZStage.h b/DeviceAdapters/CNCMicroscope/RAMPSStage/ZStage.h index 61f225ed5..7ac6d0393 100644 --- a/DeviceAdapters/CNCMicroscope/RAMPSStage/ZStage.h +++ b/DeviceAdapters/CNCMicroscope/RAMPSStage/ZStage.h @@ -66,6 +66,8 @@ class RAMPSZStage : public CStageBase bool IsContinuousFocusDrive() const; + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnPosition(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/Cephla/Squid.h b/DeviceAdapters/Cephla/Squid.h index 9de90b272..b1bf35020 100644 --- a/DeviceAdapters/Cephla/Squid.h +++ b/DeviceAdapters/Cephla/Squid.h @@ -284,6 +284,7 @@ class SquidXYStage : public CXYStageBase int IsXYStageSequenceable(bool& isSequenceable) const { isSequenceable = false; return DEVICE_OK; } + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } // action interface // ---------------- @@ -354,6 +355,8 @@ class SquidZStage : public CStageBase } bool IsContinuousFocusDrive() const { return false; }; + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + int OnAcceleration(MM::PropertyBase* pProp, MM::ActionType eAct); int OnMaxVelocity(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/ChuoSeiki_MD5000/ChuoSeiki_MD_XYZ.h b/DeviceAdapters/ChuoSeiki_MD5000/ChuoSeiki_MD_XYZ.h index d8e5c3aba..d9ce7ff8a 100644 --- a/DeviceAdapters/ChuoSeiki_MD5000/ChuoSeiki_MD_XYZ.h +++ b/DeviceAdapters/ChuoSeiki_MD5000/ChuoSeiki_MD_XYZ.h @@ -119,6 +119,7 @@ class MD_SingleStage: // Checking device functions int IsStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} bool IsContinuousFocusDrive() const {return DEVICE_OK;} + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } bool SupportsDeviceDetection(void); MM::DeviceDetectionStatus DetectDevice(void); @@ -227,6 +228,7 @@ public CXYStageBase double GetStepSizeYUm() { return stepSize_umY_; } int IsXYStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK; } + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } MM::DeviceDetectionStatus DetectDevice(void); protected: // check controller diff --git a/DeviceAdapters/ChuoSeiki_QT/ChuoSeiki_QT_XYZ.h b/DeviceAdapters/ChuoSeiki_QT/ChuoSeiki_QT_XYZ.h index 6df86506d..45d77a21e 100644 --- a/DeviceAdapters/ChuoSeiki_QT/ChuoSeiki_QT_XYZ.h +++ b/DeviceAdapters/ChuoSeiki_QT/ChuoSeiki_QT_XYZ.h @@ -251,6 +251,7 @@ class ChuoSeikiZStage : public CStageBase bool IsContinuousFocusDrive() const {return DEVICE_OK;} bool SupportsDeviceDetection(void){return DEVICE_OK;} MM::DeviceDetectionStatus DetectDevice(void); + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } private: diff --git a/DeviceAdapters/DemoCamera/DemoCamera.h b/DeviceAdapters/DemoCamera/DemoCamera.h index f6fc343ed..eb238f008 100644 --- a/DeviceAdapters/DemoCamera/DemoCamera.h +++ b/DeviceAdapters/DemoCamera/DemoCamera.h @@ -498,6 +498,8 @@ class CDemoStage : public CStageBase bool IsContinuousFocusDrive() const {return false;} + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnPosition(MM::PropertyBase* pProp, MM::ActionType eAct); @@ -578,6 +580,7 @@ class CDemoXYStage : public CXYStageBase int IsXYStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } // action interface // ---------------- diff --git a/DeviceAdapters/ESP32/esp32.h b/DeviceAdapters/ESP32/esp32.h index 60101a955..6f0f8a90b 100644 --- a/DeviceAdapters/ESP32/esp32.h +++ b/DeviceAdapters/ESP32/esp32.h @@ -325,6 +325,8 @@ class CESP32Stage : public CStageBase nrEvents = 0; return DEVICE_OK; } + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + private: double stepSizeUm_; double pos_um_; @@ -389,6 +391,8 @@ class CESP32XYStage : public CXYStageBase int IsXYStageSequenceable(bool& isSequenceable) const { isSequenceable = false; return DEVICE_OK; } + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + int OnXStageMinPos(MM::PropertyBase* pProp, MM::ActionType eAct); int OnXStageMaxPos(MM::PropertyBase* pProp, MM::ActionType eAct); int OnYStageMinPos(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/MCL_NanoDrive/MCL_NanoDrive_XYStage.h b/DeviceAdapters/MCL_NanoDrive/MCL_NanoDrive_XYStage.h index 540404b0e..594b278f0 100644 --- a/DeviceAdapters/MCL_NanoDrive/MCL_NanoDrive_XYStage.h +++ b/DeviceAdapters/MCL_NanoDrive/MCL_NanoDrive_XYStage.h @@ -46,6 +46,8 @@ class MCL_NanoDrive_XYStage : public CXYStageBase virtual double GetStepSizeYUm(); virtual int IsXYStageSequenceable(bool& isSequenceable) const; + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // Action interface int OnLowerLimitX(MM::PropertyBase* pProp, MM::ActionType eAct); int OnUpperLimitX(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/MCL_NanoDrive/MCL_NanoDrive_ZStage.h b/DeviceAdapters/MCL_NanoDrive/MCL_NanoDrive_ZStage.h index a54ab54e7..8a4a7dc53 100644 --- a/DeviceAdapters/MCL_NanoDrive/MCL_NanoDrive_ZStage.h +++ b/DeviceAdapters/MCL_NanoDrive/MCL_NanoDrive_ZStage.h @@ -51,6 +51,8 @@ class MCL_NanoDrive_ZStage : public CStageBase virtual int SendStageSequence(); virtual bool IsContinuousFocusDrive() const; + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // Action interface int OnLowerLimit(MM::PropertyBase* pProp, MM::ActionType eAct); int OnUpperLimit(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/MoticMicroscope/MoticMicroscope.h b/DeviceAdapters/MoticMicroscope/MoticMicroscope.h index 5875b773c..2e149c107 100644 --- a/DeviceAdapters/MoticMicroscope/MoticMicroscope.h +++ b/DeviceAdapters/MoticMicroscope/MoticMicroscope.h @@ -128,6 +128,8 @@ class XYStage : public CXYStageBase, public EventReceiver virtual int IsXYStageSequenceable(bool& isSequenceable) const; + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + void EventHandler(int eventId, int data); private: int _init; @@ -166,6 +168,8 @@ class ZStage : public CStageBase, public EventReceiver virtual bool IsContinuousFocusDrive() const; + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + void EventHandler(int eventId, int data); private: int _init; diff --git a/DeviceAdapters/NewportCONEX/Conex_Axis.h b/DeviceAdapters/NewportCONEX/Conex_Axis.h index 94b9d8810..e45fc0afc 100644 --- a/DeviceAdapters/NewportCONEX/Conex_Axis.h +++ b/DeviceAdapters/NewportCONEX/Conex_Axis.h @@ -118,6 +118,8 @@ class Axis : public CStageBase, public Conex_AxisBase bool IsContinuousFocusDrive() const {return false;} + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnPort (MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/NotificationTester/NotificationTester.cpp b/DeviceAdapters/NotificationTester/NotificationTester.cpp index 9683ac9c1..0d3a0b5dd 100644 --- a/DeviceAdapters/NotificationTester/NotificationTester.cpp +++ b/DeviceAdapters/NotificationTester/NotificationTester.cpp @@ -395,6 +395,11 @@ class NTestStage : public CStageBase> bool IsContinuousFocusDrive() const final { return false; } + + int UsesOnStagePositionChanged(bool& result) const final { + result = true; + return DEVICE_OK; + } }; template @@ -610,6 +615,11 @@ class NTestXYStage : public CXYStageBase> flag = false; return DEVICE_OK; } + + int UsesOnXYStagePositionChanged(bool& result) const final { + result = true; + return DEVICE_OK; + } }; MODULE_API void InitializeModuleData() diff --git a/DeviceAdapters/OpenFlexure/OpenFlexure.h b/DeviceAdapters/OpenFlexure/OpenFlexure.h index c72e8bd81..dd8437394 100644 --- a/DeviceAdapters/OpenFlexure/OpenFlexure.h +++ b/DeviceAdapters/OpenFlexure/OpenFlexure.h @@ -123,6 +123,8 @@ class XYStage : public CXYStageBase int GetLimitsUm(double& xMin, double& xMax, double& yMin, double& yMax); int IsXYStageSequenceable(bool& isSequenceable) const { isSequenceable = false; return DEVICE_OK; } + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + bool Busy() { return false; } void GetName(char*) const; @@ -165,6 +167,9 @@ class ZStage : public CStageBase int GetLimits(double& lower, double& upper) { return DEVICE_UNSUPPORTED_COMMAND;} // nah int IsStageSequenceable(bool& isSequenceable) const { isSequenceable = false; return DEVICE_OK;} bool IsContinuousFocusDrive() const { return false; } + + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + bool Busy() { return false; } // Helper functions diff --git a/DeviceAdapters/PIEZOCONCEPT/PIEZOCONCEPT.h b/DeviceAdapters/PIEZOCONCEPT/PIEZOCONCEPT.h index 4952fccfa..0af3f27cc 100644 --- a/DeviceAdapters/PIEZOCONCEPT/PIEZOCONCEPT.h +++ b/DeviceAdapters/PIEZOCONCEPT/PIEZOCONCEPT.h @@ -119,6 +119,8 @@ class CPiezoConceptStage : public CStageBase int GetStageSequenceMaxLength(long& nrEvents) const { nrEvents = 0; return DEVICE_OK; } + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + private: double stepSizeUm_; double pos_um_; @@ -182,6 +184,8 @@ class CPiezoConceptXYStage : public CXYStageBase int IsXYStageSequenceable(bool& isSequenceable) const { isSequenceable = false; return DEVICE_OK; } + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + int OnXStageMinPos(MM::PropertyBase* pProp, MM::ActionType eAct); int OnXStageMaxPos(MM::PropertyBase* pProp, MM::ActionType eAct); int OnYStageMinPos(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/PriorPureFocus/PureFocus.h b/DeviceAdapters/PriorPureFocus/PureFocus.h index 5e94fd27a..4bebb5744 100644 --- a/DeviceAdapters/PriorPureFocus/PureFocus.h +++ b/DeviceAdapters/PriorPureFocus/PureFocus.h @@ -170,6 +170,9 @@ class PureFocusOffset : public CStageBase { bool IsContinuousFocusDrive() const { return false; }; + + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + void CallbackPositionSteps(long steps); void RemoveHub() { pHub_ = 0; }; diff --git a/DeviceAdapters/PyDevice/PyStage.h b/DeviceAdapters/PyDevice/PyStage.h index dc0fa9430..3ec6665aa 100644 --- a/DeviceAdapters/PyDevice/PyStage.h +++ b/DeviceAdapters/PyDevice/PyStage.h @@ -32,6 +32,10 @@ class CPyStage : public PyStageClass { bool IsContinuousFocusDrive() const override { return true; } + int UsesOnStagePositionChanged(bool& result) const override { + result = true; + return DEVICE_OK; + } protected: double StepSizeUm() const; double origin_ = 0.0; @@ -118,6 +122,11 @@ class CPyXYStage : public PyXYStageClass { return DEVICE_UNSUPPORTED_COMMAND; } + int UsesOnXYStagePositionChanged(bool& result) const override { + result = true; + return DEVICE_OK; + } + protected: double origin_x_ = 0.0; double origin_y_ = 0.0; diff --git a/DeviceAdapters/SouthPort/microz.h b/DeviceAdapters/SouthPort/microz.h index 785a0ead1..601e37d8c 100644 --- a/DeviceAdapters/SouthPort/microz.h +++ b/DeviceAdapters/SouthPort/microz.h @@ -53,6 +53,8 @@ class MicroZStage : public CStageBase bool IsContinuousFocusDrive() const; + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // Sequence functions int IsStageSequenceable(bool& isSequenceable) const; int GetStageSequenceMaxLength(long& nrEvents) const; diff --git a/DeviceAdapters/Standa/Standa.h b/DeviceAdapters/Standa/Standa.h index fd67a6a4a..3fdc7693e 100644 --- a/DeviceAdapters/Standa/Standa.h +++ b/DeviceAdapters/Standa/Standa.h @@ -62,6 +62,8 @@ class StandaZStage : public CStageBase int IsStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} bool IsContinuousFocusDrive() const {return false;} + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnAxisLimit(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/Standa8SMC4/Standa8SMC4.h b/DeviceAdapters/Standa8SMC4/Standa8SMC4.h index de070083e..be436bfa1 100644 --- a/DeviceAdapters/Standa8SMC4/Standa8SMC4.h +++ b/DeviceAdapters/Standa8SMC4/Standa8SMC4.h @@ -58,6 +58,8 @@ class Standa8SMC4Z : public CStageBase virtual bool IsContinuousFocusDrive() const; + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnPort(MM::PropertyBase* pProp, MM::ActionType eAct); @@ -110,6 +112,8 @@ class Standa8SMC4XY : public CXYStageBase virtual bool IsContinuousFocusDrive() const; + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnPortX(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/StandaStage/StandaStage.h b/DeviceAdapters/StandaStage/StandaStage.h index ae20308cc..128142436 100644 --- a/DeviceAdapters/StandaStage/StandaStage.h +++ b/DeviceAdapters/StandaStage/StandaStage.h @@ -116,6 +116,8 @@ class CStandaStage : public CStageBase bool IsContinuousFocusDrive() const {return false;} + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- @@ -266,6 +268,7 @@ class CStandaXYStage : public CXYStageBase int IsXYStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } // action interface // ---------------- diff --git a/DeviceAdapters/ThorlabsAPTStage/ThorlabsAPTStage.h b/DeviceAdapters/ThorlabsAPTStage/ThorlabsAPTStage.h index 46cd807d2..ea2b8a811 100644 --- a/DeviceAdapters/ThorlabsAPTStage/ThorlabsAPTStage.h +++ b/DeviceAdapters/ThorlabsAPTStage/ThorlabsAPTStage.h @@ -80,6 +80,8 @@ class ThorlabsAPTStage : public CStageBase int IsStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} bool IsContinuousFocusDrive() const {return false;} + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnSerialNumber(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/TriggerScope/TriggerScope.h b/DeviceAdapters/TriggerScope/TriggerScope.h index fe2cdbe8d..366aa366e 100644 --- a/DeviceAdapters/TriggerScope/TriggerScope.h +++ b/DeviceAdapters/TriggerScope/TriggerScope.h @@ -348,6 +348,8 @@ class CTriggerScopeFocus : public CStageBase bool IsContinuousFocusDrive() const {return false;} + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + int OnSequence(MM::PropertyBase* pProp, MM::ActionType eAct); int OnDACNumber(MM::PropertyBase* pProp, MM::ActionType eAct); int OnUpperLimit(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/WOSM/WOSM.h b/DeviceAdapters/WOSM/WOSM.h index 542475bf3..34206d72e 100644 --- a/DeviceAdapters/WOSM/WOSM.h +++ b/DeviceAdapters/WOSM/WOSM.h @@ -330,6 +330,8 @@ class CWOSMStage : public CStageBase nrEvents = 0; return DEVICE_OK; } + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + private: double stepSizeUm_; double pos_um_; @@ -394,6 +396,8 @@ class CWOSMXYStage : public CXYStageBase int IsXYStageSequenceable(bool& isSequenceable) const { isSequenceable = false; return DEVICE_OK; } + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + int OnXStageMinPos(MM::PropertyBase* pProp, MM::ActionType eAct); int OnXStageMaxPos(MM::PropertyBase* pProp, MM::ActionType eAct); int OnYStageMinPos(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/WieneckeSinske/ZPiezoCanDevice.h b/DeviceAdapters/WieneckeSinske/ZPiezoCanDevice.h index 889e6c613..91941e580 100644 --- a/DeviceAdapters/WieneckeSinske/ZPiezoCanDevice.h +++ b/DeviceAdapters/WieneckeSinske/ZPiezoCanDevice.h @@ -77,7 +77,8 @@ class ZPiezoCANDevice : public CStageBase int SetOrigin(); int IsStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} - + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnPort(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/WieneckeSinske/ZPiezoWSDevice.h b/DeviceAdapters/WieneckeSinske/ZPiezoWSDevice.h index e99c444a7..dbd0c7300 100644 --- a/DeviceAdapters/WieneckeSinske/ZPiezoWSDevice.h +++ b/DeviceAdapters/WieneckeSinske/ZPiezoWSDevice.h @@ -77,7 +77,8 @@ class ZPiezoWSDevice : public CStageBase int SetOrigin(); int IsStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} - + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnPort(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/DeviceAdapters/ZeissCAN29/ZeissCAN29.h b/DeviceAdapters/ZeissCAN29/ZeissCAN29.h index 79ef67051..f251d11d3 100644 --- a/DeviceAdapters/ZeissCAN29/ZeissCAN29.h +++ b/DeviceAdapters/ZeissCAN29/ZeissCAN29.h @@ -836,6 +836,8 @@ class Axis : public CStageBase, public ZeissAxis int IsStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} bool IsContinuousFocusDrive() const {return false;} + int UsesOnStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnPosition(MM::PropertyBase* pProp, MM::ActionType eAct); @@ -890,6 +892,8 @@ class XYStage : public CXYStageBase, public ZeissAxis double GetStepSizeYUm() {return stepSize_um_;} int IsXYStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} + int UsesOnXYStagePositionChanged(bool& result) const { result = true; return DEVICE_OK; } + // action interface // ---------------- int OnMoveMode(MM::PropertyBase* pProp, MM::ActionType eAct); diff --git a/MMCore/Devices/StageInstance.cpp b/MMCore/Devices/StageInstance.cpp index 666f8f9b0..d620f7116 100644 --- a/MMCore/Devices/StageInstance.cpp +++ b/MMCore/Devices/StageInstance.cpp @@ -60,6 +60,7 @@ StageInstance::SetFocusDirection(MM::FocusDirection direction) focusDirectionHasBeenSet_ = true; } +int StageInstance::UsesOnStagePositionChanged(bool& result) const { RequireInitialized(__func__); return GetImpl()->UsesOnStagePositionChanged(result); } int StageInstance::IsStageSequenceable(bool& isSequenceable) const { RequireInitialized(__func__); return GetImpl()->IsStageSequenceable(isSequenceable); } int StageInstance::IsStageLinearSequenceable(bool& isSequenceable) const { RequireInitialized(__func__); return GetImpl()->IsStageLinearSequenceable(isSequenceable); } bool StageInstance::IsContinuousFocusDrive() const { RequireInitialized(__func__); return GetImpl()->IsContinuousFocusDrive(); } diff --git a/MMCore/Devices/StageInstance.h b/MMCore/Devices/StageInstance.h index b94b1e6bf..b4e2cff93 100644 --- a/MMCore/Devices/StageInstance.h +++ b/MMCore/Devices/StageInstance.h @@ -57,6 +57,7 @@ class StageInstance : public DeviceInstanceBase int GetLimits(double& lower, double& upper); MM::FocusDirection GetFocusDirection(); void SetFocusDirection(MM::FocusDirection direction); + int UsesOnStagePositionChanged(bool& result) const; int IsStageSequenceable(bool& isSequenceable) const; int IsStageLinearSequenceable(bool& isSequenceable) const; bool IsContinuousFocusDrive() const; diff --git a/MMCore/Devices/XYStageInstance.cpp b/MMCore/Devices/XYStageInstance.cpp index 56f06844a..0b18bce63 100644 --- a/MMCore/Devices/XYStageInstance.cpp +++ b/MMCore/Devices/XYStageInstance.cpp @@ -42,6 +42,7 @@ int XYStageInstance::SetYOrigin() { RequireInitialized(__func__); return GetImpl int XYStageInstance::GetStepLimits(long& xMin, long& xMax, long& yMin, long& yMax) { RequireInitialized(__func__); return GetImpl()->GetStepLimits(xMin, xMax, yMin, yMax); } double XYStageInstance::GetStepSizeXUm() { RequireInitialized(__func__); return GetImpl()->GetStepSizeXUm(); } double XYStageInstance::GetStepSizeYUm() { RequireInitialized(__func__); return GetImpl()->GetStepSizeYUm(); } +int XYStageInstance::UsesOnXYStagePositionChanged(bool& result) const { RequireInitialized(__func__); return GetImpl()->UsesOnXYStagePositionChanged(result); } int XYStageInstance::IsXYStageSequenceable(bool& isSequenceable) const { RequireInitialized(__func__); return GetImpl()->IsXYStageSequenceable(isSequenceable); } int XYStageInstance::GetXYStageSequenceMaxLength(long& nrEvents) const { RequireInitialized(__func__); return GetImpl()->GetXYStageSequenceMaxLength(nrEvents); } int XYStageInstance::StartXYStageSequence() { RequireInitialized(__func__); return GetImpl()->StartXYStageSequence(); } diff --git a/MMCore/Devices/XYStageInstance.h b/MMCore/Devices/XYStageInstance.h index 9dd21a46e..b6819359f 100644 --- a/MMCore/Devices/XYStageInstance.h +++ b/MMCore/Devices/XYStageInstance.h @@ -56,6 +56,7 @@ class XYStageInstance : public DeviceInstanceBase int GetStepLimits(long& xMin, long& xMax, long& yMin, long& yMax); double GetStepSizeXUm(); double GetStepSizeYUm(); + int UsesOnXYStagePositionChanged(bool& result) const; int IsXYStageSequenceable(bool& isSequenceable) const; int GetXYStageSequenceMaxLength(long& nrEvents) const; int StartXYStageSequence(); diff --git a/MMCore/MMCore.cpp b/MMCore/MMCore.cpp index 0ac29080a..a73b32827 100644 --- a/MMCore/MMCore.cpp +++ b/MMCore/MMCore.cpp @@ -106,7 +106,7 @@ namespace mmi = mmcore::internal; * (Keep the 3 numbers on one line to make it easier to look at diffs when * merging/rebasing.) */ -const int MMCore_versionMajor = 11, MMCore_versionMinor = 11, MMCore_versionPatch = 0; +const int MMCore_versionMajor = 11, MMCore_versionMinor = 12, MMCore_versionPatch = 0; /////////////////////////////////////////////////////////////////////////////// @@ -2265,6 +2265,24 @@ void CMMCore::loadExposureSequence(const char* cameraLabel, std::vector throw CMMError(getDeviceErrorText(ret, pCamera)); } +/** +* Queries whether this stage uses callbacks to signal position changes +* When false, use polling to stay updated about the positionf of the stage +*/ +bool CMMCore::isStageUsingCallbacks(const char* label) MMCORE_LEGACY_THROW(CMMError) +{ + std::shared_ptr pStage = + deviceManager_->GetDeviceOfType(label); + + mmi::DeviceModuleLockGuard guard(pStage); + + bool result; + int ret = pStage->UsesOnStagePositionChanged(result); + if (ret != DEVICE_OK) + throw CMMError(getDeviceErrorText(ret, pStage)); + return result; +} + /** * Queries stage if it can be used in a sequence @@ -2417,6 +2435,26 @@ void CMMCore::setStageLinearSequence(const char* label, double dZ_um, int nSlice throw CMMError(getDeviceErrorText(ret, pStage)); } + +/** +* Queries whether this XYStage uses callbacks to signal position changes +* When false, use polling to stay updated about the positionf of the stage +*/ +bool CMMCore::isXYStageUsingCallbacks(const char* label) MMCORE_LEGACY_THROW(CMMError) +{ + std::shared_ptr pStage = + deviceManager_->GetDeviceOfType(label); + + mmi::DeviceModuleLockGuard guard(pStage); + + bool result; + int ret = pStage->UsesOnXYStagePositionChanged(result); + if (ret != DEVICE_OK) + throw CMMError(getDeviceErrorText(ret, pStage)); + + return result; +} + /** * Queries XY stage if it can be used in a sequence * @param label the XY stage device label diff --git a/MMCore/MMCore.h b/MMCore/MMCore.h index b8d68e056..302255505 100644 --- a/MMCore/MMCore.h +++ b/MMCore/MMCore.h @@ -499,6 +499,7 @@ class CMMCore void setFocusDirection(const char* stageLabel, int sign); int getFocusDirection(const char* stageLabel) MMCORE_LEGACY_THROW(CMMError); + bool isStageUsingCallbacks(const char* stageLabel) MMCORE_LEGACY_THROW(CMMError); bool isStageSequenceable(const char* stageLabel) MMCORE_LEGACY_THROW(CMMError); bool isStageLinearSequenceable(const char* stageLabel) MMCORE_LEGACY_THROW(CMMError); void startStageSequence(const char* stageLabel) MMCORE_LEGACY_THROW(CMMError); @@ -536,6 +537,7 @@ class CMMCore double newXUm, double newYUm) MMCORE_LEGACY_THROW(CMMError); void setAdapterOriginXY(double newXUm, double newYUm) MMCORE_LEGACY_THROW(CMMError); + bool isXYStageUsingCallbacks(const char* xyStageLabel) MMCORE_LEGACY_THROW(CMMError); bool isXYStageSequenceable(const char* xyStageLabel) MMCORE_LEGACY_THROW(CMMError); void startXYStageSequence(const char* xyStageLabel) MMCORE_LEGACY_THROW(CMMError); void stopXYStageSequence(const char* xyStageLabel) MMCORE_LEGACY_THROW(CMMError); diff --git a/MMDevice/DeviceBase.h b/MMDevice/DeviceBase.h index 8fb7aab1e..055dbda33 100644 --- a/MMDevice/DeviceBase.h +++ b/MMDevice/DeviceBase.h @@ -1893,6 +1893,15 @@ class CStageBase : public CDeviceBase return DEVICE_OK; } + /** + * @brief Return true when your device adapter uses OnStagePositionChanged callbacks. + */ + virtual int UsesOnStagePositionChanged(bool& result) const + { + result = false; + return DEVICE_OK; + } + virtual int IsStageLinearSequenceable(bool& isSequenceable) const { isSequenceable = false; @@ -2103,6 +2112,15 @@ class CXYStageBase : public CDeviceBase return this->SetPositionSteps(xSteps+x, ySteps+y); } + /** + * @brief Return true when your device adapter uses OnXYStagePositionChanged callbacks. + */ + virtual int UsesOnXYStagePositionChanged(bool& result) const + { + result = false; + return DEVICE_OK; + } + virtual int Move(double /*vx*/, double /*vy*/) { return DEVICE_UNSUPPORTED_COMMAND; diff --git a/MMDevice/MMDevice.h b/MMDevice/MMDevice.h index 0027736ea..201dba3c6 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 74 +#define DEVICE_INTERFACE_VERSION 75 /////////////////////////////////////////////////////////////////////////////// // N.B. @@ -603,6 +603,15 @@ namespace MM { virtual int SetOrigin() = 0; virtual int GetLimits(double& lower, double& upper) = 0; + /** + * @brief Stages can use the OnStagePositionChanged callback to signal + * updates about their position. Some adapters do so, others do not, + * in which case the UI code should use polling. This function signals whether + * the device adapters uses callbacks, so that the UI knows it does not need + * to poll this device + */ + virtual int UsesOnStagePositionChanged(bool& result) const = 0; + /** * @brief Return the focus direction. * @@ -709,6 +718,15 @@ namespace MM { virtual int Home() = 0; virtual int Stop() = 0; + /** + * @brief XY stages can use the OnXYStagePositionChanged callback to signal + * updates about their position. Some stage adapters do so, others do not, + * in which case the UI code can use polling. This function signals whether + * the device adapters uses callbacks, so that the UI knows it does not need + * to poll this device + */ + virtual int UsesOnXYStagePositionChanged(bool &result) const = 0; + /** * @brief Define the current position as the (hardware) origin (0, 0). */