0

I have a Commons.lib project I stick a lot of my reused code in, that has gotten too big for it's own good (breaking a parser in it would halt work in 20 unrelated projects, stuff like that). I'm splitting it up to better isolate it's components but have ran into many small ... I guess "coupling" problems?

For example, I split off all functions and classes handling SDL content (the cross-platform windowing api) into it's own CommonsSDL.lib project, but a few classes in particular like class Color have some code that references SDL in it. I would like Color to belong in a separate CommonsCore.lib which has no idea SDL exists, and now have a dilemma.

// inside CommonsCore.lib, which shouldn't depend on SDL

class Color : public glm::u8vec4 {
public:
    Color(); // black transparent
    Color(glm::u8vec4 color);
    Color(uint8 r, uint8 g, uint8 b, uint8 a = 255);
    Color(const uint8 * px, Endian en = ENDIAN_DEFAULT);
    Color(uint32 hex32);

    // all the non-construction methods omitted for brevity;
    // no members in definition, besides those inherited from u8vec4
};
// inside CommonsSDL.lib, which depends on SDL and CommonsCore.lib

class Color : public glm::u8vec4 {
public:
    Color(SDL_Color color);

    void setSDLColor(SDL_Color color);
    SDL_Color getSDLColor() const;
};

I've read there's no way to extend a class definition once made, at least, from older C++11 info that likely still applies. Not without writing something likely to impact Color's behavior in a serious way, anyway.

Barring extension, would it be possible to instead supplant the definition of Color in CommonsCore.lib with the definition of Color in CommonsSDL.lib? I wouldn't mind duplicating the code they share if it's necessary, but haven't found any info regarding this possibility.

I've tried some preprocessor nonsense too but, I have come to realize that may not be possible because .lib are already compiled.

If there's no alternative, I'll just have to suck it up and slice out the coupled methods. There's 31 classes with small yet annoying coupling issues similar to Color's, and fixing them changes their interfaces in like 20 projects, so I'm grasping in the dark for a way to avoid needing to do that... of course, if that's how it is, that's how it is.

Anne Quinn
  • 12,609
  • 8
  • 54
  • 101
  • 1
    Concerning your exemplary `Color` problem... This reminds me to the recommendation, to factor out as much as possible from classes to free functions. So, you could have a basic color class (maybe, not more than a plain `struct` with some public members) and dedicated functions to create `Color` instances. So, `CommonSDL.lib` might contain such a function to convert an `SDLColor` (?) to your `Color`. This may help to build up a clear hierarchical organization (or in other words: dependencies) of how libraries build upon each other. – Scheff's Cat Jul 18 '21 at 10:50
  • If you are concerned about the performance impact of such "constructor" functions... Copy elision is mandatory since C++17, and named return value optimization is available in all major compilers meanwhile. ([What are copy elision and return value optimization?](https://stackoverflow.com/q/12953127/7478597)) – Scheff's Cat Jul 18 '21 at 10:53
  • @Scheff'sCat - that does set me at ease. I mean, I try to be unbothered by tiny losses like that nowadays, but it's nice to not pretend. My only hang up fully splitting out the methods to functions, is that changing the interface is gonna mean 100s of changes where they're used, which... another one is `Image`, and `Text`, and oh *god* `AABB` – Anne Quinn Jul 18 '21 at 11:04
  • 1
    I believe I know exactly what you mean. However, this never prevented me from anything. It's often a lot of tedious work but it comes with two advantages: 1.) You have another "self peer review" onto your code. (I always find something to fix.) 2.) You will feel a deep satisfaction once you're done and see your old code in the nice fancy new design. ;-) – Scheff's Cat Jul 18 '21 at 11:07

1 Answers1

1

Barring extension, would it be possible to instead supplant the definition of Color in CommonsCore.lib with the definition of Color in CommonsSDL.lib?

You could change the sources of CommonsCore.lib to use the new definition of Color and recompile the library. Other than that no, it wouldn't be possible. And that change would cause CommonsCore.lib to depend on SDL.

eerorika
  • 232,697
  • 12
  • 197
  • 326