summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cargo/config-nightly-fast-compile.toml16
-rw-r--r--.cargo/config.toml5
-rw-r--r--Cargo.lock4
-rw-r--r--Cargo.toml2
-rw-r--r--engine-ecs-macros/src/lib.rs1
-rw-r--r--engine-ecs/src/actions.rs51
-rw-r--r--engine-ecs/src/component.rs36
-rw-r--r--engine-ecs/src/lib.rs99
-rw-r--r--engine-ecs/src/pair.rs5
-rw-r--r--engine/src/draw_flags.rs2
-rw-r--r--engine/src/rendering.rs10
-rw-r--r--engine/src/rendering/backend/opengl.rs7
-rw-r--r--engine/src/scene.rs4
-rw-r--r--engine/src/ui/dear_imgui.rs2
-rw-r--r--engine/src/ui/view/world.rs13
-rw-r--r--rust-analyzer.json18
-rw-r--r--xtask/Cargo.toml6
-rw-r--r--xtask/src/main.rs24
18 files changed, 247 insertions, 58 deletions
diff --git a/.cargo/config-nightly-fast-compile.toml b/.cargo/config-nightly-fast-compile.toml
new file mode 100644
index 0000000..359e004
--- /dev/null
+++ b/.cargo/config-nightly-fast-compile.toml
@@ -0,0 +1,16 @@
+include = ["config.toml"]
+
+[unstable]
+codegen-backend = true
+
+[profile.dev]
+debug = "line-tables-only"
+codegen-backend = "cranelift"
+
+[build]
+rustflags = ["-Zthreads=16"]
+rustc-wrapper = "sccache"
+
+[target.'cfg(unix)']
+linker = "clang"
+rustflags = ["-Clink-arg=--ld-path=wild"]
diff --git a/.cargo/config.toml b/.cargo/config.toml
index af130b7..eed713a 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -1,3 +1,8 @@
+[alias]
+fcheck = "run -p xtask -- execute cargo +nightly check --config .cargo/config-nightly-fast-compile.toml"
+fbuild = "run -p xtask -- execute cargo +nightly build --config .cargo/config-nightly-fast-compile.toml"
+frun = "run -p xtask -- execute cargo +nightly run --config .cargo/config-nightly-fast-compile.toml"
+
[env]
SLANG_USE_PREBUILT = "1"
diff --git a/Cargo.lock b/Cargo.lock
index 6b2d0f2..7dc3324 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3148,6 +3148,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
[[package]]
+name = "xtask"
+version = "0.1.0"
+
+[[package]]
name = "zerocopy"
version = "0.8.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 4eaf692..55fe089 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[workspace]
-members = ["engine*", "util-macros", "opengl-bindings"]
+members = ["engine*", "util-macros", "opengl-bindings", "xtask"]
[workspace.dependencies]
engine = { path = "engine" }
diff --git a/engine-ecs-macros/src/lib.rs b/engine-ecs-macros/src/lib.rs
index da9eec3..9bc829b 100644
--- a/engine-ecs-macros/src/lib.rs
+++ b/engine-ecs-macros/src/lib.rs
@@ -260,6 +260,7 @@ pub fn sole_derive(input: TokenStream) -> TokenStream
{
#ecs_path::component::Parts::builder()
.name(<Self as Sole>::name(&self))
+ .is_sole(true)
.type_reflection(<Self as Sole>::type_reflection())
.build(<Self as Sole>::id(), self)
}
diff --git a/engine-ecs/src/actions.rs b/engine-ecs/src/actions.rs
index 8387acc..9ca9198 100644
--- a/engine-ecs/src/actions.rs
+++ b/engine-ecs/src/actions.rs
@@ -29,10 +29,21 @@ impl Actions<'_>
{
let new_entity_uid = Uid::new_unique();
- self.action_queue.push(Action::Spawn(
- new_entity_uid,
- components.into_parts_array().into(),
- ));
+ let components_parts = components.into_parts_array();
+
+ if let Some(comp_parts) = components_parts
+ .as_ref()
+ .iter()
+ .find(|comp_parts| comp_parts.is_sole)
+ {
+ panic!(
+ "Cannot spawn entity with sole component {}",
+ comp_parts.name
+ );
+ }
+
+ self.action_queue
+ .push(Action::Spawn(new_entity_uid, components_parts.into()));
new_entity_uid
}
@@ -50,10 +61,22 @@ impl Actions<'_>
{
let new_entity_uid = Uid::new_unique();
+ let components_parts = components.into_parts_array();
+
+ if let Some(comp_parts) = components_parts
+ .as_ref()
+ .iter()
+ .find(|comp_parts| comp_parts.is_sole)
+ {
+ panic!(
+ "Cannot spawn entity with sole component {}",
+ comp_parts.name
+ );
+ }
+
self.action_queue.push(Action::Spawn(
new_entity_uid,
- components
- .into_parts_array()
+ components_parts
.into_iter()
.chain([EntityName { name: name.into() }.into_parts()])
.collect(),
@@ -106,10 +129,18 @@ impl Actions<'_>
return;
}
- self.action_queue.push(Action::AddComponents(
- entity_uid,
- components.into_parts_array().into(),
- ));
+ let components_parts = components.into_parts_array();
+
+ if let Some(comp_parts) = components_parts
+ .as_ref()
+ .iter()
+ .find(|comp_parts| comp_parts.is_sole)
+ {
+ panic!("Cannot add sole component {} to an entity", comp_parts.name);
+ }
+
+ self.action_queue
+ .push(Action::AddComponents(entity_uid, components_parts.into()));
}
/// Queues up removing component(s) from a entity at the end of the current tick.
diff --git a/engine-ecs/src/component.rs b/engine-ecs/src/component.rs
index 9220ffb..847ecbd 100644
--- a/engine-ecs/src/component.rs
+++ b/engine-ecs/src/component.rs
@@ -294,6 +294,7 @@ pub struct Parts
{
pub id: Uid,
pub name: &'static str,
+ pub is_sole: bool,
pub type_reflection: Option<&'static TypeReflection>,
pub data: Box<dyn Any>,
pub pair_relation_metadata: Option<PairMemberMetadata>,
@@ -302,6 +303,18 @@ pub struct Parts
impl Parts
{
+ pub fn from_component_info(component_info: &Info, id: Uid, data: Box<dyn Any>)
+ -> Self
+ {
+ assert_eq!((*data).type_id(), component_info.ty_id);
+
+ Self::builder()
+ .type_reflection(component_info.type_reflection)
+ .name(component_info.name)
+ .is_sole(component_info.is_sole)
+ .build_with_any_data(id, data)
+ }
+
#[must_use]
pub fn builder() -> PartsBuilder
{
@@ -313,6 +326,7 @@ impl Parts
pub struct PartsBuilder
{
name: &'static str,
+ is_sole: bool,
type_reflection: Option<&'static TypeReflection>,
pair_relation_metadata: Option<PairMemberMetadata>,
pair_target_metadata: Option<PairMemberMetadata>,
@@ -328,6 +342,13 @@ impl PartsBuilder
}
#[must_use]
+ pub fn is_sole(mut self, is_sole: bool) -> Self
+ {
+ self.is_sole = is_sole;
+ self
+ }
+
+ #[must_use]
pub fn type_reflection(
mut self,
type_reflection: Option<&'static TypeReflection>,
@@ -338,20 +359,15 @@ impl PartsBuilder
}
#[must_use]
- pub fn pair_relation_metadata(
- mut self,
- metadata: Option<PairMemberMetadata>,
- ) -> Self
+ pub fn pair_relation_metadata(mut self, metadata: Option<PairMemberMetadata>)
+ -> Self
{
self.pair_relation_metadata = metadata;
self
}
#[must_use]
- pub fn pair_target_metadata(
- mut self,
- metadata: Option<PairMemberMetadata>,
- ) -> Self
+ pub fn pair_target_metadata(mut self, metadata: Option<PairMemberMetadata>) -> Self
{
self.pair_target_metadata = metadata;
self
@@ -363,6 +379,7 @@ impl PartsBuilder
Parts {
id,
name: self.name,
+ is_sole: self.is_sole,
type_reflection: self.type_reflection,
data: Box::new(data),
pair_relation_metadata: self.pair_relation_metadata,
@@ -376,6 +393,7 @@ impl PartsBuilder
Parts {
id,
name: self.name,
+ is_sole: self.is_sole,
type_reflection: self.type_reflection,
data,
pair_relation_metadata: self.pair_relation_metadata,
@@ -390,6 +408,7 @@ impl Default for PartsBuilder
{
Self {
name: "(unspecified)",
+ is_sole: false,
type_reflection: None,
pair_relation_metadata: None,
pair_target_metadata: None,
@@ -404,4 +423,5 @@ pub struct Info
pub type_reflection: Option<&'static TypeReflection>,
pub ty_id: TypeId,
pub name: &'static str,
+ pub is_sole: bool,
}
diff --git a/engine-ecs/src/lib.rs b/engine-ecs/src/lib.rs
index b987f65..450940a 100644
--- a/engine-ecs/src/lib.rs
+++ b/engine-ecs/src/lib.rs
@@ -1,6 +1,6 @@
#![deny(clippy::all, clippy::pedantic)]
-use std::any::{Any, TypeId};
+use std::any::Any;
use std::borrow::Cow;
use std::fmt::Debug;
use std::hint::cold_path;
@@ -54,7 +54,6 @@ use crate::query::{
TermsBuilderInterface,
MAX_TERM_CNT as QUERY_MAX_TERM_CNT,
};
-use crate::reflection::Type as TypeReflection;
use crate::sole::{Single, Sole};
use crate::system::observer::Observer;
use crate::system::{
@@ -176,7 +175,20 @@ impl World
where
Comps: ComponentSequence,
{
- self.create_ent(entity_uid, components.into_parts_array());
+ let components_parts = components.into_parts_array();
+
+ if let Some(comp_parts) = components_parts
+ .as_ref()
+ .iter()
+ .find(|comp_parts| comp_parts.is_sole)
+ {
+ panic!(
+ "Cannot spawn entity with sole component {}",
+ comp_parts.name
+ );
+ }
+
+ self.create_ent(entity_uid, components_parts);
}
/// Creates a entity with the given components. The entity will have the specified
@@ -193,10 +205,22 @@ impl World
) where
Comps: ComponentSequence,
{
+ let components_parts = components.into_parts_array();
+
+ if let Some(comp_parts) = components_parts
+ .as_ref()
+ .iter()
+ .find(|comp_parts| comp_parts.is_sole)
+ {
+ panic!(
+ "Cannot spawn entity with sole component {}",
+ comp_parts.name
+ );
+ }
+
self.create_ent(
entity_uid,
- components
- .into_parts_array()
+ components_parts
.into_iter()
.chain([EntityName { name: name.into() }.into_parts()]),
);
@@ -204,6 +228,12 @@ impl World
pub fn add_component(&mut self, entity_id: Uid, component_parts: ComponentParts)
{
+ assert!(
+ !component_parts.is_sole,
+ "Cannot add sole component {} to an entity",
+ component_parts.name
+ );
+
Self::add_entity_components(
entity_id,
[component_parts],
@@ -225,6 +255,15 @@ impl World
where
SoleT: Sole,
{
+ if self
+ .data
+ .component_storage
+ .get_entity_archetype(SoleT::id())
+ .is_some()
+ {
+ return Err(SoleAlreadyExistsError);
+ }
+
let name = sole.name();
self.create_ent(
@@ -685,22 +724,28 @@ impl World
&component_parts.pair_relation_metadata
{
Self::create_component_info_entity_if_missing(
- comp_id.relation(),
- pair_relation_metadata.name,
- pair_relation_metadata.ty,
- pair_relation_metadata.ty_id,
component_storage,
+ comp_id.relation(),
+ ComponentInfo {
+ type_reflection: pair_relation_metadata.ty,
+ ty_id: pair_relation_metadata.ty_id,
+ name: pair_relation_metadata.name,
+ is_sole: pair_relation_metadata.is_sole,
+ },
);
}
if let Some(pair_target_metadata) = &component_parts.pair_target_metadata
{
Self::create_component_info_entity_if_missing(
- comp_id.target(),
- pair_target_metadata.name,
- pair_target_metadata.ty,
- pair_target_metadata.ty_id,
component_storage,
+ comp_id.target(),
+ ComponentInfo {
+ type_reflection: pair_target_metadata.ty,
+ ty_id: pair_target_metadata.ty_id,
+ name: pair_target_metadata.name,
+ is_sole: pair_target_metadata.is_sole,
+ },
);
}
@@ -708,11 +753,14 @@ impl World
}
Self::create_component_info_entity_if_missing(
- comp_id,
- comp_name,
- component_parts.type_reflection,
- comp_type_id,
component_storage,
+ comp_id,
+ ComponentInfo {
+ type_reflection: component_parts.type_reflection,
+ ty_id: comp_type_id,
+ name: comp_name,
+ is_sole: component_parts.is_sole,
+ },
);
event_submitter.submit_event(
@@ -726,11 +774,9 @@ impl World
}
fn create_component_info_entity_if_missing(
- comp_id: Uid,
- comp_name: &'static str,
- type_reflection: Option<&'static TypeReflection>,
- type_id: TypeId,
component_storage: &mut ComponentStorage,
+ comp_id: Uid,
+ comp_info: ComponentInfo,
)
{
if let Some(comp_ent_archetype) = component_storage.get_entity_archetype(comp_id)
@@ -746,12 +792,7 @@ impl World
}
}
- let comp_info_parts = ComponentInfo {
- type_reflection,
- name: comp_name,
- ty_id: type_id,
- }
- .into_parts();
+ let comp_info_parts = comp_info.into_parts();
match component_storage.add_entity_component(
comp_id,
@@ -962,5 +1003,5 @@ impl ActionQueue
}
#[derive(Debug, thiserror::Error)]
-#[error("Sole {0} already exists")]
-pub struct SoleAlreadyExistsError(pub &'static str);
+#[error("Sole already exists")]
+pub struct SoleAlreadyExistsError;
diff --git a/engine-ecs/src/pair.rs b/engine-ecs/src/pair.rs
index 98f0257..834077c 100644
--- a/engine-ecs/src/pair.rs
+++ b/engine-ecs/src/pair.rs
@@ -46,6 +46,7 @@ impl<Relation, Target> Builder<Relation, Target>
ty: NewRelation::type_reflection(),
ty_id: TypeId::of::<NewRelation>(),
name: type_name::<NewRelation>(),
+ is_sole: false,
}),
target_metadata: self.target_metadata,
}
@@ -71,6 +72,7 @@ impl<Relation, Target> Builder<Relation, Target>
ty: NewTarget::type_reflection(),
ty_id: TypeId::of::<NewTarget>(),
name: type_name::<NewTarget>(),
+ is_sole: false,
}),
}
}
@@ -103,6 +105,7 @@ impl_multiple!(
ty: NewTarget::type_reflection(),
ty_id: TypeId::of::<NewTarget>(),
name: type_name::<NewTarget>(),
+ is_sole: false,
}),
}
}
@@ -125,6 +128,7 @@ impl_multiple!(
ty: NewRelation::type_reflection(),
ty_id: TypeId::of::<NewRelation>(),
name: type_name::<NewRelation>(),
+ is_sole: false,
}),
target_metadata: self.target_metadata,
}
@@ -770,6 +774,7 @@ pub struct MemberMetadata
pub ty: Option<&'static TypeReflection>,
pub ty_id: TypeId,
pub name: &'static str,
+ pub is_sole: bool,
}
#[macro_export]
diff --git a/engine/src/draw_flags.rs b/engine/src/draw_flags.rs
index e58eea0..b32bb14 100644
--- a/engine/src/draw_flags.rs
+++ b/engine/src/draw_flags.rs
@@ -54,5 +54,5 @@ pub enum PolygonModeFace
}
/// Component that makes a object not be drawn.
-#[derive(Debug, Clone, Copy, Component, Reflection)]
+#[derive(Debug, Default, Clone, Copy, Component, Reflection)]
pub struct NoDraw;
diff --git a/engine/src/rendering.rs b/engine/src/rendering.rs
index ffb5a4f..140d99e 100644
--- a/engine/src/rendering.rs
+++ b/engine/src/rendering.rs
@@ -108,7 +108,7 @@ impl Default for Extension
}
/// Marker component for windows that should be renderer to.
-#[derive(Debug, Clone, Copy, Component)]
+#[derive(Debug, Default, Clone, Copy, Component, Reflection)]
pub struct TargetWindow;
builder! {
@@ -632,12 +632,20 @@ pub enum SrgbaTextureDataType
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[non_exhaustive]
+pub enum DepthTextureDataType
+{
+ Float32,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[non_exhaustive]
pub enum TexturePixelDataFormat
{
Rgb(RgbTextureDataType),
Rgba(RgbaTextureDataType),
Srgb(SrgbTextureDataType),
Srgba(SrgbaTextureDataType),
+ Depth(DepthTextureDataType),
}
impl TexturePixelDataFormat
diff --git a/engine/src/rendering/backend/opengl.rs b/engine/src/rendering/backend/opengl.rs
index 444c757..381a609 100644
--- a/engine/src/rendering/backend/opengl.rs
+++ b/engine/src/rendering/backend/opengl.rs
@@ -1577,6 +1577,13 @@ fn tex_pixel_data_format_into_gl(
}
})
}
+ TexturePixelDataFormat::Depth(data_type) => {
+ GlTexturePixelDataFormat::DepthComponent(match data_type {
+ crate::rendering::DepthTextureDataType::Float32 => {
+ opengl_bindings::texture::DepthComponentDataType::Float32
+ }
+ })
+ }
}
}
diff --git a/engine/src/scene.rs b/engine/src/scene.rs
index 77c274c..2a66c3f 100644
--- a/engine/src/scene.rs
+++ b/engine/src/scene.rs
@@ -1,8 +1,8 @@
use crate::ecs::Component;
use crate::reflection::Reflection;
-#[derive(Debug, Clone, Component, Reflection)]
+#[derive(Debug, Default, Clone, Copy, Component, Reflection)]
pub struct Scene;
-#[derive(Debug, Clone, Copy, Component, Reflection)]
+#[derive(Debug, Default, Clone, Copy, Component, Reflection)]
pub struct Active;
diff --git a/engine/src/ui/dear_imgui.rs b/engine/src/ui/dear_imgui.rs
index d3ca4dc..0ae8a3b 100644
--- a/engine/src/ui/dear_imgui.rs
+++ b/engine/src/ui/dear_imgui.rs
@@ -315,7 +315,7 @@ fn update(
Ok(())
}
-#[derive(Debug, Component, Reflection)]
+#[derive(Debug, Default, Clone, Copy, Component, Reflection)]
pub struct TargetWindow;
#[derive(Debug, Default, Component)]
diff --git a/engine/src/ui/view/world.rs b/engine/src/ui/view/world.rs
index ff4c13a..143ff84 100644
--- a/engine/src/ui/view/world.rs
+++ b/engine/src/ui/view/world.rs
@@ -608,7 +608,9 @@ fn enter_add_component_popup_state(
.query::<(&ComponentInfo,)>()
.iter_with_euids()
.map(|(id, (component_info,))| {
- let user_creatable = if component_info.type_reflection.is_none() {
+ let user_creatable = if component_info.is_sole {
+ ComponentUserCreatable::No { reason: "is a sole" }
+ } else if component_info.type_reflection.is_none() {
ComponentUserCreatable::No { reason: "no type reflection" }
} else if component_info
.type_reflection
@@ -796,10 +798,11 @@ fn show_add_component_popup(
{
actions.add_components(
add_component_popup_state.target_entity_id,
- [ComponentParts::builder()
- .name(new_component_info.name)
- .type_reflection(new_component_info.type_reflection)
- .build_with_any_data(new_component_id, new_component_data)],
+ [ComponentParts::from_component_info(
+ &new_component_info,
+ new_component_id,
+ new_component_data,
+ )],
);
return true;
diff --git a/rust-analyzer.json b/rust-analyzer.json
new file mode 100644
index 0000000..f20ac7a
--- /dev/null
+++ b/rust-analyzer.json
@@ -0,0 +1,18 @@
+{
+ "cargo": {
+ "allTargets": false
+ },
+ "check": {
+ "overrideCommand": [
+ "rustup",
+ "run",
+ "nightly",
+ "cargo",
+ "check",
+ "--workspace",
+ "--message-format=json",
+ "--keep-going",
+ "--config=.cargo/config-nightly-fast-compile.toml"
+ ]
+ }
+}
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
new file mode 100644
index 0000000..337bfe3
--- /dev/null
+++ b/xtask/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "xtask"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
new file mode 100644
index 0000000..e955925
--- /dev/null
+++ b/xtask/src/main.rs
@@ -0,0 +1,24 @@
+use std::process::Command;
+
+fn main()
+{
+ let mut args = std::env::args();
+
+ let Some(task) = args.nth(1) else {
+ println!("Error: No task is specified");
+ return;
+ };
+
+ if task == "execute" {
+ let Some(program) = args.next() else {
+ println!("Error: No program is specified");
+ return;
+ };
+
+ if let Err(err) = Command::new(program).args(args).status() {
+ println!("Error: Failed to execute command: {err}");
+ }
+ } else {
+ println!("Error: Unknown task '{task}'");
+ }
+}