Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General refactor and docs #2

Merged
merged 18 commits into from
Jul 8, 2024
Merged
255 changes: 0 additions & 255 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ lunar-engine-derive= {path = "./lunar-engine-derive", version="0.1.0"}
bytemuck = { version = "1.14.0", features = ["derive"] }
chrono = "0.4.31"
futures = "0.3.30"
image = "0.24.7"
lock_api = "0.4.11"
log = "0.4.20"
parking_lot = "0.12.1"
Expand Down
10 changes: 2 additions & 8 deletions examples/blahaj/camera_movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use lunar_engine::{
input,
math::{mat4x4::Mat4x4, vec4::Vec4},
};
use lunar_engine_derive::as_any;
use winit::keyboard::KeyCode;

#[derive(Debug)]
Expand All @@ -33,6 +34,7 @@ impl FreeCam {
}

impl Component for FreeCam {
#[as_any]
fn mew() -> Self
where
Self: Sized,
Expand All @@ -50,14 +52,6 @@ impl Component for FreeCam {
self.transorm_reference = Some(reference.get_component().unwrap())
}

fn as_any(&self) -> &dyn std::any::Any {
self as &dyn std::any::Any
}

fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self as &mut dyn std::any::Any
}

fn update(&mut self) {
let trans = self.transorm_reference.as_ref().unwrap().borrow();
let old_pos = trans.position;
Expand Down
11 changes: 2 additions & 9 deletions examples/blahaj/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use lunar_engine::{
system::rendering::{self, extensions::Base},
State,
};
use lunar_engine_derive::{dependencies, marker_component};
use lunar_engine_derive::{as_any, dependencies, marker_component};
use winit::keyboard::KeyCode;

use crate::camera_movement::FreeCam;
Expand All @@ -37,6 +37,7 @@ struct Spiny {
}

impl Component for Spiny {
#[as_any]
#[dependencies(Transform)]

fn mew() -> Self
Expand All @@ -57,14 +58,6 @@ impl Component for Spiny {
self.transform.as_ref().unwrap().borrow_mut().rotation.y +=
self.speed * lunar_engine::delta_time();
}

fn as_any(&self) -> &dyn std::any::Any {
self as &dyn std::any::Any
}

fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self as &mut dyn std::any::Any
}
}

fn init(state: &mut MyState) {
Expand Down
70 changes: 61 additions & 9 deletions lunar-engine-derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//! Proc macros for easier use of the ECS

#![allow(clippy::missing_panics_doc, clippy::collapsible_if)]
#![allow(
clippy::missing_panics_doc,
clippy::collapsible_if,
clippy::too_many_lines
)]
use proc_macro::{Group, Punct, TokenStream, TokenTree};

