Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,16 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <ExpressionEvaluation/ExpressionEngine/ExpressionTree.h>
#include <ExpressionEvaluation/ExpressionEngine/ExpressionTypes.h>
#include <ExpressionEvaluation/ExpressionEvaluationBus.h>
@@ -0,0 +1,174 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/containers/unordered_map.h>
#include <ExpressionEvaluation/ExpressionEngine/ExpressionTypes.h>
namespace ExpressionEvaluation
{
// Holds all of the tokeniszed information from parsing an expression string.
//
// Provides interfaces to accessing/manipulating variables that may be exposed.
class ExpressionTree
{
// Friend class for reflection
friend class ExpressionEvaluationSystemComponent;
public:
AZ_RTTI(ExpressionTree, "{4CCF3DFD-2EA8-47CB-AF25-353BC034EF42}");
AZ_CLASS_ALLOCATOR(ExpressionTree, AZ::SystemAllocator, 0);
ExpressionTree() = default;
virtual ~ExpressionTree()
{
ClearTree();
}
void ClearTree()
{
m_tokens.clear();
m_variables.clear();
}
void PushElement(ExpressionToken&& expressionToken)
{
m_tokens.emplace_back(AZStd::move(expressionToken));
}
void RegisterVariable(const AZStd::string& displayName)
{
AZ::Crc32 nameHash = AZ::Crc32(displayName);
auto insertResult = m_variables.insert_key(nameHash);
if (insertResult.second)
{
m_orderedVariables.push_back(displayName);
}
}
size_t GetTreeSize() const
{
return m_tokens.size();
}
const AZStd::vector<AZStd::string>& GetVariables() const
{
return m_orderedVariables;
}
const ExpressionVariable& GetVariable(const AZStd::string& name) const
{
return GetVariable(AZ::Crc32(name));
}
const ExpressionVariable& GetVariable(const AZ::Crc32& nameHash) const
{
static AZStd::any k_defaultAny;
auto variableIter = m_variables.find(nameHash);
if (variableIter != m_variables.end())
{
return variableIter->second.m_value;
}
return k_defaultAny;
}
ExpressionVariable& ModVariable(const AZStd::string& name)
{
return ModVariable(AZ::Crc32(name));
}
ExpressionVariable& ModVariable(const AZ::Crc32& nameHash)
{
static AZStd::any k_defaultAny;
auto variableIter = m_variables.find(nameHash);
if (variableIter != m_variables.end())
{
return variableIter->second.m_value;
}
return k_defaultAny;
}
template<typename T>
void SetVariable(const AZStd::string& name, const T& value)
{
AZ::Crc32 nameHash = AZ::Crc32(name);
SetVariable(nameHash, value);
}
template<typename T>
void SetVariable(const AZ::Crc32& nameHash, const T& value)
{
auto variableIter = m_variables.find(nameHash);
if (variableIter != m_variables.end())
{
variableIter->second.m_value = value;
}
}
const AZStd::vector< ExpressionToken >& GetTokens() const
{
return m_tokens;
}
const AZStd::vector<AZ::Uuid>& GetSupportedTypes(const AZStd::string& variableName) const
{
AZ::Crc32 nameHash = AZ::Crc32(variableName);
return GetSupportedTypes(nameHash);
}
const AZStd::vector<AZ::Uuid>& GetSupportedTypes(const AZ::Crc32& nameHash) const
{
static AZStd::vector<AZ::Uuid> k_defaultTypes;
auto variableIter = m_variables.find(nameHash);
if (variableIter != m_variables.end())
{
return variableIter->second.m_supportedTypes;
}
return k_defaultTypes;
}
private:
struct VariableDescriptor
{
AZ_TYPE_INFO(VariableDescriptor, "{5E1A0044-E0E7-46D3-8BC6-A22E226ADB83}");
VariableDescriptor()
{
m_supportedTypes.push_back(azrtti_typeid<double>());
}
AZStd::vector< AZ::Uuid > m_supportedTypes;
ExpressionVariable m_value;
};
AZStd::unordered_map< AZ::Crc32, VariableDescriptor > m_variables;
// Signifies the temporal ordering that we encountered the variables in the parsing. Not a sorted order.
AZStd::vector< AZStd::string > m_orderedVariables;
AZStd::vector< ExpressionToken > m_tokens;
};
}
@@ -0,0 +1,89 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/any.h>
#include <AzCore/std/containers/stack.h>
#include <AzCore/std/containers/unordered_set.h>
#include <AzCore/Math/Crc.h>
namespace ExpressionEvaluation
{
using ExpressionResult = AZStd::any;
using ExpressionParserId = AZ::u32;
using ExpressionVariable = AZStd::any;
// Information that describes how the element should be handled on the stack.
struct ElementInformation
{
AZ_TYPE_INFO(ElementInformation, "{50C64349-5534-453F-8831-D6C125B4FB2C}");
enum class OperatorAssociativity
{
Left,
Right
};
// Manages whether or not this is an operator or a value type.
bool m_allowOnOperatorStack = true;
// The id the parsing inteface has assigned to the operator. Will be passed back in to aid in evaluation.
int m_id = -1;
// The priority of this operator. Used to handle pushing/popping of elements.
int m_priority = 0;
// Siginfies the associativity of the operators.
OperatorAssociativity m_associativity = OperatorAssociativity::Left;
// Any extra chunk of data this Element needs in order to be evaluated.
AZStd::any m_extraStore;
};
// All of the information required to
struct ExpressionToken
{
AZ_TYPE_INFO(ElementInformation, "{7E6DF1F4-97AC-4553-B839-9A3C88DF1C50}");
// The interface id that produced the information
ExpressionParserId m_parserId;
// The information to be executed upon.
ElementInformation m_information;
};
struct ParsingError
{
size_t m_offsetIndex = 0;
AZStd::string m_errorString;
bool IsValidExpression() const
{
return m_offsetIndex == 0 && m_errorString.empty();
}
void Clear()
{
m_offsetIndex = 0;
m_errorString.clear();
}
};
// Class to get the various symbol sets that can be added to the parsing steps.
namespace Interfaces
{
static const ExpressionParserId NumericPrimitives = AZ_CRC("ExpressionEngine::NumericPrimitive", 0x750f46ec);
static const ExpressionParserId BooleanPrimitives = AZ_CRC("ExpressionEngine::BooleanPrimitive", 0xa006d7be);
static const ExpressionParserId MathOperators = AZ_CRC("ExpressionEngine::BasicMath", 0xd0957da8);
}
}
@@ -0,0 +1,85 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/Outcome/Outcome.h>
#include <AzCore/std/string/string_view.h>
#include <ExpressionEvaluation/ExpressionEngine/ExpressionTypes.h>
#include <ExpressionEvaluation/ExpressionEngine/ExpressionTree.h>
namespace ExpressionEvaluation
{
using ParseOutcome = AZ::Outcome<ExpressionTree, ParsingError>;
using ParseInPlaceOutcome = AZ::Outcome<void, ParsingError>;
using EvaluateStringOutcome = AZ::Outcome<ExpressionResult, ParsingError>;
class ExpressionEvaluationRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
//! Parses the expression into the returned ExpressionTree.
//! /param expressionString
//! The string to parse.
//! /return Returns an Expression Tree, or a Parsing Error.
virtual ParseOutcome ParseExpression(AZStd::string_view expressionString) const = 0;
//! Parses the expression into the supplied ExpressionTree.
//! /param expressionString
//! The string to parse.
//! /param expressionTree
//! The ExpressionTree that will contain the parsed tree on Success.
//! /return Returns Success or a Parsing Error.
virtual ParseInPlaceOutcome ParseExpressionInPlace(AZStd::string_view expressionString, ExpressionTree& expressionTree) const = 0;
//! Parses the expression into the returned ExpressionTree using the specified list of parsers.
//! /param availableParsers
//! The list of parsers to use when parsing the expression.
//! /param expressionString
//! The string to parse.
//! /return Returns an Expression Tree, or a Parsing Error.
virtual ParseOutcome ParseRestrictedExpression(const AZStd::unordered_set<ExpressionParserId>& availableParsers, AZStd::string_view expressionString) const = 0;
//! Parses the expression into the supplied ExpressionTree using the specified list of parsers.
//! /param availableParsers
//! The list of parsers to use when parsing the expression.
//! /param expressionString
//! The string to parse.
//! /param expressionTree
//! The ExpressionTree that will contain the parsed tree on Success.
//! /return Returns Success, or a Parsing Error.
virtual ParseInPlaceOutcome ParseRestrictedExpressionInPlace(const AZStd::unordered_set<ExpressionParserId>& availableParsers, AZStd::string_view expressionString, ExpressionTree& expressionTree) const = 0;
//! Parses then Evaluates the specified Expression, and returns the result or parse error.
//! /param expressionString
//! The string to parse/evaluate
//! /return Returns the result of the expression evaluation, or a Parsing Error.
virtual EvaluateStringOutcome EvaluateExpression(AZStd::string_view expression) const = 0;
//! Evalutes the specified ExpressionTree
//! /param expressionTree
//! The ExpressionTree to be evaluated
//! /return Returns the result of the expression evaluation.
virtual ExpressionResult Evaluate(const ExpressionTree& expressionTree) const = 0;
};
using ExpressionEvaluationRequestBus = AZ::EBus<ExpressionEvaluationRequests>;
} // namespace ExpressionEvaluationGem