implements PLN-0081 shell hub packet migration
This commit is contained in:
parent
ae85ed4eff
commit
74df4b89ac
@ -5,7 +5,7 @@ use prometeu_hal::glyph_bank::GlyphBank;
|
|||||||
use prometeu_hal::scene_viewport_cache::{CachedTileEntry, SceneViewportCache};
|
use prometeu_hal::scene_viewport_cache::{CachedTileEntry, SceneViewportCache};
|
||||||
use prometeu_hal::scene_viewport_resolver::{LayerCopyRequest, ResolverUpdate};
|
use prometeu_hal::scene_viewport_resolver::{LayerCopyRequest, ResolverUpdate};
|
||||||
use prometeu_hal::sprite::Sprite;
|
use prometeu_hal::sprite::Sprite;
|
||||||
use prometeu_hal::{Game2DFramePacket, Gfx2dCommand, GfxBridge};
|
use prometeu_hal::{Game2DFramePacket, Gfx2dCommand, GfxBridge, GfxUiCommand, ShellUiFramePacket};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Blending modes inspired by classic 16-bit hardware.
|
/// Blending modes inspired by classic 16-bit hardware.
|
||||||
@ -714,6 +714,12 @@ impl Gfx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_shell_ui_frame_packet(&mut self, packet: &ShellUiFramePacket) {
|
||||||
|
for command in &packet.commands {
|
||||||
|
self.apply_gfxui_command(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn apply_gfx2d_command(&mut self, command: &Gfx2dCommand) {
|
fn apply_gfx2d_command(&mut self, command: &Gfx2dCommand) {
|
||||||
match command {
|
match command {
|
||||||
Gfx2dCommand::Clear { color } => self.clear(*color),
|
Gfx2dCommand::Clear { color } => self.clear(*color),
|
||||||
@ -738,6 +744,30 @@ impl Gfx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_gfxui_command(&mut self, command: &GfxUiCommand) {
|
||||||
|
match command {
|
||||||
|
GfxUiCommand::Clear { color } => self.clear(*color),
|
||||||
|
GfxUiCommand::FillRect { rect, color } => {
|
||||||
|
self.fill_rect(rect.x, rect.y, rect.w, rect.h, *color);
|
||||||
|
}
|
||||||
|
GfxUiCommand::DrawLine { x0, y0, x1, y1, color } => {
|
||||||
|
self.draw_line(*x0, *y0, *x1, *y1, *color);
|
||||||
|
}
|
||||||
|
GfxUiCommand::DrawCircle { x, y, radius, color } => {
|
||||||
|
self.draw_circle(*x, *y, *radius, *color);
|
||||||
|
}
|
||||||
|
GfxUiCommand::DrawDisc { x, y, radius, border_color, fill_color } => {
|
||||||
|
self.draw_disc(*x, *y, *radius, *border_color, *fill_color);
|
||||||
|
}
|
||||||
|
GfxUiCommand::DrawSquare { rect, border_color, fill_color } => {
|
||||||
|
self.draw_square(rect.x, rect.y, rect.w, rect.h, *border_color, *fill_color);
|
||||||
|
}
|
||||||
|
GfxUiCommand::DrawText { x, y, text, color } => {
|
||||||
|
self.draw_text(*x, *y, text, *color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn populate_layer_buckets(&mut self) {
|
fn populate_layer_buckets(&mut self) {
|
||||||
for bucket in self.layer_buckets.iter_mut() {
|
for bucket in self.layer_buckets.iter_mut() {
|
||||||
bucket.clear();
|
bucket.clear();
|
||||||
|
|||||||
@ -8,10 +8,10 @@ use crate::memory_banks::{
|
|||||||
};
|
};
|
||||||
use crate::pad::Pad;
|
use crate::pad::Pad;
|
||||||
use crate::touch::Touch;
|
use crate::touch::Touch;
|
||||||
use prometeu_hal::Game2DFramePacket;
|
|
||||||
use prometeu_hal::cartridge::AssetsPayloadSource;
|
use prometeu_hal::cartridge::AssetsPayloadSource;
|
||||||
use prometeu_hal::sprite::Sprite;
|
use prometeu_hal::sprite::Sprite;
|
||||||
use prometeu_hal::{AssetBridge, AudioBridge, GfxBridge, HardwareBridge, PadBridge, TouchBridge};
|
use prometeu_hal::{AssetBridge, AudioBridge, GfxBridge, HardwareBridge, PadBridge, TouchBridge};
|
||||||
|
use prometeu_hal::{Game2DFramePacket, ShellUiFramePacket};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Aggregate structure for all virtual hardware peripherals.
|
/// Aggregate structure for all virtual hardware peripherals.
|
||||||
@ -72,6 +72,10 @@ impl HardwareBridge for Hardware {
|
|||||||
self.frame_composer.close_game2d_packet()
|
self.frame_composer.close_game2d_packet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_shell_ui_packet(&mut self, packet: &ShellUiFramePacket) {
|
||||||
|
self.gfx.render_shell_ui_frame_packet(packet);
|
||||||
|
}
|
||||||
|
|
||||||
fn render_frame(&mut self) {
|
fn render_frame(&mut self) {
|
||||||
if self.frame_composer.active_scene_id().is_none() {
|
if self.frame_composer.active_scene_id().is_none() {
|
||||||
let packet = self.frame_composer.close_game2d_packet();
|
let packet = self.frame_composer.close_game2d_packet();
|
||||||
@ -81,6 +85,10 @@ impl HardwareBridge for Hardware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn present(&mut self) {
|
||||||
|
self.gfx.present();
|
||||||
|
}
|
||||||
|
|
||||||
fn has_glyph_bank(&self, bank_id: usize) -> bool {
|
fn has_glyph_bank(&self, bank_id: usize) -> bool {
|
||||||
self.gfx.glyph_banks.glyph_bank_slot(bank_id).is_some()
|
self.gfx.glyph_banks.glyph_bank_slot(bank_id).is_some()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use crate::asset_bridge::AssetBridge;
|
|||||||
use crate::audio_bridge::AudioBridge;
|
use crate::audio_bridge::AudioBridge;
|
||||||
use crate::gfx_bridge::GfxBridge;
|
use crate::gfx_bridge::GfxBridge;
|
||||||
use crate::pad_bridge::PadBridge;
|
use crate::pad_bridge::PadBridge;
|
||||||
use crate::render_submission::Game2DFramePacket;
|
use crate::render_submission::{Game2DFramePacket, ShellUiFramePacket};
|
||||||
use crate::sprite::Sprite;
|
use crate::sprite::Sprite;
|
||||||
use crate::touch_bridge::TouchBridge;
|
use crate::touch_bridge::TouchBridge;
|
||||||
|
|
||||||
@ -13,7 +13,9 @@ pub trait HardwareBridge {
|
|||||||
fn set_camera(&mut self, x: i32, y: i32);
|
fn set_camera(&mut self, x: i32, y: i32);
|
||||||
fn emit_sprite(&mut self, sprite: Sprite) -> bool;
|
fn emit_sprite(&mut self, sprite: Sprite) -> bool;
|
||||||
fn close_game2d_packet(&self) -> Game2DFramePacket;
|
fn close_game2d_packet(&self) -> Game2DFramePacket;
|
||||||
|
fn render_shell_ui_packet(&mut self, packet: &ShellUiFramePacket);
|
||||||
fn render_frame(&mut self);
|
fn render_frame(&mut self);
|
||||||
|
fn present(&mut self);
|
||||||
fn has_glyph_bank(&self, bank_id: usize) -> bool;
|
fn has_glyph_bank(&self, bank_id: usize) -> bool;
|
||||||
|
|
||||||
fn gfx(&self) -> &dyn GfxBridge;
|
fn gfx(&self) -> &dyn GfxBridge;
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
use crate::{CrashReport, SystemOS};
|
use crate::{CrashReport, SystemOS};
|
||||||
use prometeu_hal::color::Color;
|
use prometeu_hal::color::Color;
|
||||||
use prometeu_hal::gfx_bridge::GfxBridge;
|
|
||||||
use prometeu_hal::primitives::Rect;
|
use prometeu_hal::primitives::Rect;
|
||||||
use prometeu_hal::{HardwareBridge, InputSignals};
|
use prometeu_hal::{GfxUiCommand, HardwareBridge, InputSignals, ShellUiFramePacket};
|
||||||
use prometeu_vm::VirtualMachine;
|
use prometeu_vm::VirtualMachine;
|
||||||
|
|
||||||
const SHELL_A_BUTTON: Rect = Rect { x: 112, y: 108, w: 112, h: 48 };
|
const SHELL_A_BUTTON: Rect = Rect { x: 112, y: 108, w: 112, h: 48 };
|
||||||
@ -101,8 +100,6 @@ impl PrometeuHub {
|
|||||||
os: &mut SystemOS,
|
os: &mut SystemOS,
|
||||||
hw: &mut dyn HardwareBridge,
|
hw: &mut dyn HardwareBridge,
|
||||||
) -> Option<SystemProfileAction> {
|
) -> Option<SystemProfileAction> {
|
||||||
hw.gfx_mut().clear(Color::INDIGO);
|
|
||||||
|
|
||||||
let in_shell = os.windows().focused_window().is_some();
|
let in_shell = os.windows().focused_window().is_some();
|
||||||
|
|
||||||
if !in_shell {
|
if !in_shell {
|
||||||
@ -127,21 +124,23 @@ impl PrometeuHub {
|
|||||||
let pointer_x = hw.touch().x();
|
let pointer_x = hw.touch().x();
|
||||||
let pointer_y = hw.touch().y();
|
let pointer_y = hw.touch().y();
|
||||||
|
|
||||||
if os.windows().window_count() == 0 {
|
let packet = if os.windows().window_count() == 0 {
|
||||||
render_home(hw.gfx_mut(), pointer_x, pointer_y);
|
render_home_packet(pointer_x, pointer_y)
|
||||||
return;
|
} else {
|
||||||
}
|
let mut commands = Vec::new();
|
||||||
|
for window in os.windows().windows() {
|
||||||
for window in os.windows().windows() {
|
append_shell_window_commands(
|
||||||
render_shell_window(
|
&mut commands,
|
||||||
hw.gfx_mut(),
|
window.viewport,
|
||||||
window.viewport,
|
window.color,
|
||||||
window.color,
|
&window.title,
|
||||||
&window.title,
|
pointer_x,
|
||||||
pointer_x,
|
pointer_y,
|
||||||
pointer_y,
|
);
|
||||||
);
|
}
|
||||||
}
|
ShellUiFramePacket::new(commands)
|
||||||
|
};
|
||||||
|
hw.render_shell_ui_packet(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_shell_profile(
|
pub fn update_shell_profile(
|
||||||
@ -163,7 +162,7 @@ impl PrometeuHub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.render(os, hw);
|
self.render(os, hw);
|
||||||
hw.gfx_mut().present();
|
hw.present();
|
||||||
|
|
||||||
SystemProfileUpdate { crash, action }
|
SystemProfileUpdate { crash, action }
|
||||||
}
|
}
|
||||||
@ -192,15 +191,29 @@ fn activation_input_down(hw: &dyn HardwareBridge) -> bool {
|
|||||||
hw.touch().f().down || hw.pad().a().down || hw.pad().b().down || hw.pad().start().down
|
hw.touch().f().down || hw.pad().a().down || hw.pad().b().down || hw.pad().start().down
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_home(gfx: &mut dyn GfxBridge, pointer_x: i32, pointer_y: i32) {
|
fn render_home_packet(pointer_x: i32, pointer_y: i32) -> ShellUiFramePacket {
|
||||||
gfx.fill_rect(VIEWPORT.x, VIEWPORT.y, VIEWPORT.w, VIEWPORT.h, COLOR_BG);
|
let mut commands = Vec::new();
|
||||||
draw_panel(gfx, TITLE_PANEL, COLOR_PANEL_DARK, COLOR_BORDER);
|
commands.push(GfxUiCommand::Clear { color: COLOR_BG });
|
||||||
draw_buffer_text(gfx, TITLE_PANEL.x + 58, TITLE_PANEL.y + 9, "PROMETEU HUB", COLOR_TEXT);
|
fill_rect(&mut commands, VIEWPORT, COLOR_BG);
|
||||||
|
draw_panel(&mut commands, TITLE_PANEL, COLOR_PANEL_DARK, COLOR_BORDER);
|
||||||
draw_panel(gfx, HOME_PANEL, COLOR_PANEL, COLOR_BORDER);
|
|
||||||
draw_buffer_text(gfx, HOME_PANEL.x + 26, HOME_PANEL.y + 22, "Native Shell Apps", COLOR_TEXT);
|
|
||||||
draw_buffer_text(
|
draw_buffer_text(
|
||||||
gfx,
|
&mut commands,
|
||||||
|
TITLE_PANEL.x + 58,
|
||||||
|
TITLE_PANEL.y + 9,
|
||||||
|
"PROMETEU HUB",
|
||||||
|
COLOR_TEXT,
|
||||||
|
);
|
||||||
|
|
||||||
|
draw_panel(&mut commands, HOME_PANEL, COLOR_PANEL, COLOR_BORDER);
|
||||||
|
draw_buffer_text(
|
||||||
|
&mut commands,
|
||||||
|
HOME_PANEL.x + 26,
|
||||||
|
HOME_PANEL.y + 22,
|
||||||
|
"Native Shell Apps",
|
||||||
|
COLOR_TEXT,
|
||||||
|
);
|
||||||
|
draw_buffer_text(
|
||||||
|
&mut commands,
|
||||||
HOME_PANEL.x + 26,
|
HOME_PANEL.x + 26,
|
||||||
HOME_PANEL.y + 40,
|
HOME_PANEL.y + 40,
|
||||||
"first retro ui slice",
|
"first retro ui slice",
|
||||||
@ -209,50 +222,105 @@ fn render_home(gfx: &mut dyn GfxBridge, pointer_x: i32, pointer_y: i32) {
|
|||||||
|
|
||||||
for button in HOME_BUTTONS {
|
for button in HOME_BUTTONS {
|
||||||
let hovered = rect_contains(button.rect, pointer_x, pointer_y);
|
let hovered = rect_contains(button.rect, pointer_x, pointer_y);
|
||||||
draw_button(gfx, button.rect, button.label, hovered);
|
draw_button(&mut commands, button.rect, button.label, hovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShellUiFramePacket::new(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_shell_window(
|
fn append_shell_window_commands(
|
||||||
gfx: &mut dyn GfxBridge,
|
commands: &mut Vec<GfxUiCommand>,
|
||||||
viewport: Rect,
|
viewport: Rect,
|
||||||
color: Color,
|
color: Color,
|
||||||
title: &str,
|
title: &str,
|
||||||
pointer_x: i32,
|
pointer_x: i32,
|
||||||
pointer_y: i32,
|
pointer_y: i32,
|
||||||
) {
|
) {
|
||||||
gfx.fill_rect(VIEWPORT.x, VIEWPORT.y, VIEWPORT.w, VIEWPORT.h, COLOR_BG);
|
fill_rect(commands, VIEWPORT, COLOR_BG);
|
||||||
draw_panel(gfx, viewport, COLOR_PANEL_DARK, COLOR_BORDER);
|
draw_panel(commands, viewport, COLOR_PANEL_DARK, COLOR_BORDER);
|
||||||
gfx.fill_rect(viewport.x + 4, viewport.y + 24, viewport.w - 8, viewport.h - 28, color);
|
fill_rect(
|
||||||
draw_buffer_text(gfx, viewport.x + 10, viewport.y + 8, title, COLOR_TEXT);
|
commands,
|
||||||
draw_buffer_text(gfx, viewport.x + 18, viewport.y + 44, "native fake shell", COLOR_PANEL_DARK);
|
Rect { x: viewport.x + 4, y: viewport.y + 24, w: viewport.w - 8, h: viewport.h - 28 },
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
draw_buffer_text(commands, viewport.x + 10, viewport.y + 8, title, COLOR_TEXT);
|
||||||
|
draw_buffer_text(
|
||||||
|
commands,
|
||||||
|
viewport.x + 18,
|
||||||
|
viewport.y + 44,
|
||||||
|
"native fake shell",
|
||||||
|
COLOR_PANEL_DARK,
|
||||||
|
);
|
||||||
|
|
||||||
let close_hovered = rect_contains(CLOSE_BUTTON, pointer_x, pointer_y);
|
let close_hovered = rect_contains(CLOSE_BUTTON, pointer_x, pointer_y);
|
||||||
let close_fill = if close_hovered { COLOR_HILITE } else { COLOR_BUTTON };
|
let close_fill = if close_hovered { COLOR_HILITE } else { COLOR_BUTTON };
|
||||||
gfx.fill_rect(CLOSE_BUTTON.x, CLOSE_BUTTON.y, CLOSE_BUTTON.w, CLOSE_BUTTON.h, close_fill);
|
fill_rect(commands, CLOSE_BUTTON, close_fill);
|
||||||
gfx.draw_rect(CLOSE_BUTTON.x, CLOSE_BUTTON.y, CLOSE_BUTTON.w, CLOSE_BUTTON.h, COLOR_BORDER);
|
draw_rect(commands, CLOSE_BUTTON, COLOR_BORDER);
|
||||||
draw_buffer_text(gfx, CLOSE_BUTTON.x + 5, CLOSE_BUTTON.y + 4, "x", COLOR_TEXT);
|
draw_buffer_text(commands, CLOSE_BUTTON.x + 5, CLOSE_BUTTON.y + 4, "x", COLOR_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_panel(gfx: &mut dyn GfxBridge, rect: Rect, fill: Color, border: Color) {
|
fn fill_rect(commands: &mut Vec<GfxUiCommand>, rect: Rect, color: Color) {
|
||||||
gfx.fill_rect(rect.x, rect.y, rect.w, rect.h, fill);
|
commands.push(GfxUiCommand::FillRect { rect, color });
|
||||||
gfx.draw_rect(rect.x, rect.y, rect.w, rect.h, border);
|
|
||||||
gfx.draw_rect(rect.x + 2, rect.y + 2, rect.w - 4, rect.h - 4, COLOR_MUTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_button(gfx: &mut dyn GfxBridge, rect: Rect, label: &str, hovered: bool) {
|
fn draw_rect(commands: &mut Vec<GfxUiCommand>, rect: Rect, color: Color) {
|
||||||
|
commands.push(GfxUiCommand::DrawLine {
|
||||||
|
x0: rect.x,
|
||||||
|
y0: rect.y,
|
||||||
|
x1: rect.x + rect.w - 1,
|
||||||
|
y1: rect.y,
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
commands.push(GfxUiCommand::DrawLine {
|
||||||
|
x0: rect.x,
|
||||||
|
y0: rect.y + rect.h - 1,
|
||||||
|
x1: rect.x + rect.w - 1,
|
||||||
|
y1: rect.y + rect.h - 1,
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
commands.push(GfxUiCommand::DrawLine {
|
||||||
|
x0: rect.x,
|
||||||
|
y0: rect.y,
|
||||||
|
x1: rect.x,
|
||||||
|
y1: rect.y + rect.h - 1,
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
commands.push(GfxUiCommand::DrawLine {
|
||||||
|
x0: rect.x + rect.w - 1,
|
||||||
|
y0: rect.y,
|
||||||
|
x1: rect.x + rect.w - 1,
|
||||||
|
y1: rect.y + rect.h - 1,
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_panel(commands: &mut Vec<GfxUiCommand>, rect: Rect, fill: Color, border: Color) {
|
||||||
|
fill_rect(commands, rect, fill);
|
||||||
|
draw_rect(commands, rect, border);
|
||||||
|
draw_rect(
|
||||||
|
commands,
|
||||||
|
Rect { x: rect.x + 2, y: rect.y + 2, w: rect.w - 4, h: rect.h - 4 },
|
||||||
|
COLOR_MUTED,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_button(commands: &mut Vec<GfxUiCommand>, rect: Rect, label: &str, hovered: bool) {
|
||||||
let fill = if hovered { COLOR_BUTTON_ACTIVE } else { COLOR_BUTTON };
|
let fill = if hovered { COLOR_BUTTON_ACTIVE } else { COLOR_BUTTON };
|
||||||
let border = if hovered { COLOR_HILITE } else { COLOR_BORDER };
|
let border = if hovered { COLOR_HILITE } else { COLOR_BORDER };
|
||||||
gfx.fill_rect(rect.x, rect.y, rect.w, rect.h, fill);
|
fill_rect(commands, rect, fill);
|
||||||
gfx.draw_rect(rect.x, rect.y, rect.w, rect.h, border);
|
draw_rect(commands, rect, border);
|
||||||
gfx.draw_rect(rect.x + 3, rect.y + 3, rect.w - 6, rect.h - 6, COLOR_MUTED);
|
draw_rect(
|
||||||
gfx.fill_rect(rect.x + 12, rect.y + 12, 16, 24, border);
|
commands,
|
||||||
gfx.draw_rect(rect.x + 34, rect.y + 12, 62, 24, COLOR_PANEL_DARK);
|
Rect { x: rect.x + 3, y: rect.y + 3, w: rect.w - 6, h: rect.h - 6 },
|
||||||
draw_buffer_text(gfx, rect.x + 40, rect.y + 21, label, COLOR_TEXT);
|
COLOR_MUTED,
|
||||||
|
);
|
||||||
|
fill_rect(commands, Rect { x: rect.x + 12, y: rect.y + 12, w: 16, h: 24 }, border);
|
||||||
|
draw_rect(commands, Rect { x: rect.x + 34, y: rect.y + 12, w: 62, h: 24 }, COLOR_PANEL_DARK);
|
||||||
|
draw_buffer_text(commands, rect.x + 40, rect.y + 21, label, COLOR_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_buffer_text(gfx: &mut dyn GfxBridge, x: i32, y: i32, text: &str, color: Color) {
|
fn draw_buffer_text(commands: &mut Vec<GfxUiCommand>, x: i32, y: i32, text: &str, color: Color) {
|
||||||
gfx.draw_text(x, y, text, color);
|
commands.push(GfxUiCommand::DrawText { x, y, text: text.to_string(), color });
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -321,6 +389,16 @@ mod tests {
|
|||||||
assert_eq!(HOME_BUTTONS[1].app, NativeShellApp::ShellB);
|
assert_eq!(HOME_BUTTONS[1].app, NativeShellApp::ShellB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn home_render_produces_shell_ui_packet_commands() {
|
||||||
|
let packet = render_home_packet(SHELL_A_BUTTON.x, SHELL_A_BUTTON.y);
|
||||||
|
|
||||||
|
assert!(matches!(packet.commands.first(), Some(GfxUiCommand::Clear { .. })));
|
||||||
|
assert!(packet.commands.iter().any(|command| {
|
||||||
|
matches!(command, GfxUiCommand::DrawText { text, .. } if text == "PROMETEU HUB")
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn shell_close_button_sits_inside_shell_frame() {
|
fn shell_close_button_sits_inside_shell_frame() {
|
||||||
assert!(rect_contains(SHELL_FRAME, CLOSE_BUTTON.x, CLOSE_BUTTON.y));
|
assert!(rect_contains(SHELL_FRAME, CLOSE_BUTTON.x, CLOSE_BUTTON.y));
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{"type":"meta","next_id":{"DSC":39,"AGD":39,"DEC":31,"PLN":87,"LSN":47,"CLSN":1}}
|
{"type":"meta","next_id":{"DSC":39,"AGD":39,"DEC":31,"PLN":87,"LSN":47,"CLSN":1}}
|
||||||
{"type":"discussion","id":"DSC-0038","status":"in_progress","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-05-25","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[{"id":"AGD-0038","file":"AGD-0038-renderframepacket-boundary-for-classic-2d-renderer.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25"}],"decisions":[{"id":"DEC-0030","file":"DEC-0030-logical-render-pipeline-command-boundary.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25","ref_agenda":"AGD-0038"}],"plans":[{"id":"PLN-0073","file":"PLN-0073-render-contract-specs.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0074","file":"PLN-0074-hal-render-submission-types.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0075","file":"PLN-0075-rendermanager-core.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0076","file":"PLN-0076-capabilities-and-abi-domain-split.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0077","file":"PLN-0077-composer-buffer-and-game2d-packet.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0078","file":"PLN-0078-classic2d-game-renderer-consumer.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0079","file":"PLN-0079-gfx2d-primitive-domain.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0080","file":"PLN-0080-shell-ui-packet-and-gfxui-domain.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0081","file":"PLN-0081-shell-hub-migration.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0082","file":"PLN-0082-frame-publication-and-present-boundary.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0083","file":"PLN-0083-fade-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0084","file":"PLN-0084-host-debug-overlay-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0085","file":"PLN-0085-pbs-stdlib-and-syscall-declarations.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0086","file":"PLN-0086-end-to-end-render-boundary-validation.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]}],"lessons":[]}
|
{"type":"discussion","id":"DSC-0038","status":"in_progress","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-05-25","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[{"id":"AGD-0038","file":"AGD-0038-renderframepacket-boundary-for-classic-2d-renderer.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25"}],"decisions":[{"id":"DEC-0030","file":"DEC-0030-logical-render-pipeline-command-boundary.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25","ref_agenda":"AGD-0038"}],"plans":[{"id":"PLN-0073","file":"PLN-0073-render-contract-specs.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0074","file":"PLN-0074-hal-render-submission-types.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0075","file":"PLN-0075-rendermanager-core.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0076","file":"PLN-0076-capabilities-and-abi-domain-split.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0077","file":"PLN-0077-composer-buffer-and-game2d-packet.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0078","file":"PLN-0078-classic2d-game-renderer-consumer.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0079","file":"PLN-0079-gfx2d-primitive-domain.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0080","file":"PLN-0080-shell-ui-packet-and-gfxui-domain.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0081","file":"PLN-0081-shell-hub-migration.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0082","file":"PLN-0082-frame-publication-and-present-boundary.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0083","file":"PLN-0083-fade-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0084","file":"PLN-0084-host-debug-overlay-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0085","file":"PLN-0085-pbs-stdlib-and-syscall-declarations.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0086","file":"PLN-0086-end-to-end-render-boundary-validation.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]}],"lessons":[]}
|
||||||
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
||||||
{"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
{"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
||||||
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"discussion/lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"discussion/lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
id: PLN-0081
|
id: PLN-0081
|
||||||
ticket: render-frame-packet-boundary
|
ticket: render-frame-packet-boundary
|
||||||
title: Shell Hub Migration
|
title: Shell Hub Migration
|
||||||
status: open
|
status: done
|
||||||
created: 2026-05-25
|
created: 2026-05-25
|
||||||
ref_decisions: [DEC-0030]
|
ref_decisions: [DEC-0030]
|
||||||
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user