1 /* 2 * Copyright (c) 2011-2021, The DART development contributors 3 * All rights reserved. 4 * 5 * The list of contributors can be found at: 6 * https://github.com/dartsim/dart/blob/master/LICENSE 7 * 8 * This file is provided under the following "BSD-style" License: 9 * Redistribution and use in source and binary forms, with or 10 * without modification, are permitted provided that the following 11 * conditions are met: 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef DART_COMMON_DETAIL_PROXYASPECT_HPP_ 34 #define DART_COMMON_DETAIL_PROXYASPECT_HPP_ 35 36 #include "dart/common/Aspect.hpp" 37 38 namespace dart { 39 namespace common { 40 namespace detail { 41 42 //============================================================================== 43 template <class BaseT, class CompositeT, typename StateT> 44 class ProxyStateAspect : public BaseT 45 { 46 public: 47 using Base = BaseT; 48 using CompositeType = CompositeT; 49 using State = StateT; 50 51 virtual ~ProxyStateAspect() = default; 52 53 /// General constructor 54 template <typename... Args> ProxyStateAspect(Args &&...args)55 ProxyStateAspect(Args&&... args) 56 : Base(std::forward<Args>(args)...), mProxyState() 57 { 58 // Do nothing 59 } 60 61 // Documentation inherited setAspectState(const Aspect::State & state)62 void setAspectState(const Aspect::State& state) override final 63 { 64 mProxyState.set(static_cast<const State&>(state)); 65 } 66 67 // Documentation inherited getAspectState() const68 const Aspect::State* getAspectState() const override final 69 { 70 return &mProxyState; 71 } 72 73 // Documentation inherited cloneAspect() const74 std::unique_ptr<Aspect> cloneAspect() const override 75 { 76 return std::make_unique<ProxyStateAspect>(); 77 } 78 79 protected: 80 /// Reconfigure the Aspect to link it to this Aspect's new Composite setComposite(Composite * newComposite)81 void setComposite(Composite* newComposite) override 82 { 83 Base::setComposite(newComposite); 84 85 // Check if the Composite is the correct Owner type 86 typename State::Owner* owner 87 = dynamic_cast<typename State::Owner*>(newComposite); 88 89 if (owner && mProxyState.getOwner() != owner) 90 { 91 // Link the ProxyState to its new owner 92 mProxyState = State(owner, mProxyState.get()); 93 } 94 } 95 96 /// Reconfigure the Aspect to unlink it from this Aspect's old Composite loseComposite(Composite * oldComposite)97 void loseComposite(Composite* oldComposite) override 98 { 99 mProxyState = State(mProxyState.get()); 100 Base::loseComposite(oldComposite); 101 } 102 103 /// Proxy state for this Aspect 104 State mProxyState; 105 }; 106 107 //============================================================================== 108 template <class BaseT, class CompositeT, typename PropertiesT> 109 class ProxyPropertiesAspect : public BaseT 110 { 111 public: 112 using Base = BaseT; 113 using CompositeType = CompositeT; 114 using Properties = PropertiesT; 115 116 virtual ~ProxyPropertiesAspect() = default; 117 118 /// General constructor 119 template <typename... Args> ProxyPropertiesAspect(Args &&...args)120 ProxyPropertiesAspect(Args&&... args) 121 : Base(std::forward<Args>(args)...), mProxyProperties() 122 { 123 // Do nothing 124 } 125 126 // Documentation inherited setAspectProperties(const Aspect::Properties & properties)127 void setAspectProperties(const Aspect::Properties& properties) override final 128 { 129 mProxyProperties.set(static_cast<const Properties&>(properties)); 130 } 131 132 // Documentation inherited getAspectProperties() const133 const Aspect::Properties* getAspectProperties() const override final 134 { 135 return &mProxyProperties; 136 } 137 138 // Documentation inherited cloneAspect() const139 std::unique_ptr<Aspect> cloneAspect() const override 140 { 141 return std::make_unique<ProxyPropertiesAspect>(); 142 } 143 144 protected: 145 /// Reconfigure the Aspect to link it to this Aspect's new Composite setComposite(Composite * newComposite)146 void setComposite(Composite* newComposite) override 147 { 148 Base::setComposite(newComposite); 149 typename Properties::Owner* owner 150 = dynamic_cast<typename Properties::Owner*>(newComposite); 151 152 if (owner && mProxyProperties.getOwner() != owner) 153 { 154 // Link the ProxyProperties to its new owner 155 mProxyProperties = Properties(owner, mProxyProperties.get()); 156 } 157 } 158 159 /// Reconfigure the Aspect to unlink it from this Aspect's old Composite loseComposite(Composite * oldComposite)160 void loseComposite(Composite* oldComposite) override 161 { 162 mProxyProperties = Properties(mProxyProperties.get()); 163 Base::loseComposite(oldComposite); 164 } 165 166 /// Proxy properties for this Aspect 167 Properties mProxyProperties; 168 }; 169 170 } // namespace detail 171 } // namespace common 172 } // namespace dart 173 174 #endif // DART_COMMON_DETAIL_PROXYASPECT_HPP_ 175