dev/render-worker-establishment #32
@ -232,11 +232,11 @@ impl RuntimePlatform for Hardware {
|
||||
self
|
||||
}
|
||||
|
||||
fn audio(&self) -> &dyn prometeu_hal::AudioPlatform {
|
||||
fn audio(&self) -> &dyn AudioBridge {
|
||||
&self.audio
|
||||
}
|
||||
|
||||
fn audio_mut(&mut self) -> &mut dyn prometeu_hal::AudioPlatform {
|
||||
fn audio_mut(&mut self) -> &mut dyn AudioBridge {
|
||||
&mut self.audio
|
||||
}
|
||||
|
||||
@ -248,11 +248,11 @@ impl RuntimePlatform for Hardware {
|
||||
self
|
||||
}
|
||||
|
||||
fn assets(&self) -> &dyn prometeu_hal::AssetStoragePlatform {
|
||||
fn assets(&self) -> &dyn AssetBridge {
|
||||
&self.assets
|
||||
}
|
||||
|
||||
fn assets_mut(&mut self) -> &mut dyn prometeu_hal::AssetStoragePlatform {
|
||||
fn assets_mut(&mut self) -> &mut dyn AssetBridge {
|
||||
&mut self.assets
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::hardware::Hardware;
|
||||
use crate::memory_banks::MemoryBanks;
|
||||
use prometeu_hal::{
|
||||
AssetStoragePlatform, AudioPlatform, Game2DFrameComposer, InputPlatform, RenderBackend,
|
||||
AssetBridge, AudioBridge, Game2DFrameComposer, InputPlatform, RenderBackend,
|
||||
RenderSubmissionSink, RuntimePlatform, TelemetryPlatform,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
@ -47,11 +47,11 @@ impl RuntimePlatform for TestPlatform {
|
||||
self.hardware.game2d_frame_composer()
|
||||
}
|
||||
|
||||
fn audio(&self) -> &dyn AudioPlatform {
|
||||
fn audio(&self) -> &dyn AudioBridge {
|
||||
self.hardware.audio()
|
||||
}
|
||||
|
||||
fn audio_mut(&mut self) -> &mut dyn AudioPlatform {
|
||||
fn audio_mut(&mut self) -> &mut dyn AudioBridge {
|
||||
self.hardware.audio_mut()
|
||||
}
|
||||
|
||||
@ -63,11 +63,11 @@ impl RuntimePlatform for TestPlatform {
|
||||
self.hardware.input_mut()
|
||||
}
|
||||
|
||||
fn assets(&self) -> &dyn AssetStoragePlatform {
|
||||
fn assets(&self) -> &dyn AssetBridge {
|
||||
self.hardware.assets()
|
||||
}
|
||||
|
||||
fn assets_mut(&mut self) -> &mut dyn AssetStoragePlatform {
|
||||
fn assets_mut(&mut self) -> &mut dyn AssetBridge {
|
||||
self.hardware.assets_mut()
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,19 @@
|
||||
use crate::hardware_bridge::HardwareBridge;
|
||||
use crate::platform::RuntimePlatform;
|
||||
use crate::vm_fault::VmFault;
|
||||
|
||||
pub struct HostContext<'a> {
|
||||
pub hw: Option<&'a mut dyn HardwareBridge>,
|
||||
pub platform: Option<&'a mut dyn RuntimePlatform>,
|
||||
}
|
||||
|
||||
impl<'a> HostContext<'a> {
|
||||
pub fn new(hw: Option<&'a mut dyn HardwareBridge>) -> Self {
|
||||
Self { hw }
|
||||
Self { hw, platform: None }
|
||||
}
|
||||
|
||||
pub fn new_platform(platform: Option<&'a mut dyn RuntimePlatform>) -> Self {
|
||||
Self { hw: None, platform }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -17,6 +23,14 @@ impl<'a> HostContext<'a> {
|
||||
None => Err(VmFault::Unavailable),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn require_platform(&mut self) -> Result<&mut dyn RuntimePlatform, VmFault> {
|
||||
match &mut self.platform {
|
||||
Some(platform) => Ok(*platform),
|
||||
None => Err(VmFault::Unavailable),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HostContextProvider {
|
||||
|
||||
@ -49,9 +49,9 @@ pub use native_interface::{NativeInterface, SyscallId};
|
||||
pub use pad_bridge::PadBridge;
|
||||
pub use platform::{
|
||||
AssetStoragePlatform, AudioPlatform, ClockPacingPlatform, Game2DFrameComposer, InputPlatform,
|
||||
LegacyHardwareGame2DFrameComposer, LegacyHardwareRenderSubmissionSink, NoopTelemetryPlatform,
|
||||
RenderBackend, RenderSubmissionSink, RenderSubmitError, RuntimePlatform, TelemetryPlatform,
|
||||
TestPlatform,
|
||||
LegacyHardwareGame2DFrameComposer, LegacyHardwareRenderSubmissionSink,
|
||||
LegacyHardwareRuntimePlatform, NoopTelemetryPlatform, RenderBackend, RenderSubmissionSink,
|
||||
RenderSubmitError, RuntimePlatform, TelemetryPlatform, TestPlatform,
|
||||
};
|
||||
pub use render_submission::{
|
||||
BoundScenePacket, Camera2D, ComposerFramePacket, FrameId, Game2DFramePacket, GameSpritePacket,
|
||||
|
||||
@ -103,6 +103,89 @@ impl Game2DFrameComposer for LegacyHardwareGame2DFrameComposer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LegacyHardwareRuntimePlatform<'a> {
|
||||
hw: &'a mut dyn HardwareBridge,
|
||||
}
|
||||
|
||||
impl<'a> LegacyHardwareRuntimePlatform<'a> {
|
||||
pub fn new(hw: &'a mut dyn HardwareBridge) -> Self {
|
||||
Self { hw }
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderSubmissionSink for LegacyHardwareRuntimePlatform<'_> {
|
||||
fn submit_render_submission(
|
||||
&mut self,
|
||||
submission: RenderSubmission,
|
||||
) -> Result<(), RenderSubmitError> {
|
||||
self.hw.publish_render_submission(&submission);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderBackend for LegacyHardwareRuntimePlatform<'_> {
|
||||
fn render_frame(&mut self) {
|
||||
self.hw.render_frame();
|
||||
}
|
||||
}
|
||||
|
||||
impl Game2DFrameComposer for LegacyHardwareRuntimePlatform<'_> {
|
||||
fn begin_frame(&mut self) {
|
||||
self.hw.begin_frame();
|
||||
}
|
||||
|
||||
fn bind_scene(&mut self, scene_bank_id: usize) -> ComposerOpStatus {
|
||||
if self.hw.bind_scene(scene_bank_id) {
|
||||
ComposerOpStatus::Ok
|
||||
} else {
|
||||
ComposerOpStatus::SceneUnavailable
|
||||
}
|
||||
}
|
||||
|
||||
fn unbind_scene(&mut self) {
|
||||
self.hw.unbind_scene();
|
||||
}
|
||||
|
||||
fn set_camera(&mut self, x: i32, y: i32) -> ComposerOpStatus {
|
||||
self.hw.set_camera(x, y);
|
||||
ComposerOpStatus::Ok
|
||||
}
|
||||
|
||||
fn emit_sprite(&mut self, sprite: Sprite) -> ComposerOpStatus {
|
||||
if !self.hw.has_glyph_bank(sprite.bank_id as usize) {
|
||||
return ComposerOpStatus::BankInvalid;
|
||||
}
|
||||
|
||||
if self.hw.emit_sprite(sprite) {
|
||||
ComposerOpStatus::Ok
|
||||
} else {
|
||||
ComposerOpStatus::SpriteOverflow
|
||||
}
|
||||
}
|
||||
|
||||
fn close_game2d_packet(&self) -> Game2DFramePacket {
|
||||
self.hw.close_game2d_packet()
|
||||
}
|
||||
}
|
||||
|
||||
impl InputPlatform for LegacyHardwareRuntimePlatform<'_> {
|
||||
fn pad(&self) -> &dyn PadBridge {
|
||||
self.hw.pad()
|
||||
}
|
||||
|
||||
fn pad_mut(&mut self) -> &mut dyn PadBridge {
|
||||
self.hw.pad_mut()
|
||||
}
|
||||
|
||||
fn touch(&self) -> &dyn TouchBridge {
|
||||
self.hw.touch()
|
||||
}
|
||||
|
||||
fn touch_mut(&mut self) -> &mut dyn TouchBridge {
|
||||
self.hw.touch_mut()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AudioPlatform: AudioBridge {}
|
||||
impl<T: AudioBridge + ?Sized> AudioPlatform for T {}
|
||||
|
||||
@ -129,19 +212,63 @@ pub struct NoopTelemetryPlatform;
|
||||
|
||||
impl TelemetryPlatform for NoopTelemetryPlatform {}
|
||||
|
||||
static LEGACY_NOOP_TELEMETRY: NoopTelemetryPlatform = NoopTelemetryPlatform;
|
||||
|
||||
pub trait RuntimePlatform {
|
||||
fn render_submission_sink(&mut self) -> &mut dyn RenderSubmissionSink;
|
||||
fn render_backend(&mut self) -> &mut dyn RenderBackend;
|
||||
fn game2d_frame_composer(&mut self) -> &mut dyn Game2DFrameComposer;
|
||||
fn audio(&self) -> &dyn AudioPlatform;
|
||||
fn audio_mut(&mut self) -> &mut dyn AudioPlatform;
|
||||
fn audio(&self) -> &dyn AudioBridge;
|
||||
fn audio_mut(&mut self) -> &mut dyn AudioBridge;
|
||||
fn input(&self) -> &dyn InputPlatform;
|
||||
fn input_mut(&mut self) -> &mut dyn InputPlatform;
|
||||
fn assets(&self) -> &dyn AssetStoragePlatform;
|
||||
fn assets_mut(&mut self) -> &mut dyn AssetStoragePlatform;
|
||||
fn assets(&self) -> &dyn AssetBridge;
|
||||
fn assets_mut(&mut self) -> &mut dyn AssetBridge;
|
||||
fn telemetry(&self) -> &dyn TelemetryPlatform;
|
||||
}
|
||||
|
||||
impl RuntimePlatform for LegacyHardwareRuntimePlatform<'_> {
|
||||
fn render_submission_sink(&mut self) -> &mut dyn RenderSubmissionSink {
|
||||
self
|
||||
}
|
||||
|
||||
fn render_backend(&mut self) -> &mut dyn RenderBackend {
|
||||
self
|
||||
}
|
||||
|
||||
fn game2d_frame_composer(&mut self) -> &mut dyn Game2DFrameComposer {
|
||||
self
|
||||
}
|
||||
|
||||
fn audio(&self) -> &dyn AudioBridge {
|
||||
self.hw.audio()
|
||||
}
|
||||
|
||||
fn audio_mut(&mut self) -> &mut dyn AudioBridge {
|
||||
self.hw.audio_mut()
|
||||
}
|
||||
|
||||
fn input(&self) -> &dyn InputPlatform {
|
||||
self
|
||||
}
|
||||
|
||||
fn input_mut(&mut self) -> &mut dyn InputPlatform {
|
||||
self
|
||||
}
|
||||
|
||||
fn assets(&self) -> &dyn AssetBridge {
|
||||
self.hw.assets()
|
||||
}
|
||||
|
||||
fn assets_mut(&mut self) -> &mut dyn AssetBridge {
|
||||
self.hw.assets_mut()
|
||||
}
|
||||
|
||||
fn telemetry(&self) -> &dyn TelemetryPlatform {
|
||||
&LEGACY_NOOP_TELEMETRY
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TestPlatform: RuntimePlatform {}
|
||||
impl<T: RuntimePlatform + ?Sized> TestPlatform for T {}
|
||||
|
||||
|
||||
@ -12,9 +12,8 @@ use prometeu_hal::sprite::Sprite;
|
||||
use prometeu_hal::syscalls::Syscall;
|
||||
use prometeu_hal::vm_fault::VmFault;
|
||||
use prometeu_hal::{
|
||||
AudioOpStatus, ComposerOpStatus, Game2DFrameComposer, Gfx2dCommand, GfxUiCommand, HostContext,
|
||||
HostReturn, LegacyHardwareGame2DFrameComposer, NativeInterface, SyscallId, expect_bool,
|
||||
expect_int,
|
||||
AudioOpStatus, ComposerOpStatus, Gfx2dCommand, GfxUiCommand, HostContext, HostReturn,
|
||||
NativeInterface, SyscallId, expect_bool, expect_int,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
@ -180,7 +179,7 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
|
||||
self.ensure_game_profile_syscall(syscall)?;
|
||||
|
||||
let hw = ctx.require_hw()?;
|
||||
let platform = ctx.require_platform()?;
|
||||
|
||||
match syscall {
|
||||
Syscall::SystemHasCart => unreachable!(),
|
||||
@ -387,8 +386,7 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
};
|
||||
|
||||
let status = catch_unwind(AssertUnwindSafe(|| {
|
||||
let mut composer = LegacyHardwareGame2DFrameComposer::new(hw);
|
||||
composer.bind_scene(scene_bank_id)
|
||||
platform.game2d_frame_composer().bind_scene(scene_bank_id)
|
||||
}))
|
||||
.map_err(|payload| VmFault::Panic(Self::panic_payload_to_string(payload)))?;
|
||||
|
||||
@ -396,14 +394,14 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
Ok(())
|
||||
}
|
||||
Syscall::ComposerUnbindScene => {
|
||||
LegacyHardwareGame2DFrameComposer::new(hw).unbind_scene();
|
||||
platform.game2d_frame_composer().unbind_scene();
|
||||
ret.push_int(ComposerOpStatus::Ok as i64);
|
||||
Ok(())
|
||||
}
|
||||
Syscall::ComposerSetCamera => {
|
||||
let x = Self::int_arg_to_i32_trap(expect_int(args, 0)?, "camera x")?;
|
||||
let y = Self::int_arg_to_i32_trap(expect_int(args, 1)?, "camera y")?;
|
||||
LegacyHardwareGame2DFrameComposer::new(hw).set_camera(x, y);
|
||||
platform.game2d_frame_composer().set_camera(x, y);
|
||||
Ok(())
|
||||
}
|
||||
Syscall::ComposerEmitSprite => {
|
||||
@ -451,7 +449,7 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
}
|
||||
};
|
||||
|
||||
let status = LegacyHardwareGame2DFrameComposer::new(hw).emit_sprite(Sprite {
|
||||
let status = platform.game2d_frame_composer().emit_sprite(Sprite {
|
||||
glyph: Glyph { glyph_id, palette_id },
|
||||
x,
|
||||
y,
|
||||
@ -488,7 +486,7 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let status = hw.audio_mut().play(
|
||||
let status = platform.audio_mut().play(
|
||||
0,
|
||||
sample_id_raw as u16,
|
||||
voice_id_raw as usize,
|
||||
@ -518,7 +516,8 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if hw.assets().slot_info(SlotRef::audio(bank_id as usize)).asset_id.is_none() {
|
||||
if platform.assets().slot_info(SlotRef::audio(bank_id as usize)).asset_id.is_none()
|
||||
{
|
||||
ret.push_int(AudioOpStatus::BankInvalid as i64);
|
||||
return Ok(());
|
||||
}
|
||||
@ -534,7 +533,7 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let status = hw.audio_mut().play(
|
||||
let status = platform.audio_mut().play(
|
||||
bank_id,
|
||||
sample_id_raw as u16,
|
||||
voice_id_raw as usize,
|
||||
@ -731,7 +730,7 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
})?;
|
||||
let slot_index = expect_int(args, 1)? as usize;
|
||||
|
||||
match hw.assets().load(asset_id, slot_index) {
|
||||
match platform.assets().load(asset_id, slot_index) {
|
||||
Ok(handle) => {
|
||||
ret.push_int(AssetOpStatus::Ok as i64);
|
||||
ret.push_int(handle as i64);
|
||||
@ -745,16 +744,16 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
}
|
||||
}
|
||||
Syscall::AssetStatus => {
|
||||
ret.push_int(hw.assets().status(expect_int(args, 0)? as u32) as i64);
|
||||
ret.push_int(platform.assets().status(expect_int(args, 0)? as u32) as i64);
|
||||
Ok(())
|
||||
}
|
||||
Syscall::AssetCommit => {
|
||||
let status = hw.assets().commit(expect_int(args, 0)? as u32);
|
||||
let status = platform.assets().commit(expect_int(args, 0)? as u32);
|
||||
ret.push_int(status as i64);
|
||||
Ok(())
|
||||
}
|
||||
Syscall::AssetCancel => {
|
||||
let status = hw.assets().cancel(expect_int(args, 0)? as u32);
|
||||
let status = platform.assets().cancel(expect_int(args, 0)? as u32);
|
||||
ret.push_int(status as i64);
|
||||
Ok(())
|
||||
}
|
||||
@ -764,7 +763,7 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
||||
1 => BankType::SOUNDS,
|
||||
_ => return Err(VmFault::Trap(TRAP_TYPE, "Invalid asset type".to_string())),
|
||||
};
|
||||
let telemetry = hw
|
||||
let telemetry = platform
|
||||
.assets()
|
||||
.bank_telemetry()
|
||||
.into_iter()
|
||||
|
||||
@ -9,8 +9,9 @@ use crate::services::memcard::MemcardService;
|
||||
use prometeu_hal::asset::{BankTelemetry, BankType};
|
||||
use prometeu_hal::log::{LogLevel, LogService, LogSource};
|
||||
use prometeu_hal::{
|
||||
FrameId, HardwareBridge, HostContext, InputSignals, LegacyHardwareRenderSubmissionSink,
|
||||
RenderSubmission, RenderSubmissionPacket, RenderSubmissionSink, ShellUiFramePacket,
|
||||
FrameId, HardwareBridge, HostContext, InputSignals, LegacyHardwareRuntimePlatform,
|
||||
RenderSubmission, RenderSubmissionPacket, RenderSubmissionSink, RuntimePlatform,
|
||||
ShellUiFramePacket,
|
||||
};
|
||||
use prometeu_vm::LogicalFrameEndingReason;
|
||||
use std::collections::HashMap;
|
||||
@ -53,9 +54,9 @@ impl VirtualMachineRuntime {
|
||||
}
|
||||
|
||||
fn bank_telemetry_summary(
|
||||
hw: &dyn HardwareBridge,
|
||||
platform: &dyn RuntimePlatform,
|
||||
) -> (BankTelemetry, BankTelemetry, BankTelemetry) {
|
||||
let telemetry = hw.assets().bank_telemetry();
|
||||
let telemetry = platform.assets().bank_telemetry();
|
||||
let glyph =
|
||||
telemetry.iter().find(|entry| entry.bank_type == BankType::GLYPH).cloned().unwrap_or(
|
||||
BankTelemetry { bank_type: BankType::GLYPH, used_slots: 0, total_slots: 0 },
|
||||
@ -79,7 +80,8 @@ impl VirtualMachineRuntime {
|
||||
hw: &mut dyn HardwareBridge,
|
||||
) -> Option<CrashReport> {
|
||||
let step_result = {
|
||||
let mut ctx = HostContext::new(Some(hw));
|
||||
let mut platform = LegacyHardwareRuntimePlatform::new(hw);
|
||||
let mut ctx = HostContext::new_platform(Some(&mut platform));
|
||||
let mut fs = VirtualFS::new();
|
||||
let mut fs_state = FsState::Unmounted;
|
||||
let mut memcard = MemcardService::new();
|
||||
@ -143,6 +145,7 @@ impl VirtualMachineRuntime {
|
||||
}
|
||||
|
||||
self.update_fs(log_service, fs, fs_state);
|
||||
let mut platform = LegacyHardwareRuntimePlatform::new(hw);
|
||||
|
||||
if !self.logical_frame_active {
|
||||
if RenderManager::policy_for_app_mode(self.current_cartridge_app_mode)
|
||||
@ -154,7 +157,7 @@ impl VirtualMachineRuntime {
|
||||
}
|
||||
self.logical_frame_active = true;
|
||||
self.logical_frame_remaining_cycles = Self::CYCLES_PER_LOGICAL_FRAME;
|
||||
self.begin_logical_frame(signals, hw);
|
||||
self.begin_logical_frame(signals, &mut platform);
|
||||
|
||||
if self.needs_prepare_entry_call || vm.call_stack_is_empty() {
|
||||
vm.prepare_boot_call();
|
||||
@ -182,7 +185,7 @@ impl VirtualMachineRuntime {
|
||||
|
||||
if budget > 0 {
|
||||
let run_result = {
|
||||
let mut ctx = HostContext::new(Some(hw));
|
||||
let mut ctx = HostContext::new_platform(Some(&mut platform));
|
||||
let mut host = VmRuntimeHost {
|
||||
runtime: self,
|
||||
log_service,
|
||||
@ -250,7 +253,7 @@ impl VirtualMachineRuntime {
|
||||
self.current_app_id,
|
||||
);
|
||||
if self.current_cartridge_app_mode == AppMode::Game {
|
||||
let mut packet = hw.close_game2d_packet();
|
||||
let mut packet = platform.game2d_frame_composer().close_game2d_packet();
|
||||
packet.gfx2d = std::mem::take(&mut self.gfx2d_commands);
|
||||
self.render_manager
|
||||
.close_frame_with_packet(RenderSubmissionPacket::Game2D(packet))
|
||||
@ -264,8 +267,8 @@ impl VirtualMachineRuntime {
|
||||
}
|
||||
|
||||
let render_outcome = catch_unwind(AssertUnwindSafe(|| {
|
||||
let mut sink = LegacyHardwareRenderSubmissionSink::new(hw);
|
||||
let mut surface = HardwareRenderSurface { sink: &mut sink };
|
||||
let mut surface =
|
||||
HardwareRenderSurface { sink: platform.render_submission_sink() };
|
||||
match self
|
||||
.render_manager
|
||||
.active_render_policy()
|
||||
@ -307,7 +310,8 @@ impl VirtualMachineRuntime {
|
||||
}
|
||||
|
||||
// 1. Snapshot full telemetry at logical frame end
|
||||
let (glyph_bank, sound_bank, scene_bank) = Self::bank_telemetry_summary(hw);
|
||||
let (glyph_bank, sound_bank, scene_bank) =
|
||||
Self::bank_telemetry_summary(&platform);
|
||||
self.atomic_telemetry
|
||||
.glyph_slots_used
|
||||
.store(glyph_bank.used_slots as u32, Ordering::Relaxed);
|
||||
@ -398,7 +402,7 @@ impl VirtualMachineRuntime {
|
||||
|
||||
// 2. High-frequency telemetry update (only if inspection is active)
|
||||
if self.inspection_active {
|
||||
let (glyph_bank, sound_bank, scene_bank) = Self::bank_telemetry_summary(hw);
|
||||
let (glyph_bank, sound_bank, scene_bank) = Self::bank_telemetry_summary(&platform);
|
||||
self.atomic_telemetry
|
||||
.glyph_slots_used
|
||||
.store(glyph_bank.used_slots as u32, Ordering::Relaxed);
|
||||
@ -435,10 +439,10 @@ impl VirtualMachineRuntime {
|
||||
pub(crate) fn begin_logical_frame(
|
||||
&mut self,
|
||||
_signals: &InputSignals,
|
||||
hw: &mut dyn HardwareBridge,
|
||||
platform: &mut dyn RuntimePlatform,
|
||||
) {
|
||||
hw.begin_frame();
|
||||
hw.audio_mut().clear_commands();
|
||||
platform.game2d_frame_composer().begin_frame();
|
||||
platform.audio_mut().clear_commands();
|
||||
self.logs_written_this_frame.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user