diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/interfaces/legacy/LanguageHook.h | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/interfaces/legacy/LanguageHook.h')
-rw-r--r-- | xbmc/interfaces/legacy/LanguageHook.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/xbmc/interfaces/legacy/LanguageHook.h b/xbmc/interfaces/legacy/LanguageHook.h new file mode 100644 index 0000000..86abdac --- /dev/null +++ b/xbmc/interfaces/legacy/LanguageHook.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "AddonClass.h" +#include "CallbackHandler.h" +#include "threads/Event.h" + +/** + * This class is an interface that can be used to define programming language + * specific hooks. + */ + +class IPlayerCallback; + +namespace XBMCAddon +{ + namespace xbmc + { + class Monitor; + } + + class LanguageHook : public AddonClass + { + protected: + inline LanguageHook() = default; + + public: + ~LanguageHook() override; + + /** + * If the scripting language needs special handling for calls + * that block or are delayed in any other means, this should + * be overloaded. + * + * In Python when control is passed to a native + * method that blocks, you need to allow other threads in + * Python to run by using Py_BEGIN_ALLOW_THREADS. This is + * the place to put that functionality + */ + virtual void DelayedCallOpen() { } + + /** + * If the scripting language needs special handling for calls + * that block or are delayed in any other means, this should + * be overloaded. + * + * In Python when control is passed to a native + * method that blocks, you need to allow other threads in + * Python to run by using Py_BEGIN_ALLOW_THREADS. When that + * delayed method ends you need to restore the Python thread + * state using Py_END_ALLOW_THREADS. This is the place to put + * that functionality + */ + virtual void DelayedCallClose() { } + + virtual void MakePendingCalls() {} + + /** + * For scripting languages that need a global callback handler, this + * method should be overloaded to supply one. + */ + virtual CallbackHandler* GetCallbackHandler() { return NULL; } + + /** + * This is a callback method that can be overridden to receive a callback + * when an AddonClass that has this language hook is on is being constructed. + * It is called from the constructor of AddonClass so the implementor + * cannot assume the subclasses have been built or that calling a + * virtual function on the AddonClass will work as expected. + */ + virtual void Constructing(AddonClass* beingConstructed) { } + + /** + * This is a callback method that can be overridden to receive a callback + * when an AddonClass that has this language hook is on is being destructed. + * It is called from the destructor of AddonClass so the implementor + * should assume the subclasses have been torn down and that calling a + * virtual function on the AddonClass will not work as expected. + */ + virtual void Destructing(AddonClass* beingDestructed) { } + + /** + * This method should be done a different way but since the only other way + * I can think to do it requires an InheritableThreadLocal C++ equivalent, + * I'm going to defer to this technique for now. + * + * Currently (for python) the scripting language has the Addon id injected + * into it as a global variable. Therefore the only way to retrieve it is + * to use scripting language specific calls. So until I figure out a + * better way to do this, this is how I need to retrieve it. + */ + virtual String GetAddonId() { return emptyString; } + virtual String GetAddonVersion() { return emptyString; } + virtual long GetInvokerId() { return -1; } + + virtual void RegisterPlayerCallback(IPlayerCallback* player) = 0; + virtual void UnregisterPlayerCallback(IPlayerCallback* player) = 0; + virtual void RegisterMonitorCallback(XBMCAddon::xbmc::Monitor* player) = 0; + virtual void UnregisterMonitorCallback(XBMCAddon::xbmc::Monitor* player) = 0; + virtual bool WaitForEvent(CEvent& hEvent, unsigned int milliseconds) = 0; + + static void SetLanguageHook(LanguageHook* languageHook); + static LanguageHook* GetLanguageHook(); + static void ClearLanguageHook(); + }; + + /** + * This class can be used to access the language hook's DelayedCallOpen + * and DelayedCallClose. It should be used whenever an API method + * is written such that it can block for an indefinite amount of time + * since certain scripting languages (like Python) need to do extra + * work for delayed calls (like free the python locks and handle + * callbacks). + */ + class DelayedCallGuard + { + LanguageHook* languageHook; + bool clearOnExit = false; + + public: + inline explicit DelayedCallGuard(LanguageHook* languageHook_) : languageHook(languageHook_) + { if (languageHook) languageHook->DelayedCallOpen(); } + + inline DelayedCallGuard() : languageHook(LanguageHook::GetLanguageHook()) + { if (languageHook) languageHook->DelayedCallOpen(); } + + inline ~DelayedCallGuard() + { + if (clearOnExit) LanguageHook::ClearLanguageHook(); + if (languageHook) languageHook->DelayedCallClose(); + } + + inline LanguageHook* getLanguageHook() { return languageHook; } + }; + + class SetLanguageHookGuard + { + public: + inline explicit SetLanguageHookGuard(LanguageHook* languageHook) { LanguageHook::SetLanguageHook(languageHook); } + inline ~SetLanguageHookGuard() { LanguageHook::ClearLanguageHook(); } + }; + +} + |