Skip to content

Commit

Permalink
MMCore: Revert strict initialization checks
Browse files Browse the repository at this point in the history
When an operation that requires an initialized device is attempted on an
uninitalized device, log a warning message instead of throwing an
exception.

It turns out that the Hardware Configuration Wizard currently relies
(mostly incorrectly) on some operations that are not actually correct,
but fixing it is complicated enough that we need to revert the exception
throwing for now.

In addition, MMCore itself needs some fixes so that functions like
waitForSystem() do not cause issues in the presence of uninitialized
devices. This may also apply to other bulk actions such as
unloadAllDevices() and the system state cache.

The goal is still to enable exceptions for these checks, but only once
we've had a chance to fix these issues.

This does not revert the checks against multiple initialization attempts
and against setting a pre-init property after initialization. These are
not known to cause any issues so far.

Also add the name of the operation to the logged warning message to
assist with the necessary fixes. The log messages have log level `WRN`,
which should stand out since we have never used it before. This is to
prevent people from thinking that the "normal" operation of the Hardware
Configuration Wizard is causing errors.

Bump MMCore version to 10.6.0.
  • Loading branch information
marktsuchida committed Sep 29, 2023
1 parent 6e8b23e commit 945f97a
Show file tree
Hide file tree
Showing 17 changed files with 182 additions and 175 deletions.
20 changes: 10 additions & 10 deletions MMCore/Devices/AutoFocusInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
#include "AutoFocusInstance.h"


int AutoFocusInstance::SetContinuousFocusing(bool state) { RequireInitialized(); return GetImpl()->SetContinuousFocusing(state); }
int AutoFocusInstance::GetContinuousFocusing(bool& state) { RequireInitialized(); return GetImpl()->GetContinuousFocusing(state); }
bool AutoFocusInstance::IsContinuousFocusLocked() { RequireInitialized(); return GetImpl()->IsContinuousFocusLocked(); }
int AutoFocusInstance::FullFocus() { RequireInitialized(); return GetImpl()->FullFocus(); }
int AutoFocusInstance::IncrementalFocus() { RequireInitialized(); return GetImpl()->IncrementalFocus(); }
int AutoFocusInstance::GetLastFocusScore(double& score) { RequireInitialized(); return GetImpl()->GetLastFocusScore(score); }
int AutoFocusInstance::GetCurrentFocusScore(double& score) { RequireInitialized(); return GetImpl()->GetCurrentFocusScore(score); }
int AutoFocusInstance::AutoSetParameters() { RequireInitialized(); return GetImpl()->AutoSetParameters(); }
int AutoFocusInstance::GetOffset(double &offset) { RequireInitialized(); return GetImpl()->GetOffset(offset); }
int AutoFocusInstance::SetOffset(double offset) { RequireInitialized(); return GetImpl()->SetOffset(offset); }
int AutoFocusInstance::SetContinuousFocusing(bool state) { RequireInitialized(__func__); return GetImpl()->SetContinuousFocusing(state); }
int AutoFocusInstance::GetContinuousFocusing(bool& state) { RequireInitialized(__func__); return GetImpl()->GetContinuousFocusing(state); }
bool AutoFocusInstance::IsContinuousFocusLocked() { RequireInitialized(__func__); return GetImpl()->IsContinuousFocusLocked(); }
int AutoFocusInstance::FullFocus() { RequireInitialized(__func__); return GetImpl()->FullFocus(); }
int AutoFocusInstance::IncrementalFocus() { RequireInitialized(__func__); return GetImpl()->IncrementalFocus(); }
int AutoFocusInstance::GetLastFocusScore(double& score) { RequireInitialized(__func__); return GetImpl()->GetLastFocusScore(score); }
int AutoFocusInstance::GetCurrentFocusScore(double& score) { RequireInitialized(__func__); return GetImpl()->GetCurrentFocusScore(score); }
int AutoFocusInstance::AutoSetParameters() { RequireInitialized(__func__); return GetImpl()->AutoSetParameters(); }
int AutoFocusInstance::GetOffset(double &offset) { RequireInitialized(__func__); return GetImpl()->GetOffset(offset); }
int AutoFocusInstance::SetOffset(double offset) { RequireInitialized(__func__); return GetImpl()->SetOffset(offset); }
82 changes: 41 additions & 41 deletions MMCore/Devices/CameraInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,53 +22,53 @@
#include "CameraInstance.h"


