Instrument Neutral Distributed Interface INDI 2.2.5
indipropertyview.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 by Pawel Soja <[email protected]>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#pragma once
20
21#include "indiapi.h"
22#include "indidevapi.h"
23#include "indiwidgettraits.h"
24#include "indiwidgetview.h"
25
26#include <string>
27#include <cstring>
28#include <cstdarg>
29#include <cstdlib>
30#include <type_traits>
31
32namespace INDI
33{
34
35template <typename> struct WidgetView;
36template <typename> struct PropertyView;
37
43
49
50#define PROPERTYVIEW_BASE_ACCESS public
51// don't use direct access to low-level property
52//#define PROPERTYVIEW_BASE_ACCESS protected // future
53
81template <typename T>
83{
84 using Type = T;
87
88 friend class Property;
89 friend class PropertyPrivate;
90 friend class BaseDevice;
91 friend class DefaultDevice;
92 template <typename>
93 friend struct WidgetView;
94
95 template <typename X, typename Needed>
96 using enable_if_is_same_t = typename std::enable_if<std::is_same<X, Needed>::value, bool>::type;
97 public:
99
100 // #PS: do not delete items, they may be on the stack.
101 //~PropertyView() { for(auto &p: *this) {p.clear();} free(widget()); }
102
103 public:
104 void setDeviceName(const char *name); /* outside implementation */
105 void setDeviceName(const std::string &name); /* outside implementation */
106
107 void setName(const char *name); /* outside implementation */
108 void setName(const std::string &name); /* outside implementation */
109
110 void setLabel(const char *label); /* outside implementation */
111 void setLabel(const std::string &label); /* outside implementation */
112
113 void setGroupName(const char *name); /* outside implementation */
114 void setGroupName(const std::string &name); /* outside implementation */
115
116 void setPermission(IPerm permission); /* outside implementation */
117 void setTimeout(double timeout); /* outside implementation */
118 void setState(IPState state);
119
120 void setTimestamp(const char *timestamp); /* outside implementation */
121 void setTimestamp(const std::string &timestamp); /* outside implementation */
122
123 void setAux(void *user); /* outside implementation */
124 void setWidgets(WidgetType *w, size_t count); /* outside implementation */
125
126 template <size_t N>
127 void setWidgets(WidgetType (&w)[N]); /* outside implementation */
128
129 public: // only for ISwitch
130 void setRule(ISRule rule); /* outside implementation */
131 bool setRule(const std::string &rule); /* outside implementation */
132
133 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
134 void reset()
135 {
136 IUResetSwitch(this);
137 }
138
139 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
141 {
142 return static_cast<WidgetType *>(IUFindOnSwitch(this));
143 }
144
145 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
146 bool isSwitchOn(const std::string &name) const
147 {
148 auto onSwitch = findOnSwitch();
149 return (onSwitch && onSwitch->isNameMatch(name));
150 }
151
152 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
154 {
155 return IUFindOnSwitchIndex(this);
156 }
157
158 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
159 std::string findOnSwitchName() const
160 {
161 auto onSwitch = findOnSwitch();
162 if (onSwitch)
163 return onSwitch->getName();
164 else
165 return std::string();
166 }
167
168 public: // only for INumber
169 template <typename X = T, enable_if_is_same_t<X, INumber> = true>
170 void updateMinMax(); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
171
172 public: //getters
173 const char *getDeviceName() const
174 {
175 return this->device;
176 }
177 const char *getName() const
178 {
179 return this->name;
180 }
181 const char *getLabel() const
182 {
183 return this->label;
184 }
185 const char *getGroupName() const
186 {
187 return this->group;
188 }
189
190 IPerm getPermission() const; /* outside implementation */
191 const char *getPermissionAsString() const
192 {
193 return permStr(getPermission());
194 }
195
196 ISRule getRule() const; /* outside implementation */
197 const char * getRuleAsString() const
198 {
199 return ruleStr(getRule());
200 }
201
202 double getTimeout() const; /* outside implementation */
204 {
205 return this->s;
206 }
207 const char *getStateAsString() const
208 {
209 return pstateStr(getState());
210 }
211
212 const char *getTimestamp() const
213 {
214 return this->timestamp;
215 }
216 void *getAux() const
217 {
218 return this->aux;
219 }
220
221 int count() const; /* outside implementation */
222 WidgetType *widget() const; /* outside implementation */
223
224 WidgetType *findWidgetByName(const char *name) const; /* outside implementation */
225
226 public: //tests
227 bool isEmpty() const
228 {
229 return widget() == nullptr || count() == 0;
230 }
231
232 bool isNameMatch(const char *otherName) const
233 {
234 return !strcmp(getName(), otherName);
235 }
236 bool isNameMatch(const std::string &otherName) const
237 {
238 return getName() == otherName;
239 }
240
241 bool isLabelMatch(const char *otherLabel) const
242 {
243 return !strcmp(getLabel(), otherLabel);
244 }
245 bool isLabelMatch(const std::string &otherLabel) const
246 {
247 return getLabel() == otherLabel;
248 }
249
250 public: // only driver side
251 bool load();
252 void save(FILE *f) const; /* outside implementation */
253 bool snoop(XMLEle *root); /* outside implementation */
254
255 void vapply(const char *format, va_list args)
256 const; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
257 void vdefine(const char *format, va_list args)
258 const; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
259
260 void apply(const char *format, ...) const ATTRIBUTE_FORMAT_PRINTF(2,
261 3); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
262 void define(const char *format, ...) const ATTRIBUTE_FORMAT_PRINTF(2,
263 3); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
264
265 void apply() const
266 {
267 apply(nullptr);
268 }
269 void define() const
270 {
271 define(nullptr);
272 }
273
274 public:
275 template <typename X = T, enable_if_is_same_t<X, IText> = true>
276 void fill(
277 const char *device, const char *name, const char *label, const char *group,
278 IPerm permission, double timeout, IPState state
279 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
280
281 template <typename X = T, enable_if_is_same_t<X, INumber> = true>
282 void fill(
283 const char *device, const char *name, const char *label, const char *group,
284 IPerm permission, double timeout, IPState state
285 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
286
287 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
288 void fill(
289 const char *device, const char *name, const char *label, const char *group,
290 IPerm permission, ISRule rule, double timeout, IPState state
291 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
292
293 template <typename X = T, enable_if_is_same_t<X, ILight> = true>
294 void fill(
295 const char *device, const char *name, const char *label, const char *group,
296 IPState state
297 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
298
299 template <typename X = T, enable_if_is_same_t<X, IBLOB> = true>
300 void fill(
301 const char *device, const char *name, const char *label, const char *group,
302 IPerm permission, double timeout, IPState state
303 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
304
305 public:
306 template <typename X = T, enable_if_is_same_t<X, IText> = true>
307 bool update(const char * const texts[], const char * const names[], int n);
308 /* outside implementation - only driver side, see indipropertyview_driver.cpp */
309
310 template <typename X = T, enable_if_is_same_t<X, INumber> = true>
311 bool update(const double values[], const char * const names[], int n);
312 /* outside implementation - only driver side, see indipropertyview_driver.cpp */
313
314 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
315 bool update(const ISState states[], const char * const names[], int n);
316 /* outside implementation - only driver side, see indipropertyview_driver.cpp */
317
318 /*
319 template <typename X = T, enable_if_is_same_t<X, ILight> = true>
320 bool update(..., const char * const names[], int n);
321 */
322
323 template <typename X = T, enable_if_is_same_t<X, IBLOB> = true>
324 bool update(
325 const int sizes[], const int blobsizes[], const char * const blobs[], const char * const formats[],
326 const char * const names[], int n
327 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */
328
329 template <typename X = T, enable_if_is_same_t<X, IText> = true>
330 bool isUpdated(const char * const texts[], const char * const names[], int n) const;
331
332 template <typename X = T, enable_if_is_same_t<X, INumber> = true>
333 bool isUpdated(const double values[], const char * const names[], int n) const;
334
335 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true>
336 bool isUpdated(const ISState states[], const char * const names[], int n) const;
337
338
339 public:
341 {
342 return widget();
343 }
345 {
346 return widget() + count();
347 }
348
349 WidgetType *at(size_t index) const
350 {
351 return widget() + index;
352 }
353 public:
354 void clear()
355 {
356 for(auto &p : *this)
357 {
358 p.clear();
359 }
360 //free(widget()); // #PS: do not delete items, they may be on the stack.
361 memset((void*)this, 0, sizeof(*this));
362 }
363 public: // internal use only
365 {
366 return static_cast<PropertyView<T>*>(raw);
367 }
369 {
370 return this;
371 }
372};
373
374template <typename>
375struct WidgetView;
376
377template <>
379{
380 using Type = IText;
381 template <typename> friend struct PropertyView;
382
383 public:
385 {
386 memset((void*)this, 0, sizeof(*this));
387 }
388 WidgetView(const WidgetView<Type> &other): Type(other)
389 {
390 this->text = nullptr;
391 if (other.text != nullptr)
392 {
393 setText(other.text);
394 }
395 }
397 {
398 memset(static_cast<Type*>(&other), 0, sizeof(other));
399 }
401 {
402 return *this = WidgetView(other);
403 }
405 {
406 std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
407 return *this;
408 }
410 {
411 free(this->text);
412 }
413 void clear()
414 {
415 free(this->text);
416 memset((void*)this, 0, sizeof(*this));
417 }
418 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
419
420 public: // setters
422 {
423 this->tvp = parent;
424 }
426 {
427 this->tvp = static_cast<ITextVectorProperty*>(parent);
428 }
429
430 void setName(const char *name)
431 {
432 INDI::strlcpy(this->name, name);
433 }
434 void setName(const std::string &name)
435 {
436 setName(name.data());
437 }
438
439 void setLabel(const char *label)
440 {
441 INDI::strlcpy(this->label, label);
442 }
443 void setLabel(const std::string &label)
444 {
445 setLabel(label.data());
446 }
447
448 //void setText(const char *text) { free(this->text); this->text = strndup(text, strlen(text)); }
449 void setText(const char *text, size_t size)
450 {
451 INDI::strlcpy(this->text = static_cast<char*>(realloc(this->text, size + 1)), text, size + 1);
452 }
453 void setText(const char *text)
454 {
455 setText(text, strlen(text));
456 }
457 void setText(const std::string &text)
458 {
459 setText(text.data(), text.size());
460 }
461
462 void setAux(void *user)
463 {
464 this->aux0 = user;
465 }
466 // don't use any other aux!
467
468 public: //getters
469 const char *getName() const
470 {
471 return this->name;
472 }
473 const char *getLabel() const
474 {
475 return this->label;
476 }
477 const char *getText() const
478 {
479 return this->text ? this->text : "";
480 }
481
482 void *getAux() const
483 {
484 return this->aux0;
485 }
486
487 public: //tests
488 bool isNameMatch(const char *otherName) const
489 {
490 return !strcmp(getName(), otherName);
491 }
492 bool isNameMatch(const std::string &otherName) const
493 {
494 return getName() == otherName;
495 }
496
497 bool isLabelMatch(const char *otherLabel) const
498 {
499 return !strcmp(getLabel(), otherLabel);
500 }
501 bool isLabelMatch(const std::string &otherLabel) const
502 {
503 return getLabel() == otherLabel;
504 }
505
506 bool isEmpty() const
507 {
508 return getText()[0] == '\0';
509 }
510
511 public:
512 void fill(const char *name, const char *label, const char *initialText)
513 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
514
515 void fill(const std::string &name, const std::string &label, const std::string &initialText)
516 {
517 fill(name.c_str(), label.c_str(), initialText.c_str());
518 }
519};
520
521template <>
523{
524 using Type = INumber;
525 template <typename> friend struct PropertyView;
526
527 public:
529 {
530 memset((void*)this, 0, sizeof(*this));
531 }
532 WidgetView(const WidgetView<Type> &other): Type(other) { }
534 {
535 memset(static_cast<Type*>(&other), 0, sizeof(other));
536 }
538 {
539 return *this = WidgetView(other);
540 }
542 {
543 std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
544 return *this;
545 }
547 void clear()
548 {
549 memset((void*)this, 0, sizeof(*this));
550 }
551 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
552
553 public: // setters
555 {
556 this->nvp = parent;
557 }
559 {
560 this->nvp = static_cast<INumberVectorProperty*>(parent);
561 }
562
563 void setName(const char *name)
564 {
565 INDI::strlcpy(this->name, name);
566 }
567 void setName(const std::string &name)
568 {
569 setName(name.data());
570 }
571
572 void setLabel(const char *label)
573 {
574 INDI::strlcpy(this->label, label);
575 }
576 void setLabel(const std::string &label)
577 {
578 setLabel(label.data());
579 }
580
581 void setFormat(const char *format)
582 {
583 INDI::strlcpy(this->format, format);
584 }
585 void setFormat(const std::string &format)
586 {
587 setLabel(format.data());
588 }
589
590 void setMin(double min)
591 {
592 this->min = min;
593 }
594 void setMax(double max)
595 {
596 this->max = max;
597 }
598 void setMinMax(double min, double max)
599 {
600 setMin(min);
601 setMax(max);
602 }
603 void setStep(double step)
604 {
605 this->step = step;
606 }
607 void setValue(double value)
608 {
609 this->value = value;
610 }
611
612 void setAux(void *user)
613 {
614 this->aux0 = user;
615 }
616 // don't use any other aux!
617
618 public: //getters
619 const char *getName() const
620 {
621 return this->name;
622 }
623 const char *getLabel() const
624 {
625 return this->label;
626 }
627 const char *getFormat() const
628 {
629 return this->format;
630 }
631
632 double getMin() const
633 {
634 return this->min;
635 }
636 double getMax() const
637 {
638 return this->max;
639 }
640 double getStep() const
641 {
642 return this->step;
643 }
644 double getValue() const
645 {
646 return this->value;
647 }
648
649 void *getAux() const
650 {
651 return this->aux0;
652 }
653
654 public: //tests
655 bool isNameMatch(const char *otherName) const
656 {
657 return !strcmp(getName(), otherName);
658 }
659 bool isNameMatch(const std::string &otherName) const
660 {
661 return getName() == otherName;
662 }
663
664 bool isLabelMatch(const char *otherLabel) const
665 {
666 return !strcmp(getLabel(), otherLabel);
667 }
668 bool isLabelMatch(const std::string &otherLabel) const
669 {
670 return getLabel() == otherLabel;
671 }
672
673 public:
674 void fill(const char *name, const char *label, const char *format,
675 double min, double max, double step, double value)
676 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
677
678 void fill(const std::string &name, const std::string &label, const std::string &format,
679 double min, double max, double step, double value)
680 {
681 fill(name.c_str(), label.c_str(), format.c_str(), min, max, step, value);
682 }
683};
684
685template <>
687{
688 using Type = ISwitch;
689 template <typename> friend struct PropertyView;
690
691 public:
693 {
694 memset((void*)this, 0, sizeof(*this));
695 }
696 WidgetView(const WidgetView<Type> &other): Type(other) { }
698 {
699 memset(static_cast<Type*>(&other), 0, sizeof(other));
700 }
702 {
703 return *this = WidgetView(other);
704 }
706 {
707 std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
708 return *this;
709 }
711 void clear()
712 {
713 memset((void*)this, 0, sizeof(*this));
714 }
715 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
716
717 public: // setters
719 {
720 this->svp = parent;
721 }
723 {
724 this->svp = static_cast<ISwitchVectorProperty*>(parent);
725 }
726
727 void setName(const char *name)
728 {
729 INDI::strlcpy(this->name, name);
730 }
731 void setName(const std::string &name)
732 {
733 setName(name.data());
734 }
735
736 void setLabel(const char *label)
737 {
738 INDI::strlcpy(this->label, label);
739 }
740 void setLabel(const std::string &label)
741 {
742 setLabel(label.data());
743 }
744
745 void setState(const ISState &state)
746 {
747 this->s = state;
748 }
749 bool setState(const std::string &state)
750 {
751 return crackISState(state.data(), &this->s) == 0;
752 }
753
754 void setAux(void *user)
755 {
756 this->aux = user;
757 }
758 // don't use any other aux!
759
760 public: //getters
761 const char *getName() const
762 {
763 return this->name;
764 }
765 const char *getLabel() const
766 {
767 return this->label;
768 }
769
771 {
772 return this->s;
773 }
774 const char *getStateAsString() const
775 {
776 return sstateStr(getState());
777 }
778
779 void *getAux() const
780 {
781 return this->aux;
782 }
783
784
785 public: //tests
786 bool isNameMatch(const char *otherName) const
787 {
788 return !strcmp(getName(), otherName);
789 }
790 bool isNameMatch(const std::string &otherName) const
791 {
792 return getName() == otherName;
793 }
794
795 bool isLabelMatch(const char *otherLabel) const
796 {
797 return !strcmp(getLabel(), otherLabel);
798 }
799 bool isLabelMatch(const std::string &otherLabel) const
800 {
801 return getLabel() == otherLabel;
802 }
803
804 public:
805 void fill(const char *name, const char *label, ISState state = ISS_OFF)
806 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
807
808 void fill(const std::string &name, const std::string &label, ISState state = ISS_OFF)
809 {
810 fill(name.c_str(), label.c_str(), state);
811 }
812};
813
814template <>
816{
817 using Type = ILight;
818 template <typename> friend struct PropertyView;
819
820 public:
822 {
823 memset((void*)this, 0, sizeof(*this));
824 }
825 WidgetView(const WidgetView<Type> &other): Type(other) { }
827 {
828 memset(static_cast<Type*>(&other), 0, sizeof(other));
829 }
831 {
832 return *this = WidgetView(other);
833 }
835 {
836 std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
837 return *this;
838 }
840 void clear()
841 {
842 memset((void*)this, 0, sizeof(*this));
843 }
844 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
845
846 public: // setters
848 {
849 this->lvp = parent;
850 }
852 {
853 this->lvp = static_cast<ILightVectorProperty*>(parent);
854 }
855
856 void setName(const char *name)
857 {
858 INDI::strlcpy(this->name, name);
859 }
860 void setName(const std::string &name)
861 {
862 setName(name.data());
863 }
864
865 void setLabel(const char *label)
866 {
867 INDI::strlcpy(this->label, label);
868 }
869 void setLabel(const std::string &label)
870 {
871 setLabel(label.data());
872 }
873
874 void setState(const IPState &state)
875 {
876 this->s = state;
877 }
878 bool setState(const std::string &state)
879 {
880 return crackIPState(state.data(), &this->s) == 0;
881 }
882
883 void setAux(void *user)
884 {
885 this->aux = user;
886 }
887 // don't use any other aux!
888
889 public: //getters
890 const char *getName() const
891 {
892 return this->name;
893 }
894 const char *getLabel() const
895 {
896 return this->label;
897 }
898
900 {
901 return this->s;
902 }
903 const char *getStateAsString() const
904 {
905 return pstateStr(getState());
906 }
907
908 void *getAux() const
909 {
910 return this->aux;
911 }
912
913
914 public: //tests
915 bool isNameMatch(const char *otherName) const
916 {
917 return !strcmp(getName(), otherName);
918 }
919 bool isNameMatch(const std::string &otherName) const
920 {
921 return getName() == otherName;
922 }
923
924 bool isLabelMatch(const char *otherLabel) const
925 {
926 return !strcmp(getLabel(), otherLabel);
927 }
928 bool isLabelMatch(const std::string &otherLabel) const
929 {
930 return getLabel() == otherLabel;
931 }
932
933 public:
934 void fill(const char *name, const char *label, IPState state = IPS_OK)
935 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
936
937 void fill(const std::string &name, const std::string &&label, IPState state = IPS_OK)
938 {
939 fill(name.c_str(), label.c_str(), state);
940 }
941};
942
943template <>
945{
946 using Type = IBLOB;
947 template <typename> friend struct PropertyView;
948
949 public:
951 {
952 memset((void*)this, 0, sizeof(*this));
953 }
954 WidgetView(const WidgetView<Type> &other): Type(other) { }
956 {
957 memset(static_cast<Type*>(&other), 0, sizeof(other));
958 }
960 {
961 return *this = WidgetView(other);
962 }
964 {
965 std::swap(static_cast<Type &>(other), static_cast<Type &>(*this));
966 return *this;
967 }
968 ~WidgetView() { /* free(this->blob); */ }
969 void clear()
970 {
971 memset((void*)this, 0, sizeof(*this));
972 }
973 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; }
974
975 public: // setters
977 {
978 this->bvp = parent;
979 }
981 {
982 this->bvp = static_cast<IBLOBVectorProperty*>(parent);
983 }
984
985 void setName(const char *name)
986 {
987 INDI::strlcpy(this->name, name);
988 }
989 void setName(const std::string &name)
990 {
991 setName(name.data());
992 }
993
994 void setLabel(const char *label)
995 {
996 INDI::strlcpy(this->label, label);
997 }
998 void setLabel(const std::string &label)
999 {
1000 setLabel(label.data());
1001 }
1002
1003 void setFormat(const char *format)
1004 {
1005 INDI::strlcpy(this->format, format);
1006 }
1007 void setFormat(const std::string &format)
1008 {
1009 setFormat(format.data());
1010 }
1011
1012 void setBlob(void *blob)
1013 {
1014 this->blob = blob;
1015 }
1016 void setBlobLen(int size)
1017 {
1018 this->bloblen = size;
1019 }
1020 void setSize(int size)
1021 {
1022 this->size = size;
1023 }
1024
1025 void setAux(void *user)
1026 {
1027 this->aux0 = user;
1028 }
1029 // don't use any other aux!
1030
1031 public: //getters
1032 const char *getName() const
1033 {
1034 return this->name;
1035 }
1036 const char *getLabel() const
1037 {
1038 return this->label;
1039 }
1040 const char *getFormat() const
1041 {
1042 return this->format;
1043 }
1044 void *getBlob()
1045 {
1046 return this->blob;
1047 }
1048 const void *getBlob() const
1049 {
1050 return this->blob;
1051 }
1052 std::string getBlobAsString() const
1053 {
1054 return std::string(static_cast<const char*>(this->blob), this->bloblen);
1055 }
1056 int getBlobLen() const
1057 {
1058 return this->bloblen;
1059 }
1060 int getSize() const
1061 {
1062 return this->size;
1063 }
1064
1065 void *getAux() const
1066 {
1067 return this->aux0;
1068 }
1069
1070 public: //tests
1071 bool isNameMatch(const char *otherName) const
1072 {
1073 return !strcmp(getName(), otherName);
1074 }
1075 bool isNameMatch(const std::string &otherName) const
1076 {
1077 return getName() == otherName;
1078 }
1079
1080 bool isLabelMatch(const char *otherLabel) const
1081 {
1082 return !strcmp(getLabel(), otherLabel);
1083 }
1084 bool isLabelMatch(const std::string &otherLabel) const
1085 {
1086 return getLabel() == otherLabel;
1087 }
1088
1089 public:
1090 void fill(const char *name, const char *label, const char *format)
1091 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */
1092
1093 void fill(const std::string &name, const std::string &label, const std::string &format)
1094 {
1095 fill(name.c_str(), label.c_str(), format.c_str());
1096 }
1097
1098 public: // internal use only
1100 {
1101 return static_cast<WidgetView<Type>*>(blob);
1102 }
1104 {
1105 return this;
1106 }
1107};
1108
1109
1110
1111
1112/* outside implementation */
1113template <typename T>
1115{
1116 memset((void*)this, 0, sizeof(*this));
1117}
1118
1119template <typename T>
1120inline void PropertyView<T>::setDeviceName(const char *name)
1121{
1122 INDI::strlcpy(this->device, name);
1123}
1124
1125template <typename T>
1126inline void PropertyView<T>::setDeviceName(const std::string &name)
1127{
1128 setDeviceName(name.data());
1129}
1130
1131template <typename T>
1132inline void PropertyView<T>::setName(const char *name)
1133{
1134 INDI::strlcpy(this->name, name);
1135}
1136
1137template <typename T>
1138inline void PropertyView<T>::setName(const std::string &name)
1139{
1140 setName(name.data());
1141}
1142
1143template <typename T>
1144inline void PropertyView<T>::setLabel(const char *label)
1145{
1146 INDI::strlcpy(this->label, label);
1147}
1148
1149template <typename T>
1150inline void PropertyView<T>::setLabel(const std::string &label)
1151{
1152 setLabel(label.data());
1153}
1154
1155template <typename T>
1156inline void PropertyView<T>::setGroupName(const char *name)
1157{
1158 INDI::strlcpy(this->group, name);
1159}
1160
1161template <typename T>
1162inline void PropertyView<T>::setGroupName(const std::string &name)
1163{
1164 setGroupName(name.data());
1165}
1166
1167template <typename T>
1169{
1170 this->s = state;
1171}
1172
1173template <typename T>
1174inline void PropertyView<T>::setTimestamp(const char *timestamp)
1175{
1176 INDI::strlcpy(this->timestamp, timestamp);
1177}
1178
1179template <typename T>
1180inline void PropertyView<T>::setTimestamp(const std::string &timestamp)
1181{
1182 setTimestamp(timestamp.data());
1183}
1184
1185template <typename T>
1186template <size_t N>
1188{
1189 setWidgets(static_cast<WidgetType*>(w), N);
1190}
1191
1192template <typename T>
1193inline void PropertyView<T>::setAux(void *user)
1194{
1195 this->aux = user;
1196}
1197
1198template <>
1200{
1201 return IULoadConfigNumber(this) == nnp;
1202}
1203
1204template <>
1206{
1207 return IULoadConfigSwitch(this) == nsp;
1208}
1209
1210template <>
1212{
1213 return false;
1214}
1215
1216template <>
1218{
1219 return false;
1220}
1221
1222template <>
1224{
1225 return IULoadConfigText(this) == ntp;
1226}
1227
1228template <>
1229inline void PropertyView<INumber>::save(FILE *f) const
1230{
1231 IUSaveConfigNumber(f, this);
1232}
1233
1234template <>
1235inline void PropertyView<IText>::save(FILE *f) const
1236{
1237 IUSaveConfigText(f, this);
1238}
1239
1240template <>
1241inline void PropertyView<ISwitch>::save(FILE *f) const
1242{
1243 IUSaveConfigSwitch(f, this);
1244}
1245
1246template <>
1247inline void PropertyView<ILight>::save(FILE *f) const
1248{
1249 (void)f; /* IUSaveConfigLight(f, this); */
1250}
1251
1252template <>
1253inline void PropertyView<IBLOB>::save(FILE *f) const
1254{
1255 IUSaveConfigBLOB(f, this);
1256}
1257
1258template <>
1260{
1261 return IUSnoopNumber(root, this) == 0;
1262}
1263
1264template <>
1266{
1267 return IUSnoopText(root, this) == 0;
1268}
1269
1270template <>
1272{
1273 return IUSnoopSwitch(root, this) == 0;
1274}
1275
1276template <>
1278{
1279 return IUSnoopLight(root, this) == 0;
1280}
1281
1282template <>
1284{
1285 return IUSnoopBLOB(root, this) == 0;
1286}
1287
1288template <typename T>
1289inline void PropertyView<T>::setTimeout(double timeout)
1290{
1291 this->timeout = timeout;
1292}
1293
1294template <>
1296{ }
1297
1298template <typename T>
1300{
1301 this->p = permission;
1302}
1303
1304template <>
1307
1308template <typename T>
1311
1312template <>
1314{
1315 this->r = rule;
1316}
1317
1318template <typename T>
1319inline bool PropertyView<T>::setRule(const std::string &)
1320{
1321 return false;
1322}
1323
1324template <>
1325inline bool PropertyView<ISwitch>::setRule(const std::string &rule)
1326{
1327 return crackISRule(rule.data(), &this->r) == 0;
1328}
1329
1330template <typename T>
1332{
1333 return nullptr;
1334}
1335
1336template <>
1338{
1339 return static_cast<WidgetView<IText> *>(IUFindText(this, name));
1340}
1341
1342template <>
1344{
1345 return static_cast<WidgetView<INumber> *>(IUFindNumber(this, name));
1346}
1347
1348template <>
1350{
1351 return static_cast<WidgetView<ISwitch> *>(IUFindSwitch(this, name));
1352}
1353
1354template <>
1356{
1357 return static_cast<WidgetView<ILight> *>(IUFindLight(this, name));
1358}
1359
1360template <>
1362{
1363 return static_cast<WidgetView<IBLOB> *>(IUFindBLOB(this, name));
1364}
1365
1366template <typename T>
1368{
1369 return this->p;
1370}
1371
1372template <>
1374{
1375 return IP_RO;
1376}
1377
1378template <typename T>
1380{
1381 return ISR_NOFMANY;
1382}
1383
1384template <>
1386{
1387 return this->r;
1388}
1389
1390template <typename T>
1391inline double PropertyView<T>::getTimeout() const
1392{
1393 return this->timeout;
1394}
1395
1396template <>
1398{
1399 return 0;
1400}
1401
1402template <>
1404{
1405 this->tp = w;
1406 this->ntp = int(size);
1407}
1408
1409template <>
1411{
1412 this->np = w;
1413 this->nnp = int(size);
1414}
1415
1416template <>
1418{
1419 this->sp = w;
1420 this->nsp = int(size);
1421}
1422
1423template <>
1425{
1426 this->lp = w;
1427 this->nlp = int(size);
1428}
1429
1430template <>
1432{
1433 this->bp = w;
1434 this->nbp = int(size);
1435}
1436
1437template <>
1439{
1440 return this->ntp;
1441}
1442
1443template <>
1445{
1446 return this->nnp;
1447}
1448
1449template <>
1451{
1452 return this->nsp;
1453}
1454
1455template <>
1457{
1458 return this->nlp;
1459}
1460
1461template <>
1463{
1464 return this->nbp;
1465}
1466
1467template <>
1469{
1470 return static_cast<WidgetType*>(this->tp);
1471}
1472
1473template <>
1475{
1476 return static_cast<WidgetType*>(this->np);
1477}
1478
1479template <>
1481{
1482 return static_cast<WidgetType*>(this->sp);
1483}
1484
1485template <>
1487{
1488 return static_cast<WidgetType*>(this->lp);
1489}
1490
1491template <>
1493{
1494 return static_cast<WidgetType*>(this->bp);
1495}
1496
1497}
hid_device * device
Class to provide basic INDI device functionality.
Definition basedevice.h:52
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
Provides generic container for INDI properties.
double max(void)
#define min(a, b)
Constants and Data structure definitions for the interface to the reference INDI C API implementation...
ISState
Switch state.
Definition indiapi.h:148
@ ISS_OFF
Definition indiapi.h:149
IPerm
Permission hint, with respect to client.
Definition indiapi.h:181
@ IP_RO
Definition indiapi.h:182
IPState
Property state.
Definition indiapi.h:158
@ IPS_OK
Definition indiapi.h:160
ISRule
Switch vector rule hint.
Definition indiapi.h:170
@ ISR_NOFMANY
Definition indiapi.h:173
int IUSnoopSwitch(XMLEle *root, ISwitchVectorProperty *svp)
Update a snooped switch vector property from the given XML root element.
Definition indidevapi.c:678
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition indidevapi.c:33
int IULoadConfigSwitch(const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition indidevapi.c:214
IText * IUFindText(const ITextVectorProperty *tvp, const char *name)
Find an IText member in a vector text property.
Definition indidevapi.c:265
const char * ruleStr(ISRule r)
Definition indidevapi.c:877
ILight * IUFindLight(const ILightVectorProperty *lvp, const char *name)
Find an ILight member in a vector Light property.
Definition indidevapi.c:295
int IULoadConfigNumber(const INumberVectorProperty *nvp)
Load a number vector property value from the configuration file.
Definition indidevapi.c:126
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
Definition indidevapi.c:337
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition indidevapi.c:366
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
Definition indidevapi.c:275
int IUSnoopBLOB(XMLEle *root, IBLOBVectorProperty *bvp)
Update a snooped BLOB vector property from the given XML root element.
Definition indidevapi.c:720
int IUSnoopLight(XMLEle *root, ILightVectorProperty *lvp)
Update a snooped light vector property from the given XML root element.
Definition indidevapi.c:636
ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
Find an ISwitch member in a vector switch property.
Definition indidevapi.c:285
void IUSaveConfigBLOB(FILE *fp, const IBLOBVectorProperty *bvp)
Add a BLOB vector property value to the configuration file.
Definition indidevapi.c:38
int IUSnoopText(XMLEle *root, ITextVectorProperty *tvp)
Update a snooped text vector property from the given XML root element.
Definition indidevapi.c:600
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition indidevapi.c:23
int IUSnoopNumber(XMLEle *root, INumberVectorProperty *nvp)
Update a snooped number vector property from the given XML root element.
Definition indidevapi.c:555
const char * sstateStr(ISState s)
Definition indidevapi.c:863
const char * permStr(IPerm p)
Definition indidevapi.c:893
IBLOB * IUFindBLOB(const IBLOBVectorProperty *bvp, const char *name)
Find an IBLOB member in a vector BLOB property.
Definition indidevapi.c:305
ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *svp)
Returns the first ON switch it finds in the vector switch property.
Definition indidevapi.c:317
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition indidevapi.c:28
int crackIPState(const char *str, IPState *ip)
Extract property state (Idle, OK, Busy, Alert) from the supplied string.
Definition indidevapi.c:793
const char * pstateStr(IPState s)
Definition indidevapi.c:845
int IULoadConfigText(const ITextVectorProperty *tvp)
Load a text vector property value from the configuration file.
Definition indidevapi.c:170
int crackISRule(const char *str, ISRule *ip)
Extract switch rule (OneOfMany, OnlyOne..etc) from the supplied string.
Definition indidevapi.c:832
int crackISState(const char *str, ISState *ip)
Extract switch state (On or Off) from the supplied string.
Definition indidevapi.c:808
Interface to the reference INDI C API device implementation on the Device Driver side.
#define ATTRIBUTE_FORMAT_PRINTF(A, B)
Definition indidevapi.h:140
#define PROPERTYVIEW_BASE_ACCESS
Namespace to encapsulate INDI client, drivers, and mediator classes.
WidgetView< ISwitch > WidgetViewSwitch
PropertyView< IBLOB > PropertyViewBlob
WidgetView< ILight > WidgetViewLight
WidgetView< IText > WidgetViewText
PropertyView< ISwitch > PropertyViewSwitch
PropertyView< ILight > PropertyViewLight
WidgetView< IBLOB > WidgetViewBlob
PropertyView< INumber > PropertyViewNumber
PropertyView< IText > PropertyViewText
WidgetView< INumber > WidgetViewNumber
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
uint16_t type
Definition pwc-ioctl.h:0
One Blob (Binary Large Object) descriptor.
One light descriptor.
Provides decorator for Low-Level IXXXVectorProperty/IXXX.
bool isNameMatch(const std::string &otherName) const
bool snoop(XMLEle *root)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPState state)
std::string findOnSwitchName() const
void setGroupName(const std::string &name)
const char * getRuleAsString() const
const char * getLabel() const
void void void apply() const
WidgetType * widget() const
bool isSwitchOn(const std::string &name) const
void setTimestamp(const std::string &timestamp)
const char * getName() const
bool isLabelMatch(const std::string &otherLabel) const
void setTimestamp(const char *timestamp)
void setDeviceName(const char *name)
IPState getState() const
int count() const
void setName(const char *name)
WidgetType * at(size_t index) const
PropertyType * cast()
double getTimeout() const
bool isUpdated(const ISState states[], const char *const names[], int n) const
bool update(const char *const texts[], const char *const names[], int n)
bool isNameMatch(const char *otherName) const
WidgetType * findOnSwitch() const
int findOnSwitchIndex() const
bool isUpdated(const double values[], const char *const names[], int n) const
void setTimeout(double timeout)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
bool setRule(const std::string &rule)
void setLabel(const std::string &label)
IPerm getPermission() const
void vdefine(const char *format, va_list args) const
const char * getTimestamp() const
void setPermission(IPerm permission)
void setAux(void *user)
bool isUpdated(const char *const texts[], const char *const names[], int n) const
void setDeviceName(const std::string &name)
bool update(const double values[], const char *const names[], int n)
bool update(const ISState states[], const char *const names[], int n)
const char * getStateAsString() const
void setState(IPState state)
void setRule(ISRule rule)
bool update(const int sizes[], const int blobsizes[], const char *const blobs[], const char *const formats[], const char *const names[], int n)
void save(FILE *f) const
void setGroupName(const char *name)
void * getAux() const
WidgetType * begin() const
void setWidgets(WidgetType(&w)[N])
void setLabel(const char *label)
const char * getDeviceName() const
typename WidgetTraits< T >::PropertyType PropertyType
WidgetType * findWidgetByName(const char *name) const
void setName(const std::string &name)
static PropertyView< T > * cast(PropertyType *raw)
typename std::enable_if< std::is_same< X, Needed >::value, bool >::type enable_if_is_same_t
const char * getPermissionAsString() const
void setWidgets(WidgetType *w, size_t count)
WidgetType * end() const
void vapply(const char *format, va_list args) const
const char * getGroupName() const
bool isLabelMatch(const char *otherLabel) const
static WidgetView< Type > * cast(Type *blob)
bool isNameMatch(const std::string &otherName) const
const char * getName() const
bool isNameMatch(const char *otherName) const
void setFormat(const std::string &format)
void fill(const std::string &name, const std::string &label, const std::string &format)
const char * getLabel() const
WidgetView(const WidgetView< Type > &other)
void setFormat(const char *format)
void setParent(IBLOBVectorProperty *parent)
void setLabel(const char *label)
bool isLabelMatch(const std::string &otherLabel) const
bool isLabelMatch(const char *otherLabel) const
WidgetView< Type > & operator=(WidgetView< Type > &&other)
void setName(const std::string &name)
WidgetView< Type > & operator=(const WidgetView< Type > &other)
WidgetView(WidgetView< Type > &&other)
void setName(const char *name)
const void * getBlob() const
const char * getFormat() const
std::string getBlobAsString() const
void setParent(PropertyView< Type > *parent)
void setLabel(const std::string &label)
bool isNameMatch(const char *otherName) const
bool isNameMatch(const std::string &otherName) const
void setName(const char *name)
const char * getStateAsString() const
void setLabel(const std::string &label)
WidgetView< Type > & operator=(WidgetView< Type > &&other)
void setParent(ILightVectorProperty *parent)
void setState(const IPState &state)
bool isLabelMatch(const char *otherLabel) const
WidgetView< Type > & operator=(const WidgetView< Type > &other)
const char * getName() const
bool setState(const std::string &state)
void setName(const std::string &name)
void setLabel(const char *label)
bool isLabelMatch(const std::string &otherLabel) const
WidgetView(const WidgetView< Type > &other)
const char * getLabel() const
WidgetView(WidgetView< Type > &&other)
void fill(const std::string &name, const std::string &&label, IPState state=IPS_OK)
void setParent(PropertyView< Type > *parent)
bool isNameMatch(const char *otherName) const
void setParent(INumberVectorProperty *parent)
WidgetView(WidgetView< Type > &&other)
const char * getName() const
void setName(const char *name)
void setMinMax(double min, double max)
bool isLabelMatch(const char *otherLabel) const
const char * getFormat() const
WidgetView< Type > & operator=(const WidgetView< Type > &other)
WidgetView< Type > & operator=(WidgetView< Type > &&other)
void setName(const std::string &name)
const char * getLabel() const
WidgetView(const WidgetView< Type > &other)
bool isNameMatch(const std::string &otherName) const
void setFormat(const std::string &format)
void setParent(PropertyView< Type > *parent)
void setLabel(const std::string &label)
void setFormat(const char *format)
void fill(const std::string &name, const std::string &label, const std::string &format, double min, double max, double step, double value)
bool isLabelMatch(const std::string &otherLabel) const
void setLabel(const char *label)
WidgetView< Type > & operator=(WidgetView< Type > &&other)
const char * getLabel() const
const char * getName() const
void setParent(PropertyView< Type > *parent)
void setParent(ISwitchVectorProperty *parent)
bool isNameMatch(const char *otherName) const
WidgetView(const WidgetView< Type > &other)
void setLabel(const char *label)
void fill(const std::string &name, const std::string &label, ISState state=ISS_OFF)
void setName(const char *name)
const char * getStateAsString() const
bool isLabelMatch(const std::string &otherLabel) const
bool setState(const std::string &state)
WidgetView< Type > & operator=(const WidgetView< Type > &other)
void setState(const ISState &state)
WidgetView(WidgetView< Type > &&other)
bool isNameMatch(const std::string &otherName) const
void setName(const std::string &name)
void setLabel(const std::string &label)
bool isLabelMatch(const char *otherLabel) const
void fill(const std::string &name, const std::string &label, const std::string &initialText)
WidgetView(const WidgetView< Type > &other)
bool isLabelMatch(const std::string &otherLabel) const
bool isNameMatch(const std::string &otherName) const
void setText(const char *text)
WidgetView< Type > & operator=(const WidgetView< Type > &other)
void setLabel(const std::string &label)
const char * getLabel() const
const char * getText() const
void setName(const char *name)
void setText(const std::string &text)
void setText(const char *text, size_t size)
void setParent(ITextVectorProperty *parent)
void setLabel(const char *label)
const char * getName() const
void setName(const std::string &name)
bool isLabelMatch(const char *otherLabel) const
WidgetView< Type > & operator=(WidgetView< Type > &&other)
void setParent(PropertyView< Type > *parent)
bool isNameMatch(const char *otherName) const
WidgetView(WidgetView< Type > &&other)
One number descriptor.
One switch descriptor.
One text descriptor.
Holds the connection type.
BLOB (Binary Large Object) vector property descriptor.
Definition indiapi.h:469
Light vector property descriptor.
Definition indiapi.h:415
Number vector property descriptor.
Definition indiapi.h:317
Switch vector property descriptor.
Definition indiapi.h:365
Text vector property descriptor.
Definition indiapi.h:244