@pkmn/engine 0.1.0-dev.15f64810 → 0.1.0-dev.18478e7d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +30 -17
- package/build/pkg/addon/browser.d.ts +3 -0
- package/build/pkg/addon/browser.js +47 -0
- package/build/pkg/addon/browser.js.map +1 -0
- package/build/pkg/addon/node.d.ts +3 -0
- package/build/pkg/addon/node.js +110 -0
- package/build/pkg/addon/node.js.map +1 -0
- package/build/pkg/addon/wasm.d.ts +2 -0
- package/build/pkg/addon/wasm.js +53 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +26 -4
- package/build/pkg/addon.js +34 -65
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/layout.json +15 -2
- package/build/pkg/data/protocol.json +23 -9
- package/build/pkg/data.d.ts +23 -1
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +15 -18
- package/build/pkg/gen1.js +28 -19
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +40 -90
- package/build/pkg/index.js +23 -70
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +29 -1
- package/build/pkg/protocol.js +105 -103
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +83 -73
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +66 -0
- package/build/tools/display/debug.jsx.map +1 -0
- package/build/tools/display/index.js +152 -0
- package/build/tools/display/index.js.map +1 -0
- package/build/tools/display/ui.jsx +360 -0
- package/build/tools/display/ui.jsx.map +1 -0
- package/build/tools/display/util.js +157 -0
- package/build/tools/display/util.js.map +1 -0
- package/build.zig +346 -128
- package/package.json +59 -138
- package/src/bin/install-pkmn-engine +25 -7
- package/src/bin/pkmn-debug +1 -1
- package/src/lib/bindings/c.zig +201 -0
- package/src/lib/bindings/node.zig +117 -0
- package/src/lib/bindings/wasm.zig +51 -0
- package/src/lib/common/array.zig +70 -0
- package/src/lib/common/data.zig +8 -8
- package/src/lib/common/debug.zig +45 -29
- package/src/lib/common/js.zig +3 -7
- package/src/lib/common/optional.zig +26 -22
- package/src/lib/common/options.zig +4 -0
- package/src/lib/common/protocol.zig +196 -160
- package/src/lib/common/rational.zig +338 -254
- package/src/lib/common/rng.zig +5 -7
- package/src/lib/common/util.zig +53 -1
- package/src/lib/gen1/calc.zig +651 -205
- package/src/lib/gen1/chance.zig +443 -257
- package/src/lib/gen1/data/moves.zig +2 -4
- package/src/lib/gen1/data/species.zig +1 -3
- package/src/lib/gen1/data/types.zig +3 -4
- package/src/lib/gen1/data.zig +40 -43
- package/src/lib/gen1/helpers.zig +39 -574
- package/src/lib/gen1/mechanics.zig +328 -229
- package/src/lib/gen2/calc.zig +35 -28
- package/src/lib/gen2/chance.zig +117 -518
- package/src/lib/gen2/data/items.zig +1 -3
- package/src/lib/gen2/data/moves.zig +2 -4
- package/src/lib/gen2/data/species.zig +1 -3
- package/src/lib/gen2/data/types.zig +7 -5
- package/src/lib/gen2/data.zig +33 -35
- package/src/lib/gen2/generated.zig +18 -23
- package/src/lib/gen2/helpers.zig +32 -33
- package/src/lib/gen2/mechanics.zig +105 -132
- package/src/lib/napi.h +2 -0
- package/src/lib/node.zig +4 -121
- package/src/lib/pkmn.zig +103 -22
- package/src/lib/wasm.zig +9 -9
- package/src/tools/display/dom.ts +108 -0
- package/src/tools/display/ui.css +354 -0
- package/build/test/display.js +0 -400
- package/build/test/display.js.map +0 -1
- package/src/test/display/pkmn.html.tmpl +0 -368
package/build.zig
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
1
|
const builtin = @import("builtin");
|
|
2
|
+
const std = @import("std");
|
|
3
|
+
|
|
4
|
+
fn ArrayList(comptime T: type) type {
|
|
5
|
+
return std.array_list.Aligned(T, null);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
pub const Options = struct {
|
|
9
|
+
showdown: ?bool = null,
|
|
10
|
+
log: ?bool = null,
|
|
11
|
+
chance: ?bool = null,
|
|
12
|
+
calc: ?bool = null,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
pub fn module(
|
|
16
|
+
b: *std.Build,
|
|
17
|
+
options: Options,
|
|
18
|
+
target: std.Build.ResolvedTarget,
|
|
19
|
+
optimize: std.builtin.OptimizeMode,
|
|
20
|
+
) *std.Build.Module {
|
|
21
|
+
const build_options = b.addOptions();
|
|
22
|
+
build_options.addOption(?bool, "showdown", options.showdown);
|
|
23
|
+
build_options.addOption(?bool, "log", options.log);
|
|
24
|
+
build_options.addOption(?bool, "chance", options.chance);
|
|
25
|
+
build_options.addOption(?bool, "calc", options.calc);
|
|
26
|
+
|
|
27
|
+
const root_source_file = b.path("src/lib/pkmn.zig");
|
|
28
|
+
const imports: []const std.Build.Module.Import =
|
|
29
|
+
&.{.{ .name = "build_options", .module = build_options.createModule() }};
|
|
30
|
+
return b.createModule(.{
|
|
31
|
+
.root_source_file = root_source_file,
|
|
32
|
+
.target = target,
|
|
33
|
+
.optimize = optimize,
|
|
34
|
+
.imports = imports,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
3
37
|
|
|
4
38
|
pub fn build(b: *std.Build) !void {
|
|
5
39
|
const target = b.standardTargetOptions(.{});
|
|
@@ -8,6 +42,10 @@ pub fn build(b: *std.Build) !void {
|
|
|
8
42
|
const node_headers = b.option([]const u8, "node-headers", "Path to node-headers");
|
|
9
43
|
const node_import_lib =
|
|
10
44
|
b.option([]const u8, "node-import-library", "Path to node import library (Windows)");
|
|
45
|
+
const demo = if (try exists(b, "src/tools/demo.zig"))
|
|
46
|
+
b.option(bool, "demo", "Build the demo library") orelse false
|
|
47
|
+
else
|
|
48
|
+
false;
|
|
11
49
|
const wasm = b.option(bool, "wasm", "Build a WASM library") orelse false;
|
|
12
50
|
const wasm_stack_size =
|
|
13
51
|
b.option(u64, "wasm-stack-size", "The size of WASM stack") orelse std.wasm.page_size;
|
|
@@ -17,14 +55,17 @@ pub fn build(b: *std.Build) !void {
|
|
|
17
55
|
const emit_asm = b.option(bool, "emit-asm", "Output .s (assembly code)") orelse false;
|
|
18
56
|
const emit_ll = b.option(bool, "emit-ll", "Output .ll (LLVM IR)") orelse false;
|
|
19
57
|
|
|
20
|
-
const cmd =
|
|
58
|
+
const cmd = if (@hasDecl(std.Build, "FindProgramOptions"))
|
|
59
|
+
b.findProgram(.{ .names = &.{"strip"} })
|
|
60
|
+
else
|
|
61
|
+
b.findProgram(&.{"strip"}, &.{}) catch null;
|
|
21
62
|
|
|
22
63
|
const json = @embedFile("package.json");
|
|
23
64
|
var parsed = try std.json.parseFromSlice(std.json.Value, b.allocator, json, .{});
|
|
24
65
|
defer parsed.deinit();
|
|
25
66
|
const version = parsed.value.object.get("version").?.string;
|
|
26
67
|
const description = parsed.value.object.get("description").?.string;
|
|
27
|
-
var repository = std.mem.
|
|
68
|
+
var repository = std.mem.splitScalar(u8, parsed.value.object.get("repository").?.string, ':');
|
|
28
69
|
std.debug.assert(std.mem.eql(u8, repository.first(), "github"));
|
|
29
70
|
|
|
30
71
|
const showdown =
|
|
@@ -32,6 +73,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
32
73
|
const log = b.option(bool, "log", "Enable protocol message logging") orelse false;
|
|
33
74
|
const chance = b.option(bool, "chance", "Enable update probability tracking") orelse false;
|
|
34
75
|
const calc = b.option(bool, "calc", "Enable damage calculator support") orelse false;
|
|
76
|
+
const extra = b.option([]const []const u8, "option", "Enable extra option");
|
|
35
77
|
|
|
36
78
|
const options = b.addOptions();
|
|
37
79
|
options.addOption(?bool, "showdown", showdown);
|
|
@@ -39,9 +81,26 @@ pub fn build(b: *std.Build) !void {
|
|
|
39
81
|
options.addOption(?bool, "chance", chance);
|
|
40
82
|
options.addOption(?bool, "calc", calc);
|
|
41
83
|
|
|
84
|
+
if (extra) |opts| {
|
|
85
|
+
for (opts) |opt| {
|
|
86
|
+
if (std.mem.indexOfScalar(u8, opt, '=')) |i| {
|
|
87
|
+
options.addOption(?bool, opt[0..i], if (std.mem.eql(u8, opt[i + 1 ..], "true"))
|
|
88
|
+
true
|
|
89
|
+
else if (std.mem.eql(u8, opt[i + 1 ..], "false"))
|
|
90
|
+
false
|
|
91
|
+
else {
|
|
92
|
+
std.log.err("Invalid option: {s}\n", .{opt});
|
|
93
|
+
return error.InvalidOption;
|
|
94
|
+
});
|
|
95
|
+
} else {
|
|
96
|
+
options.addOption(?bool, opt, true);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
42
101
|
const name = if (showdown) "pkmn-showdown" else "pkmn";
|
|
43
102
|
|
|
44
|
-
const
|
|
103
|
+
const pkmn: *std.Build.Module = b.addModule("pkmn", .{
|
|
45
104
|
.root_source_file = b.path("src/lib/pkmn.zig"),
|
|
46
105
|
.optimize = optimize,
|
|
47
106
|
.target = target,
|
|
@@ -50,22 +109,34 @@ pub fn build(b: *std.Build) !void {
|
|
|
50
109
|
|
|
51
110
|
var c = false;
|
|
52
111
|
if (node_headers) |headers| {
|
|
112
|
+
const translate_c = b.addTranslateC(.{
|
|
113
|
+
.root_source_file = b.path("src/lib/napi.h"),
|
|
114
|
+
.target = target,
|
|
115
|
+
// TODO: workaround for ziglang/zig#35515
|
|
116
|
+
.optimize = .Debug,
|
|
117
|
+
});
|
|
118
|
+
translate_c.addSystemIncludePath(b.path(headers));
|
|
53
119
|
const addon = b.fmt("{s}.node", .{name});
|
|
54
|
-
const
|
|
120
|
+
const path = b.path("src/lib/node.zig");
|
|
121
|
+
const lib = b.addLibrary(.{
|
|
122
|
+
.linkage = .dynamic,
|
|
55
123
|
.name = addon,
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
124
|
+
.root_module = b.createModule(.{
|
|
125
|
+
.root_source_file = path,
|
|
126
|
+
.optimize = optimize,
|
|
127
|
+
.target = target,
|
|
128
|
+
.strip = strip,
|
|
129
|
+
.pic = pic,
|
|
130
|
+
}),
|
|
61
131
|
});
|
|
62
132
|
lib.root_module.addOptions("build_options", options);
|
|
63
|
-
lib.
|
|
64
|
-
lib.
|
|
133
|
+
lib.root_module.addImport("napi", translate_c.createModule());
|
|
134
|
+
lib.root_module.link_libc = true;
|
|
65
135
|
if (node_import_lib) |il| {
|
|
66
|
-
lib.addObjectFile(b.path(il));
|
|
136
|
+
lib.root_module.addObjectFile(b.path(il));
|
|
67
137
|
} else if (target.result.os.tag == .windows) {
|
|
68
|
-
|
|
138
|
+
var err = std.Io.File.stderr().writer(b.graph.io, &.{});
|
|
139
|
+
try err.interface.writeAll("Must provide --node-import-library path on Windows\n");
|
|
69
140
|
std.process.exit(1);
|
|
70
141
|
}
|
|
71
142
|
lib.linker_allow_shlib_undefined = true;
|
|
@@ -80,68 +151,49 @@ pub fn build(b: *std.Build) !void {
|
|
|
80
151
|
// rename the file ourself in install-pkmn-engine
|
|
81
152
|
b.installArtifact(lib);
|
|
82
153
|
} else if (wasm) {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
|
|
91
|
-
.strip = strip,
|
|
92
|
-
.pic = pic,
|
|
93
|
-
});
|
|
94
|
-
exe.root_module.addOptions("build_options", options);
|
|
95
|
-
exe.root_module.export_symbol_names = &[_][]const u8{
|
|
96
|
-
"SHOWDOWN",
|
|
97
|
-
"LOG",
|
|
98
|
-
"CHANCE",
|
|
99
|
-
"CALC",
|
|
100
|
-
"GEN1_CHOICES_SIZE",
|
|
101
|
-
"GEN1_LOGS_SIZE",
|
|
102
|
-
};
|
|
103
|
-
exe.entry = .disabled;
|
|
104
|
-
exe.stack_size = wasm_stack_size;
|
|
105
|
-
const opt = b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
|
|
106
|
-
if (optimize != .Debug and opt != null) {
|
|
107
|
-
const out = b.fmt("build/lib/{s}.wasm", .{name});
|
|
108
|
-
const sh = b.addSystemCommand(&.{ opt.?, "-O4" });
|
|
109
|
-
sh.addArtifactArg(exe);
|
|
110
|
-
sh.addArg("-o");
|
|
111
|
-
sh.addFileArg(b.path(out));
|
|
112
|
-
b.getInstallStep().dependOn(&sh.step);
|
|
113
|
-
} else {
|
|
114
|
-
b.getInstallStep().dependOn(&b.addInstallArtifact(exe, .{
|
|
115
|
-
.dest_dir = .{ .override = std.Build.InstallDir{ .lib = {} } },
|
|
116
|
-
}).step);
|
|
117
|
-
}
|
|
154
|
+
const path = "src/lib/wasm.zig";
|
|
155
|
+
try buildWasm(b, name, path, optimize, strip, pic, wasm_stack_size, null, options);
|
|
156
|
+
} else if (demo) {
|
|
157
|
+
const path = "src/tools/demo.zig";
|
|
158
|
+
const n = if (showdown) "demo-showdown" else "demo";
|
|
159
|
+
const mod = pkmn;
|
|
160
|
+
try buildWasm(b, n, path, optimize, strip, pic, wasm_stack_size, mod, options);
|
|
118
161
|
} else if (dynamic) {
|
|
119
|
-
const
|
|
162
|
+
const path = b.path("src/lib/c.zig");
|
|
163
|
+
const lib = b.addLibrary(.{
|
|
164
|
+
.linkage = .dynamic,
|
|
120
165
|
.name = name,
|
|
121
|
-
.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
166
|
+
.root_module = b.createModule(.{
|
|
167
|
+
.root_source_file = path,
|
|
168
|
+
.optimize = optimize,
|
|
169
|
+
.target = target,
|
|
170
|
+
.strip = strip,
|
|
171
|
+
.pic = pic,
|
|
172
|
+
}),
|
|
127
173
|
});
|
|
128
174
|
lib.root_module.addOptions("build_options", options);
|
|
129
|
-
lib.addIncludePath(b.path("src/include"));
|
|
175
|
+
lib.root_module.addIncludePath(b.path("src/include"));
|
|
130
176
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
131
177
|
b.installArtifact(lib);
|
|
132
178
|
c = true;
|
|
133
179
|
} else {
|
|
134
|
-
const
|
|
180
|
+
const path = b.path("src/lib/c.zig");
|
|
181
|
+
const lib = b.addLibrary(.{
|
|
182
|
+
.linkage = .static,
|
|
135
183
|
.name = name,
|
|
136
|
-
.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
184
|
+
.root_module = b.createModule(.{
|
|
185
|
+
.root_source_file = path,
|
|
186
|
+
.optimize = optimize,
|
|
187
|
+
.target = target,
|
|
188
|
+
.strip = strip,
|
|
189
|
+
.pic = pic,
|
|
190
|
+
}),
|
|
141
191
|
});
|
|
142
192
|
lib.root_module.addOptions("build_options", options);
|
|
143
|
-
lib.addIncludePath(b.path("src/include"));
|
|
144
|
-
|
|
193
|
+
lib.root_module.addIncludePath(b.path("src/include"));
|
|
194
|
+
if (target.result.os.tag != .macos) {
|
|
195
|
+
lib.bundle_compiler_rt = true;
|
|
196
|
+
}
|
|
145
197
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
146
198
|
if (emit_asm) {
|
|
147
199
|
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
@@ -162,41 +214,52 @@ pub fn build(b: *std.Build) !void {
|
|
|
162
214
|
}
|
|
163
215
|
|
|
164
216
|
if (c) {
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
.header,
|
|
168
|
-
"pkmn.h",
|
|
169
|
-
);
|
|
217
|
+
const path = b.path("src/include/pkmn.h");
|
|
218
|
+
const header = b.addInstallFileWithDir(path, .header, "pkmn.h");
|
|
170
219
|
b.getInstallStep().dependOn(&header.step);
|
|
171
220
|
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
b.allocator,
|
|
175
|
-
try std.process.getCwdAlloc(b.allocator),
|
|
176
|
-
try b.cache_root.join(b.allocator, &.{pc}),
|
|
177
|
-
);
|
|
178
|
-
const pkgconfig_file = try std.fs.cwd().createFile(file, .{});
|
|
179
|
-
|
|
180
|
-
const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
|
|
181
|
-
const writer = pkgconfig_file.writer();
|
|
182
|
-
try writer.print(
|
|
183
|
-
\\prefix={0s}/{1s}
|
|
221
|
+
const content = try std.fmt.allocPrint(b.allocator,
|
|
222
|
+
\\prefix=${{pcfiledir}}/../..
|
|
184
223
|
\\includedir=${{prefix}}/include
|
|
185
224
|
\\libdir=${{prefix}}/lib
|
|
186
225
|
\\
|
|
187
|
-
\\Name: lib{
|
|
188
|
-
\\URL: https://github.com/{
|
|
189
|
-
\\Description: {
|
|
190
|
-
\\Version: {
|
|
226
|
+
\\Name: lib{0s}
|
|
227
|
+
\\URL: https://github.com/{1s}
|
|
228
|
+
\\Description: {2s}
|
|
229
|
+
\\Version: {3s}
|
|
191
230
|
\\Cflags: -I${{includedir}}
|
|
192
|
-
\\Libs: -L${{libdir}} -l{
|
|
193
|
-
, .{
|
|
194
|
-
defer pkgconfig_file.close();
|
|
231
|
+
\\Libs: -L${{libdir}} -l{0s}
|
|
232
|
+
, .{ name, repository.next().?, description, version });
|
|
195
233
|
|
|
196
|
-
|
|
234
|
+
const pc = b.fmt("lib{s}.pc", .{name});
|
|
235
|
+
if (@hasDecl(std.Build, "FindProgramOptions")) {
|
|
236
|
+
const write_file = b.addWriteFiles();
|
|
237
|
+
const pkgconfig = write_file.add(pc, content);
|
|
238
|
+
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
239
|
+
pkgconfig,
|
|
240
|
+
.prefix,
|
|
241
|
+
b.fmt("share/pkgconfig/{s}", .{pc}),
|
|
242
|
+
).step);
|
|
243
|
+
} else {
|
|
244
|
+
const cwd = try std.process.currentPathAlloc(b.graph.io, b.allocator);
|
|
245
|
+
const file = try std.Io.Dir.path.relative(
|
|
246
|
+
b.allocator,
|
|
247
|
+
cwd,
|
|
248
|
+
&b.graph.environ_map,
|
|
249
|
+
cwd,
|
|
250
|
+
try b.cache_root.join(b.allocator, &.{pc}),
|
|
251
|
+
);
|
|
252
|
+
const pkgconfig = try std.Io.Dir.cwd().createFile(b.graph.io, file, .{});
|
|
253
|
+
defer pkgconfig.close(b.graph.io);
|
|
254
|
+
|
|
255
|
+
var writer = pkgconfig.writer(b.graph.io, &.{});
|
|
256
|
+
try writer.interface.writeAll(content);
|
|
257
|
+
|
|
258
|
+
b.installFile(file, b.fmt("share/pkgconfig/{s}", .{pc}));
|
|
259
|
+
}
|
|
197
260
|
}
|
|
198
261
|
|
|
199
|
-
const config = .{
|
|
262
|
+
const config: Config = .{
|
|
200
263
|
.target = target,
|
|
201
264
|
.optimize = optimize,
|
|
202
265
|
.pic = pic,
|
|
@@ -207,10 +270,14 @@ pub fn build(b: *std.Build) !void {
|
|
|
207
270
|
// TODO: tests can be run multiple times due to @imports
|
|
208
271
|
const tests = TestStep.create(b, options, config);
|
|
209
272
|
|
|
210
|
-
var exes
|
|
273
|
+
var exes: ArrayList(*std.Build.Step.Compile) = .empty;
|
|
211
274
|
const tools: ToolConfig = .{
|
|
212
|
-
.
|
|
213
|
-
|
|
275
|
+
.options = .{
|
|
276
|
+
.showdown = showdown,
|
|
277
|
+
.log = log,
|
|
278
|
+
.chance = chance,
|
|
279
|
+
.calc = calc,
|
|
280
|
+
},
|
|
214
281
|
.general = config,
|
|
215
282
|
.tool = .{
|
|
216
283
|
.tests = if (tests.build) tests else null,
|
|
@@ -242,13 +309,97 @@ pub fn build(b: *std.Build) !void {
|
|
|
242
309
|
if (dump) |t| b.step("dump", "Run protocol dump tool").dependOn(&t.step);
|
|
243
310
|
if (fuzz) |t| b.step("fuzz", "Run fuzz tester").dependOn(&t.step);
|
|
244
311
|
if (serde) |t| b.step("serde", "Run serialization/deserialization tool").dependOn(&t.step);
|
|
245
|
-
b.step("test", "Run all tests").dependOn(
|
|
246
|
-
b.step("tools", "Install tools").dependOn(
|
|
312
|
+
b.step("test", "Run all tests").dependOn(tests.step);
|
|
313
|
+
b.step("tools", "Install tools").dependOn(ToolsStep.create(b, &exes).step);
|
|
247
314
|
if (transitions) |t| {
|
|
248
315
|
b.step("transitions", "Visualize transitions algorithm search").dependOn(&t.step);
|
|
249
316
|
}
|
|
250
317
|
}
|
|
251
318
|
|
|
319
|
+
fn buildWasm(
|
|
320
|
+
b: *std.Build,
|
|
321
|
+
name: []const u8,
|
|
322
|
+
root_src_file: []const u8,
|
|
323
|
+
optimize: std.builtin.OptimizeMode,
|
|
324
|
+
strip: ?bool,
|
|
325
|
+
pic: ?bool,
|
|
326
|
+
wasm_stack_size: u64,
|
|
327
|
+
import: ?*std.Build.Module,
|
|
328
|
+
options: anytype,
|
|
329
|
+
) !void {
|
|
330
|
+
const mode = switch (optimize) {
|
|
331
|
+
.ReleaseFast, .ReleaseSafe => .ReleaseSmall,
|
|
332
|
+
else => optimize,
|
|
333
|
+
};
|
|
334
|
+
// https://webassembly.org/features/
|
|
335
|
+
var features = std.Target.wasm.featureSet(&.{
|
|
336
|
+
.atomics,
|
|
337
|
+
.bulk_memory,
|
|
338
|
+
// .exception_handling,
|
|
339
|
+
.extended_const,
|
|
340
|
+
// .half_precision,
|
|
341
|
+
// .multimemory,
|
|
342
|
+
.mutable_globals,
|
|
343
|
+
.nontrapping_fptoint,
|
|
344
|
+
.reference_types,
|
|
345
|
+
// .relaxed_simd,
|
|
346
|
+
.sign_ext,
|
|
347
|
+
.simd128,
|
|
348
|
+
// .tail_call,
|
|
349
|
+
});
|
|
350
|
+
if (builtin.zig_version.order(try std.SemanticVersion.parse("0.12.0")) != .lt) {
|
|
351
|
+
features.addFeature(@intFromEnum(std.Target.wasm.Feature.multivalue));
|
|
352
|
+
}
|
|
353
|
+
const freestanding = b.resolveTargetQuery(.{
|
|
354
|
+
.cpu_arch = .wasm32,
|
|
355
|
+
.os_tag = .freestanding,
|
|
356
|
+
.cpu_features_add = features,
|
|
357
|
+
});
|
|
358
|
+
const path = b.path(root_src_file);
|
|
359
|
+
const exe = b.addExecutable(.{
|
|
360
|
+
.name = name,
|
|
361
|
+
.root_module = b.createModule(.{
|
|
362
|
+
.root_source_file = path,
|
|
363
|
+
.optimize = mode,
|
|
364
|
+
.target = freestanding,
|
|
365
|
+
.strip = strip,
|
|
366
|
+
.pic = pic,
|
|
367
|
+
}),
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
var file = try std.Io.Dir.cwd().openFile(b.graph.io, root_src_file, .{});
|
|
371
|
+
defer file.close(b.graph.io);
|
|
372
|
+
var reader = file.reader(b.graph.io, &.{});
|
|
373
|
+
const bytes = try reader.interface.allocRemaining(b.allocator, .unlimited);
|
|
374
|
+
exe.root_module.export_symbol_names = try exports(b, bytes);
|
|
375
|
+
exe.entry = .disabled;
|
|
376
|
+
|
|
377
|
+
if (import) |i| {
|
|
378
|
+
exe.root_module.addImport("pkmn", i);
|
|
379
|
+
}
|
|
380
|
+
exe.stack_size = wasm_stack_size;
|
|
381
|
+
exe.root_module.addOptions("build_options", options);
|
|
382
|
+
|
|
383
|
+
const opt = if (@hasDecl(std.Build, "FindProgramOptions")) blk: {
|
|
384
|
+
if (exists(b, "./node_modules/.bin/wasm-opt") catch false) {
|
|
385
|
+
break :blk "./node_modules/.bin/wasm-opt";
|
|
386
|
+
}
|
|
387
|
+
break :blk b.findProgram(.{ .names = &.{"wasm-opt"} });
|
|
388
|
+
} else b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
|
|
389
|
+
if (optimize != .Debug and opt != null) {
|
|
390
|
+
const out = b.fmt("build/lib/{s}.wasm", .{name});
|
|
391
|
+
const sh = b.addSystemCommand(&.{ opt.?, "--enable-bulk-memory", "--enable-simd", "-O4" });
|
|
392
|
+
sh.addArtifactArg(exe);
|
|
393
|
+
sh.addArg("-o");
|
|
394
|
+
sh.addFileArg(b.path(out));
|
|
395
|
+
b.getInstallStep().dependOn(&sh.step);
|
|
396
|
+
} else {
|
|
397
|
+
b.getInstallStep().dependOn(&b.addInstallArtifact(exe, .{
|
|
398
|
+
.dest_dir = .{ .override = std.Build.InstallDir{ .lib = {} } },
|
|
399
|
+
}).step);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
252
403
|
fn maybeStrip(
|
|
253
404
|
b: *std.Build,
|
|
254
405
|
artifact: *std.Build.Step.Compile,
|
|
@@ -276,7 +427,7 @@ const Config = struct {
|
|
|
276
427
|
};
|
|
277
428
|
|
|
278
429
|
const TestStep = struct {
|
|
279
|
-
step: std.Build.Step,
|
|
430
|
+
step: *std.Build.Step,
|
|
280
431
|
build: bool,
|
|
281
432
|
|
|
282
433
|
pub fn create(b: *std.Build, options: *std.Build.Step.Options, config: Config) *TestStep {
|
|
@@ -285,79 +436,146 @@ const TestStep = struct {
|
|
|
285
436
|
b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
|
286
437
|
|
|
287
438
|
const self = b.allocator.create(TestStep) catch @panic("OOM");
|
|
288
|
-
const step = std.Build.Step.init(.{ .id = .custom, .name = "Run all tests", .owner = b });
|
|
289
|
-
self.* = .{ .step = step, .build = test_filter == null };
|
|
290
439
|
|
|
440
|
+
const path = b.path("src/lib/test.zig");
|
|
291
441
|
const tests = b.addTest(.{
|
|
292
|
-
.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
442
|
+
.root_module = b.createModule(.{
|
|
443
|
+
.root_source_file = path,
|
|
444
|
+
.optimize = config.optimize,
|
|
445
|
+
.target = config.target,
|
|
446
|
+
.single_threaded = true,
|
|
447
|
+
.strip = config.strip,
|
|
448
|
+
.pic = config.pic,
|
|
449
|
+
}),
|
|
450
|
+
.filters = if (test_filter) |filter| &.{filter} else &.{},
|
|
299
451
|
});
|
|
300
452
|
tests.root_module.addOptions("build_options", options);
|
|
453
|
+
|
|
301
454
|
maybeStrip(b, tests, &tests.step, config.strip, config.cmd);
|
|
302
455
|
if (coverage) |c| {
|
|
303
456
|
tests.setExecCmd(&.{ "kcov", "--include-pattern=src/lib", c, null });
|
|
304
457
|
}
|
|
305
|
-
|
|
458
|
+
|
|
459
|
+
if (@hasDecl(std.Build, "FindProgramOptions")) {
|
|
460
|
+
const run_step = b.addRunArtifact(tests);
|
|
461
|
+
self.* = .{ .step = &run_step.step, .build = test_filter == null };
|
|
462
|
+
} else {
|
|
463
|
+
const custom_step = b.allocator.create(std.Build.Step) catch @panic("OOM");
|
|
464
|
+
custom_step.* = std.Build.Step.init(.{
|
|
465
|
+
.id = .custom,
|
|
466
|
+
.name = "Run all tests",
|
|
467
|
+
.owner = b,
|
|
468
|
+
});
|
|
469
|
+
custom_step.dependOn(&b.addRunArtifact(tests).step);
|
|
470
|
+
self.* = .{ .step = custom_step, .build = test_filter == null };
|
|
471
|
+
}
|
|
306
472
|
|
|
307
473
|
return self;
|
|
308
474
|
}
|
|
309
475
|
};
|
|
310
476
|
|
|
311
477
|
const ToolConfig = struct {
|
|
312
|
-
|
|
313
|
-
module: *std.Build.Module,
|
|
478
|
+
options: Options,
|
|
314
479
|
general: Config,
|
|
315
480
|
tool: struct {
|
|
316
481
|
tests: ?*TestStep,
|
|
317
482
|
name: ?[]const u8 = null,
|
|
318
|
-
exes: *
|
|
483
|
+
exes: *ArrayList(*std.Build.Step.Compile),
|
|
319
484
|
},
|
|
320
485
|
};
|
|
321
486
|
|
|
322
487
|
fn tool(b: *std.Build, path: []const u8, config: ToolConfig) !?*std.Build.Step.Run {
|
|
323
|
-
|
|
324
|
-
error.FileNotFound => return null,
|
|
325
|
-
else => |e| return e,
|
|
326
|
-
};
|
|
488
|
+
if (!try exists(b, path)) return null;
|
|
327
489
|
var name = config.tool.name orelse std.fs.path.basename(path);
|
|
328
490
|
const index = std.mem.lastIndexOfScalar(u8, name, '.');
|
|
329
491
|
if (index) |i| name = name[0..i];
|
|
330
|
-
if (config.showdown orelse false) name = b.fmt("{s}-showdown", .{name});
|
|
492
|
+
if (config.options.showdown orelse false) name = b.fmt("{s}-showdown", .{name});
|
|
331
493
|
|
|
332
494
|
const exe = b.addExecutable(.{
|
|
333
495
|
.name = name,
|
|
334
|
-
.
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
496
|
+
.root_module = b.createModule(.{
|
|
497
|
+
.root_source_file = b.path(path),
|
|
498
|
+
.target = config.general.target,
|
|
499
|
+
.optimize = config.general.optimize,
|
|
500
|
+
.strip = config.general.strip,
|
|
501
|
+
.pic = config.general.pic,
|
|
502
|
+
}),
|
|
340
503
|
});
|
|
341
|
-
|
|
504
|
+
|
|
505
|
+
const import = module(b, config.options, config.general.target, config.general.optimize);
|
|
506
|
+
exe.root_module.addImport("pkmn", import);
|
|
507
|
+
if (config.general.target.result.os.tag == .windows) {
|
|
508
|
+
exe.root_module.linkSystemLibrary("advapi32", .{});
|
|
509
|
+
}
|
|
342
510
|
|
|
343
511
|
if (config.tool.tests) |ts| ts.step.dependOn(&exe.step);
|
|
344
|
-
config.tool.exes.append(exe) catch @panic("OOM");
|
|
512
|
+
config.tool.exes.append(b.allocator, exe) catch @panic("OOM");
|
|
345
513
|
|
|
346
514
|
const run = b.addRunArtifact(exe);
|
|
347
515
|
maybeStrip(b, exe, &run.step, config.general.strip, config.general.cmd);
|
|
348
|
-
if (
|
|
516
|
+
if (@hasDecl(std.Build, "FindProgramOptions")) {
|
|
517
|
+
run.addPassthruArgs();
|
|
518
|
+
} else {
|
|
519
|
+
if (b.args) |args| run.addArgs(args);
|
|
520
|
+
}
|
|
349
521
|
|
|
350
522
|
return run;
|
|
351
523
|
}
|
|
352
524
|
|
|
525
|
+
fn exists(b: *std.Build, path: []const u8) !bool {
|
|
526
|
+
std.Io.Dir.cwd().access(b.graph.io, path, .{}) catch |err| switch (err) {
|
|
527
|
+
error.FileNotFound => return false,
|
|
528
|
+
else => |e| return e,
|
|
529
|
+
};
|
|
530
|
+
return true;
|
|
531
|
+
}
|
|
532
|
+
|
|
353
533
|
const ToolsStep = struct {
|
|
354
|
-
step: std.Build.Step,
|
|
534
|
+
step: *std.Build.Step,
|
|
355
535
|
|
|
356
|
-
pub fn create(b: *std.Build, exes: *
|
|
536
|
+
pub fn create(b: *std.Build, exes: *ArrayList(*std.Build.Step.Compile)) *ToolsStep {
|
|
357
537
|
const self = b.allocator.create(ToolsStep) catch @panic("OOM");
|
|
358
|
-
|
|
359
|
-
|
|
538
|
+
|
|
539
|
+
if (@hasDecl(std.Build, "FindProgramOptions")) {
|
|
540
|
+
const step = b.allocator.create(std.Build.Step.TopLevel) catch @panic("OOM");
|
|
541
|
+
step.* = .{
|
|
542
|
+
.step = std.Build.Step.init(.{
|
|
543
|
+
.tag = .top_level,
|
|
544
|
+
.name = "Install tools",
|
|
545
|
+
.owner = b,
|
|
546
|
+
}),
|
|
547
|
+
.description = "Install tools",
|
|
548
|
+
};
|
|
549
|
+
self.* = .{ .step = &step.step };
|
|
550
|
+
} else {
|
|
551
|
+
const step = b.allocator.create(std.Build.Step) catch @panic("OOM");
|
|
552
|
+
step.* = std.Build.Step.init(.{
|
|
553
|
+
.id = .custom,
|
|
554
|
+
.name = "Install tools",
|
|
555
|
+
.owner = b,
|
|
556
|
+
});
|
|
557
|
+
self.* = .{ .step = step };
|
|
558
|
+
}
|
|
360
559
|
for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t, .{}).step);
|
|
560
|
+
|
|
361
561
|
return self;
|
|
362
562
|
}
|
|
363
563
|
};
|
|
564
|
+
|
|
565
|
+
pub fn exports(b: *std.Build, bytes: []const u8) ![][]const u8 {
|
|
566
|
+
var symbols: ArrayList([]const u8) = .empty;
|
|
567
|
+
|
|
568
|
+
var it = std.mem.splitSequence(u8, bytes, "export ");
|
|
569
|
+
_ = it.next();
|
|
570
|
+
while (it.next()) |s| {
|
|
571
|
+
if (std.mem.startsWith(u8, s, "const ")) {
|
|
572
|
+
const i = std.mem.indexOf(u8, s[6..], " ").?;
|
|
573
|
+
try symbols.append(b.allocator, s[6 .. 6 + i]);
|
|
574
|
+
} else { // "fn "
|
|
575
|
+
const i = std.mem.indexOf(u8, s[3..], "(").?;
|
|
576
|
+
try symbols.append(b.allocator, s[3 .. 3 + i]);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
return symbols.items;
|
|
581
|
+
}
|