int CameraInstance::SnapImage() { RequireInitialized(); return GetImpl()->SnapImage(); }
const unsigned char* CameraInstance::GetImageBuffer() { RequireInitialized(); return GetImpl()->GetImageBuffer(); }
const unsigned char* CameraInstance::GetImageBuffer(unsigned channelNr) { RequireInitialized(); return GetImpl()->GetImageBuffer(channelNr); }
const unsigned int* CameraInstance::GetImageBufferAsRGB32() { RequireInitialized(); return GetImpl()->GetImageBufferAsRGB32(); }
unsigned CameraInstance::GetNumberOfComponents() const { RequireInitialized(); return GetImpl()->GetNumberOfComponents(); }
int CameraInstance::SnapImage() { RequireInitialized(__func__); return GetImpl()->SnapImage(); }
const unsigned char* CameraInstance::GetImageBuffer() { RequireInitialized(__func__); return GetImpl()->GetImageBuffer(); }
const unsigned char* CameraInstance::GetImageBuffer(unsigned channelNr) { RequireInitialized(__func__); return GetImpl()->GetImageBuffer(channelNr); }
const unsigned int* CameraInstance::GetImageBufferAsRGB32() { RequireInitialized(__func__); return GetImpl()->GetImageBufferAsRGB32(); }
unsigned CameraInstance::GetNumberOfComponents() const { RequireInitialized(__func__); return GetImpl()->GetNumberOfComponents(); }

std::string CameraInstance::GetComponentName(unsigned component)
{
RequireInitialized();
RequireInitialized(__func__);
DeviceStringBuffer nameBuf(this, "GetComponentName");
int err = GetImpl()->GetComponentName(component, nameBuf.GetBuffer());
ThrowIfError(err, "Cannot get component name at index " +
ToString(component));
return nameBuf.Get();
}

int unsigned CameraInstance::GetNumberOfChannels() const { RequireInitialized(); return GetImpl()->GetNumberOfChannels(); }
int unsigned CameraInstance::GetNumberOfChannels() const { RequireInitialized(__func__); return GetImpl()->GetNumberOfChannels(); }

std::string CameraInstance::GetChannelName(unsigned channel)
{
RequireInitialized();
RequireInitialized(__func__);
DeviceStringBuffer nameBuf(this, "GetChannelName");
int err = GetImpl()->GetChannelName(channel, nameBuf.GetBuffer());
ThrowIfError(err, "Cannot get channel name at index " + ToString(channel));
return nameBuf.Get();
}

