Compare commits

..
Author SHA1 Message Date
SirKnightly 52200d9668 Automated build commit 2021-01-08 09:49:08 +00:00
m!m 85a2a8f11e Merge pull request #3092 from Goober5000/strtof_patch
interim patch for get_user_vec3d_value
2021-01-08 10:47:42 +01:00
Goober5000 e76fdea8b9 interim patch for get_user_vec3d_value
As described in #3079, the old parsing of fvec and uvec used strtod and some POFs rely on this format.  This is a quickfix that uses the new parsing method for only `get_user_vec3d_value`.
2021-01-07 18:08:27 -05:00
Goober5000 726ce953c7 Merge pull request #3089 from Goober5000/fix_submodel_debris
de-parent live debris
2021-01-07 15:24:49 -05:00
JohnAFernandez a545a4ec27 Merge pull request #3087 from Baezon/lock-restriction-safety
Safety for lock restriction handling
2021-01-07 15:01:31 -05:00
Fabian Woltermann fc0662a9c4 Merge pull request #3080 from JohnAFernandez/Vectorize-Tech-Lists
Vectorize tech lists
2021-01-07 15:16:09 +01:00
JohnAFernandez e5685ded86 Keep the lists from being cleared early by removing unneeded the loops. 2021-01-07 00:33:21 -05:00
JohnAFernandez 226cbf1204 The true fix, check the correct value 2021-01-07 00:32:52 -05:00
Goober5000 043466309a de-parent live debris
It appears that live debris is not supposed to have a parent submodel; see the retail NTF Boadicea.  This removes the parent from any live debris that might have it.

This should fix #3078.
2021-01-07 00:02:49 -05:00
Baezon 766624600d update name 2021-01-06 18:04:59 -05:00
Baezon dab9a41f45 remove redundant check 2021-01-06 17:45:32 -05:00
m!m 51d8ab13d8 Merge pull request #3088 from EatThePath/fix-empty-secondaries-locking
off-by-one fix in early exit update_aspect_lock_information()
2021-01-06 23:25:53 +01:00
Baezon b93d30e12b unused variable 2021-01-06 14:46:44 -05:00
David Gibson 945db25578 corrected off-by-one issue in the early exit condition of update_aspect_lock_information() 2021-01-06 13:46:05 -06:00
Baezon 67de007ecb lock restrictions safety 2021-01-06 14:28:27 -05:00
JohnAFernandez e9a9b3b978 Merge pull request #3085 from Baezon/docking-collision-bugfix
Safety for check_for_docking_collision
2021-01-06 14:03:00 -05:00
Baezon e10522a2c7 safety for check_for_docking_collision 2021-01-06 13:18:27 -05:00
JohnAFernandez 9f33b432fc Simply this check 2021-01-05 00:07:07 -05:00
JohnAFernandez 7a0578a797 Ok CI, I'll use nullptr 2021-01-04 22:14:36 -05:00
JohnAFernandez b81825326c Signed Vs Unsigned
AKA C'Mon CI!
2021-01-03 21:54:31 -05:00
JohnAFernandez b8c2c975c0 Change to a pointer
So that we can release bitmaps and animations properly.
2021-01-03 21:36:50 -05:00
JohnAFernandez dc0272e664 Fixes Part 1 2021-01-03 20:56:30 -05:00
JohnAFernandez 3e329d64dd Check the correct value in the animation code 2021-01-03 15:15:51 -05:00
JohnAFernandez 882ac2b1a1 Possibly Fix Memory Corruption Issue
Remove Unused Var
2021-01-03 15:14:11 -05:00
143 changed files with 5924 additions and 11726 deletions

No files matched your search

