DynExp
Highly flexible laboratory automation for dynamically changing experiments.
HardwareAdapterPVCam.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
4 #include "HardwareAdapterPVCam.h"
5 
6 namespace DynExpHardware
7 {
9  {
11  auto PVCamLock = PVCamInitializer::Lock();
12 
13  PVCamSyms::int16 NumberOfCameras = 0;
14  if (PVCamSyms::pl_cam_get_total(&NumberOfCameras) != PVCamSyms::PV_OK)
15  throw PVCamException("Error enumerating PVCAM cameras.", PVCamSyms::pl_error_code());
16 
17  std::vector<std::string> DeviceDescriptors;
18  for (decltype(NumberOfCameras) i = 0; i < NumberOfCameras; ++i)
19  {
20  std::string CameraName;
21  CameraName.resize(CAM_NAME_LEN);
22 
23  if (PVCamSyms::pl_cam_get_name(i, CameraName.data()) != PVCamSyms::PV_OK)
24  throw PVCamException("Error obtaining a PVCAM camera's name.", PVCamSyms::pl_error_code());
26 
27  DeviceDescriptors.emplace_back(std::move(CameraName));
28  }
29 
30  return DeviceDescriptors;
31  }
32 
34  {
35  auto PVCamDevices = PVCamHardwareAdapter::Enumerate();
36  if (!CameraName.Get().empty() &&
37  std::find(PVCamDevices.cbegin(), PVCamDevices.cend(), CameraName) == std::cend(PVCamDevices))
38  PVCamDevices.push_back(CameraName);
39  if (PVCamDevices.empty())
40  throw Util::EmptyException("There is not any available PVCam camera.");
41  CameraName.SetTextList(std::move(PVCamDevices));
42 
44  }
45 
47  {
48  // Swallow errors from pl_pvcam_uninit() since there is no way how to handle them and throwing from destructor is even worse.
49  if (IsInitialized)
50  PVCamSyms::pl_pvcam_uninit();
51  }
52 
54  {
55  return GetInstance().AcquireLock(Timeout);
56  }
57 
59  {
60  static PVCamInitializer Instance;
61 
62  if (MayInit)
63  {
64  auto lock = Instance.AcquireLock(std::chrono::milliseconds(100));
65 
66  // Instance.IsInitialized might have been changed in between.
67  if (!Instance.IsInitialized)
68  {
69  if (PVCamSyms::pl_pvcam_init() != PVCamSyms::PV_OK)
70  throw PVCamException("Error initializing PVCAM library.", PVCamSyms::pl_error_code());
71 
72  Instance.IsInitialized = true;
73  }
74  }
75 
76  return Instance;
77  }
78 
81  {
82  Init();
83  }
84 
86  {
87  // Not locking, since the object is being destroyed. This should be inherently thread-safe.
88  CloseUnsafe();
89  }
90 
91  decltype(PVCamSyms::rgn_type::s2) PVCamHardwareAdapter::GetImageWidth() const
92  {
94 
95  return Region.s2;
96  }
97 
98  decltype(PVCamSyms::rgn_type::p2) PVCamHardwareAdapter::GetImageHeight() const
99  {
101 
102  return Region.p2;
103  }
104 
106  {
108 
109  for (const auto& SpeedMode : CameraSpeedTable)
110  for (auto GainMode : SpeedMode.Gains)
111  Modes.emplace_back(SpeedMode.Port.second + ": " + Util::ToStr(SpeedMode.ReadoutFrequency, 0) + " MHz, "
112  + Util::ToStr(GainMode.BitDepth) + " bit, gain " + Util::ToStr(GainMode.GainIndex));
113 
114  return Modes;
115  }
116 
118  {
120 
121  return MinExpTime;
122  }
123 
125  {
127 
128  return MaxExpTime;
129  }
130 
132  {
134 
135  return ExposureTime;
136  }
137 
139  {
141 
142  return CurrentFPS;
143  }
144 
146  {
148 
149  // Move-constructs new object by stealing from internal data.
150  return std::move(CopiedImageData);
151  }
152 
154  {
156 
157  // Invokes copy-constructor.
158  return CopiedImageData;
159  }
160 
162  {
164 
166  {
170  }
171  else
173  }
174 
176  {
178 
179  if (Time < MinExpTime || Time > MaxExpTime)
180  return;
181 
182  ExposureTime = Time;
183 
185  {
186  // If running continuously, apply new exposure time
189  }
190  }
191 
193  {
194  using namespace PVCamSyms;
195 
197 
200 
201  auto PVCamLock = PVCamInitializer::Lock();
202 
203  uns32 BytesRequired = 0;
204  auto CaptureRegion = Region;
205  --CaptureRegion.s2;
206  --CaptureRegion.p2;
207  auto Result = pl_exp_setup_seq(PVCamHandle, 1, 1, &CaptureRegion, TIMED_MODE, static_cast<uns32>(ExposureTime.count()), &BytesRequired);
208  CheckError(Result);
209 
210  ReserveMemory(BytesRequired);
211 
214 
215  Result = pl_exp_start_seq(PVCamHandle, ImageData.GetPtr());
216  CheckError(Result);
217  }
218 
220  {
222 
224  return;
225 
227  }
228 
230  {
232 
234  return;
235 
237  }
238 
239  void PV_DECL PVCamHardwareAdapter::NewFrameCallback(PVCamSyms::FRAME_INFO* FrameInfo, void* PVCamHardwareAdapterPtr)
240  {
241  if (PVCamHardwareAdapterPtr)
242  static_cast<PVCamHardwareAdapter*>(PVCamHardwareAdapterPtr)->NewFrame(FrameInfo);
243  }
244 
246  {
247  auto DerivedParams = dynamic_Params_cast<PVCamHardwareAdapter>(GetParams());
248 
249  CameraName = DerivedParams->CameraName.Get();
250  CameraSpeedTable.clear();
251  MinExpTime = TimeType();
252  MaxExpTime = TimeType();
253  ExposureTime = std::chrono::milliseconds(100);
254  CurrentFPS = 0.f;
255  Region = { 0, 0, 1, 0, 0, 1 };
256  BitDepth = 0;
257  ColorMode = PVCamSyms::PL_COLOR_MODES::COLOR_NONE;
258 
259  PVCamHandleValid = false;
260  PVCamHandle = -1;
261  }
262 
264  {
265  // auto lock = AcquireLock(); not necessary here, since DynExp ensures that Object::Reset() can only
266  // be called if respective object is not in use.
267 
268  CloseUnsafe();
269 
270  ImageData.Reset();
272 
273  Init();
274 
276  }
277 
279  {
281 
283 
284  OpenUnsafe();
285  }
286 
288  {
290 
291  auto Exception = GetExceptionUnsafe();
292  Util::ForwardException(Exception);
293 
294  return IsOpened();
295  }
296 
298  {
299  return IsOpened();
300  }
301 
302  void PVCamHardwareAdapter::CheckError(const PVCamSyms::rs_bool Result, bool OnlyLog, const std::source_location Location) const
303  {
304  if (Result == PVCamSyms::PV_OK)
305  return;
306 
307  auto ErrorCode = PVCamSyms::pl_error_code();
308 
309  // Since C++17, writing to std::string's internal buffer is allowed.
310  std::string ErrorString;
311  ErrorString.resize(ERROR_MSG_LEN);
312  PVCamSyms::pl_error_message(ErrorCode, ErrorString.data());
313  ErrorString = Util::TrimTrailingZeros(ErrorString);
314  PVCamException Exception(ErrorString, ErrorCode, OnlyLog ? Util::ErrorType::Warning : Util::ErrorType::Error, Location);
315 
316  if (!OnlyLog)
317  {
318  // AcquireLock() has already been called by an (in)direct caller of this function.
319  ThrowExceptionUnsafe(std::make_exception_ptr(Exception));
320  }
321  else
322  {
323  Util::EventLog().Log(Exception);
324 
325  // Does not store exception in hardware adapter. Might be useful if the error just occurs temporarily for one frame.
326  throw Exception;
327  }
328  }
329 
331  {
332  using namespace PVCamSyms;
333 
334  if (IsOpened())
335  return;
336 
337  auto PVCamLock = PVCamInitializer::Lock();
338 
339  // Copy since pl_cam_open() unfortunately expects pointer to char* rather than const char*...
340  auto TmpName = CameraName;
341  auto Result = pl_cam_open(TmpName.data(), &PVCamHandle, OPEN_EXCLUSIVE);
342  CheckError(Result);
343 
344  PVCamHandleValid = true;
345 
348 
349  // Additional configuration and parameter readout
350  Result = pl_get_param(PVCamHandle, PARAM_SER_SIZE, ATTR_CURRENT, &Region.s2);
351  CheckError(Result);
352  Result = pl_get_param(PVCamHandle, PARAM_PAR_SIZE, ATTR_CURRENT, &Region.p2);
353  CheckError(Result);
354 
355  int32 ColorModeAvlbl = 0;
356  Result = pl_get_param(PVCamHandle, PARAM_COLOR_MODE, ATTR_AVAIL, &ColorModeAvlbl);
357  CheckError(Result);
358  if (ColorModeAvlbl)
359  {
360  Result = pl_get_param(PVCamHandle, PARAM_COLOR_MODE, ATTR_CURRENT, &ColorMode);
361  CheckError(Result);
362  }
363 
364  uns16 ExposueTimeMode = EXP_RES_ONE_MILLISEC;
365  Result = pl_set_param(PVCamHandle, PARAM_EXP_RES_INDEX, &ExposueTimeMode);
366  CheckError(Result);
367 
368  Result = pl_cam_register_callback_ex3(PVCamHandle, PL_CALLBACK_EOF, &NewFrameCallback, this);
369  CheckError(Result);
370  }
371 
373  {
374  if (IsOpened())
375  {
377 
378  // Does not matter whether lock is interrupted in bewtween here and call to StopCapturing().
379  auto PVCamLock = PVCamInitializer::Lock();
380 
381  // Handle now considered invalid, even if pl_cam_close() fails.
382  PVCamHandleValid = false;
383 
384  auto Result = PVCamSyms::pl_cam_deregister_callback(PVCamHandle, PVCamSyms::PL_CALLBACK_EOF);
385  CheckError(Result);
386  Result = PVCamSyms::pl_cam_close(PVCamHandle);
387  CheckError(Result);
388  }
389  }
390 
391  void PVCamHardwareAdapter::ReserveMemory(const PVCamSyms::uns32 BytesRequired) const
392  {
393  if (!BytesRequired)
394  ThrowExceptionUnsafe(std::make_exception_ptr(Util::InvalidDataException("Error retrieving required memory size from PVCAM camera.")));
395 
396  ImageData.Reserve(BytesRequired);
397  }
398 
400  {
401  using namespace PVCamSyms;
402 
403  uns32 Count;
404  auto Result = pl_get_param(PVCamHandle, ParamID, ATTR_COUNT, &Count);
405  CheckError(Result);
406 
407  PVCamEnumVectorType PVCamEnumVector;
408 
409  // Query trigger/exposure configuration names.
410  for (decltype(Count) i = 0; i < Count; ++i)
411  {
412  // Determine required string length.
413  uns32 StrLength;
414  Result = pl_enum_str_length(PVCamHandle, ParamID, i, &StrLength);
415  CheckError(Result);
416 
417  std::string Name;
418  Name.resize(StrLength);
419 
420  // Query key-value pair.
421  int32 Value;
422  Result = pl_get_enum_param(PVCamHandle, ParamID, i, &Value, Name.data(), StrLength);
423  CheckError(Result);
424 
425  PVCamEnumVector.emplace_back(Value, std::move(Name));
426  }
427 
428  return PVCamEnumVector;
429  }
430 
432  {
433  using namespace PVCamSyms;
434 
435  auto Ports = ReadPVCamEnumUnsafe(PARAM_READOUT_PORT, "PARAM_READOUT_PORT");
436 
437  CameraSpeedTable.clear();
438 
439  // Determine camera speed for each available port.
440  for (auto& Port : Ports)
441  {
442  // Select readout port
443  auto Result = pl_set_param(PVCamHandle, PARAM_READOUT_PORT, &Port.first);
444  CheckError(Result);
445 
446  // Query amount of available camera speed modes for the selected port.
447  uns32 SpeedCount;
448  Result = pl_get_param(PVCamHandle, PARAM_SPDTAB_INDEX, ATTR_COUNT, &SpeedCount);
449  CheckError(Result);
450 
451  // Determine properties of each available camera speed mode.
452  for (int16 i = 0; i < Util::NumToT<int16>(SpeedCount); ++i)
453  {
454  // First, select speed mode by index.
455  // Copy since pl_set_param() unfortunately expects non-const pointer...
456  auto Tmpi = i;
457  Result = pl_set_param(PVCamHandle, PARAM_SPDTAB_INDEX, &Tmpi);
458  CheckError(Result);
459 
460  // Second, query the time (in ns) required to read out a single pixel.
461  uns16 PixelTime;
462  Result = pl_get_param(PVCamHandle, PARAM_PIX_TIME, ATTR_CURRENT, &PixelTime);
463  CheckError(Result);
464 
465  // Third, obtain gain information on the selected camera speed mode.
466  int16 GainMin, GainMax, GainIncrement;
467  Result = pl_get_param(PVCamHandle, PARAM_GAIN_INDEX, ATTR_MIN, &GainMin);
468  CheckError(Result);
469  Result = pl_get_param(PVCamHandle, PARAM_GAIN_INDEX, ATTR_MAX, &GainMax);
470  CheckError(Result);
471  Result = pl_get_param(PVCamHandle, PARAM_GAIN_INDEX, ATTR_INCREMENT, &GainIncrement);
472  CheckError(Result);
473 
474  // Last, query bit depth for each gain mode.
475  PVCamReadoutOptionType PVCamReadoutOption(Port, i, 1000.f / PixelTime);
476  for (auto Gain = GainMin; Gain <= GainMax; Gain += GainIncrement)
477  {
478  // Copy since pl_set_param() unfortunately expects non-const pointer...
479  auto TmpGain = Gain;
480  Result = pl_set_param(PVCamHandle, PARAM_GAIN_INDEX, &TmpGain);
481  CheckError(Result);
482 
483  int16 BitDepth;
484  Result = pl_get_param(PVCamHandle, PARAM_BIT_DEPTH, ATTR_CURRENT, &BitDepth);
485  CheckError(Result);
486 
487  PVCamReadoutOption.Gains.push_back({ Gain, BitDepth });
488  }
489 
490  if (PVCamReadoutOption.Gains.empty())
491  ThrowExceptionUnsafe(std::make_exception_ptr(Util::EmptyException(
492  "The gain list of a speed table's entry of the selected PVCam camera is empty.")));
493 
494  CameraSpeedTable.push_back(std::move(PVCamReadoutOption));
495  }
496  }
497 
498  // By default, select the first available port, the first camera speed mode, and the first gain mode.
500  }
501 
503  {
504  using namespace PVCamSyms;
505 
506  if (CameraSpeedTable.empty())
507  ThrowExceptionUnsafe(std::make_exception_ptr(Util::EmptyException("The speed table of the selected PVCam camera is empty.")));
508 
509  decltype(ID) CurrentIndex = 0;
510  for (const auto& SpeedMode : CameraSpeedTable)
511  {
512  for (auto GainMode : SpeedMode.Gains)
513  {
514  if (ID == CurrentIndex)
515  {
516  // Set port. Copy value since pl_set_param() unfortunately expects non-const pointer...
517  auto PortID = SpeedMode.Port.first;
518  auto Result = pl_set_param(PVCamHandle, PARAM_READOUT_PORT, &PortID);
519  CheckError(Result);
520  BitDepth = GainMode.BitDepth;
521 
522  // Set speed index.
523  auto SpeedIndex = SpeedMode.SpeedIndex;
524  Result = pl_set_param(PVCamHandle, PARAM_SPDTAB_INDEX, &SpeedIndex);
525  CheckError(Result);
526 
527  // Set gain mode.
528  auto GainIndex = GainMode.GainIndex;
529  Result = pl_set_param(PVCamHandle, PARAM_GAIN_INDEX, &GainIndex);
530  CheckError(Result);
531 
533 
534  return;
535  }
536 
537  ++CurrentIndex;
538  }
539  }
540 
541  ThrowExceptionUnsafe(std::make_exception_ptr(Util::InvalidArgException("The given ID does not correspond to an entry in the camera's speed table.")));
542  }
543 
545  {
546  auto PVCamLock = PVCamInitializer::Lock();
547 
548  PVCamSyms::uns32 BytesRequired = 0;
549  auto CaptureRegion = Region;
550  --CaptureRegion.s2;
551  --CaptureRegion.p2;
552  auto Result = pl_exp_setup_cont(PVCamHandle, 1, &CaptureRegion, PVCamSyms::TIMED_MODE,
553  static_cast<PVCamSyms::uns32>(ExposureTime.count()), &BytesRequired, PVCamSyms::CIRC_OVERWRITE);
554  CheckError(Result);
555 
556  ReserveMemory(BytesRequired * NumFramesInBuffer);
557 
560 
561  Result = PVCamSyms::pl_exp_start_cont(PVCamHandle, ImageData.GetPtr(),
562  Util::NumToT<PVCamSyms::uns32>(ImageData.Size() / BytesPerPixel()));
563  CheckError(Result);
564  }
565 
567  {
568  auto PVCamLock = PVCamInitializer::Lock();
569 
571  {
572  auto Result = PVCamSyms::pl_exp_stop_cont(PVCamHandle, PVCamSyms::CCS_CLEAR);
573  CheckError(Result);
574  }
575 
576  auto Result = PVCamSyms::pl_exp_abort(PVCamHandle, PVCamSyms::CCS_CLEAR);
577  CheckError(Result);
578 
580  }
581 
583  {
584  using namespace PVCamSyms;
585 
586  ulong64 IntMinExpTime, IntMaxExpTime;
587  auto Result = pl_get_param(PVCamHandle, PARAM_EXPOSURE_TIME, ATTR_MIN, &IntMinExpTime);
588  CheckError(Result);
589  Result = pl_get_param(PVCamHandle, PARAM_EXPOSURE_TIME, ATTR_MAX, &IntMaxExpTime);
590  CheckError(Result);
591 
592  MinExpTime = std::chrono::milliseconds(IntMinExpTime);
593  MaxExpTime = std::chrono::milliseconds(IntMaxExpTime);
594  }
595 
597  {
598  PVCamSyms::ulong64 CurrentExpTime;
599  auto Result = PVCamSyms::pl_get_param(PVCamHandle, PARAM_EXPOSURE_TIME, PVCamSyms::ATTR_CURRENT, &CurrentExpTime);
600  CheckError(Result);
601 
602  ExposureTime = std::chrono::milliseconds(CurrentExpTime);
603  }
604 
605  void PVCamHardwareAdapter::NewFrame(PVCamSyms::FRAME_INFO* FrameInfo) noexcept
606  {
607  try
608  {
610 
611  CurrentFPS = 0.f;
612 
614  return;
615 
617  {
618  // Deep copy since PVCam library might overwrite ImageData outside its callbacks at any time.
620 
622 
623  {
624  auto PVCamLock = PVCamInitializer::Lock();
625 
626  auto Result = PVCamSyms::pl_exp_finish_seq(PVCamHandle, ImageData.GetPtr(), 0);
627  CheckError(Result, true);
628  }
629  }
631  {
632  unsigned char* FrameAdr = nullptr;
633  {
634  auto PVCamLock = PVCamInitializer::Lock();
635 
636  auto Result = PVCamSyms::pl_exp_get_latest_frame(PVCamHandle, reinterpret_cast<void**>(&FrameAdr));
637  CheckError(Result, true);
638  }
639 
641 
642  static std::chrono::time_point<std::chrono::system_clock> LastCall;
643 
644  auto now = std::chrono::system_clock::now();
645  if (LastCall.time_since_epoch().count())
646  CurrentFPS = 1000.f / std::chrono::duration_cast<std::chrono::milliseconds>(now - LastCall).count();
647 
648  LastCall = now;
649  }
650  }
651  catch (...)
652  {
653  // Swallow any exception since this function is called by a PVCAM thread which does not handle exceptions.
654  }
655  }
656 }
Implementation of a hardware adapter to control Teledyne Photometrics PVCam hardware....
void ConfigureParamsImpl(dispatch_tag< HardwareAdapterParamsBase >) override final
Only one instance of this class is allowed for synchronizing calls to the PVCam library from any PVCa...
static LockType Lock(const std::chrono::milliseconds Timeout=std::chrono::milliseconds(100))
static PVCamInitializer & GetInstance(bool MayInit=false)
constexpr static auto BytesPerPixel() noexcept
static constexpr unsigned int NumFramesInBuffer
void ReserveMemory(const PVCamSyms::uns32 BytesRequired) const
PVCamHardwareAdapter(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
bool IsConnectedChild() const noexcept override final
Determines the connection status of the hardware interface.
decltype(PVCamSyms::rgn_type::p2) GetImageHeight() const
Util::BlobDataType GetCurrentImage() const
std::vector< PVCamReadoutOptionType > CameraSpeedTable
PVCamEnumVectorType ReadPVCamEnumUnsafe(PVCamSyms::uns32 ParamID, std::string ParamName)
decltype(PVCamSyms::rgn_type::s2) GetImageWidth() const
void ResetImpl(dispatch_tag< HardwareAdapterBase >) override final
static void PV_DECL NewFrameCallback(PVCamSyms::FRAME_INFO *FrameInfo, void *PVCamHardwareAdapterPtr)
Util::BlobDataType GetCurrentImageCopy() const
std::vector< PVCamEnumType > PVCamEnumVectorType
void NewFrame(PVCamSyms::FRAME_INFO *FrameInfo) noexcept
bool IsReadyChild() const override final
Returns wheter this Object instance is ready (e.g. it is running or connected to a hardware device) a...
std::atomic< PVCamSyms::PL_COLOR_MODES > ColorMode
void EnsureReadyStateChild() override final
Ensures that this Object instance is ready by possibly starting its worker thread or by opening conne...
void CheckError(const PVCamSyms::rs_bool Result, bool OnlyLog=false, const std::source_location Location=std::source_location::current()) const
constexpr static auto Name() noexcept
std::atomic< CameraStateType > CameraState
DynExpInstr::CameraData::CameraModesType GetCameraModes() const
std::atomic< PVCamSyms::int16 > BitDepth
CapturingStateType
Type indicating whether the camera is currently capturing images.
Definition: Camera.h:106
@ CapturingSingle
The camera is caturing a single image and will stop afterwards.
@ CapturingContinuously
The camera is capturing one image after the other.
@ Stopped
The camera is not capturing.
std::vector< std::string > CameraModesType
List type containing strings of modes the camera can operate in.
Definition: Camera.h:100
HardwareAdapterBase(const std::thread::id OwnerThreadID, ParamsBasePtrType &&Params)
Constructs a hardware adapter instance.
static constexpr auto HardwareOperationTimeout
Default timeout used to lock the mutex provided by the base class Util::ILockable to synchronize acce...
void ThrowExceptionUnsafe(std::exception_ptr Exception) const
Stores Exception in LastException, wraps it in a Util::ForwardedException and throws the wrapped exce...
auto GetExceptionUnsafe() const
Getter for LastException.
ParamsConstTypeSyncPtrType GetParams(const std::chrono::milliseconds Timeout=GetParamsTimeoutDefault) const
Locks the mutex of the parameter class instance Params assigned to this Object instance and returns a...
Definition: Object.cpp:436
const std::thread::id OwnerThreadID
Thread id of the thread which has constructed (and owns) this Object instance.
Definition: Object.h:2302
const ParamsBasePtrType Params
Pointer to the parameter class instance belonging to this Object instance.
Definition: Object.h:2303
Refer to ParamsBase::dispatch_tag.
Definition: Object.h:2018
Tag for function dispatching mechanism within this class used when derived classes are not intended t...
Definition: Object.h:349
Data type which manages a binary large object. The reserved memory is freed upon destruction.
Definition: Util.h:517
void Reserve(size_t Size)
Reserves Size bytes of memory freeing any previously reserved memory.
Definition: Util.cpp:118
auto Size() const noexcept
Returns the size of the stored data in bytes.
Definition: Util.h:537
void Reset()
Frees any reserved memory.
Definition: Util.cpp:137
auto GetPtr() noexcept
Returns a pointer to the stored buffer.
Definition: Util.h:536
void Assign(size_t Size, const DataType Data)
Copies Size bytes from Data to the buffer freeing any previously reserved memory.
Definition: Util.cpp:131
Thrown when a list is expected to contain entries and when a query results in an empty answer or an e...
Definition: Exception.h:224
void Log(const std::string &Message, const ErrorType Type=ErrorType::Info, const size_t Line=0, const std::string &Function="", const std::string &File="", const int ErrorCode=0, const std::stacktrace &Trace={}) noexcept
Logs an event from information specified manually.
Definition: Util.cpp:309
LockType AcquireLock(const std::chrono::milliseconds Timeout=DefaultTimeout) const
Locks the internal mutex. Blocks until the mutex is locked or until the timeout duration is exceeded.
Definition: Util.cpp:8
std::unique_lock< MutexType > LockType
Definition: Util.h:66
An invalid argument like a null pointer has been passed to a function.
Definition: Exception.h:137
Data to operate on is invalid for a specific purpose. This indicates a corrupted data structure or fu...
Definition: Exception.h:163
DynExp's hardware namespace contains the implementation of DynExp hardware adapters which extend DynE...
constexpr auto Stopped
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition: Object.h:1807
std::string ToStr(const T &Value, int Precision=-1)
Converts a (numeric) value of type T to a std::string using operator<< of std::stringstream.
Definition: Util.h:625
void ForwardException(std::exception_ptr e)
Wraps the exception passed to the function in a ForwardedException and throws the ForwardedException....
Definition: Exception.cpp:30
EventLogger & EventLog()
This function holds a static EventLogger instance and returns a reference to it. DynExp uses only one...
Definition: Util.cpp:509
std::string TrimTrailingZeros(const std::string &Str)
Removes trailing zeros ('\0') from a string.
Definition: Util.h:833
Accumulates include statements to provide a precompiled header.