long CameraInstance::GetImageBufferSize() const { RequireInitialized(); return GetImpl()->GetImageBufferSize(); }
unsigned CameraInstance::GetImageWidth() const { RequireInitialized(); return GetImpl()->GetImageWidth(); }
unsigned CameraInstance::GetImageHeight() const { RequireInitialized(); return GetImpl()->GetImageHeight(); }
unsigned CameraInstance::GetImageBytesPerPixel() const { RequireInitialized(); return GetImpl()->GetImageBytesPerPixel(); }
unsigned CameraInstance::GetBitDepth() const { RequireInitialized(); return GetImpl()->GetBitDepth(); }
double CameraInstance::GetPixelSizeUm() const { RequireInitialized(); return GetImpl()->GetPixelSizeUm(); }
int CameraInstance::GetBinning() const { RequireInitialized(); return GetImpl()->GetBinning(); }
int CameraInstance::SetBinning(int binSize) { RequireInitialized(); return GetImpl()->SetBinning(binSize); }
void CameraInstance::SetExposure(double exp_ms) { RequireInitialized(); return GetImpl()->SetExposure(exp_ms); }
double CameraInstance::GetExposure() const { RequireInitialized(); return GetImpl()->GetExposure(); }
int CameraInstance::SetROI(unsigned x, unsigned y, unsigned xSize, unsigned ySize) { RequireInitialized(); return GetImpl()->SetROI(x, y, xSize, ySize); }
int CameraInstance::GetROI(unsigned& x, unsigned& y, unsigned& xSize, unsigned& ySize) { RequireInitialized(); return GetImpl()->GetROI(x, y, xSize, ySize); }
int CameraInstance::ClearROI() { RequireInitialized(); return GetImpl()->ClearROI(); }
long CameraInstance::GetImageBufferSize() const { RequireInitialized(__func__); return GetImpl()->GetImageBufferSize(); }
unsigned CameraInstance::GetImageWidth() const { RequireInitialized(__func__); return GetImpl()->GetImageWidth(); }
unsigned CameraInstance::GetImageHeight() const { RequireInitialized(__func__); return GetImpl()->GetImageHeight(); }
unsigned CameraInstance::GetImageBytesPerPixel() const { RequireInitialized(__func__); return GetImpl()->GetImageBytesPerPixel(); }
unsigned CameraInstance::GetBitDepth() const { RequireInitialized(__func__); return GetImpl()->GetBitDepth(); }
double CameraInstance::GetPixelSizeUm() const { RequireInitialized(__func__); return GetImpl()->GetPixelSizeUm(); }
int CameraInstance::GetBinning() const { RequireInitialized(__func__); return GetImpl()->GetBinning(); }
int CameraInstance::SetBinning(int binSize) { RequireInitialized(__func__); return GetImpl()->SetBinning(binSize); }
void CameraInstance::SetExposure(double exp_ms) { RequireInitialized(__func__); return GetImpl()->SetExposure(exp_ms); }
double CameraInstance::GetExposure() const { RequireInitialized(__func__); return GetImpl()->GetExposure(); }
int CameraInstance::SetROI(unsigned x, unsigned y, unsigned xSize, unsigned ySize) { RequireInitialized(__func__); return GetImpl()->SetROI(x, y, xSize, ySize); }
int CameraInstance::GetROI(unsigned& x, unsigned& y, unsigned& xSize, unsigned& ySize) { RequireInitialized(__func__); return GetImpl()->GetROI(x, y, xSize, ySize); }
int CameraInstance::ClearROI() { RequireInitialized(__func__); return GetImpl()->ClearROI(); }

/**
* Queries if the camera supports multiple simultaneous ROIs.
*/
bool CameraInstance::SupportsMultiROI()
{
RequireInitialized();
RequireInitialized(__func__);
return GetImpl()->SupportsMultiROI();
}

Expand All @@ -79,7 +79,7 @@ bool CameraInstance::SupportsMultiROI()
*/
bool CameraInstance::IsMultiROISet()
{
RequireInitialized();
RequireInitialized(__func__);
return GetImpl()->IsMultiROISet();
}

Expand All @@ -89,7 +89,7 @@ bool CameraInstance::IsMultiROISet()
*/
int CameraInstance::GetMultiROICount(unsigned int& count)
{
RequireInitialized();
RequireInitialized(__func__);
return GetImpl()->GetMultiROICount(count);
}

Expand All @@ -106,7 +106,7 @@ int CameraInstance::SetMultiROI(const unsigned int* xs, const unsigned int* ys,
const unsigned* widths, const unsigned int* heights,
unsigned numROIs)
{
RequireInitialized();
RequireInitialized(__func__);
return GetImpl()->SetMultiROI(xs, ys, widths, heights, numROIs);
}

