Skip to content

Commit

Permalink
game2d_rs: Add script bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
caseif committed Dec 12, 2024
1 parent 7dd7786 commit 3e266f5
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 8 deletions.
13 changes: 12 additions & 1 deletion engine/static/game2d_rs/src/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use argus_scripting_bind::script_bind;
use lowlevel_rustabi::argus::lowlevel::{Dirtiable, Handle, Vector2f};
use render_rustabi::argus::render::Transform2d;
use resman_rustabi::argus::resman::Resource;
use crate::sprite::Sprite;

#[script_bind(ref_only)]
pub struct Actor2d {
size: Vector2f,
z_index: u32,
Expand All @@ -31,8 +33,9 @@ pub struct Actor2d {
pub(crate) render_obj: Option<Handle>,
}

#[script_bind]
impl Actor2d {
pub fn new(
pub(crate) fn new(
sprite_defn_res: Resource,
size: Vector2f,
z_index: u32,
Expand All @@ -51,34 +54,42 @@ impl Actor2d {
}
}

#[script_bind]
pub fn get_size(&self) -> Vector2f {
self.size
}

#[script_bind]
pub fn get_z_index(&self) -> u32 {
self.z_index
}

#[script_bind]
pub fn can_occlude_light(&self) -> bool {
self.can_occlude_light.peek().value
}

#[script_bind]
pub fn set_can_occlude_light(&mut self, can_occlude: bool) {
self.can_occlude_light.set(can_occlude);
}

#[script_bind]
pub fn get_transform(&self) -> Transform2d {
self.transform.peek().value
}

#[script_bind]
pub fn set_transform(&mut self, transform: Transform2d) {
self.transform.set(transform);
}

#[script_bind]
pub fn get_sprite(&self) -> &Sprite {
&self.sprite
}

#[script_bind]
pub fn get_sprite_mut(&mut self) -> &mut Sprite {
&mut self.sprite
}
Expand Down
32 changes: 26 additions & 6 deletions engine/static/game2d_rs/src/sprite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@

use std::collections::HashMap;
use std::time::{Duration, Instant};
use argus_scripting_bind::script_bind;
use lowlevel_rustabi::argus::lowlevel::{Dirtiable, Padding, Vector2u};
use render_rustabi::argus::render::RenderObject2d;
use resman_rustabi::argus::resman::Resource;

#[derive(Clone)]
#[derive(Clone, Debug)]
pub(crate) struct SpriteAnimationFrame {
pub(crate) offset: Vector2u,
pub(crate) duration: f32,
}

#[derive(Clone)]
#[script_bind]
#[derive(Clone, Debug)]
pub(crate) struct SpriteAnimation {
pub(crate) id: String,

Expand All @@ -45,7 +47,7 @@ impl SpriteAnimation {
}
}

#[derive(Clone)]
#[derive(Clone, Debug)]
pub(crate) struct SpriteDefinition {
pub(crate) def_anim: String,
pub(crate) def_speed: f32,
Expand All @@ -55,6 +57,8 @@ pub(crate) struct SpriteDefinition {
pub(crate) animations: HashMap<String, SpriteAnimation>,
}

#[derive(Debug)]
#[script_bind(ref_only)]
pub struct Sprite {
definition: SpriteDefinition,

Expand All @@ -69,6 +73,7 @@ pub struct Sprite {
pub(crate) pending_reset: bool,
}

#[script_bind]
impl Sprite {
pub fn new(defn_res: Resource) -> Self {
let defn = defn_res.get::<SpriteDefinition>();
Expand Down Expand Up @@ -100,10 +105,12 @@ impl Sprite {
&mut self.anim_start_offsets
}

#[script_bind]
pub fn get_animation_speed(&self) -> f32 {
self.speed
}

#[script_bind]
pub fn set_animation_speed(&mut self, speed: f32) {
self.speed = speed;
}
Expand All @@ -112,6 +119,7 @@ impl Sprite {
self.definition.animations.keys().cloned().collect()
}

#[script_bind]
pub fn get_current_animation_id(&self) -> &str {
self.cur_anim_id.as_str()
}
Expand All @@ -120,22 +128,31 @@ impl Sprite {
self.definition.animations.get(&self.cur_anim_id).expect("Sprite animation is missing")
}

pub(crate) fn set_current_animation(&mut self, animation_id: String) -> Result<(), &'static str> {
pub(crate) fn set_current_animation(&mut self, animation_id: String)
-> Result<(), &'static str> {
match self.definition.animations.get(&animation_id) {
Some(_) => {
self.cur_anim_id = animation_id;
self.cur_frame = Dirtiable::new(self.anim_start_offsets.get(&self.cur_anim_id).cloned()
.expect("Sprite animation start offset is missing"));
self.cur_frame =
Dirtiable::new(self.anim_start_offsets.get(&self.cur_anim_id).cloned()
.unwrap_or_default());
Ok(())
}
None => Err("Animation not found by ID")
}
}

#[script_bind(rename = "set_current_animation")]
pub(crate) fn set_current_animation_or_die(&mut self, animation_id: String) {
self.set_current_animation(animation_id).expect("Failed to set sprite animation");
}

#[script_bind]
pub fn does_current_animation_loop(&self) -> bool {
self.get_current_animation().does_loop
}

#[script_bind]
pub fn is_current_animation_static(&self) -> bool {
self.get_current_animation().frames.len() == 1
}
Expand All @@ -144,14 +161,17 @@ impl Sprite {
self.get_current_animation().padding
}

#[script_bind]
pub fn pause_animation(&mut self) {
self.paused = false;
}

#[script_bind]
pub fn resume_animation(&mut self) {
self.paused = true;
}

#[script_bind]
pub fn reset_animation(&mut self) {
self.pending_reset = true;
}
Expand Down
74 changes: 73 additions & 1 deletion engine/static/game2d_rs/src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ use lazy_static::lazy_static;
use lowlevel_rustabi::argus::lowlevel::{Dirtiable, Vector2f, Vector3f};
use render_rustabi::argus::render::{Canvas, Transform2d};
use std::collections::HashMap;
use std::ptr;
use std::sync::{Arc, RwLock};
use std::time::Duration;
use argus_scripting_bind::script_bind;
use uuid::Uuid;
use wm_rustabi::argus::wm::get_window;
use crate::static_object::StaticObject2d;

const MAX_BACKGROUND_LAYERS: u32 = 16;
Expand All @@ -35,6 +38,7 @@ lazy_static! {
Arc::new(RwLock::new(HashMap::new()));
}

#[script_bind(ref_only)]
pub struct World2d {
id: String,
pub(crate) canvas: Canvas,
Expand All @@ -49,6 +53,7 @@ pub struct World2d {
abstract_camera: Dirtiable<Transform2d>,
}

#[script_bind]
impl World2d {
pub fn create(id: String, mut canvas: Canvas, scale_factor: f32) -> Arc<RwLock<World2d>> {
let world = Self {
Expand All @@ -75,13 +80,28 @@ impl World2d {
g_worlds.read().unwrap().get(&id).unwrap().clone()
}

#[script_bind(rename = "create")]
pub fn create_unsafe<'a>(id: String, window_id: &str, scale_factor: f32) -> &'a mut World2d {
let window = get_window(window_id).unwrap();
let arc = Self::create(id, Canvas::of(window.get_canvas()), scale_factor);
let mut guard = arc.write();
unsafe { &mut *ptr::from_mut(guard.as_deref_mut().unwrap()) }
}

pub fn get(id: &str) -> Result<Arc<RwLock<World2d>>, &'static str> {
match g_worlds.read().expect("Failed to acquire lock for worlds list").get(id) {
Some(world) => Ok(world.clone()),
None => Err("Unknown world ID"),
}
}

#[script_bind(rename = "get")]
pub fn get_unsafe<'a>(id: &str) -> &'a mut World2d {
let arc = Self::get(id).unwrap();
let mut guard = arc.write();
unsafe { &mut *ptr::from_mut(guard.as_deref_mut().unwrap()) }
}

pub fn get_or_crash(id: &str) -> Arc<RwLock<World2d>> {
match Self::get(id) {
Ok(world) => world,
Expand All @@ -97,26 +117,33 @@ impl World2d {
self.scale_factor
}

#[script_bind]
pub fn get_camera_transform(&self) -> Transform2d {
self.abstract_camera.peek().value
let val = self.abstract_camera.peek().value;
val
}

#[script_bind]
pub fn set_camera_transform(&mut self, transform: Transform2d) {
self.abstract_camera.set(transform);
}

#[script_bind]
pub fn get_ambient_light_level(&self) -> f32 {
self.al_level.peek().value
}

#[script_bind]
pub fn set_ambient_light_level(&mut self, level: f32) {
self.al_level.set(level);
}

#[script_bind]
pub fn get_ambient_light_color(&self) -> Vector3f {
self.al_color.peek().value
}

#[script_bind]
pub fn set_ambient_light_color(&mut self, color: Vector3f) {
self.al_color.set(color);
}
Expand Down Expand Up @@ -158,6 +185,14 @@ impl World2d {
Ok(self.bg_layers[bg_index as usize].as_mut().expect("Background layer is missing"))
}

#[script_bind(rename = "add_background_layer")]
pub fn add_background_layer_unsafe(
&mut self,
parallax_coeff: f32,
) -> &mut World2dLayer {
self.add_background_layer(parallax_coeff, None).unwrap()
}

fn render(&mut self) {
let scale_factor = self.get_scale_factor();
let camera_transform = self.abstract_camera.read();
Expand Down Expand Up @@ -216,6 +251,19 @@ impl World2d {
)
}

#[script_bind(rename = "create_static_object")]
pub fn create_static_object_unsafe(
&mut self,
sprite: String,
size: Vector2f,
z_index: u32,
can_occlude_light: bool,
transform: Transform2d,
) -> String {
self.create_static_object(sprite, size, z_index, can_occlude_light, transform).unwrap()
.to_string()
}

pub fn delete_static_object(&mut self, id: &Uuid) -> Result<(), &'static str> {
self.get_foreground_layer_mut().delete_static_object(id)
}
Expand All @@ -228,6 +276,11 @@ impl World2d {
self.get_foreground_layer_mut().get_actor_mut(id)
}

#[script_bind(rename = "get_actor_mut")]
pub fn get_actor_mut_unsafe(&mut self, id: &str) -> &mut Actor2d {
self.get_actor_mut(&Uuid::parse_str(id).unwrap()).unwrap()
}

pub fn create_actor(
&mut self,
sprite: String,
Expand All @@ -245,6 +298,25 @@ impl World2d {
)
}

#[script_bind(rename = "create_actor")]
pub fn create_actor_unsafe(
&mut self,
sprite: String,
size: Vector2f,
z_index: u32,
can_occlude_light: bool,
transform: Transform2d,
) -> String {
self.create_actor(
sprite,
size,
z_index,
can_occlude_light,
transform,
).unwrap()
.to_string()
}

pub fn delete_actor(&mut self, id: &Uuid) -> Result<(), &'static str> {
self.get_foreground_layer_mut().delete_actor(id)
}
Expand Down
3 changes: 3 additions & 0 deletions engine/static/game2d_rs/src/world_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::static_object::StaticObject2d;

const LAYER_PREFIX: &str = "_worldlayer_";

#[script_bind(ref_only)]
pub struct World2dLayer {
id: String,
world_id: String,
Expand All @@ -45,6 +46,7 @@ pub struct World2dLayer {
actors: HashMap<Uuid, Actor2d>,
}

#[script_bind]
impl World2dLayer {
pub(crate) fn new(
world_id: String,
Expand Down Expand Up @@ -117,6 +119,7 @@ impl World2dLayer {
self.get_scene().find_camera(self.render_camera_id.as_str())
}

#[script_bind]
pub fn get_world_id(&self) -> &str {
self.world_id.as_str()
}
Expand Down

0 comments on commit 3e266f5

Please sign in to comment.