Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduced ControlObjectSlave and converted some controls to this. #38

Merged
merged 9 commits into from
Oct 15, 2013
1 change: 1 addition & 0 deletions build/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ def sources(self, build):
"configobject.cpp",
"control/control.cpp",
"control/controlbehavior.cpp",
"controlobjectslave.cpp",
"controlobjectthread.cpp",
"controlobjectthreadwidget.cpp",
"controlobjectthreadmain.cpp",
Expand Down
90 changes: 90 additions & 0 deletions src/controlobjectslave.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <QApplication>
#include <QtDebug>

#include "controlobjectslave.h"
#include "control/control.h"

ControlObjectSlave::ControlObjectSlave(QObject* pParent)
: QObject(pParent),
m_pControl(NULL) {
}

ControlObjectSlave::ControlObjectSlave(const QString& g, const QString& i, QObject* pParent)
: QObject(pParent) {
initialize(ConfigKey(g, i));
}

ControlObjectSlave::ControlObjectSlave(const char* g, const char* i, QObject* pParent)
: QObject(pParent) {
initialize(ConfigKey(g, i));
}

ControlObjectSlave::ControlObjectSlave(const ConfigKey& key, QObject* pParent)
: QObject(pParent) {
initialize(key);
}

void ControlObjectSlave::initialize(const ConfigKey& key) {
m_pControl = ControlDoublePrivate::getControl(key, false);
}

ControlObjectSlave::~ControlObjectSlave() {
}

bool ControlObjectSlave::connectValueChanged(const QObject* receiver,
const char* method, Qt::ConnectionType type) {
bool ret = false;
if (m_pControl) {
ret = connect((QObject*)this, SIGNAL(valueChanged(double)),
receiver, method, type);
if (ret) {
// connect to ControlObjectPrivate only if required
ret = connect(m_pControl, SIGNAL(valueChanged(double, QObject*)),
this, SLOT(slotValueChanged(double, QObject*)),
Qt::DirectConnection);
}
}
return ret;
}

bool ControlObjectSlave::connectValueChanged(
const char* method, Qt::ConnectionType type) {
return connectValueChanged(parent(), method, type);
}


double ControlObjectSlave::get() {
return m_pControl ? m_pControl->get() : 0.0;
}

void ControlObjectSlave::slotSet(double v) {
set(v);
}

void ControlObjectSlave::set(double v) {
if (m_pControl) {
m_pControl->set(v, this);
}
}

void ControlObjectSlave::reset() {
if (m_pControl) {
// NOTE(rryan): This is important. The originator of this action does
// not know the resulting value so it makes sense that we should emit a
// general valueChanged() signal even though the change originated from
// us. For this reason, we provide NULL here so that the change is
// broadcast as valueChanged() and not valueChangedByThis().
m_pControl->reset();
}
}

void ControlObjectSlave::emitValueChanged() {
emit(valueChanged(get()));
}

void ControlObjectSlave::slotValueChanged(double v, QObject* pSetter) {
if (pSetter != this) {
// This is base implementation of this function without scaling
emit(valueChanged(v));
}
}
60 changes: 60 additions & 0 deletions src/controlobjectslave.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef CONTROLOBJECTSLAVE_H
#define CONTROLOBJECTSLAVE_H

#include <qmutex.h>
#include <qobject.h>
#include <qmutex.h>
#include <qwaitcondition.h>
#include <QQueue>

#include "configobject.h"

class ControlDoublePrivate;

