DynExp
Highly flexible laboratory automation for dynamically changing experiments.
OutputPortWriter.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
4 #include "moc_OutputPortWriter.cpp"
5 #include "OutputPortWriter.h"
6 
7 namespace DynExpModule
8 {
9  OutputPortWriterWidget::OutputPortWriterWidget(OutputPortWriter& Owner, QModuleWidget* parent) : QModuleWidget(Owner, parent)
10  {
11  ui.setupUi(this);
12 
13  ui.AnalogOutWidget->setVisible(false);
14  ui.DigitalOutWidget->setVisible(false);
15  }
16 
18  {
19  Init();
20  }
21 
23  {
24  UIInitialized = false;
25  IsDigitalPort = false;
26  ValueChanged = false;
27  MinAllowedValue = 0;
28  MaxAllowedValue = 1;
29  Value = 0;
30  }
31 
33  {
34  auto ModuleData = DynExp::dynamic_ModuleData_cast<OutputPortWriter>(Instance.ModuleDataGetter());
35 
36  if (ModuleData->ValueChanged)
37  {
38  {
39  auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::OutputPort>(ModuleData->OutputPort->GetInstrumentData());
40 
41  InstrData->GetSampleStream()->SeekEnd(std::ios_base::out);
42  InstrData->GetSampleStream()->WriteBasicSample({ ModuleData->Value });
43  } // InstrData unlocked here.
44  ModuleData->OutputPort->WriteData();
45 
46  ModuleData->ValueChanged = false;
47  }
48 
50  }
51 
53  {
54  }
55 
56  std::unique_ptr<DynExp::QModuleWidget> OutputPortWriter::MakeUIWidget()
57  {
58  auto Widget = std::make_unique<OutputPortWriterWidget>(*this);
59 
60  Connect(Widget->ui.ValueDial, &QAbstractSlider::valueChanged, this, &OutputPortWriter::OnValueChanged);
61  Connect(Widget->ui.StateButton, &QPushButton::clicked, this, &OutputPortWriter::OnStateButtonClicked);
62 
63  return Widget;
64  }
65 
66  void OutputPortWriter::UpdateUIChild(const ModuleBase::ModuleDataGetterType& ModuleDataGetter)
67  {
68  auto Widget = GetWidget<OutputPortWriterWidget>();
69  auto ModuleData = DynExp::dynamic_ModuleData_cast<OutputPortWriter>(ModuleDataGetter());
70 
71  QString ValueUnitStr(" ");
72  ValueUnitStr += DynExpInstr::DataStreamInstrumentData::UnitTypeToStr(ModuleData->OutputPort->GetValueUnit());
73 
74  if (!ModuleData->UIInitialized)
75  {
76  Widget->ui.AnalogOutWidget->setVisible(!ModuleData->IsDigitalPort);
77  Widget->ui.DigitalOutWidget->setVisible(ModuleData->IsDigitalPort);
78  Widget->adjustSize();
79 
80  Widget->ui.ValueDial->setMinimum(ModuleData->MinAllowedValue * DialControlValueDivider);
81  Widget->ui.ValueDial->setMaximum(ModuleData->MaxAllowedValue * DialControlValueDivider);
82  Widget->ui.ValueDial->setSingleStep(ModuleData->MaxAllowedValue - ModuleData->MinAllowedValue);
83  Widget->ui.ValueDial->setPageStep((ModuleData->MaxAllowedValue - ModuleData->MinAllowedValue) * DialControlValueDivider / 10);
84  Widget->ui.MinValueLabel->setText(QString::number(ModuleData->MinAllowedValue) + ValueUnitStr);
85  Widget->ui.MaxValueLabel->setText(QString::number(ModuleData->MaxAllowedValue) + ValueUnitStr);
86 
87  ModuleData->UIInitialized = true;
88  }
89 
90  if (!ModuleData->IsDigitalPort)
91  {
92  if (!Widget->ui.ValueDial->hasFocus())
93  Widget->ui.ValueDial->setValue(ModuleData->Value * DialControlValueDivider);
94 
95  Widget->ui.ValueLabel->setText(QString::number(ModuleData->Value) + ValueUnitStr);
96 
97  }
98  else
99  {
100  Widget->ui.StateButton->setText(ModuleData->Value ? "High" : "Low");
101  Widget->ui.StateButton->setStyleSheet(ModuleData->Value ? "background-color: lime;" : "background-color: red;");
102  }
103  }
104 
106  {
107  auto ModuleParams = DynExp::dynamic_Params_cast<OutputPortWriter>(Instance->ParamsGetter());
108  auto ModuleData = DynExp::dynamic_ModuleData_cast<OutputPortWriter>(Instance->ModuleDataGetter());
109 
110  Instance->LockObject(ModuleParams->OutputPort, ModuleData->OutputPort);
111 
112  ModuleData->IsDigitalPort = ModuleData->OutputPort->GetValueUnit() == DynExpInstr::DataStreamInstrumentData::UnitType::LogicLevel;
113  ModuleData->MinAllowedValue = ModuleData->OutputPort->GetUserMinValue();
114  ModuleData->MaxAllowedValue = ModuleData->OutputPort->GetUserMaxValue();
115  }
116 
118  {
119  auto ModuleData = DynExp::dynamic_ModuleData_cast<OutputPortWriter>(Instance->ModuleDataGetter());
120 
121  Instance->UnlockObject(ModuleData->OutputPort);
122  }
123 
125  {
126  auto ModuleData = DynExp::dynamic_ModuleData_cast<OutputPortWriter>(Instance->ModuleDataGetter());
127  ModuleData->Value = static_cast<double>(Value) / DialControlValueDivider;
128  ModuleData->ValueChanged = true;
129  }
130 
132  {
133  auto ModuleData = DynExp::dynamic_ModuleData_cast<OutputPortWriter>(Instance->ModuleDataGetter());
134  ModuleData->Value = Checked;
135  ModuleData->ValueChanged = true;
136  }
137 }
Implementation of a module to write single values to output port instruments.
@ LogicLevel
Logic level (TTL) units (1 or 0)
static const char * UnitTypeToStr(const UnitType &Unit)
Returns a descriptive string of a respective unit to be e.g. used in plots.
void ResetImpl(dispatch_tag< QModuleDataBase >) override final
OutputPortWriterWidget(OutputPortWriter &Owner, QModuleWidget *parent=nullptr)
Util::DynExpErrorCodes::DynExpErrorCodes ModuleMainLoop(DynExp::ModuleInstance &Instance) override final
Module main loop. The function is executed periodically by the module thread. Also refer to GetMainLo...
void OnStateButtonClicked(DynExp::ModuleInstance *Instance, bool Checked) const
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
static constexpr auto DialControlValueDivider
void OnValueChanged(DynExp::ModuleInstance *Instance, int Value) const
std::unique_ptr< DynExp::QModuleWidget > MakeUIWidget() override final
Used by InitUI() as a factory function for the module's user interface widget. Create the widget here...
void UpdateUIChild(const ModuleBase::ModuleDataGetterType &ModuleDataGetter) override final
void ResetImpl(dispatch_tag< QModuleBase >) override final
void OnInit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread starts. Override it to lock instruments this m...
const std::unique_ptr< ModuleDataType > ModuleData
Module data belonging to this ModuleBase instance.
Definition: Module.h:743
Refer to ParamsBase::dispatch_tag.
Definition: Module.h:189
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
Definition: Module.h:793
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
Definition: Module.h:825
Refer to ParamsBase::dispatch_tag.
Definition: Object.h:2018
QModuleWidget * Widget
User interface widget belonging to the module.
Definition: Module.h:1491
void Connect(SenderType *Sender, SignalType Signal, ReceiverType *Receiver, EventType Event)
Uses Qt's connect mechanism to connect a QObject's signal to a DynExp module's event....
Definition: Module.h:1500
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition: Object.h:3671
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition: Object.h:3570
void LockObject(const ParamsBase::Param< ObjectLink< ObjectT >> &LinkParam, LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer, std::chrono::milliseconds Timeout=ObjectLinkBase::LockObjectTimeoutDefault)
Locks an Object instance referenced by a parameter LinkParam of type ParamsBase::Param< ObjectLink< O...
Definition: Object.h:3554
DynExp's module namespace contains the implementation of DynExp modules which extend DynExp's core fu...
DynExpErrorCodes
DynExp's error codes
Definition: Exception.h:22
Accumulates include statements to provide a precompiled header.