File: hook_api.cpp

package info (click to toggle)
freespace2 24.2.0%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,716 kB
  • sloc: cpp: 595,001; ansic: 21,741; python: 1,174; sh: 457; makefile: 248; xml: 181
file content (98 lines) | stat: -rw-r--r-- 3,014 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "hook_api.h"

#include "globalincs/pstypes.h"

#include "scripting/api/objs/vecmath.h"

namespace scripting {

namespace {

class HookManager {
  public:
	int32_t addHook(HookBase* hook)
	{
		const auto doesHookExist = [hook](const HookBase* test) { return test->getHookName() == hook->getHookName(); };
		Assertion(std::find_if(_hooks.cbegin(),
							   _hooks.cend(), doesHookExist) ==
					  _hooks.cend(),
				  "Hook '%s' already exists!",
				  hook->getHookName().c_str());

		const auto id = ++_lastId;
		_hooks.push_back(hook);
		return id;
	}

	void addHookWithId(HookBase* hook)
	{
		const auto doesHookExist = [hook](const HookBase* test) { return test->getHookName() == hook->getHookName(); };
		Assertion(std::find_if(_hooks.cbegin(),
							   _hooks.cend(),
					  doesHookExist) ==
					  _hooks.cend(),
				  "Hook '%s' already exists!",
				  hook->getHookName().c_str());

		_hooks.push_back(hook);
	}

	const SCP_vector<HookBase*>& getHooks() const { return _hooks; }

  private:
	int32_t _lastId = CHA_LAST;
	SCP_vector<HookBase*> _hooks;
};

HookManager& getHookManager()
{
	static HookManager mgr;
	return mgr;
}
} // namespace

namespace detail {
ade_odata_setter<object_h> convert_arg_type(object* objp)
{
	return ade_object_to_odata(objp != nullptr ? OBJ_INDEX(objp) : -1);
}
ade_odata_setter<vec3d> convert_arg_type(vec3d vec)
{
	return scripting::api::l_Vector.Set(vec);
}
} // namespace detail

HookVariableDocumentation::HookVariableDocumentation(const char* name_, ade_type_info type_, const char* description_)
	: name(name_), type(std::move(type_)), description(description_)
{
}

HookBase::HookBase(SCP_string hookName,
				   SCP_string description,
				   SCP_vector<HookVariableDocumentation> parameters,
				   const SCP_unordered_map<SCP_string, const std::unique_ptr<const ParseableCondition>>& conditions,
				   tl::optional<HookDeprecationOptions> deprecation,
				   int32_t hookId)
	: _conditions(conditions), _hookName(std::move(hookName)), _description(std::move(description)), _parameters(std::move(parameters)), _deprecation(std::move(deprecation))
{
	// If we specify a forced id then use that. This is for special hooks that need a guaranteed id
	if (hookId >= 0) {
		_hookId = hookId;
		getHookManager().addHookWithId(this);
	} else {
		_hookId = getHookManager().addHook(this);
	}
}

const SCP_string& HookBase::getHookName() const { return _hookName; }
const SCP_string& HookBase::getDescription() const { return _description; }
const SCP_vector<HookVariableDocumentation>& HookBase::getParameters() const { return _parameters; }
const tl::optional<HookDeprecationOptions>& HookBase::getDeprecation() const { return _deprecation; }
int32_t HookBase::getHookId() const { return _hookId; }
HookBase::~HookBase() = default;

const SCP_vector<HookBase*>& getHooks() { return getHookManager().getHooks(); }

const SCP_unordered_map<SCP_string, const std::unique_ptr<const ParseableCondition>> HookImpl<void>::emptyConditions{};

} // namespace scripting