<commit_before>//  Natron
//
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 *Created by <NAME> on 6/1/2012.
 *contact: immarespond at gmail dot com
 *
 */

#ifndef KNOBIMPL_H
#define KNOBIMPL_H

#include "Knob.h"

#include <stdexcept>
#include <string>
#include <QString>
#include "Engine/Curve.h"
#include "Engine/AppInstance.h"
#include "Engine/Project.h"
#include "Engine/TimeLine.h"
#include "Engine/EffectInstance.h"

///template specializations

template <typename T>
Knob<T>::Knob(KnobHolder*  holder,const std::string& description,int dimension )
    : KnobHelper(holder,description,dimension)
    , _valueMutex(QReadWriteLock::Recursive)
    , _values(dimension)
    , _defaultValues(dimension)
    , _setValueRecursionLevel(false)
    , _setValueRecursionLevelMutex(QMutex::Recursive)
{
    
}

//Declare the specialization before defining it to avoid the following
//error: explicit specialization of 'getValueAtTime' after instantiation
template<>
std::string Knob<std::string>::getValueAtTime(double time, int dimension) const;

template<>
std::string Knob<std::string>::getValue(int dimension) const
{
    if (isAnimated(dimension)) {
        return getValueAtTime(getHolder()->getApp()->getTimeLine()->currentFrame(), dimension);
    }
    
    if (dimension > (int)_values.size() || dimension < 0) {
        throw std::invalid_argument("Knob::getValue(): Dimension out of range");
    }
    ///if the knob is slaved to another knob, returns the other knob value
    std::pair<int,boost::shared_ptr<KnobI> > master = getMaster(dimension);
    if (master.second) {
        Knob<std::string>* isString = dynamic_cast<Knob<std::string>* >(master.second.get());
        assert(isString); //< other data types aren't supported
        return isString->getValue(master.first);
    }
    
    QReadLocker l(&_valueMutex);
    return _values[dimension];
    
}

template <typename T>
T Knob<T>::getValue(int dimension) const
{
    if (isAnimated(dimension)) {
        return getValueAtTime(getHolder()->getApp()->getTimeLine()->currentFrame(), dimension);
    }

    if (dimension > (int)_values.size() || dimension < 0) {
        throw std::invalid_argument("Knob::getValue(): Dimension out of range");
    }
    ///if the knob is slaved to another knob, returns the other knob value<commit_msg>Don't use getHolder->getApp for Settings<commit_after>//  Natron
//
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 *Created by <NAME> on 6/1/2012.
 *contact: immarespond at gmail dot com
 *
 */

#ifndef KNOBIMPL_H
#define KNOBIMPL_H

#include "Knob.h"

#include <stdexcept>
#include <string>
#include <QString>
#include "Engine/Curve.h"
#include "Engine/AppInstance.h"
#include "Engine/Project.h"
#include "Engine/TimeLine.h"
#include "Engine/EffectInstance.h"

///template specializations

template <typename T>
Knob<T>::Knob(KnobHolder*  holder,const std::string& description,int dimension )
    : KnobHelper(holder,description,dimension)
    , _valueMutex(QReadWriteLock::Recursive)
    , _values(dimension)
    , _defaultValues(dimension)
    , _setValueRecursionLevel(false)
    , _setValueRecursionLevelMutex(QMutex::Recursive)
{
    
}

//Declare the specialization before defining it to avoid the following
//error: explicit specialization of 'getValueAtTime' after instantiation
template<>
std::string Knob<std::string>::getValueAtTime(double time, int dimension) const;

template<>
std::string Knob<std::string>::getValue(int dimension) const
{
    if (isAnimated(dimension)) {
        SequenceTime time;
        if (!getHolder()->getApp()) {
            time = 0;
        } else {
            time = getHolder()->getApp()->getTimeLine()->currentFrame();
        }
        return getValueAtTime(time, dimension);
    }
    
    if (dimension > (int)_values.size() || dimension < 0) {
        throw std::invalid_argument("Knob::getValue(): Dimension out of range");
    }
    ///if the knob is slaved to another knob, returns the other knob value
    std::pair<int,boost::shared_ptr<KnobI> > master = getMaster(dimension);
    if (master.second) {
        Knob<std::string>* isString = dynamic_cast<Knob<std::string>* >(master.second.get());
        assert(isString); //< other data types aren't supported
        return isString->getValue(master.first);
    }
    
    QReadLocker l(&_valueMutex);
    return _values[dimension];
    
}

template <typename T>
T Knob<T>::getValue(int dimension) const
{
    if (isAnimated(dimension)) {
        SequenceTime time;
        if (!getHolder()->getApp()) {
            time = 0;
        } else {
            time = getHolder()->getApp()->getTimeLine()->currentFrame();
        }
        return getValueAtTime(time, dimension);
    }

    if (dimension > (int)_values.size() || dimension < 0) {
        throw std::invalid_argument("Knob::getValue(): Dimension out of range");
    }
    ///if the knob is slaved to another knob, returns the other knob value
{'fraction_non_alphanumeric': 0.13390639923591213, 'fraction_numerical': 0.0049665711556829036, 'mean_word_length': 3.7427536231884058, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2436573', 'n_tokens_mistral': 1651, 'n_tokens_neox': 1601, 'n_words': 421}