ChimeraTK-ApplicationCore 04.06.00
Loading...
Searching...
No Matches
PyVoidAccessor.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#include "PyVoidAccessor.h"
5
6#include <pybind11/stl.h>
7
8namespace py = pybind11;
9
10namespace ChimeraTK {
11
12 /********************************************************************************************************************/
13
15
16 /********************************************************************************************************************/
17
18 template<class AccessorType>
20 const std::string& description, const std::unordered_set<std::string>& tags)
21 : _accessor(std::move(AccessorType(owner, name, description, tags))) {}
22
23 /********************************************************************************************************************/
24
26
27 /********************************************************************************************************************/
28
29 std::string PyVoidAccessor::repr(py::object& acc) {
30 if(not acc.cast<PyVoidAccessor&>().getTE().isInitialised()) {
31 return "<VoidAccessor(not initialized)>";
32 }
33 std::string rep{"<VoidAccessor(name="};
34 rep.append(py::cast(&acc).attr("getName")().cast<std::string>());
35 rep.append(", versionNumber=");
36 rep.append(py::cast<py::object>(py::cast(&acc).attr("getVersionNumber")()).attr("__repr__")().cast<std::string>());
37 rep.append(", dataValidity=");
38 rep.append(py::cast<py::object>(py::cast(&acc).attr("dataValidity")()).attr("__repr__")().cast<std::string>());
39 rep.append(")>");
40 return rep;
41 }
42
43 /********************************************************************************************************************/
44
46 // strictly speaking, py::nodelete is not necessary since we hand out instances only via factory function,
47 // but leave it here for consistentcy
48 py::class_<PyVoidAccessor, PyTransferElementBase, std::unique_ptr<PyVoidAccessor, py::nodelete>> scalaracc(
49 m, "VoidAccessor", py::buffer_protocol());
50 scalaracc.def(py::init<>())
51 .def("read", &PyVoidAccessor::read,
52 "Read the data from the device.\n\nIf AccessMode::wait_for_new_data was set, this function will block "
53 "until new data has arrived. Otherwise it still might block for a short time until the data transfer was "
54 "complete.")
55 .def("readNonBlocking", &PyVoidAccessor::readNonBlocking,
56 "Read the next value, if available in the input buffer.\n\nIf AccessMode::wait_for_new_data was set, this "
57 "function returns immediately and the return value indicated if a new value was available (true) or not "
58 "(false).\n\nIf AccessMode::wait_for_new_data was not set, this function is identical to read(), which "
59 "will still return quickly. Depending on the actual transfer implementation, the backend might need to "
60 "transfer data to obtain the current value before returning. Also this function is not guaranteed to be "
61 "lock free. The return value will be always true in this mode.")
62 .def("readLatest", &PyVoidAccessor::readLatest,
63 "Read the latest value, discarding any other update since the last read if present.\n\nOtherwise this "
64 "function is identical to readNonBlocking(), i.e. it will never wait for new values and it will return "
65 "whether a new value was available if AccessMode::wait_for_new_data is set.")
66 .def("write", &PyVoidAccessor::write,
67 "Write the data to device.\n\nThe return value is true, old data was lost on the write transfer (e.g. due "
68 "to an buffer overflow). In case of an unbuffered write transfer, the return value will always be false.")
69 .def("writeDestructively", &PyVoidAccessor::writeDestructively,
70 "Just like write(), but allows the implementation to destroy the content of the user buffer in the "
71 "process.\n\nThis is an optional optimisation, hence there is a default implementation which just calls "
72 "the normal doWriteTransfer(). In any case, the application must expect the user buffer of the "
73 "TransferElement to contain undefined data after calling this function.")
74 .def("getName", &PyVoidAccessor::getName, "Returns the name that identifies the process variable.")
75 .def("getUnit", &PyVoidAccessor::getUnit,
76 "Returns the engineering unit.\n\nIf none was specified, it will default to ' n./ a.'")
77 .def("getDescription", &PyVoidAccessor::getDescription, "Returns the description of this variable/register.")
78 .def("getValueType", &PyVoidAccessor::getValueType,
79 "Returns the std::type_info for the value type of this transfer element.\n\nThis can be used to determine "
80 "the type at runtime.")
81 .def("getVersionNumber", &PyVoidAccessor::getVersionNumber,
82 "Returns the version number that is associated with the last transfer (i.e. last read or write)")
83 .def("isReadOnly", &PyVoidAccessor::isReadOnly,
84 "Check if transfer element is read only, i.e. it is readable but not writeable.")
85 .def("isReadable", &PyVoidAccessor::isReadable, "Check if transfer element is readable.")
86 .def("isWriteable", &PyVoidAccessor::isWriteable, "Check if transfer element is writeable.")
87 .def("getId", &PyVoidAccessor::getId,
88 "Obtain unique ID for the actual implementation of this TransferElement.\n\nThis means that e.g. two "
89 "instances of VoidRegisterAccessor created by the same call to Device::getVoidRegisterAccessor() (e.g. "
90 "by copying the accessor to another using NDRegisterAccessorBridge::replace()) will have the same ID, "
91 "while two instances obtained by to difference calls to Device::getVoidRegisterAccessor() will have a "
92 "different ID even when accessing the very same register.")
93 .def("dataValidity", &PyVoidAccessor::dataValidity,
94 "Return current validity of the data.\n\nWill always return DataValidity.ok if the backend does not "
95 "support it")
96 .def("__repr__", &PyVoidAccessor::repr);
97
101 m.def(
102 "VoidInput",
103 [](VariableGroup& owner, const std::string& name, const std::string& description) {
104 return dynamic_cast<PyOwningObject&>(owner).make_child<PyVoidAccessor>(
105 VoidTypeTag<VoidInput>(), &owner, name, description);
106 },
107 py::return_value_policy::reference, "");
108
112 m.def(
113 "VoidOutput",
114 [](VariableGroup& owner, const std::string& name, const std::string& description) {
115 return dynamic_cast<PyOwningObject&>(owner).make_child<PyVoidAccessor>(
116 VoidTypeTag<VoidOutput>(), &owner, name, description);
117 },
118 py::return_value_policy::reference, "");
119 }
120
121 /********************************************************************************************************************/
122
123} // namespace ChimeraTK
Base class for ApplicationModule and DeviceModule, to have a common interface for these module types.
Definition Module.h:21
Base class used for all objects in the Python world which can own other objects and can be owned them...
const TransferElementAbstractor & getTE() const final
static void bind(py::module &mod)
static std::string repr(py::object &acc)
InvalidityTracer application module.
module_ module
Convenience class for output void (always UpdateMode::push)