mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 17:48:46 -10:00
Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52200d9668 | ||
|
|
85a2a8f11e | ||
|
|
e76fdea8b9 | ||
|
|
726ce953c7 | ||
|
|
a545a4ec27 | ||
|
|
fc0662a9c4 | ||
|
|
e5685ded86 | ||
|
|
226cbf1204 | ||
|
|
043466309a | ||
|
|
766624600d | ||
|
|
dab9a41f45 | ||
|
|
51d8ab13d8 | ||
|
|
b93d30e12b | ||
|
|
945db25578 | ||
|
|
67de007ecb | ||
|
|
e9a9b3b978 | ||
|
|
e10522a2c7 | ||
|
|
9f33b432fc | ||
|
|
7a0578a797 | ||
|
|
b81825326c | ||
|
|
b8c2c975c0 | ||
|
|
dc0272e664 | ||
|
|
3e329d64dd | ||
|
|
882ac2b1a1 |
No files matched your search
@@ -8,7 +8,6 @@ env:
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-5, gcc-10, clang-9]
|
||||
|
||||
@@ -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 ..
|
||||
@@ -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})
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
#include "Action.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
Action::~Action() = default;
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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),
|
||||
[¶meterExpressions](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
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
#include "BuiltinActionDefinition.h"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -159,8 +159,6 @@ extern Category RenderSingleDecal;
|
||||
extern Category GpuHeapAllocate;
|
||||
extern Category GpuHeapDeallocate;
|
||||
|
||||
extern Category ProgramStepOne;
|
||||
|
||||
}
|
||||
|
||||
#endif // _TRACING_CATEGORIES_H
|
||||
+1
-1
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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(),
|
||||
|
||||
@@ -48,5 +48,3 @@ include(antlr4.cmake)
|
||||
include(vulkan.cmake)
|
||||
|
||||
add_subdirectory(mdns)
|
||||
|
||||
add_subdirectory(variant)
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
add_library(variant INTERFACE)
|
||||
|
||||
target_include_directories(variant SYSTEM INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
@@ -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
@@ -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
@@ -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
Reference in new issue
Block a user