| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// | 
|---|
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// | 
|---|
| 3 | #pragma once | 
|---|
| 4 |  | 
|---|
| 5 | #include "BsCorePrerequisites.h" | 
|---|
| 6 | #include "Scene/BsGameObject.h" | 
|---|
| 7 | #include "Math/BsBounds.h" | 
|---|
| 8 |  | 
|---|
| 9 | namespace bs | 
|---|
| 10 | { | 
|---|
| 11 | /** @addtogroup Scene | 
|---|
| 12 | *  @{ | 
|---|
| 13 | */ | 
|---|
| 14 |  | 
|---|
| 15 | /** Flags that control behavior of a Component. */ | 
|---|
| 16 | enum class ComponentFlag | 
|---|
| 17 | { | 
|---|
| 18 | /** | 
|---|
| 19 | * Ensures that scene manager cannot pause or stop component callbacks from executing. Off by default. | 
|---|
| 20 | * Note that this flag must be specified on component creation, in its constructor and any later changes | 
|---|
| 21 | * to the flag could be ignored. | 
|---|
| 22 | */ | 
|---|
| 23 | AlwaysRun = 1 | 
|---|
| 24 | }; | 
|---|
| 25 |  | 
|---|
| 26 | typedef Flags<ComponentFlag> ComponentFlags; | 
|---|
| 27 | BS_FLAGS_OPERATORS(ComponentFlag) | 
|---|
| 28 |  | 
|---|
| 29 | /** | 
|---|
| 30 | * Components represent primary logic elements in the scene. They are attached to scene objects. | 
|---|
| 31 | * | 
|---|
| 32 | * You should implement some or all of update/fixedUpdate/onCreated/onInitialized/onEnabled/onDisabled/ | 
|---|
| 33 | * onTransformChanged/onDestroyed methods to implement the relevant component logic. Avoid putting logic in constructors | 
|---|
| 34 | * or destructors. | 
|---|
| 35 | * | 
|---|
| 36 | * Components can be in different states. These states control which of the events listed above trigger: | 
|---|
| 37 | *  - Running - Scene manager is sending out events. | 
|---|
| 38 | *  - Paused - Scene manager is sending out all events except per-frame update(). | 
|---|
| 39 | *	- Stopped - Scene manager is not sending out events except for onCreated/onDestroyed. | 
|---|
| 40 | * | 
|---|
| 41 | * These states can be changed globally though SceneManager and affect all components. Individual components can | 
|---|
| 42 | * override these states in two ways: | 
|---|
| 43 | *  - Set the ComponentFlag::AlwaysRun to true and the component will always stay in Running state, regardless of | 
|---|
| 44 | *    state set in SceneManager. This flag should be set in constructor and not change during component lifetime. | 
|---|
| 45 | *  - If the component's parent SceneObject is inactive (SceneObject::setActive(false)), or any of his parents are | 
|---|
| 46 | *    inactive, then the component is considered to be in Stopped state, regardless whether the ComponentFlag::AlwaysRun | 
|---|
| 47 | *    flag is set or not. | 
|---|
| 48 | **/ | 
|---|
| 49 | class BS_CORE_EXPORT Component : public GameObject | 
|---|
| 50 | { | 
|---|
| 51 | public: | 
|---|
| 52 | /**	Returns the SceneObject this Component is assigned to. */ | 
|---|
| 53 | const HSceneObject& sceneObject() const { return mParent; } | 
|---|
| 54 |  | 
|---|
| 55 | /** @copydoc sceneObject */ | 
|---|
| 56 | const HSceneObject& SO() const { return sceneObject(); } | 
|---|
| 57 |  | 
|---|
| 58 | /**	Returns a handle to this object. */ | 
|---|
| 59 | const HComponent& getHandle() const { return mThisHandle; } | 
|---|
| 60 |  | 
|---|
| 61 | /** Called once per frame. Only called if the component is in Running state. */ | 
|---|
| 62 | virtual void update() { } | 
|---|
| 63 |  | 
|---|
| 64 | /** | 
|---|
| 65 | * Called at fixed time intervals (e.g. 60 times per frame). Generally any physics-related functionality should | 
|---|
| 66 | * go in this method in order to ensure stability of calculations. Only called if the component is in Running | 
|---|
| 67 | * state. | 
|---|
| 68 | */ | 
|---|
| 69 | virtual void fixedUpdate() { } | 
|---|
| 70 |  | 
|---|
| 71 | /** | 
|---|
| 72 | * Calculates bounds of the visible contents represented by this component (for example a mesh for Renderable). | 
|---|
| 73 | * | 
|---|
| 74 | * @param[in]	bounds	Bounds of the contents in world space coordinates. | 
|---|
| 75 | * @return				True if the component has bounds with non-zero volume, otherwise false. | 
|---|
| 76 | */ | 
|---|
| 77 | virtual bool calculateBounds(Bounds& bounds); | 
|---|
| 78 |  | 
|---|
| 79 | /** | 
|---|
| 80 | * Checks if this and the provided component represent the same type. | 
|---|
| 81 | * | 
|---|
| 82 | * @note | 
|---|
| 83 | * RTTI type cannot be checked directly since components can be further specialized internally for scripting | 
|---|
| 84 | * purposes. | 
|---|
| 85 | */ | 
|---|
| 86 | virtual bool typeEquals(const Component& other); | 
|---|
| 87 |  | 
|---|
| 88 | /** | 
|---|
| 89 | * Removes the component from parent SceneObject and deletes it. All the references to this component will be | 
|---|
| 90 | * marked as destroyed and you will get an exception if you try to use them. | 
|---|
| 91 | * | 
|---|
| 92 | * @param[in]	immediate	If true the destruction will be performed immediately, otherwise it will be delayed | 
|---|
| 93 | *							until the end of the current frame (preferred option). | 
|---|
| 94 | */ | 
|---|
| 95 | void destroy(bool immediate = false); | 
|---|
| 96 |  | 
|---|
| 97 | /** @name Internal | 
|---|
| 98 | *  @{ | 
|---|
| 99 | */ | 
|---|
| 100 |  | 
|---|
| 101 | /** | 
|---|
| 102 | * Construct any resources the component needs before use. Called when the parent scene object is instantiated. | 
|---|
| 103 | * A non-instantiated component shouldn't be used for any other purpose than serialization. | 
|---|
| 104 | */ | 
|---|
| 105 | virtual void _instantiate() {} | 
|---|
| 106 |  | 
|---|
| 107 | /** Sets new flags that determine when is onTransformChanged called. */ | 
|---|
| 108 | void setNotifyFlags(TransformChangedFlags flags) { mNotifyFlags = flags; } | 
|---|
| 109 |  | 
|---|
| 110 | /** Gets the currently assigned notify flags. See _setNotifyFlags(). */ | 
|---|
| 111 | TransformChangedFlags _getNotifyFlags() const { return mNotifyFlags; } | 
|---|
| 112 |  | 
|---|
| 113 | /** @} */ | 
|---|
| 114 | protected: | 
|---|
| 115 | friend class SceneManager; | 
|---|
| 116 | friend class SceneObject; | 
|---|
| 117 | friend class SceneObjectRTTI; | 
|---|
| 118 |  | 
|---|
| 119 | Component(HSceneObject parent); | 
|---|
| 120 | virtual ~Component() = default; | 
|---|
| 121 |  | 
|---|
| 122 | /** Called once when the component has been created. Called regardless of the state the component is in. */ | 
|---|
| 123 | virtual void onCreated() {} | 
|---|
| 124 |  | 
|---|
| 125 | /** | 
|---|
| 126 | * Called once when the component first leaves the Stopped state. This includes component creation if requirements | 
|---|
| 127 | * for leaving Stopped state are met, in which case it is called after onCreated. | 
|---|
| 128 | */ | 
|---|
| 129 | virtual void onInitialized() {} | 
|---|
| 130 |  | 
|---|
| 131 | /**	Called once just before the component is destroyed. Called regardless of the state the component is in. */ | 
|---|
| 132 | virtual void onDestroyed() {} | 
|---|
| 133 |  | 
|---|
| 134 | /** | 
|---|
| 135 | * Called every time a component is placed into the Stopped state. This includes component destruction if component | 
|---|
| 136 | * wasn't already in Stopped state during destruction. When called during destruction it is called before | 
|---|
| 137 | * onDestroyed. | 
|---|
| 138 | */ | 
|---|
| 139 | virtual void onDisabled() {} | 
|---|
| 140 |  | 
|---|
| 141 | /** | 
|---|
| 142 | * Called every time a component leaves the Stopped state. This includes component creation if requirements | 
|---|
| 143 | * for leaving the Stopped state are met. When called during creation it is called after onInitialized. | 
|---|
| 144 | */ | 
|---|
| 145 | virtual void onEnabled() {} | 
|---|
| 146 |  | 
|---|
| 147 | /** | 
|---|
| 148 | * Called when the component's parent scene object has changed. Not called if the component is in Stopped state. | 
|---|
| 149 | * Also only called if necessary notify flags are set via _setNotifyFlags(). | 
|---|
| 150 | */ | 
|---|
| 151 | virtual void onTransformChanged(TransformChangedFlags flags) { } | 
|---|
| 152 |  | 
|---|
| 153 | /** Checks whether the component wants to received the specified transform changed message. */ | 
|---|
| 154 | bool supportsNotify(TransformChangedFlags flags) const { return (mNotifyFlags & flags) != 0; } | 
|---|
| 155 |  | 
|---|
| 156 | /** Enables or disabled a flag controlling component's behaviour. */ | 
|---|
| 157 | void setFlag(ComponentFlag flag, bool enabled) { if (enabled) mFlags.set(flag); else mFlags.unset(flag); } | 
|---|
| 158 |  | 
|---|
| 159 | /** Checks if the component has a certain flag enabled. */ | 
|---|
| 160 | bool hasFlag(ComponentFlag flag) const { return mFlags.isSet(flag); } | 
|---|
| 161 |  | 
|---|
| 162 | /** Sets an index that uniquely identifies a component with the SceneManager. */ | 
|---|
| 163 | void setSceneManagerId(UINT32 id) { mSceneManagerId = id; } | 
|---|
| 164 |  | 
|---|
| 165 | /** Returns an index that unique identifies a component with the SceneManager. */ | 
|---|
| 166 | UINT32 getSceneManagerId() const { return mSceneManagerId; } | 
|---|
| 167 |  | 
|---|
| 168 | /** | 
|---|
| 169 | * Destroys this component. | 
|---|
| 170 | * | 
|---|
| 171 | * @param[in]	handle		Game object handle this this object. | 
|---|
| 172 | * @param[in]	immediate	If true, the object will be deallocated and become unusable right away. Otherwise the | 
|---|
| 173 | *							deallocation will be delayed to the end of frame (preferred method). | 
|---|
| 174 | * | 
|---|
| 175 | * @note	Unlike destroy(), does not remove the component from its parent. | 
|---|
| 176 | */ | 
|---|
| 177 | void destroyInternal(GameObjectHandleBase& handle, bool immediate) override; | 
|---|
| 178 | private: | 
|---|
| 179 | Component(const Component& other) { } | 
|---|
| 180 |  | 
|---|
| 181 | protected: | 
|---|
| 182 | HComponent mThisHandle; | 
|---|
| 183 | TransformChangedFlags mNotifyFlags = TCF_None; | 
|---|
| 184 | ComponentFlags mFlags; | 
|---|
| 185 | UINT32 mSceneManagerId = 0; | 
|---|
| 186 |  | 
|---|
| 187 | private: | 
|---|
| 188 | HSceneObject mParent; | 
|---|
| 189 |  | 
|---|
| 190 | /************************************************************************/ | 
|---|
| 191 | /* 								RTTI		                     		*/ | 
|---|
| 192 | /************************************************************************/ | 
|---|
| 193 | public: | 
|---|
| 194 | friend class ComponentRTTI; | 
|---|
| 195 | static RTTITypeBase* getRTTIStatic(); | 
|---|
| 196 | RTTITypeBase* getRTTI() const override; | 
|---|
| 197 |  | 
|---|
| 198 | protected: | 
|---|
| 199 | Component() = default; // Serialization only | 
|---|
| 200 | }; | 
|---|
| 201 |  | 
|---|
| 202 | /** @} */ | 
|---|
| 203 | } | 
|---|