Instrument Neutral Distributed Interface INDI  2.0.2
watchdeviceproperty.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2022 Pawel Soja <kernel32.pl@gmail.com>
3  Copyright (C) 2011 Jasem Mutlaq. All rights reserved.
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 #include "watchdeviceproperty.h"
20 #include "basedevice.h"
21 #include "basedevice_p.h"
22 
23 namespace INDI
24 {
25 
26 std::vector<BaseDevice> WatchDeviceProperty::getDevices() const
27 {
28  std::vector<BaseDevice> result;
29  for (const auto &it : data)
30  {
31  result.push_back(it.second.device);
32  }
33  return result;
34 }
35 
37 {
38  auto it = data.find(name);
39  return it != data.end() ? it->second.device : BaseDevice();
40 }
41 
42 WatchDeviceProperty::DeviceInfo &WatchDeviceProperty::ensureDeviceByName(const char *name, const std::function<ParentDevice()> &constructor)
43 {
44  auto &it = data[name];
45  if (!it.device.isValid())
46  {
47  it.device = constructor();
48  it.device.setDeviceName(name);
49  it.device.attach();
50  it.emitWatchDevice();
51  }
52  return it;
53 }
54 
56 {
57  return data.empty();
58 }
59 
60 bool WatchDeviceProperty::isDeviceWatched(const char *name) const
61 {
62  return watchedDevice.size() == 0 || watchedDevice.find(name) != watchedDevice.end();
63 }
64 
66 {
67  watchedDevice.clear();
68 }
69 
70 void WatchDeviceProperty::watchDevice(const std::string &deviceName)
71 {
72  watchedDevice.insert(deviceName);
73 }
74 
75 void WatchDeviceProperty::watchDevice(const std::string &deviceName, const std::function<void (BaseDevice)> &callback)
76 {
77  watchedDevice.insert(deviceName);
78  data[deviceName].newDeviceCallback = callback;
79 }
80 
81 void WatchDeviceProperty::watchProperty(const std::string &deviceName, const std::string &propertyName)
82 {
83  watchedDevice.insert(deviceName);
84  data[deviceName].properties.insert(propertyName);
85 }
86 
88 {
89  data.clear();
90 }
91 
93 {
94  for (auto &deviceInfo : data)
95  {
96  deviceInfo.second.device = ParentDevice(ParentDevice::Invalid);
97  }
98 }
99 
101 {
102  for (auto it = data.begin(); it != data.end();)
103  {
104  if (it->second.device == device)
105  {
106  it = data.erase(it);
107  return true;
108  }
109  else
110  ++it;
111  }
112  return false;
113 }
114 
115 int WatchDeviceProperty::processXml(const INDI::LilXmlElement &root, char *errmsg, const std::function<ParentDevice()> &constructor)
116 {
117  auto deviceName = root.getAttribute("device");
118  if (!deviceName.isValid() || deviceName.toString() == "" || !isDeviceWatched(deviceName))
119  {
120  return 0;
121  }
122 
123  // Get the device information, if not available, create it
124  auto &deviceInfo = ensureDeviceByName(deviceName, constructor);
125 
126  // If we are asked to watch for specific properties only, we ignore everything else
127  if (deviceInfo.properties.size() != 0)
128  {
129  const auto it = deviceInfo.properties.find(root.getAttribute("name").toString());
130  if (it == deviceInfo.properties.end())
131  return 0;
132  }
133 
134  static const std::set<std::string> defVectors{
135  "defTextVector", "defNumberVector", "defSwitchVector",
136  "defLightVector", "defBLOBVector"
137  };
138 
139  if (defVectors.find(root.tagName()) != defVectors.end())
140  {
141  return deviceInfo.device.buildProp(root, errmsg);
142  }
143 
144  static const std::set<std::string> setVectors{
145  "setTextVector", "setNumberVector", "setSwitchVector",
146  "setLightVector", "setBLOBVector"
147  };
148 
149  if (setVectors.find(root.tagName()) != setVectors.end())
150  {
151  return deviceInfo.device.setValue(root, errmsg);
152  }
153 
154  return INDI_DISPATCH_ERROR;
155 }
156 
157 }
hid_device * device
Class to provide basic INDI device functionality.
Definition: basedevice.h:52
std::string tagName() const
Definition: indililxml.h:372
LilXmlAttribute getAttribute(const char *name) const
Definition: indililxml.h:405
std::string toString() const
Definition: indililxml.h:265
The class is used to create device instances. Class copying is not allowed. When an object is destroy...
Definition: parentdevice.h:18
void watchProperty(const std::string &deviceName, const std::string &propertyName)
bool isDeviceWatched(const char *deviceName) const
checks if the device is being watched by something
std::vector< BaseDevice > getDevices() const
DeviceInfo & ensureDeviceByName(const char *name, const std::function< ParentDevice()> &constructor)
std::map< std::string, DeviceInfo > data
BaseDevice getDeviceByName(const char *name)
std::set< std::string > watchedDevice
void watchDevice(const std::string &deviceName)
int processXml(const INDI::LilXmlElement &root, char *errmsg, const std::function< ParentDevice()> &constructor=[] { return ParentDevice(ParentDevice::Valid);})
bool deleteDevice(const BaseDevice &device)
@ INDI_DISPATCH_ERROR
Definition: indibasetypes.h:66
Namespace to encapsulate INDI client, drivers, and mediator classes.