pub trait Platform {
Show 19 methods
// Required methods
fn draw_area(&self) -> (f32, f32);
fn draw_scale_factor(&self) -> f32;
fn draw_2d(
&self,
vertices: &[Vertex2D],
indices: &[u32],
settings: DrawSettings2D,
);
fn create_sprite(
&self,
width: u16,
height: u16,
format: PixelFormat,
) -> Option<SpriteRef>;
fn update_sprite(
&self,
sprite: SpriteRef,
x_offset: u16,
y_offset: u16,
width: u16,
height: u16,
pixels: &[u8],
);
fn open_file(&self, path: &str) -> Option<FileHandle>;
fn begin_file_read(
&self,
file: FileHandle,
first_byte: u64,
buffer: Box<[u8]>,
) -> FileReadTask;
fn is_file_read_finished(&self, task: &FileReadTask) -> bool;
fn finish_file_read(
&self,
task: FileReadTask,
) -> Result<Box<[u8]>, Box<[u8]>>;
fn create_semaphore(&self) -> Semaphore;
fn available_parallelism(&self) -> usize;
fn spawn_pool_thread(&self, channels: [TaskChannel; 2]) -> ThreadState;
fn update_audio_buffer(&self, first_position: u64, samples: &[[i16; 2]]);
fn audio_playback_position(&self) -> (u64, Instant);
fn input_devices(&self) -> InputDevices;
fn default_button_for_action(
&self,
action: ActionCategory,
device: InputDevice,
) -> Option<Button>;
fn now(&self) -> Instant;
fn println(&self, message: Arguments<'_>);
fn exit(&self, clean: bool);
}
Expand description
A trait for using platform-dependent features from the engine without depending on any platform implementation directly. A platform implementation should implement this trait, and also call the engine’s “iterate” and “event” methods at appropriate times.
All the functions have a &self
parameter, so that the methods can access
some (possibly internally mutable) state, but still keeping the platform
object as widely usable as possible (a “platform” is about as global an
object as you get). Also, none of these functions are (supposed to be) hot,
and this trait is object safe, so using &dyn Platform
should be fine
performance-wise, and will hopefully help with compilation times by avoiding
generics.
Required Methods§
Sourcefn draw_area(&self) -> (f32, f32)
fn draw_area(&self) -> (f32, f32)
Get the current screen size. Could be physical pixels, could be
“logical” pixels, depends on the platform, but it’s the same coordinate
system as the Vertex2D
es passed into Platform::draw_2d
.
Sourcefn draw_scale_factor(&self) -> f32
fn draw_scale_factor(&self) -> f32
Get the current screen scale factor. When multiplied with
Platform::draw_area
should match the resolution of the framebuffer
(i.e. the resolution which sprites should match for pixel perfect
rendering).
Sourcefn draw_2d(
&self,
vertices: &[Vertex2D],
indices: &[u32],
settings: DrawSettings2D,
)
fn draw_2d( &self, vertices: &[Vertex2D], indices: &[u32], settings: DrawSettings2D, )
Render out a pile of possibly textured 2D triangles.
Sourcefn create_sprite(
&self,
width: u16,
height: u16,
format: PixelFormat,
) -> Option<SpriteRef>
fn create_sprite( &self, width: u16, height: u16, format: PixelFormat, ) -> Option<SpriteRef>
Create a sprite of the given size and format. Returns None if the sprite
could not be created due to any reason (sprite dimensions too large, out
of vram, etc.). See Vertex2D
and DrawSettings2D
for sampler
details.
§Implementation note
These are never freed during the lifetime of the engine. Internally, individual sprites are reused as they get streamed in and out.
Sourcefn update_sprite(
&self,
sprite: SpriteRef,
x_offset: u16,
y_offset: u16,
width: u16,
height: u16,
pixels: &[u8],
)
fn update_sprite( &self, sprite: SpriteRef, x_offset: u16, y_offset: u16, width: u16, height: u16, pixels: &[u8], )
Update the pixel data of a sprite within a region. Pixels are tightly packed and in the same format as passed into the creation function.
Sourcefn open_file(&self, path: &str) -> Option<FileHandle>
fn open_file(&self, path: &str) -> Option<FileHandle>
Open a file for reading. Returns None if the file can’t be read.
Sourcefn begin_file_read(
&self,
file: FileHandle,
first_byte: u64,
buffer: Box<[u8]>,
) -> FileReadTask
fn begin_file_read( &self, file: FileHandle, first_byte: u64, buffer: Box<[u8]>, ) -> FileReadTask
Start an asynchronous read operation to fill buffer
from the file
at
offset first_byte
.
Implementations can assume that 'a
will last until
Platform::finish_file_read
is called with the task returned from
this function, since FileReadTask
can’t (safely) be dropped without
it getting called.
Sourcefn is_file_read_finished(&self, task: &FileReadTask) -> bool
fn is_file_read_finished(&self, task: &FileReadTask) -> bool
Returns true if the read task has finished (in success or failure), false if it’s still pending.
Sourcefn finish_file_read(&self, task: FileReadTask) -> Result<Box<[u8]>, Box<[u8]>>
fn finish_file_read(&self, task: FileReadTask) -> Result<Box<[u8]>, Box<[u8]>>
Blocks until the read task finishes, and returns the buffer which the
file contents were written into, if successful. If the read fails, the
memory is returned wrapped in an Err
, and the buffer contents are not
guaranteed.
Sourcefn create_semaphore(&self) -> Semaphore
fn create_semaphore(&self) -> Semaphore
Creates a semaphore.
Multi-threaded platforms should use Semaphore::new
and implement the
functions so that they make use of OS synchronization primitives.
Single-threaded platforms can use Semaphore::single_threaded
.
Sourcefn available_parallelism(&self) -> usize
fn available_parallelism(&self) -> usize
Returns how many threads the system could process in parallel efficiently.
Note that this count shouldn’t be decremented by one to “leave room for the main thread,” because the main thread often sleeps while waiting for worker threads to finish their work.
If this returns 1, the thread pool will not utilize worker threads, and
spawn_pool_thread
can be left unimplemented!
.
Sourcefn spawn_pool_thread(&self, channels: [TaskChannel; 2]) -> ThreadState
fn spawn_pool_thread(&self, channels: [TaskChannel; 2]) -> ThreadState
Spawns a thread for a thread pool, using the given channels to pass tasks back and forth.
Implementation note: unless the build has panic = "abort"
, the worker
thread should catch panics, and if they happen, call signal_panic
on
the task and send the task back to the main thread via the results
channel, and then resume the panic. This will avoid the main thread
silently hanging when joining tasks that panicked the thread they were
running on, it’ll panic instead, with a message about a thread pool
thread panicking.
Sourcefn update_audio_buffer(&self, first_position: u64, samples: &[[i16; 2]])
fn update_audio_buffer(&self, first_position: u64, samples: &[[i16; 2]])
Passes a buffer of audio samples to be played back, and the playback position where the samples start.
Each sample should be a tuple containing the left and right channels’ audio samples for stereo playback, in that order.
The playback position where the platform will start reading can be
queried with Platform::audio_playback_position
.
Sourcefn audio_playback_position(&self) -> (u64, Instant)
fn audio_playback_position(&self) -> (u64, Instant)
Returns the playback position of the next sample the platform will play, and the timestamp which it should be considered to be synchronized with.
Any samples submitted with Platform::update_audio_buffer
before this
position will be ignored.
Sourcefn input_devices(&self) -> InputDevices
fn input_devices(&self) -> InputDevices
Get a list of the currently connected input devices.
Get the default button for one of the generic action categories for the given input device, if a default exists.
Sourcefn now(&self) -> Instant
fn now(&self) -> Instant
Returns the current point in time according to the platform implementation.
Sourcefn exit(&self, clean: bool)
fn exit(&self, clean: bool)
Request the process to exit, with clean: false
if intending to signal
failure. On a clean exit, the exit may be delayed until a moment later,
e.g. at the end of the current frame of the game loop, and after
resource clean up. In failure cases, the idea is to bail asap, but it’s
up to the platform.