kodi
WindowInterceptor.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "Window.h"
12 #include "guilib/GUIWindow.h"
13 
14 namespace XBMCAddon
15 {
16  namespace xbmcgui
17  {
18 
19 #ifndef SWIG
20  class Window;
21  class ref;
22 
28  {
29  protected:
31  // This instance is in Window.cpp
32  static thread_local ref* upcallTls;
33 
34  InterceptorBase() : window(NULL) { upcallTls = NULL; }
35 
49  static bool up() { bool ret = ((upcallTls) != NULL); upcallTls = NULL; return ret; }
50  public:
51 
52  virtual ~InterceptorBase() { if (window.isNotNull()) { window->interceptorClear(); } }
53 
54  virtual CGUIWindow* get() = 0;
55 
56  virtual void SetRenderOrder(int renderOrder) { }
57 
58  virtual void setActive(bool active) { }
59  virtual bool isActive() { return false; }
60 
61  friend class ref;
62  };
63 
74  class ref
75  {
76  InterceptorBase* w;
77  public:
78  inline explicit ref(InterceptorBase* b) : w(b) { w->upcallTls = this; }
79  inline ~ref() { w->upcallTls = NULL; }
80  inline CGUIWindow* operator->() { return w->get(); }
81  inline CGUIWindow* get() { return w->get(); }
82  };
83 
100 #define checkedb(methcall) ( window.isNotNull() ? window-> methcall : false )
101 #define checkedv(methcall) { if (window.isNotNull()) window-> methcall ; }
102 
103  template <class P /* extends CGUIWindow*/> class Interceptor :
104  public P, public InterceptorBase
105  {
106  std::string classname;
107  protected:
108  CGUIWindow* get() override { return this; }
109 
110  public:
111  Interceptor(const char* specializedName,
112  Window* _window, int windowid) : P(windowid, ""),
113  classname("Interceptor<" + std::string(specializedName) + ">")
114  {
115 #ifdef ENABLE_XBMC_TRACE_API
116  XBMCAddonUtils::TraceGuard tg;
117  CLog::Log(LOGDEBUG, "{}NEWADDON constructing {} 0x{:x}", tg.getSpaces(), classname,
118  (long)(((void*)this)));
119 #endif
120  window.reset(_window);
121  P::SetLoadType(CGUIWindow::LOAD_ON_GUI_INIT);
122  }
123 
124  Interceptor(const char* specializedName,
125  Window* _window, int windowid,
126  const char* xmlfile) : P(windowid, xmlfile),
127  classname("Interceptor<" + std::string(specializedName) + ">")
128  {
129 #ifdef ENABLE_XBMC_TRACE_API
130  XBMCAddonUtils::TraceGuard tg;
131  CLog::Log(LOGDEBUG, "{}NEWADDON constructing {} 0x{:x}", tg.getSpaces(), classname,
132  (long)(((void*)this)));
133 #endif
134  window.reset(_window);
135  P::SetLoadType(CGUIWindow::LOAD_ON_GUI_INIT);
136  }
137 
138 #ifdef ENABLE_XBMC_TRACE_API
139  ~Interceptor() override
140  {
141  XBMCAddonUtils::TraceGuard tg;
142  CLog::Log(LOGDEBUG, "{}NEWADDON LIFECYCLE destroying {} 0x{:x}", tg.getSpaces(), classname,
143  (long)(((void*)this)));
144  }
145 #else
146  ~Interceptor() override = default;
147 #endif
148 
149  bool OnMessage(CGUIMessage& message) override
150  { XBMC_TRACE; return up() ? P::OnMessage(message) : checkedb(OnMessage(message)); }
151  bool OnAction(const CAction &action) override
152  { XBMC_TRACE; return up() ? P::OnAction(action) : checkedb(OnAction(action)); }
153 
154  // NOTE!!: This ALWAYS skips up to the CGUIWindow instance.
155  bool OnBack(int actionId) override
156  { XBMC_TRACE; return up() ? CGUIWindow::OnBack(actionId) : checkedb(OnBack(actionId)); }
157 
158  void OnDeinitWindow(int nextWindowID) override
159  { XBMC_TRACE; if(up()) P::OnDeinitWindow(nextWindowID); else checkedv(OnDeinitWindow(nextWindowID)); }
160 
161  bool IsModalDialog() const override
162  {
163  XBMC_TRACE;
164  return checkedb(IsModalDialog());
165  }
166 
167  bool IsDialogRunning() const override
168  {
169  XBMC_TRACE;
170  return checkedb(IsDialogRunning());
171  }
172  bool IsDialog() const override
173  {
174  XBMC_TRACE;
175  return checkedb(IsDialog());
176  }
177  bool IsMediaWindow() const override
178  {
179  XBMC_TRACE;
180  return checkedb(IsMediaWindow());
181  }
182 
183  void SetRenderOrder(int renderOrder) override { XBMC_TRACE; P::m_renderOrder = renderOrder; }
184 
185  void setActive(bool active) override { XBMC_TRACE; P::m_active = active; }
186  bool isActive() override { XBMC_TRACE; return P::m_active; }
187  };
188 
189  template <class P /* extends CGUIWindow*/> class InterceptorDialog :
190  public Interceptor<P>
191  {
192  public:
193  InterceptorDialog(const char* specializedName,
194  Window* _window, int windowid) :
195  Interceptor<P>(specializedName, _window, windowid)
196  { }
197 
198  InterceptorDialog(const char* specializedName,
199  Window* _window, int windowid,
200  const char* xmlfile) :
201  Interceptor<P>(specializedName, _window, windowid,xmlfile)
202  { }
203  };
204 
205 #undef checkedb
206 #undef checkedv
207 
208 #endif
209  }
210 }
This class is a smart pointer for a Referenced class.
Definition: AddonClass.h:154
These two classes are closely associated with the Interceptor template below.
Definition: WindowInterceptor.h:27
Class encapsulating information regarding a particular user action to be sent to windows and controls...
Definition: Action.h:21
Defining LOG_LIFECYCLE_EVENTS will log all instantiations, deletions and also reference countings (in...
Definition: Addon.cpp:25
Definition: GUIMessage.h:365
Definition: GUIWindow.h:58
Definition: Window.h:186
Definition: WindowInterceptor.h:189
Guard class.
Definition: WindowInterceptor.h:74
Definition: WindowInterceptor.h:103
static bool up()
Calling up ONCE resets the upcall to to false.
Definition: WindowInterceptor.h:49