Merge pull request #4902 from JohannesLorenz/model-visitor

Make Model class visitable
This commit is contained in:
Johannes Lorenz
2019-04-27 20:09:14 +02:00
committed by GitHub
8 changed files with 222 additions and 0 deletions

View File

@@ -33,6 +33,7 @@
#include "MidiTime.h"
#include "ValueBuffer.h"
#include "MemoryManager.h"
#include "ModelVisitor.h"
// simple way to map a property of a view to a model
#define mapPropertyFromModelPtr(type,getfunc,setfunc,modelname) \
@@ -59,6 +60,11 @@
modelname.setValue( (float) val ); \
}
// use this to make subclasses visitable
#define MODEL_IS_VISITABLE \
void accept(ModelVisitor& v) override { v.visit(*this); } \
void accept(ConstModelVisitor& v) const override { v.visit(*this); }
class ControllerConnection;
@@ -68,6 +74,7 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject
Q_OBJECT
MM_OPERATORS
public:
typedef QVector<AutomatableModel *> AutoModelVector;
enum ScaleType
@@ -80,6 +87,35 @@ public:
virtual ~AutomatableModel();
// Implement those by using the MODEL_IS_VISITABLE macro
virtual void accept(ModelVisitor& v) = 0;
virtual void accept(ConstModelVisitor& v) const = 0;
public:
/**
@brief Return this class casted to Target
@test AutomatableModelTest.cpp
@param doThrow throw an assertion if the cast fails, instead of
returning a nullptr
@return the casted class if Target is the exact or a base class of
*this, nullptr otherwise
*/
template<class Target>
Target* dynamicCast(bool doThrow = false)
{
DCastVisitor<Target> vis; accept(vis);
if (doThrow && !vis.result) { Q_ASSERT(false); }
return vis.result;
}
//! const overload, see overloaded function
template<class Target>
const Target* dynamicCast(bool doThrow = false) const
{
ConstDCastVisitor<Target> vis; accept(vis);
if (doThrow && !vis.result) { Q_ASSERT(false); }
return vis.result;
}
bool isAutomated() const;
bool isAutomatedOrControlled() const
@@ -283,6 +319,22 @@ protected:
private:
// dynamicCast implementation
template<class Target>
struct DCastVisitor : public ModelVisitor
{
Target* result = nullptr;
void visit(Target& tar) { result = &tar; }
};
// dynamicCast implementation
template<class Target>
struct ConstDCastVisitor : public ConstModelVisitor
{
const Target* result = nullptr;
void visit(const Target& tar) { result = &tar; }
};
static bool mustQuoteName(const QString &name);
virtual void saveSettings( QDomDocument& doc, QDomElement& element )
@@ -382,6 +434,7 @@ public:
class LMMS_EXPORT FloatModel : public TypedAutomatableModel<float>
{
Q_OBJECT
MODEL_IS_VISITABLE
public:
FloatModel( float val = 0, float min = 0, float max = 0, float step = 0,
Model * parent = NULL,
@@ -399,6 +452,7 @@ public:
class LMMS_EXPORT IntModel : public TypedAutomatableModel<int>
{
Q_OBJECT
MODEL_IS_VISITABLE
public:
IntModel( int val = 0, int min = 0, int max = 0,
Model* parent = NULL,
@@ -414,6 +468,7 @@ public:
class LMMS_EXPORT BoolModel : public TypedAutomatableModel<bool>
{
Q_OBJECT
MODEL_IS_VISITABLE
public:
BoolModel( const bool val = false,
Model* parent = NULL,

View File

@@ -36,6 +36,7 @@
class LMMS_EXPORT ComboBoxModel : public IntModel
{
Q_OBJECT
MODEL_IS_VISITABLE
public:
ComboBoxModel( Model* parent = NULL,
const QString& displayName = QString(),

64
include/ModelVisitor.h Normal file
View File

@@ -0,0 +1,64 @@
/*
* ModelVisitor.h - visitors for automatable models
*
* Copyright (c) 2019-2019 Johannes Lorenz <j.git$$$lorenz-ho.me, $$$=@>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef MODELVISITOR_H
#define MODELVISITOR_H
class AutomatableModel;
class BoolModel;
class IntModel;
class FloatModel;
class ComboBoxModel;
class TempoSyncKnobModel;
class ModelVisitor
{
template<class ParentType = AutomatableModel, class ModelType>
void up(ModelType& m) { visit(static_cast<ParentType&>(m)); }
public:
virtual void visit(AutomatableModel& ) {}
virtual void visit(BoolModel& m);
virtual void visit(IntModel& m);
virtual void visit(FloatModel& m);
virtual void visit(ComboBoxModel& m);
virtual void visit(TempoSyncKnobModel& m);
virtual ~ModelVisitor();
};
class ConstModelVisitor
{
template<class ParentType = AutomatableModel, class ModelType>
void up(const ModelType& m) {
visit(static_cast<const ParentType&>(m)); }
public:
virtual void visit(const AutomatableModel& ) {}
virtual void visit(const BoolModel& m);
virtual void visit(const IntModel& m);
virtual void visit(const FloatModel& m);
virtual void visit(const ComboBoxModel& m);
virtual void visit(const TempoSyncKnobModel& m);
virtual ~ConstModelVisitor();
};
#endif // MODELVISITOR_H

View File

@@ -33,6 +33,7 @@ class QAction;
class LMMS_EXPORT TempoSyncKnobModel : public FloatModel
{
Q_OBJECT
MODEL_IS_VISITABLE
public:
enum TempoSyncMode
{