File: ActionExpression.h

package info (click to toggle)
freespace2 24.2.0%2Brepack-3
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,740 kB
  • sloc: cpp: 595,005; ansic: 21,741; python: 1,174; sh: 457; makefile: 243; xml: 181
file content (83 lines) | stat: -rw-r--r-- 2,082 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#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;

/**
 * @brief An expression that can be executed to compute a value at runtime
 *
 * This is the basis of having dynamic values in actions by allowing mods to specify complex expressions that make use
 * of variables and functions for computing their values at runtime.
 */
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;
};

/**
 * @brief An action expression with a specific type specified at compile time
 *
 * This is most useful for built-in actions that have the required type fixed at compile time.
 *
 * @tparam T The type of the expression value.
 */
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