1
0
Fork 0
mirror of https://github.com/doukutsu-rs/doukutsu-rs synced 2025-05-29 10:11:10 +00:00

fix missing as_any methods in the glutin backend

This commit is contained in:
József Sallai 2023-02-17 16:06:11 +02:00
parent d6715bccea
commit 1810bf6d5b

View file

@ -1,17 +1,16 @@
use std::any::Any;
use std::cell::{RefCell, UnsafeCell}; use std::cell::{RefCell, UnsafeCell};
use std::ffi::c_void; use std::ffi::c_void;
use std::mem; use std::mem;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use glutin::{Api, ContextBuilder, GlProfile, GlRequest, PossiblyCurrent, WindowedContext};
use glutin::event::{ElementState, Event, TouchPhase, VirtualKeyCode, WindowEvent}; use glutin::event::{ElementState, Event, TouchPhase, VirtualKeyCode, WindowEvent};
use glutin::event_loop::{ControlFlow, EventLoop}; use glutin::event_loop::{ControlFlow, EventLoop};
use glutin::window::WindowBuilder; use glutin::window::WindowBuilder;
use glutin::{Api, ContextBuilder, GlProfile, GlRequest, PossiblyCurrent, WindowedContext};
use imgui::{DrawCmdParams, DrawData, DrawIdx, DrawVert}; use imgui::{DrawCmdParams, DrawData, DrawIdx, DrawVert};
use crate::game::Game;
use crate::game::GAME_SUSPENDED;
use crate::common::Rect; use crate::common::Rect;
use crate::framework::backend::{Backend, BackendEventLoop, BackendRenderer, BackendTexture, SpriteBatchCommand}; use crate::framework::backend::{Backend, BackendEventLoop, BackendRenderer, BackendTexture, SpriteBatchCommand};
use crate::framework::context::Context; use crate::framework::context::Context;
@ -19,6 +18,8 @@ use crate::framework::error::GameResult;
use crate::framework::gl; use crate::framework::gl;
use crate::framework::keyboard::ScanCode; use crate::framework::keyboard::ScanCode;
use crate::framework::render_opengl::{GLContext, OpenGLRenderer}; use crate::framework::render_opengl::{GLContext, OpenGLRenderer};
use crate::game::Game;
use crate::game::GAME_SUSPENDED;
use crate::input::touch_controls::TouchPoint; use crate::input::touch_controls::TouchPoint;
pub struct GlutinBackend; pub struct GlutinBackend;
@ -44,6 +45,10 @@ impl Backend for GlutinBackend {
Ok(Box::new(GlutinEventLoop { refs: Rc::new(UnsafeCell::new(None)) })) Ok(Box::new(GlutinEventLoop { refs: Rc::new(UnsafeCell::new(None)) }))
} }
fn as_any(&self) -> &dyn Any {
self
}
} }
pub struct GlutinEventLoop { pub struct GlutinEventLoop {
@ -59,7 +64,7 @@ impl GlutinEventLoop {
let windowed_context = ContextBuilder::new(); let windowed_context = ContextBuilder::new();
let windowed_context = windowed_context.with_gl(GlRequest::Specific(Api::OpenGl, (3, 0))); let windowed_context = windowed_context.with_gl(GlRequest::Specific(Api::OpenGl, (3, 0)));
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
let windowed_context = windowed_context.with_gl(GlRequest::Specific(Api::OpenGlEs, (2, 0))); let windowed_context = windowed_context.with_gl(GlRequest::Specific(Api::OpenGlEs, (2, 0)));
let windowed_context = windowed_context let windowed_context = windowed_context
.with_gl_profile(GlProfile::Core) .with_gl_profile(GlProfile::Core)
@ -68,10 +73,10 @@ impl GlutinEventLoop {
.with_vsync(true); .with_vsync(true);
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
use glutin::platform::windows::WindowBuilderExtWindows; use glutin::platform::windows::WindowBuilderExtWindows;
window = window.with_drag_and_drop(false); window = window.with_drag_and_drop(false);
} }
window = window.with_title("doukutsu-rs"); window = window.with_title("doukutsu-rs");
@ -163,10 +168,10 @@ impl BackendEventLoop for GlutinEventLoop {
match event { match event {
Event::WindowEvent { event: WindowEvent::CloseRequested, window_id } Event::WindowEvent { event: WindowEvent::CloseRequested, window_id }
if window_id == window.window().id() => if window_id == window.window().id() =>
{ {
state_ref.shutdown(); state_ref.shutdown();
} }
Event::Resumed => { Event::Resumed => {
{ {
let mut mutex = GAME_SUSPENDED.lock().unwrap(); let mut mutex = GAME_SUSPENDED.lock().unwrap();
@ -191,74 +196,74 @@ impl BackendEventLoop for GlutinEventLoop {
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
unsafe { unsafe {
window.surface_destroyed(); window.surface_destroyed();
} }
state_ref.sound_manager.pause(); state_ref.sound_manager.pause();
} }
Event::WindowEvent { event: WindowEvent::Resized(size), window_id } Event::WindowEvent { event: WindowEvent::Resized(size), window_id }
if window_id == window.window().id() => if window_id == window.window().id() =>
{ {
if let Some(renderer) = &ctx.renderer { if let Some(renderer) = &ctx.renderer {
if let Ok(imgui) = renderer.imgui() { if let Ok(imgui) = renderer.imgui() {
imgui.io_mut().display_size = [size.width as f32, size.height as f32]; imgui.io_mut().display_size = [size.width as f32, size.height as f32];
}
ctx.real_screen_size = (size.width, size.height);
ctx.screen_size = get_scaled_size(size.width.max(1), size.height.max(1));
state_ref.handle_resize(ctx).unwrap();
} }
ctx.real_screen_size = (size.width, size.height);
ctx.screen_size = get_scaled_size(size.width.max(1), size.height.max(1));
state_ref.handle_resize(ctx).unwrap();
} }
}
Event::WindowEvent { event: WindowEvent::Touch(touch), window_id } Event::WindowEvent { event: WindowEvent::Touch(touch), window_id }
if window_id == window.window().id() => if window_id == window.window().id() =>
{ {
let mut controls = &mut state_ref.touch_controls; let mut controls = &mut state_ref.touch_controls;
let scale = state_ref.scale as f64; let scale = state_ref.scale as f64;
let loc_x = (touch.location.x * ctx.screen_size.0 as f64 / ctx.real_screen_size.0 as f64) / scale; let loc_x = (touch.location.x * ctx.screen_size.0 as f64 / ctx.real_screen_size.0 as f64) / scale;
let loc_y = (touch.location.y * ctx.screen_size.1 as f64 / ctx.real_screen_size.1 as f64) / scale; let loc_y = (touch.location.y * ctx.screen_size.1 as f64 / ctx.real_screen_size.1 as f64) / scale;
match touch.phase { match touch.phase {
TouchPhase::Started | TouchPhase::Moved => { TouchPhase::Started | TouchPhase::Moved => {
if let Some(point) = controls.points.iter_mut().find(|p| p.id == touch.id) { if let Some(point) = controls.points.iter_mut().find(|p| p.id == touch.id) {
point.last_position = point.position; point.last_position = point.position;
point.position = (loc_x, loc_y); point.position = (loc_x, loc_y);
} else { } else {
controls.touch_id_counter = controls.touch_id_counter.wrapping_add(1); controls.touch_id_counter = controls.touch_id_counter.wrapping_add(1);
let point = TouchPoint { let point = TouchPoint {
id: touch.id, id: touch.id,
touch_id: controls.touch_id_counter, touch_id: controls.touch_id_counter,
position: (loc_x, loc_y), position: (loc_x, loc_y),
last_position: (0.0, 0.0), last_position: (0.0, 0.0),
}; };
controls.points.push(point); controls.points.push(point);
if touch.phase == TouchPhase::Started { if touch.phase == TouchPhase::Started {
controls.clicks.push(point); controls.clicks.push(point);
}
} }
} }
TouchPhase::Ended | TouchPhase::Cancelled => { }
controls.points.retain(|p| p.id != touch.id); TouchPhase::Ended | TouchPhase::Cancelled => {
controls.clicks.retain(|p| p.id != touch.id); controls.points.retain(|p| p.id != touch.id);
} controls.clicks.retain(|p| p.id != touch.id);
} }
} }
}
Event::WindowEvent { event: WindowEvent::KeyboardInput { input, .. }, window_id } Event::WindowEvent { event: WindowEvent::KeyboardInput { input, .. }, window_id }
if window_id == window.window().id() => if window_id == window.window().id() =>
{ {
if let Some(keycode) = input.virtual_keycode { if let Some(keycode) = input.virtual_keycode {
if let Some(drs_scan) = conv_keycode(keycode) { if let Some(drs_scan) = conv_keycode(keycode) {
let key_state = match input.state { let key_state = match input.state {
ElementState::Pressed => true, ElementState::Pressed => true,
ElementState::Released => false, ElementState::Released => false,
}; };
ctx.keyboard_context.set_key(drs_scan, key_state); ctx.keyboard_context.set_key(drs_scan, key_state);
}
} }
} }
}
Event::RedrawRequested(id) if id == window.window().id() => { Event::RedrawRequested(id) if id == window.window().id() => {
{ {
let mutex = GAME_SUSPENDED.lock().unwrap(); let mutex = GAME_SUSPENDED.lock().unwrap();
@ -268,16 +273,16 @@ impl BackendEventLoop for GlutinEventLoop {
} }
#[cfg(not(target_os = "android"))] #[cfg(not(target_os = "android"))]
{ {
if let Err(err) = game.draw(ctx) { if let Err(err) = game.draw(ctx) {
log::error!("Failed to draw frame: {}", err); log::error!("Failed to draw frame: {}", err);
}
window.window().request_redraw();
} }
window.window().request_redraw();
}
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
request_android_redraw(); request_android_redraw();
} }
Event::MainEventsCleared => { Event::MainEventsCleared => {
if state_ref.shutdown { if state_ref.shutdown {
@ -296,21 +301,21 @@ impl BackendEventLoop for GlutinEventLoop {
game.update(ctx).unwrap(); game.update(ctx).unwrap();
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
{ {
match get_insets() { match get_insets() {
Ok(insets) => { Ok(insets) => {
ctx.screen_insets = insets; ctx.screen_insets = insets;
}
Err(e) => {
log::error!("Failed to update insets: {}", e);
}
} }
Err(e) => {
if let Err(err) = game.draw(ctx) { log::error!("Failed to update insets: {}", e);
log::error!("Failed to draw frame: {}", err);
} }
} }
if let Err(err) = game.draw(ctx) {
log::error!("Failed to draw frame: {}", err);
}
}
if state_ref.next_scene.is_some() { if state_ref.next_scene.is_some() {
mem::swap(&mut game.scene, &mut state_ref.next_scene); mem::swap(&mut game.scene, &mut state_ref.next_scene);
state_ref.next_scene = None; state_ref.next_scene = None;
@ -367,6 +372,10 @@ impl BackendEventLoop for GlutinEventLoop {
Ok(Box::new(OpenGLRenderer::new(gl_context, UnsafeCell::new(imgui)))) Ok(Box::new(OpenGLRenderer::new(gl_context, UnsafeCell::new(imgui))))
} }
fn as_any(&self) -> &dyn Any {
self
}
} }
fn conv_keycode(code: VirtualKeyCode) -> Option<ScanCode> { fn conv_keycode(code: VirtualKeyCode) -> Option<ScanCode> {