{"id":16710750,"url":"https://github.com/overminddl1/urho3d-overlib","last_synced_at":"2025-07-10T17:31:34.008Z","repository":{"id":25967393,"uuid":"29409327","full_name":"OvermindDL1/Urho3D-OverLib","owner":"OvermindDL1","description":"Urho3D Extra library helpers","archived":false,"fork":false,"pushed_at":"2015-01-18T01:18:45.000Z","size":160,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-05T16:06:15.471Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OvermindDL1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-17T23:26:21.000Z","updated_at":"2025-01-01T06:37:26.000Z","dependencies_parsed_at":"2022-08-24T07:10:06.822Z","dependency_job_id":null,"html_url":"https://github.com/OvermindDL1/Urho3D-OverLib","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/OvermindDL1/Urho3D-OverLib","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2FUrho3D-OverLib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2FUrho3D-OverLib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2FUrho3D-OverLib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2FUrho3D-OverLib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OvermindDL1","download_url":"https://codeload.github.com/OvermindDL1/Urho3D-OverLib/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2FUrho3D-OverLib/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264619021,"owners_count":23638394,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T20:09:28.651Z","updated_at":"2025-07-10T17:31:31.035Z","avatar_url":"https://github.com/OvermindDL1.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Urho3D-OverLib\nUrho3D Extra library helpers\n\nThese are various repeated bits of code I use in my projects, not everything,\nbut it may be added to over time.  These are designed to be generic, fast,\nlittle-to-no overhead, and useful.  Pull requests are always welcome.\n\n## How to use\nJust git clone or copy this project in to your project and in your\nCMakeLists.txt file add a line of `add_subdirectory(Urho3D-OverLib)` then just add the\nlibrary and headers to your project via the normal CMake way, such as in:\n```cmake\ntarget_link_libraries (${TARGET_NAME} Urho3D-OverLib)\ninclude_directories(${OverLib_SOURCE_DIR}/include)\n```\n\n## Information and Disclaimer\nEverything defined in OverLib is in use by projects and has been tested to have\nno faults with the use that it was designed for, but if any bugs are found then\nplease send pull requests with fixes.  If any new features are wanted then also\nplease send pull requests with the new features.  On occasion this library may\nbe updated as the root project grows as well, for example the next update may be\nan Input Mapper as that exists in the multiple parent projects and needs to be\nmade more generic as well.\n\n## Sections of library\n\n### OverLib\nThe OverLib class contains a few basic helpers, mostly designed for applications.\nIt can either by multi-subclassed by your Application subclass such as in:\n```cpp\nclass URHO3D_API OverAssault_Application : public Urho3D::Application, public Urho3D::OverLib::OverLib\n{\n    // Urho3D Type Information System\n    OBJECT(OverAssault_Application);\n```\nOr it can be used directly as it has static members.\n\nThe members it has at the time of the writing of this Readme are:\n\n```cpp\ntemplate \u003cclass T\u003e static T* GetOrCreateSubSystem(Urho3D::Context* context);\n```\nThis will either get a given subsystem or create it if it does not exist if it\nhas a constructor that just takes a Context.  Plan to add C++ Move support for\nperfect forwarding if a need comes up for it\n\n```cpp\ntemplate \u003cclass T\u003e static void SendBackgroundLoadResource(Urho3D::Context* context, const Urho3D::String\u0026 name, bool sendEventOnFailure = true, Urho3D::Resource* caller = 0);\n```\nThis is a wrapper for the normal Urho3D `ResourceCache::BackgroundLoadResource`\nmethod that will background load the given resource if it is not already loaded,\nor will just load the existing resource if it already is.  Unlike the normal\nUrho3D method this will always send the events of success/fail as appropriate\neven if it loaded an already existing resource, thus your code for background\nresource loading stays more clean and in one spot.\n\n### AttributeEditor\nThis namespace is primarily a partial porting of the AttributeEditor code from\nthe Urho3D Editor to C++, its static functions in OverLib::AttrributeEditor are:\n```cpp\nUrho3D::SharedPtr\u003cUrho3D::UIElement\u003e CreateAttributeEditor(Urho3D::Context* context, Urho3D::XMLFile* style, const Urho3D::AttributeInfo\u0026 info, unsigned int index, unsigned int subIndex);\n\nUrho3D::SharedPtr\u003cUrho3D::UIElement\u003e CreateBoolAttributeEditor(Urho3D::Context* context, Urho3D::XMLFile* style, const Urho3D::AttributeInfo\u0026 info, unsigned int index, unsigned int subIndex);\n\nUrho3D::SharedPtr\u003cUrho3D::UIElement\u003e CreateNumAttributeEditor(Urho3D::Context* context, Urho3D::XMLFile* style, const Urho3D::AttributeInfo\u0026 info, unsigned int index, unsigned int subIndex);\n\nUrho3D::SharedPtr\u003cUrho3D::UIElement\u003e CreateStringAttributeEditor(Urho3D::Context* context, Urho3D::XMLFile* style, const Urho3D::AttributeInfo\u0026 info, unsigned int index, unsigned int subIndex);\n\nUrho3D::SharedPtr\u003cUrho3D::UIElement\u003e CreateAttributeEditorParent(Urho3D::Context* context, Urho3D::XMLFile* style, const Urho3D::String\u0026 name, unsigned int index, unsigned int subIndex);\n\nUrho3D::SharedPtr\u003cUrho3D::LineEdit\u003e CreateAttributeLineEdit(Urho3D::Context* context, Urho3D::XMLFile* style, const Urho3D::String\u0026 name, unsigned int index, unsigned int subIndex);\n\nvoid SetValue(Urho3D::UIElement* toElement, const Urho3D::Variant\u0026 fromValue);\nUrho3D::Variant GetValue(const Urho3D::Variant\u0026 toValueWithDefault, const Urho3D::UIElement* fromElement);\n```\nThey will return a properly named set of UI Elements that you can bind and\nlisten to as normal, for example I use it like:\n```cpp\n                Settings *settings = GetSubsystem\u003cSettings\u003e();\n                XMLFile *style = GetSubsystem\u003cUI\u003e()-\u003eGetRoot()-\u003eGetDefaultStyle();\n                const Vector\u003cAttributeInfo\u003e\u0026 attrs = *settings-\u003eGetAttributes();\n                for(int i=0; i\u003cattrs.Size(); ++i)\n                {\n                    if(attrs[i].mode_ \u0026 AM_NOEDIT) continue;\n                    SharedPtr\u003cUIElement\u003e elem(AttributeEditor::CreateAttributeEditor(\n                            context_,\n                            style,\n                            attrs[i],\n                            i, 1\n                    ));\n                    if(elem) optionsList-\u003eAddItem(elem);\n```\nThen I load/save from/to it as in:\n```cpp\nvoid StateMainMenu::LoadFromSettings()\n{\n    Settings* settings = GetSubsystem\u003cSettings\u003e();\n    const Vector\u003cAttributeInfo\u003e\u0026 attrs = *settings-\u003eGetAttributes();\n    for(int i=0; i\u003cattrs.Size(); ++i)\n    {\n        const AttributeInfo \u0026attr = attrs[i];\n        if(attr.mode_ \u0026 AM_NOEDIT) continue;\n        const Variant \u0026value = settings-\u003eGetAttribute(i);\n        UIElement *elem = uiOptions_-\u003eGetChild(attr.name_, true);\n        if(!elem)\n        {\n            LOGWARNING(\"Unable to find the UI Element to set: \" + attr.name_);\n            continue;\n        }\n        AttributeEditor::SetValue(elem, value);\n    }\n}\n\nvoid StateMainMenu::SaveToSettings()\n{\n    Settings *settings = GetSubsystem\u003cSettings\u003e();\n    const Vector\u003cAttributeInfo\u003e\u0026 attrs = *settings-\u003eGetAttributes();\n    for(int i=0; i\u003cattrs.Size(); ++i)\n    {\n        const AttributeInfo \u0026attr = attrs[i];\n        if(attr.mode_ \u0026 AM_NOEDIT) continue;\n        UIElement *elem = uiOptions_-\u003eGetChild(attr.name_, true);\n        if(!elem)\n        {\n            LOGWARNING(\"Unable to find the UI Element to get: \" + attr.name_);\n            continue;\n        }\n        const Variant \u0026origValue = settings-\u003eGetAttribute(i);\n        const Variant \u0026value = AttributeEditor::GetValue(origValue, elem);\n        if(origValue != value) settings-\u003eSetAttribute(i, value);\n    }\n\n    Graphics *graphics = GetSubsystem\u003cGraphics\u003e();\n    if(graphics) graphics-\u003eSetMode(\n        settings-\u003ewindowResolution_.x_,\n        settings-\u003ewindowResolution_.y_,\n        settings-\u003ewindowFullscreen_,\n        settings-\u003ewindowBorderless_,\n        settings-\u003ewindowResizable_,\n        settings-\u003ewindowVsync_,\n        settings-\u003ewindowTripleBuffer_,\n        settings-\u003eGetWindowMultiSampleLevel());\n\n    settings-\u003eSaveSettingsFile();\n}\n```\nNOTE: This is *NOT* complete, lacking a couple of attribute editors, but it was\ncomplete enough for my use and may be expanded later.  As always pull requests\nare welcome.\n\n### StateManager\nThis is a high-level StateManager, its purpose is not to handle a stack of\nstates (though you can do that with its interfaces yourself), but rather is an\nUrho3D Event style state manager, primarily to handle timing, transitions, and\nloading screens between states.\nThe events it defines are:\n```cpp\n/// %StatePreStart is sent to a state when it is about to load, it is to let\n/// it preload its assets and prepare its scene\nEVENT(E_STATEPRESTART, StatePreStart)\n{\n}\n\n/// %StateStart is sent when it is time to add its rendering data to the scene\n/// and to fully activate.  This should be fast\nEVENT(E_STATESTART, StateStart)\n{\n}\n\n/// %StateEnd is sent when it needs to stop its rendering, such as removing\n/// nodes and whatever else, this should be fast\nEVENT(E_STATEEND, StateEnd)\n{\n}\n\n/// %StatePostEnd is sent when the state is being removed, allowing it to\n/// clean up assets and whatever else it may need\nEVENT(E_STATEPOSTEND, StatePostEnd)\n{\n}\n\n/// %StateLoadingUpdate is received primarily just by the Loading State,\n/// it receives a message posted by the loading state between its PreStart\n/// and its Start to allow it to display the state of its loading.\nEVENT(E_STATELOADINGUPDATE, StateLoadingUpdate)\n{\n    PARAM(P_MESSAGE, Message); // String\n}\n\n/// %StateLoadingStart is sent globally to announce a state change has\n/// started\nEVENT(E_STATELOADINGSTART, StateLoadingStart)\n{\n    PARAM(P_OLDSTATE, OldState); // Old StateObject\n    PARAM(P_NEWSTATE, NewState); // New StateObject\n}\n\n/// %StateLoadingEnd is sent globally to announce a state change has\n/// finished and is now fully loaded and operational\nEVENT(E_STATELOADINGEND, StateLoadingEnd)\n{\n    PARAM(P_NEWSTATE, NewState); // New StateObject\n}\n```\nThose are primarily designed to be used by the State's themselves, which are not\na subclass nor required to subclass anything, they can be any normal Urho3D\nObject.  This does, however, contain a helper class to do the grunt work and\nbinding for you:\n```cpp\nclass URHO3D_API StateObject : public Urho3D::Object\n{\n    OBJECT(StateObject);\n\npublic:\n    StateObject(Urho3D::Context* context);\n\nprotected:\n    virtual void HandleStatePreStart(Urho3D::StringHash eventType, Urho3D::VariantMap\u0026 eventData);\n    virtual void HandleStateStart(Urho3D::StringHash eventType, Urho3D::VariantMap\u0026 eventData);\n    virtual void HandleStateEnd(Urho3D::StringHash eventType, Urho3D::VariantMap\u0026 eventData);\n    virtual void HandleStatePostEnd(Urho3D::StringHash eventType, Urho3D::VariantMap\u0026 eventData);\n    virtual void HandleLoadingUpdate(Urho3D::StringHash eventType, Urho3D::VariantMap\u0026 eventData);\n\nprotected:\n    void PostLoadingUpdate(const Urho3D::String\u0026 msg);\n    void PostLoadingComplete();\n};\n```\nIf you subclass StateObject then you can optionally inherit any of the Handle\nmethods to do what you need at whatever times, for example you can start loading\nassets in PreStart (background loading is great here!), updating your progress\nby calling PosLoadingUpdate with a string/message of how your loading is going,\nthis could just be a message announcing the percentage complete, or what you are\nloading or just loaded, or just leave it blank, however you want to handle it.\nOnce loading is complete across your frames and you are to a state where you can\nactually begin rendering (say that enough of your resources have background\nloaded) then call PostLoadingComplete, which will then call your Start callback\nand unload what was before.  PostLoadingUpdate and postLoadingComplete only\ncall these respectively (if you are not using the helper class):\n```cpp\n// PostLoadingUpdate\nGetSubsystem\u003cOverLib::StateManager\u003e()-\u003ePostLoadingUpdate(msg);\n\n// PostLoadingComplete\nGetSubsystem\u003cOverLib::StateManager\u003e()-\u003ePostLoadingComplete();\n```\n\nThe End event is where you should stop rendering your parts 'now', just a simple\nunhooking from the scene or whatever else.  You can then do your background\nunloading in the PostEnd event.\n\nThe LoadingUpdate event is only passed to a state that is a Loading state.  The\nLoading state is like any other normal state, except it is always loaded (though\nnot Start'ed until time) in the background and is switched to whenever an old\nstate is unloaded but the new state has not yet finished loading its starting\nassets, it receives a message from the loading state that you can display to\nupdate the user of the loading progress if you wish, but is otherwise a normal\nstate like any other so you can render models, animations, just display a splash\nimage, whatever you wish.\n\nThe StateManager itself is defined as such:\n```cpp\n/// %StateManager able to be set as a SubSystem in Urho3D\nclass URHO3D_API StateManager : public Urho3D::Object\n{\n    OBJECT(StateManager);\n\npublic:\n    /// Construct.\n    StateManager(Urho3D::Context* context);\n    /// Constructor with an initial loading state\n    StateManager(Urho3D::Context* context, Urho3D::Object* loadingState);\n    /// Destruct.\n    ~StateManager();\n\npublic:\n    void SetState(Urho3D::Object* state);\n    Urho3D::Object* GetState();\n\n    void SetLoadingState(Urho3D::Object* loadingState);\n    Urho3D::Object* GetLoadingState();\n\npublic: // Only for use by the States themselves\n    void PostLoadingUpdate(Urho3D::String msg);\n    void PostLoadingComplete();\n}\n```\nIt can be constructed with no loading state (a clear screen will display when\nstates are being changed but there is no loading state defined) or by including\na loading state, and the loading state can be changed at any point by calling\n`SetLoadingState` with it.  To change the active state itself then just call\nSetState with the new state, it will then follow these steps:\n\n1. Verifies no state transition is already in progress, or it throws.\n2. PreStarts the Loading state if it exists.\n3. Ends the old state if it exists.\n4. Starts the loading state if it exists.\n5. PostEnds the old state if it exists.\n6. PreStarts the new state if it exists.\n\nA this point it then returns and normal rendering proceeds as normal.  The state\nthat is starting up can call PostLoadingUpdate to pass the loading status to the\nloading state so it can display updates if both wish. Once the new state calls\nPostLoadingComplete (irrespective of if PostLoadingUpdate is ever called or not)\nthen the following happens:\n\n1. If it is not currently state transitioning (say if PostLoadingComplete is\ncalled without GetState ever having been called), then it throws.\n2. Ends the loading state.\n3. Starts the new state\n4. PostEnds the loading state\n\nIn general the loading state does its asset loading in its constructor so it is\nalways and quickly available, unless of course your loading state is a more\ncomplex scene, then load the resources immediately.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foverminddl1%2Furho3d-overlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foverminddl1%2Furho3d-overlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foverminddl1%2Furho3d-overlib/lists"}