1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef C2UTILS_INTERFACE_HELPER_H_ 18 #define C2UTILS_INTERFACE_HELPER_H_ 19 20 #include <C2Component.h> 21 #include <util/C2InterfaceUtils.h> 22 23 #include <map> 24 #include <mutex> 25 #include <vector> 26 27 #include <stddef.h> 28 29 /** 30 * Interface Helper 31 */ 32 using C2R = C2SettingResultsBuilder; 33 34 template<typename T, bool E=std::is_enum<T>::value> 35 struct _c2_reduce_enum_to_underlying_type { 36 typedef T type; 37 }; 38 39 template<typename T> 40 struct _c2_reduce_enum_to_underlying_type<T, true> { 41 typedef typename std::underlying_type<T>::type type; 42 }; 43 44 /** 45 * Helper class to implement parameter reflectors. This class is dynamic and is designed to be 46 * shared by multiple interfaces. This allows interfaces to add structure descriptors as needed. 47 */ 48 class C2ReflectorHelper : public C2ParamReflector { 49 public: 50 C2ReflectorHelper() = default; 51 virtual ~C2ReflectorHelper() = default; 52 virtual std::unique_ptr<C2StructDescriptor> describe( 53 C2Param::CoreIndex paramIndex) const override; 54 55 /** 56 * Adds support for describing the given parameters. 57 * 58 * \param Params types of codec 2.0 structs (or parameters) to describe 59 */ 60 template<typename... Params> 61 C2_INLINE void addStructDescriptors() { 62 std::vector<C2StructDescriptor> structs; 63 addStructDescriptors(structs, (_Tuple<Params...> *)nullptr); 64 } 65 66 /** 67 * Adds support for describing a specific struct. 68 * 69 * \param strukt descriptor for the struct that will be moved out. 70 */ 71 void addStructDescriptor(C2StructDescriptor &&strukt); 72 73 private: 74 template<typename... Params> 75 class C2_HIDE _Tuple { }; 76 77 /** 78 * Adds support for describing the given descriptors. 79 * 80 * \param structs List of structure descriptors to add support for 81 */ 82 void addStructDescriptors( 83 std::vector<C2StructDescriptor> &structs, _Tuple<> *); 84 85 /** 86 * Utility method that adds support for describing the given descriptors in a recursive manner 87 * one structure at a time using a list of structure descriptors temporary. 88 * 89 * \param T the type of codec 2.0 struct to describe 90 * \param Params rest of the structs 91 * \param structs Temporary list of structure descriptors used to optimize the operation. 92 */ 93 template<typename T, typename... Params> 94 C2_INLINE void addStructDescriptors( 95 std::vector<C2StructDescriptor> &structs, _Tuple<T, Params...> *) { 96 structs.emplace_back((T*)nullptr); 97 addStructDescriptors(structs, (_Tuple<Params...> *)nullptr); 98 } 99 100 mutable std::mutex _mMutex; 101 std::map<C2Param::CoreIndex, const C2StructDescriptor> _mStructs; ///< descriptors 102 }; 103 104 /** 105 * Utility class that implements the codec 2.0 interface API-s for some parameters. 106 * 107 * This class must be subclassed. 108 */ 109 class C2InterfaceHelper { 110 public: 111 /** 112 * Returns the base offset of a field at |offset| that could be part of an array or part of a 113 * sub-structure. 114 * 115 * This method does not do field size verification, e.g. if offset if obtained from a structure, 116 * it will not stop at the structure boundary - this is okay, as we just want the base offset 117 * here, which is the same. 118 */ 119 static 120 size_t GetBaseOffset(const std::shared_ptr<C2ParamReflector> &reflector, 121 C2Param::CoreIndex index, size_t offset); 122 123 /** 124 * The interface helper class uses references to std::shared_ptr<T> config parameters. 125 * Internally, these need to be generalized to std::shared_ptr<C2Param> refs, but the cast is 126 * not allowed (as these are references). As such, this class never returns pointer to the 127 * shared_ptrs. 128 */ 129 struct ParamRef { 130 template<typename T, typename enable= 131 typename std::enable_if<std::is_convertible<T, C2Param>::value>::type> 132 inline C2_HIDE ParamRef(std::shared_ptr<T> ¶m) 133 : _mRef(reinterpret_cast<std::shared_ptr<C2Param>*>(¶m)) { } 134 135 // used by comparison operator for containers 136 operator std::shared_ptr<C2Param> *() const { return _mRef; } 137 138 /** 139 * Returns a shared pointer to the parameter. 140 */ 141 std::shared_ptr<C2Param> get() const { return *_mRef; } 142 143 private: 144 std::shared_ptr<C2Param> *_mRef; 145 }; 146 147 /** 148 * Field helper. 149 * 150 * Contains additional information for the field: possible values, and currently supported 151 * values. 152 */ 153 class FieldHelper { 154 public: 155 /** 156 * Creates helper for a field with given possible values. 157 * 158 * \param param parameter reference. The parameter does not have to be initialized at this 159 * point. 160 * \param field field identifier 161 * \param values possible values for the field 162 */ 163 FieldHelper(const ParamRef ¶m, const _C2FieldId &field, 164 std::unique_ptr<C2FieldSupportedValues> &&values); 165 166 /** 167 * Creates a param-field identifier for this field. This method is called after the 168 * underlying parameter has been initialized. 169 * 170 * \aram index 171 * 172 * @return C2ParamField 173 */ 174 C2ParamField makeParamField(C2Param::Index index) const; 175 176 /** 177 * Sets the currently supported values for this field. 178 * 179 * \param values currently supported values that will be moved out 180 */ 181 void setSupportedValues(std::unique_ptr<C2FieldSupportedValues> &&values); 182 183 /** 184 * Gets the currently supported values for this field. This defaults to the possible values 185 * if currently supported values were never set. 186 */ 187 const C2FieldSupportedValues *getSupportedValues() const; 188 189 /** 190 * Gets the possible values for this field. 191 */ 192 const C2FieldSupportedValues *getPossibleValues() const; 193 194 protected: 195 // TODO: move to impl for safety 196 ParamRef mParam; 197 _C2FieldId mFieldId; 198 std::unique_ptr<C2FieldSupportedValues> mPossible; 199 std::unique_ptr<C2FieldSupportedValues> mSupported; ///< if different from possible 200 }; 201 202 template<typename T> 203 struct C2_HIDE Param; 204 class ParamHelper; 205 206 /** 207 * Factory is an interface to get the parameter helpers from a std::shared_ptr<T> &. 208 */ 209 class Factory { 210 // \todo this may be already in ParamHelper 211 virtual std::shared_ptr<C2ParamReflector> getReflector() const = 0; 212 213 virtual std::shared_ptr<ParamHelper> getParamHelper(const ParamRef ¶m) const = 0; 214 215 public: 216 virtual ~Factory() = default; 217 218 template<typename T> 219 Param<T> get(std::shared_ptr<T> ¶m, std::shared_ptr<T> altValue = nullptr) const { 220 return Param<T>(getParamHelper(ParamRef(param)), 221 altValue == nullptr ? param : altValue, 222 getReflector()); 223 } 224 }; 225 226 /** 227 * Typed field helper. 228 */ 229 template<typename T> 230 struct Field { 231 /** 232 * Constructor. 233 * 234 * \param helper helper for this field 235 * \param index parameter index (this is needed as it is not available during parameter 236 * construction) \todo remove 237 */ 238 Field(std::shared_ptr<FieldHelper> helper, C2Param::Index index); 239 240 bool supportsAtAll(T value) const { 241 return C2FieldSupportedValuesHelper<T>(*_mHelper->getPossibleValues()).supports(value); 242 } 243 244 bool supportsNow(T value) const { 245 return C2FieldSupportedValuesHelper<T>(*_mHelper->getSupportedValues()).supports(value); 246 } 247 248 /** 249 * Creates a conflict resolution suggestion builder for this field. 250 */ 251 C2ParamFieldValuesBuilder<T> shouldBe() const; 252 253 /** 254 * Creates a currently supported values builder for this field. This is only supported 255 * for non-const fields to disallow setting supported values for dependencies. 256 */ 257 C2ParamFieldValuesBuilder<T> mustBe(); 258 259 operator C2ParamField() const { 260 return _mField; 261 } 262 263 // TODO 264 C2R validatePossible(const T &value __unused) const { 265 /// TODO 266 return C2R::Ok(); 267 } 268 269 private: 270 std::shared_ptr<FieldHelper> _mHelper; 271 C2ParamField _mField; 272 }; 273 274 class ParamHelper { 275 public: 276 ParamHelper(ParamRef param, C2StringLiteral name, C2StructDescriptor &&); 277 ParamHelper(ParamHelper &&); 278 ~ParamHelper(); 279 280 /** 281 * Finds a field descriptor. 282 */ 283 std::shared_ptr<FieldHelper> findField(size_t baseOffs, size_t baseSize) const; 284 285 /// returns the parameter ref for this parameter 286 const ParamRef ref() const; 287 288 /// returns the current value of this parameter as modifiable. The constness of this 289 /// object determines the constness of the returned value. 290 std::shared_ptr<C2Param> value(); 291 292 /// returns the current value of this parameter as const 293 std::shared_ptr<const C2Param> value() const; 294 295 /** 296 * Performs a configuration change request for this parameter. 297 * 298 * \param value the value that is being assigned to this parameter. 299 * This could be pointing to the current value of the 300 * parameter. This must not change. 301 * \param mayBlock whether blocking is allowed 302 * \param endValue the resulting value 303 * \param factory parameter factory (to access dependencies) 304 * \param failures vector of failures to append any failures from this 305 * operation 306 * 307 * \retval C2_OK configuration was successful 308 * \retval C2_BAD_VALUE value is incorrect (TBD) 309 * \retval C2_NO_MEMORY not enough memory to perform the assignment 310 * \retval C2_TIMED_OUT configuration timed out 311 * \retval C2_BLOCKING configuration requires blocking to be allowed 312 * \retval C2_CORRUPTED interface is corrupted 313 */ 314 c2_status_t trySet( 315 const C2Param *value, bool mayBlock, 316 bool *changed, 317 Factory &factory, 318 std::vector<std::unique_ptr<C2SettingResult>>* const failures); 319 320 /// returns parameter indices that depend on this parameter 321 const std::vector<C2Param::Index> getDownDependencies() const; 322 323 /// adds a dependent parameter 324 void addDownDependency(C2Param::Index index); 325 326 /// returns that parameter refs for parameters that depend on this 327 const std::vector<ParamRef> getDependenciesAsRefs() const; 328 329 /// returns and moves out stored struct descriptor 330 C2StructDescriptor retrieveStructDescriptor(); 331 332 /// returns the name of this parameter 333 C2String name() const; 334 335 /// returns the index of this parameter 336 C2Param::Index index() const; 337 338 /// returns the parameter descriptor 339 std::shared_ptr<const C2ParamDescriptor> getDescriptor() const; 340 341 /** 342 * Validates param helper. 343 * 344 * For now, this fills field info for const params. 345 * 346 * \retval C2_CORRUPTED the parameter cannot be added as such 347 */ 348 c2_status_t validate(const std::shared_ptr<C2ParamReflector> &reflector); 349 350 protected: 351 typedef C2ParamDescriptor::attrib_t attrib_t; 352 attrib_t& attrib(); 353 354 /// sets the default value of this parameter 355 void setDefaultValue(std::shared_ptr<C2Param> default_); 356 357 /// sets the setter method 358 void setSetter(std::function<C2R(const C2Param *, bool, bool *, Factory &)> setter); 359 360 /// sets the getter method 361 void setGetter(std::function<std::shared_ptr<C2Param>(bool)> getter); 362 363 /// sets the dependencies 364 void setDependencies(std::vector<C2Param::Index> indices, std::vector<ParamRef> refs); 365 366 /// sets the fields and their supported values 367 void setFields(std::vector<C2ParamFieldValues> &&fields); 368 369 /// build this into a final ParamHelper object 370 std::shared_ptr<ParamHelper> build(); 371 372 class Impl; 373 std::unique_ptr<Impl> mImpl; 374 }; 375 376 /** 377 * Typed parameter helper. This provides access to members as well as field helpers. 378 */ 379 template<typename T> 380 struct C2_HIDE Param { 381 Param( 382 std::shared_ptr<ParamHelper> helper, std::shared_ptr<T> ¶m, 383 std::shared_ptr<C2ParamReflector> reflector) 384 : v(*param.get()), 385 _mTypedParam(param), 386 _mHelper(helper), 387 _mReflector(reflector) { } 388 389 template<typename S> 390 using FieldType = Field< 391 typename _c2_reduce_enum_to_underlying_type< 392 typename std::remove_const< 393 typename std::remove_extent<S>::type>::type>::type>; 394 395 template<typename S> 396 FieldType<S> F(S &field) { 397 size_t offs = (uintptr_t)&field - (uintptr_t)&get(); 398 // this must fall either within sizeof(T) + FLEX_SIZE or param->size() 399 // size_t size = sizeof(field); 400 // mParam may be null 401 size_t baseSize = sizeof(typename std::remove_extent<S>::type); 402 size_t baseOffs = GetBaseOffset( 403 _mReflector, T::CORE_INDEX, offs - sizeof(C2Param)); 404 if (~baseOffs == 0) { 405 // C2_LOG(FATAL) << "unknown field at offset " << offs << " size " << sizeof(S) 406 // << " base-size " << baseSize; 407 // __builtin_trap(); 408 } else { 409 baseOffs += sizeof(C2Param); 410 } 411 412 std::shared_ptr<FieldHelper> helper = _mHelper->findField(baseOffs, baseSize); 413 return FieldType<S>(helper, _mTypedParam->index()); 414 } 415 416 // const Param have const Fields; however, remove const from S 417 template<typename S> 418 const FieldType<S> F(S &field) const { 419 return const_cast<const FieldType<S>>(const_cast<Param *>(this)->F(field)); 420 } 421 422 /// Returns a const ref value of this const param. 423 const T &get() const { 424 return *_mTypedParam.get(); 425 } 426 427 /// Returns a modifiable ref value of this non-const param. 428 T &set() { 429 return *_mTypedParam.get(); 430 } 431 432 /// Const-reference to the value.s 433 T const &v; 434 435 private: 436 std::shared_ptr<T> _mTypedParam; 437 std::shared_ptr<ParamHelper> _mHelper; 438 std::shared_ptr<C2ParamReflector> _mReflector; 439 }; 440 441 template<typename T> 442 using C2P = Param<T>; 443 444 /** 445 * Templated move builder class for a parameter helper. 446 */ 447 template<typename T> 448 class C2_HIDE ParamBuilder : private ParamHelper { 449 public: 450 /** Construct the parameter builder from minimal info required. */ 451 ParamBuilder(std::shared_ptr<T> ¶m, C2StringLiteral name) 452 : ParamHelper(param, name, C2StructDescriptor((T*)nullptr)), 453 mTypedParam(¶m) { 454 attrib() = attrib_t::IS_PERSISTENT; 455 } 456 457 /** Makes this parameter required. */ 458 inline ParamBuilder &required() { 459 attrib() |= attrib_t::IS_REQUIRED; 460 return *this; 461 } 462 463 /** Makes this parameter transient (not persistent). */ 464 inline ParamBuilder &transient() { 465 attrib() &= ~attrib_t::IS_PERSISTENT; 466 return *this; 467 } 468 469 /** Makes this parameter hidden (not exposed in JAVA API). */ 470 inline ParamBuilder &hidden() { 471 attrib() |= attrib_t::IS_HIDDEN; 472 return *this; 473 } 474 475 /** Makes this parameter internal (not exposed to query/settings). */ 476 inline ParamBuilder &internal() { 477 attrib() |= attrib_t::IS_INTERNAL; 478 return *this; 479 } 480 481 /** Adds default value. Must be added exactly once. */ 482 inline ParamBuilder &withDefault(std::shared_ptr<T> default_) { 483 // CHECK(!mDefaultValue); 484 // WARN_IF(!default_); // could be nullptr if OOM 485 // technically, this could be in the parent 486 *mTypedParam = std::shared_ptr<T>(T::From(C2Param::Copy(*default_).release())); 487 setDefaultValue(default_); 488 std::shared_ptr<T> *typedParam = mTypedParam; 489 setGetter([typedParam](bool) -> std::shared_ptr<C2Param> { 490 return std::static_pointer_cast<C2Param>(*typedParam); 491 }); 492 return *this; 493 } 494 495 /** Adds default value. Must be added exactly once. */ 496 inline ParamBuilder &withDefault(T *default_) { 497 return withDefault(std::shared_ptr<T>(default_)); 498 } 499 500 /** Adds all fields to this parameter with their possible values. */ 501 inline ParamBuilder &withFields(std::vector<C2ParamFieldValues> &&fields_) { 502 setFields(std::move(fields_)); 503 return *this; 504 } 505 506 /** 507 * Adds a constant value (also as default). Must be added exactly once. 508 * 509 * Const parameters by definition have no dependencies. 510 */ 511 inline ParamBuilder &withConstValue(std::shared_ptr<T> default_) { 512 attrib() |= attrib_t::IS_CONST; 513 setSetter([default_]( 514 const C2Param *value, bool mayBlock __unused, bool *changed, Factory &) -> C2R { 515 *changed = false; 516 const T *typedValue = T::From(value); 517 if (typedValue == nullptr) { 518 return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here. 519 } 520 if (*typedValue != *default_) { 521 return C2R::Corrupted(); // TODO ReadOnly(*default_); 522 } 523 *changed = false; 524 return C2R::Ok(); 525 }); 526 return withDefault(default_); 527 } 528 529 /** Adds constant value (also as default). Must be added exactly once. */ 530 inline ParamBuilder &withConstValue(T *default_) { 531 return withConstValue(std::shared_ptr<T>(default_)); 532 } 533 534 /** 535 * Use a strict setter. 536 * 537 * \param fn strict setter 538 * \param deps dependencies (references) 539 */ 540 template<typename ... Deps> 541 inline ParamBuilder &withSetter( 542 C2R (*fn)(bool, const C2P<T> &, C2P<T> &, const C2P<Deps> &...), 543 std::shared_ptr<Deps>& ... deps) { 544 attrib() |= attrib_t::IS_STRICT; 545 std::shared_ptr<T> *typedParam = mTypedParam; 546 setSetter([typedParam, fn, &deps...]( 547 const C2Param *value, bool mayBlock, bool *changed, Factory &factory) -> C2R { 548 *changed = false; 549 const T *typedValue = T::From(value); 550 if (typedValue == nullptr) { 551 return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here. 552 } 553 // Do copy-on-change for parameters in this helper so change can be detected by 554 // a change of the pointer. Do this by working on a proposed value. 555 std::shared_ptr<T> proposedValue = 556 std::shared_ptr<T>(T::From(C2Param::Copy(*value).release())); 557 if (proposedValue == nullptr) { 558 return C2R::NoMemory(value->index()); 559 } 560 C2P<T> oldValue = factory.get(*typedParam); 561 // Get a parameter helper with value pointing to proposedValue 562 C2P<T> helper = factory.get(*typedParam, proposedValue); 563 C2R result = fn(mayBlock, oldValue, helper, factory.get(deps)...); 564 565 // If value changed, copy result to current value 566 if (helper.get() != *typedParam->get()) { 567 *typedParam = proposedValue; 568 *changed = true; 569 } 570 return result; 571 }); 572 setDependencies(std::vector<C2Param::Index>{ deps->index()... }, 573 std::vector<ParamRef>{ ParamRef(deps)... }); 574 return *this; 575 } 576 577 /** 578 * Use a non-strict setter. 579 * 580 * \param fn non-strict setter 581 * \param deps dependencies (references) 582 */ 583 template<typename ... Deps> 584 inline ParamBuilder &withSetter( 585 C2R (*fn)(bool, C2P<T> &, const C2P<Deps> &...), std::shared_ptr<Deps>& ... deps) { 586 std::shared_ptr<T> *typedParam = mTypedParam; 587 setSetter([typedParam, fn, &deps...]( 588 const C2Param *value, bool mayBlock, bool *changed, Factory &factory) -> C2R { 589 *changed = false; 590 const T *typedValue = T::From(value); 591 if (typedValue == nullptr) { 592 return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here. 593 } 594 // Do copy-on-change for parameters in this helper so change can be detected by 595 // a change of the pointer. Do this by working on a proposed value. 596 std::shared_ptr<T> proposedValue = 597 std::shared_ptr<T>(T::From(C2Param::Copy(*value).release())); 598 if (proposedValue == nullptr) { 599 return C2R::NoMemory(value->index()); 600 } 601 // Get a parameter helper with value pointing to proposedValue 602 C2P<T> helper = factory.get(*typedParam, proposedValue); 603 C2R result = fn(mayBlock, helper, factory.get(deps)...); 604 605 // If value changed, copy result to current value 606 if (helper.get() != *typedParam->get()) { 607 *typedParam = proposedValue; 608 *changed = true; 609 } 610 return result; 611 }); 612 setDependencies(std::vector<C2Param::Index>{ deps->index()... }, 613 std::vector<ParamRef>{ ParamRef(deps)... }); 614 return *this; 615 } 616 617 /** 618 * Marks this a calculated (read-only) field. 619 * 620 * \param fn non-strict setter (calculator) 621 * \param deps dependencies (references) 622 */ 623 template<typename ... Deps> 624 inline ParamBuilder &calculatedAs( 625 C2R (*fn)(bool, C2P<T> &, const C2P<Deps> &...), std::shared_ptr<Deps>& ... deps) { 626 attrib() |= attrib_t::IS_READ_ONLY; 627 return withSetter(fn, std::forward<decltype(deps)>(deps)...); 628 } 629 630 inline std::shared_ptr<ParamHelper> build() { 631 return ParamHelper::build(); 632 } 633 634 protected: 635 std::shared_ptr<T> *mTypedParam; 636 }; 637 638 template<typename T> 639 static ParamBuilder<T> DefineParam(std::shared_ptr<T> ¶m, C2StringLiteral name) { 640 return ParamBuilder<T>(param, name); 641 } 642 643 public: 644 c2_status_t query( 645 const std::vector<C2Param*> &stackParams, 646 const std::vector<C2Param::Index> &heapParamIndices, 647 c2_blocking_t mayBlock, 648 std::vector<std::unique_ptr<C2Param>>* const heapParams) const; 649 650 /** 651 * Helper implementing config calls as well as other configuration updates. 652 * 653 * This method is virtual, so implementations may provide wrappers around it (and perform 654 * actions just before and after a configuration). 655 * 656 * \param params 657 * \param mayBlock 658 * \param failures 659 * \param updateParams if true, the updated parameter values are copied back into the arguments 660 * passed in |params| 661 * \param changes pointed to a vector to receive settings with their values changed. If not 662 * null, settings with their values changed are added to this. 663 * \return result from config 664 */ 665 virtual c2_status_t config( 666 const std::vector<C2Param*> ¶ms, c2_blocking_t mayBlock, 667 std::vector<std::unique_ptr<C2SettingResult>>* const failures, 668 bool updateParams = true, 669 std::vector<std::shared_ptr<C2Param>> *changes = nullptr); 670 671 c2_status_t querySupportedParams( 672 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const; 673 674 c2_status_t querySupportedValues( 675 std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const; 676 677 std::shared_ptr<C2ReflectorHelper> getReflector() { 678 return mReflector; 679 } 680 681 typedef std::unique_lock<std::mutex> Lock; 682 683 /** 684 * Locks the interface and returns a lock. This lock must be unlocked or released without 685 * calling any other blocking call. 686 */ 687 Lock lock() const; 688 689 private: 690 void setInterfaceAddressBounds(uintptr_t start, uintptr_t end) { 691 // TODO: exclude this helper 692 (void)start; 693 (void)end; 694 } 695 696 protected: 697 mutable std::mutex mMutex; 698 std::shared_ptr<C2ReflectorHelper> mReflector; 699 struct FactoryImpl; 700 std::shared_ptr<FactoryImpl> _mFactory; 701 702 C2InterfaceHelper(std::shared_ptr<C2ReflectorHelper> reflector); 703 704 /** 705 * Adds a parameter to this interface. 706 * \note This method CHECKs. 707 * 708 * \param param parameter to add. 709 */ 710 void addParameter(std::shared_ptr<ParamHelper> param); 711 712 /** 713 * Returns the dependency index for a parameter. 714 * 715 * \param ix the index of the parameter 716 */ 717 size_t getDependencyIndex_l(C2Param::Index ix) const; 718 719 virtual ~C2InterfaceHelper() = default; 720 721 /** 722 * Sets subclass instance's address and size. 723 * 724 * \todo allow subclass to specify parameter address range directly (e.g. do not assume that 725 * they are local to the subclass instance) 726 * 727 * \param T type of the derived instance 728 * \param instance pointer to the derived instance 729 */ 730 template<typename T> 731 inline C2_HIDE void setDerivedInstance(T *instance) { 732 setInterfaceAddressBounds((uintptr_t)instance, (uintptr_t)(instance + 1)); 733 } 734 735 C2_DO_NOT_COPY(C2InterfaceHelper); 736 }; 737 738 /** 739 * Creates a C2ParamFieldValuesBuilder class for a field of a parameter 740 * 741 * \param spParam a configuration parameter in an interface class subclassed from C2InterfaceHelper. 742 * \param field a field of such parameter 743 */ 744 #define C2F(spParam, field) \ 745 C2ParamFieldValuesBuilder< \ 746 typename _c2_reduce_enum_to_underlying_type< \ 747 typename std::remove_reference< \ 748 typename std::remove_extent< \ 749 decltype(spParam->field)>::type>::type>::type>( \ 750 C2ParamField(spParam.get(), &spParam->field)) 751 752 #endif // C2UTILS_INTERFACE_HELPER_H_ 753