1
0
Fork 0

Compare commits

..

2 commits

Author SHA1 Message Date
f70340db24 asset_preloader refactor 2025-02-22 02:07:06 +05:00
1cdd4efd78 Asset preload structures and their impls 2025-02-22 01:57:53 +05:00
12 changed files with 954 additions and 1225 deletions

1888
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,19 @@
cargo-features = ["codegen-backend"]
[package]
name = "evolution-rs"
version = "0.1.0"
edition = "2024"
edition = "2021"
[dependencies]
bevy = "0.17.3"
bevy = { version = "0.15.2", features = ["dynamic_linking", "wayland"] }
bevy-trait-query = "0.7.0"
log = { version = "*", features = ["max_level_debug", "release_max_level_warn"] }
[profile.dev]
opt-level = 1
codegen-backend = "cranelift"
[profile.dev.package."*"]
opt-level = 3
codegen-backend = "llvm"

View file

@ -1,4 +0,0 @@
use bevy::prelude::Component;
#[derive(Component)]
pub struct AnimalProperty;

View file

@ -0,0 +1,50 @@
use bevy::prelude::{Resource, Asset};
use crate::asset_preloader::preloader::*;
use std::any::type_name;
#[derive(Resource)]
pub struct AssetPreloadChecker<T>
where T : Asset
{
pub data: Vec<T>,
typename: String
}
pub struct AssetPreloadCheckerBuilder<T>
where T: Asset
{
data : AssetPreloadChecker<T>
}
impl<T: Asset> AssetPreloadChecker<T>{
pub(crate) fn build(asset_preload: &mut AssetPreload) -> AssetPreloadCheckerBuilder<T>
{
let checker = AssetPreloadChecker::new();
asset_preload.0.insert(checker.typename.clone(), false);
AssetPreloadCheckerBuilder{
data: checker
}
}
fn new() -> Self{
AssetPreloadChecker
{
data: Vec::new(),
typename: type_name::<T>().to_string()
}
}
}
impl<T: Asset> AssetPreloadCheckerBuilder<T>{
pub fn finish(self) -> AssetPreloadChecker<T> {
self.data
}
pub fn map_vec<'a, F>(&'a mut self, mut f: F)
where F: FnMut(&mut Vec<T>) + 'a{
f(&mut self.data.data);
}
}

View file

@ -0,0 +1,15 @@
use bevy::prelude::*;
use preloader::*;
use checker::*;
pub mod preloader;
pub mod checker;
pub(crate) fn check_preload_status(gl_preloader: Res<AssetPreload>) {
todo!();
}
pub(crate) fn check_loader_status<T>(loader: Res<AssetPreloadChecker<T>>)
where T: Asset{
todo!();
}

View file

@ -0,0 +1,16 @@
use std::collections::HashMap;
use bevy::prelude::Resource;
pub enum AssetPreloadState{
Loading,
Ready
}
#[derive(Resource)]
pub(crate) struct AssetPreload(pub(crate) HashMap<String,bool>);
impl AssetPreload{
pub(crate) fn new() -> Self{
AssetPreload(HashMap::new())
}
}

View file

