| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- //
- // Copyright (c) 2008-2017 the Urho3D project.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- #pragma once
- #include "../Container/HashSet.h"
- #include "../Core/Attribute.h"
- #include "../Core/Object.h"
- namespace Atomic
- {
- // ATOMIC BEGIN
- class GlobalEventListener
- {
- public:
- virtual void BeginSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData) = 0;
- virtual void EndSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData) = 0;
- };
- // ATOMIC END
- /// Tracking structure for event receivers.
- class ATOMIC_API EventReceiverGroup : public RefCounted
- {
- ATOMIC_REFCOUNTED(EventReceiverGroup);
- public:
- /// Construct.
- EventReceiverGroup() :
- inSend_(0),
- dirty_(false)
- {
- }
- /// Begin event send. When receivers are removed during send, group has to be cleaned up afterward.
- void BeginSendEvent();
- /// End event send. Clean up if necessary.
- void EndSendEvent();
- /// Add receiver. Same receiver must not be double-added!
- void Add(Object* object);
- /// Remove receiver. Leave holes during send, which requires later cleanup.
- void Remove(Object* object);
- /// Receivers. May contain holes during sending.
- PODVector<Object*> receivers_;
- private:
- /// "In send" recursion counter.
- unsigned inSend_;
- /// Cleanup required flag.
- bool dirty_;
- };
- /// Urho3D execution context. Provides access to subsystems, object factories and attributes, and event receivers.
- class ATOMIC_API Context : public RefCounted
- {
- friend class Object;
- ATOMIC_REFCOUNTED(Context)
- public:
- /// Construct.
- Context();
- /// Destruct.
- ~Context();
- /// Create an object by type. Return pointer to it or null if no factory found.
- template <class T> inline SharedPtr<T> CreateObject()
- {
- return StaticCast<T>(CreateObject(T::GetTypeStatic()));
- }
- // ATOMIC BEGIN
- /// Create an object by type hash. Return pointer to it or null if no factory found.
- SharedPtr<Object> CreateObject(StringHash objectType, const XMLElement &source = XMLElement::EMPTY);
- // ATOMIC END
- /// Register a factory for an object type.
- void RegisterFactory(ObjectFactory* factory);
- /// Register a factory for an object type and specify the object category.
- void RegisterFactory(ObjectFactory* factory, const char* category);
- /// Register a subsystem.
- void RegisterSubsystem(Object* subsystem);
- /// Remove a subsystem.
- void RemoveSubsystem(StringHash objectType);
- /// Register object attribute.
- void RegisterAttribute(StringHash objectType, const AttributeInfo& attr);
- /// Remove object attribute.
- void RemoveAttribute(StringHash objectType, const char* name);
- /// Update object attribute's default value.
- void UpdateAttributeDefaultValue(StringHash objectType, const char* name, const Variant& defaultValue);
- /// Return a preallocated map for event data. Used for optimization to avoid constant re-allocation of event data maps.
- VariantMap& GetEventDataMap();
- /// Initialises the specified SDL systems, if not already. Returns true if successful. This call must be matched with ReleaseSDL() when SDL functions are no longer required, even if this call fails.
- bool RequireSDL(unsigned int sdlFlags);
- /// Indicate that you are done with using SDL. Must be called after using RequireSDL().
- void ReleaseSDL();
- #ifdef ATOMIC_IK
- /// Initialises the IK library, if not already. This call must be matched with ReleaseIK() when the IK library is no longer required.
- void RequireIK();
- /// Indicate that you are done with using the IK library.
- void ReleaseIK();
- #endif
- /// Copy base class attributes to derived class.
- void CopyBaseAttributes(StringHash baseType, StringHash derivedType);
- /// Template version of registering an object factory.
- template <class T> void RegisterFactory();
- /// Template version of registering an object factory with category.
- template <class T> void RegisterFactory(const char* category);
- /// Template version of removing a subsystem.
- template <class T> void RemoveSubsystem();
- /// Template version of registering an object attribute.
- template <class T> void RegisterAttribute(const AttributeInfo& attr);
- /// Template version of removing an object attribute.
- template <class T> void RemoveAttribute(const char* name);
- /// Template version of copying base class attributes to derived class.
- template <class T, class U> void CopyBaseAttributes();
- /// Template version of updating an object attribute's default value.
- template <class T> void UpdateAttributeDefaultValue(const char* name, const Variant& defaultValue);
- /// Return subsystem by type.
- Object* GetSubsystem(StringHash type) const;
- /// Return global variable based on key
- const Variant& GetGlobalVar(StringHash key) const ;
- /// Return all global variables.
- const VariantMap& GetGlobalVars() const { return globalVars_; }
- /// Set global variable with the respective key and value
- void SetGlobalVar(StringHash key, const Variant& value);
- /// Return all subsystems.
- const HashMap<StringHash, SharedPtr<Object> >& GetSubsystems() const { return subsystems_; }
- /// Return all object factories.
- const HashMap<StringHash, SharedPtr<ObjectFactory> >& GetObjectFactories() const { return factories_; }
- /// Return all object categories.
- const HashMap<String, Vector<StringHash> >& GetObjectCategories() const { return objectCategories_; }
- /// Return active event sender. Null outside event handling.
- Object* GetEventSender() const;
- /// Return active event handler. Set by Object. Null outside event handling.
- EventHandler* GetEventHandler() const { return eventHandler_; }
- /// Return object type name from hash, or empty if unknown.
- const String& GetTypeName(StringHash objectType) const;
- /// Return a specific attribute description for an object, or null if not found.
- AttributeInfo* GetAttribute(StringHash objectType, const char* name);
- /// Template version of returning a subsystem.
- template <class T> T* GetSubsystem() const;
- /// Template version of returning a specific attribute description.
- template <class T> AttributeInfo* GetAttribute(const char* name);
- /// Return attribute descriptions for an object type, or null if none defined.
- const Vector<AttributeInfo>* GetAttributes(StringHash type) const
- {
- HashMap<StringHash, Vector<AttributeInfo> >::ConstIterator i = attributes_.Find(type);
- return i != attributes_.End() ? &i->second_ : 0;
- }
- /// Return network replication attribute descriptions for an object type, or null if none defined.
- const Vector<AttributeInfo>* GetNetworkAttributes(StringHash type) const
- {
- HashMap<StringHash, Vector<AttributeInfo> >::ConstIterator i = networkAttributes_.Find(type);
- return i != networkAttributes_.End() ? &i->second_ : 0;
- }
- /// Return all registered attributes.
- const HashMap<StringHash, Vector<AttributeInfo> >& GetAllAttributes() const { return attributes_; }
- /// Return event receivers for a sender and event type, or null if they do not exist.
- EventReceiverGroup* GetEventReceivers(Object* sender, StringHash eventType)
- {
- HashMap<Object*, HashMap<StringHash, SharedPtr<EventReceiverGroup> > >::Iterator i = specificEventReceivers_.Find(sender);
- if (i != specificEventReceivers_.End())
- {
- HashMap<StringHash, SharedPtr<EventReceiverGroup> >::Iterator j = i->second_.Find(eventType);
- return j != i->second_.End() ? j->second_ : (EventReceiverGroup*)0;
- }
- else
- return 0;
- }
- /// Return event receivers for an event type, or null if they do not exist.
- EventReceiverGroup* GetEventReceivers(StringHash eventType)
- {
- HashMap<StringHash, SharedPtr<EventReceiverGroup> >::Iterator i = eventReceivers_.Find(eventType);
- return i != eventReceivers_.End() ? i->second_ : (EventReceiverGroup*)0;
- }
- // ATOMIC BEGIN
- /// Get whether an Editor Context
- bool GetEditorContext() { return editorContext_; }
- /// Get whether an Editor Context
- void SetEditorContext(bool editor) { editorContext_ = editor; }
- // hook for listening into events
- void AddGlobalEventListener(GlobalEventListener* listener) { globalEventListeners_.Push(listener); }
- void RemoveGlobalEventListener(GlobalEventListener* listener) { globalEventListeners_.Erase(globalEventListeners_.Find(listener)); }
- Engine* GetEngine() const { return engine_; }
- Time* GetTime() const { return time_; }
- WorkQueue* GetWorkQueue() const { return workQueue_; }
- Profiler* GetProfiler() const { return profiler_; }
- FileSystem* GetFileSystem() const { return fileSystem_; }
- Log* GetLog() const { return log_; }
- ResourceCache* GetResourceCache() const { return cache_; }
- Localization* GetLocalization() const { return l18n_; }
- Network* GetNetwork() const { return network_; }
- Web* GetWeb() const { return web_; }
- Database* GetDatabase() const { return db_; }
- Input* GetInput() const { return input_; }
- Audio* GetAudio() const { return audio_; }
- UI* GetUI() const { return ui_; }
- SystemUI* GetSystemUI() const { return systemUi_; }
- Graphics* GetGraphics() const { return graphics_; }
- Renderer* GetRenderer() const { return renderer_; }
- Console* GetConsole() const { return console_; }
- DebugHud* GetDebugHud() const { return debugHud_; }
- Metrics* GetMetrics() const { return metrics_; }
- // ATOMIC END
- private:
- /// Add event receiver.
- void AddEventReceiver(Object* receiver, StringHash eventType);
- /// Add event receiver for specific event.
- void AddEventReceiver(Object* receiver, Object* sender, StringHash eventType);
- /// Remove an event sender from all receivers. Called on its destruction.
- void RemoveEventSender(Object* sender);
- /// Remove event receiver from specific events.
- void RemoveEventReceiver(Object* receiver, Object* sender, StringHash eventType);
- /// Remove event receiver from non-specific events.
- void RemoveEventReceiver(Object* receiver, StringHash eventType);
- /// Begin event send.
- void BeginSendEvent(Object* sender, StringHash eventType);
- /// End event send. Clean up event receivers removed in the meanwhile.
- void EndSendEvent();
- /// Set current event handler. Called by Object.
- void SetEventHandler(EventHandler* handler) { eventHandler_ = handler; }
- /// Object factories.
- HashMap<StringHash, SharedPtr<ObjectFactory> > factories_;
- /// Subsystems.
- HashMap<StringHash, SharedPtr<Object> > subsystems_;
- /// Attribute descriptions per object type.
- HashMap<StringHash, Vector<AttributeInfo> > attributes_;
- /// Network replication attribute descriptions per object type.
- HashMap<StringHash, Vector<AttributeInfo> > networkAttributes_;
- /// Event receivers for non-specific events.
- HashMap<StringHash, SharedPtr<EventReceiverGroup> > eventReceivers_;
- /// Event receivers for specific senders' events.
- HashMap<Object*, HashMap<StringHash, SharedPtr<EventReceiverGroup> > > specificEventReceivers_;
- /// Event sender stack.
- PODVector<Object*> eventSenders_;
- /// Event data stack.
- PODVector<VariantMap*> eventDataMaps_;
- /// Active event handler. Not stored in a stack for performance reasons; is needed only in esoteric cases.
- EventHandler* eventHandler_;
- /// Object categories.
- HashMap<String, Vector<StringHash> > objectCategories_;
- /// Variant map for global variables that can persist throughout application execution.
- VariantMap globalVars_;
- // ATOMIC BEGIN
- /// Begin event send.
- void GlobalBeginSendEvent(Object* sender, StringHash eventType, VariantMap& eventData) {
- for (unsigned i = 0; i < globalEventListeners_.Size(); i++)
- globalEventListeners_[i]->BeginSendEvent(this, sender, eventType, eventData);
- eventSenders_.Push(sender);
- }
- /// End event send. Clean up event receivers removed in the meanwhile.
- void GlobalEndSendEvent(Object* sender, StringHash eventType, VariantMap& eventData) {
- for (unsigned i = 0; i < globalEventListeners_.Size(); i++)
- globalEventListeners_[i]->EndSendEvent(this, sender, eventType, eventData);
- eventSenders_.Pop();
- }
- PODVector<GlobalEventListener*> globalEventListeners_;
- bool editorContext_;
- WeakPtr<Engine> engine_;
- WeakPtr<Time> time_;
- WeakPtr<WorkQueue> workQueue_;
- WeakPtr<Profiler> profiler_;
- WeakPtr<FileSystem> fileSystem_;
- WeakPtr<Log> log_;
- WeakPtr<ResourceCache> cache_;
- WeakPtr<Localization> l18n_;
- WeakPtr<Network> network_;
- WeakPtr<Web> web_;
- WeakPtr<Database> db_;
- WeakPtr<Input> input_;
- WeakPtr<Audio> audio_;
- WeakPtr<UI> ui_;
- WeakPtr<SystemUI> systemUi_;
- WeakPtr<Graphics> graphics_;
- WeakPtr<Renderer> renderer_;
- WeakPtr<Console> console_;
- WeakPtr<DebugHud> debugHud_;
- WeakPtr<Metrics> metrics_;
- friend class Engine;
- // ATOMIC END
- };
- template <class T> void Context::RegisterFactory() { RegisterFactory(new ObjectFactoryImpl<T>(this)); }
- template <class T> void Context::RegisterFactory(const char* category)
- {
- RegisterFactory(new ObjectFactoryImpl<T>(this), category);
- }
- template <class T> void Context::RemoveSubsystem() { RemoveSubsystem(T::GetTypeStatic()); }
- template <class T> void Context::RegisterAttribute(const AttributeInfo& attr) { RegisterAttribute(T::GetTypeStatic(), attr); }
- template <class T> void Context::RemoveAttribute(const char* name) { RemoveAttribute(T::GetTypeStatic(), name); }
- template <class T, class U> void Context::CopyBaseAttributes() { CopyBaseAttributes(T::GetTypeStatic(), U::GetTypeStatic()); }
- template <class T> T* Context::GetSubsystem() const { return static_cast<T*>(GetSubsystem(T::GetTypeStatic())); }
- template <class T> AttributeInfo* Context::GetAttribute(const char* name) { return GetAttribute(T::GetTypeStatic(), name); }
- template <class T> void Context::UpdateAttributeDefaultValue(const char* name, const Variant& defaultValue)
- {
- UpdateAttributeDefaultValue(T::GetTypeStatic(), name, defaultValue);
- }
- }
|