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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Copyright 2020-2022 The Defold Foundation
// Copyright 2014-2020 King
// Copyright 2009-2014 Ragnar Svensson, Christian Murray
// Licensed under the Defold License version 1.0 (the "License"); you may not use
// this file except in compliance with the License.
//
// You may obtain a copy of the License, together with FAQs at
// https://www.defold.com/license
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef DMSDK_CONFIGFILE_H
#define DMSDK_CONFIGFILE_H
#include <stdint.h>
namespace dmConfigFile
{
/*# SDK ConfigFile API documentation
*
* Configuration file access functions.
* The configuration file is compiled version of the [file:game.project] file.
*
* @document
* @name ConfigFile
* @namespace dmConfigFile
* @path engine/dlib/src/dmsdk/dlib/configfile.h
*/
/*# HConfig type definition
*
* ```cpp
* typedef struct Config* HConfig;
* ```
*
* @typedef
* @name dmConfigFile::HConfig
*/
typedef struct Config* HConfig;
/*# get config value as string
*
* Get config value as string, returns default if the key isn't found
*
* @name dmConfigFile::GetString
* @param config [type:dmConfigFile::HConfig] Config file handle
* @param key [type:const char*] Key in format section.key (.key for no section)
* @param default_value [type:const char*] Default value to return if key isn't found
* @return value [type:const char*] found value or default value
* @examples
*
* ```cpp
* static dmExtension::Result AppInitialize(dmExtension::AppParams* params)
* {
* const char* projectTitle = dmConfigFile::GetString(params->m_ConfigFile, "project.title", "Untitled");
* }
* ```
*/
const char* GetString(HConfig config, const char* key, const char* default_value);
/*# get config value as int
*
* Get config value as int, returns default if the key isn't found
* Note: default_value is returned for invalid integer values
*
* @name dmConfigFile::GetInt
* @param config [type:dmConfigFile::HConfig] Config file handle
* @param key [type:const char*] Key in format section.key (.key for no section)
* @param default_value [type:int32_t] Default value to return if key isn't found
* @return value [type:int32_t] found value or default value
* @examples
*
* ```cpp
* static dmExtension::Result AppInitialize(dmExtension::AppParams* params)
* {
* int32_t displayWidth = dmConfigFile::GetInt(params->m_ConfigFile, "display.width", 640);
* }
* ```
*/
int32_t GetInt(HConfig config, const char* key, int32_t default_value);
/*# get config value as float
*
* Get config value as float, returns default if the key isn't found
* Note: default_value is returned for invalid float values
*
* @name dmConfigFile::GetFloat
* @param config [type:dmConfigFile::HConfig] Config file handle
* @param key [type:const char*] Key in format section.key (.key for no section)
* @param default_value [type:float] Default value to return if key isn't found
* @return value [type:float] found value or default value
* @examples
*
* ```cpp
* static dmExtension::Result AppInitialize(dmExtension::AppParams* params)
* {
* float gravity = dmConfigFile::GetFloat(params->m_ConfigFile, "physics.gravity_y", -9.8f);
* }
* ```
*/
float GetFloat(HConfig config, const char* key, float default_value);
/**
* Configfile extension declaration helper. Internal function. Use DM_DECLARE_CONFIGFILE_EXTENSION
* @param desc
* @param desc_size bytesize of buffer holding desc
* @param name extension name. human readble
* @param app_init app-init function. May be null
* @param app_finalize app-final function. May be null
* @param initialize init function. May not be 0
* @param finalize function. May not be 0
* @param update update function. May be null
* @param on_event event callback function. May be null
*/
void Register(struct PluginDesc* desc,
uint32_t desc_size,
const char *name,
void (*create)(HConfig config),
void (*destroy)(HConfig config),
bool (*get_string)(HConfig config, const char* key, const char* default_value, const char** out),
bool (*get_int)(HConfig config, const char* key, int32_t default_value, int32_t* out),
bool (*get_float)(HConfig config, const char* key, float default_value, float* out)
);
/**
* Extension declaration helper. Internal
*/
#ifdef __GNUC__
// Workaround for dead-stripping on OSX/iOS. The symbol "name" is explicitly exported. See wscript "exported_symbols"
// Otherwise it's dead-stripped even though -no_dead_strip_inits_and_terms is passed to the linker
// The bug only happens when the symbol is in a static library though
#define DM_REGISTER_CONFIGFILE_EXTENSION(symbol, desc, desc_size, name, create, destroy, get_string, get_int, get_float) extern "C" void __attribute__((constructor)) symbol () { \
dmConfigFile::Register((struct dmConfigFile::PluginDesc*) &desc, desc_size, name, create, destroy, get_string, get_int, get_float); \
}
#else
#define DM_REGISTER_CONFIGFILE_EXTENSION(symbol, desc, desc_size, name, create, destroy, get_string, get_int, get_float) extern "C" void symbol () { \
dmConfigFile::Register((struct dmConfigFile::PluginDesc*) &desc, desc_size, name, create, destroy, get_string, get_int, get_float); \
}\
int symbol ## Wrapper(void) { symbol(); return 0; } \
__pragma(section(".CRT$XCU",read)) \
__declspec(allocate(".CRT$XCU")) int (* _Fp ## symbol)(void) = symbol ## Wrapper;
#endif
/**
* Extension desc bytesize declaration. Internal
*/
const uint32_t m_ExtensionDescBufferSize = 64;
// internal
#define DM_EXTENSION_PASTE_SYMREG(x, y) x ## y
// internal
#define DM_EXTENSION_PASTE_SYMREG2(x, y) DM_EXTENSION_PASTE_SYMREG(x, y)
/*# declare a new config file extension
*
* Declare and register new config file extension to the engine.
* Each get function should return true if it sets a proper value. Otherwise return false.
*
* @macro
* @name DM_DECLARE_CONFIGFILE_EXTENSION
* @param symbol [type:symbol] external extension symbol description (no quotes).
* @param name [type:const char*] extension name. Human readable.
* @param init [type:function(dmConfigFile::HConfig)] init function. May be null.
* @param get_string [type:function(const char* section_plus_name, const char* default, const char** out)] Gets a string property. May be null.
* @param get_int [type:function(const char* section_plus_name, int default, int* out)] Gets an int property. May be null.
* @param get_float [type:function(const char* section_plus_name, float default, float* out)] Gets a float property. May be null.
*
* @examples
*
* Register a new config file extension:
*
* ```cpp
* DM_DECLARE_CONFIGFILE_EXTENSION(MyConfigfileExtension, "MyConfigfileExtension", create, destroy, get_string, get_int, get_float);
* ```
*/
#define DM_DECLARE_CONFIGFILE_EXTENSION(symbol, name, create, destroy, get_string, get_int, get_float) \
uint8_t DM_ALIGNED(16) DM_EXTENSION_PASTE_SYMREG2(symbol, __LINE__)[dmConfigFile::m_ExtensionDescBufferSize]; \
DM_REGISTER_CONFIGFILE_EXTENSION(symbol, DM_EXTENSION_PASTE_SYMREG2(symbol, __LINE__), sizeof(DM_EXTENSION_PASTE_SYMREG2(symbol, __LINE__)), name, create, destroy, get_string, get_int, get_float);
}
#endif // DMSDK_CONFIGFILE_H