blob: 5b29cc45572c3e2c9c92255649593e050d9ff63b [file] [log] [blame] [edit]
#include "rive/animation/transition_viewmodel_condition.hpp"
#include "rive/animation/state_transition.hpp"
#include "rive/importers/state_transition_importer.hpp"
#include "rive/importers/state_machine_importer.hpp"
#include "rive/animation/state_machine.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/component_dirt.hpp"
using namespace rive;
class ConditionComparisonNone : public ConditionComparison
{
public:
ConditionComparisonNone() : ConditionComparison(nullptr) {}
bool compare(const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) override
{
return false;
}
};
class ConditionComparisonSelf : public ConditionComparison
{
public:
ConditionComparisonSelf(BindableProperty* property) :
ConditionComparison(nullptr), m_bindableProperty(property)
{}
bool compare(const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) override
{
auto bindableInstance =
stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
auto dataBind =
stateMachineInstance->bindableDataBindToTarget(bindableInstance);
if (dataBind != nullptr)
{
auto source = dataBind->source();
if (source != nullptr && source->hasChanged() &&
!source->isUsedInLayer(layerInstance))
{
return true;
}
}
return false;
}
private:
BindableProperty* m_bindableProperty;
};
class ConditionComparisonNumber : public ConditionComparison
{
public:
ConditionComparisonNumber(ConditionComparandNumber* left,
ConditionComparandNumber* right,
ConditionOperation* operation) :
ConditionComparison(operation),
m_leftComparand(left),
m_rightComparand(right)
{}
~ConditionComparisonNumber()
{
delete m_leftComparand;
delete m_rightComparand;
}
bool compare(const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) override
{
return compareNumbers(m_leftComparand->value(stateMachineInstance),
m_rightComparand->value(stateMachineInstance));
}
private:
ConditionComparandNumber* m_leftComparand = nullptr;
ConditionComparandNumber* m_rightComparand = nullptr;
};
class ConditionComparisonBoolean : public ConditionComparison
{
public:
ConditionComparisonBoolean(ConditionComparandBoolean* left,
ConditionComparandBoolean* right,
ConditionOperation* operation) :
ConditionComparison(operation),
m_leftComparand(left),
m_rightComparand(right)
{}
~ConditionComparisonBoolean() override
{
delete m_leftComparand;
delete m_rightComparand;
}
bool compare(const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) override
{
return compareBooleans(m_leftComparand->value(stateMachineInstance),
m_rightComparand->value(stateMachineInstance));
}
private:
ConditionComparandBoolean* m_leftComparand = nullptr;
ConditionComparandBoolean* m_rightComparand = nullptr;
};
class ConditionComparisonString : public ConditionComparison
{
public:
ConditionComparisonString(ConditionComparandString* left,
ConditionComparandString* right,
ConditionOperation* operation) :
ConditionComparison(operation),
m_leftComparand(left),
m_rightComparand(right)
{}
~ConditionComparisonString()
{
delete m_leftComparand;
delete m_rightComparand;
}
bool compare(const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) override
{
return compareStrings(m_leftComparand->value(stateMachineInstance),
m_rightComparand->value(stateMachineInstance));
}
private:
ConditionComparandString* m_leftComparand = nullptr;
ConditionComparandString* m_rightComparand = nullptr;
};
class ConditionComparisonColor : public ConditionComparison
{
public:
ConditionComparisonColor(ConditionComparandColor* left,
ConditionComparandColor* right,
ConditionOperation* operation) :
ConditionComparison(operation),
m_leftComparand(left),
m_rightComparand(right)
{}
~ConditionComparisonColor()
{
delete m_leftComparand;
delete m_rightComparand;
}
bool compare(const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) override
{
return compareColors(m_leftComparand->value(stateMachineInstance),
m_rightComparand->value(stateMachineInstance));
}
private:
ConditionComparandColor* m_leftComparand = nullptr;
ConditionComparandColor* m_rightComparand = nullptr;
};
class ConditionComparisonEnum : public ConditionComparison
{
public:
ConditionComparisonEnum(ConditionComparandUint32* left,
ConditionComparandUint32* right,
ConditionOperation* operation) :
ConditionComparison(operation),
m_leftComparand(left),
m_rightComparand(right)
{}
~ConditionComparisonEnum()
{
delete m_leftComparand;
delete m_rightComparand;
}
bool compare(const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) override
{
return compareUints32(m_leftComparand->value(stateMachineInstance),
m_rightComparand->value(stateMachineInstance));
}
private:
ConditionComparandUint32* m_leftComparand = nullptr;
ConditionComparandUint32* m_rightComparand = nullptr;
};
class ConditionComparisonUint32 : public ConditionComparison
{
public:
ConditionComparisonUint32(ConditionComparandUint32* left,
ConditionComparandUint32* right,
ConditionOperation* operation) :
ConditionComparison(operation),
m_leftComparand(left),
m_rightComparand(right)
{}
~ConditionComparisonUint32()
{
delete m_leftComparand;
delete m_rightComparand;
}
bool compare(const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) override
{
return compareUints32(m_leftComparand->value(stateMachineInstance),
m_rightComparand->value(stateMachineInstance));
}
private:
ConditionComparandUint32* m_leftComparand = nullptr;
ConditionComparandUint32* m_rightComparand = nullptr;
};
TransitionViewModelCondition::~TransitionViewModelCondition()
{
if (m_leftComparator != nullptr)
{
delete m_leftComparator;
m_leftComparator = nullptr;
}
if (m_rightComparator != nullptr)
{
delete m_rightComparator;
m_rightComparator = nullptr;
}
if (m_comparison != nullptr)
{
delete m_comparison;
m_comparison = nullptr;
}
}
bool TransitionViewModelCondition::evaluate(
const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) const
{
if (stateMachineInstance->dataContext())
{
return m_comparison->compare(stateMachineInstance, layerInstance);
}
return false;
}
void TransitionViewModelCondition::useInLayer(
const StateMachineInstance* stateMachineInstance,
StateMachineLayerInstance* layerInstance) const
{
if (leftComparator() != nullptr)
{
return leftComparator()->useInLayer(stateMachineInstance,
layerInstance);
}
}
ConditionOperation* TransitionViewModelCondition::operation(
TransitionConditionOp op)
{
switch (op)
{
case TransitionConditionOp::equal:
return new ConditionOperationEqual();
case TransitionConditionOp::notEqual:
return new ConditionOperationNotEqual();
case TransitionConditionOp::lessThanOrEqual:
return new ConditionOperationLessThanOrEqual();
case TransitionConditionOp::lessThan:
return new ConditionOperationLessThan();
case TransitionConditionOp::greaterThanOrEqual:
return new ConditionOperationGreaterThanOrEqual();
case TransitionConditionOp::greaterThan:
return new ConditionOperationGreaterThan();
}
return new ConditionOperation();
}
void TransitionViewModelCondition::initialize()
{
if (leftComparator() && rightComparator())
{
if (leftComparator()->is<TransitionPropertyArtboardComparator>())
{
auto leftProperty =
leftComparator()->as<TransitionPropertyArtboardComparator>();
if (rightComparator()->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyNumber>())
{
auto leftComparand =
new ConditionComparandArtboardProperty(leftProperty);
auto rightComparand = new ConditionComparandNumberBindable(
rightBindableProperty->as<BindablePropertyNumber>());
m_comparison =
new ConditionComparisonNumber(leftComparand,
rightComparand,
operation(op()));
return;
}
else if (rightBindableProperty->is<BindablePropertyInteger>())
{
auto leftComparand =
new ConditionComparandArtboardProperty(leftProperty);
auto rightComparand =
new ConditionComparandNumberBindableInteger(
rightBindableProperty
->as<BindablePropertyInteger>());
m_comparison =
new ConditionComparisonNumber(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()->is<TransitionValueNumberComparator>())
{
auto leftComparand =
new ConditionComparandArtboardProperty(leftProperty);
auto rightComparand = new ConditionComparandNumberValue(
rightComparator()->as<TransitionValueNumberComparator>());
m_comparison = new ConditionComparisonNumber(leftComparand,
rightComparand,
operation(op()));
return;
}
}
auto leftBindableProperty =
leftComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightComparator()->is<TransitionSelfComparator>())
{
m_comparison = new ConditionComparisonSelf(leftBindableProperty);
return;
}
switch (leftBindableProperty->coreType())
{
case BindablePropertyNumber::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyNumber>())
{
auto leftComparand =
new ConditionComparandNumberBindable(
leftBindableProperty
->as<BindablePropertyNumber>());
auto rightComparand =
new ConditionComparandNumberBindable(
rightBindableProperty
->as<BindablePropertyNumber>());
m_comparison =
new ConditionComparisonNumber(leftComparand,
rightComparand,
operation(op()));
return;
}
else if (rightBindableProperty
->is<BindablePropertyInteger>())
{
auto leftComparand =
new ConditionComparandNumberBindable(
leftBindableProperty
->as<BindablePropertyNumber>());
auto rightComparand =
new ConditionComparandNumberBindableInteger(
rightBindableProperty
->as<BindablePropertyInteger>());
m_comparison =
new ConditionComparisonNumber(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()
->is<TransitionValueNumberComparator>())
{
auto leftComparand = new ConditionComparandNumberBindable(
leftBindableProperty->as<BindablePropertyNumber>());
auto rightComparand = new ConditionComparandNumberValue(
rightComparator()
->as<TransitionValueNumberComparator>());
m_comparison =
new ConditionComparisonNumber(leftComparand,
rightComparand,
operation(op()));
return;
}
break;
}
case BindablePropertyBoolean::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyBoolean>())
{
auto leftComparand =
new ConditionComparandBooleanBindable(
leftBindableProperty
->as<BindablePropertyBoolean>());
auto rightComparand =
new ConditionComparandBooleanBindable(
rightBindableProperty
->as<BindablePropertyBoolean>());
m_comparison =
new ConditionComparisonBoolean(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()
->is<TransitionValueBooleanComparator>())
{
auto leftComparand = new ConditionComparandBooleanBindable(
leftBindableProperty->as<BindablePropertyBoolean>());
auto rightComparand = new ConditionComparandBooleanValue(
rightComparator()
->as<TransitionValueBooleanComparator>());
m_comparison =
new ConditionComparisonBoolean(leftComparand,
rightComparand,
operation(op()));
return;
}
break;
}
case BindablePropertyString::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyString>())
{
auto leftComparand =
new ConditionComparandStringBindable(
leftBindableProperty
->as<BindablePropertyString>());
auto rightComparand =
new ConditionComparandStringBindable(
rightBindableProperty
->as<BindablePropertyString>());
m_comparison =
new ConditionComparisonString(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()
->is<TransitionValueStringComparator>())
{
auto leftComparand = new ConditionComparandStringBindable(
leftBindableProperty->as<BindablePropertyString>());
auto rightComparand = new ConditionComparandStringValue(
rightComparator()
->as<TransitionValueStringComparator>());
m_comparison =
new ConditionComparisonString(leftComparand,
rightComparand,
operation(op()));
return;
}
break;
}
case BindablePropertyColor::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyColor>())
{
auto leftComparand =
new ConditionComparandColorBindable(
leftBindableProperty
->as<BindablePropertyColor>());
auto rightComparand =
new ConditionComparandColorBindable(
rightBindableProperty
->as<BindablePropertyColor>());
m_comparison =
new ConditionComparisonColor(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()
->is<TransitionValueColorComparator>())
{
auto leftComparand = new ConditionComparandColorBindable(
leftBindableProperty->as<BindablePropertyColor>());
auto rightComparand = new ConditionComparandColorValue(
rightComparator()
->as<TransitionValueColorComparator>());
m_comparison =
new ConditionComparisonColor(leftComparand,
rightComparand,
operation(op()));
return;
}
break;
}
case BindablePropertyEnum::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyEnum>())
{
auto leftComparand = new ConditionComparandEnumBindable(
leftBindableProperty->as<BindablePropertyEnum>());
auto rightComparand =
new ConditionComparandEnumBindable(
rightBindableProperty
->as<BindablePropertyEnum>());
m_comparison =
new ConditionComparisonEnum(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()->is<TransitionValueEnumComparator>())
{
auto leftComparand = new ConditionComparandEnumBindable(
leftBindableProperty->as<BindablePropertyEnum>());
auto rightComparand = new ConditionComparandEnumValue(
rightComparator()->as<TransitionValueEnumComparator>());
m_comparison = new ConditionComparisonEnum(leftComparand,
rightComparand,
operation(op()));
return;
}
break;
}
case BindablePropertyTrigger::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyTrigger>())
{
auto leftComparand =
new ConditionComparandTriggerBindable(
leftBindableProperty
->as<BindablePropertyTrigger>());
auto rightComparand =
new ConditionComparandTriggerBindable(
rightBindableProperty
->as<BindablePropertyTrigger>());
m_comparison =
new ConditionComparisonUint32(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()
->is<TransitionValueTriggerComparator>())
{
m_comparison =
new ConditionComparisonSelf(leftBindableProperty);
return;
}
break;
}
case BindablePropertyInteger::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyInteger>())
{
auto leftComparand =
new ConditionComparandIntegerBindable(
leftBindableProperty
->as<BindablePropertyInteger>());
auto rightComparand =
new ConditionComparandIntegerBindable(
rightBindableProperty
->as<BindablePropertyInteger>());
m_comparison =
new ConditionComparisonUint32(leftComparand,
rightComparand,
operation(op()));
return;
}
else if (rightBindableProperty
->is<BindablePropertyNumber>())
{
auto leftComparand =
new ConditionComparandNumberBindableInteger(
leftBindableProperty
->as<BindablePropertyInteger>());
auto rightComparand =
new ConditionComparandNumberBindable(
rightBindableProperty
->as<BindablePropertyNumber>());
m_comparison =
new ConditionComparisonNumber(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()
->is<TransitionValueNumberComparator>())
{
auto leftComparand =
new ConditionComparandNumberBindableInteger(
leftBindableProperty
->as<BindablePropertyInteger>());
auto rightComparand = new ConditionComparandNumberValue(
rightComparator()
->as<TransitionValueNumberComparator>());
m_comparison =
new ConditionComparisonNumber(leftComparand,
rightComparand,
operation(op()));
return;
}
break;
}
case BindablePropertyAsset::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyAsset>())
{
auto leftComparand =
new ConditionComparandAssetBindable(
leftBindableProperty
->as<BindablePropertyAsset>());
auto rightComparand =
new ConditionComparandAssetBindable(
rightBindableProperty
->as<BindablePropertyAsset>());
m_comparison =
new ConditionComparisonUint32(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()
->is<TransitionValueAssetComparator>())
{
auto leftComparand = new ConditionComparandAssetBindable(
leftBindableProperty->as<BindablePropertyAsset>());
auto rightComparand = new ConditionComparandAssetValue(
rightComparator()
->as<TransitionValueAssetComparator>());
m_comparison =
new ConditionComparisonUint32(leftComparand,
rightComparand,
operation(op()));
return;
}
break;
}
case BindablePropertyArtboard::typeKey:
{
if (rightComparator()
->is<TransitionPropertyViewModelComparator>())
{
auto rightBindableProperty =
rightComparator()
->as<TransitionPropertyViewModelComparator>()
->bindableProperty();
if (rightBindableProperty->is<BindablePropertyArtboard>())
{
auto leftComparand =
new ConditionComparandArtboardBindable(
leftBindableProperty
->as<BindablePropertyArtboard>());
auto rightComparand =
new ConditionComparandArtboardBindable(
rightBindableProperty
->as<BindablePropertyArtboard>());
m_comparison =
new ConditionComparisonUint32(leftComparand,
rightComparand,
operation(op()));
return;
}
}
else if (rightComparator()
->is<TransitionValueArtboardComparator>())
{
auto leftComparand = new ConditionComparandArtboardBindable(
leftBindableProperty->as<BindablePropertyArtboard>());
auto rightComparand = new ConditionComparandArtboardValue(
rightComparator()
->as<TransitionValueArtboardComparator>());
m_comparison =
new ConditionComparisonUint32(leftComparand,
rightComparand,
operation(op()));
return;
}
break;
}
default:
break;
}
m_comparison = new ConditionComparisonNone();
}
}
bool ConditionComparison::compareNumbers(float left, float right)
{
return m_operation->compareNumbers(left, right);
}
bool ConditionComparison::compareStrings(const std::string& left,
const std::string& right)
{
return m_operation->compareStrings(left, right);
}
bool ConditionComparison::compareBooleans(bool left, bool right)
{
return m_operation->compareBooleans(left, right);
}
bool ConditionComparison::compareColors(int left, int right)
{
return m_operation->compareInts(left, right);
}
bool ConditionComparison::compareUints32(uint32_t left, uint32_t right)
{
return m_operation->compareUints32(left, right);
}