dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6

Thread: Gobally available Service with scoped Lifetime

  1. #1
    Join Date
    Jul 2016
    Posts
    4

    Gobally available Service with scoped Lifetime

    Hey

    I am currently working on a game and ran into a very usual problem in game development.
    What I am trying to do, is providing global and scoped access to Services/Subsystems (e.g. Graphics renderer) that are not static.

    Basicly 'Provider' is a template for actual providers (e.g. GraphicsProvider), whose hold pointers to services, that then can be accesst through 'Get<T>()' from all over the code.
    Get will return nullptr if there is no provider holding the service, or if there is no service registered to the provider.
    Please have a look into main.cpp to get an idea of how it is used.

    full code:
    main.cpp
    provider.h
    traits.h

    Do you have advide or a better solution?
    What do you think about this approach?

    Thanks lots

  2. #2
    Join Date
    Aug 2006
    Posts
    232

    Re: Gobally available Service with scoped Lifetime

    Code:
    static Provider *s_pInstance;
    Looks static to me.

    Don't you need the graphics renderer during the whole lifetime of the application? Then with your solution the "scoped" object is practically global anyway.

    Do you really need to access these services/subsystems from all over your codebase?

    You should strive to design your program in a way that minimizes dependencies.
    Last edited by TubularX; July 21st, 2016 at 10:25 AM.

  3. #3
    Join Date
    Jul 2016
    Posts
    4

    Re: Gobally available Service with scoped Lifetime

    Quote Originally Posted by TubularX View Post
    Don't you need the graphics renderer during the whole lifetime of the application? Then with your solution the "scoped" object is practically global anyway.
    This is true for Graphics, but might not be for other services.

    Quote Originally Posted by TubularX View Post
    Do you really need to access these services/subsystems from all over your codebase?

    You should strive to design your program in a way that minimizes dependencies.
    I would like to seperate 'engine' and 'game', even though the engine is built to fit the game (not like unity, being a general approach). To minimize dependencies, only one of them should know the other.
    If the engine knows the game, i can adjust it and improve the overall communication between game and engine. In this case only the engine needs to know about Graphics for example, because the engine will take care of routines (rendering, update, etc.) and requires data from game.
    This way the 'game' is a very simple abstraction of what happens in terms of game logic and in the same time a database for the engine that presents contents to the user.
    How do you think about this?

    What do you think about the Provider thingy in general?

  4. #4
    Join Date
    Aug 2006
    Posts
    232

    Re: Gobally available Service with scoped Lifetime

    Well, I'm not convinced with the idea of "global and scoped access". Isn't it just global state in disguise? What's the benefits compared to using a global pointer with a scope guard? The performance of Provider is worse, because it requires extra overhead "if(provider::s_pInstance)" every time you're getting.

    I don't know what your services are doing, but maybe you can use a messaging system / event queue instead. Or just pass references around (store references to the services in the classes that needs to access them).

    BTW, there's a bug in your code:

    Code:
    if(s_pInstance == this); s_pInstance = nullptr;

  5. #5
    Join Date
    Jul 2016
    Posts
    4

    Re: Gobally available Service with scoped Lifetime

    Quote Originally Posted by TubularX View Post
    Well, I'm not convinced with the idea of "global and scoped access". Isn't it just global state in disguise? What's the benefits compared to using a global pointer with a scope guard? The performance of Provider is worse, because it requires extra overhead "if(provider::s_pInstance)" every time you're getting.
    The primarily benefit is the abstraction and that it's more difficult to use it incorrectly. Since this is an open source project, i think using templates in that fashion might not be good, but it delivers a way to access globals in a kinda familiar way.
    What properties of a scope guard would help here? I could design provider in a way, that its owning the services. What do you think about that?

    Quote Originally Posted by TubularX View Post
    I don't know what your services are doing, but maybe you can use a messaging system / event queue instead. Or just pass references around (store references to the services in the classes that needs to access them).
    Passing references deeply into the class tree causes a small object creation and memory overhead and makes maintaining a harder from my experience.
    Also, if the service uses interface pattern, i can replace it on runtime.

    Quote Originally Posted by TubularX View Post
    BTW, there's a bug in your code:
    Code:
    if(s_pInstance == this); s_pInstance = nullptr;
    Thanks^^

    I still think its a bit overkill but i kinda like the pattern.

  6. #6
    Join Date
    Aug 2006
    Posts
    232

    Re: Gobally available Service with scoped Lifetime

    it's more difficult to use it incorrectly
    More difficult than what?

    What properties of a scope guard would help here?
    For example, here's a solution using a scope guard instead of your Provider:

    Code:
    Graphics* graphics = nullptr;
    
    template <typename T>
    class GlobalPointerGuard
    {
        T*& m_p;
    public:
        GlobalPointerGuard( T*& p ) : m_p(p) {}
        ~GlobalPointerGuard() { m_p = nullptr; }
    };
    
    int main()
    {
      {
        Graphics scoped_graphics;
        GlobalPointerGuard<Graphics> t( graphics = &scoped_graphics );
    
        function();
      }
    
      function();
    
      return 0;
    }
    
    void function()
    {
      // do something with Graphics
      std::cout << graphics << std::endl;
    }
    This way you'll need to declare one global pointer for each service, but no extra if-statement.

    Global state can become a maintenance nightmare, especially as the project grows and if you're going to run code concurrently.
    Last edited by TubularX; July 24th, 2016 at 06:07 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)