Expand All @@ -123,19 +123,19 @@ int CameraInstance::SetMultiROI(const unsigned int* xs, const unsigned int* ys,
int CameraInstance::GetMultiROI(unsigned* xs, unsigned* ys, unsigned* widths,
unsigned* heights, unsigned* length)
{
RequireInitialized();
RequireInitialized(__func__);
return GetImpl()->GetMultiROI(xs, ys, widths, heights, length);
}

int CameraInstance::StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow) { RequireInitialized(); return GetImpl()->StartSequenceAcquisition(numImages, interval_ms, stopOnOverflow); }
int CameraInstance::StartSequenceAcquisition(double interval_ms) { RequireInitialized(); return GetImpl()->StartSequenceAcquisition(interval_ms); }
int CameraInstance::StopSequenceAcquisition() { RequireInitialized(); return GetImpl()->StopSequenceAcquisition(); }
int CameraInstance::PrepareSequenceAcqusition() { RequireInitialized(); return GetImpl()->PrepareSequenceAcqusition(); }
bool CameraInstance::IsCapturing() { RequireInitialized(); return GetImpl()->IsCapturing(); }
int CameraInstance::StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow) { RequireInitialized(__func__); return GetImpl()->StartSequenceAcquisition(numImages, interval_ms, stopOnOverflow); }
int CameraInstance::StartSequenceAcquisition(double interval_ms) { RequireInitialized(__func__); return GetImpl()->StartSequenceAcquisition(interval_ms); }
int CameraInstance::StopSequenceAcquisition() { RequireInitialized(__func__); return GetImpl()->StopSequenceAcquisition(); }
int CameraInstance::PrepareSequenceAcqusition() { RequireInitialized(__func__); return GetImpl()->PrepareSequenceAcqusition(); }
bool CameraInstance::IsCapturing() { RequireInitialized(__func__); return GetImpl()->IsCapturing(); }

std::string CameraInstance::GetTags()
{
RequireInitialized();
RequireInitialized(__func__);
// TODO Probably makes sense to deserialize here.
// Also note the danger of limiting serialized metadata to MM::MaxStrLength
// (CCameraBase takes no precaution to limit string length; it is an
Expand All @@ -145,12 +145,12 @@ std::string CameraInstance::GetTags()
return serializedMetadataBuf.Get();
}

void CameraInstance::AddTag(const char* key, const char* deviceLabel, const char* value) { RequireInitialized(); return GetImpl()->AddTag(key, deviceLabel, value); }
void CameraInstance::RemoveTag(const char* key) { RequireInitialized(); return GetImpl()->RemoveTag(key); }
int CameraInstance::IsExposureSequenceable(bool& isSequenceable) const { RequireInitialized(); return GetImpl()->IsExposureSequenceable(isSequenceable); }
int CameraInstance::GetExposureSequenceMaxLength(long& nrEvents) const { RequireInitialized(); return GetImpl()->GetExposureSequenceMaxLength(nrEvents); }
int CameraInstance::StartExposureSequence() { RequireInitialized(); return GetImpl()->StartExposureSequence(); }
int CameraInstance::StopExposureSequence() { RequireInitialized(); return GetImpl()->StopExposureSequence(); }
int CameraInstance::ClearExposureSequence() { RequireInitialized(); return GetImpl()->ClearExposureSequence(); }
int CameraInstance::AddToExposureSequence(double exposureTime_ms) { RequireInitialized(); return GetImpl()->AddToExposureSequence(exposureTime_ms); }
int CameraInstance::SendExposureSequence() const { RequireInitialized(); return GetImpl()->SendExposureSequence(); }
void CameraInstance::AddTag(const char* key, const char* deviceLabel, const char* value) { RequireInitialized(__func__); return GetImpl()->AddTag(key, deviceLabel, value); }
void CameraInstance::RemoveTag(const char* key) { RequireInitialized(__func__); return GetImpl()->RemoveTag(key); }
int CameraInstance::IsExposureSequenceable(bool& isSequenceable) const { RequireInitialized(__func__); return GetImpl()->IsExposureSequenceable(isSequenceable); }
int CameraInstance::GetExposureSequenceMaxLength(long& nrEvents) const { RequireInitialized(__func__); return GetImpl()->GetExposureSequenceMaxLength(nrEvents); }
int CameraInstance::StartExposureSequence() { RequireInitialized(__func__); return GetImpl()->StartExposureSequence(); }
int CameraInstance::StopExposureSequence() { RequireInitialized(__func__); return GetImpl()->StopExposureSequence(); }
int CameraInstance::ClearExposureSequence() { RequireInitialized(__func__); return GetImpl()->ClearExposureSequence(); }
int CameraInstance::AddToExposureSequence(double exposureTime_ms) { RequireInitialized(__func__); return GetImpl()->AddToExposureSequence(exposureTime_ms); }
int CameraInstance::SendExposureSequence() const { RequireInitialized(__func__); return GetImpl()->SendExposureSequence(); }
17 changes: 12 additions & 5 deletions MMCore/Devices/DeviceInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,17 @@ DeviceInstance::ThrowIfError(int code, const std::string& message) const
}

