Skip to content

Commit 5d74cb0

Browse files
committed
core: Remove main_window in favor of users creating their own windows. Added event window_open which is called when the platform has finished initializing the window
1 parent b33f855 commit 5d74cb0

File tree

4 files changed

+72
-50
lines changed

4 files changed

+72
-50
lines changed

examples/core-custom-entrypoint/App.zig

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub const mach_module = .app;
77

88
pub const mach_systems = .{ .main, .init, .deinit, .tick };
99

10+
window: mach.ObjectID,
1011
title_timer: mach.time.Timer,
1112
pipeline: *gpu.RenderPipeline,
1213

@@ -28,18 +29,33 @@ pub fn init(
2829
core.on_tick = app_mod.id.tick;
2930
core.on_exit = app_mod.id.deinit;
3031

31-
const main_window = core.windows.getValue(core.main_window);
32+
const window = try core.windows.new(.{ .title = "core-custom-entrypoint" });
33+
34+
// Store our render pipeline in our module's state, so we can access it later on.
35+
app.* = .{
36+
.window = window,
37+
.title_timer = try mach.time.Timer.start(),
38+
.pipeline = undefined,
39+
};
40+
41+
// TODO(object): window-title
42+
// try updateWindowTitle(core);
43+
}
44+
45+
fn setupPipeline(core: *mach.Core, app: *App, window_id: mach.ObjectID) !void {
46+
_ = window_id; // autofix
47+
const window = core.windows.getValue(app.window);
3248

3349
// Create our shader module
34-
const shader_module = main_window.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
50+
const shader_module = window.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
3551
defer shader_module.release();
3652

3753
// Blend state describes how rendered colors get blended
3854
const blend = gpu.BlendState{};
3955

4056
// Color target describes e.g. the pixel format of the window we are rendering to.
4157
const color_target = gpu.ColorTargetState{
42-
.format = main_window.framebuffer_format,
58+
.format = window.framebuffer_format,
4359
.blend = &blend,
4460
};
4561

@@ -60,36 +76,31 @@ pub fn init(
6076
.entry_point = "vertex_main",
6177
},
6278
};
63-
const pipeline = main_window.device.createRenderPipeline(&pipeline_descriptor);
64-
65-
// Store our render pipeline in our module's state, so we can access it later on.
66-
app.* = .{
67-
.title_timer = try mach.time.Timer.start(),
68-
.pipeline = pipeline,
69-
};
7079

71-
// TODO(object): window-title
72-
// try updateWindowTitle(core);
80+
app.pipeline = window.device.createRenderPipeline(&pipeline_descriptor);
7381
}
7482

