looking for suggestions

1 view
Skip to first unread message

allister

unread,
Feb 28, 2007, 7:32:26 AM2/28/07
to Philippine C++ Users Group
Hi,

Here goes..

I want to have a single object (a singleton of XDrawFactory) that will
be used by a client (XControlHandler). This singleton must draw
objects according to a scheme specified by the client. The scheme
(XEventDrawScheme) is just an enum of integers.

When XControlHandler asks XDrawFactory to draw objects to a canvas
(TCanvas), XDrawFactory must create an array of drawable objects
(XDrawObject) according to the specified scheme, and loop over this
array to draw each XDrawObject on the canvas. The creation of this
array of XDrawObjects can be simple or very complicated depending on
the selected scheme and the available data (available from a LCEvent
object) .

So, I defined XDrawFactory as follows:

class XDrawFactory
{
private:
XDrawFactory();
static XDrawFactory* instance;

public:
virtual ~XDrawFactory();

static XDrawFactory* getInstance() {
if (!instance) instance = new XDrawFactory(); return instance;
}

XEventDrawScheme getDrawScheme() const { return _scheme; }

// when successful, this will delete the old XDrawImpl and create
a new one
// corresponding to the new scheme.
bool setDrawScheme(XEventDrawScheme ds = kXDrawByMC);

void draw(TCanvas *c) { _drawImpl->draw(c); }
bool processEvent(lcio::LCEvent* evt) { _drawImpl-
>processEvent(evt); }

protected:
XEventDrawScheme _scheme;
XDrawImpl* _drawImpl;
};

XDrawFactory* XDrawFactory::instance = 0;

The various drawing scheme implementations will then look like this:

class XDrawImpl
{
public:
XDrawImpl();
virtual ~XDrawImpl();

virtual void draw(TCanvas *c) = 0;
virtual bool processEvent(lcio::LCEvent*) = 0;
}

class XDrawImplByMC : public XDrawImpl
{
XDrawImplByMC();
virtual ~XDrawImplByMC();

virtual void draw(TCanvas *c);
virtual bool processEvent();
};

Any suggestions or comments on how I may improve this design and make
it easy to maintain when new schemes are required? Are there pitfalls
I must watch out for?

Thanks in advance,
Allister
--
Allister Levi C. Sanchez (allister...@gmail.com /
san...@poly.in2p3.fr)
Chargé de Recherche CNRS, Laboratoire Leprince-Ringuet, École
Polytechnique, France
http://allistersanchez.blogspot.com

Dean Michael Berris

unread,
Feb 28, 2007, 9:26:29 AM2/28/07
to Allister Levi Sanchez, phil...@googlegroups.com
Hi Sir Allister!

I suggest using STL constructs and templates where possible (see
http://sgi.com/tech/stl ) as well as some Boost libraries (shared_ptr,
http://boost.org/ ):

typedef boost::shared_ptr<DrawableObjects> drawable_ptr;

template <const Scheme> class GenerationPolicy;

struct schemes {
enum { FIRST, SECOND, THIRD };
};

template <> class GenerationPolicy<schemes::FIRST> {
protected: std::list<drawable_ptr> _objects;
protected: ~GenerationPolicy() { };
public: GenerationPolicy() : {
_objects.push_back(drawable_ptr(new SomethingDrawable()));
_objects.push_back(drawable_ptr(new SomethineElseDrawable());
};
};

template <> GenerationPolicy<schemes::SECOND> {
protected: std::list<drawable_ptr> _objects;
protected: ~GenerationPolicy() { };
public: GenerationPolicy() : {
// specific to this implementation...
};
};

template <const Scheme>
class XDrawImpl : public GenerationPolicy<Scheme> {
public:
XDrawImpl : GenerationPolicy<Scheme>() { };
void draw(TCanvas * c) {
struct draw_this {
TCanvas * _c;
draw_this(TCanvas * c_) : _c(c_) { };
void operator() (drawable_ptr p) {
_c->draw(*p);
};
};
std::for_each(_objects.begin(), _objects.end(),
draw_this(c));
};
};

This allows you to keep one implementation of the XDrawImpl for
varying schemes at compile time.

Hope this helps!

--
Dean Michael C. Berris
http://cplusplus-soup.blogspot.com/
mikhailberis AT gmail DOT com
+63 928 7291459

Dean Michael Berris

unread,
Feb 28, 2007, 9:45:03 AM2/28/07
to Allister Levi Sanchez, phil...@googlegroups.com
On 2/28/07, Dean Michael Berris <mikhai...@gmail.com> wrote:
>
> template <> class GenerationPolicy<schemes::FIRST> {
> protected: std::list<drawable_ptr> _objects;
> protected: ~GenerationPolicy() { };
> public: GenerationPolicy() : {
> _objects.push_back(drawable_ptr(new SomethingDrawable()));
> _objects.push_back(drawable_ptr(new SomethineElseDrawable());
> };
> };
>
> template <> GenerationPolicy<schemes::SECOND> {

should be:

template <> class GenerationPolicy<schemes::SECOND> {

> protected: std::list<drawable_ptr> _objects;
> protected: ~GenerationPolicy() { };
> public: GenerationPolicy() : {
> // specific to this implementation...
> };
> };
>

--

Joel de Guzman

unread,
Feb 28, 2007, 5:45:46 PM2/28/07
to phil...@googlegroups.com
Dean Michael Berris wrote:
>
> This allows you to keep one implementation of the XDrawImpl for
> varying schemes at compile time.

And get rid of the "X" prefix. It's too 90s ;-) Use namespaces
instead.

Regards,
--
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Reply all
Reply to author
Forward
0 new messages