1 /*****************************************************************************
2  * Copyright (c) 2014-2020 OpenRCT2 developers
3  *
4  * For a complete list of all authors, please refer to contributors.md
5  * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6  *
7  * OpenRCT2 is licensed under the GNU General Public License version 3.
8  *****************************************************************************/
9 
10 #pragma once
11 
12 #ifdef ENABLE_SCRIPTING
13 
14 #    include "../common.h"
15 #    include "Duktape.hpp"
16 
17 #    include <any>
18 #    include <memory>
19 #    include <string>
20 #    include <tuple>
21 #    include <vector>
22 
23 namespace OpenRCT2::Scripting
24 {
25     class ScriptEngine;
26     class ScriptExecutionInfo;
27     class Plugin;
28 
29     enum class HOOK_TYPE
30     {
31         ACTION_QUERY,
32         ACTION_EXECUTE,
33         INTERVAL_TICK,
34         INTERVAL_DAY,
35         NETWORK_CHAT,
36         NETWORK_AUTHENTICATE,
37         NETWORK_JOIN,
38         NETWORK_LEAVE,
39         RIDE_RATINGS_CALCULATE,
40         ACTION_LOCATION,
41         GUEST_GENERATION,
42         VEHICLE_CRASH,
43         COUNT,
44         UNDEFINED = -1,
45     };
46     constexpr size_t NUM_HOOK_TYPES = static_cast<size_t>(HOOK_TYPE::COUNT);
47     HOOK_TYPE GetHookType(const std::string& name);
48 
49     struct Hook
50     {
51         uint32_t Cookie;
52         std::shared_ptr<Plugin> Owner;
53         DukValue Function;
54 
55         Hook() = default;
HookHook56         Hook(uint32_t cookie, std::shared_ptr<Plugin> owner, const DukValue& function)
57             : Cookie(cookie)
58             , Owner(owner)
59             , Function(function)
60         {
61         }
62     };
63 
64     struct HookList
65     {
66         HOOK_TYPE Type{};
67         std::vector<Hook> Hooks;
68 
69         HookList() = default;
70         HookList(const HookList&) = delete;
71         HookList(HookList&& src) = default;
72     };
73 
74     class HookEngine
75     {
76     private:
77         ScriptEngine& _scriptEngine;
78         std::vector<HookList> _hookMap;
79         uint32_t _nextCookie = 1;
80 
81     public:
82         HookEngine(ScriptEngine& scriptEngine);
83         HookEngine(const HookEngine&) = delete;
84         uint32_t Subscribe(HOOK_TYPE type, std::shared_ptr<Plugin> owner, const DukValue& function);
85         void Unsubscribe(HOOK_TYPE type, uint32_t cookie);
86         void UnsubscribeAll(std::shared_ptr<const Plugin> owner);
87         void UnsubscribeAll();
88         bool HasSubscriptions(HOOK_TYPE type) const;
89         void Call(HOOK_TYPE type, bool isGameStateMutable);
90         void Call(HOOK_TYPE type, const DukValue& arg, bool isGameStateMutable);
91         void Call(
92             HOOK_TYPE type, const std::initializer_list<std::pair<std::string_view, std::any>>& args, bool isGameStateMutable);
93 
94     private:
95         HookList& GetHookList(HOOK_TYPE type);
96         const HookList& GetHookList(HOOK_TYPE type) const;
97     };
98 } // namespace OpenRCT2::Scripting
99 
100 #endif
101