tirbofish/dropbear · diff
i dont even know what im doing, and i cant even work on this until an event is done
Signature present but could not be verified.
Unverified
@@ -19,6 +19,7 @@ bytemuck = { version = "1.23", features = ["derive"] } chrono = "0.4" clap = "4.5" colored = "3.0" +crossbeam-channel = "0.5" dropbear-engine = { path = "dropbear-engine" } egui = "0.32" egui-toast-fork = "0.18" @@ -81,6 +81,26 @@ open class BaseScript: RunnableScript { } } + +// todo +public func getCurrentScene() -> Scene! { + if true /* check if script is attached to scene */ { + Scene() + } else { + nil + } +} + +// todo +public func getAttachedEntity() -> Entity { + Entity() +} + +// todo +public func getScene() -> Scene { + Scene() +} + /// A macro for a class of a script that can be used with any entity (when added). /// /// Let's say that you have an entity of a player. You want to get movement for @@ -112,24 +132,5 @@ public macro ScriptEntry() = #externalMacro(module: "dropbear_macro", type: "Scr public macro Script(entity: String) = #externalMacro(module: "dropbear_macro", type: "ScriptMacro") public func getInput() -> Input { - Input() -} - -// todo -public func getCurrentScene() -> Scene! { - if true /* check if script is attached to scene */ { - Scene() - } else { - nil - } -} - -// todo -public func getAttachedEntity() -> Entity { - Entity() -} - -// todo -public func getScene() -> Scene { - Scene() + } @@ -1,3 +1,7 @@ public class Entity { - // todo: work on + let id: Int + + init() { + self.id = 0 + } } @@ -3,12 +3,9 @@ @ScriptEntry class Player: BaseScript { override func onLoad() { - print("Player script loaded") - // let current_scene = dropbear.getCurrentScene() - // let player = current_scene?.getEntity("player") - if dropbear.getInput().isKeyPressed(Key.W) { - // player?.moveForward() - } + let input = dropbear.getInput(); + + } override func onUpdate(dt: Float) { @@ -0,0 +1,26 @@ +private class InternalFFIData { + static let shared = InternalFFIData() + let input_data: RawInputData + + private init() { + + } +} + +struct FFIInputState: Codable { + var keysPressed: [UInt32] + var mousePosition: (Float, Float) + var mouseDelta: (Float, Float) + var mouseButtons: [UInt32] + + init(keysPressed: [UInt32] = [], + mousePosition: (Float, Float) = (0, 0), + mouseDelta: (Float, Float) = (0, 0), + mouseButtons: [UInt32] = []) + { + self.keysPressed = keysPressed + self.mousePosition = mousePosition + self.mouseDelta = mouseDelta + self.mouseButtons = mouseButtons + } +} @@ -1,41 +1,31 @@ -/// A type alias for making the creation of `Vector3` simple. -/// -/// Defaults to `Double` -typealias Vector3D = Math.Vector3<Double> +/// A class containing an `x`, `y` and `z` value of type `T`. +/// +/// The type `T` must conform as +/// an `ExpressibleByIntegerLiteral` (no strings or other stuff). +class Vector3<T> +where T: ExpressibleByIntegerLiteral { + /// The first value in a `Vector3` + var x: T + /// The second value in a `Vector3` + var y: T + /// The third value in a `Vector3` + var z: T -/** Math library for the dropbear-engine Swift API -* I couldn't seem to find any sort of library that deals with vector math, so why not I create my own -*/ -enum Math { - /// A class containing an `x`, `y` and `z` value of type `T`. - /// - /// The type `T` must conform as - /// an `ExpressibleByIntegerLiteral` (no strings or other stuff). - class Vector3<T> - where T: ExpressibleByIntegerLiteral { - /// The first value in a `Vector3` - var x: T - /// The second value in a `Vector3` - var y: T - /// The third value in a `Vector3` - var z: T - - /// Initialises a new Vector3 - /// - /// # Parameters: - /// - x: A value of type T - /// - y: A value of type T - /// - z: A value of type T - init(x: T, y: T, z: T) { - self.x = x - self.y = y - self.z = z - } + /// Initialises a new Vector3 + /// + /// # Parameters: + /// - x: A value of type T + /// - y: A value of type T + /// - z: A value of type T + init(x: T, y: T, z: T) { + self.x = x + self.y = y + self.z = z + } - /// Creates a new Vector3 of type `T` with all values set to zero. - /// - Returns: Vector3 of type `T` - static func zero() -> Vector3<T> { - return Vector3(x: 0, y: 0, z: 0) - } + /// Creates a new Vector3 of type `T` with all values set to zero. + /// - Returns: Vector3 of type `T` + static func zero() -> Vector3<T> { + return Vector3(x: 0, y: 0, z: 0) } } @@ -26,6 +26,7 @@ winit.workspace = true tokio.workspace = true rayon.workspace = true libloading.workspace = true +crossbeam-channel.workspace = true [features] editor = [] @@ -2,7 +2,7 @@ use std::{ collections::{HashMap, HashSet}, time::{Duration, Instant}, }; - +use serde::{Deserialize, Serialize}; use winit::{event::MouseButton, keyboard::KeyCode}; #[derive(Clone)] @@ -5,10 +5,36 @@ use hecs::{Entity, World}; use std::path::PathBuf; use std::{collections::HashMap, fs}; use std::env::current_exe; +use glam::{Quat, Vec3}; use libloading::{library_filename, Library}; +use once_cell::sync::Lazy; +use parking_lot::Mutex; +use serde::{Deserialize, Serialize}; pub const TEMPLATE_SCRIPT: &str = include_str!("../../resources/scripting/swift/sample.swift"); +#[derive(Debug, Clone)] +pub enum ScriptCommand { + /// Allows you to set a Transform value to a specific entity. + /// + /// # API Usage + /// ```swift + /// let player = dropbear.getAttachedEntity() // fetches entity information + /// + /// player.translate(Vector3(x: 1.0)) + /// player.setPosition(player.getTransform().position + Vector3(x: 1.0)) + /// player.rotateX(angle: 95.radians) + /// player.scale(Vector3(x: 1.4, y: 1.5, z: 0.8)) + /// player.setTransform(Transform(position: Vector3.zero(), rotation: Quaternion.identity(), scale: Vector3.zero()) + /// ``` + SetTransform { + entity: Entity, + position: Option<Vec3>, + rotation: Option<Quat>, + scale: Option<Vec3>, + } +} + #[derive(Clone)] pub struct DropbearScriptingAPIContext { pub current_entity: Option<Entity>, @@ -17,6 +43,8 @@ pub struct DropbearScriptingAPIContext { pub current_input: Option<InputState>, pub persistent_data: HashMap<String, Value>, pub frame_data: HashMap<String, Value>, + + command_sender: Option<crossbeam_channel::Sender<ScriptCommand>>, } impl Default for DropbearScriptingAPIContext { @@ -33,6 +61,7 @@ impl DropbearScriptingAPIContext { current_input: None, persistent_data: HashMap::new(), frame_data: HashMap::new(), + command_sender: None, } } @@ -122,6 +151,14 @@ impl ScriptManager { Ok(()) } + fn process_commands(&mut self) { + + } + + fn populate(&self) { + + } + pub fn update_entity_script( &mut self, entity_id: hecs::Entity, @@ -0,0 +1,34 @@ +// This is the header for the Swift FFI functions. This is just to be used as reference. +// +// I suppose you could use this for any other language other than Swift... + +// ---------------------------------- +// An expandable vector of uint32_t +typedef struct { + const uint32_t* ptr; + size_t len; + size_t cap; +} CArrayU32; + +// Creates a new empty CArrayU32 +CArrayU32 new_array_u32(void); + +/// Frees memory of a CArrayU32 +void free_array_u32(CArrayU32 arr); + +// ---------------------------------- + +// A expandable vector of uint8_t +typedef struct { + const uint8_t* ptr; + size_t len; + size_t cap; +} CArrayU8; + +// Creates a new empty CArrayU8 +CArrayU8 new_array_u8(void); + +/// Frees memory of a CArrayU8 +void free_array_u8(CArrayU8 arr); + +// ---------------------------------- @@ -1,2 +1,112 @@ //! A module for dealing with the FFI between Swift dropbear-engine scripting API and -//! the game engine in Rust. +//! the game engine in Rust. + +use serde::{Deserialize, Serialize}; +use winit::event::MouseButton; +use crate::input::InputState; +use winit::platform::scancode::PhysicalKeyExtScancode; + +#[derive(Serialize, Deserialize)] +pub struct FFIInputState { + pub keys_pressed: Vec<u32>, + pub mouse_position: [f32; 2], + pub mouse_delta: [f32; 2], + pub mouse_buttons: Vec<u32>, +} + +impl From<InputState> for FFIInputState { + fn from(value: InputState) -> Self { + + let keys_pressed = value.pressed_keys.iter().map(|k| { + k.to_scancode().unwrap() + }).collect::<Vec<_>>(); + + let mut mouse_buttons = Vec::new(); + for m in value.mouse_button { + let r = match m { + MouseButton::Left => 1u32, + MouseButton::Right => 2u32, + MouseButton::Middle => 3u32, + _ => 0u32 + }; + mouse_buttons.push(r); + } + + Self { + keys_pressed, + mouse_position: [value.mouse_pos.0 as f32, value.mouse_pos.1 as f32], + mouse_delta: [value.mouse_delta.unwrap_or_default().0 as f32, value.mouse_delta.unwrap_or_default().1 as f32], + mouse_buttons, + } + } +} + +mod vec { + use std::mem::ManuallyDrop; + + /// An expandable array of [`u32`], similar to a [`Vec`] but for C API's + #[repr(C)] + pub struct CArrayU32 { + /// Pointer/Reference to the contents + pub ptr: *const u32, + /// Number of elements in vector + pub len: usize, + /// Maximum capacity of elements in vector + pub cap: usize, + } + + /// An expandable array of [`u8`], similar to a [`Vec`] but for C API's + #[repr(C)] + pub struct CArrayU8 { + /// Pointer/Reference to the contents + pub ptr: *const u8, + /// Number of elements in vector + pub len: usize, + /// Maximum capacity of elements in vector + pub cap: usize, + } + + /// Creates a new [`CArrayU32`] from a vector (used for Rust) + pub fn vec_into_carray_u32(v: Vec<u32>) -> CArrayU32 { + let mut v = ManuallyDrop::new(v); + CArrayU32 { ptr: v.as_mut_ptr(), len: v.len(), cap: v.capacity() } + } + + /// Created a nw [`CArrayU8`] from a vector (used for Rust) + pub fn vec_into_carray_u8(v: Vec<u8>) -> CArrayU8 { + let mut v = ManuallyDrop::new(v); + CArrayU8 { ptr: v.as_mut_ptr(), len: v.len(), cap: v.capacity() } + } + + /// Create a new empty CArrayU32 + #[unsafe(no_mangle)] + pub extern "C" fn new_array_u32() -> CArrayU32 { + vec_into_carray_u32(Vec::new()) + } + + /// Create a new empty CArrayU8 + #[unsafe(no_mangle)] + pub extern "C" fn new_array_u8() -> CArrayU8 { + vec_into_carray_u8(Vec::new()) + } + + /// Frees the vector from memory. + /// + /// Since Rust is unable to manage an FFI from outside the language, this function is required. + /// + /// This function is exposed under the name of `free_array_u32` + #[unsafe(no_mangle)] + pub extern "C" fn free_array_u32(arr: CArrayU32) { + unsafe { Vec::from_raw_parts(arr.ptr as *mut u32, arr.len, arr.cap); } + } + + /// Frees the vector from memory. + /// + /// Since Rust is unable to manage an FFI from outside the language, this function is required. + /// + /// This function is exposed under the name of `free_array_u8` + #[unsafe(no_mangle)] + pub extern "C" fn free_array_u8(arr: CArrayU8) { + unsafe { Vec::from_raw_parts(arr.ptr as *mut u8, arr.len, arr.cap); } + } +}