LCOV - code coverage report
Current view: top level - xenolith/scene/nodes - XLNode.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 55 59 93.2 %
Date: 2024-05-12 00:16:13 Functions: 121 128 94.5 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2021 Roman Katuntsev <sbkarr@stappler.org>
       3             :  Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef XENOLITH_SCENE_NODES_XLNODE_H_
      25             : #define XENOLITH_SCENE_NODES_XLNODE_H_
      26             : 
      27             : #include "XLNodeInfo.h"
      28             : #include "XLComponent.h"
      29             : 
      30             : namespace STAPPLER_VERSIONIZED stappler::xenolith {
      31             : 
      32             : class Component;
      33             : class Scene;
      34             : class Scheduler;
      35             : class InputListener;
      36             : class Action;
      37             : class ActionManager;
      38             : class Director;
      39             : class FrameContext;
      40             : 
      41             : struct ActionStorage : public Ref {
      42             :         Vector<Rc<Action>> actionToStart;
      43             : 
      44             :         void addAction(Rc<Action> &&a);
      45             :         void removeAction(Action *a);
      46             :         void removeAllActions();
      47             :         void removeActionByTag(uint32_t);
      48             :         void removeAllActionsByTag(uint32_t);
      49             :         Action *getActionByTag(uint32_t);
      50             : };
      51             : 
      52             : class Node : public Ref {
      53             : public:
      54             :         /* Nodes with transparent zOrder will not be added into zPath */
      55             :         static constexpr ZOrder ZOrderTransparent = ZOrder::min();
      56             :         static constexpr ZOrder ZOrderMax = ZOrder::max();
      57             :         static constexpr ZOrder ZOrderMin = ZOrder::min() + ZOrder(1);
      58             : 
      59             :         static bool isParent(Node *parent, Node *node);
      60             :         static Mat4 getChainNodeToParentTransform(Node *parent, Node *node, bool withParent);
      61             :         static Mat4 getChainParentToNodeTransform(Node *parent, Node *node, bool withParent);
      62             : 
      63             :         Node();
      64             :         virtual ~Node();
      65             : 
      66             :         virtual bool init();
      67             : 
      68             :         virtual void setLocalZOrder(ZOrder localZOrder);
      69      142254 :         virtual ZOrder getLocalZOrder() const { return _zOrder; }
      70             : 
      71             :         virtual void setScale(float scale);
      72             :         virtual void setScale(const Vec2 &);
      73             :         virtual void setScale(const Vec3 &);
      74             :         virtual void setScaleX(float scaleX);
      75             :         virtual void setScaleY(float scaleY);
      76             :         virtual void setScaleZ(float scaleZ);
      77             : 
      78           8 :         virtual const Vec3 & getScale() const { return _scale; }
      79             : 
      80             :         virtual void setPosition(const Vec2 &position);
      81             :         virtual void setPosition(const Vec3 &position);
      82             :         virtual void setPositionX(float);
      83             :         virtual void setPositionY(float);
      84             :         virtual void setPositionZ(float);
      85             : 
      86        1034 :         virtual const Vec3 & getPosition() const { return _position; }
      87             : 
      88             :         virtual void setSkewX(float skewX);
      89             :         virtual void setSkewY(float skewY);
      90             : 
      91           2 :         virtual const Vec2 & getSkew() const { return _skew; }
      92             : 
      93             :         /**
      94             :          * Sets the anchor point in percent.
      95             :          *
      96             :          * anchorPoint is the point around which all transformations and positioning manipulations take place.
      97             :          * It's like a pin in the node where it is "attached" to its parent.
      98             :          * The anchorPoint is normalized, like a percentage. (0,0) means the bottom-left corner and (1,1) means the top-right corner.
      99             :          * But you can use values higher than (1,1) and lower than (0,0) too.
     100             :          * The default anchorPoint is (0.5,0.5), so it starts in the center of the node.
     101             :          * @note If node has a physics body, the anchor must be in the middle, you cann't change this to other value.
     102             :          *
     103             :          * @param anchorPoint   The anchor point of node.
     104             :          */
     105             :         virtual void setAnchorPoint(const Vec2& anchorPoint);
     106          14 :         virtual const Vec2 & getAnchorPoint() const { return _anchorPoint; }
     107             : 
     108             :         /**
     109             :          * Sets the untransformed size of the node.
     110             :          *
     111             :          * The contentSize remains the same no matter the node is scaled or rotated.
     112             :          * All nodes has a size. Layer and Scene has the same size of the screen.
     113             :          *
     114             :          * @param contentSize   The untransformed size of the node.
     115             :          */
     116             :         virtual void setContentSize(const Size2& contentSize);
     117        3406 :         virtual const Size2& getContentSize() const { return _contentSize; }
     118             : 
     119             :         virtual void setVisible(bool visible);
     120       91715 :         virtual bool isVisible() const { return _visible; }
     121             : 
     122             :         virtual void setRotation(float rotationInRadians);
     123             :         virtual void setRotation(const Vec3 & rotationInRadians);
     124             :         virtual void setRotation(const Quaternion & quat);
     125             : 
     126           2 :         virtual float getRotation() const { return _rotation.z; }
     127           2 :         virtual const Vec3 &getRotation3D() const { return _rotation; }
     128           2 :         virtual const Quaternion &getRotationQuat() const { return _rotationQuat; }
     129             : 
     130             :         template<typename N, typename ... Args>
     131       16816 :         auto addChild(N *child, Args &&... args) -> N * {
     132       16816 :                 addChildNode(child, std::forward<Args>(args)...);
     133       16816 :                 return child;
     134             :         }
     135             : 
     136             :         template<typename N, typename ... Args>
     137        8328 :         auto addChild(const Rc<N> &child, Args &&... args) -> N * {
     138        8328 :                 addChildNode(child.get(), std::forward<Args>(args)...);
     139        8328 :                 return child.get();
     140             :         }
     141             : 
     142             :         virtual void addChildNode(Node *child);
     143             :         virtual void addChildNode(Node *child, ZOrder localZOrder);
     144             :         virtual void addChildNode(Node *child, ZOrder localZOrder, uint64_t tag);
     145             : 
     146             :         virtual Node* getChildByTag(uint64_t tag) const;
     147             : 
     148           2 :         virtual const Vector<Rc<Node>>& getChildren() const { return _children; }
     149           2 :         virtual size_t getChildrenCount() const { return _children.size(); }
     150             : 
     151             :         virtual void setParent(Node *parent);
     152       19458 :         virtual Node *getParent() const { return _parent; }
     153             : 
     154             :         virtual void removeFromParent(bool cleanup = true);
     155             :         virtual void removeChild(Node *child, bool cleanup = true);
     156             :         virtual void removeChildByTag(uint64_t tag, bool cleanup = true);
     157             :         virtual void removeAllChildren(bool cleanup = true);
     158             : 
     159             :         virtual void reorderChild(Node *child, ZOrder localZOrder);
     160             : 
     161             :         /**
     162             :          * Sorts the children array once before drawing, instead of every time when a child is added or reordered.
     163             :          * This appraoch can improves the performance massively.
     164             :          * @note Don't call this manually unless a child added needs to be removed in the same frame.
     165             :          */
     166             :         virtual void sortAllChildren();
     167             : 
     168             :         template <typename A>
     169             :         auto runAction(A *action) -> A * {
     170             :                 runActionObject(action);
     171             :                 return action;
     172             :         }
     173             : 
     174             :         template <typename A>
     175             :         auto runAction(A *action, uint32_t tag) -> A * {
     176             :                 runActionObject(action, tag);
     177             :                 return action;
     178             :         }
     179             : 
     180             :         template <typename A>
     181         595 :         auto runAction(const Rc<A> &action) -> A * {
     182         595 :                 runActionObject(action.get());
     183         595 :                 return action.get();
     184             :         }
     185             : 
     186             :         template <typename A>
     187        1021 :         auto runAction(const Rc<A> &action, uint32_t tag) -> A * {
     188        1021 :                 runActionObject(action.get(), tag);
     189        1021 :                 return action.get();
     190             :         }
     191             : 
     192             :         void runActionObject(Action *);
     193             :         void runActionObject(Action *, uint32_t tag);
     194             : 
     195             :         void stopAllActions();
     196             : 
     197             :         void stopAction(Action *action);
     198             :         void stopActionByTag(uint32_t tag);
     199             :         void stopAllActionsByTag(uint32_t tag);
     200             : 
     201             :         Action* getActionByTag(uint32_t tag);
     202             :         size_t getNumberOfRunningActions() const;
     203             : 
     204             : 
     205             :         template <typename C>
     206             :         auto addComponent(C *component) -> C * {
     207             :                 if (addComponentItem(component)) {
     208             :                         return component;
     209             :                 }
     210             :                 return nullptr;
     211             :         }
     212             : 
     213             :         template <typename C>
     214         774 :         auto addComponent(const Rc<C> &component) -> C * {
     215         774 :                 if (addComponentItem(component.get())) {
     216         774 :                         return component.get();
     217             :                 }
     218           0 :                 return nullptr;
     219             :         }
     220             : 
     221             :         virtual bool addComponentItem(Component *);
     222             :         virtual bool removeComponent(Component *);
     223             :         virtual bool removeComponentByTag(uint64_t);
     224             :         virtual bool removeAllComponentByTag(uint64_t);
     225             :         virtual void removeAllComponents();
     226             : 
     227             :     template <typename T>
     228             :     T *getComponentByType() const;
     229             : 
     230             :     template <typename T>
     231             :     T *getComponentByType(uint32_t tag) const;
     232             : 
     233             :         template <typename C>
     234             :         auto addInputListener(C *component) -> C * {
     235             :                 if (addInputListenerItem(component)) {
     236             :                         return component;
     237             :                 }
     238             :                 return nullptr;
     239             :         }
     240             : 
     241             :         template <typename C>
     242          96 :         auto addInputListener(const Rc<C> &component) -> C * {
     243          96 :                 if (addInputListenerItem(component.get())) {
     244          96 :                         return component.get();
     245             :                 }
     246           0 :                 return nullptr;
     247             :         }
     248             : 
     249             :         virtual bool addInputListenerItem(InputListener *);
     250             :         virtual bool removeInputListener(InputListener *);
     251             : 
     252           2 :         virtual StringView getName() const { return _name; }
     253          32 :         virtual void setName(StringView str) { _name = str.str<Interface>(); }
     254             : 
     255           2 :         virtual const Value &getDataValue() const { return _dataValue; }
     256           2 :         virtual void setDataValue(Value &&val) { _dataValue = move(val); }
     257             : 
     258           2 :         virtual uint64_t getTag() const { return _tag; }
     259             :         virtual void setTag(uint64_t tag);
     260             : 
     261         902 :         virtual bool isRunning() const { return _running; }
     262             : 
     263             :         virtual void onEnter(Scene *);
     264             :         virtual void onExit();
     265             : 
     266             :         virtual void onContentSizeDirty();
     267             :         virtual void onTransformDirty(const Mat4 &);
     268             :         virtual void onGlobalTransformDirty(const Mat4 &);
     269             :         virtual void onReorderChildDirty();
     270             : 
     271             :         virtual void cleanup();
     272             : 
     273             :         virtual Rect getBoundingBox() const;
     274             : 
     275             :         virtual void resume();
     276             :         virtual void pause();
     277             : 
     278             :         virtual void update(const UpdateTime &time);
     279             : 
     280             :         virtual const Mat4& getNodeToParentTransform() const;
     281             : 
     282             :         virtual void setNodeToParentTransform(const Mat4& transform);
     283             :         virtual const Mat4& getParentToNodeTransform() const;
     284             : 
     285             :         virtual Mat4 getNodeToWorldTransform() const;
     286             :         virtual Mat4 getWorldToNodeTransform() const;
     287             : 
     288             :         Vec2 convertToNodeSpace(const Vec2& worldPoint) const;
     289             :         Vec2 convertToWorldSpace(const Vec2& nodePoint) const;
     290             :         Vec2 convertToNodeSpaceAR(const Vec2& worldPoint) const;
     291             :         Vec2 convertToWorldSpaceAR(const Vec2& nodePoint) const;
     292             : 
     293        5425 :         virtual bool isCascadeOpacityEnabled() const { return _cascadeOpacityEnabled; }
     294       36277 :         virtual bool isCascadeColorEnabled() const { return _cascadeColorEnabled; }
     295             : 
     296             :         virtual void setCascadeOpacityEnabled(bool cascadeOpacityEnabled);
     297             :         virtual void setCascadeColorEnabled(bool cascadeColorEnabled);
     298             : 
     299         516 :         virtual float getOpacity() const { return _realColor.a; }
     300        5425 :         virtual float getDisplayedOpacity() const { return _displayedColor.a; }
     301             :         virtual void setOpacity(float opacity);
     302             :         virtual void setOpacity(OpacityValue);
     303             :         virtual void updateDisplayedOpacity(float parentOpacity);
     304             : 
     305        2078 :         virtual Color4F getColor() const { return _realColor; }
     306           4 :         virtual Color4F getDisplayedColor() const { return _displayedColor; }
     307             :         virtual void setColor(const Color4F& color, bool withOpacity = false);
     308             :         virtual void updateDisplayedColor(const Color4F& parentColor);
     309             : 
     310        4246 :         virtual void setDepthIndex(float value) { _depthIndex = value; }
     311           2 :         virtual float getDepthIndex() const { return _depthIndex; }
     312             : 
     313             :         virtual void draw(FrameInfo &, NodeFlags flags);
     314             : 
     315             :         // visit on unsorted nodes, commit most of geometry changes
     316             :         // on this step, we process child-to-parent changes (like nodes, based on label's size)
     317             :         virtual bool visitGeometry(FrameInfo &, NodeFlags parentFlags);
     318             : 
     319             :         // visit on sorted nodes, push draw commands
     320             :         // on this step, we also process parent-to-child geometry changes
     321             :         virtual bool visitDraw(FrameInfo &, NodeFlags parentFlags);
     322             : 
     323             :         void scheduleUpdate();
     324             :         void unscheduleUpdate();
     325             : 
     326             :         virtual bool isTouched(const Vec2 &location, float padding = 0.0f);
     327             :         virtual bool isTouchedNodeSpace(const Vec2 &location, float padding = 0.0f);
     328             : 
     329             :         virtual void setOnEnterCallback(Function<void(Scene *)> &&);
     330             :         virtual void setOnExitCallback(Function<void()> &&);
     331             :         virtual void setOnContentSizeDirtyCallback(Function<void()> &&);
     332             :         virtual void setOnTransformDirtyCallback(Function<void(const Mat4 &)> &&);
     333             :         virtual void setOnReorderChildDirtyCallback(Function<void()> &&);
     334             : 
     335           0 :         float getInputDensity() const { return _inputDensity; }
     336             : 
     337             :         Scene *getScene() const { return _scene; }
     338         426 :         Director *getDirector() const { return _director; }
     339        1575 :         Scheduler *getScheduler() const { return _scheduler; }
     340             :         ActionManager *getActionManager() const { return _actionManager; }
     341      569808 :         FrameContext *getFrameContext() const { return _frameContext; }
     342             : 
     343             :         virtual float getMaxDepthIndex() const;
     344             : 
     345             :         virtual void retainFocus();
     346             :         virtual void releaseFocus();
     347             :         virtual void clearFocus();
     348             : 
     349           2 :         virtual uint32_t getFocus() const { return _focus; }
     350             : 
     351             : protected:
     352             :         virtual void updateCascadeOpacity();
     353             :         virtual void disableCascadeOpacity();
     354             :         virtual void updateCascadeColor();
     355             :         virtual void disableCascadeColor();
     356      324961 :         virtual void updateColor() { }
     357             : 
     358             :         Mat4 transform(const Mat4 &parentTransform);
     359             :         virtual NodeFlags processParentFlags(FrameInfo &info, NodeFlags parentFlags);
     360             : 
     361             :         virtual void visitSelf(FrameInfo &, NodeFlags flags, bool visibleByCamera);
     362             : 
     363             :         virtual bool wrapVisit(FrameInfo &, NodeFlags flags, const Callback<void(NodeFlags, bool visible)> &, bool useContext);
     364             : 
     365             :         bool _is3d = false;
     366             :         bool _running = false;
     367             :         bool _visible = true;
     368             :         bool _scheduled = false;
     369             :         bool _paused = false;
     370             : 
     371             :         bool _cascadeColorEnabled = false;
     372             :         bool _cascadeOpacityEnabled = true;
     373             : 
     374             :         bool _contentSizeDirty = true;
     375             :         bool _reorderChildDirty = true;
     376             :         mutable bool _transformCacheDirty = true; // dynamic value
     377             :         mutable bool _transformInverseDirty = true; // dynamic value
     378             :         bool _transformDirty = true;
     379             : 
     380             :         String _name;
     381             :         Value _dataValue;
     382             : 
     383             :         uint64_t _tag = InvalidTag;
     384       86291 :         ZOrder _zOrder = ZOrder(0);
     385             :         uint32_t _focus = 0;
     386             : 
     387             :         Vec2 _skew;
     388             :         Vec2 _anchorPoint;
     389             :         Size2 _contentSize;
     390             : 
     391             :         Vec3 _position;
     392             :         Vec3 _scale = Vec3(1.0f, 1.0f, 1.0f);
     393             :         Vec3 _rotation;
     394             :         float _inputDensity = 1.0f;
     395             :         float _depthIndex = 0.0f;
     396             : 
     397             :         // to support HDR, we use float colors;
     398             :         Color4F _displayedColor = Color4F::WHITE;
     399             :         Color4F _realColor = Color4F::WHITE;
     400             : 
     401             :         Quaternion _rotationQuat;
     402             : 
     403             :         mutable Mat4 _transform = Mat4::IDENTITY;
     404             :         mutable Mat4 _inverse = Mat4::IDENTITY;
     405             :         Mat4 _modelViewTransform = Mat4::IDENTITY;
     406             : 
     407             :         Vector<Rc<Node>> _children;
     408             :         Node *_parent = nullptr;
     409             : 
     410             :         Function<void(Scene *)> _onEnterCallback;
     411             :         Function<void()> _onExitCallback;
     412             :         Function<void()> _onContentSizeDirtyCallback;
     413             :         Function<void(const Mat4 &)> _onTransformDirtyCallback;
     414             :         Function<void()> _onReorderChildDirtyCallback;
     415             : 
     416             :         Vector<Rc<Component>> _components;
     417             :         Vector<Rc<InputListener>> _inputEvents;
     418             : 
     419             :         Scene *_scene = nullptr;
     420             :         Director *_director = nullptr;
     421             :         Scheduler *_scheduler = nullptr;
     422             :         ActionManager *_actionManager = nullptr;
     423             :         FrameContext *_frameContext = nullptr;
     424             : 
     425             :         Rc<ActionStorage> _actionStorage;
     426             : };
     427             : 
     428             : 
     429             : template <typename T>
     430       16639 : auto Node::getComponentByType() const -> T * {
     431       17031 :         for (auto &it : _components) {
     432         392 :                 if (auto ret = dynamic_cast<T *>(it.get())) {
     433           0 :                         return ret;
     434             :                 }
     435             :         }
     436       16639 :         return nullptr;
     437             : }
     438             : 
     439             : template <typename T>
     440             : auto Node::getComponentByType(uint32_t tag) const -> T * {
     441             :         for (auto &it : _components) {
     442             :                 if (it->getFrameTag() == tag) {
     443             :                         if (auto ret = dynamic_cast<T *>(it.get())) {
     444             :                                 return ret;
     445             :                         }
     446             :                 }
     447             :         }
     448             :         return nullptr;
     449             : }
     450             : 
     451             : 
     452             : }
     453             : 
     454             : #endif /* XENOLITH_SCENE_NODES_XLNODE_H_ */

Generated by: LCOV version 1.14