1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::any::Any;
use {
self::{
executor::{Executor, Spawner},
globals::{Global, EngineGlobals},
swap::Swap
},
crate::{
scene::{
game_object::GameObject,
},
event::UserEvent,
},
std::{
pin::Pin,
sync::{
Arc,
RwLock,
mpsc::sync_channel
}
},
futures::future::BoxFuture,
winit::event::Event,
};
pub mod globals;
pub mod executor;
pub mod swap;
pub trait Scriptable {
fn spawn_script_core(&mut self, this: Arc<RwLock<dyn GameObject>>, spawner: Spawner);
fn spawn_script_handler(&mut self, this: Arc<RwLock<dyn GameObject>>, spawner: Spawner, event: Event<'static, UserEvent<Arc<dyn Any + Send + Sync>>>);
fn get_globals(&self) -> Result<Box<dyn Global>, &'static str>;
fn set_globals(&mut self, globals: Box<dyn Global>) -> Result<(), &'static str>;
}
pub type BoxedStartFn<T> = Pin<Box<fn(Arc<RwLock<T>>, EngineGlobals) -> BoxFuture<'static, Swap>>>;
pub type BoxedFrameFn<T> = Pin<Box<fn(Arc<RwLock<T>>, EngineGlobals) -> BoxFuture<'static, Swap>>>;
pub type BoxedEventHandlerFn<T> = Pin<Box<fn(Arc<RwLock<T>>, EngineGlobals, Event<'static, UserEvent<Arc<dyn Any + Send + Sync>>>) -> BoxFuture<'static, Swap>>>;
pub struct Script<T> where T: ?Sized + Send + 'static{
pub has_started: bool,
pub globals: Option<Box<dyn Global>>,
pub start: BoxedStartFn<T>,
pub frame: BoxedFrameFn<T>,
pub event_handler: Option<BoxedEventHandlerFn<T>>
}
impl<T: ?Sized + Send + 'static> std::fmt::Debug for Script<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Script")
.field("has_started", &self.has_started)
.field("globals", &self.globals)
.field("start", &self.start)
.field("frame", &self.frame)
.field("event_handler", &self.event_handler).finish()
}
}
impl<T> Script<T> where T: ?Sized + Send + 'static{
pub fn new_boxed(
start: BoxedStartFn<T>,
frame: BoxedFrameFn<T>,
event_handler: Option<BoxedEventHandlerFn<T>>) -> Box<Script<T>> {
Box::new(Script{
has_started: false,
globals: None,
start,
frame,
event_handler
})
}
}
impl<T> Clone for Script<T> where T: Clone + Send + 'static{
fn clone(&self) -> Self {
Script{
has_started: self.has_started,
globals: self.globals.clone(),
start: self.start.clone(),
frame: self.frame.clone(),
event_handler: self.event_handler.clone()
}
}
}
pub fn new_executor_and_spawner(engine_globals: EngineGlobals) -> (Executor, Spawner) {
const MAX_QUEUED_TASKS: usize = 10_000;
let (task_sender, queue) = sync_channel(MAX_QUEUED_TASKS);
(Executor {queue, ready: Vec::new() }, Spawner { task_sender, engine_globals })
}