API tweaks

master
Mark 2024-02-16 13:28:47 -08:00
parent 308e380241
commit 5528f6ed4e
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
10 changed files with 197 additions and 112 deletions

View File

@ -0,0 +1,121 @@
use galactica_content::{Content, Outfit};
use log::error;
use rhai::{CustomType, FnNamespace, FuncRegistration, ImmutableString, Module, TypeBuilder};
use std::sync::Arc;
pub fn build_ct_module(ct_src: Arc<Content>) -> Module {
let mut module = Module::new();
module.set_id("GalacticaContentModule");
let ct = ct_src.clone();
let _ = FuncRegistration::new("get_outfit")
.with_namespace(FnNamespace::Internal)
.set_into_module(&mut module, move |outfit_name: ImmutableString| {
let outfit = ct.outfits.get(&outfit_name.clone().into());
match outfit {
Some(o) => OutfitState::new(o.clone()),
None => {
error!("called `ct::get_outfit` with an invalid outfit `{outfit_name:?}`");
OutfitState::new_none()
}
}
});
return module;
}
#[derive(Debug, Clone)]
pub struct OutfitState {
outfit: Option<Arc<Outfit>>,
}
impl OutfitState {
pub fn new(outfit: Arc<Outfit>) -> Self {
Self {
outfit: Some(outfit),
}
}
pub fn new_none() -> Self {
Self { outfit: None }
}
}
impl CustomType for OutfitState {
fn build(mut builder: TypeBuilder<Self>) {
builder
.with_name("OutfitState")
.with_fn("is_some", |s: &mut Self| s.outfit.is_some())
.with_fn("display_name", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.display_name.clone())
.unwrap_or("".to_string())
})
.with_fn("desc", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.desc.clone())
.unwrap_or("".to_string())
})
.with_fn("index", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.index.to_string())
.unwrap_or("".to_string())
})
.with_fn("thumbnail", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.thumbnail.index.to_string())
.unwrap_or("".to_string())
})
//
// Stat getters
//
.with_fn("stat_thrust", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.steer_power)
.unwrap_or(0.0)
})
.with_fn("stat_steer_power", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.steer_power)
.unwrap_or(0.0)
})
.with_fn("stat_shield_strength", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_strength)
.unwrap_or(0.0)
})
.with_fn("stat_shield_generation", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_generation)
.unwrap_or(0.0)
})
.with_fn("stat_shield_delay", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_delay)
.unwrap_or(0.0)
})
.with_fn("stat_shield_dps", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| {
if x.gun.is_some() {
(1.0 / x.gun.as_ref().unwrap().rate)
* x.gun.as_ref().unwrap().projectile.damage
} else {
0.0
}
})
.unwrap_or(0.0)
});
}
}

View File

@ -1,4 +1,5 @@
mod conf; mod conf;
mod ct;
mod radialbar; mod radialbar;
mod scrollbox; mod scrollbox;
mod sprite; mod sprite;
@ -6,6 +7,7 @@ mod textbox;
mod ui; mod ui;
pub use conf::build_conf_module; pub use conf::build_conf_module;
pub use ct::{build_ct_module, OutfitState};
pub use radialbar::build_radialbar_module; pub use radialbar::build_radialbar_module;
pub use scrollbox::build_scrollbox_module; pub use scrollbox::build_scrollbox_module;
pub use sprite::build_sprite_module; pub use sprite::build_sprite_module;

View File

@ -62,6 +62,32 @@ pub fn build_sprite_module(ct_src: Arc<Content>, state_src: Rc<RefCell<UiState>>
} }
}); });
let state = state_src.clone();
let ct = ct_src.clone();
let _ = FuncRegistration::new("set_sprite")
.with_namespace(FnNamespace::Internal)
.set_into_module(
&mut module,
move |name: ImmutableString, sprite: ImmutableString| {
let mut ui_state = state.borrow_mut();
match ui_state.get_mut_by_name(&name) {
Some(UiElement::Sprite(x)) => {
let m = ct.sprites.get(&sprite.clone().into()).clone();
if m.is_none() {
error!("called `sprite::set_sprite` with an invalid sprite `{sprite}`");
return;
}
x.set_sprite(m.unwrap().clone())
}
_ => {
error!("called `sprite::set_sprite` on an invalid name `{sprite}`")
}
}
},
);
let state = state_src.clone(); let state = state_src.clone();
let ct = ct_src.clone(); let ct = ct_src.clone();
let _ = FuncRegistration::new("set_mask") let _ = FuncRegistration::new("set_mask")
@ -198,6 +224,7 @@ pub fn build_sprite_module(ct_src: Arc<Content>, state_src: Rc<RefCell<UiState>>
e.set_color(x); e.set_color(x);
}); });
// TODO: fix click collider when preserving aspect
let state = state_src.clone(); let state = state_src.clone();
let _ = FuncRegistration::new("preserve_aspect") let _ = FuncRegistration::new("preserve_aspect")
.with_namespace(FnNamespace::Internal) .with_namespace(FnNamespace::Internal)
@ -221,8 +248,9 @@ pub fn build_sprite_module(ct_src: Arc<Content>, state_src: Rc<RefCell<UiState>>
e.set_preserve_aspect(x); e.set_preserve_aspect(x);
}); });
// TODO: maybe remove?
let state = state_src.clone(); let state = state_src.clone();
let _ = FuncRegistration::new("set_disable_events") let _ = FuncRegistration::new("disable_events")
.with_namespace(FnNamespace::Internal) .with_namespace(FnNamespace::Internal)
.set_into_module(&mut module, move |name: ImmutableString, x: bool| { .set_into_module(&mut module, move |name: ImmutableString, x: bool| {
let mut ui_state = state.borrow_mut(); let mut ui_state = state.borrow_mut();
@ -230,13 +258,13 @@ pub fn build_sprite_module(ct_src: Arc<Content>, state_src: Rc<RefCell<UiState>>
Some(UiElement::SubElement { element, .. }) => match &mut **element { Some(UiElement::SubElement { element, .. }) => match &mut **element {
UiElement::Sprite(x) => x, UiElement::Sprite(x) => x,
_ => { _ => {
error!("called `sprite::set_disable_events` on an invalid name `{name}`"); error!("called `sprite::disable_events` on an invalid name `{name}`");
return; return;
} }
}, },
Some(UiElement::Sprite(x)) => x, Some(UiElement::Sprite(x)) => x,
_ => { _ => {
error!("called `sprite::set_disable_events` on an invalid name `{name}`"); error!("called `sprite::disable_events` on an invalid name `{name}`");
return; return;
} }
}; };

View File

@ -23,8 +23,8 @@ pub fn build_textbox_module(
move |name: ImmutableString, move |name: ImmutableString,
font_size: f32, font_size: f32,
line_height: f32, line_height: f32,
rect: Rect, color: Color,
color: Color| { rect: Rect| {
let mut ui_state = state.borrow_mut(); let mut ui_state = state.borrow_mut();
if ui_state.contains_name(&name) { if ui_state.contains_name(&name) {
@ -72,6 +72,32 @@ pub fn build_textbox_module(
}, },
); );
let state = state_src.clone();
let font = font_src.clone();
let _ = FuncRegistration::new("set_color")
.with_namespace(FnNamespace::Internal)
.set_into_module(&mut module, move |name: ImmutableString, color: Color| {
let mut ui_state = state.borrow_mut();
let e = match ui_state.get_mut_by_name(&name) {
Some(UiElement::SubElement { element, .. }) => match &mut **element {
UiElement::Text(x) => x,
_ => {
error!("called `textbox::set_color` on an invalid name `{name}`");
return;
}
},
Some(UiElement::Text(x)) => x,
_ => {
error!("called `textbox::set_color` on an invalid name `{name}`");
return;
}
};
e.set_color(&mut font.borrow_mut(), color);
});
let state = state_src.clone(); let state = state_src.clone();
let font = font_src.clone(); let font = font_src.clone();
let _ = FuncRegistration::new("align_left") let _ = FuncRegistration::new("align_left")

View File

@ -10,19 +10,11 @@ pub enum Anchor {
} }
#[export_module] #[export_module]
#[allow(non_upper_case_globals)]
pub mod anchor_mod { pub mod anchor_mod {
#[allow(non_upper_case_globals)]
pub const Center: Anchor = Anchor::Center; pub const Center: Anchor = Anchor::Center;
#[allow(non_upper_case_globals)]
pub const NorthWest: Anchor = Anchor::NorthWest; pub const NorthWest: Anchor = Anchor::NorthWest;
#[allow(non_upper_case_globals)]
pub const NorthEast: Anchor = Anchor::NorthEast; pub const NorthEast: Anchor = Anchor::NorthEast;
#[allow(non_upper_case_globals)]
pub const SouthWest: Anchor = Anchor::SouthWest; pub const SouthWest: Anchor = Anchor::SouthWest;
#[allow(non_upper_case_globals)]
pub const SouthEast: Anchor = Anchor::SouthEast; pub const SouthEast: Anchor = Anchor::SouthEast;
} }

View File

@ -17,7 +17,7 @@ pub struct Rect {
} }
impl Rect { impl Rect {
pub fn new(x: f32, y: f32, w: f32, h: f32, anchor_self: Anchor, anchor_parent: Anchor) -> Self { pub fn new(x: f32, y: f32, w: f32, h: f32, anchor_parent: Anchor, anchor_self: Anchor,) -> Self {
Self { Self {
pos: Point2::new(x, y), pos: Point2::new(x, y),
dim: Vector2::new(w, h), dim: Vector2::new(w, h),

View File

@ -6,6 +6,7 @@ mod state;
pub use directive::*; pub use directive::*;
pub use event::*; pub use event::*;
pub use functions::OutfitState;
pub use helpers::{anchor::*, color::*, rect::*, vector::*}; pub use helpers::{anchor::*, color::*, rect::*, vector::*};
pub use state::*; pub use state::*;
@ -52,6 +53,7 @@ pub fn register_into_engine(
// Modules // Modules
engine.register_static_module("ui", functions::build_ui_module(state_src.clone()).into()); engine.register_static_module("ui", functions::build_ui_module(state_src.clone()).into());
engine.register_static_module("ct", functions::build_ct_module(ct_src.clone()).into());
engine.register_static_module( engine.register_static_module(
"sprite", "sprite",
functions::build_sprite_module(ct_src.clone(), state_src.clone()).into(), functions::build_sprite_module(ct_src.clone(), state_src.clone()).into(),

View File

@ -1,4 +1,4 @@
use galactica_content::{Outfit, Ship, SystemObject}; use galactica_content::{Ship, SystemObject};
use galactica_system::{ use galactica_system::{
data::{self}, data::{self},
phys::{objects::PhysShip, PhysSimShipHandle}, phys::{objects::PhysShip, PhysSimShipHandle},
@ -10,7 +10,7 @@ use rapier2d::dynamics::RigidBody;
use rhai::{Array, CustomType, Dynamic, ImmutableString, TypeBuilder}; use rhai::{Array, CustomType, Dynamic, ImmutableString, TypeBuilder};
use std::sync::Arc; use std::sync::Arc;
use super::{Color, UiVector}; use super::{functions::OutfitState, Color, UiVector};
use crate::{RenderInput, RenderState}; use crate::{RenderInput, RenderState};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -147,101 +147,6 @@ impl CustomType for ShipState {
} }
} }
#[derive(Debug, Clone)]
pub struct OutfitState {
outfit: Option<Arc<Outfit>>,
}
impl OutfitState {
pub fn new(outfit: Arc<Outfit>) -> Self {
Self {
outfit: Some(outfit),
}
}
pub fn new_none() -> Self {
Self { outfit: None }
}
}
impl CustomType for OutfitState {
fn build(mut builder: TypeBuilder<Self>) {
builder
.with_name("OutfitState")
.with_fn("is_some", |s: &mut Self| s.outfit.is_some())
.with_fn("display_name", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.display_name.clone())
.unwrap_or("".to_string())
})
.with_fn("desc", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.desc.clone())
.unwrap_or("".to_string())
})
.with_fn("index", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.index.to_string())
.unwrap_or("".to_string())
})
.with_fn("thumbnail", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.thumbnail.index.to_string())
.unwrap_or("".to_string())
})
//
// Stat getters
//
.with_fn("stat_thrust", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.steer_power)
.unwrap_or(0.0)
})
.with_fn("stat_steer_power", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.steer_power)
.unwrap_or(0.0)
})
.with_fn("stat_shield_strength", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_strength)
.unwrap_or(0.0)
})
.with_fn("stat_shield_generation", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_generation)
.unwrap_or(0.0)
})
.with_fn("stat_shield_delay", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_delay)
.unwrap_or(0.0)
})
.with_fn("stat_shield_dps", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| {
if x.gun.is_some() {
(1.0 / x.gun.as_ref().unwrap().rate)
* x.gun.as_ref().unwrap().projectile.damage
} else {
0.0
}
})
.unwrap_or(0.0)
});
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SystemObjectState { pub struct SystemObjectState {
object: Option<Arc<SystemObject>>, object: Option<Arc<SystemObject>>,

View File

@ -50,6 +50,10 @@ impl UiSprite {
} }
} }
pub fn set_sprite(&mut self, sprite: Arc<Sprite>) {
self.anim = SpriteAutomaton::new(sprite);
}
pub fn set_mask(&mut self, mask: Option<Arc<Sprite>>) { pub fn set_mask(&mut self, mask: Option<Arc<Sprite>>) {
self.mask = mask; self.mask = mask;
} }

View File

@ -64,6 +64,11 @@ impl UiTextBox {
self.reflow(font); self.reflow(font);
} }
pub fn set_color(&mut self, font: &mut FontSystem, color: api::Color) {
self.color = color;
self.reflow(font);
}
pub fn set_align(&mut self, font: &mut FontSystem, align: Align) { pub fn set_align(&mut self, font: &mut FontSystem, align: Align) {
self.justify = align; self.justify = align;
self.reflow(font); self.reflow(font);