Skip to content

Commit

Permalink
Refactor ScriptLoader into Library
Browse files Browse the repository at this point in the history
This refactor has two goals:
 - Make the loading of sprites async
 - Reduce the surface of the Lua code

This also reduced the used memory on my system of around 20 MiB.
  • Loading branch information
hasenbanck committed Jan 4, 2025
1 parent aacc2ab commit d73a628
Show file tree
Hide file tree
Showing 26 changed files with 365 additions and 280 deletions.
9 changes: 6 additions & 3 deletions korangar/src/input/mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::graphics::Texture;
use crate::interface::application::InterfaceSettings;
use crate::interface::resource::{ItemSource, SkillSource};
use crate::inventory::Skill;
use crate::loaders::{ResourceMetadata, Sprite};
use crate::world::{Actions, SpriteAnimationState};
use crate::loaders::Sprite;
use crate::world::{Actions, ResourceMetadata, SpriteAnimationState};

#[derive(Default)]
pub enum MouseInputMode {
Expand Down Expand Up @@ -42,7 +42,10 @@ impl MouseInputMode {

pub fn grabbed(&self) -> Option<Grabbed> {
match self {
MouseInputMode::MoveItem(_, item) => Some(Grabbed::Texture(item.metadata.texture.clone())),
MouseInputMode::MoveItem(_, item) => match item.metadata.texture.as_ref() {
None => None,
Some(texture) => Some(Grabbed::Texture(texture.clone())),
},
MouseInputMode::MoveSkill(_, skill) => Some(Grabbed::Action(
skill.sprite.clone(),
skill.actions.clone(),
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/elements/containers/equipment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use crate::interface::elements::ItemBox;
use crate::interface::layout::{ScreenClip, ScreenPosition, ScreenSize};
use crate::interface::resource::ItemSource;
use crate::interface::theme::InterfaceTheme;
use crate::loaders::ResourceMetadata;
use crate::renderer::InterfaceRenderer;
use crate::world::ResourceMetadata;

pub struct EquipmentContainer {
items: PlainRemote<Vec<InventoryItem<ResourceMetadata>>>,
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/elements/containers/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use crate::interface::elements::ItemBox;
use crate::interface::layout::{CornerRadius, ScreenClip, ScreenPosition, ScreenSize};
use crate::interface::resource::{ItemSource, Move, PartialMove};
use crate::interface::theme::InterfaceTheme;
use crate::loaders::ResourceMetadata;
use crate::renderer::InterfaceRenderer;
use crate::world::ResourceMetadata;

pub struct InventoryContainer {
items: PlainRemote<Vec<InventoryItem<ResourceMetadata>>>,
Expand Down
9 changes: 6 additions & 3 deletions korangar/src/interface/elements/miscellanious/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::layout::{CornerRadius, ScreenClip, ScreenPosition, ScreenSize};
use crate::interface::resource::{ItemSource, Move, PartialMove};
use crate::interface::theme::InterfaceTheme;
use crate::loaders::{FontSize, ResourceMetadata, Scaling};
use crate::loaders::{FontSize, Scaling};
use crate::renderer::{InterfaceRenderer, SpriteRenderer};
use crate::world::ResourceMetadata;

#[derive(new)]
pub struct ItemBox {
Expand Down Expand Up @@ -100,9 +101,11 @@ impl Element<InterfaceSettings> for ItemBox {

renderer.render_background(CornerRadius::uniform(5.0), background_color);

if let Some(item) = &self.item {
if let Some(item) = &self.item
&& let Some(texture) = item.metadata.texture.as_ref()
{
renderer.renderer.render_sprite(
item.metadata.texture.clone(),
texture.clone(),
renderer.position,
ScreenSize::uniform(30.0).scaled(Scaling::new(application.get_scaling_factor())),
renderer.clip,
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/elements/shop/buy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::{ShopEntry, ShopEntryOperation};
use crate::interface::layout::{ScreenClip, ScreenPosition, ScreenSize};
use crate::interface::theme::InterfaceTheme;
use crate::loaders::ResourceMetadata;
use crate::renderer::InterfaceRenderer;
use crate::world::ResourceMetadata;

pub struct BuyContainer {
items: PlainRemote<Vec<ShopItem<ResourceMetadata>>>,
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/elements/shop/buy_cart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::{ShopEntry, ShopEntryOperation};
use crate::interface::layout::{ScreenClip, ScreenPosition, ScreenSize};
use crate::interface::theme::InterfaceTheme;
use crate::loaders::ResourceMetadata;
use crate::renderer::InterfaceRenderer;
use crate::world::ResourceMetadata;

pub struct BuyCartContainer {
cart: PlainTrackedState<Vec<ShopItem<(ResourceMetadata, u32)>>>,
Expand Down
21 changes: 12 additions & 9 deletions korangar/src/interface/elements/shop/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ use crate::input::MouseInputMode;
use crate::interface::application::InterfaceSettings;
use crate::interface::layout::{CornerRadius, ScreenClip, ScreenPosition, ScreenSize};
use crate::interface::theme::InterfaceTheme;
use crate::loaders::{FontSize, ResourceMetadata, Scaling};
use crate::loaders::{FontSize, Scaling};
use crate::renderer::{InterfaceRenderer, SpriteRenderer};
use crate::world::ResourceMetadata;

pub trait ItemResourceProvider {
fn get_resource_metadata(&self) -> &ResourceMetadata;
Expand Down Expand Up @@ -97,14 +98,16 @@ where

renderer.render_background(CornerRadius::uniform(5.0), background_color);

renderer.renderer.render_sprite(
self.item.get_resource_metadata().texture.clone(),
renderer.position,
ScreenSize::uniform(30.0).scaled(Scaling::new(application.get_scaling_factor())),
renderer.clip,
Color::WHITE,
false,
);
if let Some(texture) = self.item.get_resource_metadata().texture.as_ref() {
renderer.renderer.render_sprite(
texture.clone(),
renderer.position,
ScreenSize::uniform(30.0).scaled(Scaling::new(application.get_scaling_factor())),
renderer.clip,
Color::WHITE,
false,
);
}

if let Some(quantity) = (self.get_quantity)(&self.item) {
renderer.render_text(
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/elements/shop/sell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::{ShopEntry, ShopEntryOperation};
use crate::interface::layout::{ScreenClip, ScreenPosition, ScreenSize};
use crate::interface::theme::InterfaceTheme;
use crate::loaders::ResourceMetadata;
use crate::renderer::InterfaceRenderer;
use crate::world::ResourceMetadata;

pub struct SellContainer {
items: PlainRemote<Vec<SellItem<(ResourceMetadata, u16)>>>,
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/elements/shop/sell_cart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::{ShopEntry, ShopEntryOperation};
use crate::interface::layout::{ScreenClip, ScreenPosition, ScreenSize};
use crate::interface::theme::InterfaceTheme;
use crate::loaders::ResourceMetadata;
use crate::renderer::InterfaceRenderer;
use crate::world::ResourceMetadata;

pub struct SellCartContainer {
cart: PlainTrackedState<Vec<SellItem<(ResourceMetadata, u16)>>>,
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use korangar_networking::InventoryItem;
use ragnarok_packets::{EquipPosition, HotbarSlot};

use crate::inventory::Skill;
use crate::loaders::ResourceMetadata;
use crate::world::ResourceMetadata;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ItemSource {
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/windows/character/equipment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::EquipmentContainer;
use crate::interface::layout::ScreenSize;
use crate::interface::windows::WindowCache;
use crate::loaders::ResourceMetadata;
use crate::world::ResourceMetadata;

#[derive(new)]
pub struct EquipmentWindow {
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/windows/character/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::InventoryContainer;
use crate::interface::layout::ScreenSize;
use crate::interface::windows::WindowCache;
use crate::loaders::ResourceMetadata;
use crate::world::ResourceMetadata;

#[derive(new)]
pub struct InventoryWindow {
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/windows/shop/buy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::BuyContainer;
use crate::interface::layout::ScreenSize;
use crate::interface::windows::WindowCache;
use crate::loaders::ResourceMetadata;
use crate::world::ResourceMetadata;

#[derive(new)]
pub struct BuyWindow {
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/windows/shop/buy_cart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::BuyCartContainer;
use crate::interface::layout::ScreenSize;
use crate::interface::windows::WindowCache;
use crate::loaders::ResourceMetadata;
use crate::world::ResourceMetadata;

#[derive(new)]
pub struct BuyCartWindow {
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/windows/shop/sell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::SellContainer;
use crate::interface::layout::ScreenSize;
use crate::interface::windows::WindowCache;
use crate::loaders::ResourceMetadata;
use crate::world::ResourceMetadata;

#[derive(new)]
pub struct SellWindow {
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/interface/windows/shop/sell_cart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::interface::application::InterfaceSettings;
use crate::interface::elements::SellCartContainer;
use crate::interface::layout::ScreenSize;
use crate::interface::windows::WindowCache;
use crate::loaders::ResourceMetadata;
use crate::world::ResourceMetadata;

#[derive(new)]
pub struct SellCartWindow {
Expand Down
25 changes: 19 additions & 6 deletions korangar/src/inventory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,34 @@ mod hotbar;
mod skills;

use std::cell::Ref;
use std::sync::Arc;

use korangar_interface::state::{PlainRemote, PlainTrackedState, TrackedState, TrackedStateExt, ValueState};
use korangar_networking::{InventoryItem, InventoryItemDetails, NoMetadata};
use ragnarok_packets::{EquipPosition, InventoryIndex};
use ragnarok_packets::{EquipPosition, InventoryIndex, ItemId};

pub use self::hotbar::Hotbar;
pub use self::skills::{Skill, SkillTree};
use crate::loaders::{ResourceMetadata, ScriptLoader, TextureLoader};
use crate::graphics::Texture;
use crate::loaders::AsyncLoader;
use crate::world::{Library, ResourceMetadata};

#[derive(Default)]
pub struct Inventory {
items: PlainTrackedState<Vec<InventoryItem<ResourceMetadata>>>,
}

impl Inventory {
pub fn fill(&mut self, texture_loader: &TextureLoader, script_loader: &ScriptLoader, items: Vec<InventoryItem<NoMetadata>>) {
pub fn fill(&mut self, async_loader: &AsyncLoader, library: &Library, items: Vec<InventoryItem<NoMetadata>>) {
let items = items
.into_iter()
.map(|item| script_loader.load_inventory_item_metadata(texture_loader, item))
.map(|item| library.load_inventory_item_metadata(async_loader, item))
.collect();

self.items.set(items);
}

pub fn add_item(&mut self, texture_loader: &TextureLoader, script_loader: &ScriptLoader, item: InventoryItem<NoMetadata>) {
pub fn add_item(&mut self, async_loader: &AsyncLoader, library: &Library, item: InventoryItem<NoMetadata>) {
self.items.with_mut(|items| {
if let Some(found_item) = items.iter_mut().find(|inventory_item| inventory_item.index == item.index) {
let InventoryItemDetails::Regular { amount, .. } = &mut found_item.details else {
Expand All @@ -39,7 +42,7 @@ impl Inventory {

*amount += added_amount;
} else {
let item = script_loader.load_inventory_item_metadata(texture_loader, item);
let item = library.load_inventory_item_metadata(async_loader, item);

items.push(item);
}
Expand All @@ -48,6 +51,16 @@ impl Inventory {
});
}

pub fn update_item_sprite(&mut self, item_id: ItemId, texture: Arc<Texture>) {
self.items.with_mut(|items| {
items.iter_mut().filter(|item| item.item_id == item_id).for_each(|item| {
item.metadata.texture = Some(texture.clone());
});

ValueState::Mutated(())
})
}

pub fn remove_item(&mut self, index: InventoryIndex, remove_amount: u16) {
self.items.with_mut(|items| {
let position = items.iter().position(|item| item.index == index).expect("item not in inventory");
Expand Down
79 changes: 65 additions & 14 deletions korangar/src/loaders/async/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,32 @@ use hashbrown::HashMap;
use korangar_debug::logging::print_debug;
#[cfg(feature = "debug")]
use korangar_util::texture_atlas::AtlasAllocation;
use ragnarok_packets::{EntityId, TilePosition};
use ragnarok_packets::{EntityId, ItemId, TilePosition};
use rayon::{ThreadPool, ThreadPoolBuilder};

use crate::graphics::Texture;
use crate::loaders::error::LoadError;
use crate::loaders::{ActionLoader, AnimationLoader, MapLoader, ModelLoader, SpriteLoader, TextureLoader};
use crate::loaders::{ActionLoader, AnimationLoader, ImageType, MapLoader, ModelLoader, SpriteLoader, TextureLoader};
#[cfg(feature = "debug")]
use crate::threads;
use crate::world::{AnimationData, EntityType, Map};

#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
pub enum ItemLocation {
Inventory,
Shop,
}

#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub enum LoaderId {
AnimationData(EntityId),
ItemSprite(ItemId),
Map(String),
}

pub enum LoadableResource {
AnimationData(Arc<AnimationData>),
ItemSprite { texture: Arc<Texture>, location: ItemLocation },
Map { map: Box<Map>, player_position: TilePosition },
}

Expand Down Expand Up @@ -76,19 +85,61 @@ impl AsyncLoader {
}
}

pub fn request_animation_data_load(&self, entity_id: EntityId, entity_type: EntityType, entity_part_files: Vec<String>) {
let sprite_loader = self.sprite_loader.clone();
let action_loader = self.action_loader.clone();
let animation_loader = self.animation_loader.clone();

self.request_load(LoaderId::AnimationData(entity_id), move || {
let animation_data = match animation_loader.get(&entity_part_files) {
None => animation_loader.load(&sprite_loader, &action_loader, entity_type, &entity_part_files)?,
Some(animation_data) => animation_data,
};
#[must_use]
pub fn request_animation_data_load(
&self,
entity_id: EntityId,
entity_type: EntityType,
entity_part_files: Vec<String>,
) -> Option<Arc<AnimationData>> {
match self.animation_loader.get(&entity_part_files) {
Some(animation_data) => Some(animation_data),
None => {
let sprite_loader = self.sprite_loader.clone();
let action_loader = self.action_loader.clone();
let animation_loader = self.animation_loader.clone();

self.request_load(LoaderId::AnimationData(entity_id), move || {
let animation_data = match animation_loader.get(&entity_part_files) {
Some(animation_data) => animation_data,
None => animation_loader.load(&sprite_loader, &action_loader, entity_type, &entity_part_files)?,
};
Ok(LoadableResource::AnimationData(animation_data))
});

None
}
}
}

Ok(LoadableResource::AnimationData(animation_data))
});
#[must_use]
pub fn request_item_sprite_load(
&self,
item_location: ItemLocation,
item_id: ItemId,
path: &str,
image_type: ImageType,
) -> Option<Arc<Texture>> {
match self.texture_loader.get(path, image_type) {
Some(texture) => Some(texture),
None => {
let texture_loader = self.texture_loader.clone();
let path = path.to_string();

self.request_load(LoaderId::ItemSprite(item_id), move || {
let texture = match texture_loader.get(&path, image_type) {
None => texture_loader.load(&path, image_type)?,
Some(texture) => texture,
};
Ok(LoadableResource::ItemSprite {
texture,
location: item_location,
})
});

None
}
}
}

pub fn request_map_load(
Expand Down
2 changes: 0 additions & 2 deletions korangar/src/loaders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ mod font;
mod gamefile;
mod map;
mod model;
mod script;
mod server;
mod sprite;
mod texture;
Expand All @@ -22,7 +21,6 @@ pub use self::gamefile::*;
pub use self::map::{MapLoader, MAP_TILE_SIZE};
pub use self::model::*;
pub use self::r#async::*;
pub use self::script::{ResourceMetadata, ScriptLoader};
pub use self::server::{load_client_info, ClientInfo, ServiceId};
pub use self::sprite::*;
pub use self::texture::{ImageType, TextureAtlasFactory, TextureLoader};
Expand Down
Loading

0 comments on commit d73a628

Please sign in to comment.