@ -1,24 +1,62 @@
use crate::{animal_properties::AnimalProperty, card::Card, hand::Hand};
use bevy::{ecs::system::SystemId, prelude::*};
use bevy::{
ecs::system::SystemId,
prelude::*
};
use crate::{
card::Card,
hand::Hand,
properties::TestProperty
};
pub mod animal;
pub mod animal_properties;
pub mod card;
pub mod hand;
pub mod animal;
pub mod properties;
pub mod plugins;
pub mod asset_preloader;
#[derive(Component)]
/*#[derive(Component)]
pub struct JustUpdated;
#[derive(Resource)]
pub struct Systems {
pub update_hand_dimensions: SystemId,
}
pub update_hand_dimensions: SystemId
}*/
pub fn setup(mut commands: Commands,asset_server: Res<AssetServer>) {
let hand_img: Handle<Image> = asset_server.load("sprites/hand_9s.png");
commands.spawn(Camera2d);
commands.spawn(
(
Hand{name: "Rendo".to_string()},
Sprite {
image: hand_img,
image_mode: SpriteImageMode::Sliced(TextureSlicer {
border: BorderRect::square(4.),
center_scale_mode: SliceScaleMode::Stretch,
sides_scale_mode: SliceScaleMode::Stretch,
..default()
}),
..default()
},
Transform::from_xyz(0., -300., 0.)
)
);
}
pub fn setup_board()
{
}
/*pub fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
) {
let updhd_id = commands.register_system(update_hand_dimensions);
commands.insert_resource(Systems {
update_hand_dimensions: updhd_id,
update_hand_dimensions: updhd_id
});
commands.spawn(Camera2d);
commands.spawn((
@ -27,7 +65,7 @@ pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
Sprite {
image: asset_server.load("sprites/hand_9s.png"),
image_mode: SpriteImageMode::Sliced(TextureSlicer {
border: BorderRect::all(4.),
border: BorderRect::square(4.),
center_scale_mode: SliceScaleMode::Stretch,
sides_scale_mode: SliceScaleMode::Stretch,
..default()
@ -40,64 +78,55 @@ pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
pub fn test_setup_hand(
mut commands: Commands,
asset_server: Res<AssetServer>,
systems: Res<Systems>,
query: Single<Entity, With<Hand>>,
//systems: Res<Systems>,
query: Single<Entity, With<Hand>>
) {
let hand_id = query.into_inner();
for _ in 0..4 {
create_card(&mut commands, &asset_server, Some(hand_id), &systems);
create_card(&mut commands, &asset_server, Some(hand_id));
}
}
pub fn create_card(
cmd: &mut Commands,
commands: &mut Commands,
asset_server: &Res<AssetServer>,
hand_entity: Option<Entity>,
systems: &Res<Systems>,
//systems: &Res<Systems>
) {
let card = cmd
.spawn((
let mut card = commands.spawn((
Card,
AnimalProperty,
TestProperty,
Transform::from_xyz(0., 0., 0.),
Sprite::from_image(asset_server.load("sprites/card_back_placeholder.png")),
))
.id();
if let Some(hand) = hand_entity
&& let Ok(mut hand_commands) = cmd.get_entity(hand)
{
hand_commands.add_child(card);
hand_commands.insert(JustUpdated);
cmd.run_system(systems.update_hand_dimensions);
Sprite::from_image(asset_server.load("sprites/card_back_placeholder.png"))
));
if let Some(hand) = hand_entity {
card.set_parent(hand);
commands.entity(hand).insert(JustUpdated);
//commands.run_system(systems.update_hand_dimensions);
}
}
// TODO: replace this const with getting asset dimensions from Assets<Image>
const CARD_SPRITE_SIZE: Vec2 = Vec2::new(128., 192.);
pub fn update_hand_dimensions(
mut commands: Commands,
p_query: Single<(Entity, &mut Sprite, &Children), (Added<JustUpdated>, With<Hand>)>,
mut c_query: Query<(&mut Transform, &Sprite), (With<Card>, Without<Hand>)>,
assets: Res<Assets<Image>>
) {
let mut hand = p_query.into_inner();
let size = hand.2.iter().count();
let hor_margin = 8.;
let ver_margin = 8.;
let sprite_size = CARD_SPRITE_SIZE;
let hand_total_width = (sprite_size.x + hor_margin) * (size as f32);
let hand_height = ver_margin * 2. + sprite_size.y;
let hand_offset = (hand_total_width - sprite_size.x - hor_margin) / 2.;
for (index, child_id) in hand.2.iter().enumerate() {
let Ok(mut child) = c_query.get_mut(child_id) else {
continue;
};
let offset_x = (sprite_size.x + hor_margin) * (index as f32) - hand_offset;
let offset_y = 0.;
child.0.translation = Vec3::from((Vec2::new(offset_x, offset_y), 1.));
let mut counter = 0.;
let mut hand_total_width = 0.;
let mut hand_height = 0.;
for &child_id in hand.2.iter() {
let Ok(mut child) = c_query.get_mut(child_id) else { continue; };
let sprite_size = assets.get(child.1.image.id()).unwrap().size_f32();
let hor_margin = Vec2::new(4., 0.);
let ver_margin = Vec2::new(0., 4.);
hand_total_width += sprite_size.x + hor_margin.x;
hand_height = sprite_size.y + ver_margin.y * 2.;
child.0.translation = Vec3::from((ver_margin + (sprite_size + hor_margin) * counter, 0.));
counter += 1.;
}
hand.1.custom_size = Some(Vec2::new(hand_total_width, hand_height));
commands.entity(hand.0).remove::<JustUpdated>();
}
*/

