Skip to content

Commit cc57403

Browse files
A few tweaks: arguments for snippet_execute_string, added snippet_call_ext, fixed key event name parsing, now works when working directory != program directory
1 parent 74119ea commit cc57403

File tree

11 files changed

+309
-26
lines changed

11 files changed

+309
-26
lines changed

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ The DLL does code preprocessing and other operations that were deemed too slow t
2525
The scripts use `object_event_add` + `event_perform_object` to store and call the final code without parsing penalties that would occur with `execute_string`.
2626

2727
## Intended use cases
28-
<center>
28+
<p align="center">
2929

3030
![shrug](./misc/shrug.png)\
3131
~~What use cases?~~
3232

33-
</center>
33+
</p>
3434

3535
You could use it for dynamic content loading if you are making a game in GM8.1.
3636

@@ -52,8 +52,6 @@ If you compile a [GMEdit](https://github.com/YellowAfterlife/GMEdit/) version fr
5252
5353
- Wildcard support in listfiles?\
5454
(`folder/*.gml`)
55-
- Arguments for `snippet_execute_string`?\
56-
(needs an "argument count waterfall")
5755
5856
## Meta
5957

docs/index.dmd

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ The extension can be found
7878
```
7979
and a `snippet_function_add` for each script in the project.
8080
}
81-
#[snippet_execute_string(gml_code)->]() {
81+
#[snippet_execute_string(gml_code, ...arguments)->]() {
8282
Like regular `execute_string`, but uses the snippet preprocessor
8383
(e.g. can call snippets using `func()`).
8484
}
@@ -115,6 +115,11 @@ The extension can be found
115115
#[snippet_call(name, ...arguments)->]() {
116116
Calls a snippet with the given name and returns the result, not unlike `script_execute`.
117117
}
118+
#[snippet_call_ext(name, argument_list, offset=0, ?count)->]() {
119+
Like [snippet_call], but takes arguments from a ds_list instead.
120+
121+
If `count` is not specified, it's assumed to be `ds_list_size(argument_list) - offset`.
122+
}
118123
}
119124
#[Objects](objects) {
120125
#[snippet_define_object(name, gml_code)->]() {
@@ -295,6 +300,10 @@ The extension can be found
295300
}
296301
#[Other stuff](other) {
297302
File functions:
303+
#[sniptools_file_exists(path)->]() {
304+
Returns whether the extension/C++ thinks that the file exists,
305+
which doesn't necessarily match with when GameMaker thinks that a file exists.
306+
}
298307
#[sniptools_file_get_contents(path)->]() {
299308
Returns the contents of a file as a string (`""` if a file is missing).
300309
}

docs/index.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@
485485
<a class="sf" href="#snippet_parse_event_file">snippet_parse_event_file</a><span class="op">(</span><span class="st">"events.gml"</span><span class="op">)</span><span class="op">;</span>
486486
</pre><p>
487487
and a <code>snippet_function_add</code> for each script in the project.
488-
</p></article></section><section><header id="snippet_execute_string"><a href="#snippet_execute_string" title="(permalink)">snippet_execute_string(gml_code)&#8203;<span class="ret-arrow">&#10140;</span></a></header><article><p>
488+
</p></article></section><section><header id="snippet_execute_string"><a href="#snippet_execute_string" title="(permalink)">snippet_execute_string(gml_code, ...arguments)&#8203;<span class="ret-arrow">&#10140;</span></a></header><article><p>
489489
Like regular <code>execute_string</code>, but uses the snippet preprocessor
490490
(e.g. can call snippets using <code>func()</code>).
491491
</p></article></section></article></section><section><header id="snippets"><a href="#snippets" title="(permalink)">Snippets</a></header><article><a class="sticky-side" href="#snippets" title="Snippets"><span>Snippets</span></a><section><header id="snippet_define"><a href="#snippet_define" title="(permalink)">snippet_define(name, gml_code)</a></header><article><p>
@@ -515,6 +515,10 @@
515515
Calls:
516516
</p><section><header id="snippet_call"><a href="#snippet_call" title="(permalink)">snippet_call(name, ...arguments)&#8203;<span class="ret-arrow">&#10140;</span></a></header><article><p>
517517
Calls a snippet with the given name and returns the result, not unlike <code>script_execute</code>.
518+
</p></article></section><section><header id="snippet_call_ext"><a href="#snippet_call_ext" title="(permalink)">snippet_call_ext(name, argument_list, offset=0, ?count)&#8203;<span class="ret-arrow">&#10140;</span></a></header><article><p>
519+
Like <a href="#snippet_call">snippet_call</a>, but takes arguments from a ds_list instead.
520+
</p><p>
521+
If <code>count</code> is not specified, it's assumed to be <code>ds_list_size(argument_list) - offset</code>.
518522
</p></article></section></article></section><section><header id="objects"><a href="#objects" title="(permalink)">Objects</a></header><article><a class="sticky-side" href="#objects" title="Objects"><span>Objects</span></a><section><header id="snippet_define_object"><a href="#snippet_define_object" title="(permalink)">snippet_define_object(name, gml_code)&#8203;<span class="ret-arrow">&#10140;</span></a></header><article><p>
519523
Creates/overwrites an object.
520524
</p><p>
@@ -662,7 +666,10 @@
662666
Calls to it in subsequently compiled snippet will be the <a href="#preproc.call">preprocessor</a>.
663667
</p></article></section></article></section><section><header id="other"><a href="#other" title="(permalink)">Other stuff</a></header><article><a class="sticky-side" href="#other" title="Other stuff"><span>Other stuff</span></a><p>
664668
File functions:
665-
</p><section><header id="sniptools_file_get_contents"><a href="#sniptools_file_get_contents" title="(permalink)">sniptools_file_get_contents(path)&#8203;<span class="ret-arrow">&#10140;</span></a></header><article><p>
669+
</p><section><header id="sniptools_file_exists"><a href="#sniptools_file_exists" title="(permalink)">sniptools_file_exists(path)&#8203;<span class="ret-arrow">&#10140;</span></a></header><article><p>
670+
Returns whether the extension/C++ thinks that the file exists,
671+
which doesn't necessarily match with when GameMaker thinks that a file exists.
672+
</p></article></section><section><header id="sniptools_file_get_contents"><a href="#sniptools_file_get_contents" title="(permalink)">sniptools_file_get_contents(path)&#8203;<span class="ret-arrow">&#10140;</span></a></header><article><p>
666673
Returns the contents of a file as a string (<code>""</code> if a file is missing).
667674
</p></article></section><p>
668675
String functions:

snippets/named_events.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ dllx double snippet_event_get_number(const char* name) {
134134
case gml_event_type_arg::key: {
135135
auto key = str.substr(pos + 1);
136136
auto kp = gml_keycodes.find(key);
137-
if (kp != gml_keycodes.end()) kp->second;
137+
if (kp != gml_keycodes.end()) return kp->second;
138138

139139
int numb = 0;
140140
if (std::sscanf(key.c_str(), "%d", &numb)) {

snippets/snippets.aps

-620 Bytes
Binary file not shown.

snippets/sniptools.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
#include <queue>
44
#include "CharTools.h"
55

6+
///
7+
dllx double sniptools_file_exists(const char* path) {
8+
std::ifstream fs(path);
9+
return fs.good();
10+
}
611
///
712
dllx const char* sniptools_file_get_contents(const char* path) {
813
std::ifstream fs(path);

snippets_gml/snippets.gml

Lines changed: 144 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#define snippet_init_dll
2-
/// snippet_init_dll()
2+
/// snippet_init_dll(?path_prefix)
33
var _path, _dir;
4+
if (argument_count > 0) {
5+
_dir = argument[0];
6+
} else _dir = "";
47

5-
_dir = "";
68
_path = _dir + "snippets.dll";
79
global.f_snippet_event_get_type = external_define(_path, "snippet_event_get_type", dll_cdecl, ty_real, 1, ty_string);
810
global.f_snippet_event_get_number = external_define(_path, "snippet_event_get_number", dll_cdecl, ty_real, 1, ty_string);
@@ -14,6 +16,7 @@ global.f_snippet_function_add = external_define(_path, "snippet_function_add", d
1416
global.f_snippet_function_remove = external_define(_path, "snippet_function_remove", dll_cdecl, ty_real, 1, ty_string);
1517
global.f_snippet_parse_api_entry = external_define(_path, "snippet_parse_api_entry", dll_cdecl, ty_real, 1, ty_string);
1618
global.f_snippet_parse_api_file = external_define(_path, "snippet_parse_api_file", dll_cdecl, ty_real, 1, ty_string);
19+
global.f_sniptools_file_exists = external_define(_path, "sniptools_file_exists", dll_cdecl, ty_real, 1, ty_string);
1720
global.f_sniptools_file_get_contents = external_define(_path, "sniptools_file_get_contents", dll_cdecl, ty_string, 1, ty_string);
1821
global.f_sniptools_string_trim = external_define(_path, "sniptools_string_trim", dll_cdecl, ty_string, 1, ty_string);
1922
global.f_sniptools_string_trim_start = external_define(_path, "sniptools_string_trim_start", dll_cdecl, ty_string, 1, ty_string);
@@ -28,7 +31,14 @@ global.f_snippet_preproc_concat_names = external_define(_path, "snippet_preproc_
2831

2932

3033
#define snippet_init
31-
/// ()
34+
/// (?path_prefix)
35+
var _dir, _dir_auto;
36+
_dir_auto = argument_count == 0;
37+
if (_dir_auto) {
38+
_dir = "";
39+
} else {
40+
_dir = argument[0];
41+
}
3242
snippet_init_dll();
3343
var i; i = 0;
3444
global.__snippet__argument[0] = 0;
@@ -52,8 +62,15 @@ for (i = 0; i < global.__snippet__blank_object; i += 1) if (object_exists(i)) {
5262
// contains things like "create\nstep" in case we need to delete events later
5363
global.__snippet__object_events = ds_map_create();
5464

55-
snippet_parse_api_file("fnames");
56-
snippet_parse_event_file("events.gml");
65+
if (_dir == "" || filename_drive(_dir) == "") { // relative path?
66+
if (sniptools_file_exists(program_directory + _dir + "\fnames")) {
67+
_dir = program_directory + _dir + "\";
68+
} else if (sniptools_file_exists(working_directory + _dir + "\fnames")) {
69+
_dir = working_directory + _dir + "\";
70+
}
71+
}
72+
snippet_parse_api_file(_dir + "fnames");
73+
snippet_parse_event_file(_dir + "events.gml");
5774
5875
// collect scripts:
5976
var _max_gap; _max_gap = 1024;
@@ -77,14 +94,58 @@ while (_gap < _max_gap || !_seen_snippet_init) {
7794
);*/
7895
7996
#define snippet_execute_string
80-
/// (gml_code)
81-
var n; n = external_call(global.f_snippet_preproc_run, "", argument0, "define");
97+
/// (gml_code, ...arguments)
98+
var n; n = external_call(global.f_snippet_preproc_run, "", argument[0], "define");
99+
100+
// NB! Store-restore mirrors across snippet_execute_string, snippet_call, snippet_call_ext
101+
// store old arguments:
102+
var _old_argc; _old_argc = global.__snippet__argument_count;
103+
var _old_args; _old_args = global.__snippet__argument;
104+
var i; i = 1;
105+
repeat (_old_argc - 1) {
106+
_old_args[i] = global.__snippet__argument[i];
107+
i += 1;
108+
}
109+
110+
// copy new arguments:
111+
var _argc; _argc = argument_count - 1;
112+
global.__snippet__argument_count = _argc;
113+
i = 0;
114+
repeat (_argc) {
115+
global.__snippet__argument[i] = argument[i + 1];
116+
i += 1;
117+
}
118+
119+
// clear "extra" arguments:
120+
repeat (_old_argc - _argc) {
121+
global.__snippet__argument[i] = 0;
122+
i += 1;
123+
}
124+
125+
// run the snippet(s):
82126
var _result; _result = 0;
83127
repeat (n) {
84128
var _name; _name = external_call(global.f_snippet_preproc_pop_name);
85129
var _code; _code = external_call(global.f_snippet_preproc_pop_code);
86-
_result = execute_string(_code);
130+
global.__snippet__result = 0;
131+
execute_string(_code);
132+
_result = global.__snippet__result;
133+
}
134+
135+
// restore previous arguments:
136+
global.__snippet__argument_count = _old_argc;
137+
i = 0;
138+
repeat (_old_argc) {
139+
global.__snippet__argument[i] = _old_args[i];
140+
i += 1;
87141
}
142+
143+
// clear the extra arguments (the other way around!):
144+
repeat (_argc - _old_argc) {
145+
global.__snippet__argument[i] = 0;
146+
i += 1;
147+
}
148+
88149
return _result;
89150
90151
#define snippet_define
@@ -142,9 +203,10 @@ if (ds_map_exists(global.__snippet__code_map, argument0)) {
142203
} else return "";
143204
144205
#define snippet_call
145-
/// (name, ...args)
146-
var _name; _name = argument0;
206+
/// (name, ...arguments)
207+
var _name; _name = argument[0];
147208
209+
// NB! Store-restore mirrors across snippet_execute_string, snippet_call, snippet_call_ext
148210
// store old arguments:
149211
var _old_argc; _old_argc = global.__snippet__argument_count;
150212
var _old_args; _old_args = global.__snippet__argument;
@@ -170,6 +232,74 @@ repeat (_old_argc - _argc) {
170232
}
171233
172234
if (ds_map_exists(global.__snippet__map, _name)) {
235+
global.__snippet__result = 0;
236+
// one snippet per event:
237+
var _enumb; _enumb = ds_map_find_value(global.__snippet__map, _name);
238+
event_perform_object(obj_snippets, ev_alarm, _enumb);
239+
//*/
240+
241+
/* one snippet per object:
242+
var _obj; _obj = ds_map_find_value(global.__snippet__map, _name);
243+
event_perform_object(_obj, ev_other, 257);
244+
//*/
245+
} else {
246+
show_error('Snippet "' + _name + '" does not exist!', true);
247+
}
248+
249+
// restore previous arguments:
250+
global.__snippet__argument_count = _old_argc;
251+
i = 0;
252+
repeat (_old_argc) {
253+
global.__snippet__argument[i] = _old_args[i];
254+
i += 1;
255+
}
256+
257+
// clear the extra arguments (the other way around!):
258+
repeat (_argc - _old_argc) {
259+
global.__snippet__argument[i] = 0;
260+
i += 1;
261+
}
262+
263+
return global.__snippet__result;
264+
265+
#define snippet_call_ext
266+
/// (name, argument_list, offset=0, ?count)
267+
var _name; _name = argument[0];
268+
var _args; _args = argument[1];
269+
var _argi, _argc;
270+
if (argument_count > 2) {
271+
_argi = argument[2];
272+
} else _argi = 0;
273+
if (argument_count > 3) {
274+
_argc = argument[3];
275+
} else _argc = ds_list_size(_args) - _argi;
276+
277+
// NB! Store-restore mirrors across snippet_execute_string, snippet_call, snippet_call_ext
278+
// store old arguments:
279+
var _old_argc; _old_argc = global.__snippet__argument_count;
280+
var _old_args; _old_args = global.__snippet__argument;
281+
var i; i = 1;
282+
repeat (_old_argc - 1) {
283+
_old_args[i] = global.__snippet__argument[i];
284+
i += 1;
285+
}
286+
287+
// copy new arguments:
288+
global.__snippet__argument_count = _argc;
289+
i = 0;
290+
repeat (_argc) {
291+
global.__snippet__argument[i] = ds_list_find_value(_args, _argi + i);
292+
i += 1;
293+
}
294+
295+
// clear "extra" arguments:
296+
repeat (_old_argc - _argc) {
297+
global.__snippet__argument[i] = 0;
298+
i += 1;
299+
}
300+
301+
if (ds_map_exists(global.__snippet__map, _name)) {
302+
global.__snippet__result = 0;
173303
// one snippet per event:
174304
var _enumb; _enumb = ds_map_find_value(global.__snippet__map, _name);
175305
event_perform_object(obj_snippets, ev_alarm, _enumb);
@@ -489,6 +619,10 @@ return external_call(global.f_snippet_parse_api_entry, argument0);
489619
/// snippet_parse_api_file(path)
490620
return external_call(global.f_snippet_parse_api_file, argument0);
491621
622+
#define sniptools_file_exists
623+
/// sniptools_file_exists(path)
624+
return external_call(global.f_sniptools_file_exists, argument0);
625+
492626
#define sniptools_file_get_contents
493627
/// sniptools_file_get_contents(path)
494628
return external_call(global.f_sniptools_file_get_contents, argument0);

0 commit comments

Comments
 (0)