I have an embedded graphics library for C++14 and C++17 (preferred) at https://honeythecodewitch.com/gfx
I'm currently working on a major version update so with that comes a lot of refactoring.
I'd currently like to refactor my draw class, which is a class with static template methods on it for doing various drawing operations,
draw::line<>()
draw::filled_ellipse<>()
draw::text<>()
draw::image<>()
etc
The draw class is the primary facility for drawing in my library, so the surface area is bound to be pretty big. I don't mind that. What I'm concerned about is maintenance.
Right now draw:: is several thousand lines of code in a single class. I want to break it up into different classes in different headers, like draw_line, draw_ellipse, draw_polygon etc, and then make draw inherit publicly from all of those.
The issue is what to do with those foundational composition classes? I don't want them to show up in autocomplete lists when you go to draw items. I also want them in different individual files.
One thing I considered was "private headers" that have these classes in them. Those headers could be included in the gfx_drawing.hpp main drawing header and imported under the empty namespace so they only exist for the scope of that master file.
namespace gfx {
namespace {
#include "gfx_draw_line.hpp"
#include "gfx_filled_ellipse.hpp"
...
}
struct draw : public draw_line, public draw_ellipse ... {
....
}
}
I don't like it. For starters I'm concerned about referencing gfx:: qualified items under that nested empty namespace. I'm not sure it will break things, but nor am I sure it won't. Secondly, it feels like preprocessor abuse putting the #includes inside that namespace declaration. Finally, I'm not even sure it will prevent VS Code from making those inner classes show up in intellisense (even if they shouldn't - if they do, I want to name them accordingly as to cut down on actual in practice autocomplete pollution.
I need ideas for hiding these composite classes, or a different way to structure this that allows me to separate drawing operations but combine them together under a public draw:: class <--- that last bit is non-negotiable as changing to something other than my draw:: facilities changes the heart and soul of my library, rendering it very unlike its current self. I'm not ready for that absent some very compelling reasons.
What I have tried:
I'm currently stashing the "hidden" bits under gfx::helpers::
It's less than ideal, but it sort of works
#ifndef HTCW_GFX_DRAW_HPP
#define HTCW_GFX_DRAW_HPP
#include "gfx_draw_common.hpp"
#include "gfx_draw_point.hpp"
#include "gfx_draw_filled_rectangle.hpp"
#include "gfx_draw_line.hpp"
#include "gfx_draw_rectangle.hpp"
#include "gfx_draw_bitmap.hpp"
#include "gfx_draw_icon.hpp"
#include "gfx_draw_text.hpp"
#include "gfx_draw_ellipse.hpp"
#include "gfx_draw_arc.hpp"
#include "gfx_draw_rounded_rectangle.hpp"
#include "gfx_draw_filled_rounded_rectangle.hpp"
#include "gfx_draw_polygon.hpp"
#include "gfx_draw_filled_polygon.hpp"
#include "gfx_draw_sprite.hpp"
#include "gfx_draw_image.hpp"
namespace gfx {
struct draw : public helpers::xdraw_point,
public helpers::xdraw_filled_rectangle,
public helpers::xdraw_line,
public helpers::xdraw_rectangle,
public helpers::xdraw_bitmap,
public helpers::xdraw_icon,
public helpers::xdraw_text,
public helpers::xdraw_ellipse,
public helpers::xdraw_arc,
public helpers::xdraw_rounded_rectangle,
public helpers::xdraw_filled_rounded_rectangle,
public helpers::xdraw_polygon,
public helpers::xdraw_filled_polygon,
public helpers::xdraw_sprite,
public helpers::xdraw_image
{};
}
#endif