View file

@ -1,6 +1,10 @@
use bevy::prelude::*;
use evolution_rs::{plugins::*, setup, test_setup_hand};
use evolution_rs::{
plugins::*,
setup, //test_setup_hand, update_hand_dimensions
};
// Надо придумать способ подгружать все ассеты, а затем уже исполнять программу
// Суть в том, что есть AssetServer::wait_for_asset(handle), который возвращает Future, то есть ассинхронное вычисление или типо того
@ -12,7 +16,9 @@ use evolution_rs::{plugins::*, setup, test_setup_hand};
// P.S. оставляю комменты в коде, потому что так надёжнее, чем сообщениями, которые можно потерять
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, (setup, test_setup_hand).chain())
.add_plugins((DefaultPlugins,BasePropertiesPlugin, asset_preloader::AssetPreloadPlugin))
.add_systems(Startup, setup)
//.add_systems(PostStartup, (test_setup_hand, update_hand_dimensions).chain())
.run();
}

View file

@ -1 +0,0 @@

View file

@ -0,0 +1,14 @@
use bevy::prelude::*;
use crate::asset_preloader::{preloader::AssetPreload,checker::AssetPreloadChecker};
pub struct AssetPreloadPlugin;
impl Plugin for AssetPreloadPlugin {
fn build(&self, app: &mut App) {
//app.init_resource::<AssetPreloadChecker<Image>>();
let mut preload = AssetPreload::new();
let image: AssetPreloadChecker<Image> = AssetPreloadChecker::build(&mut preload).finish();
app.insert_resource(image);
}
}

21
src/plugins/mod.rs Normal file
View file

@ -0,0 +1,21 @@
use bevy::prelude::{App,Plugin};
use crate::properties::{Property, TestProperty};
pub mod asset_preloader;
pub struct BasePropertiesPlugin;
impl Plugin for BasePropertiesPlugin
{
fn build(&self, app: &mut App) {
// Моды должны будут делать кастомный плагин и подгружать его при загрузке мода
use bevy_trait_query::RegisterExt;
app
.register_component_as::<dyn Property, TestProperty>();
//.add_systems(schedule, <ЗДЕСЬ ДОЛЖНА БЫТЬ СИСТЕМА ДЛЯ УСЛОВИЯ>)
//.add_systems(schedule, <ЗДЕСЬ ДОЛЖНА БЫТЬ СИСТЕМА ДЛЯ ТРИГГЕРА);
}
}

25
src/properties/mod.rs Normal file
View file

@ -0,0 +1,25 @@
use bevy_trait_query;
use bevy::prelude::Component;
// Базовый трейт для свойства животного
// Интересно, будет ли участвовать в моддинге
#[bevy_trait_query::queryable]
pub trait Property{
fn check_condition(self : &Self) -> bool;
fn trigger(self : &Self);
}
#[derive(Component)]
pub struct TestProperty;
impl Property for TestProperty
{
fn check_condition(self: &Self) -> bool {
false
}
fn trigger(self: &Self) {
println!("Testing property!");
}
}