Jump to content
  • Advertisement
Sign in to follow this  
GenuineXP

Abstraction/Plugin Thoughts

This topic is 3629 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working with abstraction across binary boundaries (i.e., a library that loads a shared object at runtime) and I'm wondering about the way I've chosen to handle inter-object communication. Here's how things tend to work at the moment. In the library, which exposes some abstracted functionality implemented in some other shared object (plugin), we find this setup.
class thing {
public:
    thing(subsystem_impl_ptr_t impl, const resource_id_t& rid);
    void load(const path& file);
private:
    subsystem_impl_ptr_t impl_;
    resource_id_t rid_;
};
class subsystem {
public:
    void do_something();
    thing_ptr_t make_thing();
private:
    subsystem_impl_ptr_t impl_;
};
class subsystem_impl {
public:
    void do_something();
    resource_id_t make_thing();
    void load_thing(const resource_id_t& rid, const path& file);
protected:
    virtual void do_do_something() = 0;
    virtual resource_id_t do_make_thing() = 0;
    virtual void do_load_thing(const resource_id_t& rid, const path& file) = 0;
};

Meanwhile, in the shared object (plugin) we have this.
class xxx_thing {
public:
    xxx_thing(/*...*/);
};
class xxx_subsystem_impl : public subsystem_impl {
protected:
    virtual void do_do_something();
    virtual resource_id_t do_make_thing();
    virtual void do_load_thing(const resource_id_t& rid, const path& file);
};

Please note that I just came up with this code on the fly. I wrote it to illustrate my thoughts; it does not look exactly like the code in use. In the library, a resource called thing exists along with a subsystem its associated with. There's a proxy class used by clients to access this subsystem, aptly named subsystem in this example. This proxy makes use of the pimpl idiom, and actually uses an implementation object under the hood, here called subsystem_impl. Now, for a plugin to be usable, it needs to implement subsystem_impl. There are a few things to note at this point, however. The resource thing is not abstract and is not implemented directly in the plugin. Instead, all thing-related operations are associated with the same implementation interface (i.e., subsystem_impl). This is where the plugin implements all functionality of the subsystem. Because of this, the function load_thing is a part of subsystem_impl. The plugin implements subsystem_impl and also defines its own (and totally isolated) version of a thing. The plugin's version is very concrete, and is implemented using the appropriate APIs. If I client wants to use the subsystem to load a thing, they would first use the subsystem proxy to create a thing object. This would result in the proxy using the subsystem interface (subsystem_impl), which returns a resource ID. This is merely a handle that ultimately associates the thing object in the library with the xxx_thing in the plugin. This approach has been working just fine, but I'm not sure it's the best solution. I'm not a fan of the indirection here, where an object in the library is associated via a handle to another object in the plugin. I guess my question is, is there a good reason why I may want to instead handle resources like thing more like the subsystem interface? Should thing have been an abstract class that is implemented in the plugin via inheritance? This way, no handles are needed, and there's no need for xxx_subsystem_impl to have functions directly related to xxx_thing. On the other hand, one advantage of this approach is that my subsystem implementations (in the plugin) simply store maps with a resource ID key of these resources, which is handy and easy to use. It also helps prevent problems with communications between binaries. Just to make my terrible example a little more concrete, in terms of my code, subsystem is graphics, subsystem_impl is graphics_impl, thing is image, xxx_subsystem_impl is gl_sdl_graphics_impl, and xxx_thing is il_image. Phew. Any thoughts? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!