diff --git a/main.cpp b/main.cpp index 2d8959aa..31a3ed1b 100644 --- a/main.cpp +++ b/main.cpp @@ -3,31 +3,8 @@ int main(int argc, char *argv[]) { - PIVector > in; - in.resize(5); - for (int i = 0; i < in.size_s(); ++i) - for (int j = 0; j < 20; ++j) - in[i] << j+i*100; -// piCout << in.size() << in[0].size(); - PIVector2D f0; - PIVector2D f1(30, 40); - //in.resize(1); - PIVector2D f2(in); - f0 = f2; -// piCout << f0; -// piCout << f1; -// piCout << f2; -// piCout << f2.rows() << f2.cols() << f2.size_all() << f2.rows()*f2.cols(); -// piCout << in; - piCout << f2; - f2.setRow(2, f2[2]);; - piCout << f2; -// piCout << f2.toVectors(); -// PIVector t = f2.toPlainVector(); -// piCout << t; -// piCout << PIVector2D(f2.rows(), f2.cols(), t); - return 0; - + PIConnection conn; + conn.configureFromConfig("0.conf"); return 0; } diff --git a/src_main/containers/pideque.h b/src_main/containers/pideque.h index ba509674..2ad92d2e 100755 --- a/src_main/containers/pideque.h +++ b/src_main/containers/pideque.h @@ -181,6 +181,8 @@ public: inline bool operator !=(const PIDeque & t) const {if (pid_size != t.pid_size) return true; for (size_t i = 0; i < pid_size; ++i) if (t[i] != (*this)[i]) return true; return false;} inline bool contains(const T & v) const {for (size_t i = pid_start; i < pid_start + pid_size; ++i) if (v == pid_data[i]) return true; return false;} inline int etries(const T & v) const {int ec = 0; for (size_t i = pid_start; i < pid_start + pid_size; ++i) if (v == pid_data[i]) ++ec; return ec;} + inline ssize_t indexOf(const T & v) const {for (ssize_t i = pid_start; i < pid_start + pid_size; ++i) if (v == pid_data[i]) return i - pid_start; return -1;} + inline ssize_t lastIndexOf(const T & v) const {for (ssize_t i = pid_start + pid_size - 1; i >= pid_start; --i) if (v == pid_data[i]) return i - pid_start; return -1;} inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);} inline const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);} diff --git a/src_main/containers/piset.h b/src_main/containers/piset.h index 4c44015a..1877a84f 100644 --- a/src_main/containers/piset.h +++ b/src_main/containers/piset.h @@ -67,6 +67,19 @@ public: //_CSet::_sort(); } + //! Contructs set from deque of elements + PISet(const PIDeque & values) { + if (values.isEmpty()) return; + //_CSet::pim_content.resize(values.size_s()); + //_CSet::pim_index.resize(values.size_s()); + for (int i = 0; i < values.size_s(); ++i) { + //_CSet::pim_index[i].index = i; + //_CSet::pim_index[i].key = values[i]; + _CSet::insert(values[i], 0); + } + //_CSet::_sort(); + } + typedef T key_type; PISet & operator <<(const T & t) {_CSet::insert(t, 0); return *this;} @@ -92,11 +105,50 @@ public: return *this; } + //! Intersect set with "v" + PISet & intersect(const PISet & v) { + for (typename _CSet::iterator i = _CSet::begin(); i != _CSet::end(); ++i) + if (!v.contains(i.key())) { + _CSet::remove(i.key()); + --i; + } + return *this; + } + + //! Unite set with "v" + PISet & operator +=(const PISet & v) {return unite(v);} + + //! Unite set with "v" + PISet & operator |=(const PISet & v) {return unite(v);} + + //! Subtract set with "v" + PISet & operator -=(const PISet & v) {return subtract(v);} + + //! Intersect set with "v" + PISet & operator &=(const PISet & v) {return intersect(v);} + //! Returns content of set as PIVector PIVector toVector() const {PIVector ret; for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i) ret << (*i).first; return ret;} + + //! Returns content of set as PIDeque + PIDeque toDeque() const {PIDeque ret; for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i) ret << (*i).first; return ret;} + }; +//! \relatesalso PISet \brief Returns unite of two sets +template PISet operator +(const PISet & v0, const PISet & v1) {PISet ret(v0); ret.unite(v1); return ret;} + +//! \relatesalso PISet \brief Returns subtraction of two sets +template PISet operator -(const PISet & v0, const PISet & v1) {PISet ret(v0); ret.subtract(v1); return ret;} + +//! \relatesalso PISet \brief Returns unite of two sets +template PISet operator |(const PISet & v0, const PISet & v1) {PISet ret(v0); ret.unite(v1); return ret;} + +//! \relatesalso PISet \brief Returns intersetion of two sets +template PISet operator &(const PISet & v0, const PISet & v1) {PISet ret(v0); ret.intersect(v1); return ret;} + + template inline PICout operator <<(PICout s, const PISet & v) { s.space(); diff --git a/src_main/io/piconnection.cpp b/src_main/io/piconnection.cpp index f8689e14..8c0b035c 100755 --- a/src_main/io/piconnection.cpp +++ b/src_main/io/piconnection.cpp @@ -126,10 +126,20 @@ bool PIConnection::configure(PIConfig & conf, const PIString & name_) { cb(ce.getValue("channel").children()), sb(ce.getValue("sender").children()); PIStringList dev_list(ce.getValue("device").value()); PIStringList name_list(ce.getValue("device").name()); + PIStringList flt_list(ce.getValue("filter").value()); piForeachC (PIConfig::Entry * e, db) { dev_list << e->value(); name_list << e->name(); } + piForeachC (PIConfig::Entry * e, fb) + flt_list << e->name(); + PISet chk_set = (PISet(name_list) & PISet(flt_list)); + //piCout << name_list << flt_list << chk_set; + chk_set.remove(""); + if (!chk_set.isEmpty()) { + piCoutObj << "Error," << chk_set.toVector() << "names assigned to both devices and filters!"; + return false; + } PIMap dev_aliases; for (int i = 0; i < dev_list.size_s(); ++i) { PIString fn(dev_list[i]); @@ -138,10 +148,11 @@ bool PIConnection::configure(PIConfig & conf, const PIString & name_) { PIIODevice::DeviceMode dm = PIIODevice::ReadWrite; PIIODevice::splitFullPath(fn, &fn, &dm); //piCout << fn; + //piCoutObj << "add" << fn << n; PIIODevice * dev = addDevice(fn, dm); if (!dev) continue; dev_aliases[n] = fn; - device_names[n] = dev; + //device_names[n] = dev; setDeviceName(dev, n); dev->setName(name_ + ".device." + dev_list[i]); PIConfig::Entry de = ce.getValue("device." + n); @@ -267,8 +278,11 @@ PIString PIConnection::makeConfig() const { if (f.second == 0) continue; if (f.second->extractor == 0) continue; PIString prefix = "filter." + f.first; - for (int i = 0; i < f.second->devices.size_s(); ++i) - ret << prefix << ".device." << i << " = " << device_names.key(f.second->devices[i]) << " #s\n"; + for (int i = 0; i < f.second->devices.size_s(); ++i) { + PIString dname = device_names.key(f.second->devices[i]); + if (dname.isEmpty()) dname = devPath(f.second->devices[i]); + ret << prefix << ".device." << i << " = " << dname << " #s\n"; + } PIDiagnostics * diag = diags_.value(f.second->extractor, 0); ret << prefix << ".bufferSize = " << f.second->extractor->bufferSize() << " #n\n"; if (diag != 0) @@ -293,15 +307,22 @@ PIString PIConnection::makeConfig() const { piForeachC (CPair & c, channels_) { piForeachC (PIIODevice * d, c.second) { PIString prefix = "channel." + PIString::fromNumber(dn); ++dn; - ret << prefix << ".from = " << devPath(c.first) << " #s\n"; - ret << prefix << ".to = " << devPath(d) << " #s\n"; + PIString dname = device_names.key(c.first); + if (dname.isEmpty()) dname = devPath(c.first); + ret << prefix << ".from = " << dname << " #s\n"; + dname = device_names.key(const_cast(d)); + if (dname.isEmpty()) dname = devPath(d); + ret << prefix << ".to = " << dname << " #s\n"; } } piForeachC (SPair & s, senders) { if (s.second == 0) continue; PIString prefix = "sender." + s.second->name(); - for (int i = 0; i < s.second->devices.size_s(); ++i) - ret << prefix << ".device." << i << " = " << devPath(s.second->devices[i]) << " #s\n"; + for (int i = 0; i < s.second->devices.size_s(); ++i) { + PIString dname = device_names.key(s.second->devices[i]); + if (dname.isEmpty()) dname = devPath(s.second->devices[i]); + ret << prefix << ".device." << i << " = " << dname << " #s\n"; + } double int_ = s.second->int_; if (int_ > 0.) ret << prefix << ".frequency = " << (1000. / int_) << " #f\n"; @@ -333,7 +354,14 @@ PIIODevice * PIConnection::addDevice(const PIString & full_path, PIIODevice::Dev } -PIStringList PIConnection::deviceNames(const PIIODevice *dev) const { +void PIConnection::setDeviceName(PIIODevice * dev, const PIString & name) { + if (!dev) return; + device_names[name] = dev; + //dev->setProperty(); +} + + +PIStringList PIConnection::deviceNames(const PIIODevice * dev) const { PIStringList ret; piForeachC (DNPair & s, device_names) if (s.second == dev) @@ -423,17 +451,15 @@ PIVector PIConnection::boundedDevices() const { PIPacketExtractor * PIConnection::addFilter(const PIString & name_, const PIString & full_path, PIPacketExtractor::SplitMode mode) { - PIString fp(PIIODevice::normalizeFullPath(full_path)); PIString fname_ = name_.trimmed(); Extractor * e = extractors.value(fname_); if (full_path.isEmpty()) return (e == 0 ? 0 : e->extractor); - PIIODevice * dev = deviceByName(fp); - if (!dev) dev = deviceByFullPath(fp); + PIIODevice * dev = devByString(full_path); PIPacketExtractor * pe(0); if (extractors.value(full_path) != 0) pe = extractors.value(full_path)->extractor; if (pe != 0) dev = pe; if (dev == 0) { - piCoutObj << "\"addFilter\" error: no such device \"" << full_path << "\"!"; + piCoutObj << "\"addFilter\" error: no such device or filter \"" << full_path << "\"!"; return 0; } if (e == 0) { @@ -467,15 +493,14 @@ PIPacketExtractor * PIConnection::addFilter(const PIString & name_, const PIStri PIPacketExtractor * PIConnection::addFilter(PIPacketExtractor * filter, const PIString & full_path) { - PIString fp(PIIODevice::normalizeFullPath(full_path)); Extractor * e = 0; if (full_path.isEmpty()) return (e == 0 ? 0 : e->extractor); - PIIODevice * dev = deviceByFullPath(fp); + PIIODevice * dev = devByString(full_path); PIPacketExtractor * pe(0); if (extractors.value(full_path) != 0) pe = extractors.value(full_path)->extractor; if (pe != 0) dev = pe; if (dev == 0) { - piCoutObj << "\"addFilter\" error: no such device \"" << full_path << "\"!"; + piCoutObj << "\"addFilter\" error: no such device or filter \"" << full_path << "\"!"; return 0; } if (e == 0) { @@ -505,12 +530,17 @@ PIPacketExtractor * PIConnection::addFilter(PIPacketExtractor * filter, const PI bool PIConnection::removeFilter(const PIString & name_, const PIString & full_path) { - PIString fp(PIIODevice::normalizeFullPath(full_path)); + return removeFilter(name_, devByString(full_path)); +} + + +bool PIConnection::removeFilter(const PIString & name_, const PIIODevice * dev) { + if (dev == 0) return false; Extractor * p = extractors.value(name_.trimmed()); if (p == 0) return false; bool ret = false; for (int i = 0; i < p->devices.size_s(); ++i) { - if (devFPath(p->devices[i]) == fp || devFPath(p->devices[i]) == full_path) { + if (p->devices[i] == dev) { bounded_extractors[p->devices[i]].removeAll(p->extractor); p->devices.remove(i); --i; @@ -525,12 +555,6 @@ bool PIConnection::removeFilter(const PIString & name_, const PIString & full_pa } -bool PIConnection::removeFilter(const PIString & name, const PIIODevice * dev) { - if (dev == 0) return false; - return removeFilter(name, devFPath(dev)); -} - - bool PIConnection::removeFilter(const PIString & name_) { Extractor * p = extractors.value(name_.trimmed()); if (p == 0) return false; @@ -597,9 +621,7 @@ PIVector PIConnection::filterBoundedDevices(const PIString & name bool PIConnection::addChannel(const PIString & name0, const PIString & name1) { //piCout << "addChannel" << name0 << name1; if (name0.isEmpty() || name1.isEmpty()) return false; - PIIODevice * dev0 = deviceByName(name0), * dev1 = deviceByName(name1); - if (!dev0) dev0 = deviceByFullPath(name0); - if (!dev1) dev1 = deviceByFullPath(name1); + PIIODevice * dev0 = devByString(name0), * dev1 = devByString(name1); PIPacketExtractor * pe0(0), * pe1(0); if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor; if (extractors.value(name1) != 0) pe1 = extractors.value(name1)->extractor; @@ -617,7 +639,7 @@ bool PIConnection::addChannel(const PIString & name0, const PIString & name1) { bool PIConnection::removeChannel(const PIString & name0, const PIString & name1) { - PIIODevice * dev0 = deviceByFullPath(name0), * dev1 = deviceByFullPath(name1); + PIIODevice * dev0 = devByString(name0), * dev1 = devByString(name1); PIPacketExtractor * pe0(0), * pe1(0); if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor; if (extractors.value(name1) != 0) pe1 = extractors.value(name1)->extractor; @@ -630,7 +652,7 @@ bool PIConnection::removeChannel(const PIString & name0, const PIString & name1) bool PIConnection::removeChannel(const PIString & name0) { - PIIODevice * dev0 = deviceByFullPath(name0); + PIIODevice * dev0 = devByString(name0); PIPacketExtractor * pe0(0); if (extractors.value(name0) != 0) pe0 = extractors.value(name0)->extractor; if (pe0 != 0) dev0 = pe0; @@ -661,6 +683,14 @@ PIString PIConnection::devFPath(const PIIODevice * d) const { } +PIIODevice * PIConnection::devByString(const PIString & s) const { + if (s.isEmpty()) return 0; + PIIODevice * ret = deviceByName(s); + if (!ret) ret = deviceByFullPath(s); + return ret; +} + + PIVector > PIConnection::channels() const { PIVector > ret; piForeachC (CPair & i, channels_) { @@ -672,20 +702,19 @@ PIVector > PIConnection::channels() const { } -void PIConnection::addSender(const PIString & name_, const PIString & full_path, float frequency, bool start_) { - PIString fp(PIIODevice::normalizeFullPath(full_path)); +void PIConnection::addSender(const PIString & name_, const PIString & full_path_name, float frequency, bool start_) { PIString fname_ = name_.trimmed(); - if (fp.isEmpty() || frequency <= 0.) return; + if (full_path_name.isEmpty() || frequency <= 0.) return; Sender * s = senders.value(fname_); - PIIODevice * dev = deviceByFullPath(fp); if (s == 0) { s = new Sender(this); s->setName(fname_); s->int_ = 1000. / frequency; senders[fname_] = s; } + PIIODevice * dev = devByString(full_path_name); if (dev == 0) { - piCoutObj << "\"addSender\" error: no such device \"" << full_path << "\"!"; + piCoutObj << "\"addSender\" error: no such device \"" << full_path_name << "\"!"; return; } if (!s->isRunning() && start_) { @@ -699,10 +728,9 @@ void PIConnection::addSender(const PIString & name_, const PIString & full_path, } -bool PIConnection::removeSender(const PIString & name, const PIString & full_path) { - PIString fp(PIIODevice::normalizeFullPath(full_path)); +bool PIConnection::removeSender(const PIString & name, const PIString & full_path_name) { Sender * s = senders.value(name, 0); - PIIODevice * d = deviceByFullPath(fp); + PIIODevice * d = devByString(full_path_name); if (s == 0 || d == 0) return false; s->lock(); bool ret = s->devices.contains(d); @@ -766,9 +794,8 @@ void PIConnection::removeAllSenders() { } -void PIConnection::startThreadedRead(const PIString & full_path) { - PIString fp(PIIODevice::normalizeFullPath(full_path)); - DevicePool::DeviceData * dd = __device_pool__->devices.value(fp, 0); +void PIConnection::startThreadedRead(const PIString & full_path_name) { + DevicePool::DeviceData * dd = __device_pool__->deviceData(devByString(full_path_name)); if (dd == 0) return; if (dd->dev == 0) return; if (dd->started || dd->dev->mode() == PIIODevice::WriteOnly) return; @@ -800,9 +827,8 @@ void PIConnection::startAllSenders() { } -void PIConnection::stopThreadedRead(const PIString & full_path) { - PIString fp(PIIODevice::normalizeFullPath(full_path)); - DevicePool::DeviceData * dd = __device_pool__->devices.value(fp, 0); +void PIConnection::stopThreadedRead(const PIString & full_path_name) { + DevicePool::DeviceData * dd = __device_pool__->deviceData(devByString(full_path_name)); if (dd == 0) return; if (dd->dev == 0) return; if (!dd->started || dd->dev->mode() == PIIODevice::WriteOnly) return; @@ -834,8 +860,7 @@ void PIConnection::stopAllSenders() { PIDiagnostics * PIConnection::diagnostic(const PIString & full_path_name) const { - PIIODevice * dev = deviceByFullPath(full_path_name); - if (dev == 0) dev = device_names.value(full_path_name, 0); + PIIODevice * dev = devByString(full_path_name); PIPacketExtractor * pe(0); if (extractors.value(full_path_name) != 0) pe = extractors.value(full_path_name)->extractor; if (pe != 0) dev = pe; @@ -1004,6 +1029,16 @@ PIIODevice * PIConnection::DevicePool::device(const PIString & fp) const { } +PIConnection::DevicePool::DeviceData * PIConnection::DevicePool::deviceData(PIIODevice * d) const { + if (!d) return 0; + piForeachC (DDPair & i, devices) { + if (i.second->dev == d) + return i.second; + } + return 0; +} + + PIVector PIConnection::DevicePool::boundedConnections() const { PIVector ret; piForeachC (DDPair & i, devices) { diff --git a/src_main/io/piconnection.h b/src_main/io/piconnection.h index b615e3a7..b7d3e592 100755 --- a/src_main/io/piconnection.h +++ b/src_main/io/piconnection.h @@ -62,7 +62,7 @@ public: * or \a startAllThreadedReads(). By default, read thread doesn`t start */ PIIODevice * addDevice(const PIString & full_path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = false); - void setDeviceName(PIIODevice * dev, const PIString & name) {device_names[name] = dev;} + void setDeviceName(PIIODevice * dev, const PIString & name); PIStringList deviceNames(const PIIODevice * dev) const; @@ -130,7 +130,7 @@ public: /*! \brief Add to connection channel from "name_from" to "name_to" - * \details "name_from" and "name_to" can be full pathes of devices or filter names. + * \details "name_from" and "name_to" can be full pathes of devices or device names or filter names. * Returns \b false if there if no such device or filter, else create channel and returns \b true */ bool addChannel(const PIString & name_from, const PIString & name_to); @@ -179,14 +179,14 @@ public: * If "start" is true, sender is started immediately. Else, you can start sender with * functions \a startSender() * \n \b Attention! "frequency" is actual olny if new sender was created! */ - void addSender(const PIString & name, const PIString & full_path, float frequency, bool start = false); + void addSender(const PIString & name, const PIString & full_path_name, float frequency, bool start = false); //! Add to connection sender with name "name" device "dev" void addSender(const PIString & name, const PIIODevice * dev, float frequency, bool start = false) {addSender(name, devFPath(dev), frequency, start);} /*! \brief Remove from sender with name "name" device with full path "full_path_name" * \details If there is no devices bounded to this sender, it will be removed. Returns if sender was removed */ - bool removeSender(const PIString & name, const PIString & full_path); + bool removeSender(const PIString & name, const PIString & full_path_name); //! Remove from sender with name "name" device "dev" bool removeSender(const PIString & name, const PIIODevice * dev) {return removeSender(name, devFPath(dev));} @@ -211,7 +211,7 @@ public: //! Start read thread of device with full path "full_path" - void startThreadedRead(const PIString & full_path); + void startThreadedRead(const PIString & full_path_name); //! Start read thread of device "dev" void startThreadedRead(const PIIODevice * dev) {startThreadedRead(devFPath(dev));} @@ -229,7 +229,7 @@ public: void start() {startAllThreadedReads(); startAllSenders();} //! Stop read thread of device with full path "full_path" - void stopThreadedRead(const PIString & full_path); + void stopThreadedRead(const PIString & full_path_name); //! Stop read thread of device "dev" void stopThreadedRead(const PIIODevice * dev) {stopThreadedRead(devFPath(dev));} @@ -286,6 +286,8 @@ public: PIOBJECT_SUBCLASS(DevicePool, PIThread) friend void __DevicePool_threadReadDP(void * ddp); friend class PIConnection; + protected: + struct DeviceData; public: DevicePool(); @@ -294,6 +296,7 @@ public: bool removeDevice(PIConnection * parent, const PIString & fp); void unboundConnection(PIConnection * parent); PIIODevice * device(const PIString & fp) const; + DeviceData * deviceData(PIIODevice * d) const; PIVector boundedConnections() const; PIVector boundedDevices() const; PIVector boundedDevices(const PIConnection * parent) const; @@ -367,6 +370,7 @@ private: PIString devPath(const PIIODevice * d) const; PIString devFPath(const PIIODevice * d) const; + PIIODevice * devByString(const PIString & s) const; struct Extractor { Extractor(): extractor(0) {}