LCOV - code coverage report
Current view: top level - xenolith/scene/input - XLInputDispatcher.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 23 26 88.5 %
Date: 2024-05-12 00:16:13 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2022 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_INPUT_XLINPUTDISPATCHER_H_
      25             : #define XENOLITH_SCENE_INPUT_XLINPUTDISPATCHER_H_
      26             : 
      27             : #include "XLApplicationInfo.h"
      28             : #include "XLInputListener.h"
      29             : #include "XLTextInputManager.h"
      30             : 
      31             : namespace STAPPLER_VERSIONIZED stappler::xenolith {
      32             : 
      33             : class InputListenerStorage : public PoolRef {
      34             : public:
      35             :         struct Rec {
      36             :                 InputListener *listener;
      37             :                 uint32_t focus;
      38             :         };
      39             : 
      40             :         virtual ~InputListenerStorage();
      41             : 
      42             :         InputListenerStorage(PoolRef *);
      43             : 
      44             :         void clear();
      45             :         void reserve(const InputListenerStorage *);
      46             : 
      47             :         void addListener(InputListener *, uint32_t focusValue);
      48             : 
      49             :         void updateFocus(uint32_t focusValue);
      50             : 
      51             :         template <typename Callback>
      52             :         bool foreach(const Callback &, bool focusOnly);
      53             : 
      54             : protected:
      55             :         memory::vector<Rec> *_preSceneEvents;
      56             :         memory::vector<Rec> *_sceneEvents; // in reverse order
      57             :         memory::vector<Rec> *_postSceneEvents;
      58             :         uint32_t _maxFocusValue = 0;
      59             : };
      60             : 
      61             : class InputDispatcher : public Ref {
      62             : public:
      63          40 :         virtual ~InputDispatcher() { }
      64             : 
      65             :         bool init(PoolRef *, TextInputViewInterface *);
      66             : 
      67             :         void update(const UpdateTime &time);
      68             : 
      69             :         Rc<InputListenerStorage> acquireNewStorage();
      70             :         void commitStorage(Rc<InputListenerStorage> &&);
      71             : 
      72             :         void handleInputEvent(const InputEventData &);
      73             : 
      74             :         Vector<InputEventData> getActiveEvents() const;
      75             : 
      76             :         void setListenerExclusive(const InputListener *l);
      77             :         void setListenerExclusiveForTouch(const InputListener *l, uint32_t);
      78             :         void setListenerExclusiveForKey(const InputListener *l, InputKeyCode);
      79             : 
      80          60 :         const Rc<TextInputManager> &getTextInputManager() const { return _textInput; }
      81             : 
      82          10 :         bool isInBackground() const { return _inBackground; }
      83         216 :         bool hasFocus() const { return _hasFocus; }
      84         216 :         bool isPointerWithinWindow() const { return _pointerInWindow; }
      85             : 
      86             :         bool hasActiveInput() const;
      87             : 
      88             : protected:
      89             :         InputEvent getEventInfo(const InputEventData &) const;
      90             :         void updateEventInfo(InputEvent &, const InputEventData &) const;
      91             : 
      92             :         struct EventHandlersInfo {
      93             :                 InputEvent event;
      94             :                 Vector<Rc<InputListener>> listeners;
      95             :                 Rc<InputListener> exclusive;
      96             :                 Vector<const InputListener *> processed;
      97             :                 bool isKeyEvent = false;
      98             : 
      99             :                 void handle(bool removeOnFail);
     100             :                 void clear(bool cancel);
     101             : 
     102             :                 void setExclusive(const InputListener *);
     103             :         };
     104             : 
     105             :         void setListenerExclusive(EventHandlersInfo &, const InputListener *l) const;
     106             : 
     107             :         void clearKey(const InputEventData &);
     108             :         EventHandlersInfo *resetKey(const InputEventData &);
     109             :         void handleKey(const InputEventData &, bool clear);
     110             : 
     111             :         void cancelTouchEvents(float x, float y, InputModifier mods);
     112             : 
     113             :         uint64_t _currentTime = 0;
     114             :         HashMap<uint32_t, EventHandlersInfo> _activeEvents;
     115             :         HashMap<InputKeyCode, EventHandlersInfo> _activeKeys;
     116             :         HashMap<uint32_t, EventHandlersInfo> _activeKeySyms;
     117             :         Rc<InputListenerStorage> _events;
     118             :         Rc<InputListenerStorage> _tmpEvents;
     119             :         Rc<TextInputManager> _textInput;
     120             :         Rc<PoolRef> _pool;
     121             : 
     122             :         Vec2 _pointerLocation = Vec2::ZERO;
     123             :         bool _inBackground = false;
     124             :         bool _hasFocus = true;
     125             :         bool _pointerInWindow = false;
     126             : };
     127             : 
     128             : template <typename Callback>
     129        2637 : bool InputListenerStorage::foreach(const Callback &cb, bool focusOnly) {
     130        2637 :         memory::vector<Rec>::reverse_iterator it, end;
     131        2637 :         it = _preSceneEvents->rbegin();
     132        2637 :         end = _preSceneEvents->rend();
     133             : 
     134        3985 :         for (;it != end; ++ it) {
     135        1348 :                 if (!focusOnly || it->focus >= _maxFocusValue) {
     136        1348 :                         if (!cb(*it)) {
     137           0 :                                 return false;
     138             :                         }
     139             :                 }
     140             :         }
     141             : 
     142        2637 :         it = _sceneEvents->rbegin();
     143        2637 :         end = _sceneEvents->rend();
     144             : 
     145       10849 :         for (;it != end; ++ it) {
     146        8212 :                 if (!focusOnly || it->focus >= _maxFocusValue) {
     147        8212 :                         if (!cb(*it)) {
     148           0 :                                 return false;
     149             :                         }
     150             :                 }
     151             :         }
     152             : 
     153        2637 :         it = _postSceneEvents->rbegin();
     154        2637 :         end = _postSceneEvents->rend();
     155             : 
     156        6030 :         for (;it != end; ++ it) {
     157        3393 :                 if (!focusOnly || it->focus >= _maxFocusValue) {
     158        3393 :                         if (!cb(*it)) {
     159           0 :                                 return false;
     160             :                         }
     161             :                 }
     162             :         }
     163             : 
     164        2637 :         return true;
     165             : }
     166             : 
     167             : }
     168             : 
     169             : #endif /* XENOLITH_SCENE_INPUT_XLINPUTDISPATCHER_H_ */

Generated by: LCOV version 1.14