Added pickling functionality for deviceInfo C++ object. Ugly but working implementation.
This commit is contained in:
parent
466a6f5cc1
commit
ff5afb8eb1
@ -87,6 +87,9 @@ cdef extern from "lasp_cppdaq.h" nogil:
|
||||
unsigned ninchannels
|
||||
unsigned noutchannels
|
||||
|
||||
string serialize()
|
||||
|
||||
cppDeviceInfo deserialize(string)
|
||||
bool hasInputIEPE
|
||||
bool hasInputACCouplingSwitch
|
||||
bool hasInputTrigger
|
||||
|
@ -19,6 +19,7 @@
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::getline;
|
||||
using std::runtime_error;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
@ -89,7 +90,7 @@ const DaqApi rtaudioAsioApi("RtAudio Windows ASIO", 5,
|
||||
|
||||
// Structure containing device info parameters
|
||||
class DeviceInfo {
|
||||
public:
|
||||
public:
|
||||
DaqApi api;
|
||||
string device_name = "";
|
||||
|
||||
@ -133,11 +134,118 @@ public:
|
||||
<< " number of output channels: " << noutchannels;
|
||||
return str.str();
|
||||
}
|
||||
|
||||
string serialize() const {
|
||||
// Simple serializer for this object, used because we found a bit late that
|
||||
// this object needs to be send over the wire. We do not want to make this
|
||||
// implementation in Python, as these objects are created here, in the C++
|
||||
// code. The Python wrapper is just a readonly wrapper.
|
||||
std::stringstream str;
|
||||
|
||||
str << api.apiname << "\t";
|
||||
str << api.apicode << "\t";
|
||||
str << api.api_specific_subcode << "\t";
|
||||
str << device_name << "\t";
|
||||
|
||||
str << availableDataTypes.size() << "\t";
|
||||
for(const DataType& dtype: availableDataTypes) {
|
||||
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
|
||||
str << dtype.name << "\t";
|
||||
str << dtype.sw << "\t";
|
||||
str << dtype.is_floating << "\t";
|
||||
}
|
||||
str << prefDataTypeIndex << "\t";
|
||||
|
||||
str << availableSampleRates.size() << "\t";
|
||||
for(const double& fs: availableSampleRates) {
|
||||
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
|
||||
str << fs << "\t";
|
||||
}
|
||||
str << prefSampleRateIndex << "\t";
|
||||
|
||||
str << availableFramesPerBlock.size() << "\t";
|
||||
for(const us& fb: availableFramesPerBlock) {
|
||||
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
|
||||
str << fb << "\t";
|
||||
}
|
||||
str << prefFramesPerBlockIndex << "\t";
|
||||
|
||||
str << availableInputRanges.size() << "\t";
|
||||
for(const double& fs: availableInputRanges) {
|
||||
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
|
||||
str << fs << "\t";
|
||||
}
|
||||
str << prefInputRangeIndex << "\t";
|
||||
|
||||
str << ninchannels << "\t";
|
||||
str << noutchannels << "\t";
|
||||
str << int(hasInputIEPE) << "\t";
|
||||
str << int(hasInputACCouplingSwitch) << "\t";
|
||||
str << int(hasInputTrigger) << "\t";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
static DeviceInfo deserialize(const string& dstr) {
|
||||
DeviceInfo devinfo;
|
||||
|
||||
std::stringstream str(dstr);
|
||||
string tmp;
|
||||
us N;
|
||||
auto nexts = [&]() { getline(str, tmp, '\t'); return tmp; };
|
||||
auto nexti = [&]() { getline(str, tmp, '\t'); return std::atoi(tmp.c_str()); };
|
||||
auto nextf = [&]() { getline(str, tmp, '\t'); return std::atof(tmp.c_str()); };
|
||||
|
||||
// Api
|
||||
string apiname = nexts();
|
||||
auto apicode = nexti();
|
||||
auto api_specific_subcode = nexti();
|
||||
DaqApi api(apiname, apicode, api_specific_subcode);
|
||||
devinfo.api = api;
|
||||
|
||||
devinfo.device_name = nexts();
|
||||
|
||||
N = us(nexti());
|
||||
for(us i=0;i<N; i++) {
|
||||
DataType dtype;
|
||||
dtype.name = nexts();
|
||||
dtype.sw =nexti();
|
||||
dtype.is_floating = bool(nexti());
|
||||
devinfo.availableDataTypes.push_back(dtype);
|
||||
}
|
||||
devinfo.prefDataTypeIndex = nexti();
|
||||
|
||||
N = us(nexti());
|
||||
for(us i=0;i<N; i++) {
|
||||
devinfo.availableSampleRates.push_back(nextf());
|
||||
}
|
||||
devinfo.prefSampleRateIndex = nexti();
|
||||
|
||||
N = us(nexti());
|
||||
for(us i=0;i<N; i++) {
|
||||
devinfo.availableSampleRates.push_back(nextf());
|
||||
}
|
||||
devinfo.prefSampleRateIndex = nexti();
|
||||
|
||||
N = us(nexti());
|
||||
for(us i=0;i<N; i++) {
|
||||
devinfo.availableFramesPerBlock.push_back(nexti());
|
||||
}
|
||||
devinfo.prefFramesPerBlockIndex = nexti();
|
||||
|
||||
devinfo.ninchannels = nexti();
|
||||
devinfo.noutchannels = nexti();
|
||||
devinfo.hasInputIEPE = bool(nexti());
|
||||
devinfo.hasInputACCouplingSwitch = bool(nexti());
|
||||
devinfo.hasInputTrigger = bool(nexti());
|
||||
|
||||
return devinfo;
|
||||
}
|
||||
};
|
||||
|
||||
// Device configuration parameters
|
||||
class DaqConfiguration {
|
||||
public:
|
||||
public:
|
||||
DaqApi api;
|
||||
string device_name;
|
||||
|
||||
@ -185,7 +293,7 @@ class Daq : public DaqConfiguration, public DeviceInfo {
|
||||
|
||||
mutable std::mutex mutex;
|
||||
|
||||
public:
|
||||
public:
|
||||
static vector<DeviceInfo> getDeviceInfo();
|
||||
|
||||
static Daq *createDaq(const DeviceInfo &, const DaqConfiguration &config);
|
||||
|
@ -9,6 +9,10 @@ DeviceInfo C++ object wrapper
|
||||
"""
|
||||
__all__ = ['DeviceInfo']
|
||||
|
||||
def pickle(dat):
|
||||
dev = DeviceInfo()
|
||||
dev.devinfo.deserialize(dat)
|
||||
return dev
|
||||
|
||||
cdef class DeviceInfo:
|
||||
def __cinit__(self):
|
||||
@ -17,6 +21,9 @@ cdef class DeviceInfo:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __reduce__(self):
|
||||
return (pickle, (self.devinfo.serialize(),))
|
||||
|
||||
@property
|
||||
def api(self): return self.devinfo.api.apiname.decode('utf-8')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user