-1
View File
@@ -8,7 +8,6 @@ env:
jobs:
build_linux:
strategy:
fail-fast: false
matrix:
configuration: [Debug, Release]
compiler: [gcc-5, gcc-10, clang-9]
+1 -2
View File
@@ -32,5 +32,4 @@ export LD_LIBRARY_PATH
cmake -G Ninja -DFSO_FATAL_WARNINGS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON $CMAKE_OPTIONS \
-DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_BUILD_APPIMAGE=ON -DCMAKE_BUILD_TYPE=$CONFIGURATION \
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=ON \
-DSHADERS_ENABLE_COMPILATION=ON ..
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=ON ..
-2
View File
@@ -63,8 +63,6 @@ ENDIF(FSO_USE_SPEECH)
TARGET_LINK_LIBRARIES(code PUBLIC jansson)
target_link_libraries(code PUBLIC variant)
# Headers for standalone "gui" on UNIX
IF(UNIX)
TARGET_LINK_LIBRARIES(code PUBLIC ${MONGOOSE_LIBS})
-8
View File
@@ -1,8 +0,0 @@
#include "Action.h"
namespace actions {
Action::~Action() = default;
}
-23
View File
@@ -1,23 +0,0 @@
#pragma once
#include "common.h"
namespace actions {
enum class ActionResult
{
Finished,
Errored,
Wait
};
class Action {
public:
virtual ~Action() = 0;
virtual ActionResult execute(ProgramLocals& locals) const = 0;
virtual std::unique_ptr<Action> clone() const = 0;
};
} // namespace actions
-20
View File
@@ -1,20 +0,0 @@
#include "ActionDefinition.h"
namespace actions {
ActionDefinition::ActionDefinition(SCP_string name, SCP_vector<ActionParameter> parameters)
: m_name(std::move(name)), m_parameters(std::move(parameters))
{
}
const SCP_string& ActionDefinition::getName() const
{
return m_name;
}
const SCP_vector<ActionParameter>& ActionDefinition::getParameters() const
{
return m_parameters;
}
} // namespace actions
-32
View File
@@ -1,32 +0,0 @@
#pragma once
#include "Action.h"
#include "actions/expression/ActionExpression.h"
#include "actions/expression/Value.h"
namespace actions {
struct ActionParameter {
SCP_string name;
expression::ValueType type;
};
class ActionDefinition {
public:
ActionDefinition(SCP_string name, SCP_vector<ActionParameter> parameters);
const SCP_string& getName() const;
const SCP_vector<actions::ActionParameter>& getParameters() const;
virtual flagset<ProgramContextFlags> getRequiredContext() const = 0;
virtual std::unique_ptr<Action> createAction(
const SCP_unordered_map<SCP_string, expression::ActionExpression>& parameterExpressions) const = 0;
private:
SCP_string m_name;
SCP_vector<ActionParameter> m_parameters;
};
} // namespace actions
-148
View File
@@ -1,148 +0,0 @@
#include "ActionDefinitionManager.h"
#include "BuiltinActionDefinition.h"
#include "actions/types/MoveToSubmodel.h"
#include "actions/types/ParticleEffectAction.h"
#include "actions/types/PlaySoundAction.h"
#include "actions/types/SetDirectionAction.h"
#include "actions/types/SetPositionAction.h"
#include "actions/types/WaitAction.h"
#include "utils/join_string.h"
namespace actions {
namespace {
void parseActionParameters(const SCP_vector<ActionParameter>& params,
SCP_unordered_map<SCP_string, expression::ActionExpression>& parameterExpressions,
const expression::ParseContext& context)
{
// We do not impose a set order of the parameters so we need to do something similar to the outer loop and
// check for every possibility in a loop.
for (size_t i = 0; i < params.size(); ++i) {
// We might be doing some empty loops here in case of errors but there is a bound so this will finish
// eventually
for (const auto& parameter : params) {
// Do not check for parameters which we already found
if (parameterExpressions.find(parameter.name) != parameterExpressions.end()) {
continue;
}
const auto paramString = "+" + parameter.name + ":";
if (!optional_string(paramString.c_str())) {
continue;
}
// We found our parameter!
parameterExpressions[parameter.name] =
expression::ActionExpression::parseFromTable(parameter.type, context);
break;
}
}
}
} // namespace
const ActionDefinitionManager& ActionDefinitionManager::instance()
{
static const ActionDefinitionManager manager = []() {
ActionDefinitionManager newManager;
newManager.addDefinition(
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::MoveToSubmodel>("Move To Subobject")));
newManager.addDefinition(std::unique_ptr<ActionDefinition>(
new BuiltinActionDefinition<types::ParticleEffectAction>("Start Particle Effect")));
newManager.addDefinition(
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::PlaySoundAction>("Play 3D Sound")));
newManager.addDefinition(
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::SetDirectionAction>("Set Direction")));
newManager.addDefinition(
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::SetPositionAction>("Set Position")));
newManager.addDefinition(
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::WaitAction>("Wait")));
return newManager;
}();
return manager;
}
void ActionDefinitionManager::addDefinition(std::unique_ptr<ActionDefinition> def)
{
m_definitions.push_back(std::move(def));
}
std::unique_ptr<Action> ActionDefinitionManager::parseAction(const flagset<ProgramContextFlags>& context_flags,
const expression::ParseContext& context) const
{
// We search through all definitions for every time we want to check for an action. This is not the most efficient
// way to handle this since it results in an O(n^2) runtime. A better alternative would be to either construct a
// regex with all the accepted actions as alternatives (although runtime of this is also doubtful) or peek at the
// next token, extract the relevant part (The stuff between "+" and ":") and then look that up in a map. Then we
// would get down to O(n).
// Since this only happens at parse time, this is good enough for now.
for (const auto& actionDef : m_definitions) {
const auto parseString = "+" + actionDef->getName() + ":";
if (!optional_string(parseString.c_str())) {
continue;
}
SCP_unordered_map<SCP_string, expression::ActionExpression> parameterExpressions;
const auto& params = actionDef->getParameters();
if (params.size() == 1) {
// Single parameters are expected to be placed directly after the action name
parameterExpressions[params.front().name] =
expression::ActionExpression::parseFromTable(params.front().type, context);
} else {
parseActionParameters(params, parameterExpressions, context);
if (parameterExpressions.size() != params.size()) {
SCP_vector<ActionParameter> missingParameters;
std::copy_if(params.cbegin(),
params.cend(),
std::back_inserter(missingParameters),
[&parameterExpressions](const ActionParameter& param) {
const auto iter = parameterExpressions.find(param.name);
return iter == parameterExpressions.cend();
});
SCP_vector<SCP_string> missingParameterNames;
std::transform(missingParameters.cbegin(),
missingParameters.cend(),
std::back_inserter(missingParameterNames),
[](const ActionParameter& param) { return "+" + param.name; });
const auto namesList = util::join_container(missingParameterNames, ", ");
error_display(0, "Missing parameters for action '%s': %s", parseString.c_str(), namesList.c_str());
// Fix up the parameter list so that we can continue parsing
for (const auto& missingParam : missingParameters) {
parameterExpressions[missingParam.name] = expression::ActionExpression();
}
}
}
auto actionInstance = actionDef->createAction(parameterExpressions);
const auto requiredFlags = actionDef->getRequiredContext();
if ((context_flags & requiredFlags) != requiredFlags) {
// We are missing at least one context flag so this action is not valid here. We still return the action
// here though since that is the only way we can keep parsing the table without throwing random error
// messages at the user. However, this will trigger an Assertion (in debug) or crashes when the action is
// actually run later.
error_display(0,
"The action %s is not available in the current context. This will lead to an Assertion failure when "
"this action is triggered.",
parseString.c_str());
}
return actionInstance;
}
return std::unique_ptr<Action>();
}
} // namespace actions
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include "ActionDefinition.h"
namespace actions {
class ActionDefinitionManager {
public:
// This type is supposed to be global so it may not be copied
ActionDefinitionManager(const ActionDefinitionManager&) = delete;
ActionDefinitionManager& operator=(const ActionDefinitionManager&) = delete;
ActionDefinitionManager(ActionDefinitionManager&&) noexcept = default;
ActionDefinitionManager& operator=(ActionDefinitionManager&&) noexcept = default;
std::unique_ptr<Action> parseAction(const flagset<ProgramContextFlags>& context_flags,
const expression::ParseContext& context) const;
static const ActionDefinitionManager& instance();
private:
ActionDefinitionManager() = default;
void addDefinition(std::unique_ptr<ActionDefinition> def);
SCP_vector<std::unique_ptr<ActionDefinition>> m_definitions;
};
} // namespace actions
-2
View File
@@ -1,2 +0,0 @@
#include "BuiltinActionDefinition.h"
-36
View File
@@ -1,36 +0,0 @@
#pragma once
#include "ActionDefinition.h"
#include "expression/Value.h"
namespace actions {
template <typename TAction>
class BuiltinActionDefinition : public ActionDefinition {
using ActionValueType = typename TAction::ValueType;
public:
BuiltinActionDefinition(SCP_string name)
: ActionDefinition(std::move(name), {{"parameter", expression::ValueTypeTraits<ActionValueType>::type}})
{
}
flagset<ProgramContextFlags> getRequiredContext() const override
{
return flagset<ProgramContextFlags>(TAction::getRequiredExecutionContextFlags());
}
std::unique_ptr<Action> createAction(
const SCP_unordered_map<SCP_string, expression::ActionExpression>& parameterExpressions) const override
{
const auto paramIter = parameterExpressions.find("parameter");
// This should have been caught earlier
Assertion(paramIter != parameterExpressions.cend(), "Could not find built-in parameter!");
return std::unique_ptr<Action>(new TAction(paramIter->second.template asTyped<ActionValueType>()));
}
};
} // namespace actions
-174
View File
@@ -1,174 +0,0 @@
#include "Program.h"
#include "Action.h"
#include "actions/ActionDefinitionManager.h"
#include "executor/global_executors.h"
#include "tracing/Monitor.h"
#include "tracing/categories.h"
#include "tracing/tracing.h"
namespace {
using namespace actions;
tracing::Monitor<int> RunningProgramsMonitor("RunningPrograms", 0);
struct ProgramRunner {
tracing::RunningCounter runningCounter{RunningProgramsMonitor};
ProgramInstance instance;
explicit ProgramRunner(const ProgramInstance& _instance) : instance(_instance) {}
executor::Executor::CallbackResult operator()()
{
TRACE_SCOPE(tracing::ProgramStepOne);
auto res = instance.step();
switch (res) {
case ProgramState::Running:
// If the program is still running then we need to reschedule our execution
return executor::Executor::CallbackResult::Reschedule;
case ProgramState::Done:
case ProgramState::Errored:
default:
return executor::Executor::CallbackResult::Done;
}
}
};
} // namespace
namespace actions {
ProgramInstance::ProgramInstance(const actions::Program* program) : _program(program) {}
ProgramState ProgramInstance::step()
{
if (!_locals.host.IsValid()) {
return ProgramState::Done;
}
auto& actions = _program->getActions();
for (; _currentInstruction < actions.size(); ++_currentInstruction) {
auto& action = actions[_currentInstruction];
auto result = action->execute(_locals);
if (result == ActionResult::Errored) {
return ProgramState::Errored;
}
if (result == ActionResult::Wait) {
// Action is not done yet, call again next frame
return ProgramState::Running;
}
// Action finished, run next action in program
}
// End of program reached, we are done now
return ProgramState::Done;
}
ProgramLocals& ProgramInstance::locals()
{
return _locals;
}
const ProgramLocals& ProgramInstance::locals() const
{
return _locals;
}
const SCP_vector<std::unique_ptr<actions::Action>>& Program::getActions() const
{
return _actions;
}
Program::Program() = default;
ProgramInstance Program::newInstance() const
{
return ProgramInstance(this);
}
void Program::parseActions(const flagset<ProgramContextFlags>& context_flags, const expression::ParseContext& context)
{
while (true) {
auto action = ActionDefinitionManager::instance().parseAction(context_flags, context);
if (!action) {
break;
}
_actions.push_back(std::move(action));
}
}
Program::Program(const Program& other) { *this = other; }
Program& Program::operator=(const Program& other)
{
_actions.clear();
_actions.reserve(other._actions.size());
for (auto& action : other._actions) {
_actions.emplace_back(action->clone());
}
return *this;
}
Program& Program::operator=(Program&&) noexcept = default;
Program::Program(Program&&) noexcept = default;
const SCP_vector<actions::Program>& ProgramSet::getPrograms() const
{
return _programs;
}
ProgramSet::ProgramSet() = default;
ProgramSet::ProgramSet(const flagset<ProgramContextFlags>& context_flags) : _contextFlags(context_flags) {}
void ProgramSet::start(object* objp, const vec3d* local_pos, const matrix* local_orient, int submodel) const
{
if (_contextFlags[ProgramContextFlags::HasObject]) {
Assertion(objp != nullptr, "Invalid object pointer supplied.");
}
if (_contextFlags[ProgramContextFlags::HasSubobject]) {
Assertion(submodel >= 0, "Invalid subobject supplied.");
}
for (const auto& prog : _programs) {
auto instance = prog.newInstance();
instance.locals().host = object_h(objp);
instance.locals().localPosition = *local_pos;
instance.locals().localOrient = *local_orient;
instance.locals().hostSubobject = submodel;
instance.locals().variables = getDefaultTableVariables();
// Just use the executor system to take care of running this program
executor::OnSimulationExecutor->post(ProgramRunner(instance));
}
}
ProgramSet ProgramSet::parseProgramSet(const char* tag, const flagset<ProgramContextFlags>& context_flags)
{
ProgramSet set(context_flags);
const auto parseContext = getTableParseContext();
while (optional_string(tag)) {
Program p;
p.parseActions(context_flags, parseContext);
set._programs.push_back(std::move(p));
}
return set;
}
} // namespace actions
-112
View File
@@ -1,112 +0,0 @@
#pragma once
#include "globalincs/pstypes.h"
#include "Action.h"
#include "common.h"
namespace actions {
class Program;
class ProgramSet;
enum class ProgramState
{
Running,
Done,
Errored
};
/**
* @brief An instance of a program execution
*
* A program instance contains all information related to a single execution of a program. A program instance is
* independent from other instances. Local variables used by actions are stored in a specific structure which can be
* used by actions to keep track of state in this specific instance.
*/
class ProgramInstance {
size_t _currentInstruction = 0;
ProgramLocals _locals;
const Program* _program = nullptr;
public:
explicit ProgramInstance(const Program* program);
ProgramState step();
ProgramLocals& locals();
const ProgramLocals& locals() const;
};
/**
* @brief A program specified in a table
*
* A program is a sequential collection of Actions which are executed in sequence.
*/
class Program {
SCP_vector<std::unique_ptr<Action>> _actions;
public:
Program();
Program(const Program& other);
Program& operator=(const Program& other);
Program(Program&& other) noexcept;
Program& operator=(Program&& other) noexcept;
const SCP_vector<std::unique_ptr<actions::Action>>& getActions() const;
/**
* @brief Creates a new program instance from this program
*
* The program instance is initialized to its initial values.
*
* @return The new program instance
*/
ProgramInstance newInstance() const;
void parseActions(const flagset<ProgramContextFlags>& context_flags, const expression::ParseContext& context);
};
/**
* @brief A set of parsed programs
*
* Programs are parsed in sets of zero or more programs to make it possible for the content creator to split up
* programs.
*/
class ProgramSet {
flagset<ProgramContextFlags> _contextFlags;
SCP_vector<Program> _programs;
public:
ProgramSet();
explicit ProgramSet(const flagset<ProgramContextFlags>& context_flags);
const SCP_vector<actions::Program>& getPrograms() const;
/**
* @brief Starts the execution of all programs within this set with the specified parameters
* @param objp The object on which this program is executed
* @param local_pos The local position relative to the object or the subsystem if specified
* @param local_orien The local orientation relative to the object or the subsystem if specified
* @param submodel The submodel of the model to which this program is attached to.
*/
void start(object* objp, const vec3d* local_pos, const matrix* local_orient, int submodel = -1) const;
/**
* @brief Parses a program set of zero or more programs
*
* The tag is entirely optional and if it doesn't appear in the current table then an empty set will be returned
* which does nothing if started.
*
* @param tag The tag which is required before a program can be specified
* @param context_flags A set of flags which specify in which environment the program will be used. This is used
* mainly for validating the used actions.
* @return The parsed program set.
*/
static ProgramSet parseProgramSet(const char* tag, const flagset<ProgramContextFlags>& context_flags = {});
};
} // namespace actions
-27
View File
@@ -1,27 +0,0 @@
#include "common.h"
namespace actions {
expression::ParseContext getTableParseContext()
{
expression::ParseContext ctx;
auto& locals = ctx.variables.addScope("locals");
locals.addMember("position", expression::ValueType::Vector);
locals.addMember("direction", expression::ValueType::Vector);
return ctx;
}
expression::ProgramVariables getDefaultTableVariables()
{
expression::ProgramVariables vars;
vars.setValue({"locals", "position"}, expression::Value(vmd_zero_vector));
vars.setValue({"locals", "direction"}, expression::Value(vmd_zero_vector));
return vars;
}
} // namespace actions
-59
View File
@@ -1,59 +0,0 @@
#pragma once
#include "globalincs/flagset.h"
#include "actions/expression/ParseContext.h"
#include "actions/expression/ProgramVariables.h"
#include "math/vecmat.h"
#include "object/object.h"
class object;
class ship_subsys;
namespace actions {
struct ProgramLocals {
object_h host;
vec3d localPosition = vmd_zero_vector;
matrix localOrient = vmd_identity_matrix;
int hostSubobject = -1;
int waitTimestamp = 0;
expression::ProgramVariables variables;
};
/**
* @brief A list of flags for altering the program parsing behavior
*
* This should be used for differentiating between different program environments when validating the program (e.g. a
* particle effect requires an object host).
*/
// clang-format off
FLAG_LIST(ProgramContextFlags) {
HasObject = 0, //!< The program will be started with an object host
HasSubobject, //!< The program will be started with a subobject host
NUM_VALUES
};
// clang-format on
/**
* @brief Constructs the "table" parse context
*
* This is the context that is available when parsing a program from an external table (e.g. ships or weapons).
*
* @return The parse context
*/
expression::ParseContext getTableParseContext();
/**
* @brief Gets a program variables instance initialized with the default values
*
* The values are consistent with what is required for the default table parse context;
*
* @return The program variables
*/
expression::ProgramVariables getDefaultTableVariables();
} // namespace actions
@@ -1,66 +0,0 @@
#include "ActionExpression.h"
#include "ExpressionParser.h"
#include "TypeDefinition.h"
#include "actions/expression/nodes/AbstractExpression.h"
namespace actions {
namespace expression {
namespace {
SCP_string getTypeName(ValueType type)
{
const auto& typeDef = TypeDefinition::forValueType(type);
return typeDef.getName();
}
} // namespace
ActionExpression ActionExpression::parseFromTable(ValueType expectedReturnType, const ParseContext& context)
{
SCP_string expressionText;
stuff_string(expressionText, F_NAME);
ExpressionParser parser(expressionText);
auto expression = parser.parse(context);
if (!expression) {
error_display(0, "Failed to parse action expression:\n%s", parser.getErrorText().c_str());
return ActionExpression();
}
auto type = expression->getExpressionType();
// Check if the type this evaluates to matches what we expect
if (!checkTypeWithImplicitConversion(type, expectedReturnType)) {
error_display(0,
"Expression evaluates to type <%s> but <%s> was expected!",
getTypeName(type).c_str(),
getTypeName(expectedReturnType).c_str());
return ActionExpression();
}
// Everything is valid
return ActionExpression(expression);
}
Value ActionExpression::execute(const ProgramVariables& variables) const
{
// Do not crash on invalid expressions
if (!isValid()) {
return Value();
}
return m_expression->execute(variables);
}
bool ActionExpression::isValid() const
{
return m_expression != nullptr;
}
} // namespace expression
} // namespace actions
@@ -1,70 +0,0 @@
#pragma once
#include "ParseContext.h"
#include "ProgramVariables.h"
#include "TypeDefinition.h"
#include "parse/parselo.h"
namespace actions {
namespace expression {
namespace nodes {
class AbstractExpression;
}
template <typename T>
class TypedActionExpression;
class ActionExpression {
public:
ActionExpression() = default;
Value execute(const ProgramVariables& variables) const;
bool isValid() const;
template <typename T>
TypedActionExpression<T> asTyped() const;
static ActionExpression parseFromTable(ValueType expectedReturnType, const ParseContext& context);
protected:
explicit ActionExpression(std::shared_ptr<nodes::AbstractExpression> expression)
: m_expression(std::move(expression))
{
}
std::shared_ptr<nodes::AbstractExpression> m_expression;
};
template <typename T>
class TypedActionExpression {
public:
explicit TypedActionExpression(ActionExpression expression) : m_expression(std::move(expression)) {}
T execute(const ProgramVariables& variables) const
{
// Do not crash on invalid expressions
if (!m_expression.isValid()) {
return T();
}
return m_expression.execute(variables).template get<T>();
}
static TypedActionExpression<T> parseFromTable(const ParseContext& context)
{
return ActionExpression::parseFromTable(ValueTypeTraits<T>::type, context).template asTyped<T>();
}
private:
ActionExpression m_expression;
};
template <typename T>
TypedActionExpression<T> ActionExpression::asTyped() const
{
return TypedActionExpression<T>(*this);
}
} // namespace expression
} // namespace actions
@@ -1,194 +0,0 @@
#include "ExpressionParser.h"
#include "actions/expression/nodes/FunctionCallExpression.h"
#include "actions/expression/nodes/LiteralExpression.h"
#include "actions/expression/nodes/RandomRangeExpression.h"
#include "actions/expression/nodes/VariableReferenceExpression.h"
#include "actions/expression/nodes/VectorConstructorExpression.h"
#include "libs/antlr/ErrorListener.h"
PUSH_SUPPRESS_WARNINGS
#include "action_expression/generated/ActionExpressionLexer.h"
#include "action_expression/generated/ActionExpressionParser.h"
#include "action_expression/generated/ActionExpressionVisitor.h"
POP_SUPPRESS_WARNINGS
namespace actions {
namespace expression {
namespace {
class ExpressionBuilderVisitor : public ActionExpressionVisitor {
public:
antlrcpp::Any visitExpression_main(ActionExpressionParser::Expression_mainContext* context) override
{
return visit(context->expression());
}
antlrcpp::Any visitExpression(ActionExpressionParser::ExpressionContext* context) override
{
if (context->value_expression() != nullptr) {
return visit(context->value_expression());
}
if (context->parenthesis_expression()) {
return visit(context->parenthesis_expression());
}
if (context->random_range_expression()) {
return visit(context->random_range_expression());
}
if (context->variable_reference_expression()) {
return visit(context->variable_reference_expression());
}
// This is an operator so treat it as one.
antlr4::Token* operatorTok;
SCP_string operatorText;
if (context->PLUS() != nullptr) {
operatorTok = context->PLUS()->getSymbol();
operatorText = context->PLUS()->getText();
} else {
operatorTok = context->MINUS()->getSymbol();
operatorText = context->MINUS()->getText();
}
const auto leftExpr = visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>();
const auto rightExpr = visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>();
auto operatorExpression = std::make_shared<nodes::FunctionCallExpression>(operatorTok,
true,
std::move(operatorText),
SCP_vector<std::shared_ptr<nodes::AbstractExpression>>{leftExpr, rightExpr});
return std::static_pointer_cast<nodes::AbstractExpression>(operatorExpression);
}
antlrcpp::Any visitVariable_reference_expression(
ActionExpressionParser::Variable_reference_expressionContext* context) override
{
const auto identifiers = context->IDENTIFIER();
SCP_vector<SCP_string> partNames;
partNames.reserve(identifiers.size());
std::transform(identifiers.begin(),
identifiers.end(),
std::back_inserter(partNames),
[](antlr4::tree::TerminalNode* node) { return node->getText(); });
SCP_vector<antlr4::Token*> partTokens;
partTokens.reserve(identifiers.size());
std::transform(identifiers.begin(),
identifiers.end(),
std::back_inserter(partTokens),
[](antlr4::tree::TerminalNode* node) { return node->getSymbol(); });
auto expression =
std::make_shared<nodes::VariableReferenceExpression>(std::move(partNames), std::move(partTokens));
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
}
antlrcpp::Any visitRandom_range_expression(ActionExpressionParser::Random_range_expressionContext* context) override
{
auto expression = std::make_shared<nodes::RandomRangeExpression>(context->RAND_L_PAREN()->getSymbol(),
visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>(),
visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>());
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
}
antlrcpp::Any visitLiteral_expression(ActionExpressionParser::Literal_expressionContext* context) override
{
std::shared_ptr<nodes::LiteralExpression> expression;
if (context->FLOAT() != nullptr) {
expression = std::make_shared<nodes::LiteralExpression>(context->FLOAT()->getSymbol(),
Value(std::stof(context->FLOAT()->getText())));
} else if (context->INT() != nullptr) {
expression = std::make_shared<nodes::LiteralExpression>(context->INT()->getSymbol(),
Value(std::stoi(context->INT()->getText())));
} else {
const auto idText = context->STRING()->getText();
// Cut off the first and last characters since those are the < > braces
expression = std::make_shared<nodes::LiteralExpression>(context->STRING()->getSymbol(),
Value(idText.substr(1, idText.size() - 2)));
}
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
}
antlrcpp::Any visitParenthesis_expression(ActionExpressionParser::Parenthesis_expressionContext* context) override
{
return visit(context->expression());
}
antlrcpp::Any visitValue_expression(ActionExpressionParser::Value_expressionContext* context) override
{
return visitChildren(context);
}
antlrcpp::Any visitVec3d_constructor(ActionExpressionParser::Vec3d_constructorContext* context) override
{
auto xExpression = visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>();
auto yExpression = visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>();
auto zExpression = visit(context->expression(2)).as<std::shared_ptr<nodes::AbstractExpression>>();
auto expression = std::make_shared<nodes::VectorConstructorExpression>(context->L_PAREN()->getSymbol(),
xExpression,
yExpression,
zExpression);
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
}
};
} // namespace
ExpressionParser::ExpressionParser(SCP_string expressionText) : m_expressionText(std::move(expressionText)) {}
std::shared_ptr<nodes::AbstractExpression> ExpressionParser::parse(const ParseContext& context)
{
antlr4::ANTLRInputStream input(m_expressionText);
ActionExpressionLexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
::ActionExpressionParser parser(&tokens);
// By default we log to stderr which we do not want
parser.removeErrorListeners();
libs::antlr::ErrorListener errListener;
parser.addErrorListener(&errListener);
antlr4::tree::ParseTree* tree = parser.expression_main();
std::shared_ptr<nodes::AbstractExpression> exprReturn;
if (errListener.diagnostics.empty()) {
// Only do semantic checking if syntax is valid
ExpressionBuilderVisitor builder;
exprReturn = tree->accept(&builder).as<std::shared_ptr<nodes::AbstractExpression>>();
if (!exprReturn->validate(&parser, context)) {
exprReturn = nullptr;
} else {
exprReturn->validationDone();
}
}
if (!errListener.diagnostics.empty()) {
SCP_stringstream outStream;
for (const auto& diag : errListener.diagnostics) {
SCP_string tokenUnderline;
if (diag.tokenLength > 1) {
tokenUnderline = SCP_string(diag.tokenLength - 1, '~');
}
outStream << m_expressionText << "\n"
<< SCP_string(diag.columnInLine, ' ') << "^" << tokenUnderline << "\n"
<< diag.errorMessage << "\n";
}
m_errorText = outStream.str();
return nullptr;
}
return exprReturn;
}
const SCP_string& ExpressionParser::getErrorText() const
{
return m_errorText;
}
} // namespace expression
} // namespace actions
@@ -1,27 +0,0 @@
#pragma once
#include "globalincs/pstypes.h"
#include "ParseContext.h"
#include "actions/expression/nodes/AbstractExpression.h"
namespace actions {
namespace expression {
class ExpressionParser {
public:
ExpressionParser(SCP_string expressionText);
std::shared_ptr<nodes::AbstractExpression> parse(const ParseContext& context);
const SCP_string& getErrorText() const;
private:
SCP_string m_expressionText;
SCP_string m_errorText;
};
} // namespace expression
} // namespace actions
@@ -1,93 +0,0 @@
#include "FunctionManager.h"
#include "TypeDefinition.h"
#include "math/vecmat.h"
namespace actions {
namespace expression {
namespace {
template <typename T>
Value value_plus(const SCP_vector<Value>& parameters)
{
return Value(parameters[0].get<T>() + parameters[1].get<T>());
}
template <typename T>
Value value_minus(const SCP_vector<Value>& parameters)
{
return Value(parameters[0].get<T>() - parameters[1].get<T>());
}
} // namespace
const FunctionManager& FunctionManager::instance()
{
static const FunctionManager manager = []() {
FunctionManager newManager;
newManager.addOperator("+", {ValueType::Integer, ValueType::Integer}, ValueType::Integer, value_plus<int>);
newManager.addOperator("+", {ValueType::Float, ValueType::Float}, ValueType::Float, value_plus<float>);
newManager.addOperator("+", {ValueType::Vector, ValueType::Vector}, ValueType::Vector, value_plus<vec3d>);
newManager.addOperator("-", {ValueType::Integer, ValueType::Integer}, ValueType::Integer, value_minus<int>);
newManager.addOperator("-", {ValueType::Float, ValueType::Float}, ValueType::Float, value_minus<float>);
newManager.addOperator("-", {ValueType::Vector, ValueType::Vector}, ValueType::Vector, value_minus<vec3d>);
return newManager;
}();
return manager;
}
void FunctionManager::addOperator(const SCP_string& name,
std::initializer_list<ValueType> parameterTypes,
ValueType returnType,
FunctionImplementation implementation)
{
m_operators[name].push_back({name, parameterTypes, returnType, std::move(implementation)});
}
const FunctionDefinition* FunctionManager::findOperator(const SCP_string& name,
const SCP_vector<ValueType>& parameters) const
{
const auto iter = m_operators.find(name);
if (iter == m_operators.end()) {
return nullptr;
}
// Prefer exact matches
for (const auto& funcDef : iter->second) {
if (funcDef.parameterTypes == parameters) {
return &funcDef;
}
}
// Now check if there are matches with implicit conversions
for (const auto& funcDef : iter->second) {
// Reject functions with different amount of elements
if (funcDef.parameterTypes.size() != parameters.size()) {
continue;
}
auto funcParamIter = funcDef.parameterTypes.cbegin();
auto actualParamIter = parameters.cbegin();
bool match = true;
for (; funcParamIter != funcDef.parameterTypes.cend(); ++funcParamIter, ++actualParamIter) {
if (!checkTypeWithImplicitConversion(*actualParamIter, *funcParamIter)) {
// Also doesn't match with implicit conversions
match = false;
break;
}
}
if (match) {
return &funcDef;
}
}
return nullptr;
}
FunctionManager::FunctionManager() = default;
} // namespace expression
} // namespace actions
-45
View File
@@ -1,45 +0,0 @@
#pragma once
#include "Value.h"
namespace actions {
namespace expression {
using FunctionImplementation = std::function<Value(const SCP_vector<Value>& parameters)>;
struct FunctionDefinition {
SCP_string name;
SCP_vector<ValueType> parameterTypes;
ValueType returnType;
FunctionImplementation implementation;
};
class FunctionManager {
public:
// This type is supposed to be global so it may not be copied
FunctionManager(const FunctionManager&) = delete;
FunctionManager& operator=(const FunctionManager&) = delete;
FunctionManager(FunctionManager&&) noexcept = default;
FunctionManager& operator=(FunctionManager&&) noexcept = default;
void addOperator(const SCP_string& name,
std::initializer_list<ValueType> parameterTypes,
ValueType returnType,
FunctionImplementation implementation);
const FunctionDefinition* findOperator(const SCP_string& name, const SCP_vector<ValueType>& parameterTypes) const;
static const FunctionManager& instance();
private:
FunctionManager();
SCP_unordered_map<SCP_string, SCP_vector<FunctionDefinition>> m_operators;
};
} // namespace expression
} // namespace actions
-13
View File
@@ -1,13 +0,0 @@
#pragma once
#include "ProgramVariables.h"
namespace actions {
namespace expression {
struct ParseContext {
ProgramVariablesDefinition variables;
};
} // namespace expression
} // namespace actions
@@ -1,61 +0,0 @@
#include "ProgramVariables.h"
namespace actions {
namespace expression {
ProgramVariablesDefinition& ProgramVariablesDefinition::addScope(const SCP_string& name)
{
auto scope = std::unique_ptr<ProgramVariablesDefinition>(new ProgramVariablesDefinition());
auto scopePtr = scope.get();
m_scopes.insert(std::make_pair(name, std::move(scope)));
return *scopePtr;
}
void ProgramVariablesDefinition::addMember(const SCP_string& name, ValueType type)
{
m_memberTypes[name] = type;
}
ProgramVariablesDefinition* ProgramVariablesDefinition::getScope(const SCP_string& name) const
{
const auto iter = m_scopes.find(name);
if (iter == m_scopes.cend()) {
return nullptr;
}
return iter->second.get();
}
ValueType ProgramVariablesDefinition::getMemberType(const SCP_string& name) const
{
const auto iter = m_memberTypes.find(name);
if (iter == m_memberTypes.cend()) {
return ValueType::Invalid;
}
return iter->second;
}
Value ProgramVariables::getValue(std::initializer_list<const char*> memberPathParts) const
{
return getValue<decltype(memberPathParts)>(memberPathParts);
}
void ProgramVariables::setValue(std::initializer_list<const char*> memberPathParts, Value value)
{
setValue<decltype(memberPathParts)>(memberPathParts, std::move(value));
}
Value ProgramVariables::getValue(const SCP_string& fullMemberName) const
{
const auto iter = m_values.find(fullMemberName);
// This should have been validated earlier
Assertion(iter != m_values.end(), "Could not find member %s in variables!", fullMemberName.c_str());
return iter->second;
}
} // namespace expression
} // namespace actions
@@ -1,61 +0,0 @@
#pragma once
#include "Value.h"
#include "utils/join_string.h"
namespace actions {
namespace expression {
struct ProgramVariables {
public:
template <typename TContainer>
static SCP_string getMemberName(const TContainer& memberPathParts)
{
return util::join_container(memberPathParts, ".");
}
template <typename TContainer>
Value getValue(const TContainer& memberPathParts) const
{
const auto name = getMemberName(memberPathParts);
return getValue(name);
}
Value getValue(std::initializer_list<const char*> memberPathParts) const;
Value getValue(const SCP_string& fullMemberName) const;
template <typename TContainer>
void setValue(const TContainer& memberPathParts, Value value)
{
const auto name = getMemberName(memberPathParts);
m_values[name] = std::move(value);
}
void setValue(std::initializer_list<const char*> memberPathParts, Value value);
private:
SCP_unordered_map<SCP_string, Value> m_values;
};
class ProgramVariablesDefinition {
public:
ProgramVariablesDefinition& addScope(const SCP_string& name);
void addMember(const SCP_string& name, ValueType type);
ProgramVariablesDefinition* getScope(const SCP_string& name) const;
ValueType getMemberType(const SCP_string& name) const;
private:
SCP_unordered_map<SCP_string, std::unique_ptr<ProgramVariablesDefinition>> m_scopes;
SCP_unordered_map<SCP_string, ValueType> m_memberTypes;
};
} // namespace expression
} // namespace actions
@@ -1,60 +0,0 @@
#include "TypeDefinition.h"
namespace actions {
namespace expression {
// Integers can be safely converted to floats (for the most part)
TypeDefinition TypeDefinition::s_integer("Integer", {ValueType::Float});
// No implicit conversions here
TypeDefinition TypeDefinition::s_float("Float", {});
TypeDefinition TypeDefinition::s_vector("Vector", {});
// Identifiers are a technicality needed for making non-math values work but they have no further use other than their
// string content
TypeDefinition TypeDefinition::s_identifier("Identifier", {});
TypeDefinition::TypeDefinition(SCP_string name, SCP_vector<actions::expression::ValueType> allowedImplicitConversion)
: m_name(std::move(name)), m_allowedImplicitConversions(std::move(allowedImplicitConversion))
{
}
const SCP_string& TypeDefinition::getName() const
{
return m_name;
}
const SCP_vector<actions::expression::ValueType>& TypeDefinition::getAllowedImplicitConversions() const
{
return m_allowedImplicitConversions;
}
const TypeDefinition& TypeDefinition::forValueType(ValueType type)
{
switch (type) {
case ValueType::Integer:
return s_integer;
case ValueType::Float:
return s_float;
case ValueType::Vector:
return s_vector;
case ValueType::String:
return s_identifier;
default:
UNREACHABLE("Invalid value type!");
return s_integer; // Make compiler happy
}
}
bool checkTypeWithImplicitConversion(ValueType currentType, ValueType expectedType)
{
if (currentType == expectedType) {
// No need to consider implicit conversions;
return true;
}
const auto& currentTypeDef = TypeDefinition::forValueType(currentType);
const auto& allowedConversions = currentTypeDef.getAllowedImplicitConversions();
// For now, no transitiv conversions are allowed
return std::find(allowedConversions.cbegin(), allowedConversions.cend(), expectedType) != allowedConversions.cend();
}
} // namespace expression
} // namespace actions
-40
View File
@@ -1,40 +0,0 @@
#pragma once
#include "Value.h"
namespace actions {
namespace expression {
class TypeDefinition {
public:
TypeDefinition(SCP_string name, SCP_vector<actions::expression::ValueType> allowedImplicitConversion);
const SCP_string& getName() const;
const SCP_vector<actions::expression::ValueType>& getAllowedImplicitConversions() const;
static const TypeDefinition& forValueType(ValueType type);
// This type is supposed to be global so it may not be copied
TypeDefinition(const TypeDefinition&) = delete;
TypeDefinition& operator=(const TypeDefinition&) = delete;
TypeDefinition(TypeDefinition&&) = delete;
TypeDefinition& operator=(TypeDefinition&&) = delete;
private:
SCP_string m_name;
// The types this type is allowed to implicitly convert to
SCP_vector<ValueType> m_allowedImplicitConversions;
static TypeDefinition s_integer;
static TypeDefinition s_float;
static TypeDefinition s_vector;
static TypeDefinition s_identifier;
};
bool checkTypeWithImplicitConversion(ValueType currentType, ValueType expectedType);
} // namespace expression
} // namespace actions
-80
View File
@@ -1,80 +0,0 @@
#include "Value.h"
#include "math/vecmat.h"
namespace actions {
namespace expression {
Value::Value(int val) : m_value(val) {}
Value::Value(float val) : m_value(val) {}
Value::Value(const vec3d& val) : m_value(val) {}
Value::Value(SCP_string val) : m_value(std::move(val)) {}
ValueType actions::expression::Value::getType() const
{
switch (m_value.index()) {
case 1:
return ValueType::Integer;
case 2:
return ValueType::Float;
case 3:
return ValueType::Vector;
case 4:
return ValueType::String;
default:
return ValueType::Invalid;
}
}
int Value::getInteger() const
{
return get<int>();
}
float Value::getFloat() const
{
return get<float>();
}
vec3d Value::getVector() const
{
return get<vec3d>();
}
SCP_string Value::getIdentifier() const
{
return get<SCP_string>();
}
bool operator==(const Value& lhs, const Value& rhs)
{
return lhs.m_value == rhs.m_value;
}
bool operator!=(const Value& lhs, const Value& rhs)
{
return !(rhs == lhs);
}
std::ostream& operator<<(std::ostream& os, const Value& value)
{
os << "Value<";
switch (value.getType()) {
case ValueType::Invalid:
os << "INVALID";
break;
case ValueType::Integer:
os << value.get<int>();
break;
case ValueType::Float:
os << value.get<float>();
break;
case ValueType::Vector:
os << value.get<vec3d>();
break;
case ValueType::String:
os << value.get<SCP_string>();
break;
}
os << ">";
return os;
}
} // namespace expression
} // namespace actions
-104
View File
@@ -1,104 +0,0 @@
#pragma once
#include "globalincs/pstypes.h"
#include <mpark/variant.hpp>
namespace actions {
namespace expression {
namespace detail {
template <typename ToType>
struct implicit_conversion {
template <typename T>
ToType operator()(const T&)
{
throw std::runtime_error("Invalid implicit conversion.");
}
};
template<>
struct implicit_conversion<float> {
inline float operator()(int val) {
return i2fl(val);
}
template <typename T>
float operator()(const T&)
{
throw std::runtime_error("Invalid implicit conversion.");
}
};
} // namespace detail
enum class ValueType
{
Invalid,
Integer,
Float,
Vector,
String,
};
template <typename T>
struct ValueTypeTraits;
template <>
struct ValueTypeTraits<int> {
static constexpr ValueType type = ValueType::Integer;
};
template <>
struct ValueTypeTraits<float> {
static constexpr ValueType type = ValueType::Float;
};
template <>
struct ValueTypeTraits<vec3d> {
static constexpr ValueType type = ValueType::Vector;
};
template <>
struct ValueTypeTraits<SCP_string> {
static constexpr ValueType type = ValueType::String;
};
class Value {
public:
Value() = default;
explicit Value(int val);
explicit Value(float val);
explicit Value(const vec3d& val);
explicit Value(SCP_string val);
ValueType getType() const;
int getInteger() const;
float getFloat() const;
vec3d getVector() const;
SCP_string getIdentifier() const;
template <typename T>
T get() const
{
const auto currentType = getType();
const auto expectedType = ValueTypeTraits<T>::type;
if (currentType == expectedType) {
// No conversion necessary
return mpark::get<T>(m_value);
}
return mpark::visit(detail::implicit_conversion<T>{}, m_value);
}
friend bool operator==(const Value& lhs, const Value& rhs);
friend bool operator!=(const Value& lhs, const Value& rhs);
friend std::ostream& operator<<(std::ostream& os, const Value& value);
private:
mpark::variant<mpark::monostate, int, float, vec3d, SCP_string> m_value;
};
} // namespace expression
} // namespace actions
@@ -1,31 +0,0 @@
#include "AbstractExpression.h"
namespace actions {
namespace expression {
namespace nodes {
AbstractExpression::AbstractExpression(antlr4::Token* token) : m_token(token) {}
AbstractExpression::~AbstractExpression() = default;
antlr4::Token* AbstractExpression::getToken() const
{
return m_token;
}
ValueType AbstractExpression::getExpressionType() const
{
// Since expressions are immutable, caching this will be more efficient
if (m_cachedType == ValueType::Invalid) {
m_cachedType = determineReturnType();
}
return m_cachedType;
}
void AbstractExpression::validationDone()
{
// This pointer will become invalid after this so reset it now to avoid issues
m_token = nullptr;
}
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,38 +0,0 @@
#pragma once
#include "actions/expression/ParseContext.h"
#include "actions/expression/Value.h"
#include <Parser.h>
#include <Token.h>
namespace actions {
namespace expression {
namespace nodes {
class AbstractExpression {
public:
AbstractExpression(antlr4::Token* token);
virtual ~AbstractExpression();
virtual Value execute(const ProgramVariables& variables) const = 0;
virtual bool validate(antlr4::Parser* parser, const ParseContext& context) = 0;
virtual void validationDone();
ValueType getExpressionType() const;
antlr4::Token* getToken() const;
protected:
virtual ValueType determineReturnType() const = 0;
antlr4::Token* m_token = nullptr;
mutable ValueType m_cachedType = ValueType::Invalid;
};
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,95 +0,0 @@
#include "FunctionCallExpression.h"
#include "actions/expression/TypeDefinition.h"
namespace actions {
namespace expression {
namespace nodes {
FunctionCallExpression::FunctionCallExpression(antlr4::Token* token,
bool isOperator,
SCP_string functionName,
SCP_vector<std::shared_ptr<AbstractExpression>> parameterExpressions)
: AbstractExpression(token), m_isOperator(isOperator), m_functionName(std::move(functionName)),
m_parameterExpressions(std::move(parameterExpressions))
{
}
FunctionCallExpression::~FunctionCallExpression() = default;
Value FunctionCallExpression::execute(const ProgramVariables& variables) const
{
SCP_vector<Value> parameterValues;
parameterValues.reserve(m_parameterExpressions.size());
std::transform(m_parameterExpressions.cbegin(),
m_parameterExpressions.cend(),
std::back_inserter(parameterValues),
[&variables](const std::shared_ptr<AbstractExpression>& expression) { return expression->execute(variables); });
return m_functionDef->implementation(parameterValues);
}
bool FunctionCallExpression::validate(antlr4::Parser* parser, const ParseContext& context)
{
bool valid = true;
for (const auto& paramExpression : m_parameterExpressions) {
valid &= paramExpression->validate(parser, context);
}
if (!valid) {
// Exit early if there were errors since the values below are meaningless otherwise
return false;
}
Assertion(m_isOperator, "Non-operator functions are not supported yet!");
SCP_vector<ValueType> parameterTypes;
std::transform(m_parameterExpressions.cbegin(),
m_parameterExpressions.cend(),
std::back_inserter(parameterTypes),
[](const std::shared_ptr<AbstractExpression>& expression) { return expression->getExpressionType(); });
const auto functionDef = FunctionManager::instance().findOperator(m_functionName, parameterTypes);
if (functionDef == nullptr) {
SCP_stringstream paramListStream;
if (!parameterTypes.empty()) {
paramListStream << "<" << TypeDefinition::forValueType(parameterTypes.front()).getName() << ">";
for (auto iter = parameterTypes.cbegin() + 1; iter != parameterTypes.cend(); ++iter) {
paramListStream << ", <" << TypeDefinition::forValueType(*iter).getName() << ">";
}
}
parser->notifyErrorListeners(m_token,
SCP_string("Could not find a definition for the ") + (m_isOperator ? "operator" : "function") + " '" +
m_functionName + "' with parameters (" + paramListStream.str() + ")",
nullptr);
return false;
}
m_functionDef = functionDef;
return true;
}
ValueType FunctionCallExpression::determineReturnType() const
{
return m_functionDef->returnType;
}
void FunctionCallExpression::validationDone()
{
AbstractExpression::validationDone();
// We no longer need this so we can save some memory
m_functionName.clear();
m_functionName.shrink_to_fit();
for (const auto& paramExpression : m_parameterExpressions) {
paramExpression->validationDone();
}
}
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,38 +0,0 @@
#pragma once
#include "AbstractExpression.h"
#include "actions/expression/FunctionManager.h"
#include "actions/expression/Value.h"
namespace actions {
namespace expression {
namespace nodes {
class FunctionCallExpression : public AbstractExpression {
public:
FunctionCallExpression(antlr4::Token* token,
bool isOperator,
SCP_string functionName,
SCP_vector<std::shared_ptr<AbstractExpression>> parameterExpressions);
~FunctionCallExpression() override;
Value execute(const ProgramVariables& variables) const override;
bool validate(antlr4::Parser* parser, const ParseContext& context) override;
void validationDone() override;
protected:
ValueType determineReturnType() const override;
private:
bool m_isOperator;
SCP_string m_functionName;
const FunctionDefinition* m_functionDef = nullptr;
SCP_vector<std::shared_ptr<AbstractExpression>> m_parameterExpressions;
};
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,30 +0,0 @@
#include "LiteralExpression.h"
namespace actions {
namespace expression {
namespace nodes {
LiteralExpression::LiteralExpression(antlr4::Token* token, Value literalValue)
: AbstractExpression(token), m_literalValue(std::move(literalValue))
{
}
LiteralExpression::~LiteralExpression() = default;
Value LiteralExpression::execute(const ProgramVariables& /*variables*/) const
{
return m_literalValue;
}
bool LiteralExpression::validate(antlr4::Parser* /*parser*/, const ParseContext& /*context*/)
{
// Literals are always valid
return true;
}
ValueType LiteralExpression::determineReturnType() const
{
return m_literalValue.getType();
}
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,28 +0,0 @@
#pragma once
#include "AbstractExpression.h"
#include "actions/expression/Value.h"
namespace actions {
namespace expression {
namespace nodes {
class LiteralExpression : public AbstractExpression {
public:
LiteralExpression(antlr4::Token* token, Value literalValue);
~LiteralExpression() override;
Value execute(const ProgramVariables& variables) const override;
bool validate(antlr4::Parser* parser, const ParseContext& context) override;
protected:
ValueType determineReturnType() const override;
private:
Value m_literalValue;
};
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,108 +0,0 @@
#include "RandomRangeExpression.h"
#include "actions/expression/TypeDefinition.h"
#include "utils/RandomRange.h"
namespace actions {
namespace expression {
namespace nodes {
namespace {
template <typename T>
Value executeHelper(const Value& leftVal, const Value& rightVal)
{
auto leftContentVal = leftVal.get<T>();
auto rightContentVal = rightVal.get<T>();
if (leftContentVal == rightContentVal) {
// no need to do random stuff here
return Value(rightContentVal);
}
if (rightContentVal < leftContentVal) {
// We can fix this issue
std::swap(leftContentVal, rightContentVal);
}
// Might be a bit inefficient not to cache this somehow but the bounds can be dynamic
return Value(util::UniformRange<T>(leftContentVal, rightContentVal).next());
}
} // namespace
RandomRangeExpression::RandomRangeExpression(antlr4::Token* token,
std::shared_ptr<AbstractExpression> leftExpression,
std::shared_ptr<AbstractExpression> rightExpression)
: AbstractExpression(token), m_leftExpression(std::move(leftExpression)),
m_rightExpression(std::move(rightExpression))
{
}
RandomRangeExpression::~RandomRangeExpression() = default;
Value RandomRangeExpression::execute(const ProgramVariables& variables) const
{
const auto leftVal = m_leftExpression->execute(variables);
const auto rightVal = m_rightExpression->execute(variables);
if (leftVal.getType() == ValueType::Integer) {
return executeHelper<int>(leftVal, rightVal);
} else {
return executeHelper<float>(leftVal, rightVal);
}
}
bool RandomRangeExpression::validate(antlr4::Parser* parser, const ParseContext& context)
{
bool valid = true;
valid &= m_leftExpression->validate(parser, context);
valid &= m_rightExpression->validate(parser, context);
if (!valid) {
// Exit early if there were errors since the values below are meaningless otherwise
return false;
}
const auto leftType = m_leftExpression->getExpressionType();
const auto rightType = m_rightExpression->getExpressionType();
const auto& leftTypedef = TypeDefinition::forValueType(leftType);
const auto& rightTypedef = TypeDefinition::forValueType(rightType);
// Both values must be the same
if (leftType != rightType) {
parser->notifyErrorListeners(m_rightExpression->getToken(),
"Inconsistent types for random range. Must be the same but got <" + leftTypedef.getName() + "> and <" +
rightTypedef.getName() + ">.",
nullptr);
return false;
}
// And we only support floats or integers
if (leftType != ValueType::Float && leftType != ValueType::Integer) {
parser->notifyErrorListeners(m_leftExpression->getToken(),
"Invalid parameter type for random range. Must be <Float> or <Integer> but got <" + leftTypedef.getName() +
">.",
nullptr);
return false;
}
// Everything is fine.
return true;
}
ValueType RandomRangeExpression::determineReturnType() const
{
// Return type is the same as the contained return types
return m_leftExpression->getExpressionType();
}
void RandomRangeExpression::validationDone()
{
AbstractExpression::validationDone();
m_leftExpression->validationDone();
m_rightExpression->validationDone();
}
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,30 +0,0 @@
#pragma once
#include "AbstractExpression.h"
namespace actions {
namespace expression {
namespace nodes {
class RandomRangeExpression : public AbstractExpression {
public:
RandomRangeExpression(antlr4::Token* token,
std::shared_ptr<AbstractExpression> leftExpression,
std::shared_ptr<AbstractExpression> rightExpression);
~RandomRangeExpression() override;
Value execute(const ProgramVariables& variables) const override;
bool validate(antlr4::Parser* parser, const ParseContext& context) override;
void validationDone() override;
protected:
ValueType determineReturnType() const override;
private:
std::shared_ptr<AbstractExpression> m_leftExpression;
std::shared_ptr<AbstractExpression> m_rightExpression;
};
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,69 +0,0 @@
#include "VariableReferenceExpression.h"
namespace actions {
namespace expression {
namespace nodes {
VariableReferenceExpression::VariableReferenceExpression(SCP_vector<SCP_string> references,
SCP_vector<antlr4::Token*> referenceTokens)
: AbstractExpression(referenceTokens.back()), m_references(std::move(references)),
m_referenceTokens(std::move(referenceTokens))
{
}
VariableReferenceExpression::~VariableReferenceExpression() = default;
Value VariableReferenceExpression::execute(const ProgramVariables& variables) const
{
return variables.getValue(m_fullVariablePath);
}
bool VariableReferenceExpression::validate(antlr4::Parser* parser, const ParseContext& context)
{
// Start out in the global scope
auto currentScope = &context.variables;
SCP_string currentScopeName("<global>");
for (size_t i = 0; i < m_references.size() - 1; ++i) {
const auto nextScope = currentScope->getScope(m_references[i]);
if (nextScope == nullptr) {
parser->notifyErrorListeners(m_referenceTokens[i],
"Could not find scope " + m_references[i] + " in scope " + currentScopeName + ".",
nullptr);
return false;
}
currentScope = nextScope;
currentScopeName = m_references[i];
}
auto variableType = currentScope->getMemberType(m_references.back());
if (variableType == ValueType::Invalid) {
parser->notifyErrorListeners(m_referenceTokens.back(),
"Could not find variable " + m_references.back() + " in scope " + currentScopeName + ".",
nullptr);
return false;
}
// Cache this so we don't duplicate all this code in determineReturnType()
m_variableType = variableType;
m_fullVariablePath = ProgramVariables::getMemberName(m_references);
return true;
}
ValueType VariableReferenceExpression::determineReturnType() const
{
return m_variableType;
}
void VariableReferenceExpression::validationDone()
{
AbstractExpression::validationDone();
// Clear these since they are not necessary anymore
m_references.clear();
m_referenceTokens.clear();
}
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,32 +0,0 @@
#pragma once
#include "AbstractExpression.h"
namespace actions {
namespace expression {
namespace nodes {
class VariableReferenceExpression : public AbstractExpression {
public:
VariableReferenceExpression(const SCP_vector<SCP_string> references,
SCP_vector<antlr4::Token*> referenceTokens);
~VariableReferenceExpression() override;
Value execute(const ProgramVariables& variables) const override;
bool validate(antlr4::Parser* parser, const ParseContext& context) override;
void validationDone() override;
protected:
ValueType determineReturnType() const override;
private:
ValueType m_variableType = ValueType::Invalid;
SCP_string m_fullVariablePath;
SCP_vector<SCP_string> m_references;
SCP_vector<antlr4::Token*> m_referenceTokens;
};
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,87 +0,0 @@
#include "VectorConstructorExpression.h"
#include "actions/expression/TypeDefinition.h"
namespace actions {
namespace expression {
namespace nodes {
VectorConstructorExpression::VectorConstructorExpression(antlr4::Token* token,
std::shared_ptr<AbstractExpression> xExpression,
std::shared_ptr<AbstractExpression> yExpression,
std::shared_ptr<AbstractExpression> zExpression)
: AbstractExpression(token), m_xExpression(std::move(xExpression)), m_yExpression(std::move(yExpression)),
m_zExpression(std::move(zExpression))
{
}
VectorConstructorExpression::~VectorConstructorExpression() = default;
Value VectorConstructorExpression::execute(const ProgramVariables& variables) const
{
auto xValue = m_xExpression->execute(variables);
auto yValue = m_yExpression->execute(variables);
auto zValue = m_zExpression->execute(variables);
vec3d vecVal;
vecVal.xyz.x = xValue.getFloat();
vecVal.xyz.y = yValue.getFloat();
vecVal.xyz.z = zValue.getFloat();
return Value(vecVal);
}
bool VectorConstructorExpression::validate(antlr4::Parser* parser, const ParseContext& context)
{
bool valid = true;
valid &= m_xExpression->validate(parser, context);
valid &= m_yExpression->validate(parser, context);
valid &= m_zExpression->validate(parser, context);
if (!valid) {
// Exit early if there were errors since the values below are meaningless otherwise
return false;
}
if (!checkTypeWithImplicitConversion(m_xExpression->getExpressionType(), ValueType::Float)) {
const auto& typeDef = TypeDefinition::forValueType(m_xExpression->getExpressionType());
parser->notifyErrorListeners(m_xExpression->getToken(),
"Invalid value type for vector constructor. Expected <Float>, got <" + typeDef.getName() + ">",
nullptr);
valid = false;
}
if (!checkTypeWithImplicitConversion(m_yExpression->getExpressionType(), ValueType::Float)) {
const auto& typeDef = TypeDefinition::forValueType(m_yExpression->getExpressionType());
parser->notifyErrorListeners(m_yExpression->getToken(),
"Invalid value type for vector constructor. Expected <Float>, got <" + typeDef.getName() + ">",
nullptr);
valid = false;
}
if (!checkTypeWithImplicitConversion(m_zExpression->getExpressionType(), ValueType::Float)) {
const auto& typeDef = TypeDefinition::forValueType(m_zExpression->getExpressionType());
parser->notifyErrorListeners(m_zExpression->getToken(),
"Invalid value type for vector constructor. Expected <Float>, got <" + typeDef.getName() + ">",
nullptr);
valid = false;
}
return valid;
}
ValueType VectorConstructorExpression::determineReturnType() const
{
// No need to look at the expressions here since we will always be a vector
return ValueType::Vector;
}
void VectorConstructorExpression::validationDone()
{
AbstractExpression::validationDone();
m_xExpression->validationDone();
m_yExpression->validationDone();
m_zExpression->validationDone();
}
} // namespace nodes
} // namespace expression
} // namespace actions
@@ -1,34 +0,0 @@
#pragma once
#include "AbstractExpression.h"
#include "actions/expression/Value.h"
namespace actions {
namespace expression {
namespace nodes {
class VectorConstructorExpression : public AbstractExpression {
public:
VectorConstructorExpression(antlr4::Token* token,
std::shared_ptr<AbstractExpression> xExpression,
std::shared_ptr<AbstractExpression> yExpression,
std::shared_ptr<AbstractExpression> zExpression);
~VectorConstructorExpression() override;
Value execute(const ProgramVariables& variables) const override;
bool validate(antlr4::Parser* parser, const ParseContext& context) override;
void validationDone() override;
protected:
ValueType determineReturnType() const override;
private:
std::shared_ptr<AbstractExpression> m_xExpression;
std::shared_ptr<AbstractExpression> m_yExpression;
std::shared_ptr<AbstractExpression> m_zExpression;
};
} // namespace nodes
} // namespace expression
} // namespace actions
-79
View File
@@ -1,79 +0,0 @@
#include "MoveToSubmodel.h"
#include "math/vecmat.h"
#include "parse/parselo.h"
#include "ship/ship.h"
#include <utility>
namespace actions {
namespace types {
flagset<ProgramContextFlags> MoveToSubmodel::getRequiredExecutionContextFlags()
{
return flagset<ProgramContextFlags>{ProgramContextFlags::HasObject, ProgramContextFlags::HasSubobject};
}
MoveToSubmodel::MoveToSubmodel(expression::TypedActionExpression<ValueType> subObjectExpression)
: m_subObjectExpression(std::move(subObjectExpression))
{
}
MoveToSubmodel::~MoveToSubmodel() = default;
ActionResult MoveToSubmodel::execute(ProgramLocals& locals) const
{
// The calling code should ensure that this never happens
Assertion(locals.hostSubobject >= 0, "Did not have a valid host subobject.");
auto instance = object_get_model_instance(locals.host.objp);
Assertion(instance != -1, "Model instances are required if a host subobject is specified.");
auto pmi = model_get_instance(instance);
auto pm = model_get(pmi->model_num);
const auto destinationSubObject = m_subObjectExpression.execute(locals.variables);
bool goToParent = false;
if (destinationSubObject == "<parent>") {
goToParent = true;
}
if (goToParent) {
// Special case when we simply want to go to our parent without explicitly specifying its name
auto parentSubobject = pm->submodel[locals.hostSubobject].parent;
if (parentSubobject < 0) {
Warning(LOCATION,
"Current program subobject %s on model %s has no parent!",
pm->submodel[locals.hostSubobject].name,
pm->filename);
return ActionResult::Errored;
}
// We have a valid parent so this move will work properly
locals.hostSubobject = parentSubobject;
return ActionResult::Finished;
}
// We need to do a linear search for the right subobject
for (int i = 0; i < pm->n_models; ++i) {
const auto submodel = pm->submodel[i];
if (subsystem_stricmp(destinationSubObject.c_str(), submodel.name) == 0) {
// Found something!
locals.hostSubobject = i;
return ActionResult::Finished;
}
}
Warning(LOCATION, "Could not find subobject %s in model %s!", destinationSubObject.c_str(), pm->filename);
return ActionResult::Errored;
}
std::unique_ptr<Action> MoveToSubmodel::clone() const
{
return std::unique_ptr<Action>(new MoveToSubmodel(*this));
}
} // namespace types
} // namespace actions
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include "globalincs/flagset.h"
#include "actions/Action.h"
#include "actions/expression/ActionExpression.h"
namespace actions {
namespace types {
class MoveToSubmodel : public Action {
public:
using ValueType = SCP_string;
static flagset<ProgramContextFlags> getRequiredExecutionContextFlags();
explicit MoveToSubmodel(expression::TypedActionExpression<ValueType> subObjectExpression);
~MoveToSubmodel() override;
ActionResult execute(ProgramLocals& locals) const override;
std::unique_ptr<Action> clone() const override;
private:
expression::TypedActionExpression<ValueType> m_subObjectExpression;
};
} // namespace types
} // namespace actions
@@ -1,76 +0,0 @@
#include "ParticleEffectAction.h"
#include "math/vecmat.h"
#include "parse/parselo.h"
#include "ship/ship.h"
#include <utility>
namespace actions {
namespace types {
flagset<ProgramContextFlags> ParticleEffectAction::getRequiredExecutionContextFlags()
{
return flagset<ProgramContextFlags>{ProgramContextFlags::HasObject};
}
ParticleEffectAction::ParticleEffectAction(expression::TypedActionExpression<ValueType> effectExpression)
: m_effectExpression(std::move(effectExpression))
{
}
ParticleEffectAction::~ParticleEffectAction() = default;
ActionResult ParticleEffectAction::execute(ProgramLocals& locals) const
{
auto effectIdx = particle::ParticleManager::get()->getEffectByName(m_effectExpression.execute(locals.variables));
if (!effectIdx.isValid()) {
// In case the parsing code failed
return ActionResult::Errored;
}
using namespace particle;
auto source = ParticleManager::get()->createSource(effectIdx);
vec3d local_pos;
matrix local_orient;
if (locals.hostSubobject != -1) {
auto instance = object_get_model_instance(locals.host.objp);
Assertion(instance != -1, "Model instances are required if a host subobject is specified.");
auto pmi = model_get_instance(instance);
auto pm = model_get(pmi->model_num);
find_submodel_instance_point_orient(&local_pos,
&local_orient,
pm,
pmi,
locals.hostSubobject,
&locals.localPosition,
&locals.localOrient);
} else {
local_pos = locals.localPosition;
local_orient = locals.localOrient;
}
local_pos += locals.variables.getValue({"locals", "position"}).getVector();
auto direction = locals.variables.getValue({"locals", "direction"}).getVector();
source.moveToObject(locals.host.objp, &local_pos);
source.setOrientationFromNormalizedVec(&direction, true);
source.finish();
return ActionResult::Finished;
}
std::unique_ptr<Action> ParticleEffectAction::clone() const
{
return std::unique_ptr<Action>(new ParticleEffectAction(*this));
}
} // namespace types
} // namespace actions
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include "actions/Action.h"
#include "actions/expression/ActionExpression.h"
#include "particle/ParticleManager.h"
namespace actions {
namespace types {
class ParticleEffectAction : public Action {
public:
using ValueType = SCP_string;
static flagset<ProgramContextFlags> getRequiredExecutionContextFlags();
explicit ParticleEffectAction(expression::TypedActionExpression<ValueType> effectExpression);
~ParticleEffectAction() override;
ActionResult execute(ProgramLocals& locals) const override;
std::unique_ptr<Action> clone() const override;
private:
expression::TypedActionExpression<ValueType> m_effectExpression;
};
} // namespace types
} // namespace actions
-65
View File
@@ -1,65 +0,0 @@
//
//
#include "PlaySoundAction.h"
#include "ship/ship.h"
#include <utility>
namespace actions {
namespace types {
flagset<ProgramContextFlags> PlaySoundAction::getRequiredExecutionContextFlags()
{
return flagset<ProgramContextFlags>{ProgramContextFlags::HasObject};
}
PlaySoundAction::PlaySoundAction(expression::TypedActionExpression<ValueType> soundIdExpression)
: m_soundIdExpression(std::move(soundIdExpression))
{
}
PlaySoundAction::~PlaySoundAction() = default;
ActionResult PlaySoundAction::execute(ProgramLocals& locals) const
{
vec3d local_pos;
matrix local_orient;
if (locals.hostSubobject != -1) {
auto instance = object_get_model_instance(locals.host.objp);
Assertion(instance != -1, "Model instances are required if a host subobject is specified.");
auto pmi = model_get_instance(instance);
auto pm = model_get(pmi->model_num);
find_submodel_instance_point_orient(&local_pos,
&local_orient,
pm,
pmi,
locals.hostSubobject,
&locals.localPosition,
&locals.localOrient);
} else {
local_pos = locals.localPosition;
local_orient = locals.localOrient;
}
local_pos += locals.variables.getValue({"locals", "position"}).getVector();
vec3d global_pos;
vm_vec_unrotate(&global_pos, &local_pos, &locals.host.objp->orient);
global_pos += locals.host.objp->pos;
const auto soundId = gamesnd_get_by_name(m_soundIdExpression.execute(locals.variables).c_str());
// Sound is not attached to the host but the object sound system currently only supports persistent sounds
snd_play_3d(gamesnd_get_game_sound(soundId), &global_pos, &Eye_position);
return ActionResult::Finished;
}
std::unique_ptr<Action> PlaySoundAction::clone() const
{
return std::unique_ptr<Action>(new PlaySoundAction(*this));
}
} // namespace types
} // namespace actions
-28
View File
@@ -1,28 +0,0 @@
#pragma once
#include "actions/Action.h"
#include "actions/expression/ActionExpression.h"
#include "gamesnd/gamesnd.h"
namespace actions {
namespace types {
class PlaySoundAction : public Action {
public:
using ValueType = SCP_string;
static flagset<ProgramContextFlags> getRequiredExecutionContextFlags();
explicit PlaySoundAction(expression::TypedActionExpression<ValueType> soundIdExpression);
~PlaySoundAction() override;
ActionResult execute(ProgramLocals& locals) const override;
std::unique_ptr<Action> clone() const override;
private:
expression::TypedActionExpression<ValueType> m_soundIdExpression;
};
} // namespace types
} // namespace actions
-39
View File
@@ -1,39 +0,0 @@
#include "SetDirectionAction.h"
#include "math/vecmat.h"
#include "parse/parselo.h"
#include <utility>
namespace actions {
namespace types {
flagset<ProgramContextFlags> SetDirectionAction::getRequiredExecutionContextFlags()
{
return flagset<ProgramContextFlags>{};
}
SetDirectionAction::SetDirectionAction(expression::TypedActionExpression<vec3d> newDirExpression)
: m_newDirExpression(std::move(newDirExpression))
{
}
SetDirectionAction::~SetDirectionAction() = default;
ActionResult SetDirectionAction::execute(ProgramLocals& locals) const
{
auto dir = m_newDirExpression.execute(locals.variables);
vm_vec_normalize_safe(&dir);
locals.variables.setValue({"locals", "direction"}, expression::Value(dir));
return ActionResult::Finished;
}
std::unique_ptr<Action> SetDirectionAction::clone() const
{
return std::unique_ptr<Action>(new SetDirectionAction(*this));
}
} // namespace types
} // namespace actions
-27
View File
@@ -1,27 +0,0 @@
#pragma once
#include "actions/Action.h"
#include "actions/expression/ActionExpression.h"
namespace actions {
namespace types {
class SetDirectionAction : public Action {
public:
using ValueType = vec3d;
static flagset<ProgramContextFlags> getRequiredExecutionContextFlags();
SetDirectionAction(expression::TypedActionExpression<ValueType> newDirExpression);
~SetDirectionAction() override;
ActionResult execute(ProgramLocals& locals) const override;
std::unique_ptr<Action> clone() const override;
private:
expression::TypedActionExpression<ValueType> m_newDirExpression;
};
} // namespace types
} // namespace actions
-34
View File
@@ -1,34 +0,0 @@
#include "SetPositionAction.h"
#include "parse/parselo.h"
#include <utility>
namespace actions {
namespace types {
flagset<ProgramContextFlags> SetPositionAction::getRequiredExecutionContextFlags()
{
return flagset<ProgramContextFlags>{};
}
SetPositionAction::SetPositionAction(expression::TypedActionExpression<ValueType> newPositionExpression)
: m_newPosExpression(std::move(newPositionExpression))
{
}
SetPositionAction::~SetPositionAction() = default;
ActionResult SetPositionAction::execute(ProgramLocals& locals) const
{
locals.variables.setValue({"locals", "position"}, expression::Value(m_newPosExpression.execute(locals.variables)));
return ActionResult::Finished;
}
std::unique_ptr<Action> SetPositionAction::clone() const
{
return std::unique_ptr<Action>(new SetPositionAction(*this));
}
} // namespace types
} // namespace actions
-28
View File
@@ -1,28 +0,0 @@
#pragma once
#include "actions/Action.h"
#include "actions/expression/ActionExpression.h"
namespace actions {
namespace types {
class SetPositionAction : public Action {
public:
using ValueType = vec3d;
static flagset<ProgramContextFlags> getRequiredExecutionContextFlags();
SetPositionAction(expression::TypedActionExpression<ValueType> newPositionExpression);
~SetPositionAction() override;
ActionResult execute(ProgramLocals& locals) const override;
std::unique_ptr<Action> clone() const override;
private:
expression::TypedActionExpression<vec3d> m_newPosExpression;
};
} // namespace types
} // namespace actions
-48
View File
@@ -1,48 +0,0 @@
#include "WaitAction.h"
#include "io/timer.h"
#include "parse/parselo.h"
namespace actions {
namespace types {
flagset<ProgramContextFlags> WaitAction::getRequiredExecutionContextFlags()
{
return flagset<ProgramContextFlags>{};
}
WaitAction::WaitAction(expression::TypedActionExpression<float> waitTimeExpression)
: _waitTimeExpression(std::move(waitTimeExpression))
{
}
WaitAction::~WaitAction() = default;
ActionResult WaitAction::execute(actions::ProgramLocals& locals) const
{
if (!timestamp_valid(locals.waitTimestamp)) {
auto waitTime = _waitTimeExpression.execute(locals.variables);
// Catch errors in the expression
if (waitTime < 0.001f) {
waitTime = 0.001f;
}
locals.waitTimestamp = timestamp(fl2i(waitTime * TIMESTAMP_FREQUENCY));
}
if (!timestamp_elapsed(locals.waitTimestamp)) {
// Wait until the timestamp is elapsed
return ActionResult::Wait;
}
// Timestamp is elapsed. The timestamp is elapsed so that timestamp_valid above returns false for the next wait
// action
locals.waitTimestamp = 0;
return ActionResult::Finished;
}
std::unique_ptr<Action> WaitAction::clone() const
{
return std::unique_ptr<Action>(new WaitAction(*this));
}
} // namespace types
} // namespace actions
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include "actions/Action.h"
#include "actions/common.h"
#include "actions/expression/ActionExpression.h"
#include "utils/RandomRange.h"
namespace actions {
namespace types {
class WaitAction : public Action {
public:
using ValueType = float;
static flagset<ProgramContextFlags> getRequiredExecutionContextFlags();
explicit WaitAction(expression::TypedActionExpression<ValueType> waitTimeExpression);
~WaitAction() override;
ActionResult execute(ProgramLocals& locals) const override;
std::unique_ptr<Action> clone() const override;
private:
expression::TypedActionExpression<ValueType> _waitTimeExpression;
};
} // namespace types
} // namespace actions
+2 -2
View File
@@ -7840,7 +7840,7 @@ void update_aspect_lock_information(ai_info *aip, vec3d *vec_to_enemy, float dis
object *aiobjp = &Objects[shipp->objnum];
// AL 3-7-98: This probably should never happen, but check to ensure that current_secondary_bank is valid
if ( (swp->current_secondary_bank < 0) || (swp->current_secondary_bank > swp->num_secondary_banks) ) {
if ( (swp->current_secondary_bank < 0) || (swp->current_secondary_bank >= swp->num_secondary_banks) ) {
return;
}
@@ -9065,7 +9065,7 @@ void ai_chase()
}
}
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank]) && weapon_can_lock_on_ship(swip, En_objp->instance)) {
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank]) && weapon_target_satisfies_lock_restrictions(swip, En_objp)) {
if (current_bank >= 0) {
float firing_range;
+8 -20
View File
@@ -10,7 +10,6 @@
#include <sstream>
#include <climits>
#include "gamesnd.h"
#include "gamesnd/gamesnd.h"
#include "localization/localize.h"
#include "parse/parselo.h"
@@ -422,30 +421,19 @@ bool parse_game_sound(const char* tag, gamesnd_id* idx_dest)
{
if (optional_string(tag))
{
*idx_dest = parse_game_sound_inline();
return true;
}
SCP_string buf;
stuff_string(buf, F_NAME);
return false;
}
*idx_dest = gamesnd_get_by_name(buf.c_str());
/**
* @brief Parses a game sound that should appear at the current parsing location
* @return The game sound id or invalid id when parsing fails
*/
gamesnd_id parse_game_sound_inline()
{
SCP_string buf;
stuff_string(buf, F_NAME);
auto id = gamesnd_get_by_name(buf.c_str());
// The special case "-1" is needed to silence warnings where sounds are intentionally removed
if (!id.isValid() && buf != "-1") {
// The special case "-1" is needed to silence warnings where sounds are intentionally removed
if (idx_dest->isValid() || buf == "-1")
return true;
error_display(0, "Could not find game sound with name '%s'!", buf.c_str());
}
return id;
return false;
}
/**
-2
View File
@@ -372,8 +372,6 @@ interface_snd_id gamesnd_get_by_iface_tbl_index(int index);
// Does all parsing for a sound. Returns true if a sound was successfully parsed.
bool parse_game_sound(const char* tag, gamesnd_id* idx_dest);
gamesnd_id parse_game_sound_inline();
void parse_iface_sound(const char* tag, interface_snd_id* idx_dest);
void parse_iface_sound_list(const char* tag, SCP_vector<interface_snd_id>& destination, const char* object_name, bool scp_list = false);
+3 -3
View File
@@ -924,7 +924,7 @@ void hud_lock_acquire_uncaged_target(lock_info *current_lock, weapon_info *wip)
continue;
}*/
if (!weapon_can_lock_on_ship(wip, A->instance)) {
if (!weapon_target_satisfies_lock_restrictions(wip, A)) {
continue;
}
@@ -1042,7 +1042,7 @@ void hud_lock_determine_lock_target(lock_info *lock_slot, weapon_info *wip)
return;
}
if ( !weapon_can_lock_on_ship(wip, lock_slot->obj->instance) ) {
if ( !weapon_target_satisfies_lock_restrictions(wip, lock_slot->obj) ) {
ship_clear_lock(lock_slot);
return;
}
@@ -1110,7 +1110,7 @@ void hud_lock_determine_lock_target(lock_info *lock_slot, weapon_info *wip)
return;
}
if ( !weapon_can_lock_on_ship(wip, lock_slot->obj->instance) ) {
if ( !weapon_target_satisfies_lock_restrictions(wip, lock_slot->obj) ) {
ship_clear_lock(lock_slot);
return;
}
-23
View File
@@ -1,23 +0,0 @@
#include "ErrorListener.h"
namespace libs {
namespace antlr {
void ErrorListener::syntaxError(antlr4::Recognizer*,
antlr4::Token* offendingSymbol,
size_t line,
size_t charPositionInLine,
const std::string& msg,
std::exception_ptr)
{
// Apparently stop < start is a thing?
const auto left = std::min(offendingSymbol->getStartIndex(), offendingSymbol->getStopIndex());
const auto right = std::max(offendingSymbol->getStartIndex(), offendingSymbol->getStopIndex());
const auto length = right - left + 1;
diagnostics.push_back(Diagnostic{line, charPositionInLine, length, msg});
}
} // namespace antlr
} // namespace libs
-29
View File
@@ -1,29 +0,0 @@
#include "globalincs/pstypes.h"
#include <BaseErrorListener.h>
#include <Token.h>
namespace libs {
namespace antlr {
struct Diagnostic {
size_t line;
size_t columnInLine;
size_t tokenLength;
SCP_string errorMessage;
};
struct ErrorListener : public antlr4::BaseErrorListener {
SCP_vector<Diagnostic> diagnostics;
void syntaxError(antlr4::Recognizer* /*recognizer*/,
antlr4::Token* offendingSymbol,
size_t line,
size_t charPositionInLine,
const std::string& msg,
std::exception_ptr /*e*/) override;
};
} // namespace antlr
} // namespace libs
-17
View File
@@ -157,17 +157,6 @@ void vm_set_identity(matrix *m)
m->vec.fvec.xyz.x = 0.0f; m->vec.fvec.xyz.y = 0.0f; m->vec.fvec.xyz.z = 1.0f;
}
vec3d vm_vec_new(float x, float y, float z)
{
vec3d vec;
vec.xyz.x = x;
vec.xyz.y = y;
vec.xyz.z = z;
return vec;
}
//adds two vectors, fills in dest, returns ptr to dest
//ok for dest to equal either source, but should use vm_vec_add2() if so
//dest = src0 + src1
@@ -2842,9 +2831,3 @@ void vm_interpolate_angles_quick(angles *dest0, angles *src0, angles *src1, floa
dest0->h = src0->h + (arc_measures.h * interp_perc);
dest0->b = src0->b + (arc_measures.b * interp_perc);
}
std::ostream& operator<<(std::ostream& os, const vec3d& vec)
{
os << "vec3d<" << vec.xyz.x << ", " << vec.xyz.y << ", " << vec.xyz.z << ")";
return os;
}
-4
View File
@@ -52,8 +52,6 @@ extern void vm_set_identity(matrix *m);
#define vm_vec_make(v,_x,_y,_z) ((v)->xyz.x=(_x), (v)->xyz.y=(_y), (v)->xyz.z=(_z))
extern vec3d vm_vec_new(float x, float y, float z);
//Global constants
extern vec3d vmd_zero_vector;
@@ -656,8 +654,6 @@ inline matrix operator*(const matrix& left, const matrix& right) {
return out;
}
std::ostream& operator<<(std::ostream& os, const vec3d& vec);
#endif
+115 -195
View File
@@ -5,7 +5,8 @@
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
@@ -235,14 +236,10 @@ typedef struct {
int textures_loaded; // if the model has textures loaded for it or not (hacky mem management)
} tech_list_entry;
static tech_list_entry *Ship_list = nullptr;
static int Ship_list_size = 0;
static tech_list_entry *Weapon_list = nullptr;
static int Weapon_list_size = 0;
static tech_list_entry *Intel_list = nullptr;
static int Intel_list_size = 0;
static tech_list_entry *Current_list; // points to currently valid display list
static int Current_list_size = 0;
static SCP_vector<tech_list_entry> Ship_list;
static SCP_vector<tech_list_entry> Weapon_list;
static SCP_vector<tech_list_entry> Intel_list;
static SCP_vector<tech_list_entry>* Current_list = &Ship_list; // A pointer to the current display list
// slider stuff
static UI_SLIDER2 Tech_slider;
@@ -274,64 +271,63 @@ void techroom_init_desc(const char *src, int w)
void techroom_unload_animation()
{
int i;
//clear everything, just in case, it will get loaded when needed later
if (Weapon_list != NULL) {
for (i = 0; i < Weapon_list_size; i++) {
if (Weapon_list[i].animation.num_frames != 0) {
generic_anim_unload(&Weapon_list[i].animation);
}
for (auto& list_entry : Weapon_list) {
if (list_entry.animation.type != BM_TYPE_NONE && list_entry.has_anim != 0) {
generic_anim_unload(&list_entry.animation);
}
if (Weapon_list[i].bitmap >= 0) {
bm_release(Weapon_list[i].bitmap);
Weapon_list[i].bitmap = -1;
}
if (list_entry.bitmap >= 0) {
bm_release(list_entry.bitmap);
list_entry.bitmap = -1;
}
}
for (i = 0; i < Intel_list_size; i++) {
if (Intel_list[i].animation.num_frames != 0) {
generic_anim_unload(&Intel_list[i].animation);
for (auto & intel_entry : Intel_list) {
if (intel_entry.animation.type != BM_TYPE_NONE && intel_entry.has_anim != 0) {
generic_anim_unload(&intel_entry.animation);
}
if (Intel_list[i].bitmap >= 0) {
bm_release(Intel_list[i].bitmap);
Intel_list[i].bitmap = -1;
if (intel_entry.bitmap >= 0) {
bm_release(intel_entry.bitmap);
intel_entry.bitmap = -1;
}
}
}
void techroom_select_new_entry()
{
Assert(Current_list != NULL);
if (Current_list == NULL || Current_list_size <= 0) {
if (Current_list->empty()) {
Cur_entry_index = Cur_entry = -1;
techroom_init_desc(NULL,0);
techroom_init_desc(nullptr,0);
return;
}
Cur_entry_index = Current_list[Cur_entry].index;
Assert(Cur_entry < static_cast<int>(Current_list->size()));
Cur_entry_index = Current_list->at(Cur_entry).index;
Assert( Cur_entry_index >= 0 );
// if we are in the ships tab, load the ship model
if (Tab == SHIPS_DATA_TAB) {
ship_info *sip = &Ship_info[Cur_entry_index];
int i = 0;
// little memory management, kinda hacky but it should keep the techroom at around
// 100meg rather than the 700+ it can get to with all ships loaded - taylor
for (int i=0; i<Current_list_size; i++) {
if ((Current_list[i].model_num > -1) && (Current_list[i].textures_loaded)) {
for (auto & list_entry : *Current_list) {
if ((list_entry.model_num > -1) && (list_entry.textures_loaded)) {
// don't unload any spot within 5 of current
if ( (i < Cur_entry + 5) && (i > Cur_entry - 5) )
if ((i < Cur_entry + 5) && (i > Cur_entry - 5) )
continue;
mprintf(("TECH ROOM: Dumping excess ship textures...\n"));
model_page_out_textures(Current_list[i].model_num);
model_page_out_textures(list_entry.model_num);
Current_list[i].textures_loaded = 0;
list_entry.textures_loaded = 0;
}
i++;
}
Techroom_ship_modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
@@ -341,12 +337,12 @@ void techroom_select_new_entry()
}
Techroom_ship_model_instance = model_create_instance(true, Techroom_ship_modelnum);
Current_list[Cur_entry].model_num = Techroom_ship_modelnum;
Current_list->at(Cur_entry).model_num = Techroom_ship_modelnum;
// page in ship textures properly (takes care of nondimming pixels)
model_page_in_textures(Techroom_ship_modelnum, Cur_entry_index);
Current_list[Cur_entry].textures_loaded = 1;
Current_list->at(Cur_entry).textures_loaded = 1;
} else {
Techroom_ship_modelnum = -1;
@@ -358,19 +354,19 @@ void techroom_select_new_entry()
Trackball_mode = 0;
// load animation here, we now only have one loaded
int stream_result = generic_anim_init_and_stream(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
int stream_result = generic_anim_init_and_stream(&Current_list->at(Cur_entry).animation, Current_list->at(Cur_entry).tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
if (stream_result >= 0) {
Current_list[Cur_entry].has_anim = 1;
Current_list->at(Cur_entry).has_anim = 1;
} else {
// we've failed to load any animation
// load an image and treat it like a 1 frame animation
Current_list[Cur_entry].bitmap = bm_load(Current_list[Cur_entry].tech_anim_filename);
Current_list->at(Cur_entry).bitmap = bm_load(Current_list->at(Cur_entry).tech_anim_filename);
}
}
techroom_init_desc(Current_list[Cur_entry].desc, Tech_desc_coords[gr_screen.res][SHIP_W_COORD]);
fsspeech_play(FSSPEECH_FROM_TECHROOM, Current_list[Cur_entry].desc);
techroom_init_desc(Current_list->at(Cur_entry).desc, Tech_desc_coords[gr_screen.res][SHIP_W_COORD]);
fsspeech_play(FSSPEECH_FROM_TECHROOM, Current_list->at(Cur_entry).desc);
}
// write out the current description in the bottom window
@@ -432,7 +428,7 @@ void tech_common_render()
y = 0;
z = List_offset;
while (y + font_height <= Tech_list_coords[gr_screen.res][SHIP_H_COORD]) {
if (z >= Current_list_size) {
if (z >= static_cast<int>(Current_list->size())) {
break;
}
@@ -445,7 +441,7 @@ void tech_common_render()
}
memset( buf, 0, sizeof(buf) );
strncpy(buf, Current_list[z].name, sizeof(buf) - 1);
strncpy(buf, Current_list->at(z).name, sizeof(buf) - 1);
if (Lcl_gr && !Disable_built_in_translations)
lcl_translate_ship_name_gr(buf);
@@ -626,7 +622,7 @@ void tech_prev_entry()
Cur_entry--;
if (Cur_entry < 0) {
Cur_entry = Current_list_size - 1;
Cur_entry = static_cast<int>(Current_list->size() - 1);
// scroll to end of list
List_offset = Cur_entry - Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() + 1;
@@ -654,7 +650,7 @@ void tech_next_entry()
techroom_unload_animation();
Cur_entry++;
if (Cur_entry >= Current_list_size) {
if (Cur_entry >= static_cast<int>(Current_list->size())) {
Cur_entry = 0;
// scroll to beginning of list
@@ -710,7 +706,7 @@ void tech_scroll_list_up()
void tech_scroll_list_down()
{
if (List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() < Current_list_size) {
if (List_offset + Tech_list_coords[gr_screen.res][SHIP_H_COORD] / gr_get_font_height() < static_cast<int>(Current_list->size())) {
List_offset++;
gamesnd_play_iface(InterfaceSounds::SCROLL);
} else {
@@ -735,27 +731,27 @@ void techroom_anim_render(float frametime)
tech_common_render();
// exit now if there are no entries to show
if (Current_list_size == 0 || Cur_entry < 0)
if (Current_list->empty() || Cur_entry < 0 || Cur_entry >= static_cast<int>(Current_list->size()))
return;
// render the animation
if(Current_list[Cur_entry].animation.num_frames > 0)
if(Current_list->at(Cur_entry).animation.num_frames > 0)
{
//grab dimensions
bm_get_info((Current_list[Cur_entry].animation.streaming) ? Current_list[Cur_entry].animation.bitmap_id : Current_list[Cur_entry].animation.first_frame, &x, &y, NULL, NULL, NULL);
bm_get_info((Current_list->at(Cur_entry).animation.streaming) ? Current_list->at(Cur_entry).animation.bitmap_id : Current_list->at(Cur_entry).animation.first_frame, &x, &y, nullptr, nullptr, nullptr);
//get the centre point - adjust
x = Tech_ani_centre_coords[gr_screen.res][0] - x / 2;
y = Tech_ani_centre_coords[gr_screen.res][1] - y / 2;
generic_anim_render(&Current_list[Cur_entry].animation, frametime, x, y, true);
generic_anim_render(&Current_list->at(Cur_entry).animation, frametime, x, y, true);
}
// if our active item has a bitmap instead of an animation, draw it
else if((Cur_entry >= 0) && (Current_list[Cur_entry].bitmap >= 0)){
else if((Cur_entry >= 0) && (Current_list->at(Cur_entry).bitmap >= 0)){
//grab dimensions
bm_get_info(Current_list[Cur_entry].bitmap, &x, &y, NULL, NULL, NULL);
bm_get_info(Current_list->at(Cur_entry).bitmap, &x, &y, nullptr, nullptr, nullptr);
//get the centre point - adjust
x = Tech_ani_centre_coords[gr_screen.res][0] - x / 2;
y = Tech_ani_centre_coords[gr_screen.res][1] - y / 2;
gr_set_bitmap(Current_list[Cur_entry].bitmap);
gr_set_bitmap(Current_list->at(Cur_entry).bitmap);
gr_bitmap(x, y, GR_RESIZE_MENU);
}
}
@@ -792,50 +788,40 @@ void techroom_change_tab(int num)
// load ship info if necessary
if ( !Ships_loaded ) {
if (Ship_list == NULL) {
Ship_list = new tech_list_entry[Ship_info.size()];
if (Ship_list.empty()) {
Ship_list.reserve(Ship_info.size());
}
Ship_list_size = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.bitmap = -1;
temp_entry.animation.num_frames = 0; // no anim for ships
temp_entry.has_anim = 0; // no anim for ships
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto it = Ship_info.begin(); it != Ship_info.end(); ++it)
{
if (Techroom_show_all || (it->flags & si_mask).any_set())
{
// this ship should be displayed, fill out the entry struct
Ship_list[Ship_list_size].bitmap = -1;
Ship_list[Ship_list_size].index = (int)std::distance(Ship_info.begin(), it);
Ship_list[Ship_list_size].animation.num_frames = 0; // no anim for ships
Ship_list[Ship_list_size].has_anim = 0; // no anim for ships
Ship_list[Ship_list_size].name = *it->tech_title ? it->tech_title : it->get_display_name();
Ship_list[Ship_list_size].desc = it->tech_desc;
Ship_list[Ship_list_size].model_num = -1;
Ship_list[Ship_list_size].textures_loaded = 0;
temp_entry.index = (int)std::distance(Ship_info.begin(), it);
temp_entry.name = *it->tech_title ? it->tech_title : it->get_display_name();
temp_entry.desc = it->tech_desc;
Ship_list_size++;
Ship_list.push_back(temp_entry);
}
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Ship_info.empty() && !Ship_list_size) {
Ship_list[0].index = -1;
Ship_list[0].desc = NULL;
Ship_list[0].name = NULL;
Ship_list[0].bitmap = -1;
Ship_list[0].has_anim = 0;
Ship_list[0].animation.num_frames = 0;
Ship_list[0].model_num = -1;
Ship_list[0].textures_loaded = 0;
}
Ships_loaded = true;
}
Current_list = Ship_list;
Current_list_size = Ship_list_size;
Current_list = &Ship_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems((int)Current_list->size() > max_num_entries_viewable ? (int)Current_list->size()-max_num_entries_viewable : 0);
// no anim to start here
break;
@@ -844,57 +830,45 @@ void techroom_change_tab(int num)
// load weapon info & anims if necessary
if ( !Weapons_loaded ) {
if (Weapon_list == NULL) {
Weapon_list = new tech_list_entry[Weapon_info.size()];
}
Weapon_list_size = 0;
Weapon_list.reserve(Weapon_info.size());
wi_mask.set(multi ? Weapon::Info_Flags::Player_allowed : Weapon::Info_Flags::In_tech_database);
wi_mask.set(Weapon::Info_Flags::Default_in_tech_database);
int i = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.has_anim = 1;
temp_entry.bitmap = -1;
temp_entry.animation.num_frames = 0;
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto &wi : Weapon_info)
{
if (Techroom_show_all || (wi.wi_flags & wi_mask).any_set())
{
// we have a weapon that should be in the tech db, so fill out the entry struct
Weapon_list[Weapon_list_size].index = i;
Weapon_list[Weapon_list_size].desc = wi.tech_desc;
Weapon_list[Weapon_list_size].has_anim = 1;
Weapon_list[Weapon_list_size].name = wi.tech_title[0] ? wi.tech_title : wi.get_display_name();
Weapon_list[Weapon_list_size].bitmap = -1;
Weapon_list[Weapon_list_size].animation.num_frames = 0;
Weapon_list[Weapon_list_size].model_num = -1;
Weapon_list[Weapon_list_size].textures_loaded = 0;
// we have a weapon that should be in the tech db, so fill out specific info
temp_entry.index = i;
temp_entry.desc = wi.tech_desc;
temp_entry.name = wi.tech_title[0] ? wi.tech_title : wi.get_display_name();
// copy the weapon animation filename
strncpy(Weapon_list[Weapon_list_size].tech_anim_filename, wi.tech_anim_filename, MAX_FILENAME_LEN - 1);
++Weapon_list_size;
strncpy(temp_entry.tech_anim_filename, wi.tech_anim_filename, MAX_FILENAME_LEN - 1);
Weapon_list.push_back(temp_entry);
}
++i;
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Weapon_info.empty() && !Weapon_list_size) {
Weapon_list[0].index = -1;
Weapon_list[0].desc = NULL;
Weapon_list[0].name = NULL;
Weapon_list[0].bitmap = -1;
Weapon_list[0].has_anim = 0;
Weapon_list[0].animation.num_frames = 0;
Weapon_list[0].model_num = -1;
Weapon_list[0].textures_loaded = 0;
}
Weapons_loaded = true;
}
Current_list = Weapon_list;
Current_list_size = Weapon_list_size;
Current_list = &Weapon_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems(static_cast<int>(Current_list->size()) > max_num_entries_viewable ? static_cast<int>(Current_list->size())-max_num_entries_viewable : 0);
break;
@@ -902,60 +876,46 @@ void techroom_change_tab(int num)
// load intel if necessary
if ( !Intel_loaded ) {
if (Intel_list == nullptr) {
Intel_list = new tech_list_entry[Intel_info.size()];
if (Intel_list.empty()) {
Intel_list.reserve(Intel_info.size());
}
Intel_list_size = 0;
int i = 0;
tech_list_entry temp_entry;
// we always initially set these values, so keep them outside the loop.
temp_entry.has_anim = 0;
temp_entry.model_num = -1;
temp_entry.textures_loaded = 0;
for (auto &ii : Intel_info) {
if (Techroom_show_all || (ii.flags & IIF_IN_TECH_DATABASE)) {
// leave option for no animation if string == "none"
if (!strcmp(ii.anim_filename, "none")) {
Intel_list[Intel_list_size].has_anim = 0;
Intel_list[Intel_list_size].animation.num_frames = 0;
temp_entry.animation.num_frames = 0;
} else {
// try and load as an animation
Intel_list[Intel_list_size].has_anim = 0;
Intel_list[Intel_list_size].bitmap = -1;
strncpy(Intel_list[Intel_list_size].tech_anim_filename, ii.anim_filename, NAME_LENGTH - 1);
temp_entry.bitmap = -1;
strncpy(temp_entry.tech_anim_filename, ii.anim_filename, NAME_LENGTH - 1);
}
Intel_list[Intel_list_size].desc = ii.desc.c_str();
Intel_list[Intel_list_size].index = i;
Intel_list[Intel_list_size].name = ii.name;
Intel_list[Intel_list_size].model_num = -1;
Intel_list[Intel_list_size].textures_loaded = 0;
temp_entry.desc = ii.desc.c_str();
temp_entry.index = i;
temp_entry.name = ii.name;
Intel_list_size++;
Intel_list.push_back(temp_entry);
}
++i;
}
// make sure that at least the default entry is cleared out if we didn't grab anything
if (!Intel_info.empty() && !Intel_list_size) {
Intel_list[0].index = -1;
Intel_list[0].desc = NULL;
Intel_list[0].name = NULL;
Intel_list[0].bitmap = -1;
Intel_list[0].has_anim = 0;
Intel_list[0].animation.num_frames = 0;
Intel_list[0].model_num = -1;
Intel_list[0].textures_loaded = 0;
}
Intel_loaded = true;
}
// index lookup on intel is a pretty pointless, but it keeps everything
// consistent and doesn't really hurt anything
Current_list = Intel_list;
Current_list_size = Intel_list_size;
Current_list = &Intel_list;
font_height = gr_get_font_height();
max_num_entries_viewable = Tech_list_coords[gr_screen.res][SHIP_H_COORD] / font_height;
Tech_slider.set_numberItems(Current_list_size > max_num_entries_viewable ? Current_list_size-max_num_entries_viewable : 0);
Tech_slider.set_numberItems(static_cast<int>(Current_list->size()) > max_num_entries_viewable ? static_cast<int>(Current_list->size())-max_num_entries_viewable : 0);
break;
}
@@ -1123,7 +1083,7 @@ void techroom_intel_reset()
void techroom_init()
{
int i, idx;
int i;
techroom_buttons *b;
Ships_loaded = false;
@@ -1212,9 +1172,9 @@ void techroom_init()
Tech_slider.create(&Ui_window, Tech_slider_coords[gr_screen.res][SHIP_X_COORD], Tech_slider_coords[gr_screen.res][SHIP_Y_COORD], Tech_slider_coords[gr_screen.res][SHIP_W_COORD], Tech_slider_coords[gr_screen.res][SHIP_H_COORD], (int)Ship_info.size(), Tech_slider_filename[gr_screen.res], &tech_scroll_list_up, &tech_scroll_list_down, &tech_ship_scroll_capture);
// zero intel anim/bitmap stuff
for(idx=0; idx<Intel_list_size; idx++){
Intel_list[idx].animation.num_frames = 0;
Intel_list[idx].bitmap = -1;
for(auto & intel_item : Intel_list){
intel_item.animation.num_frames = 0;
intel_item.bitmap = -1;
}
mprintf(("Techroom successfully initialized, now changing tab...\n"));
@@ -1223,63 +1183,23 @@ void techroom_init()
void techroom_lists_reset()
{
int i;
//unload the current animation, we load another one for the new current entry
if(Tab != SHIPS_DATA_TAB)
if (Tab != SHIPS_DATA_TAB)
techroom_unload_animation();
Current_list = NULL;
Current_list_size = 0;
model_free_all();
Techroom_ship_modelnum = -1;
Techroom_ship_model_instance = -1;
if (Ship_list != NULL) {
delete[] Ship_list;
Ship_list = NULL;
}
Ship_list_size = 0;
// This can be cleared immediately because there are no anims or bitmaps associated.
Ship_list.clear();
Ships_loaded = false;
if (Weapon_list != NULL) {
for (i = 0; i < Weapon_list_size; i++) {
if (Weapon_list[i].animation.num_frames != 0) {
generic_anim_unload(&Weapon_list[i].animation);
}
if (Weapon_list[i].bitmap >= 0) {
bm_release(Weapon_list[i].bitmap);
Weapon_list[i].bitmap = -1;
}
}
delete[] Weapon_list;
Weapon_list = NULL;
}
Weapon_list_size = 0;
// now that we're sure all the bitmaps are released, clear the vectors.
Weapon_list.clear();
Weapons_loaded = false;
if (Intel_list != nullptr) {
for (i = 0; i < Intel_list_size; i++) {
if (Intel_list[i].animation.num_frames != 0) {
generic_anim_unload(&Intel_list[i].animation);
}
if (Intel_list[i].bitmap >= 0) {
bm_release(Intel_list[i].bitmap);
Intel_list[i].bitmap = -1;
}
}
delete[] Intel_list;
Intel_list = nullptr;
}
Intel_list_size = 0;
Intel_list.clear();
Intel_loaded = false;
}
+8 -10
View File
@@ -12,16 +12,14 @@
#ifndef _MODEL_H
#define _MODEL_H
#include "globalincs/globals.h" // for NAME_LENGTH
#include "globalincs/globals.h" // for NAME_LENGTH
#include "globalincs/pstypes.h"
#include "actions/Program.h"
#include "gamesnd/gamesnd.h"
#include "graphics/2d.h"
#include "gamesnd/gamesnd.h"
#include "io/timer.h"
#include "model/model_flags.h"
#include "object/object.h"
#include "ship/ship_flags.h"
#include "model/model_flags.h"
class object;
class model_render_params;
@@ -206,13 +204,13 @@ public:
//Per-turret ownage settings - SUSHI
int turret_max_bomb_ownage;
int turret_max_target_ownage;
actions::ProgramSet beam_warmdown_program;
int turret_max_target_ownage;
void reset();
model_subsystem();
model_subsystem() {
reset();
}
};
typedef struct model_special {
@@ -805,7 +803,7 @@ polymodel *model_get(int model_num);
polymodel_instance* model_get_instance(int model_instance_num);
// routine to copy susbsystems. Must be called when subsystems sets are the same -- see ship.cpp
// routine to copy subsystems. Must be called when subsystems sets are the same -- see ship.cpp
void model_copy_subsystems(int n_subsystems, model_subsystem *d_sp, model_subsystem *s_sp);
// If MR_FLAG_OUTLINE bit set this color will be used for outlines.
+55 -9
View File
@@ -462,6 +462,55 @@ void get_user_prop_value(char *buf, char *value)
*p1 = c;
}
// Stuff a floating point value pointed at by Mp.
// Advances past float characters.
int stuff_float_temp(float *f, bool optional)
{
char *str_start = Mp;
char *str_end;
// since strtof ignores white space anyway, might as well make it explicit
ignore_white_space();
auto result = strtof(Mp, &str_end);
bool success = false, comma = false;
int retval = 0;
// no float found?
if (result == 0.0f && str_end == Mp)
{
if (!optional)
error_display(1, "Expecting float, found [%.32s].\n", next_tokens());
}
else
{
*f = result;
success = true;
}
if (success)
Mp = str_end;
if (*Mp == ',')
{
comma = true;
Mp++;
}
if (optional && !success)
Mp = str_start;
if (success)
retval = 2;
else if (optional)
retval = comma ? 1 : 0;
else
skip_token();
diag_printf("Stuffed float: %f\n", *f);
return retval;
}
// routine to parse out a vec3d from a user property field of an object
bool get_user_vec3d_value(char *buf, vec3d *value, bool require_brackets)
{
@@ -494,11 +543,11 @@ bool get_user_vec3d_value(char *buf, vec3d *value, bool require_brackets)
}
// get comma-separated floats
if (stuff_float_optional(&f1) != 2)
if (stuff_float_temp(&f1, true) != 2)
break;
if (stuff_float_optional(&f2) != 2)
if (stuff_float_temp(&f2, true) != 2)
break;
if (stuff_float_optional(&f3) != 2)
if (stuff_float_temp(&f3, true) != 2)
break;
if (require_brackets)
@@ -2722,6 +2771,9 @@ int model_load(const char *filename, int n_subsystems, model_subsystem *subsyst
Assert(pm->submodel[i].num_live_debris < MAX_LIVE_DEBRIS);
pm->submodel[i].live_debris[pm->submodel[i].num_live_debris++] = j;
pm->submodel[j].is_live_debris = 1;
// make sure live debris doesn't have a parent
pm->submodel[j].parent = -1;
}
}
@@ -5565,10 +5617,4 @@ void model_subsystem::reset()
turret_max_bomb_ownage = 0;
turret_max_target_ownage = 0;
beam_warmdown_program = actions::ProgramSet();
}
model_subsystem::model_subsystem() {
reset();
}
+4 -6
View File
@@ -69,16 +69,14 @@ static bool check_for_docking_collision(object *objp1, object *objp2)
}
if (aip1->mode == AIM_DOCK) {
if (dock_check_find_docked_object(&Objects[aip1->goal_objnum], objp2)){
if (aip1->mode == AIM_DOCK && aip1->goal_objnum >= 0 && aip1->goal_objnum < MAX_OBJECTS) {
if (dock_check_find_docked_object(&Objects[aip1->goal_objnum], objp2))
return true;
}
}
if (aip2->mode == AIM_DOCK) {
if (dock_check_find_docked_object(&Objects[aip2->goal_objnum], objp1)){
if (aip2->mode == AIM_DOCK && aip2->goal_objnum >= 0 && aip2->goal_objnum < MAX_OBJECTS) {
if (dock_check_find_docked_object(&Objects[aip2->goal_objnum], objp1))
return true;
}
}
return false;
+6 -6
View File
@@ -165,22 +165,22 @@ bool SourceOrigin::isValid() const {
SourceOrientation::SourceOrientation() : m_orientation(vmd_identity_matrix) {}
void SourceOrientation::setFromVector(const vec3d& vec, bool relative) {
void SourceOrientation::setFromVector(const vec3d& vec) {
vec3d workVec = vec;
vm_vec_normalize(&workVec);
this->setFromNormalizedVector(workVec, relative);
this->setFromNormalizedVector(workVec);
}
void SourceOrientation::setFromNormalizedVector(const vec3d& vec, bool relative) {
void SourceOrientation::setFromNormalizedVector(const vec3d& vec) {
vm_vector_2_matrix_norm(&m_orientation, &vec);
m_isRelative = relative;
m_isRelative = false;
}
void SourceOrientation::setFromMatrix(const matrix& mat, bool relative) {
void SourceOrientation::setFromMatrix(const matrix& mat) {
m_orientation = mat;
m_isRelative = relative;
m_isRelative = false;
}
void SourceOrientation::setNormal(const vec3d& normal) {
+3 -3
View File
@@ -155,18 +155,18 @@ class SourceOrientation {
*
* @param vec The vector to create the matrix from
*/
void setFromVector(const vec3d& vec, bool relative = false);
void setFromVector(const vec3d& vec);
/**
* @brief Sets the direction from an already normalized vector
*
* @param vec The normalized vector
*/
void setFromNormalizedVector(const vec3d& vec, bool relative = false);
void setFromNormalizedVector(const vec3d& vec);
void setNormal(const vec3d& normal);
void setFromMatrix(const matrix& mat, bool relative = false);
void setFromMatrix(const matrix& mat);
vec3d getDirectionVector(const SourceOrigin* origin) const;
+6 -6
View File
@@ -84,28 +84,28 @@ namespace particle
}
}
void ParticleSourceWrapper::setOrientationFromNormalizedVec(vec3d* normalizedDir, bool relative)
void ParticleSourceWrapper::setOrientationFromNormalizedVec(vec3d* normalizedDir)
{
for (auto& source : m_sources)
{
source->getOrientation()->setFromNormalizedVector(*normalizedDir, relative);
source->getOrientation()->setFromNormalizedVector(*normalizedDir);
}
}
void ParticleSourceWrapper::setOrientationFromVec(vec3d* dir, bool relative)
void ParticleSourceWrapper::setOrientationFromVec(vec3d* dir)
{
for (auto& source : m_sources)
{
source->getOrientation()->setFromVector(*dir, relative);
source->getOrientation()->setFromVector(*dir);
}
}
void ParticleSourceWrapper::setOrientationMatrix(matrix* mtx, bool relative)
void ParticleSourceWrapper::setOrientationMatrix(matrix* mtx)
{
for (auto& source : m_sources)
{
source->getOrientation()->setFromMatrix(*mtx, relative);
source->getOrientation()->setFromMatrix(*mtx);
}
}
+3 -3
View File
@@ -54,11 +54,11 @@ namespace particle
void moveTo(vec3d* pos);
void setOrientationFromNormalizedVec(vec3d* normalizedDir, bool relative = false);
void setOrientationFromNormalizedVec(vec3d* normalizedDir);
void setOrientationFromVec(vec3d* dir, bool relative = false);
void setOrientationFromVec(vec3d* dir);
void setOrientationMatrix(matrix* mtx, bool relative = false);
void setOrientationMatrix(matrix* mtx);
void setOrientationNormal(vec3d* normal);
+27 -2
View File
@@ -1,7 +1,6 @@
#include "doc_parser.h"
#include "parse/parselo.h"
#include "libs/antlr/ErrorListener.h"
#undef TRUE
#undef FALSE
@@ -16,6 +15,32 @@ namespace scripting {
namespace {
struct Diagnostic {
size_t line;
size_t columnInLine;
size_t tokenLength;
SCP_string errorMessage;
};
struct ErrorListener : public antlr4::BaseErrorListener {
SCP_vector<Diagnostic> diagnostics;
void syntaxError(antlr4::Recognizer* /*recognizer*/,
antlr4::Token* offendingSymbol,
size_t line,
size_t charPositionInLine,
const std::string& msg,
std::exception_ptr /*e*/) override
{
// Apparently stop < start is a thing?
const auto left = std::min(offendingSymbol->getStartIndex(), offendingSymbol->getStopIndex());
const auto right = std::max(offendingSymbol->getStartIndex(), offendingSymbol->getStopIndex());
const auto length = right - left + 1;
diagnostics.push_back(Diagnostic{line, charPositionInLine, length, msg});
}
};
ade_type_info merge_alternatives(const ade_type_info& left, const ade_type_info& right)
{
SCP_vector<ade_type_info> elements;
@@ -344,7 +369,7 @@ bool argument_list_parser::parse(const SCP_string& argumentList)
ArgumentListParser parser(&tokens);
// By default we log to stderr which we do not want
parser.removeErrorListeners();
libs::antlr::ErrorListener errListener;
ErrorListener errListener;
parser.addErrorListener(&errListener);
antlr4::tree::ParseTree* tree = parser.arg_list();
+14 -24
View File
@@ -943,7 +943,7 @@ void ship_info::clone(const ship_info& other)
if ( other.n_subsystems > 0 ) {
if( n_subsystems < 1 ) {
subsystems = new model_subsystem[other.n_subsystems];
subsystems = (model_subsystem *)vm_malloc(sizeof(model_subsystem) * other.n_subsystems);
} else {
for ( int i = 0; i < n_subsystems; i++ ) {
for ( int j = 0; j < subsystems[i].n_triggers; j++ ) {
@@ -954,11 +954,10 @@ void ship_info::clone(const ship_info& other)
}
}
}
delete[] subsystems;
subsystems = new model_subsystem[other.n_subsystems];
subsystems = (model_subsystem *)vm_realloc(subsystems, sizeof(model_subsystem) * other.n_subsystems);
}
Assert(subsystems != nullptr);
Assert(subsystems != NULL);
for ( int i = n_subsystems; i < other.n_subsystems; i++ ) {
subsystems[i].triggers = (queued_animation*) vm_malloc(sizeof(queued_animation) * (other.subsystems[i].n_triggers));
}
@@ -1897,8 +1896,8 @@ ship_info::~ship_info()
}
}
delete[] subsystems;
subsystems = nullptr;
vm_free(subsystems);
subsystems = NULL;
}
free_strings();
@@ -4532,9 +4531,9 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
int n_subsystems = 0;
int cont_flag = 1;
model_subsystem subsystems[MAX_MODEL_SUBSYSTEMS] = {}; // see model.h for max_model_subsystems
model_subsystem subsystems[MAX_MODEL_SUBSYSTEMS]; // see model.h for max_model_subsystems
for (auto i=0; i<MAX_MODEL_SUBSYSTEMS; i++) {
subsystems[i].reset();
subsystems[i].stepped_rotation = NULL;
}
float hull_percentage_of_hits = 100.0f;
@@ -5034,8 +5033,6 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
}
}
sp->beam_warmdown_program = actions::ProgramSet::parseProgramSet("$On Beam Warmdown:",
{actions::ProgramContextFlags::HasObject, actions::ProgramContextFlags::HasSubobject});
}
break;
case 2:
@@ -5058,21 +5055,14 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
// when done reading subsystems, malloc and copy the subsystem data to the ship info structure
int orig_n_subsystems = sip->n_subsystems;
if ( n_subsystems > 0 ) {
// Let's make sure that n_subsystems is not negative
Assertion(sip->n_subsystems >= 0, "Invalid n_subsystems detected!");
auto new_n = sip->n_subsystems + n_subsystems;
std::unique_ptr<model_subsystem[]> subsys_storage(new model_subsystem[new_n]);
if(sip->n_subsystems <= 0) {
if(sip->n_subsystems < 1) {
sip->n_subsystems = n_subsystems;
} else {
// This used realloc originally so we need to copy the existing subsystems to the new storage
std::copy(sip->subsystems, sip->subsystems + sip->n_subsystems, subsys_storage.get());
sip->subsystems = (model_subsystem*)vm_malloc(sizeof(model_subsystem) * sip->n_subsystems);
} else {
sip->n_subsystems += n_subsystems;
}
sip->subsystems = subsys_storage.release();
sip->subsystems = (model_subsystem *)vm_realloc(sip->subsystems, sizeof(model_subsystem) * sip->n_subsystems);
}
Assert(sip->subsystems != NULL);
}
@@ -13338,7 +13328,7 @@ int ship_type_name_lookup(const char *name)
// Return true/false for subsystem found/not found.
// Stuff vector *pos with absolute position.
// subsysp is a pointer to the subsystem.
int get_subsystem_pos(vec3d* pos, object* objp, ship_subsys* subsysp)
int get_subsystem_pos(vec3d *pos, object *objp, ship_subsys *subsysp)
{
if (subsysp == NULL) {
*pos = objp->pos;
@@ -13346,7 +13336,7 @@ int get_subsystem_pos(vec3d* pos, object* objp, ship_subsys* subsysp)
}
Assertion(objp->type == OBJ_SHIP, "Only ships can have subsystems!");
model_subsystem* mss = subsysp->system_info;
model_subsystem *mss = subsysp->system_info;
if (mss->subobj_num == -1) {
// If it's a special point subsys, we can use its offset directly
+1 -1
View File
@@ -285,7 +285,7 @@ void shipfx_blow_off_subsystem(object *ship_objp, ship *ship_p, ship_subsys *sub
shipfx_blow_up_model(ship_objp, psub->subobj_num, 50, &subobj_pos );
// create live debris objects, if any
// TODO: some MULITPLAYER implcations here!!
// TODO: some MULTIPLAYER implcations here!!
shipfx_subsystem_maybe_create_live_debris(ship_objp, ship_p, subsys, exp_center, 1.0f);
int fireball_type = fireball_ship_explosion_type(&Ship_info[ship_p->ship_info_index]);
-67
View File
@@ -6,67 +6,6 @@ add_file_folder(""
prefix_header.h
)
add_file_folder("Actions"
actions/Action.cpp
actions/Action.h
actions/ActionDefinition.cpp
actions/ActionDefinition.h
actions/ActionDefinitionManager.cpp
actions/ActionDefinitionManager.h
actions/BuiltinActionDefinition.cpp
actions/BuiltinActionDefinition.h
actions/common.cpp
actions/common.h
actions/Program.cpp
actions/Program.h
)
add_file_folder("Actions\\\\Expression"
actions/expression/ActionExpression.cpp
actions/expression/ActionExpression.h
actions/expression/ExpressionParser.cpp
actions/expression/ExpressionParser.h
actions/expression/FunctionManager.cpp
actions/expression/FunctionManager.h
actions/expression/ParseContext.h
actions/expression/ProgramVariables.cpp
actions/expression/ProgramVariables.h
actions/expression/TypeDefinition.cpp
actions/expression/TypeDefinition.h
actions/expression/Value.cpp
actions/expression/Value.h
)
add_file_folder("Actions\\\\Expression\\\\Nodes"
actions/expression/nodes/AbstractExpression.cpp
actions/expression/nodes/AbstractExpression.h
actions/expression/nodes/FunctionCallExpression.cpp
actions/expression/nodes/FunctionCallExpression.h
actions/expression/nodes/LiteralExpression.cpp
actions/expression/nodes/LiteralExpression.h
actions/expression/nodes/RandomRangeExpression.cpp
actions/expression/nodes/RandomRangeExpression.h
actions/expression/nodes/VariableReferenceExpression.cpp
actions/expression/nodes/VariableReferenceExpression.h
actions/expression/nodes/VectorConstructorExpression.cpp
actions/expression/nodes/VectorConstructorExpression.h
)
add_file_folder("Actions\\\\Types"
actions/types/MoveToSubmodel.cpp
actions/types/MoveToSubmodel.h
actions/types/ParticleEffectAction.cpp
actions/types/ParticleEffectAction.h
actions/types/PlaySoundAction.cpp
actions/types/PlaySoundAction.h
actions/types/SetDirectionAction.cpp
actions/types/SetDirectionAction.h
actions/types/SetPositionAction.cpp
actions/types/SetPositionAction.h
actions/types/WaitAction.cpp
actions/types/WaitAction.h
)
# AI files
add_file_folder("AI"
ai/ai.cpp
@@ -698,11 +637,6 @@ add_file_folder("Libs"
libs/jansson.h
)
add_file_folder("Libs\\\\AntLR"
libs/antlr/ErrorListener.cpp
libs/antlr/ErrorListener.h
)
add_file_folder("Libs\\\\Discord"
libs/discord/discord.cpp
libs/discord/discord.h
@@ -1524,7 +1458,6 @@ add_file_folder("Utils"
utils/HeapAllocator.cpp
utils/HeapAllocator.h
utils/id.h
utils/join_string.h
utils/RandomRange.h
utils/string_utils.cpp
utils/string_utils.h
+3 -28
View File
@@ -5,35 +5,10 @@ using namespace tracing;
namespace tracing {
MonitorBase::MonitorBase(const char* name) : _name(name), _tracing_cat(name, false) {}
void MonitorBase::valueChanged(float newVal)
{
MonitorBase::MonitorBase(const char* name) : _name(name), _tracing_cat(name, false) {
}
void MonitorBase::valueChanged(float newVal) {
tracing::counter::value(_tracing_cat, newVal);
}
RunningCounter::RunningCounter(Monitor<int>& monitor) : _monitor(monitor)
{
_monitor += 1;
}
RunningCounter::~RunningCounter()
{
_monitor -= 1;
}
RunningCounter::RunningCounter(const RunningCounter& other) : _monitor(other._monitor)
{
_monitor += 1;
}
RunningCounter& RunningCounter::operator=(const RunningCounter&)
{
return *this;
}
RunningCounter::RunningCounter(RunningCounter&& other) noexcept : _monitor(other._monitor)
{
_monitor += 1;
}
RunningCounter& RunningCounter::operator=(RunningCounter&&) noexcept
{
return *this;
}
} // namespace tracing
+1 -18
View File
@@ -58,24 +58,7 @@ class Monitor: public MonitorBase {
}
};
/**
* @brief Class that keeps track of how many operations are currently running
*/
class RunningCounter {
Monitor<int>& _monitor;
public:
explicit RunningCounter(Monitor<int>& monitor);
~RunningCounter();
RunningCounter(const RunningCounter&);
RunningCounter& operator=(const RunningCounter&);
RunningCounter(RunningCounter&&) noexcept;
RunningCounter& operator=(RunningCounter&&) noexcept;
};
} // namespace tracing
}
// Creates a monitor variable
#define MONITOR(function_name) static ::tracing::Monitor<int> mon_##function_name(#function_name, 0);
-2
View File
@@ -143,6 +143,4 @@ Category RenderDecals("Render all decals", true);
Category RenderSingleDecal("Render single decal", true);
Category GpuHeapAllocate("GPU heap allocate", false);
Category GpuHeapDeallocate("GPU heap deallocate", false);
Category ProgramStepOne("Step one program", false);
}
-2
View File
@@ -159,8 +159,6 @@ extern Category RenderSingleDecal;
extern Category GpuHeapAllocate;
extern Category GpuHeapDeallocate;
extern Category ProgramStepOne;
}
#endif // _TRACING_CATEGORIES_H
+1 -1
View File
@@ -46,7 +46,7 @@ public:
return stream;
}
inline bool isValid() const { return m_val != default_value; }
inline bool isValid() { return m_val != default_value; }
private:
Impl m_val;
-29
View File
@@ -1,29 +0,0 @@
#pragma once
namespace util {
template <typename TIter>
SCP_string join_range(TIter&& begin, TIter&& end, const SCP_string& joiner)
{
SCP_stringstream stream;
bool first = true;
for (auto iter = begin; iter != end; ++iter) {
stream << *iter;
if (first) {
first = false;
} else {
stream << joiner;
}
}
return stream.str();
}
template <typename TContainer>
SCP_string join_container(TContainer& container, const SCP_string& joiner)
{
return join_range(std::begin(container), std::end(container), joiner);
}
} // namespace util
-8
View File
@@ -2006,14 +2006,6 @@ void beam_start_warmdown(beam *b)
snd_stop(b->beam_sound_loop);
b->beam_sound_loop = sound_handle::invalid();
}
if (b->subsys != nullptr) {
// Starts the warmdown program if it exists
b->subsys->system_info->beam_warmdown_program.start(b->objp,
&vmd_zero_vector,
&vmd_identity_matrix,
b->subsys->system_info->subobj_num);
}
}
// recalculate beam sounds (looping sounds relative to the player)
+5 -9
View File
@@ -14,17 +14,15 @@
#include "globalincs/globals.h"
#include "globalincs/systemvars.h"
#include "actions/Program.h"
#include "decals/decals.h"
#include "gamesnd/gamesnd.h"
#include "graphics/2d.h"
#include "graphics/generic.h"
#include "gamesnd/gamesnd.h"
#include "model/model.h"
#include "particle/ParticleManager.h"
#include "weapon/shockwave.h"
#include "weapon/trails.h"
#include "particle/ParticleManager.h"
#include "weapon/weapon_flags.h"
#include "decals/decals.h"
class object;
class ship_subsys;
@@ -514,8 +512,6 @@ struct weapon_info
decals::creation_info impact_decal;
actions::ProgramSet on_create_program;
public:
weapon_info();
@@ -680,8 +676,8 @@ void shield_impact_explosion(vec3d *hitpos, object *objp, float radius, int idx)
// Swifty - return number of max simultaneous locks
int weapon_get_max_missile_seekers(weapon_info *wip);
// return if this weapon can lock on this ship, based on its type, class, species or iff
bool weapon_can_lock_on_ship(weapon_info *wip, int ship_num);
// return if this weapon can lock on this target, based on its type, class, species or iff
bool weapon_target_satisfies_lock_restrictions(weapon_info *wip, object* target);
// return if this weapon has iff restrictions, and should ignore normal iff targeting restrictions
bool weapon_has_iff_restrictions(weapon_info* wip);
+14 -40
View File
@@ -3012,19 +3012,6 @@ int parse_weapon(int subtype, bool replace, const char *filename)
}
}
// This only works with lasters and missiles for now
if (wip->subtype == WP_MISSILE || wip->subtype == WP_LASER) {
// We always have an object we are attached to
flagset<actions::ProgramContextFlags> contexts{actions::ProgramContextFlags::HasObject};
if (wip->render_type == WRT_POF) {
// We will render with a model so we can have subobejcts
contexts.set(actions::ProgramContextFlags::HasSubobject, true);
}
wip->on_create_program = actions::ProgramSet::parseProgramSet("$On Create:", contexts);
}
/* Generate a substitution pattern for this weapon.
This pattern is very naive such that it calculates the lowest common denominator as being all of
the periods multiplied together.
@@ -4106,9 +4093,8 @@ void find_homing_object(object *weapon_objp, int num)
continue;
homing_object_team = obj_team(objp);
bool can_lock_on_ship = objp->type != OBJ_SHIP || weapon_can_lock_on_ship(wip, objp->instance);
bool can_attack = weapon_has_iff_restrictions(wip) || iff_x_attacks_y(wp->team, homing_object_team);
if (can_lock_on_ship && can_attack)
if (weapon_target_satisfies_lock_restrictions(wip, objp) && can_attack)
{
if ( objp->type == OBJ_SHIP )
{
@@ -5366,13 +5352,9 @@ void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_o
if ( parent_objp == NULL || Ships[parent_objp->instance].ai_index >= 0 ) {
int target_team = -1;
int target_ship_num = -1;
if ( target_objnum >= 0 ) {
int obj_type = Objects[target_objnum].type;
if (obj_type == OBJ_SHIP)
target_ship_num = Objects[target_objnum].instance;
if ( (obj_type == OBJ_SHIP) || (obj_type == OBJ_WEAPON) ) {
target_team = obj_team(&Objects[target_objnum]);
@@ -5394,7 +5376,7 @@ void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_o
targeting_same = 0;
}
bool can_lock = weapon_has_iff_restrictions(wip) && target_ship_num >= 0 ? weapon_can_lock_on_ship(wip, target_ship_num) :
bool can_lock = (weapon_has_iff_restrictions(wip) && target_objnum >= 0) ? weapon_target_satisfies_lock_restrictions(wip, &Objects[target_objnum]) :
(!targeting_same || (MULTI_DOGFIGHT && (target_team == Iff_traitor)));
// Cyborg17 - exclude all invalid object numbers here since in multi, the lock slots can get out of sync.
@@ -5777,8 +5759,10 @@ int weapon_create( vec3d * pos, matrix * porient, int weapon_type, int parent_ob
objp->radius = model_get_radius(wip->model_num);
// Always create an instance in case we need them
wp->model_instance_num = model_create_instance(false, wip->model_num);
// if we intrinsic-rotate, make sure we have a model instance
if (model_get(wip->model_num)->flags & PM_FLAG_HAS_INTRINSIC_ROTATE) {
wp->model_instance_num = model_create_instance(false, wip->model_num);
}
} else if ( wip->render_type == WRT_LASER ) {
objp->radius = wip->laser_head_radius;
}
@@ -5959,17 +5943,6 @@ int weapon_create( vec3d * pos, matrix * porient, int weapon_type, int parent_ob
weapon_update_state(wp);
if (wip->render_type == WRT_LASER) {
// No model so we also have no submodel
wip->on_create_program.start(&Objects[objnum], &vmd_zero_vector, &vmd_identity_matrix, -1);
} else if (wip->render_type == WRT_POF) {
// We have a model so we can specify a subobject
wip->on_create_program.start(&Objects[objnum],
&vmd_zero_vector,
&vmd_identity_matrix,
model_get(wip->model_num)->detail[0]);
}
Script_system.SetHookObject("Weapon", &Objects[objnum]);
Script_system.RunCondition(CHA_ONWEAPONCREATED);
Script_system.RemHookVar("Weapon");
@@ -8383,8 +8356,6 @@ void weapon_info::reset()
// Reset using default constructor
this->impact_decal = decals::creation_info();
this->on_create_program = actions::ProgramSet();
}
const char* weapon_info::get_display_name() const
@@ -8715,16 +8686,19 @@ int weapon_get_max_missile_seekers(weapon_info *wip)
}
// returns whether a homing weapon can home on a particular ship
bool weapon_can_lock_on_ship(weapon_info* wip, int ship_num)
bool weapon_target_satisfies_lock_restrictions(weapon_info* wip, object* target)
{
if (target->type != OBJ_SHIP)
return true;
auto& restrictions = wip->ship_restrict;
// if you didn't specify any restrictions, you can always lock
if (restrictions.empty()) return true;
int type_num = Ship_info[Ships[ship_num].ship_info_index].class_type;
int class_num = Ships[ship_num].ship_info_index;
int species_num = Ship_info[Ships[ship_num].ship_info_index].species;
int iff_num = Ships[ship_num].team;
int type_num = Ship_info[Ships[target->instance].ship_info_index].class_type;
int class_num = Ships[target->instance].ship_info_index;
int species_num = Ship_info[Ships[target->instance].ship_info_index].species;
int iff_num = Ships[target->instance].team;
// otherwise, you're good as long as it matches one of the allowances in the restriction list
return std::any_of(restrictions.begin(), restrictions.end(),
-2
View File
@@ -48,5 +48,3 @@ include(antlr4.cmake)
include(vulkan.cmake)
add_subdirectory(mdns)
add_subdirectory(variant)
-5
View File
@@ -1,5 +0,0 @@
add_library(variant INTERFACE)
target_include_directories(variant SYSTEM INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
-23
View File
@@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
File diff suppressed because it is too large. Load diff
+1 -6
View File
@@ -1,12 +1,7 @@
find_program(GLSLC_PATH glslc)
# Add an option for this so that this can be disabled locally when not needed
option(SHADERS_ENABLE_COMPILATION "Enable compilation of shaders to SPIR-V" OFF)
mark_as_advanced(SHADERS_ENABLE_COMPILATION)
if (SHADERS_ENABLE_COMPILATION AND GLSLC_PATH)
if (GLSLC_PATH)
if(PLATFORM_WINDOWS)
set(SHADERTOOL_FILENAME "shadertool-windows.tar.gz")
elseif(PLATFORM_LINUX)
+18 -33
View File
@@ -1,35 +1,4 @@
function(add_parser filename)
get_filename_component(_name "${filename}" NAME_WE)
get_filename_component(_absolutePath "${filename}" ABSOLUTE)
get_filename_component(_directory "${_absolutePath}" DIRECTORY)
get_filename_component(_directoryName "${_directory}" NAME)
if (ANTLR_FOUND)
antlr_target(${_name} "${_absolutePath}"
VISITOR
OUTPUT_DIRECTORY "${_directory}/generated")
target_sources(parsers PRIVATE "${_absolutePath}")
source_group("${_directoryName}" FILES "${_absolutePath}")
else()
# Otherwise we just use the ones that are checked in
set(ANTLR_${_name}_OUTPUTS
${_directory}/generated/${_name}BaseVisitor.cpp
${_directory}/generated/${_name}BaseVisitor.h
${_directory}/generated/${_name}Lexer.cpp
${_directory}/generated/${_name}Lexer.h
${_directory}/generated/${_name}Parser.cpp
${_directory}/generated/${_name}Parser.h
${_directory}/generated/${_name}Visitor.cpp
${_directory}/generated/${_name}Visitor.h
)
endif()
target_sources(parsers PRIVATE ${ANTLR_${_name}_OUTPUTS})
source_group("${_directoryName}\\generated" FILES ${ANTLR_${_name}_OUTPUTS})
endfunction()
add_library(parsers STATIC)
target_link_libraries(parsers PUBLIC antlr4_static)
@@ -39,12 +8,28 @@ find_package(ANTLR)
if (ANTLR_FOUND)
# If we have an ANTLR installation then we can generate new sources
message(STATUS "Using ANTLR to generate parser")
antlr_target(ArgumentList "${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/ArgumentList.g4"
VISITOR
OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated")
target_sources(parsers PRIVATE "arg_parser/ArgumentList.g4")
source_group("arg_parser" FILES "arg_parser\\ArgumentList.g4")
else()
# Otherwise we just use the ones that are checked in
message(STATUS "Using generated ANTLR files")
set(ANTLR_ArgumentList_OUTPUTS
${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated/ArgumentListBaseVisitor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated/ArgumentListBaseVisitor.h
${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated/ArgumentListLexer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated/ArgumentListLexer.h
${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated/ArgumentListParser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated/ArgumentListParser.h
${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated/ArgumentListVisitor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/arg_parser/generated/ArgumentListVisitor.h
)
endif()
add_parser(arg_parser/ArgumentList.g4)
add_parser(action_expression/ActionExpression.g4)
target_sources(parsers PRIVATE ${ANTLR_ArgumentList_OUTPUTS})
source_group("arg_parser\\generated" FILES ${ANTLR_ArgumentList_OUTPUTS})
target_include_directories(parsers PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -1,61 +0,0 @@
grammar ActionExpression;
expression_main: expression EOF;
expression
: value_expression
| random_range_expression
| parenthesis_expression
| variable_reference_expression
| expression ( PLUS | MINUS ) expression
;
parenthesis_expression: L_PAREN expression R_PAREN;
value_expression
: literal_expression
| vec3d_constructor
;
literal_expression
: FLOAT
| INT
| STRING
;
// variable references are just a list of identifiers instead of being applied to expressions to avoid introducing types
// for all the intermediate parts
variable_reference_expression: IDENTIFIER (DOT IDENTIFIER)*;
random_range_expression: RAND_L_PAREN expression expression R_PAREN;
vec3d_constructor: L_PAREN expression expression expression R_PAREN;
PLUS: '+';
MINUS: '-';
FLOAT
: '-'? ([0-9]+ '.' [0-9]+)
;
INT: '-'? [0-9]+;
// The left parenthesis for the start of a random range
RAND_L_PAREN: '~(';
L_PAREN: '(';
R_PAREN: ')';
IDENTIFIER: [a-zA-Z][a-zA-Z0-9]*;
DOT: '.';
STRING: '"' .*? '"';
SPACE
: [ \t\r\n] -> skip
;
OTHER
: .
;
@@ -1,43 +0,0 @@
token literal names:
null
'+'
'-'
null
null
'~('
'('
')'
null
'.'
null
null
null
token symbolic names:
null
PLUS
MINUS
FLOAT
INT
RAND_L_PAREN
L_PAREN
R_PAREN
IDENTIFIER
DOT
STRING
SPACE
OTHER
rule names:
expression_main
expression
parenthesis_expression
value_expression
literal_expression
variable_reference_expression
random_range_expression
vec3d_constructor
atn:
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 14, 66, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 27, 10, 3, 3, 3, 3, 3, 3, 3, 7, 3, 32, 10, 3, 12, 3, 14, 3, 35, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 5, 5, 43, 10, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 7, 7, 50, 10, 7, 12, 7, 14, 7, 53, 11, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 2, 3, 4, 10, 2, 4, 6, 8, 10, 12, 14, 16, 2, 4, 3, 2, 3, 4, 4, 2, 5, 6, 12, 12, 2, 63, 2, 18, 3, 2, 2, 2, 4, 26, 3, 2, 2, 2, 6, 36, 3, 2, 2, 2, 8, 42, 3, 2, 2, 2, 10, 44, 3, 2, 2, 2, 12, 46, 3, 2, 2, 2, 14, 54, 3, 2, 2, 2, 16, 59, 3, 2, 2, 2, 18, 19, 5, 4, 3, 2, 19, 20, 7, 2, 2, 3, 20, 3, 3, 2, 2, 2, 21, 22, 8, 3, 1, 2, 22, 27, 5, 8, 5, 2, 23, 27, 5, 14, 8, 2, 24, 27, 5, 6, 4, 2, 25, 27, 5, 12, 7, 2, 26, 21, 3, 2, 2, 2, 26, 23, 3, 2, 2, 2, 26, 24, 3, 2, 2, 2, 26, 25, 3, 2, 2, 2, 27, 33, 3, 2, 2, 2, 28, 29, 12, 3, 2, 2, 29, 30, 9, 2, 2, 2, 30, 32, 5, 4, 3, 4, 31, 28, 3, 2, 2, 2, 32, 35, 3, 2, 2, 2, 33, 31, 3, 2, 2, 2, 33, 34, 3, 2, 2, 2, 34, 5, 3, 2, 2, 2, 35, 33, 3, 2, 2, 2, 36, 37, 7, 8, 2, 2, 37, 38, 5, 4, 3, 2, 38, 39, 7, 9, 2, 2, 39, 7, 3, 2, 2, 2, 40, 43, 5, 10, 6, 2, 41, 43, 5, 16, 9, 2, 42, 40, 3, 2, 2, 2, 42, 41, 3, 2, 2, 2, 43, 9, 3, 2, 2, 2, 44, 45, 9, 3, 2, 2, 45, 11, 3, 2, 2, 2, 46, 51, 7, 10, 2, 2, 47, 48, 7, 11, 2, 2, 48, 50, 7, 10, 2, 2, 49, 47, 3, 2, 2, 2, 50, 53, 3, 2, 2, 2, 51, 49, 3, 2, 2, 2, 51, 52, 3, 2, 2, 2, 52, 13, 3, 2, 2, 2, 53, 51, 3, 2, 2, 2, 54, 55, 7, 7, 2, 2, 55, 56, 5, 4, 3, 2, 56, 57, 5, 4, 3, 2, 57, 58, 7, 9, 2, 2, 58, 15, 3, 2, 2, 2, 59, 60, 7, 8, 2, 2, 60, 61, 5, 4, 3, 2, 61, 62, 5, 4, 3, 2, 62, 63, 5, 4, 3, 2, 63, 64, 7, 9, 2, 2, 64, 17, 3, 2, 2, 2, 6, 26, 33, 42, 51]
@@ -1,18 +0,0 @@
PLUS=1
MINUS=2
FLOAT=3
INT=4
RAND_L_PAREN=5
L_PAREN=6
R_PAREN=7
IDENTIFIER=8
DOT=9
STRING=10
SPACE=11
OTHER=12
'+'=1
'-'=2
'~('=5
'('=6
')'=7
'.'=9
@@ -1,7 +0,0 @@
// Generated from /media/cache/code/asarium/fs2open.github.com/parsers/action_expression/ActionExpression.g4 by ANTLR 4.8
#include "ActionExpressionBaseVisitor.h"
@@ -1,52 +0,0 @@
// Generated from /media/cache/code/asarium/fs2open.github.com/parsers/action_expression/ActionExpression.g4 by ANTLR 4.8
#pragma once
#include "antlr4-runtime.h"
#include "ActionExpressionVisitor.h"
/**
* This class provides an empty implementation of ActionExpressionVisitor, which can be
* extended to create a visitor which only needs to handle a subset of the available methods.
*/
class ActionExpressionBaseVisitor : public ActionExpressionVisitor {
public:
virtual antlrcpp::Any visitExpression_main(ActionExpressionParser::Expression_mainContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitExpression(ActionExpressionParser::ExpressionContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitParenthesis_expression(ActionExpressionParser::Parenthesis_expressionContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitValue_expression(ActionExpressionParser::Value_expressionContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitLiteral_expression(ActionExpressionParser::Literal_expressionContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitVariable_reference_expression(ActionExpressionParser::Variable_reference_expressionContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitRandom_range_expression(ActionExpressionParser::Random_range_expressionContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitVec3d_constructor(ActionExpressionParser::Vec3d_constructorContext *ctx) override {
return visitChildren(ctx);
}
};
@@ -1,176 +0,0 @@
// Generated from /media/cache/code/asarium/fs2open.github.com/parsers/action_expression/ActionExpression.g4 by ANTLR 4.8
#include "ActionExpressionLexer.h"
using namespace antlr4;
ActionExpressionLexer::ActionExpressionLexer(CharStream *input) : Lexer(input) {
_interpreter = new atn::LexerATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache);
}
ActionExpressionLexer::~ActionExpressionLexer() {
delete _interpreter;
}
std::string ActionExpressionLexer::getGrammarFileName() const {
return "ActionExpression.g4";
}
const std::vector<std::string>& ActionExpressionLexer::getRuleNames() const {
return _ruleNames;
}
const std::vector<std::string>& ActionExpressionLexer::getChannelNames() const {
return _channelNames;
}
const std::vector<std::string>& ActionExpressionLexer::getModeNames() const {
return _modeNames;
}
const std::vector<std::string>& ActionExpressionLexer::getTokenNames() const {
return _tokenNames;
}
dfa::Vocabulary& ActionExpressionLexer::getVocabulary() const {
return _vocabulary;
}
const std::vector<uint16_t> ActionExpressionLexer::getSerializedATN() const {
return _serializedATN;
}
const atn::ATN& ActionExpressionLexer::getATN() const {
return _atn;
}
// Static vars and initialization.
std::vector<dfa::DFA> ActionExpressionLexer::_decisionToDFA;
atn::PredictionContextCache ActionExpressionLexer::_sharedContextCache;
// We own the ATN which in turn owns the ATN states.
atn::ATN ActionExpressionLexer::_atn;
std::vector<uint16_t> ActionExpressionLexer::_serializedATN;
std::vector<std::string> ActionExpressionLexer::_ruleNames = {
u8"PLUS", u8"MINUS", u8"FLOAT", u8"INT", u8"RAND_L_PAREN", u8"L_PAREN",
u8"R_PAREN", u8"IDENTIFIER", u8"DOT", u8"STRING", u8"SPACE", u8"OTHER"
};
std::vector<std::string> ActionExpressionLexer::_channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
std::vector<std::string> ActionExpressionLexer::_modeNames = {
u8"DEFAULT_MODE"
};
std::vector<std::string> ActionExpressionLexer::_literalNames = {
"", u8"'+'", u8"'-'", "", "", u8"'~('", u8"'('", u8"')'", "", u8"'.'"
};
std::vector<std::string> ActionExpressionLexer::_symbolicNames = {
"", u8"PLUS", u8"MINUS", u8"FLOAT", u8"INT", u8"RAND_L_PAREN", u8"L_PAREN",
u8"R_PAREN", u8"IDENTIFIER", u8"DOT", u8"STRING", u8"SPACE", u8"OTHER"
};
dfa::Vocabulary ActionExpressionLexer::_vocabulary(_literalNames, _symbolicNames);
std::vector<std::string> ActionExpressionLexer::_tokenNames;
ActionExpressionLexer::Initializer::Initializer() {
// This code could be in a static initializer lambda, but VS doesn't allow access to private class members from there.
for (size_t i = 0; i < _symbolicNames.size(); ++i) {
std::string name = _vocabulary.getLiteralName(i);
if (name.empty()) {
name = _vocabulary.getSymbolicName(i);
}
if (name.empty()) {
_tokenNames.push_back("<INVALID>");
} else {
_tokenNames.push_back(name);
}
}
_serializedATN = {
0x3, 0x608b, 0xa72a, 0x8133, 0xb9ed, 0x417c, 0x3be7, 0x7786, 0x5964,
0x2, 0xe, 0x54, 0x8, 0x1, 0x4, 0x2, 0x9, 0x2, 0x4, 0x3, 0x9, 0x3, 0x4,
0x4, 0x9, 0x4, 0x4, 0x5, 0x9, 0x5, 0x4, 0x6, 0x9, 0x6, 0x4, 0x7, 0x9,
0x7, 0x4, 0x8, 0x9, 0x8, 0x4, 0x9, 0x9, 0x9, 0x4, 0xa, 0x9, 0xa, 0x4,
0xb, 0x9, 0xb, 0x4, 0xc, 0x9, 0xc, 0x4, 0xd, 0x9, 0xd, 0x3, 0x2, 0x3,
0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x5, 0x4, 0x21, 0xa, 0x4, 0x3, 0x4,
0x6, 0x4, 0x24, 0xa, 0x4, 0xd, 0x4, 0xe, 0x4, 0x25, 0x3, 0x4, 0x3, 0x4,
0x6, 0x4, 0x2a, 0xa, 0x4, 0xd, 0x4, 0xe, 0x4, 0x2b, 0x3, 0x5, 0x5, 0x5,
0x2f, 0xa, 0x5, 0x3, 0x5, 0x6, 0x5, 0x32, 0xa, 0x5, 0xd, 0x5, 0xe, 0x5,
0x33, 0x3, 0x6, 0x3, 0x6, 0x3, 0x6, 0x3, 0x7, 0x3, 0x7, 0x3, 0x8, 0x3,
0x8, 0x3, 0x9, 0x3, 0x9, 0x7, 0x9, 0x3f, 0xa, 0x9, 0xc, 0x9, 0xe, 0x9,
0x42, 0xb, 0x9, 0x3, 0xa, 0x3, 0xa, 0x3, 0xb, 0x3, 0xb, 0x7, 0xb, 0x48,
0xa, 0xb, 0xc, 0xb, 0xe, 0xb, 0x4b, 0xb, 0xb, 0x3, 0xb, 0x3, 0xb, 0x3,
0xc, 0x3, 0xc, 0x3, 0xc, 0x3, 0xc, 0x3, 0xd, 0x3, 0xd, 0x3, 0x49, 0x2,
0xe, 0x3, 0x3, 0x5, 0x4, 0x7, 0x5, 0x9, 0x6, 0xb, 0x7, 0xd, 0x8, 0xf,
0x9, 0x11, 0xa, 0x13, 0xb, 0x15, 0xc, 0x17, 0xd, 0x19, 0xe, 0x3, 0x2,
0x6, 0x3, 0x2, 0x32, 0x3b, 0x4, 0x2, 0x43, 0x5c, 0x63, 0x7c, 0x5, 0x2,
0x32, 0x3b, 0x43, 0x5c, 0x63, 0x7c, 0x5, 0x2, 0xb, 0xc, 0xf, 0xf, 0x22,
0x22, 0x2, 0x5a, 0x2, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x5, 0x3, 0x2, 0x2,
0x2, 0x2, 0x7, 0x3, 0x2, 0x2, 0x2, 0x2, 0x9, 0x3, 0x2, 0x2, 0x2, 0x2,
0xb, 0x3, 0x2, 0x2, 0x2, 0x2, 0xd, 0x3, 0x2, 0x2, 0x2, 0x2, 0xf, 0x3,
0x2, 0x2, 0x2, 0x2, 0x11, 0x3, 0x2, 0x2, 0x2, 0x2, 0x13, 0x3, 0x2, 0x2,
0x2, 0x2, 0x15, 0x3, 0x2, 0x2, 0x2, 0x2, 0x17, 0x3, 0x2, 0x2, 0x2, 0x2,
0x19, 0x3, 0x2, 0x2, 0x2, 0x3, 0x1b, 0x3, 0x2, 0x2, 0x2, 0x5, 0x1d,
0x3, 0x2, 0x2, 0x2, 0x7, 0x20, 0x3, 0x2, 0x2, 0x2, 0x9, 0x2e, 0x3, 0x2,
0x2, 0x2, 0xb, 0x35, 0x3, 0x2, 0x2, 0x2, 0xd, 0x38, 0x3, 0x2, 0x2, 0x2,
0xf, 0x3a, 0x3, 0x2, 0x2, 0x2, 0x11, 0x3c, 0x3, 0x2, 0x2, 0x2, 0x13,
0x43, 0x3, 0x2, 0x2, 0x2, 0x15, 0x45, 0x3, 0x2, 0x2, 0x2, 0x17, 0x4e,
0x3, 0x2, 0x2, 0x2, 0x19, 0x52, 0x3, 0x2, 0x2, 0x2, 0x1b, 0x1c, 0x7,
0x2d, 0x2, 0x2, 0x1c, 0x4, 0x3, 0x2, 0x2, 0x2, 0x1d, 0x1e, 0x7, 0x2f,
0x2, 0x2, 0x1e, 0x6, 0x3, 0x2, 0x2, 0x2, 0x1f, 0x21, 0x7, 0x2f, 0x2,
0x2, 0x20, 0x1f, 0x3, 0x2, 0x2, 0x2, 0x20, 0x21, 0x3, 0x2, 0x2, 0x2,
0x21, 0x23, 0x3, 0x2, 0x2, 0x2, 0x22, 0x24, 0x9, 0x2, 0x2, 0x2, 0x23,
0x22, 0x3, 0x2, 0x2, 0x2, 0x24, 0x25, 0x3, 0x2, 0x2, 0x2, 0x25, 0x23,
0x3, 0x2, 0x2, 0x2, 0x25, 0x26, 0x3, 0x2, 0x2, 0x2, 0x26, 0x27, 0x3,
0x2, 0x2, 0x2, 0x27, 0x29, 0x7, 0x30, 0x2, 0x2, 0x28, 0x2a, 0x9, 0x2,
0x2, 0x2, 0x29, 0x28, 0x3, 0x2, 0x2, 0x2, 0x2a, 0x2b, 0x3, 0x2, 0x2,
0x2, 0x2b, 0x29, 0x3, 0x2, 0x2, 0x2, 0x2b, 0x2c, 0x3, 0x2, 0x2, 0x2,
0x2c, 0x8, 0x3, 0x2, 0x2, 0x2, 0x2d, 0x2f, 0x7, 0x2f, 0x2, 0x2, 0x2e,
0x2d, 0x3, 0x2, 0x2, 0x2, 0x2e, 0x2f, 0x3, 0x2, 0x2, 0x2, 0x2f, 0x31,
0x3, 0x2, 0x2, 0x2, 0x30, 0x32, 0x9, 0x2, 0x2, 0x2, 0x31, 0x30, 0x3,
0x2, 0x2, 0x2, 0x32, 0x33, 0x3, 0x2, 0x2, 0x2, 0x33, 0x31, 0x3, 0x2,
0x2, 0x2, 0x33, 0x34, 0x3, 0x2, 0x2, 0x2, 0x34, 0xa, 0x3, 0x2, 0x2,
0x2, 0x35, 0x36, 0x7, 0x80, 0x2, 0x2, 0x36, 0x37, 0x7, 0x2a, 0x2, 0x2,
0x37, 0xc, 0x3, 0x2, 0x2, 0x2, 0x38, 0x39, 0x7, 0x2a, 0x2, 0x2, 0x39,
0xe, 0x3, 0x2, 0x2, 0x2, 0x3a, 0x3b, 0x7, 0x2b, 0x2, 0x2, 0x3b, 0x10,
0x3, 0x2, 0x2, 0x2, 0x3c, 0x40, 0x9, 0x3, 0x2, 0x2, 0x3d, 0x3f, 0x9,
0x4, 0x2, 0x2, 0x3e, 0x3d, 0x3, 0x2, 0x2, 0x2, 0x3f, 0x42, 0x3, 0x2,
0x2, 0x2, 0x40, 0x3e, 0x3, 0x2, 0x2, 0x2, 0x40, 0x41, 0x3, 0x2, 0x2,
0x2, 0x41, 0x12, 0x3, 0x2, 0x2, 0x2, 0x42, 0x40, 0x3, 0x2, 0x2, 0x2,
0x43, 0x44, 0x7, 0x30, 0x2, 0x2, 0x44, 0x14, 0x3, 0x2, 0x2, 0x2, 0x45,
0x49, 0x7, 0x24, 0x2, 0x2, 0x46, 0x48, 0xb, 0x2, 0x2, 0x2, 0x47, 0x46,
0x3, 0x2, 0x2, 0x2, 0x48, 0x4b, 0x3, 0x2, 0x2, 0x2, 0x49, 0x4a, 0x3,
0x2, 0x2, 0x2, 0x49, 0x47, 0x3, 0x2, 0x2, 0x2, 0x4a, 0x4c, 0x3, 0x2,
0x2, 0x2, 0x4b, 0x49, 0x3, 0x2, 0x2, 0x2, 0x4c, 0x4d, 0x7, 0x24, 0x2,
0x2, 0x4d, 0x16, 0x3, 0x2, 0x2, 0x2, 0x4e, 0x4f, 0x9, 0x5, 0x2, 0x2,
0x4f, 0x50, 0x3, 0x2, 0x2, 0x2, 0x50, 0x51, 0x8, 0xc, 0x2, 0x2, 0x51,
0x18, 0x3, 0x2, 0x2, 0x2, 0x52, 0x53, 0xb, 0x2, 0x2, 0x2, 0x53, 0x1a,
0x3, 0x2, 0x2, 0x2, 0xa, 0x2, 0x20, 0x25, 0x2b, 0x2e, 0x33, 0x40, 0x49,
0x3, 0x8, 0x2, 0x2,
};
atn::ATNDeserializer deserializer;
_atn = deserializer.deserialize(_serializedATN);
size_t count = _atn.getNumberOfDecisions();
_decisionToDFA.reserve(count);
for (size_t i = 0; i < count; i++) {
_decisionToDFA.emplace_back(_atn.getDecisionState(i), i);
}
}
ActionExpressionLexer::Initializer ActionExpressionLexer::_init;
@@ -1,57 +0,0 @@
// Generated from /media/cache/code/asarium/fs2open.github.com/parsers/action_expression/ActionExpression.g4 by ANTLR 4.8
#pragma once
#include "antlr4-runtime.h"
class ActionExpressionLexer : public antlr4::Lexer {
public:
enum {
PLUS = 1, MINUS = 2, FLOAT = 3, INT = 4, RAND_L_PAREN = 5, L_PAREN = 6,
R_PAREN = 7, IDENTIFIER = 8, DOT = 9, STRING = 10, SPACE = 11, OTHER = 12
};
ActionExpressionLexer(antlr4::CharStream *input);
~ActionExpressionLexer();
virtual std::string getGrammarFileName() const override;
virtual const std::vector<std::string>& getRuleNames() const override;
virtual const std::vector<std::string>& getChannelNames() const override;
virtual const std::vector<std::string>& getModeNames() const override;
virtual const std::vector<std::string>& getTokenNames() const override; // deprecated, use vocabulary instead
virtual antlr4::dfa::Vocabulary& getVocabulary() const override;
virtual const std::vector<uint16_t> getSerializedATN() const override;
virtual const antlr4::atn::ATN& getATN() const override;
private:
static std::vector<antlr4::dfa::DFA> _decisionToDFA;
static antlr4::atn::PredictionContextCache _sharedContextCache;
static std::vector<std::string> _ruleNames;
static std::vector<std::string> _tokenNames;
static std::vector<std::string> _channelNames;
static std::vector<std::string> _modeNames;
static std::vector<std::string> _literalNames;
static std::vector<std::string> _symbolicNames;
static antlr4::dfa::Vocabulary _vocabulary;
static antlr4::atn::ATN _atn;
static std::vector<uint16_t> _serializedATN;
// Individual action functions triggered by action() above.
// Individual semantic predicate functions triggered by sempred() above.
struct Initializer {
Initializer();
};
static Initializer _init;
};
@@ -1,53 +0,0 @@
token literal names:
null
'+'
'-'
null
null
'~('
'('
')'
null
'.'
null
null
null
token symbolic names:
null
PLUS
MINUS
FLOAT
INT
RAND_L_PAREN
L_PAREN
R_PAREN
IDENTIFIER
DOT
STRING
SPACE
OTHER
rule names:
PLUS
MINUS
FLOAT
INT
RAND_L_PAREN
L_PAREN
R_PAREN
IDENTIFIER
DOT
STRING
SPACE
OTHER
channel names:
DEFAULT_TOKEN_CHANNEL
HIDDEN
mode names:
DEFAULT_MODE
atn:
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 14, 84, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 5, 4, 33, 10, 4, 3, 4, 6, 4, 36, 10, 4, 13, 4, 14, 4, 37, 3, 4, 3, 4, 6, 4, 42, 10, 4, 13, 4, 14, 4, 43, 3, 5, 5, 5, 47, 10, 5, 3, 5, 6, 5, 50, 10, 5, 13, 5, 14, 5, 51, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 7, 9, 63, 10, 9, 12, 9, 14, 9, 66, 11, 9, 3, 10, 3, 10, 3, 11, 3, 11, 7, 11, 72, 10, 11, 12, 11, 14, 11, 75, 11, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 73, 2, 14, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 3, 2, 6, 3, 2, 50, 59, 4, 2, 67, 92, 99, 124, 5, 2, 50, 59, 67, 92, 99, 124, 5, 2, 11, 12, 15, 15, 34, 34, 2, 90, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 3, 27, 3, 2, 2, 2, 5, 29, 3, 2, 2, 2, 7, 32, 3, 2, 2, 2, 9, 46, 3, 2, 2, 2, 11, 53, 3, 2, 2, 2, 13, 56, 3, 2, 2, 2, 15, 58, 3, 2, 2, 2, 17, 60, 3, 2, 2, 2, 19, 67, 3, 2, 2, 2, 21, 69, 3, 2, 2, 2, 23, 78, 3, 2, 2, 2, 25, 82, 3, 2, 2, 2, 27, 28, 7, 45, 2, 2, 28, 4, 3, 2, 2, 2, 29, 30, 7, 47, 2, 2, 30, 6, 3, 2, 2, 2, 31, 33, 7, 47, 2, 2, 32, 31, 3, 2, 2, 2, 32, 33, 3, 2, 2, 2, 33, 35, 3, 2, 2, 2, 34, 36, 9, 2, 2, 2, 35, 34, 3, 2, 2, 2, 36, 37, 3, 2, 2, 2, 37, 35, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 39, 3, 2, 2, 2, 39, 41, 7, 48, 2, 2, 40, 42, 9, 2, 2, 2, 41, 40, 3, 2, 2, 2, 42, 43, 3, 2, 2, 2, 43, 41, 3, 2, 2, 2, 43, 44, 3, 2, 2, 2, 44, 8, 3, 2, 2, 2, 45, 47, 7, 47, 2, 2, 46, 45, 3, 2, 2, 2, 46, 47, 3, 2, 2, 2, 47, 49, 3, 2, 2, 2, 48, 50, 9, 2, 2, 2, 49, 48, 3, 2, 2, 2, 50, 51, 3, 2, 2, 2, 51, 49, 3, 2, 2, 2, 51, 52, 3, 2, 2, 2, 52, 10, 3, 2, 2, 2, 53, 54, 7, 128, 2, 2, 54, 55, 7, 42, 2, 2, 55, 12, 3, 2, 2, 2, 56, 57, 7, 42, 2, 2, 57, 14, 3, 2, 2, 2, 58, 59, 7, 43, 2, 2, 59, 16, 3, 2, 2, 2, 60, 64, 9, 3, 2, 2, 61, 63, 9, 4, 2, 2, 62, 61, 3, 2, 2, 2, 63, 66, 3, 2, 2, 2, 64, 62, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 65, 18, 3, 2, 2, 2, 66, 64, 3, 2, 2, 2, 67, 68, 7, 48, 2, 2, 68, 20, 3, 2, 2, 2, 69, 73, 7, 36, 2, 2, 70, 72, 11, 2, 2, 2, 71, 70, 3, 2, 2, 2, 72, 75, 3, 2, 2, 2, 73, 74, 3, 2, 2, 2, 73, 71, 3, 2, 2, 2, 74, 76, 3, 2, 2, 2, 75, 73, 3, 2, 2, 2, 76, 77, 7, 36, 2, 2, 77, 22, 3, 2, 2, 2, 78, 79, 9, 5, 2, 2, 79, 80, 3, 2, 2, 2, 80, 81, 8, 12, 2, 2, 81, 24, 3, 2, 2, 2, 82, 83, 11, 2, 2, 2, 83, 26, 3, 2, 2, 2, 10, 2, 32, 37, 43, 46, 51, 64, 73, 3, 8, 2, 2]
@@ -1,18 +0,0 @@
PLUS=1
MINUS=2
FLOAT=3
INT=4
RAND_L_PAREN=5
L_PAREN=6
R_PAREN=7
IDENTIFIER=8
DOT=9
STRING=10
SPACE=11
OTHER=12
'+'=1
'-'=2
'~('=5
'('=6
')'=7
'.'=9
@@ -1,732 +0,0 @@
// Generated from /media/cache/code/asarium/fs2open.github.com/parsers/action_expression/ActionExpression.g4 by ANTLR 4.8
#include "ActionExpressionVisitor.h"
#include "ActionExpressionParser.h"
using namespace antlrcpp;
using namespace antlr4;
ActionExpressionParser::ActionExpressionParser(TokenStream *input) : Parser(input) {
_interpreter = new atn::ParserATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache);
}
ActionExpressionParser::~ActionExpressionParser() {
delete _interpreter;
}
std::string ActionExpressionParser::getGrammarFileName() const {
return "ActionExpression.g4";
}
const std::vector<std::string>& ActionExpressionParser::getRuleNames() const {
return _ruleNames;
}
dfa::Vocabulary& ActionExpressionParser::getVocabulary() const {
return _vocabulary;
}
//----------------- Expression_mainContext ------------------------------------------------------------------
ActionExpressionParser::Expression_mainContext::Expression_mainContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
ActionExpressionParser::ExpressionContext* ActionExpressionParser::Expression_mainContext::expression() {
return getRuleContext<ActionExpressionParser::ExpressionContext>(0);
}
tree::TerminalNode* ActionExpressionParser::Expression_mainContext::EOF() {
return getToken(ActionExpressionParser::EOF, 0);
}
size_t ActionExpressionParser::Expression_mainContext::getRuleIndex() const {
return ActionExpressionParser::RuleExpression_main;
}
antlrcpp::Any ActionExpressionParser::Expression_mainContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<ActionExpressionVisitor*>(visitor))
return parserVisitor->visitExpression_main(this);
else
return visitor->visitChildren(this);
}
ActionExpressionParser::Expression_mainContext* ActionExpressionParser::expression_main() {
Expression_mainContext *_localctx = _tracker.createInstance<Expression_mainContext>(_ctx, getState());
enterRule(_localctx, 0, ActionExpressionParser::RuleExpression_main);
auto onExit = finally([=] {
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(16);
expression(0);
setState(17);
match(ActionExpressionParser::EOF);
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- ExpressionContext ------------------------------------------------------------------
ActionExpressionParser::ExpressionContext::ExpressionContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
ActionExpressionParser::Value_expressionContext* ActionExpressionParser::ExpressionContext::value_expression() {
return getRuleContext<ActionExpressionParser::Value_expressionContext>(0);
}
ActionExpressionParser::Random_range_expressionContext* ActionExpressionParser::ExpressionContext::random_range_expression() {
return getRuleContext<ActionExpressionParser::Random_range_expressionContext>(0);
}
ActionExpressionParser::Parenthesis_expressionContext* ActionExpressionParser::ExpressionContext::parenthesis_expression() {
return getRuleContext<ActionExpressionParser::Parenthesis_expressionContext>(0);
}
ActionExpressionParser::Variable_reference_expressionContext* ActionExpressionParser::ExpressionContext::variable_reference_expression() {
return getRuleContext<ActionExpressionParser::Variable_reference_expressionContext>(0);
}
std::vector<ActionExpressionParser::ExpressionContext *> ActionExpressionParser::ExpressionContext::expression() {
return getRuleContexts<ActionExpressionParser::ExpressionContext>();
}
ActionExpressionParser::ExpressionContext* ActionExpressionParser::ExpressionContext::expression(size_t i) {
return getRuleContext<ActionExpressionParser::ExpressionContext>(i);
}
tree::TerminalNode* ActionExpressionParser::ExpressionContext::PLUS() {
return getToken(ActionExpressionParser::PLUS, 0);
}
tree::TerminalNode* ActionExpressionParser::ExpressionContext::MINUS() {
return getToken(ActionExpressionParser::MINUS, 0);
}
size_t ActionExpressionParser::ExpressionContext::getRuleIndex() const {
return ActionExpressionParser::RuleExpression;
}
antlrcpp::Any ActionExpressionParser::ExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<ActionExpressionVisitor*>(visitor))
return parserVisitor->visitExpression(this);
else
return visitor->visitChildren(this);
}
ActionExpressionParser::ExpressionContext* ActionExpressionParser::expression() {
return expression(0);
}
ActionExpressionParser::ExpressionContext* ActionExpressionParser::expression(int precedence) {
ParserRuleContext *parentContext = _ctx;
size_t parentState = getState();
ActionExpressionParser::ExpressionContext *_localctx = _tracker.createInstance<ExpressionContext>(_ctx, parentState);
ActionExpressionParser::ExpressionContext *previousContext = _localctx;
(void)previousContext; // Silence compiler, in case the context is not used by generated code.
size_t startState = 2;
enterRecursionRule(_localctx, 2, ActionExpressionParser::RuleExpression, precedence);
size_t _la = 0;
auto onExit = finally([=] {
unrollRecursionContexts(parentContext);
});
try {
size_t alt;
enterOuterAlt(_localctx, 1);
setState(24);
_errHandler->sync(this);
switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 0, _ctx)) {
case 1: {
setState(20);
value_expression();
break;
}
case 2: {
setState(21);
random_range_expression();
break;
}
case 3: {
setState(22);
parenthesis_expression();
break;
}
case 4: {
setState(23);
variable_reference_expression();
break;
}
}
_ctx->stop = _input->LT(-1);
setState(31);
_errHandler->sync(this);
alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 1, _ctx);
while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
if (alt == 1) {
if (!_parseListeners.empty())
triggerExitRuleEvent();
previousContext = _localctx;
_localctx = _tracker.createInstance<ExpressionContext>(parentContext, parentState);
pushNewRecursionContext(_localctx, startState, RuleExpression);
setState(26);
if (!(precpred(_ctx, 1))) throw FailedPredicateException(this, "precpred(_ctx, 1)");
setState(27);
_la = _input->LA(1);
if (!(_la == ActionExpressionParser::PLUS
|| _la == ActionExpressionParser::MINUS)) {
_errHandler->recoverInline(this);
}
else {
_errHandler->reportMatch(this);
consume();
}
setState(28);
expression(2);
}
setState(33);
_errHandler->sync(this);
alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 1, _ctx);
}
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- Parenthesis_expressionContext ------------------------------------------------------------------
ActionExpressionParser::Parenthesis_expressionContext::Parenthesis_expressionContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* ActionExpressionParser::Parenthesis_expressionContext::L_PAREN() {
return getToken(ActionExpressionParser::L_PAREN, 0);
}
ActionExpressionParser::ExpressionContext* ActionExpressionParser::Parenthesis_expressionContext::expression() {
return getRuleContext<ActionExpressionParser::ExpressionContext>(0);
}
tree::TerminalNode* ActionExpressionParser::Parenthesis_expressionContext::R_PAREN() {
return getToken(ActionExpressionParser::R_PAREN, 0);
}
size_t ActionExpressionParser::Parenthesis_expressionContext::getRuleIndex() const {
return ActionExpressionParser::RuleParenthesis_expression;
}
antlrcpp::Any ActionExpressionParser::Parenthesis_expressionContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<ActionExpressionVisitor*>(visitor))
return parserVisitor->visitParenthesis_expression(this);
else
return visitor->visitChildren(this);
}
ActionExpressionParser::Parenthesis_expressionContext* ActionExpressionParser::parenthesis_expression() {
Parenthesis_expressionContext *_localctx = _tracker.createInstance<Parenthesis_expressionContext>(_ctx, getState());
enterRule(_localctx, 4, ActionExpressionParser::RuleParenthesis_expression);
auto onExit = finally([=] {
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(34);
match(ActionExpressionParser::L_PAREN);
setState(35);
expression(0);
setState(36);
match(ActionExpressionParser::R_PAREN);
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- Value_expressionContext ------------------------------------------------------------------
ActionExpressionParser::Value_expressionContext::Value_expressionContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
ActionExpressionParser::Literal_expressionContext* ActionExpressionParser::Value_expressionContext::literal_expression() {
return getRuleContext<ActionExpressionParser::Literal_expressionContext>(0);
}
ActionExpressionParser::Vec3d_constructorContext* ActionExpressionParser::Value_expressionContext::vec3d_constructor() {
return getRuleContext<ActionExpressionParser::Vec3d_constructorContext>(0);
}
size_t ActionExpressionParser::Value_expressionContext::getRuleIndex() const {
return ActionExpressionParser::RuleValue_expression;
}
antlrcpp::Any ActionExpressionParser::Value_expressionContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<ActionExpressionVisitor*>(visitor))
return parserVisitor->visitValue_expression(this);
else
return visitor->visitChildren(this);
}
ActionExpressionParser::Value_expressionContext* ActionExpressionParser::value_expression() {
Value_expressionContext *_localctx = _tracker.createInstance<Value_expressionContext>(_ctx, getState());
enterRule(_localctx, 6, ActionExpressionParser::RuleValue_expression);
auto onExit = finally([=] {
exitRule();
});
try {
setState(40);
_errHandler->sync(this);
switch (_input->LA(1)) {
case ActionExpressionParser::FLOAT:
case ActionExpressionParser::INT:
case ActionExpressionParser::STRING: {
enterOuterAlt(_localctx, 1);
setState(38);
literal_expression();
break;
}
case ActionExpressionParser::L_PAREN: {
enterOuterAlt(_localctx, 2);
setState(39);
vec3d_constructor();
break;
}
default:
throw NoViableAltException(this);
}
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- Literal_expressionContext ------------------------------------------------------------------
ActionExpressionParser::Literal_expressionContext::Literal_expressionContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* ActionExpressionParser::Literal_expressionContext::FLOAT() {
return getToken(ActionExpressionParser::FLOAT, 0);
}
tree::TerminalNode* ActionExpressionParser::Literal_expressionContext::INT() {
return getToken(ActionExpressionParser::INT, 0);
}
tree::TerminalNode* ActionExpressionParser::Literal_expressionContext::STRING() {
return getToken(ActionExpressionParser::STRING, 0);
}
size_t ActionExpressionParser::Literal_expressionContext::getRuleIndex() const {
return ActionExpressionParser::RuleLiteral_expression;
}
antlrcpp::Any ActionExpressionParser::Literal_expressionContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<ActionExpressionVisitor*>(visitor))
return parserVisitor->visitLiteral_expression(this);
else
return visitor->visitChildren(this);
}
ActionExpressionParser::Literal_expressionContext* ActionExpressionParser::literal_expression() {
Literal_expressionContext *_localctx = _tracker.createInstance<Literal_expressionContext>(_ctx, getState());
enterRule(_localctx, 8, ActionExpressionParser::RuleLiteral_expression);
size_t _la = 0;
auto onExit = finally([=] {
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(42);
_la = _input->LA(1);
if (!((((_la & ~ 0x3fULL) == 0) &&
((1ULL << _la) & ((1ULL << ActionExpressionParser::FLOAT)
| (1ULL << ActionExpressionParser::INT)
| (1ULL << ActionExpressionParser::STRING))) != 0))) {
_errHandler->recoverInline(this);
}
else {
_errHandler->reportMatch(this);
consume();
}
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- Variable_reference_expressionContext ------------------------------------------------------------------
ActionExpressionParser::Variable_reference_expressionContext::Variable_reference_expressionContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
std::vector<tree::TerminalNode *> ActionExpressionParser::Variable_reference_expressionContext::IDENTIFIER() {
return getTokens(ActionExpressionParser::IDENTIFIER);
}
tree::TerminalNode* ActionExpressionParser::Variable_reference_expressionContext::IDENTIFIER(size_t i) {
return getToken(ActionExpressionParser::IDENTIFIER, i);
}
std::vector<tree::TerminalNode *> ActionExpressionParser::Variable_reference_expressionContext::DOT() {
return getTokens(ActionExpressionParser::DOT);
}
tree::TerminalNode* ActionExpressionParser::Variable_reference_expressionContext::DOT(size_t i) {
return getToken(ActionExpressionParser::DOT, i);
}
size_t ActionExpressionParser::Variable_reference_expressionContext::getRuleIndex() const {
return ActionExpressionParser::RuleVariable_reference_expression;
}
antlrcpp::Any ActionExpressionParser::Variable_reference_expressionContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<ActionExpressionVisitor*>(visitor))
return parserVisitor->visitVariable_reference_expression(this);
else
return visitor->visitChildren(this);
}
ActionExpressionParser::Variable_reference_expressionContext* ActionExpressionParser::variable_reference_expression() {
Variable_reference_expressionContext *_localctx = _tracker.createInstance<Variable_reference_expressionContext>(_ctx, getState());
enterRule(_localctx, 10, ActionExpressionParser::RuleVariable_reference_expression);
auto onExit = finally([=] {
exitRule();
});
try {
size_t alt;
enterOuterAlt(_localctx, 1);
setState(44);
match(ActionExpressionParser::IDENTIFIER);
setState(49);
_errHandler->sync(this);
alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 3, _ctx);
while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
if (alt == 1) {
setState(45);
match(ActionExpressionParser::DOT);
setState(46);
match(ActionExpressionParser::IDENTIFIER);
}
setState(51);
_errHandler->sync(this);
alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 3, _ctx);
}
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- Random_range_expressionContext ------------------------------------------------------------------
ActionExpressionParser::Random_range_expressionContext::Random_range_expressionContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* ActionExpressionParser::Random_range_expressionContext::RAND_L_PAREN() {
return getToken(ActionExpressionParser::RAND_L_PAREN, 0);
}
std::vector<ActionExpressionParser::ExpressionContext *> ActionExpressionParser::Random_range_expressionContext::expression() {
return getRuleContexts<ActionExpressionParser::ExpressionContext>();
}
ActionExpressionParser::ExpressionContext* ActionExpressionParser::Random_range_expressionContext::expression(size_t i) {
return getRuleContext<ActionExpressionParser::ExpressionContext>(i);
}
tree::TerminalNode* ActionExpressionParser::Random_range_expressionContext::R_PAREN() {
return getToken(ActionExpressionParser::R_PAREN, 0);
}
size_t ActionExpressionParser::Random_range_expressionContext::getRuleIndex() const {
return ActionExpressionParser::RuleRandom_range_expression;
}
antlrcpp::Any ActionExpressionParser::Random_range_expressionContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<ActionExpressionVisitor*>(visitor))
return parserVisitor->visitRandom_range_expression(this);
else
return visitor->visitChildren(this);
}
ActionExpressionParser::Random_range_expressionContext* ActionExpressionParser::random_range_expression() {
Random_range_expressionContext *_localctx = _tracker.createInstance<Random_range_expressionContext>(_ctx, getState());
enterRule(_localctx, 12, ActionExpressionParser::RuleRandom_range_expression);
auto onExit = finally([=] {
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(52);
match(ActionExpressionParser::RAND_L_PAREN);
setState(53);
expression(0);
setState(54);
expression(0);
setState(55);
match(ActionExpressionParser::R_PAREN);
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- Vec3d_constructorContext ------------------------------------------------------------------
ActionExpressionParser::Vec3d_constructorContext::Vec3d_constructorContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* ActionExpressionParser::Vec3d_constructorContext::L_PAREN() {
return getToken(ActionExpressionParser::L_PAREN, 0);
}
std::vector<ActionExpressionParser::ExpressionContext *> ActionExpressionParser::Vec3d_constructorContext::expression() {
return getRuleContexts<ActionExpressionParser::ExpressionContext>();
}
ActionExpressionParser::ExpressionContext* ActionExpressionParser::Vec3d_constructorContext::expression(size_t i) {
return getRuleContext<ActionExpressionParser::ExpressionContext>(i);
}
tree::TerminalNode* ActionExpressionParser::Vec3d_constructorContext::R_PAREN() {
return getToken(ActionExpressionParser::R_PAREN, 0);
}
size_t ActionExpressionParser::Vec3d_constructorContext::getRuleIndex() const {
return ActionExpressionParser::RuleVec3d_constructor;
}
antlrcpp::Any ActionExpressionParser::Vec3d_constructorContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<ActionExpressionVisitor*>(visitor))
return parserVisitor->visitVec3d_constructor(this);
else
return visitor->visitChildren(this);
}
ActionExpressionParser::Vec3d_constructorContext* ActionExpressionParser::vec3d_constructor() {
Vec3d_constructorContext *_localctx = _tracker.createInstance<Vec3d_constructorContext>(_ctx, getState());
enterRule(_localctx, 14, ActionExpressionParser::RuleVec3d_constructor);
auto onExit = finally([=] {
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(57);
match(ActionExpressionParser::L_PAREN);
setState(58);
expression(0);
setState(59);
expression(0);
setState(60);
expression(0);
setState(61);
match(ActionExpressionParser::R_PAREN);
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
bool ActionExpressionParser::sempred(RuleContext *context, size_t ruleIndex, size_t predicateIndex) {
switch (ruleIndex) {
case 1: return expressionSempred(dynamic_cast<ExpressionContext *>(context), predicateIndex);
default:
break;
}
return true;
}
bool ActionExpressionParser::expressionSempred(ExpressionContext *_localctx, size_t predicateIndex) {
switch (predicateIndex) {
case 0: return precpred(_ctx, 1);
default:
break;
}
return true;
}
// Static vars and initialization.
std::vector<dfa::DFA> ActionExpressionParser::_decisionToDFA;
atn::PredictionContextCache ActionExpressionParser::_sharedContextCache;
// We own the ATN which in turn owns the ATN states.
atn::ATN ActionExpressionParser::_atn;
std::vector<uint16_t> ActionExpressionParser::_serializedATN;
std::vector<std::string> ActionExpressionParser::_ruleNames = {
"expression_main", "expression", "parenthesis_expression", "value_expression",
"literal_expression", "variable_reference_expression", "random_range_expression",
"vec3d_constructor"
};
std::vector<std::string> ActionExpressionParser::_literalNames = {
"", "'+'", "'-'", "", "", "'~('", "'('", "')'", "", "'.'"
};
std::vector<std::string> ActionExpressionParser::_symbolicNames = {
"", "PLUS", "MINUS", "FLOAT", "INT", "RAND_L_PAREN", "L_PAREN", "R_PAREN",
"IDENTIFIER", "DOT", "STRING", "SPACE", "OTHER"
};
dfa::Vocabulary ActionExpressionParser::_vocabulary(_literalNames, _symbolicNames);
std::vector<std::string> ActionExpressionParser::_tokenNames;
ActionExpressionParser::Initializer::Initializer() {
for (size_t i = 0; i < _symbolicNames.size(); ++i) {
std::string name = _vocabulary.getLiteralName(i);
if (name.empty()) {
name = _vocabulary.getSymbolicName(i);
}
if (name.empty()) {
_tokenNames.push_back("<INVALID>");
} else {
_tokenNames.push_back(name);
}
}
_serializedATN = {
0x3, 0x608b, 0xa72a, 0x8133, 0xb9ed, 0x417c, 0x3be7, 0x7786, 0x5964,
0x3, 0xe, 0x42, 0x4, 0x2, 0x9, 0x2, 0x4, 0x3, 0x9, 0x3, 0x4, 0x4, 0x9,
0x4, 0x4, 0x5, 0x9, 0x5, 0x4, 0x6, 0x9, 0x6, 0x4, 0x7, 0x9, 0x7, 0x4,
0x8, 0x9, 0x8, 0x4, 0x9, 0x9, 0x9, 0x3, 0x2, 0x3, 0x2, 0x3, 0x2, 0x3,
0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x5, 0x3, 0x1b, 0xa, 0x3,
0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x7, 0x3, 0x20, 0xa, 0x3, 0xc, 0x3, 0xe,
0x3, 0x23, 0xb, 0x3, 0x3, 0x4, 0x3, 0x4, 0x3, 0x4, 0x3, 0x4, 0x3, 0x5,
0x3, 0x5, 0x5, 0x5, 0x2b, 0xa, 0x5, 0x3, 0x6, 0x3, 0x6, 0x3, 0x7, 0x3,
0x7, 0x3, 0x7, 0x7, 0x7, 0x32, 0xa, 0x7, 0xc, 0x7, 0xe, 0x7, 0x35, 0xb,
0x7, 0x3, 0x8, 0x3, 0x8, 0x3, 0x8, 0x3, 0x8, 0x3, 0x8, 0x3, 0x9, 0x3,
0x9, 0x3, 0x9, 0x3, 0x9, 0x3, 0x9, 0x3, 0x9, 0x3, 0x9, 0x2, 0x3, 0x4,
0xa, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x10, 0x2, 0x4, 0x3, 0x2, 0x3,
0x4, 0x4, 0x2, 0x5, 0x6, 0xc, 0xc, 0x2, 0x3f, 0x2, 0x12, 0x3, 0x2, 0x2,
0x2, 0x4, 0x1a, 0x3, 0x2, 0x2, 0x2, 0x6, 0x24, 0x3, 0x2, 0x2, 0x2, 0x8,
0x2a, 0x3, 0x2, 0x2, 0x2, 0xa, 0x2c, 0x3, 0x2, 0x2, 0x2, 0xc, 0x2e,
0x3, 0x2, 0x2, 0x2, 0xe, 0x36, 0x3, 0x2, 0x2, 0x2, 0x10, 0x3b, 0x3,
0x2, 0x2, 0x2, 0x12, 0x13, 0x5, 0x4, 0x3, 0x2, 0x13, 0x14, 0x7, 0x2,
0x2, 0x3, 0x14, 0x3, 0x3, 0x2, 0x2, 0x2, 0x15, 0x16, 0x8, 0x3, 0x1,
0x2, 0x16, 0x1b, 0x5, 0x8, 0x5, 0x2, 0x17, 0x1b, 0x5, 0xe, 0x8, 0x2,
0x18, 0x1b, 0x5, 0x6, 0x4, 0x2, 0x19, 0x1b, 0x5, 0xc, 0x7, 0x2, 0x1a,
0x15, 0x3, 0x2, 0x2, 0x2, 0x1a, 0x17, 0x3, 0x2, 0x2, 0x2, 0x1a, 0x18,
0x3, 0x2, 0x2, 0x2, 0x1a, 0x19, 0x3, 0x2, 0x2, 0x2, 0x1b, 0x21, 0x3,
0x2, 0x2, 0x2, 0x1c, 0x1d, 0xc, 0x3, 0x2, 0x2, 0x1d, 0x1e, 0x9, 0x2,
0x2, 0x2, 0x1e, 0x20, 0x5, 0x4, 0x3, 0x4, 0x1f, 0x1c, 0x3, 0x2, 0x2,
0x2, 0x20, 0x23, 0x3, 0x2, 0x2, 0x2, 0x21, 0x1f, 0x3, 0x2, 0x2, 0x2,
0x21, 0x22, 0x3, 0x2, 0x2, 0x2, 0x22, 0x5, 0x3, 0x2, 0x2, 0x2, 0x23,
0x21, 0x3, 0x2, 0x2, 0x2, 0x24, 0x25, 0x7, 0x8, 0x2, 0x2, 0x25, 0x26,
0x5, 0x4, 0x3, 0x2, 0x26, 0x27, 0x7, 0x9, 0x2, 0x2, 0x27, 0x7, 0x3,
0x2, 0x2, 0x2, 0x28, 0x2b, 0x5, 0xa, 0x6, 0x2, 0x29, 0x2b, 0x5, 0x10,
0x9, 0x2, 0x2a, 0x28, 0x3, 0x2, 0x2, 0x2, 0x2a, 0x29, 0x3, 0x2, 0x2,
0x2, 0x2b, 0x9, 0x3, 0x2, 0x2, 0x2, 0x2c, 0x2d, 0x9, 0x3, 0x2, 0x2,
0x2d, 0xb, 0x3, 0x2, 0x2, 0x2, 0x2e, 0x33, 0x7, 0xa, 0x2, 0x2, 0x2f,
0x30, 0x7, 0xb, 0x2, 0x2, 0x30, 0x32, 0x7, 0xa, 0x2, 0x2, 0x31, 0x2f,
0x3, 0x2, 0x2, 0x2, 0x32, 0x35, 0x3, 0x2, 0x2, 0x2, 0x33, 0x31, 0x3,
0x2, 0x2, 0x2, 0x33, 0x34, 0x3, 0x2, 0x2, 0x2, 0x34, 0xd, 0x3, 0x2,
0x2, 0x2, 0x35, 0x33, 0x3, 0x2, 0x2, 0x2, 0x36, 0x37, 0x7, 0x7, 0x2,
0x2, 0x37, 0x38, 0x5, 0x4, 0x3, 0x2, 0x38, 0x39, 0x5, 0x4, 0x3, 0x2,
0x39, 0x3a, 0x7, 0x9, 0x2, 0x2, 0x3a, 0xf, 0x3, 0x2, 0x2, 0x2, 0x3b,
0x3c, 0x7, 0x8, 0x2, 0x2, 0x3c, 0x3d, 0x5, 0x4, 0x3, 0x2, 0x3d, 0x3e,
0x5, 0x4, 0x3, 0x2, 0x3e, 0x3f, 0x5, 0x4, 0x3, 0x2, 0x3f, 0x40, 0x7,
0x9, 0x2, 0x2, 0x40, 0x11, 0x3, 0x2, 0x2, 0x2, 0x6, 0x1a, 0x21, 0x2a,
0x33,
};
atn::ATNDeserializer deserializer;
_atn = deserializer.deserialize(_serializedATN);
size_t count = _atn.getNumberOfDecisions();
_decisionToDFA.reserve(count);
for (size_t i = 0; i < count; i++) {
_decisionToDFA.emplace_back(_atn.getDecisionState(i), i);
}
}
ActionExpressionParser::Initializer ActionExpressionParser::_init;
@@ -1,192 +0,0 @@
// Generated from /media/cache/code/asarium/fs2open.github.com/parsers/action_expression/ActionExpression.g4 by ANTLR 4.8
#pragma once
#include "antlr4-runtime.h"
class ActionExpressionParser : public antlr4::Parser {
public:
enum {
PLUS = 1, MINUS = 2, FLOAT = 3, INT = 4, RAND_L_PAREN = 5, L_PAREN = 6,
R_PAREN = 7, IDENTIFIER = 8, DOT = 9, STRING = 10, SPACE = 11, OTHER = 12
};
enum {
RuleExpression_main = 0, RuleExpression = 1, RuleParenthesis_expression = 2,
RuleValue_expression = 3, RuleLiteral_expression = 4, RuleVariable_reference_expression = 5,
RuleRandom_range_expression = 6, RuleVec3d_constructor = 7
};
ActionExpressionParser(antlr4::TokenStream *input);
~ActionExpressionParser();
virtual std::string getGrammarFileName() const override;
virtual const antlr4::atn::ATN& getATN() const override { return _atn; };
virtual const std::vector<std::string>& getTokenNames() const override { return _tokenNames; }; // deprecated: use vocabulary instead.
virtual const std::vector<std::string>& getRuleNames() const override;
virtual antlr4::dfa::Vocabulary& getVocabulary() const override;
class Expression_mainContext;
class ExpressionContext;
class Parenthesis_expressionContext;
class Value_expressionContext;
class Literal_expressionContext;
class Variable_reference_expressionContext;
class Random_range_expressionContext;
class Vec3d_constructorContext;
class Expression_mainContext : public antlr4::ParserRuleContext {
public:
Expression_mainContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
ExpressionContext *expression();
antlr4::tree::TerminalNode *EOF();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
Expression_mainContext* expression_main();
class ExpressionContext : public antlr4::ParserRuleContext {
public:
ExpressionContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
Value_expressionContext *value_expression();
Random_range_expressionContext *random_range_expression();
Parenthesis_expressionContext *parenthesis_expression();
Variable_reference_expressionContext *variable_reference_expression();
std::vector<ExpressionContext *> expression();
ExpressionContext* expression(size_t i);
antlr4::tree::TerminalNode *PLUS();
antlr4::tree::TerminalNode *MINUS();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ExpressionContext* expression();
ExpressionContext* expression(int precedence);
class Parenthesis_expressionContext : public antlr4::ParserRuleContext {
public:
Parenthesis_expressionContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *L_PAREN();
ExpressionContext *expression();
antlr4::tree::TerminalNode *R_PAREN();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
Parenthesis_expressionContext* parenthesis_expression();
class Value_expressionContext : public antlr4::ParserRuleContext {
public:
Value_expressionContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
Literal_expressionContext *literal_expression();
Vec3d_constructorContext *vec3d_constructor();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
Value_expressionContext* value_expression();
class Literal_expressionContext : public antlr4::ParserRuleContext {
public:
Literal_expressionContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *FLOAT();
antlr4::tree::TerminalNode *INT();
antlr4::tree::TerminalNode *STRING();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
Literal_expressionContext* literal_expression();
class Variable_reference_expressionContext : public antlr4::ParserRuleContext {
public:
Variable_reference_expressionContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<antlr4::tree::TerminalNode *> IDENTIFIER();
antlr4::tree::TerminalNode* IDENTIFIER(size_t i);
std::vector<antlr4::tree::TerminalNode *> DOT();
antlr4::tree::TerminalNode* DOT(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
Variable_reference_expressionContext* variable_reference_expression();
class Random_range_expressionContext : public antlr4::ParserRuleContext {
public:
Random_range_expressionContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *RAND_L_PAREN();
std::vector<ExpressionContext *> expression();
ExpressionContext* expression(size_t i);
antlr4::tree::TerminalNode *R_PAREN();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
Random_range_expressionContext* random_range_expression();
class Vec3d_constructorContext : public antlr4::ParserRuleContext {
public:
Vec3d_constructorContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *L_PAREN();
std::vector<ExpressionContext *> expression();
ExpressionContext* expression(size_t i);
antlr4::tree::TerminalNode *R_PAREN();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
Vec3d_constructorContext* vec3d_constructor();
virtual bool sempred(antlr4::RuleContext *_localctx, size_t ruleIndex, size_t predicateIndex) override;
bool expressionSempred(ExpressionContext *_localctx, size_t predicateIndex);
private:
static std::vector<antlr4::dfa::DFA> _decisionToDFA;
static antlr4::atn::PredictionContextCache _sharedContextCache;
static std::vector<std::string> _ruleNames;
static std::vector<std::string> _tokenNames;
static std::vector<std::string> _literalNames;
static std::vector<std::string> _symbolicNames;
static antlr4::dfa::Vocabulary _vocabulary;
static antlr4::atn::ATN _atn;
static std::vector<uint16_t> _serializedATN;
struct Initializer {
Initializer();
};
static Initializer _init;
};
@@ -1,7 +0,0 @@
// Generated from /media/cache/code/asarium/fs2open.github.com/parsers/action_expression/ActionExpression.g4 by ANTLR 4.8
#include "ActionExpressionVisitor.h"
@@ -1,40 +0,0 @@
// Generated from /media/cache/code/asarium/fs2open.github.com/parsers/action_expression/ActionExpression.g4 by ANTLR 4.8
#pragma once
#include "antlr4-runtime.h"
#include "ActionExpressionParser.h"
/**
* This class defines an abstract visitor for a parse tree
* produced by ActionExpressionParser.
*/
class ActionExpressionVisitor : public antlr4::tree::AbstractParseTreeVisitor {
public:
/**
* Visit parse trees produced by ActionExpressionParser.
*/
virtual antlrcpp::Any visitExpression_main(ActionExpressionParser::Expression_mainContext *context) = 0;
virtual antlrcpp::Any visitExpression(ActionExpressionParser::ExpressionContext *context) = 0;
virtual antlrcpp::Any visitParenthesis_expression(ActionExpressionParser::Parenthesis_expressionContext *context) = 0;
virtual antlrcpp::Any visitValue_expression(ActionExpressionParser::Value_expressionContext *context) = 0;
virtual antlrcpp::Any visitLiteral_expression(ActionExpressionParser::Literal_expressionContext *context) = 0;
virtual antlrcpp::Any visitVariable_reference_expression(ActionExpressionParser::Variable_reference_expressionContext *context) = 0;
virtual antlrcpp::Any visitRandom_range_expression(ActionExpressionParser::Random_range_expressionContext *context) = 0;
virtual antlrcpp::Any visitVec3d_constructor(ActionExpressionParser::Vec3d_constructorContext *context) = 0;
};
Loaded 100 of 143 files, more files were not shown because too many files have changed in this diff. Show more