| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- /************************************************************************************
- PublicHeader: Kernel
- Filename : OVR_Callbacks.h
- Content : Callback library
- Created : June 20, 2014
- Author : Chris Taylor
- Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
- Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
- you may not use the Oculus VR Rift SDK except in compliance with the License,
- which is provided at the time of installation or download, or which
- otherwise accompanies this software in either electronic or hard copy form.
- You may obtain a copy of the License at
- http://www.oculusvr.com/licenses/LICENSE-3.2
- Unless required by applicable law or agreed to in writing, the Oculus VR SDK
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ************************************************************************************/
- #ifndef OVR_Callbacks_h
- #define OVR_Callbacks_h
- #include "OVR_CallbacksInternal.h"
- #include "OVR_String.h" // For CallbackHash
- #include "OVR_Hash.h" // For CallbackHash
- namespace OVR {
- //-----------------------------------------------------------------------------
- // CallbackEmitter
- //
- // Emitter of callbacks.
- // Thread-safety: All public members may be safely called concurrently.
- template<class DelegateT>
- class CallbackEmitter : public NewOverrideBase
- {
- public:
- CallbackEmitter();
- ~CallbackEmitter();
- // Add a listener.
- bool AddListener(CallbackListener<DelegateT>* listener);
- // Get the current number of listeners. Note that this can change as other threads
- // add listeners to the emitter.
- int GetListenerCount() const;
- bool HasListeners() const
- {
- return Emitter->HasListeners();
- }
- void Call()
- {
- Emitter->Call();
- }
- template<class Param1>
- void Call(Param1* p1)
- {
- Emitter->Call(p1);
- }
- template<class Param1>
- void Call(Param1& p1)
- {
- Emitter->Call(p1);
- }
- template<class Param1, class Param2>
- void Call(Param1* p1, Param2* p2)
- {
- Emitter->Call(p1, p2);
- }
- template<class Param1, class Param2>
- void Call(Param1& p1, Param2& p2)
- {
- Emitter->Call(p1, p2);
- }
- template<class Param1, class Param2, class Param3>
- void Call(Param1* p1, Param2* p2, Param3* p3)
- {
- Emitter->Call(p1, p2, p3);
- }
- template<class Param1, class Param2, class Param3>
- void Call(Param1& p1, Param2& p2, Param3& p3)
- {
- Emitter->Call(p1, p2, p3);
- }
- // Remove all listeners and prevent further listeners from being added.
- void Shutdown();
- protected:
- Ptr< FloatingCallbackEmitter<DelegateT> > Emitter;
- };
- //-----------------------------------------------------------------------------
- // CallbackListener
- //
- // Listener for callbacks.
- // Thread-safety: Operations on a listener are not thread-safe.
- // The listener may only listen to *one emitter* at a time.
- template<class DelegateT>
- class CallbackListener : public NewOverrideBase
- {
- friend class CallbackEmitter<DelegateT>;
- public:
- CallbackListener();
- ~CallbackListener();
- // Stop listening to callbacks.
- // And set a new handler for callbacks.
- void SetHandler(DelegateT handler);
- // Is listening to an emitter at this instant?
- // If the Emitter has shutdown, then this may inaccurately return true.
- bool IsListening() const;
- // Stops listening to callbacks.
- void Cancel();
- protected:
- /// Internal data:
- // Reference to the associated listener.
- Ptr< FloatingCallbackListener<DelegateT> > FloatingListener;
- // Reference to the associated emitter.
- Ptr< FloatingCallbackEmitter<DelegateT> > FloatingEmitter;
- DelegateT Handler;
- };
- //-----------------------------------------------------------------------------
- // Template Implementation: CallbackEmitter
- template<class DelegateT>
- CallbackEmitter<DelegateT>::CallbackEmitter()
- {
- Emitter = *new FloatingCallbackEmitter<DelegateT>;
- }
- template<class DelegateT>
- CallbackEmitter<DelegateT>::~CallbackEmitter()
- {
- Emitter->Shutdown();
- // Emitter goes out of scope here.
- }
- template<class DelegateT>
- bool CallbackEmitter<DelegateT>::AddListener(CallbackListener<DelegateT>* listener)
- {
- // The listener object can only be attached to one emitter at a time.
- // The caller should explicitly Cancel() a listener before listening
- // to a new emitter, even if it is the same emitter.
- OVR_ASSERT(!listener->FloatingEmitter && !listener->FloatingListener);
- if (listener->FloatingEmitter || listener->FloatingListener)
- {
- // Cancel any previous listening
- listener->Cancel();
- }
- // Set the floating listener and emitter
- listener->FloatingListener = *new FloatingCallbackListener<DelegateT>(listener->Handler);
- listener->FloatingEmitter = Emitter.GetPtr();
- // The remaining input checks are performed inside.
- return Emitter->AddListener(listener->FloatingListener);
- }
- template<class DelegateT>
- int CallbackEmitter<DelegateT>::GetListenerCount() const
- {
- return Emitter->Listeners.GetSizeI();
- }
- template<class DelegateT>
- void CallbackEmitter<DelegateT>::Shutdown()
- {
- Emitter->Shutdown();
- }
- //-----------------------------------------------------------------------------
- // Template Implementation: CallbackListener
- template<class DelegateT>
- CallbackListener<DelegateT>::CallbackListener()
- {
- // Listener is null until a handler is set.
- }
- template<class DelegateT>
- CallbackListener<DelegateT>::~CallbackListener()
- {
- Cancel();
- }
- template<class DelegateT>
- void CallbackListener<DelegateT>::Cancel()
- {
- if (FloatingListener)
- {
- FloatingListener->EnterCancelState();
- }
- if (FloatingEmitter)
- {
- if (FloatingListener)
- {
- FloatingEmitter->OnListenerCancel(FloatingListener);
- }
- }
- // FloatingEmitter goes out of scope here.
- FloatingEmitter = nullptr;
- // FloatingListener goes out of scope here.
- FloatingListener = nullptr;
- }
- template<class DelegateT>
- void CallbackListener<DelegateT>::SetHandler(DelegateT handler)
- {
- Cancel();
- Handler = handler;
- }
- template<class DelegateT>
- bool CallbackListener<DelegateT>::IsListening() const
- {
- if (!FloatingListener.GetPtr())
- {
- return false;
- }
- return FloatingListener->IsValid();
- }
- //-----------------------------------------------------------------------------
- // CallbackHash
- //
- // A hash containing CallbackEmitters
- template<class DelegateT>
- class CallbackHash : public NewOverrideBase
- {
- typedef Hash<String, CallbackEmitter<DelegateT>*, String::HashFunctor> HashTable;
- public:
- ~CallbackHash()
- {
- Clear();
- }
- void Clear()
- {
- for (auto ii = Table.Begin(); ii != Table.End(); ++ii)
- {
- delete ii->Second;
- }
- Table.Clear();
- }
- CallbackEmitter<DelegateT>* GetKey(String key)
- {
- CallbackEmitter<DelegateT>** emitter = Table.Get(key);
- if (emitter)
- {
- return *emitter;
- }
- return nullptr;
- }
- void AddListener(String key, CallbackListener<DelegateT>* listener)
- {
- CallbackEmitter<DelegateT>** pEmitter = Table.Get(key);
- CallbackEmitter<DelegateT>* emitter = nullptr;
- if (!pEmitter)
- {
- emitter = new CallbackEmitter<DelegateT>;
- Table.Add(key, emitter);
- }
- else
- {
- emitter = *pEmitter;
- }
- emitter->AddListener(listener);
- }
- void RemoveKey(String key)
- {
- CallbackEmitter<DelegateT>** emitter = Table.Get(key);
- if (emitter)
- {
- delete *emitter;
- Table.Remove(key);
- }
- }
- protected:
- HashTable Table; // Hash table
- };
- } // namespace OVR
- #endif // OVR_Callbacks_h
|