WIP adjusted BuilderTool (specialisation) and tests....
compiles ok, but segfaults
This commit is contained in:
parent
2bd931b6da
commit
0bb8051fc5
9 changed files with 139 additions and 177 deletions
|
|
@ -36,7 +36,7 @@ Credits for many further implementation ideas go to
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** @file visitor.cpp
|
/** @file visitor.hpp
|
||||||
** A library implementation of the <b>Visitor Pattern</b> taylored specifically
|
** A library implementation of the <b>Visitor Pattern</b> taylored specifically
|
||||||
** to cinelerra's needs within the Proc Layer. Visitor enables <b>double dispatch</b>
|
** to cinelerra's needs within the Proc Layer. Visitor enables <b>double dispatch</b>
|
||||||
** calls, based both on the concrete type of some target object and the concrete type of
|
** calls, based both on the concrete type of some target object and the concrete type of
|
||||||
|
|
@ -90,14 +90,13 @@ namespace cinelerra
|
||||||
*/
|
*/
|
||||||
template
|
template
|
||||||
< typename RET = void,
|
< typename RET = void,
|
||||||
template <class> class ERR = UseDefault,
|
template <class> class ERR = UseDefault
|
||||||
>
|
>
|
||||||
class Tool
|
class Tool : public ERR<RET>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef RET ReturnType; ///< Tool function invocation return type
|
typedef RET ReturnType; ///< Tool function invocation return type
|
||||||
typedef Tool<RET> ToolBase; ///< for templating the Tag and Dispatcher
|
typedef Tool ToolBase; ///< for templating the Tag and Dispatcher
|
||||||
typedef ERR<ToolBase> ErrorPolicy;
|
|
||||||
|
|
||||||
virtual ~Tool () { }; ///< use RTTI for all visiting tools
|
virtual ~Tool () { }; ///< use RTTI for all visiting tools
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "common/error.hpp"
|
#include "common/error.hpp"
|
||||||
#include "common/util.hpp"
|
#include "common/util.hpp"
|
||||||
|
#include "common/singleton.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -153,7 +154,7 @@ namespace cinelerra
|
||||||
static ReturnType
|
static ReturnType
|
||||||
errorHandler (TAR& target, TOOL& tool)
|
errorHandler (TAR& target, TOOL& tool)
|
||||||
{
|
{
|
||||||
return TOOL::ErrorPolicy::onUnknown (target, tool);
|
return tool.onUnknown (target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,16 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
====================================================================
|
|
||||||
This code is heavily inspired by
|
|
||||||
The Loki Library (loki-lib/trunk/include/loki/Visitor.h)
|
|
||||||
Copyright (c) 2001 by Andrei Alexandrescu
|
|
||||||
This Loki code accompanies the book:
|
|
||||||
Alexandrescu, Andrei. "Modern C++ Design: Generic Programming
|
|
||||||
and Design Patterns Applied".
|
|
||||||
Copyright (c) 2001. Addison-Wesley. ISBN 0201704315
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @file visitorpolicies.hpp
|
||||||
|
** Policies usable for configuring the cinelerra::visitor::Tool for different kinds of error handling.
|
||||||
|
** @see buildertool.hpp for another flavor (calling and catch-all-function)
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CINELERRA_VISITORPOLICIES_H
|
#ifndef CINELERRA_VISITORPOLICIES_H
|
||||||
#define CINELERRA_VISITORPOLICIES_H
|
#define CINELERRA_VISITORPOLICIES_H
|
||||||
|
|
@ -41,57 +39,36 @@ namespace cinelerra
|
||||||
{
|
{
|
||||||
namespace visitor
|
namespace visitor
|
||||||
{
|
{
|
||||||
/* == several Policies usable in conjunction with cinelerra::visitor::Visitable == */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Policy returning just the default return value in case
|
* Policy returning just the default return value in case
|
||||||
* of encountering an unknown Visitor (typically caused by
|
* of encountering an unknown Visitor (typically caused by
|
||||||
* adding a new class to the visitable hierarchy)
|
* adding a new class to the visitable hierarchy)
|
||||||
*/
|
*/
|
||||||
template<class TOOL>
|
template<class RET>
|
||||||
struct UseDefault
|
struct UseDefault
|
||||||
{
|
{
|
||||||
typedef TOOL::ReturnType Ret;
|
|
||||||
|
|
||||||
template<class TAR>
|
template<class TAR>
|
||||||
static Ret onUnknown (TAR&, TOOL&)
|
RET
|
||||||
|
onUnknown (TAR&)
|
||||||
{
|
{
|
||||||
return Ret();
|
return RET();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Policy to throw when encountering an unknown visiting tool
|
* Policy to throw when encountering an unknown visiting tool
|
||||||
*/
|
*/
|
||||||
template<class TOOL>
|
template<class RET>
|
||||||
struct ThrowException
|
struct ThrowException
|
||||||
{
|
{
|
||||||
typedef TOOL::ReturnType Ret;
|
|
||||||
|
|
||||||
template<class TAR>
|
template<class TAR>
|
||||||
static Ret onUnknown (TAR&, TOOL&)
|
RET
|
||||||
|
onUnknown (TAR&)
|
||||||
{
|
{
|
||||||
throw cinelerra::error::Config("unable to decide what tool operation to call");
|
throw cinelerra::error::Config("unable to decide what tool operation to call");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Policy invoking an catch-all function for processing
|
|
||||||
* an unknown tool / target pair
|
|
||||||
* @note using this policy effectively enforces
|
|
||||||
* implementing a catch-all function \c treat(TAR&)
|
|
||||||
*/
|
|
||||||
template<class TOOL>
|
|
||||||
struct InvokeCatchAllFunction
|
|
||||||
{
|
|
||||||
typedef TOOL::ReturnType Ret;
|
|
||||||
|
|
||||||
template<class TAR>
|
|
||||||
static Ret onUnknown (TAR& target,TOOL& tool)
|
|
||||||
{
|
|
||||||
return tool.catchAll (target);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace visitor
|
} // namespace visitor
|
||||||
|
|
|
||||||
|
|
@ -26,55 +26,16 @@
|
||||||
|
|
||||||
|
|
||||||
#include "common/visitor.hpp"
|
#include "common/visitor.hpp"
|
||||||
|
#include "proc/mobject/builder/buildertool.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace mobject
|
namespace mobject
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
namespace builder{ class BuilderTool; }
|
|
||||||
|
|
||||||
using cinelerra::visitor::Visitable;
|
using cinelerra::visitor::Visitable;
|
||||||
using cinelerra::visitor::InvokeCatchAllFunction;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All Buidables support double-dispatch of given Tool operations.
|
|
||||||
* The actual operation is thus selected at runtime based both on the
|
|
||||||
* actual type of the Tool class /and/ the actual type of the Buildabele.
|
|
||||||
*/
|
|
||||||
class Buildable : public Visitable
|
|
||||||
< void, // return type of apply
|
|
||||||
builder::BuilderTool, // visiting tool base class
|
|
||||||
InvokeCatchAllFunction // how to handle unknown
|
|
||||||
>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Catch-all implementation for applying any builder tool
|
|
||||||
* to some (uspecified) buildable object. Typically the provided
|
|
||||||
* actual Tool class will contain overloaded fuctions for treating
|
|
||||||
* different Buildable subclasses specifically and the concrete Buildables
|
|
||||||
* will define explicitly to be specifically visitable.
|
|
||||||
*/
|
|
||||||
// virtual void apply (builder::BuilderTool&); ////////////////////////////// besser weg????
|
|
||||||
virtual void fallback(builder::BuilderTool&) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** mark a Buildable subclass as actually treatable
|
|
||||||
* by some BuilderTool. Note this defines a more concrete
|
|
||||||
* apply-function, which actually dispatches with a
|
|
||||||
* Placement<TARGET>. Crutial to make the builder work.
|
|
||||||
*/
|
|
||||||
#define DEFINE_BUILDABLE \
|
|
||||||
virtual void apply (builder::BuilderTool& tool) \
|
|
||||||
{ return dispatchOp (*this, tool); }
|
|
||||||
|
|
||||||
///////////////////////////////bringt das überhaupt was???
|
|
||||||
|
|
||||||
#define DEFINE_FALLBACK \
|
|
||||||
virtual void fallback(builder::BuilderTool& tool) \
|
|
||||||
{ apply(tool); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,42 +25,69 @@
|
||||||
#define MOBJECT_BUILDER_TOOL_H
|
#define MOBJECT_BUILDER_TOOL_H
|
||||||
|
|
||||||
#include "common/visitor.hpp"
|
#include "common/visitor.hpp"
|
||||||
#include "proc/mobject/buildable.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace mobject
|
namespace mobject
|
||||||
{
|
{
|
||||||
|
class Buildable;
|
||||||
|
|
||||||
namespace builder
|
namespace builder
|
||||||
{
|
{
|
||||||
|
|
||||||
using cinelerra::visitor::Tool;
|
/**
|
||||||
|
* Policy invoking an catch-all function for processing
|
||||||
|
* an unknown tool / target pair, effectively enforcing the
|
||||||
|
* implementation of a catch-all function \c onUnknown(BASE&)
|
||||||
|
*/
|
||||||
|
template<class RET>
|
||||||
|
class InvokeCatchAllFunction
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual ~InvokeCatchAllFunction() {}
|
||||||
|
public:
|
||||||
|
virtual RET onUnknown (Buildable& target) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used according to the visitor pattern: each Tool contains
|
* Base class of all BuilderTools, used according to the visitor pattern:
|
||||||
* the concrete implementation for one task to be done to the various MObject classes
|
* each Tool contains the concrete implementation for one task to be done
|
||||||
|
* to the various MObject classes. The concrete builder tool implementation
|
||||||
|
* should not diretcly inherit from this base interface, but rather through
|
||||||
|
* an instantiation of the BuilderToolType template. Additionally, it should
|
||||||
|
* inherit from the Applicable template parametrized with all conctrete
|
||||||
|
* Buildable classes, for which it wants calls to be dispatched.
|
||||||
*/
|
*/
|
||||||
class BuilderTool : public Tool //////////////////////////auf die Zielklasse templaten und Placement festmachen???
|
typedef cinelerra::visitor::Tool<void, InvokeCatchAllFunction> BuilderTool;
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef mobject::Buildable Buildable;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** This operation is to be overloaded for specific MObject subclasses to be treated.
|
|
||||||
*/
|
|
||||||
//virtual void treat (Buildable& mElement) = 0;
|
|
||||||
template<class BB>
|
|
||||||
void catchy (BB& elem) {elem.fallback(*this); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class TO, class BO>
|
template<class TOOLImpl>
|
||||||
void zoing(TO& ttt,BO& bot)
|
class BuilderToolType
|
||||||
{
|
: public cinelerra::visitor::ToolType<TOOLImpl, BuilderTool>
|
||||||
ttt->treat(bot);
|
{ }
|
||||||
}
|
;
|
||||||
|
|
||||||
|
|
||||||
|
template
|
||||||
|
< class TAR, // concrete Buildable to be treated
|
||||||
|
class TOOLImpl // concrete BuilderTool implementation
|
||||||
|
>
|
||||||
|
class Applicable
|
||||||
|
: public cinelerra::visitor::Applicable<TAR,TOOLImpl, BuilderTool>
|
||||||
|
{ }
|
||||||
|
;
|
||||||
|
|
||||||
} // namespace mobject::builder
|
} // namespace mobject::builder
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker Interface for classes Visitable by Builder tools.
|
||||||
|
*/
|
||||||
|
class Buildable : public cinelerra::visitor::Visitable<builder::BuilderTool>
|
||||||
|
{ };
|
||||||
|
|
||||||
} // namespace mobject
|
} // namespace mobject
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,7 @@ namespace mobject
|
||||||
|
|
||||||
virtual Time& getLength() { return length; }
|
virtual Time& getLength() { return length; }
|
||||||
|
|
||||||
// DEFINE_PROCESSABLE_BY (builder::BuilderTool);
|
DEFINE_PROCESSABLE_BY (builder::BuilderTool);
|
||||||
DEFINE_BUILDABLE;
|
|
||||||
DEFINE_FALLBACK;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,9 @@ namespace cinelerra
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class BASE>
|
||||||
class VerboseVisitor
|
class VerboseVisitor
|
||||||
: public Tool
|
: public BASE
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void talk_to (string guy)
|
void talk_to (string guy)
|
||||||
|
|
@ -73,7 +74,7 @@ namespace cinelerra
|
||||||
class Babbler
|
class Babbler
|
||||||
: public Applicable<Boss,Babbler>,
|
: public Applicable<Boss,Babbler>,
|
||||||
public Applicable<BigBoss,Babbler>,
|
public Applicable<BigBoss,Babbler>,
|
||||||
public ToolType<Babbler, VerboseVisitor>
|
public ToolType<Babbler, VerboseVisitor<Tool> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void treat (Boss&) { talk_to("Boss"); }
|
void treat (Boss&) { talk_to("Boss"); }
|
||||||
|
|
@ -83,35 +84,36 @@ namespace cinelerra
|
||||||
// the classes above comprise the standard use case,
|
// the classes above comprise the standard use case,
|
||||||
// what follows are rather exotic corner cases
|
// what follows are rather exotic corner cases
|
||||||
|
|
||||||
class Blatherer
|
|
||||||
: public Applicable<BigBoss,Blatherer>,
|
template<class RET>
|
||||||
public ToolType<Blatherer, VerboseVisitor>
|
struct Catched
|
||||||
{
|
{
|
||||||
public:
|
RET onUnknown (HomoSapiens&) { cout << "we-do-everything-for-YOU!\n"; } ///< catch-all function
|
||||||
void treat (BigBoss&) { talk_to("big Boss"); }
|
|
||||||
void treat (HomoSapiens&) { talk_to("we-do-everything-for-YOU"); } ///< catch-all function
|
|
||||||
void catchy(HomoSapiens&) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef visitor::Tool<void, Catched> Hastalavista;
|
||||||
|
typedef Visitable<Hastalavista> Chief; ///< another special kind of visitables
|
||||||
|
|
||||||
typedef Visitable<void,Blatherer,InvokeCatchAllFunction> Vista2;
|
|
||||||
|
|
||||||
class Chief : public Vista2 ///< abstract intermeidary node
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
class Leader : public Chief,
|
class Leader : public Chief,
|
||||||
public Boss ///< can act as HomoSapiens or as Chief
|
public Boss ///< can act as HomoSapiens or as Chief
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using HomoSapiens::apply;
|
using HomoSapiens::apply;
|
||||||
virtual void apply (Blatherer& tool) { return Vista2::dispatchOp (*this, tool); }
|
virtual void apply (Hastalavista& tool) { return Chief::dispatchOp (*this, tool); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Visionary : public Leader
|
class Visionary : public Leader
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Blatherer
|
||||||
|
: public Applicable<Visionary,Blatherer,Hastalavista>,
|
||||||
|
public ToolType<Blatherer, VerboseVisitor<Hastalavista> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void treat (Leader&) { talk_to("Mr.Future"); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -132,9 +134,9 @@ namespace cinelerra
|
||||||
{
|
{
|
||||||
virtual void run(Arg arg)
|
virtual void run(Arg arg)
|
||||||
{
|
{
|
||||||
//known_visitor_known_class();
|
known_visitor_known_class();
|
||||||
//visitor_not_visiting_some_class();
|
visitor_not_visiting_some_class();
|
||||||
//visitor_treating_new_subclass();
|
visitor_treating_new_subclass();
|
||||||
}
|
}
|
||||||
|
|
||||||
void known_visitor_known_class()
|
void known_visitor_known_class()
|
||||||
|
|
@ -174,27 +176,22 @@ namespace cinelerra
|
||||||
|
|
||||||
HomoSapiens& homo1 (x1);
|
HomoSapiens& homo1 (x1);
|
||||||
HomoSapiens& homo2 (x2);
|
HomoSapiens& homo2 (x2);
|
||||||
HomoSapiens& homo3 (x3);
|
|
||||||
Chief& chief1 (x1);
|
Chief& chief1 (x1);
|
||||||
Chief& chief2 (x2);
|
Chief& chief2 (x2);
|
||||||
Leader& lead1 (x1);
|
Leader& lead1 (x1);
|
||||||
Leader& lead2 (x2);
|
Leader& lead2 (x2);
|
||||||
|
|
||||||
Blatherer bla;
|
Blatherer bla;
|
||||||
VerboseVisitor vista;
|
Babbler bab;
|
||||||
Tool& tool1 (vista);
|
Tool& tool1 (bab);
|
||||||
Tool& tool2 (bla);
|
Hastalavista& tool2 (bla);
|
||||||
cout << "=== Blatherer meets Leader, Visionary and HomoSapiens masqueraded as HomoSapiens ===\n";
|
|
||||||
homo1.apply (bla); // nothing happens, because Blatherer doesn't declare to do anything as Tool
|
|
||||||
homo2.apply (bla);
|
|
||||||
homo3.apply (bla);
|
|
||||||
cout << "=== Blatherer meets Leader and Visionary masqueraded as Chief ===\n";
|
cout << "=== Blatherer meets Leader and Visionary masqueraded as Chief ===\n";
|
||||||
chief1.apply (bla); // but now, acting in the Chief hierarchy, the catch-all is called
|
chief1.apply (bla); // but now, acting in the Chief hierarchy, the catch-all is called
|
||||||
chief2.apply (bla);
|
chief2.apply (bla);
|
||||||
cout << "=== VerboseVistr masqueraded as Tool meets Leader and Visionary masqueraded as HomoSapiens ===\n";
|
cout << "=== Babbler masqueraded as Tool meets Leader and Visionary masqueraded as HomoSapiens ===\n";
|
||||||
homo1.apply (tool1); // because acting in the HomoSapiens hierarch, no visiting happens and no catch-all
|
homo1.apply (tool1); // because acting in the HomoSapiens hierarchy, no visiting happens and no catch-all
|
||||||
homo2.apply (tool1);
|
homo2.apply (tool1);
|
||||||
cout << "=== Blatherer masqueraded as Tool meets Leader and Visionary masqueraded as Leader ===\n";
|
cout << "=== Blatherer masqueraded as Hastalavista meets Leader and Visionary masqueraded as Leader ===\n";
|
||||||
lead1.apply (tool2); // nothing happens, because Leader here is treated by his HomoSapiens base
|
lead1.apply (tool2); // nothing happens, because Leader here is treated by his HomoSapiens base
|
||||||
lead2.apply (tool2);
|
lead2.apply (tool2);
|
||||||
|
|
||||||
|
|
@ -215,7 +212,7 @@ namespace cinelerra
|
||||||
|
|
||||||
|
|
||||||
/** Register this test class... */
|
/** Register this test class... */
|
||||||
// LAUNCHER (VisitingToolExtended_test, "unit common");
|
LAUNCHER (VisitingToolExtended_test, "unit common");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,17 @@ namespace cinelerra
|
||||||
{
|
{
|
||||||
typedef visitor::Tool<> VisitingTool;
|
typedef visitor::Tool<> VisitingTool;
|
||||||
|
|
||||||
|
class VerboseVisitor
|
||||||
|
: public VisitingTool
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void talk_to (string guy)
|
||||||
|
{
|
||||||
|
cout << format ("Hello %s, nice to meet you...\n") % guy;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class HomoSapiens : public Visitable<>
|
class HomoSapiens : public Visitable<>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -53,17 +64,17 @@ namespace cinelerra
|
||||||
DEFINE_PROCESSABLE_BY (VisitingTool);
|
DEFINE_PROCESSABLE_BY (VisitingTool);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// the classes above comprise the standard visitor use case,
|
||||||
|
// now we'll extend the hierarchy a bit...
|
||||||
|
|
||||||
class VerboseVisitor
|
|
||||||
: public VisitingTool
|
class BigBoss : public Boss
|
||||||
{
|
{
|
||||||
protected:
|
public:
|
||||||
void talk_to (string guy)
|
DEFINE_PROCESSABLE_BY (VerboseVisitor);
|
||||||
{
|
|
||||||
cout << format ("Hello %s, nice to meet you...\n") % guy;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Babbler
|
class Babbler
|
||||||
: public Applicable<Boss,Babbler>,
|
: public Applicable<Boss,Babbler>,
|
||||||
public Applicable<BigBoss,Babbler>,
|
public Applicable<BigBoss,Babbler>,
|
||||||
|
|
@ -75,16 +86,6 @@ namespace cinelerra
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// the classes above comprise the standard visitor use case,
|
|
||||||
// now we'll extend the hierarchy a bit...
|
|
||||||
|
|
||||||
|
|
||||||
class BigBoss : public Boss
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DEFINE_PROCESSABLE_BY (VerboseVisitor);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Leader : public Boss
|
class Leader : public Boss
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,25 @@ namespace mobject
|
||||||
|
|
||||||
using session::Clip;
|
using session::Clip;
|
||||||
using session::AbstractMO;
|
using session::AbstractMO;
|
||||||
using cinelerra::visitor::Applicable;
|
|
||||||
|
|
||||||
|
|
||||||
|
class DummyMO : public AbstractMO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DummyMO() { };
|
||||||
|
virtual bool isValid() const { return true;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestTool : public BuilderToolType<TestTool>,
|
||||||
|
public Applicable<Clip,TestTool>,
|
||||||
|
public Applicable<AbstractMO,TestTool>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void treat (Clip& c) { cout << "media is: "<< str(c.getMedia()) <<"\n"; }
|
||||||
|
void treat (AbstractMO&){ cout << "catch-all-MO.\n"; }
|
||||||
|
void onUnknown (Buildable&){ cout << "catch-all-function called.\n"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -68,21 +84,6 @@ namespace mobject
|
||||||
{
|
{
|
||||||
virtual void run(Arg arg)
|
virtual void run(Arg arg)
|
||||||
{
|
{
|
||||||
class DummyMO : public AbstractMO
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DummyMO() { };
|
|
||||||
virtual bool isValid() const { return true;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TestTool : public BuilderTool,
|
|
||||||
public Applicable<Clip>,
|
|
||||||
public Applicable<AbstractMO>
|
|
||||||
{
|
|
||||||
void treat (Clip& c) { cout << "media is: "<< str(c.getMedia()) <<"\n"; }
|
|
||||||
void treat (Buildable&){ cout << "catch-all-function called.\n"; }
|
|
||||||
void treat (AbstractMO&){ cout << "catch-all-MO.\n"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
TestTool t1;
|
TestTool t1;
|
||||||
BuilderTool& tool (t1);
|
BuilderTool& tool (t1);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue