Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
app_hooks.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2010 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 /*
24  * hooks to allow customization / app-specific behavior.
25  */
26 
27 #include "precompiled.h"
28 #include "lib/app_hooks.h"
29 
30 #include "lib/sysdep/sysdep.h"
31 
32 #include <cstdio>
33 
34 //-----------------------------------------------------------------------------
35 // default implementations
36 //-----------------------------------------------------------------------------
37 
39 {
40 }
41 
42 
43 static const OsPath& def_get_log_dir()
44 {
45  static OsPath logDir;
46  if(logDir.empty())
47  logDir = sys_ExecutablePathname().Parent();
48  return logDir;
49 }
50 
51 
52 static void def_bundle_logs(FILE* UNUSED(f))
53 {
54 }
55 
56 
57 static const wchar_t* def_translate(const wchar_t* text)
58 {
59  return text;
60 }
61 
62 
63 static void def_translate_free(const wchar_t* UNUSED(text))
64 {
65  // no-op - translate() doesn't own the pointer.
66 }
67 
68 
69 static void def_log(const wchar_t* text)
70 {
71 #if ICC_VERSION
72 #pragma warning(push)
73 #pragma warning(disable:181) // "invalid printf conversion" - but wchar_t* and %ls are legit
74 #endif
75  printf("%ls", text); // must not use wprintf, since stdout on Unix is byte-oriented
76 #if ICC_VERSION
77 #pragma warning(pop)
78 #endif
79 }
80 
81 
82 static ErrorReactionInternal def_display_error(const wchar_t* UNUSED(text), size_t UNUSED(flags))
83 {
84  return ERI_NOT_IMPLEMENTED;
85 }
86 
87 
88 //-----------------------------------------------------------------------------
89 
90 // contains the current set of hooks. starts with the default values and
91 // may be changed via app_hooks_update.
92 //
93 // rationale: we don't ever need to switch "hook sets", so one global struct
94 // is fine. by always having one defined, we also avoid the trampolines
95 // having to check whether their function pointer is valid.
96 static AppHooks ah =
97 {
103  def_log,
105 };
106 
107 // separate copy of ah; used to determine if a particular hook has been
108 // redefined. the additional storage needed is negligible and this is
109 // easier than comparing each value against its corresponding def_ value.
111 
112 // register the specified hook function pointers. any of them that
113 // are non-zero override the previous function pointer value
114 // (these default to the stub hooks which are functional but basic).
116 {
117  ENSURE(new_ah);
118 
119 #define OVERRIDE_IF_NONZERO(HOOKNAME) if(new_ah->HOOKNAME) ah.HOOKNAME = new_ah->HOOKNAME;
120  OVERRIDE_IF_NONZERO(override_gl_upload_caps)
121  OVERRIDE_IF_NONZERO(get_log_dir)
122  OVERRIDE_IF_NONZERO(bundle_logs)
123  OVERRIDE_IF_NONZERO(translate)
124  OVERRIDE_IF_NONZERO(translate_free)
126  OVERRIDE_IF_NONZERO(display_error)
127 }
128 
129 bool app_hook_was_redefined(size_t offset_in_struct)
130 {
131  const u8* ah_bytes = (const u8*)&ah;
132  const u8* default_ah_bytes = (const u8*)&default_ah;
133  typedef void(*FP)(); // a bit safer than comparing void* pointers
134  if(*(FP)(ah_bytes+offset_in_struct) != *(FP)(default_ah_bytes+offset_in_struct))
135  return true;
136  return false;
137 }
138 
139 
140 //-----------------------------------------------------------------------------
141 // trampoline implementations
142 // (boilerplate code; hides details of how to call the app hook)
143 //-----------------------------------------------------------------------------
144 
146 {
149 }
150 
152 {
153  return ah.get_log_dir();
154 }
155 
156 void ah_bundle_logs(FILE* f)
157 {
158  ah.bundle_logs(f);
159 }
160 
161 const wchar_t* ah_translate(const wchar_t* text)
162 {
163  return ah.translate(text);
164 }
165 
166 void ah_translate_free(const wchar_t* text)
167 {
168  ah.translate_free(text);
169 }
170 
171 void ah_log(const wchar_t* text)
172 {
173  ah.log(text);
174 }
175 
176 ErrorReactionInternal ah_display_error(const wchar_t* text, size_t flags)
177 {
178  return ah.display_error(text, flags);
179 }
#define u8
Definition: types.h:39
static OsPath logDir
Definition: Pyrogenesis.cpp:89
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
static void def_translate_free(const wchar_t *text)
Definition: app_hooks.cpp:63
ErrorReactionInternal(* display_error)(const wchar_t *text, size_t flags)
Definition: app_hooks.h:187
const wchar_t *(* translate)(const wchar_t *text)
Definition: app_hooks.h:184
special return value for the display_error app hook stub to indicate that it has done nothing and tha...
Definition: debug.h:175
Path Parent() const
Definition: path.h:150
const OsPath &(* get_log_dir)()
Definition: app_hooks.h:182
void ah_log(const wchar_t *text)
write text to the app&#39;s log.
Definition: app_hooks.cpp:171
void ah_override_gl_upload_caps()
override default decision on using OpenGL extensions relating to texture upload.
Definition: app_hooks.cpp:145
void(* override_gl_upload_caps)()
Definition: app_hooks.h:181
static const OsPath & def_get_log_dir()
Definition: app_hooks.cpp:43
void ah_translate_free(const wchar_t *text)
free text that was returned by translate.
Definition: app_hooks.cpp:166
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
Definition: path.h:75
static ErrorReactionInternal def_display_error(const wchar_t *text, size_t flags)
Definition: app_hooks.cpp:82
ErrorReactionInternal ah_display_error(const wchar_t *text, size_t flags)
display an error dialog, thus overriding sys_display_error.
Definition: app_hooks.cpp:176
void(* translate_free)(const wchar_t *text)
Definition: app_hooks.h:185
static AppHooks ah
Definition: app_hooks.cpp:96
void(* bundle_logs)(FILE *f)
Definition: app_hooks.h:183
static void def_override_gl_upload_caps()
Definition: app_hooks.cpp:38
static void def_bundle_logs(FILE *f)
Definition: app_hooks.cpp:52
static AppHooks default_ah
Definition: app_hooks.cpp:110
bool empty() const
Definition: path.h:118
OsPath sys_ExecutablePathname()
Definition: bsd.cpp:33
static const wchar_t * def_translate(const wchar_t *text)
Definition: app_hooks.cpp:57
const OsPath & ah_get_log_dir()
return path to directory into which crash dumps should be written.
Definition: app_hooks.cpp:151
bool app_hook_was_redefined(size_t offset_in_struct)
was the app hook changed via app_hooks_update from its default value?
Definition: app_hooks.cpp:129
holds a function pointer (allowed to be NULL) for each hook.
Definition: app_hooks.h:179
void app_hooks_update(AppHooks *new_ah)
update the app hook function pointers.
Definition: app_hooks.cpp:115
void(* log)(const wchar_t *text)
Definition: app_hooks.h:186
def log
Definition: tests.py:21
static void def_log(const wchar_t *text)
Definition: app_hooks.cpp:69
const wchar_t * ah_translate(const wchar_t *text)
translate text to the current locale.
Definition: app_hooks.cpp:161
ErrorReactionInternal
all choices offered by the error dialog.
Definition: debug.h:154
void ah_bundle_logs(FILE *f)
gather all app-related logs/information and write it to file.
Definition: app_hooks.cpp:156
#define OVERRIDE_IF_NONZERO(HOOKNAME)