void
DeviceInstance::RequireInitialized() const
{
if (!initialized_)
ThrowError("Operation not permitted on uninitialized device");
DeviceInstance::RequireInitialized(const char *operation) const
{
if (!initialized_) {
// This is an error, but existing application code (in particular,
// the Hardware Configuration Wizard) breaks if we enforce it strictly.
// Until such code is fixed, we only log.
LOG_WARNING(Logger()) << "Operation (" << operation <<
") not permitted on uninitialized device (this will be an error in a future version of MMCore; for now we continue with the operation anyway, even though it might not be safe)";
// Eventually to be replaced with:
// ThrowError("Operation not permitted on uninitialized device");
}
}

void
Expand Down Expand Up @@ -326,7 +333,7 @@ DeviceInstance::GetErrorText(int code) const
bool
DeviceInstance::Busy()
{
RequireInitialized();
RequireInitialized(__func__);
return pImpl_->Busy();
}

Expand Down
2 changes: 1 addition & 1 deletion MMCore/Devices/DeviceInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class DeviceInstance
void ThrowError(const std::string& message) const;
void ThrowIfError(int code) const;
void ThrowIfError(int code, const std::string& message) const;
void RequireInitialized() const;
void RequireInitialized(const char *) const;

/// Utility class for getting fixed-length strings from the device interface.
/**
Expand Down
34 changes: 17 additions & 17 deletions MMCore/Devices/GalvoInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,26 @@
#include "GalvoInstance.h"


int GalvoInstance::PointAndFire(double x, double y, double time_us) { RequireInitialized(); return GetImpl()->PointAndFire(x, y, time_us); }
int GalvoInstance::SetSpotInterval(double pulseInterval_us) { RequireInitialized(); return GetImpl()->SetSpotInterval(pulseInterval_us); }
int GalvoInstance::SetPosition(double x, double y) { RequireInitialized(); return GetImpl()->SetPosition(x, y); }
int GalvoInstance::GetPosition(double& x, double& y) { RequireInitialized(); return GetImpl()->GetPosition(x, y); }
int GalvoInstance::SetIlluminationState(bool on) { RequireInitialized(); return GetImpl()->SetIlluminationState(on); }
double GalvoInstance::GetXRange() { RequireInitialized(); return GetImpl()->GetXRange(); }
double GalvoInstance::GetXMinimum() { RequireInitialized(); return GetImpl()->GetXMinimum(); }
double GalvoInstance::GetYRange() { RequireInitialized(); return GetImpl()->GetYRange(); }
double GalvoInstance::GetYMinimum() { RequireInitialized(); return GetImpl()->GetYMinimum(); }
int GalvoInstance::AddPolygonVertex(int polygonIndex, double x, double y) { RequireInitialized(); return GetImpl()->AddPolygonVertex(polygonIndex, x, y); }
int GalvoInstance::DeletePolygons() { RequireInitialized(); return GetImpl()->DeletePolygons(); }
int GalvoInstance::RunSequence() { RequireInitialized(); return GetImpl()->RunSequence(); }
int GalvoInstance::LoadPolygons() { RequireInitialized(); return GetImpl()->LoadPolygons(); }
int GalvoInstance::SetPolygonRepetitions(int repetitions) { RequireInitialized(); return GetImpl()->SetPolygonRepetitions(repetitions); }
int GalvoInstance::RunPolygons() { RequireInitialized(); return GetImpl()->RunPolygons(); }
int GalvoInstance::StopSequence() { RequireInitialized(); return GetImpl()->StopSequence(); }
int GalvoInstance::PointAndFire(double x, double y, double time_us) { RequireInitialized(__func__); return GetImpl()->PointAndFire(x, y, time_us); }
int GalvoInstance::SetSpotInterval(double pulseInterval_us) { RequireInitialized(__func__); return GetImpl()->SetSpotInterval(pulseInterval_us); }
int GalvoInstance::SetPosition(double x, double y) { RequireInitialized(__func__); return GetImpl()->SetPosition(x, y); }
int GalvoInstance::GetPosition(double& x, double& y) { RequireInitialized(__func__); return GetImpl()->GetPosition(x, y); }
int GalvoInstance::SetIlluminationState(bool on) { RequireInitialized(__func__); return GetImpl()->SetIlluminationState(on); }
double GalvoInstance::GetXRange() { RequireInitialized(__func__); return GetImpl()->GetXRange(); }
double GalvoInstance::GetXMinimum() { RequireInitialized(__func__); return GetImpl()->GetXMinimum(); }
double GalvoInstance::GetYRange() { RequireInitialized(__func__); return GetImpl()->GetYRange(); }
double GalvoInstance::GetYMinimum() { RequireInitialized(__func__); return GetImpl()->GetYMinimum(); }
int GalvoInstance::AddPolygonVertex(int polygonIndex, double x, double y) { RequireInitialized(__func__); return GetImpl()->AddPolygonVertex(polygonIndex, x, y); }
int GalvoInstance::DeletePolygons() { RequireInitialized(__func__); return GetImpl()->DeletePolygons(); }
int GalvoInstance::RunSequence() { RequireInitialized(__func__); return GetImpl()->RunSequence(); }
int GalvoInstance::LoadPolygons() { RequireInitialized(__func__); return GetImpl()->LoadPolygons(); }
int GalvoInstance::SetPolygonRepetitions(int repetitions) { RequireInitialized(__func__); return GetImpl()->SetPolygonRepetitions(repetitions); }
int GalvoInstance::RunPolygons() { RequireInitialized(__func__); return GetImpl()->RunPolygons(); }
int GalvoInstance::StopSequence() { RequireInitialized(__func__); return GetImpl()->StopSequence(); }

std::string GalvoInstance::GetChannel()
{
RequireInitialized();
RequireInitialized(__func__);
DeviceStringBuffer nameBuf(this, "GetChannel");
int err = GetImpl()->GetChannel(nameBuf.GetBuffer());
ThrowIfError(err, "Cannot get current channel name");
Expand Down
4 changes: 2 additions & 2 deletions MMCore/Devices/HubInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
std::vector<std::string>
HubInstance::GetInstalledPeripheralNames()
{
RequireInitialized();
RequireInitialized(__func__);

std::vector<MM::Device*> peripherals = GetInstalledPeripherals();

Expand Down Expand Up @@ -61,7 +61,7 @@ HubInstance::GetInstalledPeripheralNames()
std::string
HubInstance::GetInstalledPeripheralDescription(const std::string& peripheralName)
{
RequireInitialized();
RequireInitialized(__func__);

std::vector<MM::Device*> peripherals = GetInstalledPeripherals();
for (std::vector<MM::Device*>::iterator it = peripherals.begin(), end = peripherals.end();
Expand Down
2 changes: 1 addition & 1 deletion MMCore/Devices/ImageProcessorInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
#include "ImageProcessorInstance.h"


int ImageProcessorInstance::Process(unsigned char* buffer, unsigned width, unsigned height, unsigned byteDepth) { RequireInitialized(); return GetImpl()->Process(buffer, width, height, byteDepth); }
int ImageProcessorInstance::Process(unsigned char* buffer, unsigned width, unsigned height, unsigned byteDepth) { RequireInitialized(__func__); return GetImpl()->Process(buffer, width, height, byteDepth); }
2 changes: 1 addition & 1 deletion MMCore/Devices/MagnifierInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
#include "MagnifierInstance.h"


double MagnifierInstance::GetMagnification() { RequireInitialized(); return GetImpl()->GetMagnification(); }
double MagnifierInstance::GetMagnification() { RequireInitialized(__func__); return GetImpl()->GetMagnification(); }
Loading

0 comments on commit 945f97a

Please sign in to comment.