///Adds a `compile_error` with the defined message, before the provided token stream
Expand All @@ -15,21 +19,21 @@ fn comp_error(error: &str, item: TokenStream) -> TokenStream {
///Describes various struct types
enum StructType {
///Normal struct
///```
///```ignore
///struct A {
/// ...
///}
///```
Regular,
///Tupple struct
///
///```
///```ignore
///struct A(...);
///```
Tupple,
///Empty struct
///
///```
///```ignore
///struct A;
///```
Empty,
Expand Down Expand Up @@ -95,7 +99,7 @@ fn is_struct_declaration(item: &TokenStream) -> Option<StructType> {
///component calls to the aliased component.
///
///# Examples
///```
///```ignore
///struct CopmonentA {
/// ...
///}
Expand Down Expand Up @@ -211,6 +215,10 @@ pub fn alias(attr: TokenStream, item: TokenStream) -> TokenStream {
.parse::<TokenStream>()
.unwrap();

let comment = format!("///Alias of [`{base}`]")
.parse::<TokenStream>()
.unwrap();

let mut items = items;

let tmp = if let TokenTree::Group(i) = items.last().unwrap() {
Expand All @@ -223,8 +231,13 @@ pub fn alias(attr: TokenStream, item: TokenStream) -> TokenStream {

*items.last_mut().unwrap() = tmp;

let mut o = items.into_iter().collect::<TokenStream>();
o.extend([deref, deref_mut, component_impl]);
let mut o = comment.into_iter().collect::<TokenStream>();
o.extend([
items.into_iter().collect::<TokenStream>(),
deref,
deref_mut,
component_impl,
]);

o
}
Expand All @@ -234,7 +247,7 @@ pub fn alias(attr: TokenStream, item: TokenStream) -> TokenStream {
///distinguish an entity.
///
///# Examples
///```
///```ignore
///#[marker_component]
///struct Marker;
///
Expand Down Expand Up @@ -309,7 +322,7 @@ pub fn marker_component(attr: TokenStream, item: TokenStream) -> TokenStream {
///Defines dependencies of a component. Must be placed inside the `impl Component` block
///
///# Examples
///```
///```ignore
///struct Test;
///
///impl Component for Test {
Expand Down Expand Up @@ -368,3 +381,42 @@ pub fn dependencies(attr: TokenStream, item: TokenStream) -> TokenStream {
.chain(item)
.collect::<TokenStream>()
}

#[proc_macro_attribute]
///Implements `as_any` and `as_any_mut` functions for Components and Assets
///
///# Examples
///```ignore
///struct TestAsset{
/// ...
///}
///
///impl Asset for TestAsset{
///#[as_any]
/// ...
///}
///```
///
///```ignore
///struct TestComponent{
/// ...
///}
///
///impl Component for TestComponent{
///#[as_any]
/// ...
///}
///```
pub fn as_any(_: TokenStream, item: TokenStream) -> TokenStream {
let as_any =
" fn as_any(&self) -> &dyn std::any::Any { self as &dyn std::any::Any } ".to_string();
let as_any_mut =
" fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self as &mut dyn std::any::Any } ";

(as_any + as_any_mut)
.parse::<TokenStream>()
.unwrap()
.into_iter()
.chain(item)
.collect()
}
12 changes: 8 additions & 4 deletions src/asset_managment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub type UUID = u128;
///
///ID must not be set before the asset is registered
pub trait Asset: Send + Sync + std::any::Any {
///Returns id of the entity
///Returns id of the asset
fn get_id(&self) -> UUID;
///Performs initialization of the asset
///
Expand All @@ -98,13 +98,14 @@ pub trait Asset: Send + Sync + std::any::Any {
///# Errors
///Returns an error if the id was already set
fn set_id(&mut self, id: UUID) -> Result<(), Error>;
///Returns wether or not the asset is initialized
///Returns whether or not the asset is initialized
fn is_initialized(&self) -> bool;
//Will not be needed after Rust 1.75.0
//Cannot be implemented automatically, well... likely can be, but i can't be bothered
///Converts trait object to a `std::any::Any` reference
///
///This function should be implemented as follows
///Please use [`lunar_engine_derive::as_any`] to implement this function automatically.
///Alternatively this function should be implemented as follows
///```
///# use lunar_engine::asset_managment::Asset;
///# use std::any::Any;
Expand All @@ -126,7 +127,8 @@ pub trait Asset: Send + Sync + std::any::Any {
fn as_any(&self) -> &dyn std::any::Any;
///Converts trait object to a mutable `std::any::Any` reference
///
///This function should be implemented as follows
///Please use [`lunar_engine_derive::as_any`] to implement this function automatically.
///Alternatively this function should be implemented as follows
///```
///# use lunar_engine::asset_managment::Asset;
///# use std::any::Any;
Expand Down Expand Up @@ -160,6 +162,7 @@ pub type AssetGuard<'a, T> = lock_api::MappedRwLockReadGuard<'a, parking_lot::Ra
pub type AssetGuardMut<'a, T> = lock_api::MappedRwLockWriteGuard<'a, parking_lot::RawRwLock, T>;

impl<T> AssetReference<T> {
///Borrows the asset immutably
pub fn borrow(&self) -> AssetGuard<'_, T> {
let read = self.refernce.read();
lock_api::RwLockReadGuard::<'_, parking_lot::RawRwLock, Box<(dyn Asset + 'static)>>::map(
Expand All @@ -168,6 +171,7 @@ impl<T> AssetReference<T> {
)
}

///Borrows the asset mutably
pub fn borrow_mut(&self) -> AssetGuardMut<'_, T> {
let write = self.refernce.write();
lock_api::RwLockWriteGuard::<'_, parking_lot::RawRwLock, Box<(dyn Asset + 'static)>>::map(
Expand Down
11 changes: 3 additions & 8 deletions src/asset_managment/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use lunar_engine_derive::as_any;

use super::*;

struct TestAsset {
Expand All @@ -16,6 +18,7 @@ impl TestAsset {
}

impl Asset for TestAsset {
#[as_any]
fn get_id(&self) -> UUID {
self.id.unwrap()
}
Expand All @@ -40,14 +43,6 @@ impl Asset for TestAsset {
}
}

fn as_any(&self) -> &dyn std::any::Any {
self as &dyn std::any::Any
}

fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self as &mut dyn std::any::Any
}

fn is_initialized(&self) -> bool {
self.initialized
}
Expand Down
87 changes: 87 additions & 0 deletions src/assets/material.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use lunar_engine_derive::as_any;

use crate::asset_managment::{Asset, AssetStore, UUID};

use super::BindgroupState;

///Trait for implementing materials
#[allow(clippy::module_name_repetitions)]
pub trait MaterialTrait {
///Render function of the material
fn render(&self, render_pass: &mut wgpu::RenderPass);
///Initialization of the material
fn intialize(&mut self);
///Disposal of the material
fn dispose(&mut self);
///Creation of bindgroups and populating them with data
fn set_bindgroups(&mut self, asset_store: &AssetStore);
///State of the bindgroups of the material
fn bindgroup_sate(&self) -> BindgroupState;
}

///Stores material data, wrapper around the material trait object
pub struct Material {
id: Option<UUID>,
initialized: bool,
material: Box<dyn MaterialTrait + Sync + Send>,
}

impl Asset for Material {
#[as_any]

fn get_id(&self) -> UUID {
self.id.unwrap()
}

fn initialize(&mut self) -> Result<(), Box<dyn std::error::Error + Send>> {
self.material.intialize();
self.initialized = true;
Ok(())
}

fn dispose(&mut self) {
self.material.dispose();
self.initialized = false;
}

fn set_id(&mut self, id: UUID) -> Result<(), crate::asset_managment::Error> {
if self.id.is_some() {
Err(crate::asset_managment::Error::IdAlreadySet)
} else {
self.id = Some(id);
Ok(())
}
}

fn is_initialized(&self) -> bool {
self.initialized
}
}

impl Material {
#[must_use]
///Get the bindgroup state of the material
pub fn get_bindgroup_state(&self) -> BindgroupState {
self.material.bindgroup_sate()
}

///Initialize bindgroups of the material
pub fn initialize_bindgroups(&mut self, asset_store: &AssetStore) {
self.material.set_bindgroups(asset_store);
}

///Call the render function of the material
pub fn render(&self, render_pass: &mut wgpu::RenderPass) {
self.material.render(render_pass);
}
}

impl From<Box<dyn MaterialTrait + 'static + Send + Sync>> for Material {
fn from(value: Box<dyn MaterialTrait + 'static + Send + Sync>) -> Self {
Self {
id: None,
initialized: false,
material: value,
}
}
}
4 changes: 3 additions & 1 deletion src/assets/materials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use std::sync::Arc;

use crate::{asset_managment::UUID, grimoire, DEVICE, FORMAT};

use super::{BindgroupState, MaterialTrait, Texture};
use super::{material::MaterialTrait, BindgroupState, Texture};

///Basic material that renders an object with a given texture, without lighting
pub struct TextureUnlit {
#[cfg(target_arch = "wasm32")]
pipeline: Option<Arc<crate::wrappers::WgpuWrapper<wgpu::RenderPipeline>>>,
Expand All @@ -25,6 +26,7 @@ pub struct TextureUnlit {
impl TextureUnlit {
#[allow(clippy::new_ret_no_self)]
#[must_use]
///Creates a new material with a give texture id
pub fn new(texture_id: UUID) -> Box<dyn MaterialTrait + 'static + Sync + Send> {
Box::new(Self {
pipeline: None,
Expand Down
Loading
Loading