示例#1
0
文件: chaser.cpp 项目: speakman/qlc
bool Chaser::write(QByteArray* universes)
{
	Q_UNUSED(universes);

	/* With some changes to scene, chaser could basically act as a
	   proxy for its members by calling the scene's write() functions
	   by itself instead of starting/stopping them. Whether this would do
	   any good is not clear. */

	/* TODO: One extra step is required in single shot mode to return
	   false and thus get a chaser removed from MasterTimer. Not a big
	   problem, but removing already after starting the last step would
	   improve performance (very) slightly. */

	if (m_elapsed == 0)
	{
		/* This is the first step since the last start() call */

		/* Get the next step index */
		nextStep();

		/* Start the current function */
		startMemberAt(m_runTimePosition);

		/* Mark one cycle being elapsed */
		m_elapsed = 1;
	}
	else if (m_elapsed >= Bus::instance()->value(m_busID) ||
		 m_tapped == true)
	{
		/* Reset tapped flag even if it wasn't true */
		m_tapped = false;

		/* Stop current function */
		stopMemberAt(m_runTimePosition);

		/* Get the next step index */
		nextStep();

		/* Check, whether we have gone a full cycle (thru all steps) */
		if (roundCheck() == false)
			return false;
		else
			startMemberAt(m_runTimePosition);

		/* Mark one cycle being elapsed since it tracks only the
		   duration of the current step. */
		m_elapsed = 1;
	}
	else
	{
		/* Just waiting for hold time to pass */
		m_elapsed++;
	}

	return true;
}
示例#2
0
void RGBMatrix::tap()
{
    if (stopped() == false)
    {
        FixtureGroup* grp = doc()->fixtureGroup(fixtureGroup());
        // Filter out taps that are too close to each other
        if (grp != NULL && uint(m_roundTime->elapsed()) >= (duration() / 4))
            roundCheck(grp->size());
    }
}
示例#3
0
void RGBMatrix::write(MasterTimer* timer, QList<Universe *> universes)
{
    Q_UNUSED(timer);
    Q_UNUSED(universes);

    FixtureGroup* grp = doc()->fixtureGroup(fixtureGroup());
    if (grp == NULL)
    {
        // No fixture group to control
        stop();
        return;
    }

    // No time to do anything.
    if (duration() == 0)
        return;

    // Invalid/nonexistent script
    {
        QMutexLocker algorithmLocker(&m_algorithmMutex);
        if (m_algorithm == NULL || m_algorithm->apiVersion() == 0)
            return;

        // Get new map every time when elapsed is reset to zero
        if (elapsed() == 0)
        {
            qDebug() << "RGBMatrix stepColor:" << QString::number(m_stepColor.rgb(), 16);
            RGBMap map = m_algorithm->rgbMap(grp->size(), m_stepColor.rgb(), m_step);
            updateMapChannels(map, grp);
        }
    }

    // Run the generic fader that takes care of fading in/out individual channels
    m_fader->write(universes);

    // Increment elapsed time
    incrementElapsed();

    // Check if we need to change direction, stop completely or go to next step
    if (elapsed() >= duration())
        roundCheck(grp->size());
}
示例#4
0
bool ChaserRunner::write(MasterTimer* timer, UniverseArray* universes)
{
    // Nothing to do
    if (m_steps.size() == 0)
        return false;

    if (m_newCurrent != -1)
    {
        // Manually-set current step
        m_currentStep = m_newCurrent;
        m_newCurrent = -1;

        // No need to do roundcheck here, since manually-set steps are
        // always within m_steps limits.

        m_elapsed = 1;
        handleChannelSwitch(timer, universes);
        emit currentStepChanged(m_currentStep);
    }
    else if (m_elapsed == 0)
    {
        // First step
        m_elapsed = 1;
        handleChannelSwitch(timer, universes);
        emit currentStepChanged(m_currentStep);
    }
    else if ((isAutoStep() && m_elapsed >= Bus::instance()->value(m_holdBusId))
             || m_next == true || m_previous == true)
    {
        // Next step
        if (m_direction == Function::Forward)
        {
            // "Previous" for a forwards chaser is -1
            if (m_previous == true)
                m_currentStep--;
            else
                m_currentStep++;
        }
        else
        {
            // "Previous" for a backwards scene is +1
            if (m_previous == true)
                m_currentStep++;
            else
                m_currentStep--;
        }

        if (roundCheck() == false)
            return false;

        m_elapsed = 1;
        m_next = false;
        m_previous = false;

        handleChannelSwitch(timer, universes);
        emit currentStepChanged(m_currentStep);
    }
    else
    {
        // Current step. UINT_MAX is the maximum hold time.
        if (m_elapsed < UINT_MAX)
            m_elapsed++;
    }

    QMutableMapIterator <quint32,FadeChannel> it(m_channelMap);
    while (it.hasNext() == true)
    {
        Scene* scene = qobject_cast<Scene*> (m_steps.at(m_currentStep));
        if (scene == NULL)
            continue;

        quint32 fadeTime = Bus::instance()->value(scene->busID());

        FadeChannel& channel(it.next().value());
        if (channel.current() == channel.target() && channel.group() != QLCChannel::Intensity)
        {
            /* Write the final value to LTP channels only once */
        }
        else
        {
            uchar value = uchar(floor((qreal(channel.calculateCurrent(fadeTime, m_elapsed)) * m_intensity) + 0.5));
            universes->write(channel.address(), value, channel.group());
        }
    }

    return true;
}
示例#5
0
bool ChaserRunner::write(MasterTimer* timer, UniverseArray* universes)
{
    Q_UNUSED(universes);

    // Nothing to do
    if (m_chaser->steps().size() == 0)
        return false;

    if (m_newCurrent != -1)
    {
        // Manually-set current step
        m_currentStep = m_newCurrent;
        m_newCurrent = -1;

        // No need to do roundcheck here, since manually-set steps are
        // always within m_chaser->steps() limits.

        m_elapsed = MasterTimer::tick();
        switchFunctions(timer);
        emit currentStepChanged(m_currentStep);
    }
    else if (m_elapsed == 0)
    {
        // First step
        m_elapsed = MasterTimer::tick();
        switchFunctions(timer);
        emit currentStepChanged(m_currentStep);
    }
    else if (m_next == true || m_previous == true ||
             (currentDuration() != Function::infiniteSpeed() && m_elapsed >= currentDuration()))
    {
        // Next step
        if (m_direction == Function::Forward)
        {
            // "Previous" for a forwards chaser is -1
            if (m_previous == true)
                m_currentStep--;
            else
                m_currentStep++;
        }
        else
        {
            // "Previous" for a backwards scene is +1
            if (m_previous == true)
                m_currentStep++;
            else
                m_currentStep--;
        }

        if (roundCheck() == false)
            return false;

        m_elapsed = MasterTimer::tick();
        m_next = false;
        m_previous = false;

        switchFunctions(timer);
        emit currentStepChanged(m_currentStep);
    }
    else
    {
        // Current step. UINT_MAX is the maximum hold time.
        if (m_elapsed < UINT_MAX)
            m_elapsed += MasterTimer::tick();
    }

    // When the speeds of the chaser change, they need to be updated to the lower
    // level (only current function) as well. Otherwise the new speeds would take
    // effect only on the next step change.
    if (m_updateOverrideSpeeds == true)
    {
        m_updateOverrideSpeeds = false;
        if (m_currentFunction != NULL)
        {
            m_currentFunction->setOverrideFadeInSpeed(currentFadeIn());
            m_currentFunction->setOverrideFadeOutSpeed(currentFadeOut());
        }
    }

    return true;
}
示例#6
0
void RGBMatrix::write(MasterTimer* timer, QList<Universe *> universes)
{
    Q_UNUSED(timer);

    {
        QMutexLocker algorithmLocker(&m_algorithmMutex);
        if (m_group == NULL)
        {
            // No fixture group to control
            stop(FunctionParent::master());
            return;
        }

        // No time to do anything.
        if (duration() == 0)
            return;

        // Invalid/nonexistent script
        if (m_algorithm == NULL || m_algorithm->apiVersion() == 0)
            return;

        if (isPaused() == false)
        {
            // Get a new map every time elapsed is reset to zero
            if (elapsed() < MasterTimer::tick())
            {
                if (tempoType() == Beats)
                    m_stepBeatDuration = beatsToTime(duration(), timer->beatTimeDuration());

                //qDebug() << "RGBMatrix step" << m_stepHandler->currentStepIndex() << ", color:" << QString::number(m_stepHandler->stepColor().rgb(), 16);
                RGBMap map = m_algorithm->rgbMap(m_group->size(), m_stepHandler->stepColor().rgb(), m_stepHandler->currentStepIndex());
                updateMapChannels(map, m_group);
            }
        }
    }

    // Run the generic fader that takes care of fading in/out individual channels
    m_fader->write(universes, isPaused());

    if (isPaused() == false)
    {
        // Increment the ms elapsed time
        incrementElapsed();

        /* Check if we need to change direction, stop completely or go to next step
         * The cases are:
         * 1- time tempo type: act normally, on ms elapsed time
         * 2- beat tempo type, beat occurred: check if the elapsed beats is a multiple of
         *    the step beat duration. If so, proceed to the next step
         * 3- beat tempo type, not beat: if the ms elapsed time reached the step beat
         *    duration in ms, and the ms time to the next beat is not less than 1/16 of
         *    the step beat duration in ms, then proceed to the next step. If the ms time to the
         *    next beat is less than 1/16 of the step beat duration in ms, then defer the step
         *    change to case #2, to resync the matrix to the next beat
         */
        if (tempoType() == Time && elapsed() >= duration())
        {
            roundCheck();
        }
        else if (tempoType() == Beats)
        {
            if (timer->isBeat())
            {
                incrementElapsedBeats();
                qDebug() << "Elapsed beats:" << elapsedBeats() << ", time elapsed:" << elapsed() << ", step time:" << m_stepBeatDuration;
                if (elapsedBeats() % duration() == 0)
                {
                    roundCheck();
                    resetElapsed();
                }
            }
            else if (elapsed() >= m_stepBeatDuration && (uint)timer->timeToNextBeat() > m_stepBeatDuration / 16)
            {
                qDebug() << "Elapsed exceeded";
                roundCheck();
            }
        }
    }
}