Skip to content

Commit

Permalink
qmlui: improve DMX dump to achieve maximum flexibility
Browse files Browse the repository at this point in the history
  • Loading branch information
mcallegari committed Nov 9, 2024
1 parent 7872029 commit e60bb30
Show file tree
Hide file tree
Showing 14 changed files with 710 additions and 404 deletions.
5 changes: 5 additions & 0 deletions engine/src/doc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,11 @@ QList<Fixture*> const& Doc::fixtures() const
return m_fixturesListCache;
}

int Doc::fixturesCount() const
{
return m_fixtures.count();
}

Fixture* Doc::fixture(quint32 id) const
{
return m_fixtures.value(id, NULL);
Expand Down
7 changes: 7 additions & 0 deletions engine/src/doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,13 @@ class Doc : public QObject
*/
QList<Fixture*> const& fixtures() const;

/**
* Get the number of fixtures currently added to the project
*
* @return The number of fixtures
*/
int fixturesCount() const;

/**
* Get the fixture that occupies the given DMX address. If multiple fixtures
* occupy the same address, the one that has been last modified is returned.
Expand Down
15 changes: 3 additions & 12 deletions qmlui/contextmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1740,14 +1740,10 @@ int ContextManager::dumpChannelMask() const
return m_dumpChannelMask;
}

void ContextManager::dumpDmxChannels(QString name, quint32 mask)
void ContextManager::dumpDmxChannels(quint32 channelMask, QString sceneName, int sceneID, bool allChannels, bool nonZeroOnly)
{
m_functionManager->dumpOnNewScene(m_dumpValues, selectedFixtureIDList(), mask, name);
}

void ContextManager::dumpDmxChannels(quint32 sceneID, quint32 mask)
{
m_functionManager->dumpOnScene(m_dumpValues, selectedFixtureIDList(), mask, sceneID);
m_functionManager->dumpDmxValues(m_dumpValues, allChannels ? QList<quint32>() : selectedFixtureIDList(), channelMask,
sceneName, sceneID == -1 ? Function::invalidId() : sceneID, nonZeroOnly);
}

void ContextManager::resetDumpValues()
Expand All @@ -1764,8 +1760,3 @@ void ContextManager::resetDumpValues()
emit dumpChannelMaskChanged();
}

GenericDMXSource *ContextManager::dmxSource() const
{
return m_source;
}

7 changes: 2 additions & 5 deletions qmlui/contextmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,15 +302,12 @@ protected slots:
/** Return the current DMX dump channel type mask */
int dumpChannelMask() const;

Q_INVOKABLE void dumpDmxChannels(QString name, quint32 mask);

Q_INVOKABLE void dumpDmxChannels(quint32 sceneID, quint32 mask);
Q_INVOKABLE void dumpDmxChannels(quint32 channelMask, QString sceneName, int sceneID,
bool allChannels, bool nonZeroOnly);

/** Resets the current values used for dumping or preview */
Q_INVOKABLE void resetDumpValues();

GenericDMXSource *dmxSource() const;

/** Return a list only of the fixture IDs from the selected preview items */
QList<quint32> selectedFixtureIDList() const;

Expand Down
25 changes: 24 additions & 1 deletion qmlui/fixturemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ FixtureManager::FixtureManager(QQuickView *view, Doc *doc, QObject *parent)
, m_maxBeamDegrees(0)
, m_invertedZoom(false)
, m_colorsMask(0)
, m_capabilityMask(0)
, m_selectedChannelModifier(nullptr)
{
Q_ASSERT(m_doc != nullptr);
Expand Down Expand Up @@ -415,7 +416,7 @@ bool FixtureManager::renameFixture(quint32 itemID, QString newName)

int FixtureManager::fixturesCount()
{
return m_doc->fixtures().count();
return m_doc->fixturesCount();
}

QVariant FixtureManager::groupsTreeModel()
Expand Down Expand Up @@ -1776,6 +1777,7 @@ QMultiHash<int, SceneValue> FixtureManager::getFixtureCapabilities(quint32 itemI
bool hasShutter = false, hasColorWheel = false, hasGobos = false;
bool hasBeam = false;
int origColorsMask = m_colorsMask;
quint32 origCapabilityMask = m_capabilityMask;
QLCPhysical phy;

QList<quint32> channelIndices;
Expand Down Expand Up @@ -1810,6 +1812,18 @@ QMultiHash<int, SceneValue> FixtureManager::getFixtureCapabilities(quint32 itemI

int chType = channel->group();

if (chType == QLCChannel::Intensity)
{
if (channel->colour() == QLCChannel::NoColour)
m_capabilityMask |= App::DimmerType;
else
m_capabilityMask |= App::ColorType;
}
else
{
m_capabilityMask |= (1 << chType);
}

switch (channel->group())
{
case QLCChannel::Intensity:
Expand Down Expand Up @@ -1955,6 +1969,9 @@ QMultiHash<int, SceneValue> FixtureManager::getFixtureCapabilities(quint32 itemI
if (origColorsMask != m_colorsMask)
emit colorsMaskChanged(m_colorsMask);

if (origCapabilityMask != m_capabilityMask)
emit capabilityMaskChanged();

updateCapabilityCounter(hasDimmer, "capIntensity", capDelta);
updateCapabilityCounter(hasColor, "capColor", capDelta);
updateCapabilityCounter(hasPosition, "capPosition", capDelta);
Expand All @@ -1973,6 +1990,7 @@ void FixtureManager::resetCapabilities()
m_minBeamDegrees = 15.0;
m_maxBeamDegrees = 0;
m_colorsMask = 0;
m_capabilityMask = 0;
}

QList<SceneValue> FixtureManager::getFixturePosition(quint32 fxID, int type, int degrees)
Expand Down Expand Up @@ -2136,6 +2154,11 @@ QVariantList FixtureManager::presetChannel(quint32 fixtureID, int chIndex)
return prList;
}

quint32 FixtureManager::capabilityMask() const
{
return m_capabilityMask;
}

int FixtureManager::colorsMask() const
{
return m_colorsMask;
Expand Down
11 changes: 11 additions & 0 deletions qmlui/fixturemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class FixtureManager : public QObject
Q_PROPERTY(QVariantList colorWheelChannels READ colorWheelChannels NOTIFY colorWheelChannelsChanged)
Q_PROPERTY(QVariantList shutterChannels READ shutterChannels NOTIFY shutterChannelsChanged)
Q_PROPERTY(int colorsMask READ colorsMask NOTIFY colorsMaskChanged)
Q_PROPERTY(quint32 capabilityMask READ capabilityMask NOTIFY capabilityMaskChanged)

Q_PROPERTY(QStringList colorFiltersFileList READ colorFiltersFileList NOTIFY colorFiltersFileListChanged)
Q_PROPERTY(int colorFilterFileIndex READ colorFilterFileIndex WRITE setColorFilterFileIndex NOTIFY colorFilterFileIndexChanged)
Expand Down Expand Up @@ -437,6 +438,9 @@ public slots:
/** Returns a preset channel usable by the QML PresetTool */
Q_INVOKABLE QVariantList presetChannel(quint32 fixtureID, int chIndex);

/** Return the current capability type mask */
quint32 capabilityMask() const;

/** Returns the currently available colors as a bitmask */
int colorsMask() const;

Expand Down Expand Up @@ -469,6 +473,9 @@ public slots:
/** Notify the listeners that the available colors changed */
void colorsMaskChanged(int colorsMask);

/** Notify the listeners that the available capabilities changed */
void capabilityMaskChanged();

private:
/** Generic method that returns the names of the cached channels for
* the required $group */
Expand Down Expand Up @@ -496,6 +503,10 @@ public slots:

/** Bitmask holding the colors supported by the currently selected fixtures */
int m_colorsMask;

/** Bitmask holding the capability supported by the currently selected fixtures */
quint32 m_capabilityMask;

/** A map of the currently available colors and their counters */
QMap<int, int> m_colorCounters;

Expand Down
133 changes: 133 additions & 0 deletions qmlui/functionmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ QVariant FunctionManager::functionsList()
return QVariant::fromValue(m_functionTree);
}

quint32 FunctionManager::nextFunctionId() const
{
return m_doc->nextFunctionID();
}

QVariantList FunctionManager::usageList(quint32 fid)
{
QVariantList list;
Expand Down Expand Up @@ -1103,6 +1108,134 @@ void FunctionManager::deleteSelectedFolders()
* DMX values (dumping and Scene editor)
*********************************************************************/

void FunctionManager::dumpDmxValues(QList<SceneValue> dumpValues, QList<quint32> selectedFixtures,
quint32 channelMask, QString sceneName, quint32 sceneID, bool nonZeroOnly)
{
qDebug() << "[DUMP] # of values:" << dumpValues.count();
qDebug() << "[DUMP] Selected fixture IDs:" << selectedFixtures;
qDebug() << "[DUMP] Channel mask:" << channelMask;
qDebug() << "[DUMP] Scene name/ID:" << sceneName << sceneID;
qDebug() << "[DUMP] Only non-zero?" << nonZeroOnly;

QList<Universe*> ua = m_doc->inputOutputMap()->claimUniverses();

// 1- load current pre-GM values from all the universes
QByteArray preGMValues(ua.size() * UNIVERSE_SIZE, 0);

for (int i = 0; i < ua.count(); ++i)
{
const int offset = i * UNIVERSE_SIZE;
preGMValues.replace(offset, UNIVERSE_SIZE, ua.at(i)->preGMValues());
if (ua.at(i)->passthrough())
{
for (int j = 0; j < UNIVERSE_SIZE; ++j)
{
const int ofs = offset + j;
preGMValues[ofs] =
static_cast<char>(ua.at(i)->applyPassthrough(j, static_cast<uchar>(preGMValues[ofs])));
}
}
}

m_doc->inputOutputMap()->releaseUniverses(false);

// 2- determine if we're dumping on a new or existing Scene
Scene *targetScene = nullptr;
if (sceneID != Function::invalidId())
{
targetScene = qobject_cast<Scene*>(m_doc->function(sceneID));
}
else
{
targetScene = new Scene(m_doc);
targetScene->setName(sceneName);
}

// 3- prepare the fixture list. If 'all channels' is required,
// selectedFixtures list will be empty

QList<Fixture *> fixtureList;
bool allChannels = false;
for (quint32 fixtureID : selectedFixtures)
{
Fixture *fixture = m_doc->fixture(fixtureID);
if (fixture != nullptr)
fixtureList.append(fixture);
}

if (fixtureList.isEmpty())
{
fixtureList.append(m_doc->fixtures());
allChannels = true;
}

// 4- iterate over all channels of all gathered fixtures
// and store values in the target Scene
for (Fixture *fixture : fixtureList)
{
quint32 baseAddress = fixture->universeAddress();

for (quint32 chIndex = 0; chIndex < fixture->channels(); chIndex++)
{
if (allChannels)
{
uchar value = preGMValues.at(baseAddress + chIndex);
if (!nonZeroOnly || (nonZeroOnly && value > 0))
{
SceneValue scv = SceneValue(fixture->id(), chIndex, value);
targetScene->setValue(scv);
}
}
else
{
const QLCChannel *channel = fixture->channel(chIndex);
quint32 chTypeBit = 0;

if (channel->group() == QLCChannel::Intensity)
{
if (channel->colour() == QLCChannel::NoColour)
chTypeBit |= App::DimmerType;
else
chTypeBit |= App::ColorType;
}
else
{
chTypeBit |= (1 << channel->group());
}

if (channelMask & chTypeBit)
{
uchar value = preGMValues.at(baseAddress + chIndex);
SceneValue scv = SceneValue(fixture->id(), chIndex, value);
int matchVal = dumpValues.indexOf(scv);
if (matchVal != -1)
scv.value = dumpValues.at(matchVal).value;

targetScene->setValue(scv);
}
}
}
}

// 5- add Scene to the project, if needed
if (sceneID == Function::invalidId())
{
if (sceneName.isEmpty())
targetScene->setName(QString("%1 %2").arg(targetScene->name()).arg(m_doc->nextFunctionID() + 1));
else
targetScene->setName(sceneName);

if (m_doc->addFunction(targetScene) == true)
{
setPreviewEnabled(false);
Tardis::instance()->enqueueAction(Tardis::FunctionCreate, targetScene->id(), QVariant(),
Tardis::instance()->actionToByteArray(Tardis::FunctionCreate, targetScene->id()));
}
else
delete targetScene;
}
}

quint32 FunctionManager::getChannelTypeMask(quint32 fxID, quint32 channel)
{
Fixture *fixture = m_doc->fixture(fxID);
Expand Down
5 changes: 5 additions & 0 deletions qmlui/functionmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class FunctionManager : public QObject
/** Read only property to expose the function tree to the QML UI */
QVariant functionsList();

Q_INVOKABLE quint32 nextFunctionId() const;

/** Get a list of Functions that use $fid */
Q_INVOKABLE QVariantList usageList(quint32 fid);

Expand Down Expand Up @@ -289,6 +291,9 @@ public slots:
/** Reset the currently set channel values */
void resetDumpValues();

void dumpDmxValues(QList<SceneValue> dumpValues, QList<quint32> selectedFixtures,
quint32 channelMask, QString sceneName, quint32 sceneID, bool nonZeroOnly);

/** Dump DMX values provided by $dumpValues, filtered by the provided $selectedFixtures
* and the provided $channelMask.
* The new Scene will be named with $name if not empty, otherwise with an autogenerated name */
Expand Down
5 changes: 5 additions & 0 deletions qmlui/inputoutputmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ void InputOutputManager::removeLastUniverse()
emit universeNamesChanged();
}

int InputOutputManager::universesCount()
{
return m_ioMap->universesCount();
}

bool InputOutputManager::blackout() const
{
return m_blackout;
Expand Down
1 change: 1 addition & 0 deletions qmlui/inputoutputmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ protected slots:

Q_INVOKABLE void addUniverse();
Q_INVOKABLE void removeLastUniverse();
Q_INVOKABLE int universesCount();

/** Get/Set the global output blackout state */
bool blackout() const;
Expand Down
Loading

0 comments on commit e60bb30

Please sign in to comment.