class ControlObjectSlave : public QObject {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class could use a comment that describes what it is and why you would use it as opposed to ControlObjectThread.

Q_OBJECT
public:
ControlObjectSlave(QObject* pParent=NULL);
ControlObjectSlave(const QString& g, const QString& i, QObject* pParent=NULL);
ControlObjectSlave(const char* g, const char* i, QObject* pParent=NULL);
ControlObjectSlave(const ConfigKey& key, QObject* pParent=NULL);
virtual ~ControlObjectSlave();

void initialize(const ConfigKey& key);

bool connectValueChanged(const QObject* receiver,
const char* method, Qt::ConnectionType type = Qt::AutoConnection);
bool connectValueChanged(
const char* method, Qt::ConnectionType type = Qt::AutoConnection );


/** Called from update(); */
void emitValueChanged();

inline bool valid() const { return m_pControl != NULL; }

// Returns the value of the object. Thread safe, non-blocking.
virtual double get();

public slots:
// Set the control to a new value. Non-blocking.
virtual void slotSet(double v);
// Sets the control value to v. Thread safe, non-blocking.
virtual void set(double v);
// Resets the control to its default value. Thread safe, non-blocking.
virtual void reset();

signals:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment that you must not connect directly but instead should use connectValueChanged.

void valueChanged(double);

protected slots:
// Receives the value from the master control and re-emits either
// valueChanged(double) or valueChangedByThis(double) based on pSetter.
virtual void slotValueChanged(double v, QObject* pSetter);

protected:
// Pointer to connected control.
ControlDoublePrivate* m_pControl;
};

