Line data Source code
1 : /* Copyright (C) 2021 Wildfire Games.
2 : *
3 : * Permission is hereby granted, free of charge, to any person obtaining
4 : * a copy of this software and associated documentation files (the
5 : * "Software"), to deal in the Software without restriction, including
6 : * without limitation the rights to use, copy, modify, merge, publish,
7 : * distribute, sublicense, and/or sell copies of the Software, and to
8 : * permit persons to whom the Software is furnished to do so, subject to
9 : * the following conditions:
10 : *
11 : * The above copyright notice and this permission notice shall be included
12 : * in all copies or substantial portions of the Software.
13 : *
14 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 : * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 : * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 : * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 : */
22 :
23 : #include "precompiled.h"
24 :
25 : #include "lib/app_hooks.h"
26 :
27 : #include "lib/sysdep/sysdep.h"
28 :
29 : #include <cstdio>
30 :
31 : //-----------------------------------------------------------------------------
32 : // default implementations
33 : //-----------------------------------------------------------------------------
34 :
35 0 : static const OsPath& def_get_log_dir()
36 : {
37 0 : static OsPath logDir;
38 0 : if(logDir.empty())
39 0 : logDir = sys_ExecutablePathname().Parent();
40 0 : return logDir;
41 : }
42 :
43 :
44 0 : static void def_bundle_logs(FILE* UNUSED(f))
45 : {
46 0 : }
47 :
48 :
49 0 : static ErrorReactionInternal def_display_error(const wchar_t* UNUSED(text), size_t UNUSED(flags))
50 : {
51 0 : return ERI_NOT_IMPLEMENTED;
52 : }
53 :
54 :
55 : //-----------------------------------------------------------------------------
56 :
57 : // contains the current set of hooks. starts with the default values and
58 : // may be changed via app_hooks_update.
59 : //
60 : // rationale: we don't ever need to switch "hook sets", so one global struct
61 : // is fine. by always having one defined, we also avoid the trampolines
62 : // having to check whether their function pointer is valid.
63 : static AppHooks ah =
64 : {
65 : def_get_log_dir,
66 : def_bundle_logs,
67 : def_display_error
68 : };
69 :
70 : // separate copy of ah; used to determine if a particular hook has been
71 : // redefined. the additional storage needed is negligible and this is
72 : // easier than comparing each value against its corresponding def_ value.
73 1 : static AppHooks default_ah = ah;
74 :
75 : // register the specified hook function pointers. any of them that
76 : // are non-zero override the previous function pointer value
77 : // (these default to the stub hooks which are functional but basic).
78 0 : void app_hooks_update(AppHooks* new_ah)
79 : {
80 0 : ENSURE(new_ah);
81 :
82 : #define OVERRIDE_IF_NONZERO(HOOKNAME) if(new_ah->HOOKNAME) ah.HOOKNAME = new_ah->HOOKNAME;
83 0 : OVERRIDE_IF_NONZERO(get_log_dir)
84 0 : OVERRIDE_IF_NONZERO(bundle_logs)
85 0 : OVERRIDE_IF_NONZERO(display_error)
86 : #undef OVERRIDE_IF_NONZERO
87 0 : }
88 :
89 0 : bool app_hook_was_redefined(size_t offset_in_struct)
90 : {
91 0 : const u8* ah_bytes = (const u8*)&ah;
92 0 : const u8* default_ah_bytes = (const u8*)&default_ah;
93 : typedef void(*FP)(); // a bit safer than comparing void* pointers
94 0 : if(*(FP)(ah_bytes+offset_in_struct) != *(FP)(default_ah_bytes+offset_in_struct))
95 0 : return true;
96 0 : return false;
97 : }
98 :
99 :
100 : //-----------------------------------------------------------------------------
101 : // trampoline implementations
102 : // (boilerplate code; hides details of how to call the app hook)
103 : //-----------------------------------------------------------------------------
104 :
105 0 : const OsPath& ah_get_log_dir()
106 : {
107 0 : return ah.get_log_dir();
108 : }
109 :
110 0 : void ah_bundle_logs(FILE* f)
111 : {
112 0 : ah.bundle_logs(f);
113 0 : }
114 :
115 0 : ErrorReactionInternal ah_display_error(const wchar_t* text, size_t flags)
116 : {
117 0 : return ah.display_error(text, flags);
118 3 : }
|