1 /* 2 Copyright (C) 2021 by Pawel Soja <kernel32.pl@gmail.com> 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 25 #include "indidriver.h" // IUSaveConfigXXX (indicom.c) 26 27 #include "indiwidgetview.h" 28 29 #include <string> 30 #include <cstring> 31 #include <cstdarg> 32 #include <cstdlib> 33 #include <type_traits> 34 35 namespace INDI 36 { 37 38 template <typename> struct WidgetView; 39 template <typename> struct PropertyView; 40 41 #define PROPERTYVIEW_BASE_ACCESS public 42 // don't use direct access to low-level property 43 //#define PROPERTYVIEW_BASE_ACCESS protected // future 44 45 /** 46 * \class INDI::PropertyView and INDI::WidgetView 47 * \brief Provides decorator for Low-Level IXXXVectorProperty/IXXX 48 * 49 * INDI::PropertyView 50 * 51 * A class that will allow a easy transition to the new widget handling interface (future). 52 * - Use PropertyView<IText> instead of ITextVectorProperty 53 * - Use PropertyView<INumber> instead of INumberVectorProperty 54 * - Use PropertyView<ISwitch> instead of ISwitchVectorProperty 55 * - Use PropertyView<ILight> instead of ILightVectorProperty 56 * - Use PropertyView<IBLOB> instead of IBLOBVectorProperty 57 * 58 * The PropertyView<IXXX> class is compatible with low-level IXXXVectorProperty structures. 59 * 60 * INDI::WidgetView 61 * 62 * A class that will allow a easy transition to the new widget handling interface (future). 63 * - Use WidgetView<IText> instead of IText 64 * - Use WidgetView<INumber> instead of INumber 65 * - Use WidgetView<ISwitch> instead of ISwitch 66 * - Use WidgetView<ILight> instead of ILight 67 * - Use WidgetView<IBLOB> instead of IBLOB 68 * 69 * The WidgetView<IXXX> class is compatible with low-level IXXX structures. 70 */ 71 72 template <typename T> 73 struct PropertyView: PROPERTYVIEW_BASE_ACCESS WidgetTraits<T>::PropertyType 74 { 75 using Type = T; 76 using PropertyType = typename WidgetTraits<T>::PropertyType; 77 using WidgetType = WidgetView<T>; 78 79 friend class Property; 80 friend class PropertyPrivate; 81 friend class BaseDevice; 82 friend class DefaultDevice; 83 template <typename> 84 friend struct WidgetView; 85 86 template <typename X, typename Needed> 87 using enable_if_is_same_t = typename std::enable_if<std::is_same<X, Needed>::value, bool>::type; 88 public: 89 PropertyView(); 90 91 // #PS: do not delete items, they may be on the stack. 92 //~PropertyView() { for(auto &p: *this) {p.clear();} free(widget()); } 93 94 public: 95 void setDeviceName(const char *name); /* outside implementation */ 96 void setDeviceName(const std::string &name); /* outside implementation */ 97 98 void setName(const char *name); /* outside implementation */ 99 void setName(const std::string &name); /* outside implementation */ 100 101 void setLabel(const char *label); /* outside implementation */ 102 void setLabel(const std::string &label); /* outside implementation */ 103 104 void setGroupName(const char *name); /* outside implementation */ 105 void setGroupName(const std::string &name); /* outside implementation */ 106 107 void setPermission(IPerm permission); /* outside implementation */ 108 void setTimeout(double timeout); /* outside implementation */ 109 void setState(IPState state); 110 111 void setTimestamp(const char *timestamp); /* outside implementation */ 112 void setTimestamp(const std::string ×tamp); /* outside implementation */ 113 114 void setAux(void *user); /* outside implementation */ 115 void setWidgets(WidgetType *w, size_t count); /* outside implementation */ 116 117 template <size_t N> 118 void setWidgets(WidgetType (&w)[N]); /* outside implementation */ 119 120 public: // only for ISwitch 121 void setRule(ISRule rule); /* outside implementation */ 122 bool setRule(const std::string &rule); /* outside implementation */ 123 124 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true> resetPropertyView125 void reset() { IUResetSwitch(this); } 126 127 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true> findOnSwitchPropertyView128 WidgetType *findOnSwitch() const { return static_cast<WidgetType *>(IUFindOnSwitch(this)); } 129 130 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true> findOnSwitchIndexPropertyView131 int findOnSwitchIndex() const { return IUFindOnSwitchIndex(this); } 132 133 public: // only for INumber 134 template <typename X = T, enable_if_is_same_t<X, INumber> = true> 135 void updateMinMax(); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 136 137 public: //getters getDeviceNamePropertyView138 const char *getDeviceName() const { return this->device; } getNamePropertyView139 const char *getName() const { return this->name; } getLabelPropertyView140 const char *getLabel() const { return this->label; } getGroupNamePropertyView141 const char *getGroupName() const { return this->group; } 142 143 IPerm getPermission() const; /* outside implementation */ getPermissionAsStringPropertyView144 const char *getPermissionAsString() const { return permStr(getPermission()); } 145 146 ISRule getRule() const; /* outside implementation */ getRuleAsStringPropertyView147 const char * getRuleAsString() const { return ruleStr(getRule()); } 148 149 double getTimeout() const; /* outside implementation */ getStatePropertyView150 IPState getState() const { return this->s; } getStateAsStringPropertyView151 const char *getStateAsString() const { return pstateStr(getState()); } 152 getTimestampPropertyView153 const char *getTimestamp() const { return this->timestamp; } getAuxPropertyView154 void *getAux() const { return this->aux; } 155 156 int count() const; /* outside implementation */ 157 WidgetType *widget() const; /* outside implementation */ 158 159 WidgetType *findWidgetByName(const char *name) const; /* outside implementation */ 160 161 public: //tests isEmptyPropertyView162 bool isEmpty() const { return widget() == nullptr || count() == 0; } 163 isNameMatchPropertyView164 bool isNameMatch(const char *otherName) const { return !strcmp(getName(), otherName); } isNameMatchPropertyView165 bool isNameMatch(const std::string &otherName) const { return getName() == otherName; } 166 isLabelMatchPropertyView167 bool isLabelMatch(const char *otherLabel) const { return !strcmp(getLabel(), otherLabel); } isLabelMatchPropertyView168 bool isLabelMatch(const std::string &otherLabel) const { return getLabel() == otherLabel; } 169 170 public: // only driver side 171 void save(FILE *f) const; /* outside implementation */ 172 173 void vapply(const char *format, va_list args) const; /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 174 void vdefine(const char *format, va_list args) const; /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 175 176 void apply(const char *format, ...) const ATTRIBUTE_FORMAT_PRINTF(2, 3); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 177 void define(const char *format, ...) const ATTRIBUTE_FORMAT_PRINTF(2, 3); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 178 applyPropertyView179 void apply() const { apply(nullptr); } definePropertyView180 void define() const { define(nullptr); } 181 182 public: 183 template <typename X = T, enable_if_is_same_t<X, IText> = true> 184 void fill( 185 const char *device, const char *name, const char *label, const char *group, 186 IPerm permission, double timeout, IPState state 187 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 188 189 template <typename X = T, enable_if_is_same_t<X, INumber> = true> 190 void fill( 191 const char *device, const char *name, const char *label, const char *group, 192 IPerm permission, double timeout, IPState state 193 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 194 195 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true> 196 void fill( 197 const char *device, const char *name, const char *label, const char *group, 198 IPerm permission, ISRule rule, double timeout, IPState state 199 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 200 201 template <typename X = T, enable_if_is_same_t<X, ILight> = true> 202 void fill( 203 const char *device, const char *name, const char *label, const char *group, 204 IPState state 205 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 206 207 template <typename X = T, enable_if_is_same_t<X, IBLOB> = true> 208 void fill( 209 const char *device, const char *name, const char *label, const char *group, 210 IPerm permission, double timeout, IPState state 211 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 212 213 public: 214 template <typename X = T, enable_if_is_same_t<X, IText> = true> 215 bool update(const char * const texts[], const char * const names[], int n); 216 /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 217 218 template <typename X = T, enable_if_is_same_t<X, INumber> = true> 219 bool update(const double values[], const char * const names[], int n); 220 /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 221 222 template <typename X = T, enable_if_is_same_t<X, ISwitch> = true> 223 bool update(const ISState states[], const char * const names[], int n); 224 /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 225 226 /* 227 template <typename X = T, enable_if_is_same_t<X, ILight> = true> 228 bool update(..., const char * const names[], int n); 229 */ 230 231 template <typename X = T, enable_if_is_same_t<X, IBLOB> = true> 232 bool update( 233 const int sizes[], const int blobsizes[], const char * const blobs[], const char * const formats[], 234 const char * const names[], int n 235 ); /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 236 237 238 public: beginPropertyView239 WidgetType *begin() const { return widget(); } endPropertyView240 WidgetType *end() const { return widget() + count(); } 241 atPropertyView242 WidgetType *at(size_t index) const { return widget() + index; } 243 public: clearPropertyView244 void clear() 245 { 246 for(auto &p: *this) { p.clear(); } 247 //free(widget()); // #PS: do not delete items, they may be on the stack. 248 memset(this, 0, sizeof(*this)); 249 } 250 }; 251 252 template <typename> 253 struct WidgetView; 254 255 template <> 256 struct WidgetView<IText>: PROPERTYVIEW_BASE_ACCESS IText 257 { 258 using Type = IText; 259 template <typename> friend struct PropertyView; 260 261 public: 262 WidgetView() { memset(this, 0, sizeof(*this)); } 263 WidgetView(const WidgetView &other): Type(other) { this->text = nullptr; setText(other.text); } 264 WidgetView(WidgetView &&other): Type(other) { memset(static_cast<Type*>(&other), 0, sizeof(other)); } 265 WidgetView &operator=(const WidgetView &other) { return *this = WidgetView(other); } 266 WidgetView &operator=(WidgetView &&other) { std::swap(static_cast<Type&>(other), static_cast<Type&>(*this)); return *this; } 267 ~WidgetView() { free(this->text); } 268 void clear() { free(this->text); memset(this, 0, sizeof(*this)); } 269 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; } 270 271 public: // setters 272 void setParent(ITextVectorProperty *parent) { this->tvp = parent; } 273 void setParent(PropertyView<Type> *parent) { this->tvp = static_cast<ITextVectorProperty*>(parent); } 274 275 void setName(const char *name) { strncpy(this->name, name, MAXINDINAME); } 276 void setName(const std::string &name) { setName(name.data()); } 277 278 void setLabel(const char *label) { strncpy(this->label, label, MAXINDILABEL); } 279 void setLabel(const std::string &label) { setLabel(label.data()); } 280 281 //void setText(const char *text) { free(this->text); this->text = strndup(text, strlen(text)); } 282 void setText(const char *text, size_t size) { this->text = strncpy(static_cast<char*>(realloc(this->text, size + 1)), text, size); this->text[size] = '\0'; } 283 void setText(const char *text) { setText(text, strlen(text)); } 284 void setText(const std::string &text) { setText(text.data(), text.size()); } 285 286 void setAux(void *user) { this->aux0 = user; } 287 // don't use any other aux! 288 289 public: //getters 290 const char *getName() const { return this->name; } 291 const char *getLabel() const { return this->label; } 292 const char *getText() const { return this->text; } 293 294 void *getAux() const { return this->aux0; } 295 296 public: //tests 297 bool isNameMatch(const char *otherName) const { return !strcmp(getName(), otherName); } 298 bool isNameMatch(const std::string &otherName) const { return getName() == otherName; } 299 300 bool isLabelMatch(const char *otherLabel) const { return !strcmp(getLabel(), otherLabel); } 301 bool isLabelMatch(const std::string &otherLabel) const { return getLabel() == otherLabel; } 302 303 public: 304 void fill(const char *name, const char *label, const char *initialText) 305 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 306 307 void fill(const std::string &name, const std::string &label, const std::string &initialText) 308 { fill(name.c_str(), label.c_str(), initialText.c_str()); } 309 }; 310 311 template <> 312 struct WidgetView<INumber>: PROPERTYVIEW_BASE_ACCESS INumber 313 { 314 using Type = INumber; 315 template <typename> friend struct PropertyView; 316 317 public: 318 WidgetView() { memset(this, 0, sizeof(*this)); } 319 WidgetView(const WidgetView &other): Type(other) { } 320 WidgetView(WidgetView &&other): Type(other) { memset(static_cast<Type*>(&other), 0, sizeof(other)); } 321 WidgetView &operator=(const WidgetView &other) { return *this = WidgetView(other); } 322 WidgetView &operator=(WidgetView &&other) { std::swap(static_cast<Type&>(other), static_cast<Type&>(*this)); return *this; } 323 ~WidgetView() { } 324 void clear() { memset(this, 0, sizeof(*this)); } 325 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; } 326 327 public: // setters 328 void setParent(INumberVectorProperty *parent) { this->nvp = parent; } 329 void setParent(PropertyView<Type> *parent) { this->nvp = static_cast<INumberVectorProperty*>(parent); } 330 331 void setName(const char *name) { strncpy(this->name, name, MAXINDINAME); } 332 void setName(const std::string &name) { setName(name.data()); } 333 334 void setLabel(const char *label) { strncpy(this->label, label, MAXINDILABEL); } 335 void setLabel(const std::string &label) { setLabel(label.data()); } 336 337 void setFormat(const char *format) { strncpy(this->format, format, MAXINDIFORMAT); } 338 void setFormat(const std::string &format) { setLabel(format.data()); } 339 340 void setMin(double min) { this->min = min; } 341 void setMax(double max) { this->max = max; } 342 void setMinMax(double min, double max) { setMin(min); setMax(max); } 343 void setStep(double step) { this->step = step; } 344 void setValue(double value) { this->value = value; } 345 346 void setAux(void *user) { this->aux0 = user; } 347 // don't use any other aux! 348 349 public: //getters 350 const char *getName() const { return this->name; } 351 const char *getLabel() const { return this->label; } 352 const char *getFormat() const { return this->format; } 353 354 double getMin() const { return this->min; } 355 double getMax() const { return this->max; } 356 double getStep() const { return this->step; } 357 double getValue() const { return this->value; } 358 359 void *getAux() const { return this->aux0; } 360 361 public: //tests 362 bool isNameMatch(const char *otherName) const { return !strcmp(getName(), otherName); } 363 bool isNameMatch(const std::string &otherName) const { return getName() == otherName; } 364 365 bool isLabelMatch(const char *otherLabel) const { return !strcmp(getLabel(), otherLabel); } 366 bool isLabelMatch(const std::string &otherLabel) const { return getLabel() == otherLabel; } 367 368 public: 369 void fill(const char *name, const char *label, const char *format, 370 double min, double max, double step, double value) 371 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 372 373 void fill(const std::string &name, const std::string &label, const std::string &format, 374 double min, double max, double step, double value) 375 { fill(name.c_str(), label.c_str(), format.c_str(), min, max, step, value); } 376 }; 377 378 template <> 379 struct WidgetView<ISwitch>: PROPERTYVIEW_BASE_ACCESS ISwitch 380 { 381 using Type = ISwitch; 382 template <typename> friend struct PropertyView; 383 384 public: 385 WidgetView() { memset(this, 0, sizeof(*this)); } 386 WidgetView(const WidgetView &other): Type(other) { } 387 WidgetView(WidgetView &&other): Type(other) { memset(static_cast<Type*>(&other), 0, sizeof(other)); } 388 WidgetView &operator=(const WidgetView &other) { return *this = WidgetView(other); } 389 WidgetView &operator=(WidgetView &&other) { std::swap(static_cast<Type&>(other), static_cast<Type&>(*this)); return *this; } 390 ~WidgetView() { } 391 void clear() { memset(this, 0, sizeof(*this)); } 392 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; } 393 394 public: // setters 395 void setParent(ISwitchVectorProperty *parent) { this->svp = parent; } 396 void setParent(PropertyView<Type> *parent) { this->svp = static_cast<ISwitchVectorProperty*>(parent); } 397 398 void setName(const char *name) { strncpy(this->name, name, MAXINDINAME); } 399 void setName(const std::string &name) { setName(name.data()); } 400 401 void setLabel(const char *label) { strncpy(this->label, label, MAXINDILABEL); } 402 void setLabel(const std::string &label) { setLabel(label.data()); } 403 404 void setState(const ISState &state) { this->s = state; } 405 bool setState(const std::string &state) { return crackISState(state.data(), &this->s) == 0; } 406 407 void setAux(void *user) { this->aux = user; } 408 // don't use any other aux! 409 410 public: //getters 411 const char *getName() const { return this->name; } 412 const char *getLabel() const { return this->label; } 413 414 ISState getState() const { return this->s; } 415 const char *getStateAsString() const { return sstateStr(getState()); } 416 417 void *getAux() const { return this->aux; } 418 419 420 public: //tests 421 bool isNameMatch(const char *otherName) const { return !strcmp(getName(), otherName); } 422 bool isNameMatch(const std::string &otherName) const { return getName() == otherName; } 423 424 bool isLabelMatch(const char *otherLabel) const { return !strcmp(getLabel(), otherLabel); } 425 bool isLabelMatch(const std::string &otherLabel) const { return getLabel() == otherLabel; } 426 427 public: 428 void fill(const char *name, const char *label, ISState state = ISS_OFF) 429 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 430 431 void fill(const std::string &name, const std::string &label, ISState state = ISS_OFF) 432 { fill(name.c_str(), label.c_str(), state); } 433 }; 434 435 template <> 436 struct WidgetView<ILight>: PROPERTYVIEW_BASE_ACCESS ILight 437 { 438 using Type = ILight; 439 template <typename> friend struct PropertyView; 440 441 public: 442 WidgetView() { memset(this, 0, sizeof(*this)); } 443 WidgetView(const WidgetView &other): Type(other) { } 444 WidgetView(WidgetView &&other): Type(other) { memset(static_cast<Type*>(&other), 0, sizeof(other)); } 445 WidgetView &operator=(const WidgetView &other) { return *this = WidgetView(other); } 446 WidgetView &operator=(WidgetView &&other) { std::swap(static_cast<Type&>(other), static_cast<Type&>(*this)); return *this; } 447 ~WidgetView() { } 448 void clear() { memset(this, 0, sizeof(*this)); } 449 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; } 450 451 public: // setters 452 void setParent(ILightVectorProperty *parent) { this->lvp = parent; } 453 void setParent(PropertyView<Type> *parent) { this->lvp = static_cast<ILightVectorProperty*>(parent); } 454 455 void setName(const char *name) { strncpy(this->name, name, MAXINDINAME); } 456 void setName(const std::string &name) { setName(name.data()); } 457 458 void setLabel(const char *label) { strncpy(this->label, label, MAXINDILABEL); } 459 void setLabel(const std::string &label) { setLabel(label.data()); } 460 461 void setState(const IPState &state) { this->s = state; } 462 bool setState(const std::string &state) { return crackIPState(state.data(), &this->s) == 0; } 463 464 void setAux(void *user) { this->aux = user; } 465 // don't use any other aux! 466 467 public: //getters 468 const char *getName() const { return this->name; } 469 const char *getLabel() const { return this->label; } 470 471 IPState getState() const { return this->s; } 472 const char *getStateAsString() const { return pstateStr(getState()); } 473 474 void *getAux() const { return this->aux; } 475 476 477 public: //tests 478 bool isNameMatch(const char *otherName) const { return !strcmp(getName(), otherName); } 479 bool isNameMatch(const std::string &otherName) const { return getName() == otherName; } 480 481 bool isLabelMatch(const char *otherLabel) const { return !strcmp(getLabel(), otherLabel); } 482 bool isLabelMatch(const std::string &otherLabel) const { return getLabel() == otherLabel; } 483 484 public: 485 void fill(const char *name, const char *label, IPState state = IPS_OK) 486 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 487 488 void fill(const std::string &name, const std::string &&label, IPState state = IPS_OK) 489 { fill(name.c_str(), label.c_str(), state); } 490 }; 491 492 template <> 493 struct WidgetView<IBLOB>: PROPERTYVIEW_BASE_ACCESS IBLOB 494 { 495 using Type = IBLOB; 496 template <typename> friend struct PropertyView; 497 498 public: 499 WidgetView() { memset(this, 0, sizeof(*this)); } 500 WidgetView(const WidgetView &other): Type(other) { } 501 WidgetView(WidgetView &&other): Type(other) { memset(static_cast<Type*>(&other), 0, sizeof(other)); } 502 WidgetView &operator=(const WidgetView &other) { return *this = WidgetView(other); } 503 WidgetView &operator=(WidgetView &&other) { std::swap(static_cast<Type&>(other), static_cast<Type&>(*this)); return *this; } 504 ~WidgetView() { /* free(this->blob); */ } 505 void clear() { /* free(this->blob); */ memset(this, 0, sizeof(*this)); } 506 // bool isNull() const { return reinterpret_cast<const void*>(this) == nullptr; } 507 508 public: // setters 509 void setParent(IBLOBVectorProperty *parent) { this->bvp = parent; } 510 void setParent(PropertyView<Type> *parent) { this->bvp = static_cast<IBLOBVectorProperty*>(parent); } 511 512 void setName(const char *name) { strncpy(this->name, name, MAXINDINAME); } 513 void setName(const std::string &name) { setName(name.data()); } 514 515 void setLabel(const char *label) { strncpy(this->label, label, MAXINDILABEL); } 516 void setLabel(const std::string &label) { setLabel(label.data()); } 517 518 void setFormat(const char *format) { strncpy(this->format, format, MAXINDIBLOBFMT); } 519 void setFormat(const std::string &format) { setLabel(format.data()); } 520 521 void setBlob(void *blob) { this->blob = blob; } 522 void setBlobLen(int size) { this->bloblen = size; } 523 void setSize(int size) { this->size = size; } 524 525 void setAux(void *user) { this->aux0 = user; } 526 // don't use any other aux! 527 528 public: //getters 529 const char *getName() const { return this->name; } 530 const char *getLabel() const { return this->label; } 531 const char *getFormat() const { return this->format; } 532 533 const void *getBlob() const { return this->blob; } 534 int getBlobLen() const { return this->bloblen; } 535 int getSize() const { return this->size; } 536 537 void *getAux() const { return this->aux0; } 538 539 public: //tests 540 bool isNameMatch(const char *otherName) const { return !strcmp(getName(), otherName); } 541 bool isNameMatch(const std::string &otherName) const { return getName() == otherName; } 542 543 bool isLabelMatch(const char *otherLabel) const { return !strcmp(getLabel(), otherLabel); } 544 bool isLabelMatch(const std::string &otherLabel) const { return getLabel() == otherLabel; } 545 546 public: 547 void fill(const char *name, const char *label, const char *format) 548 ; /* outside implementation - only driver side, see indipropertyview_driver.cpp */ 549 550 void fill(const std::string &name, const std::string &label, const std::string &format) 551 { fill(name.c_str(), label.c_str(), format.c_str()); } 552 }; 553 554 555 556 557 /* outside implementation */ 558 template <typename T> 559 inline PropertyView<T>::PropertyView() 560 { memset(this, 0, sizeof(*this)); } 561 562 template <typename T> 563 inline void PropertyView<T>::setDeviceName(const char *name) 564 { strncpy(this->device, name, MAXINDIDEVICE); } 565 566 template <typename T> 567 inline void PropertyView<T>::setDeviceName(const std::string &name) 568 { setDeviceName(name.data()); } 569 570 template <typename T> 571 inline void PropertyView<T>::setName(const char *name) 572 { strncpy(this->name, name, MAXINDINAME); } 573 574 template <typename T> 575 inline void PropertyView<T>::setName(const std::string &name) 576 { setName(name.data()); } 577 578 template <typename T> 579 inline void PropertyView<T>::setLabel(const char *label) 580 { strncpy(this->label, label, MAXINDILABEL); } 581 582 template <typename T> 583 inline void PropertyView<T>::setLabel(const std::string &label) 584 { setLabel(label.data()); } 585 586 template <typename T> 587 inline void PropertyView<T>::setGroupName(const char *name) 588 { strncpy(this->group, name, MAXINDIGROUP); } 589 590 template <typename T> 591 inline void PropertyView<T>::setGroupName(const std::string &name) 592 { setGroupName(name.data()); } 593 594 template <typename T> 595 inline void PropertyView<T>::setState(IPState state) 596 { this->s = state; } 597 598 template <typename T> 599 inline void PropertyView<T>::setTimestamp(const char *timestamp) 600 { strncpy(this->timestamp, timestamp, MAXINDITSTAMP); } 601 602 template <typename T> 603 inline void PropertyView<T>::setTimestamp(const std::string ×tamp) 604 { setTimestamp(timestamp.data()); } 605 606 template <typename T> 607 template <size_t N> 608 inline void PropertyView<T>::setWidgets(WidgetType (&w)[N]) 609 { setWidgets(static_cast<WidgetType*>(w), N); } 610 611 template <typename T> 612 inline void PropertyView<T>::setAux(void *user) 613 { this->aux = user; } 614 615 template <> 616 inline void PropertyView<IText>::save(FILE *f) const 617 { IUSaveConfigText(f, this); } 618 619 template <> 620 inline void PropertyView<INumber>::save(FILE *f) const 621 { IUSaveConfigNumber(f, this); } 622 623 template <> 624 inline void PropertyView<ISwitch>::save(FILE *f) const 625 { IUSaveConfigSwitch(f, this); } 626 627 template <> 628 inline void PropertyView<ILight>::save(FILE *f) const 629 { (void)f; /* IUSaveConfigLight(f, this); */ } 630 631 template <> 632 inline void PropertyView<IBLOB>::save(FILE *f) const 633 { IUSaveConfigBLOB(f, this); } 634 635 template <typename T> 636 inline void PropertyView<T>::setTimeout(double timeout) 637 { this->timeout = timeout; } 638 639 template <> 640 inline void PropertyView<ILight>::setTimeout(double) 641 { } 642 643 template <typename T> 644 inline void PropertyView<T>::setPermission(IPerm permission) 645 { this->p = permission; } 646 647 template <> 648 inline void PropertyView<ILight>::setPermission(IPerm) 649 { } 650 651 template <typename T> 652 inline void PropertyView<T>::setRule(ISRule) 653 { } 654 655 template <> 656 inline void PropertyView<ISwitch>::setRule(ISRule rule) 657 { this->r = rule; } 658 659 template <typename T> 660 inline bool PropertyView<T>::setRule(const std::string &) 661 { return false; } 662 663 template <> 664 inline bool PropertyView<ISwitch>::setRule(const std::string &rule) 665 { return crackISRule(rule.data(), &this->r) == 0; } 666 667 template <typename T> 668 inline WidgetView<T> *PropertyView<T>::findWidgetByName(const char *) const 669 { return nullptr; } 670 671 template <> 672 inline WidgetView<IText> *PropertyView<IText>::findWidgetByName(const char *name) const 673 { return static_cast<WidgetView<IText> *>(IUFindText(this, name)); } 674 675 template <> 676 inline WidgetView<INumber> *PropertyView<INumber>::findWidgetByName(const char *name) const 677 { return static_cast<WidgetView<INumber> *>(IUFindNumber(this, name)); } 678 679 template <> 680 inline WidgetView<ISwitch> *PropertyView<ISwitch>::findWidgetByName(const char *name) const 681 { return static_cast<WidgetView<ISwitch> *>(IUFindSwitch(this, name)); } 682 683 template <> 684 inline WidgetView<ILight> *PropertyView<ILight>::findWidgetByName(const char *name) const 685 { return static_cast<WidgetView<ILight> *>(IUFindLight(this, name)); } 686 687 template <> 688 inline WidgetView<IBLOB> *PropertyView<IBLOB>::findWidgetByName(const char *name) const 689 { return static_cast<WidgetView<IBLOB> *>(IUFindBLOB(this, name)); } 690 691 template <typename T> 692 inline IPerm PropertyView<T>::getPermission() const 693 { return this->p; } 694 695 template <> 696 inline IPerm PropertyView<ILight>::getPermission() const 697 { return IP_RO; } 698 699 template <typename T> 700 inline ISRule PropertyView<T>::getRule() const 701 { return ISR_NOFMANY; } 702 703 template <> 704 inline ISRule PropertyView<ISwitch>::getRule() const 705 { return this->r; } 706 707 template <typename T> 708 inline double PropertyView<T>::getTimeout() const 709 { return this->timeout; } 710 711 template <> 712 inline double PropertyView<ILight>::getTimeout() const 713 { return 0; } 714 715 template <> 716 inline void PropertyView<IText>::setWidgets(WidgetType *w, size_t size) 717 { this->tp = w; this->ntp = size; } 718 719 template <> 720 inline void PropertyView<INumber>::setWidgets(WidgetType *w, size_t size) 721 { this->np = w; this->nnp = size; } 722 723 template <> 724 inline void PropertyView<ISwitch>::setWidgets(WidgetType *w, size_t size) 725 { this->sp = w; this->nsp = size; } 726 727 template <> 728 inline void PropertyView<ILight>::setWidgets(WidgetType *w, size_t size) 729 { this->lp = w; this->nlp = size; } 730 731 template <> 732 inline void PropertyView<IBLOB>::setWidgets(WidgetType *w, size_t size) 733 { this->bp = w; this->nbp = size; } 734 735 template <> 736 inline int PropertyView<IText>::count() const 737 { return this->ntp; } 738 739 template <> 740 inline int PropertyView<INumber>::count() const 741 { return this->nnp; } 742 743 template <> 744 inline int PropertyView<ISwitch>::count() const 745 { return this->nsp; } 746 747 template <> 748 inline int PropertyView<ILight>::count() const 749 { return this->nlp; } 750 751 template <> 752 inline int PropertyView<IBLOB>::count() const 753 { return this->nbp; } 754 755 template <> 756 inline PropertyView<IText>::WidgetType *PropertyView<IText>::widget() const 757 { return static_cast<WidgetType*>(this->tp); } 758 759 template <> 760 inline PropertyView<INumber>::WidgetType *PropertyView<INumber>::widget() const 761 { return static_cast<WidgetType*>(this->np); } 762 763 template <> 764 inline PropertyView<ISwitch>::WidgetType *PropertyView<ISwitch>::widget() const 765 { return static_cast<WidgetType*>(this->sp); } 766 767 template <> 768 inline PropertyView<ILight>::WidgetType *PropertyView<ILight>::widget() const 769 { return static_cast<WidgetType*>(this->lp); } 770 771 template <> 772 inline PropertyView<IBLOB>::WidgetType *PropertyView<IBLOB>::widget() const 773 { return static_cast<WidgetType*>(this->bp); } 774 775 } 776