#endif // CONTROLOBJECTSLAVE_H
11 changes: 11 additions & 0 deletions src/controlobjectthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ void ControlObjectThread::initialize(const ConfigKey& key) {
ControlObjectThread::~ControlObjectThread() {
}

bool ControlObjectThread::connectValueChanged(const QObject* receiver,
const char* method, Qt::ConnectionType type) {
return connect((QObject*)this, SIGNAL(valueChanged(double)), receiver, method, type);
}

bool ControlObjectThread::connectValueChanged(
const char* method, Qt::ConnectionType type) {
return connect((QObject*)this, SIGNAL(valueChanged(double)), parent(), method, type);
}


double ControlObjectThread::get() {
return m_pControl ? m_pControl->get() : 0.0;
}
Expand Down
6 changes: 6 additions & 0 deletions src/controlobjectthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ class ControlObjectThread : public QObject {

void initialize(const ConfigKey& key);

bool connectValueChanged(const QObject* receiver,
const char* method, Qt::ConnectionType type = Qt::AutoConnection);
bool connectValueChanged(
const char* method, Qt::ConnectionType type = Qt::AutoConnection );


/** Called from update(); */
void emitValueChanged();

Expand Down
12 changes: 4 additions & 8 deletions src/engine/bpmcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "engine/bpmcontrol.h"
#include "engine/enginechannel.h"
#include "engine/enginemaster.h"
#include "controlobjectslave.h"

const int minBpm = 30;
const int maxInterval = (int)(1000.*(60./(CSAMPLE)minBpm));
Expand All @@ -19,14 +20,9 @@ BpmControl::BpmControl(const char* _group,
ConfigObject<ConfigValue>* _config) :
EngineControl(_group, _config),
m_tapFilter(this, filterLength, maxInterval) {
m_pPlayButton = ControlObject::getControl(_group, "play");
m_pRateSlider = ControlObject::getControl(_group, "rate");
connect(m_pRateSlider, SIGNAL(valueChanged(double)),
this, SLOT(slotAdjustBpm()),
Qt::DirectConnection);
connect(m_pRateSlider, SIGNAL(valueChangedFromEngine(double)),
this, SLOT(slotAdjustBpm()),
Qt::DirectConnection);
m_pPlayButton = new ControlObjectSlave(_group, "play", this);
m_pRateSlider = new ControlObjectSlave(_group, "rate", this);
m_pRateSlider->connectValueChanged(SLOT(slotAdjustBpm()), Qt::DirectConnection);

m_pRateRange = ControlObject::getControl(_group, "rateRange");
connect(m_pRateRange, SIGNAL(valueChanged(double)),
Expand Down
5 changes: 3 additions & 2 deletions src/engine/bpmcontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
class ControlObject;
class ControlPushButton;
class EngineBuffer;
class ControlObjectSlave;

class BpmControl : public EngineControl {
Q_OBJECT
Expand Down Expand Up @@ -42,8 +43,8 @@ class BpmControl : public EngineControl {
bool syncPhase(EngineBuffer* pOtherEngineBuffer);

// ControlObjects that come from EngineBuffer
ControlObject* m_pPlayButton;
ControlObject* m_pRateSlider;
ControlObjectSlave* m_pPlayButton;
ControlObjectSlave* m_pRateSlider;
ControlObject* m_pRateRange;
ControlObject* m_pRateDir;

Expand Down
3 changes: 2 additions & 1 deletion src/engine/clockcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
#include "configobject.h"
#include "cachingreader.h"
#include "engine/enginecontrol.h"
#include "controlobjectslave.h"

ClockControl::ClockControl(const char* pGroup, ConfigObject<ConfigValue>* pConfig)
: EngineControl(pGroup, pConfig) {
m_pCOBeatActive = new ControlObject(ConfigKey(pGroup, "beat_active"));
m_pCOBeatActive->set(0.0f);
m_pCOSampleRate = ControlObject::getControl(ConfigKey("[Master]","samplerate"));
m_pCOSampleRate = new ControlObjectSlave("[Master]","samplerate");
}

ClockControl::~ClockControl() {
Expand Down
4 changes: 3 additions & 1 deletion src/engine/clockcontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "trackinfoobject.h"
#include "track/beats.h"

class ControlObjectSlave;

class ClockControl: public EngineControl {
Q_OBJECT
public:
Expand All @@ -25,7 +27,7 @@ class ClockControl: public EngineControl {

private:
ControlObject* m_pCOBeatActive;
ControlObject* m_pCOSampleRate;
ControlObjectSlave* m_pCOSampleRate;
TrackPointer m_pTrack;
BeatsPointer m_pBeats;
};
Expand Down
3 changes: 2 additions & 1 deletion src/engine/enginebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "engine/bpmcontrol.h"
#include "engine/quantizecontrol.h"
#include "util/timer.h"
#include "controlobjectslave.h"

#ifdef __VINYLCONTROL__
#include "engine/vinylcontrolcontrol.h"
Expand Down Expand Up @@ -174,7 +175,7 @@ EngineBuffer::EngineBuffer(const char * _group, ConfigObject<ConfigValue> * _con
m_pRepeat->setButtonMode(ControlPushButton::TOGGLE);

// Sample rate
m_pSampleRate = ControlObject::getControl(ConfigKey("[Master]","samplerate"));
m_pSampleRate = new ControlObjectSlave("[Master]", "samplerate", this);

m_pTrackSamples = new ControlObject(ConfigKey(m_group, "track_samples"));
m_pTrackSampleRate = new ControlObject(ConfigKey(m_group, "track_samplerate"));
Expand Down
3 changes: 2 additions & 1 deletion src/engine/enginebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class RateControl;
class LoopingControl;
class ReadAheadManager;
class ControlObject;
class ControlObjectSlave;
class ControlPushButton;
class ControlObjectThreadMain;
class ControlBeat;
Expand Down Expand Up @@ -228,7 +229,7 @@ class EngineBuffer : public EngineObject
ControlObject* m_pMasterRate;
ControlPotmeter* m_playposSlider;
ControlPotmeter* m_visualPlaypos;
ControlObject* m_pSampleRate;
ControlObjectSlave* m_pSampleRate;
ControlPushButton* m_pKeylock;

ControlPushButton* m_pEject;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/enginecontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ EngineControl::EngineControl(const char * _group,
m_dTotalSamples(0),
m_pEngineMaster(NULL),
m_pEngineBuffer(NULL),
m_numDecks(ConfigKey("[Master]", "num_decks")) {
m_numDecks("[Master]", "num_decks") {
}

EngineControl::~EngineControl() {
Expand Down
6 changes: 3 additions & 3 deletions src/library/librarycontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ LibraryControl::LibraryControl(QObject* pParent)
: QObject(pParent),
m_pLibraryWidget(NULL),
m_pSidebarWidget(NULL),
m_numDecks(ConfigKey("[Master]", "num_decks")),
m_numSamplers(ConfigKey("[Master]", "num_samplers")),
m_numPreviewDecks(ConfigKey("[Master]", "num_preview_decks")) {
m_numDecks("[Master]", "num_decks"),
m_numSamplers("[Master]", "num_samplers"),
m_numPreviewDecks("[Master]", "num_preview_decks") {

slotNumDecksChanged(m_numDecks.get());
slotNumSamplersChanged(m_numSamplers.get());
Expand Down