7583
pub fn tick(core: *mach.Core, app: *App) !void {
7684
while (core.nextEvent()) |event| {
7785
switch (event) {
86+
.window_open => |ev| {
87+
try setupPipeline(core, app, ev.window_id);
88+
},
7889
.close => core.exit(),
7990
else => {},
8091
}
8192
}
8293

83-
const main_window = core.windows.getValue(core.main_window);
94+
const window = core.windows.getValue(app.window);
8495

8596
// Grab the back buffer of the swapchain
8697
// TODO(Core)
87-
const back_buffer_view = main_window.swap_chain.getCurrentTextureView().?;
98+
const back_buffer_view = window.swap_chain.getCurrentTextureView().?;
8899
defer back_buffer_view.release();
89100

90101
// Create a command encoder
91102
const label = @tagName(mach_module) ++ ".tick";
92-
const encoder = main_window.device.createCommandEncoder(&.{ .label = label });
103+
const encoder = window.device.createCommandEncoder(&.{ .label = label });
93104
defer encoder.release();
94105

95106
// Begin render pass
@@ -116,7 +127,7 @@ pub fn tick(core: *mach.Core, app: *App) !void {
116127
// Submit our commands to the queue
117128
var command = encoder.finish(&.{ .label = label });
118129
defer command.release();
119-
main_window.queue.submit(&[_]*gpu.CommandBuffer{command});
130+
window.queue.submit(&[_]*gpu.CommandBuffer{command});
120131

121132
// update the window title every second
122133
if (app.title_timer.read() >= 1.0) {

examples/core-triangle/App.zig

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub const main = mach.schedule(.{
1414
.{ mach.Core, .main },
1515
});
1616

17+
window: mach.ObjectID,
1718
title_timer: mach.time.Timer,
1819
pipeline: *gpu.RenderPipeline,
1920

@@ -25,18 +26,32 @@ pub fn init(
2526
core.on_tick = app_mod.id.tick;
2627
core.on_exit = app_mod.id.deinit;
2728

28-
const main_window = core.windows.getValue(core.main_window);
29+
const window = try core.windows.new(.{
30+
.title = "core-triangle",
31+
});
32+
33+
// Store our render pipeline in our module's state, so we can access it later on.
34+
app.* = .{
35+
.window = window,
36+
.title_timer = try mach.time.Timer.start(),
37+
.pipeline = undefined,
38+
};
39+
}
40+
41+
fn setupPipeline(core: *mach.Core, app: *App, window_id: mach.ObjectID) !void {
42+
var window = core.windows.getValue(window_id);
43+
defer core.windows.setValueRaw(window_id, window);
2944

3045
// Create our shader module
31-
const shader_module = main_window.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
46+
const shader_module = window.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
3247
defer shader_module.release();
3348

3449
// Blend state describes how rendered colors get blended
3550
const blend = gpu.BlendState{};
3651

3752
// Color target describes e.g. the pixel format of the window we are rendering to.
3853
const color_target = gpu.ColorTargetState{
39-
.format = main_window.framebuffer_format,
54+
.format = window.framebuffer_format,
4055
.blend = &blend,
4156
};
4257

@@ -57,13 +72,7 @@ pub fn init(
5772
.entry_point = "vertex_main",
5873
},
5974
};
60-
const pipeline = main_window.device.createRenderPipeline(&pipeline_descriptor);
61-
62-
// Store our render pipeline in our module's state, so we can access it later on.
63-
app.* = .{
64-
.title_timer = try mach.time.Timer.start(),
65-
.pipeline = pipeline,
66-
};
75+
app.pipeline = window.device.createRenderPipeline(&pipeline_descriptor);
6776
}
6877

6978
// TODO(object): window-title
@@ -72,19 +81,22 @@ pub fn init(
7281
pub fn tick(app: *App, core: *mach.Core) void {
7382
while (core.nextEvent()) |event| {
7483
switch (event) {
84+
.window_open => |ev| {
85+
try setupPipeline(core, app, ev.window_id);
86+
},
7587
.key_press => |ev| {
7688
switch (ev.key) {
7789
.right => {
78-
core.windows.set(core.main_window, .width, core.windows.get(core.main_window, .width) + 10);
90+
core.windows.set(app.window, .width, core.windows.get(app.window, .width) + 10);
7991
},
8092
.left => {
81-
core.windows.set(core.main_window, .width, core.windows.get(core.main_window, .width) - 10);
93+
core.windows.set(app.window, .width, core.windows.get(app.window, .width) - 10);
8294
},
8395
.up => {
84-
core.windows.set(core.main_window, .height, core.windows.get(core.main_window, .height) + 10);
96+
core.windows.set(app.window, .height, core.windows.get(app.window, .height) + 10);
8597
},
8698
.down => {
87-
core.windows.set(core.main_window, .height, core.windows.get(core.main_window, .height) - 10);
99+
core.windows.set(app.window, .height, core.windows.get(app.window, .height) - 10);
88100
},
89101
else => {},
90102
}
@@ -94,17 +106,17 @@ pub fn tick(app: *App, core: *mach.Core) void {
94106
}
95107
}
96108

97-
const main_window = core.windows.getValue(core.main_window);
109+
const window = core.windows.getValue(app.window);
98110

99111
// Grab the back buffer of the swapchain
100112
// TODO(Core)
101-
const back_buffer_view = main_window.swap_chain.getCurrentTextureView().?;
113+
const back_buffer_view = window.swap_chain.getCurrentTextureView().?;
102114
defer back_buffer_view.release();
103115

104116
// Create a command encoder
105117
const label = @tagName(mach_module) ++ ".tick";
106118

107-
const encoder = main_window.device.createCommandEncoder(&.{ .label = label });
119+
const encoder = window.device.createCommandEncoder(&.{ .label = label });
108120
defer encoder.release();
109121

110122
// Begin render pass
@@ -131,7 +143,7 @@ pub fn tick(app: *App, core: *mach.Core) void {
131143
// Submit our commands to the queue
132144
var command = encoder.finish(&.{ .label = label });
133145
defer command.release();
134-
main_window.queue.submit(&[_]*gpu.CommandBuffer{command});
146+
window.queue.submit(&[_]*gpu.CommandBuffer{command});
135147

136148
// update the window title every second
137149
// if (app.title_timer.read() >= 1.0) {

examples/play-opus/App.zig

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub const deinit = mach.schedule(.{
2828
.{ mach.Audio, .deinit },
2929
});
3030

31+
window: mach.ObjectID,
3132
/// Tag object we set as a child of mach.Audio objects to indicate they are background music.
3233
// TODO(object): consider adding a better object 'tagging' system?
3334
bgm: mach.Objects(.{}, struct {}),
@@ -46,6 +47,10 @@ pub fn init(
4647
core.on_tick = app_mod.id.tick;
4748
core.on_exit = app_mod.id.deinit;
4849

50+
const window = try core.windows.new(.{
51+
.title = "play-opus",
52+
});
53+
4954
// Configure the audio module to send our app's .audio_state_change event when an entity's sound
5055
// finishes playing.
5156
audio.on_state_change = app_mod.id.audioStateChange;
@@ -61,7 +66,7 @@ pub fn init(
6166
const sfx = try mach.Audio.Opus.decodeStream(allocator, sfx_sound_stream);
6267

6368
// Initialize module state
64-
app.* = .{ .sfx = sfx, .bgm = app.bgm };
69+
app.* = .{ .sfx = sfx, .bgm = app.bgm, .window = window };
6570

6671
const bgm_buffer = blk: {
6772
audio.buffers.lock();
@@ -138,16 +143,16 @@ pub fn tick(
138143
}
139144
}
140145

141-
var main_window = core.windows.getValue(core.main_window);
146+
var window = core.windows.getValue(app.window);
142147

143148
// Grab the back buffer of the swapchain
144149
// TODO(Core)
145-
const back_buffer_view = main_window.swap_chain.getCurrentTextureView().?;
150+
const back_buffer_view = window.swap_chain.getCurrentTextureView().?;
146151
defer back_buffer_view.release();
147152

148153
// Create a command encoder
149154
const label = @tagName(mach_module) ++ ".tick";
150-
const encoder = main_window.device.createCommandEncoder(&.{ .label = label });
155+
const encoder = window.device.createCommandEncoder(&.{ .label = label });
151156
defer encoder.release();
152157

153158
// Begin render pass
@@ -172,5 +177,5 @@ pub fn tick(
172177
// Submit our commands to the queue
173178
var command = encoder.finish(&.{ .label = label });
174179
defer command.release();
175-
main_window.queue.submit(&[_]*gpu.CommandBuffer{command});
180+
window.queue.submit(&[_]*gpu.CommandBuffer{command});
176181
}

src/Core.zig

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,6 @@ on_tick: ?mach.FunctionID = null,
106106
/// Callback system invoked when application is exiting
107107
on_exit: ?mach.FunctionID = null,
108108

109-
/// Main window of the application
110-
main_window: mach.ObjectID,
111-
112109
/// Current state of the application
113110
state: enum {
114111
running,
@@ -132,8 +129,6 @@ pub fn init(core: *Core) !void {
132129
// TODO: fix all leaks and use options.allocator
133130
try mach.sysgpu.Impl.init(allocator, .{});
134131

135-
const main_window = try core.windows.new(.{});
136-
137132
var events = EventQueue.init(allocator);
138133
try events.ensureTotalCapacity(8192);
139134

@@ -142,19 +137,13 @@ pub fn init(core: *Core) !void {
142137
.windows = core.windows,
143138

144139
.allocator = allocator,
145-
.main_window = main_window,
146140
.events = events,
147141
.input_state = .{},
148142

149143
.input = .{ .target = 0 },
150144
.frame = .{ .target = 1 },
151145
};
152146

153-
// Tick the platform so that the platform can grab the newly created window
154-
// and perform initialization
155-
// TODO: consider removing `main_window` and then this wont be necessary
156-
try Platform.tick(core);
157-
158147
try core.frame.start();
159148
try core.input.start();
160149
}
@@ -229,6 +218,8 @@ pub fn initWindow(core: *Core, window_id: mach.ObjectID) !void {
229218
core_window.framebuffer_format = core_window.swap_chain_descriptor.format;
230219
core_window.framebuffer_width = core_window.swap_chain_descriptor.width;
231220
core_window.framebuffer_height = core_window.swap_chain_descriptor.height;
221+
222+
core.pushEvent(.{ .window_open = .{ .window_id = window_id } });
232223
}
233224

234225
pub fn tick(core: *Core, core_mod: mach.Mod(Core)) !void {
@@ -686,6 +677,9 @@ pub const Event = union(enum) {
686677
yoffset: f32,
687678
},
688679
window_resize: ResizeEvent,
680+
window_open: struct {
681+
window_id: mach.ObjectID,
682+
},
689683
focus_gained: struct {
690684
window_id: mach.ObjectID,
691685
},

0 commit comments

Comments
 (0)