mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Further generalize the typed module.
This enables us to automatically create configuration formats from enums or structs. For enums, we create a structure with a field for each case, representing a pattern match; the configuration format can then enter a different expression for each case. For structs, we create an enum with a variant for each field, representing projecting by that field; the configuration format selects the field to project from, and then can write a further expression on that field (for instance, it can perform another pattern match). So far we don't actually have anything that *uses* this functionality; I decided to finish it for the purpose of specifying a default lantern offset, only to discover that we already return a lantern offset from the animation crate. So I fixed it there instead.
This commit is contained in:
parent
62427cb01f
commit
6f3d5da6f3
@ -1,11 +1,15 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
@ -25,15 +29,18 @@ impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::BipedLarge(body) }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Ogre = 0,
|
||||
Cyclops = 1,
|
||||
Wendigo = 2,
|
||||
Troll = 3,
|
||||
Dullahan = 4,
|
||||
}
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Ogre = 0,
|
||||
Cyclops = 1,
|
||||
Wendigo = 2,
|
||||
Troll = 3,
|
||||
Dullahan = 4,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
@ -77,10 +84,13 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -1,11 +1,15 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
@ -25,18 +29,21 @@ impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::BirdMedium(body) }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Duck = 0,
|
||||
Chicken = 1,
|
||||
Goose = 2,
|
||||
Peacock = 3,
|
||||
Eagle = 4,
|
||||
Snowyowl = 5,
|
||||
Parrot = 6,
|
||||
Cockatrice = 7,
|
||||
}
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Duck = 0,
|
||||
Chicken = 1,
|
||||
Goose = 2,
|
||||
Peacock = 3,
|
||||
Eagle = 4,
|
||||
Snowyowl = 5,
|
||||
Parrot = 6,
|
||||
Cockatrice = 7,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
@ -89,10 +96,13 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -1,13 +1,18 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub head: Head,
|
||||
pub torso: Torso,
|
||||
pub wing_l: WingL,
|
||||
pub wing_r: WingR,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub head: Head,
|
||||
pub torso: Torso,
|
||||
pub wing_l: WingL,
|
||||
pub wing_r: WingR,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
let mut rng = thread_rng();
|
||||
@ -20,30 +25,42 @@ impl Body {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Head {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
head,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Head {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_HEADS: [Head; 1] = [Head::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
torso,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_TORSOS: [Torso; 1] = [Torso::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum WingL {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
wing_l,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum WingL {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_WING_LS: [WingL; 1] = [WingL::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum WingR {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
wing_r,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum WingR {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_WING_RS: [WingR; 1] = [WingR::Default];
|
||||
|
@ -1,11 +1,15 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
@ -25,16 +29,19 @@ impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::Critter(body) }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Rat = 0,
|
||||
Axolotl = 1,
|
||||
Gecko = 2,
|
||||
Turtle = 3,
|
||||
Squirrel = 4,
|
||||
Fungome = 5,
|
||||
}
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Rat = 0,
|
||||
Axolotl = 1,
|
||||
Gecko = 2,
|
||||
Turtle = 3,
|
||||
Squirrel = 4,
|
||||
Fungome = 5,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
@ -79,10 +86,14 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -1,11 +1,15 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
@ -25,11 +29,14 @@ impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::Dragon(body) }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Reddragon = 0,
|
||||
}
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Reddragon = 0,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
@ -59,10 +66,14 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -1,15 +1,20 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub head: Head,
|
||||
pub torso: Torso,
|
||||
pub rear: Rear,
|
||||
pub tail: Tail,
|
||||
pub fin_l: FinL,
|
||||
pub fin_r: FinR,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub head: Head,
|
||||
pub torso: Torso,
|
||||
pub rear: Rear,
|
||||
pub tail: Tail,
|
||||
pub fin_l: FinL,
|
||||
pub fin_r: FinR,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
let mut rng = thread_rng();
|
||||
@ -24,44 +29,63 @@ impl Body {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Head {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
head,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Head {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
|
||||
const ALL_HEADS: [Head; 1] = [Head::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
torso,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_TORSOS: [Torso; 1] = [Torso::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Rear {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
rear,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Rear {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_REARS: [Rear; 1] = [Rear::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Tail {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
tail,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Tail {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_TAILS: [Tail; 1] = [Tail::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum FinL {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
fin_l,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum FinL {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_FIN_LS: [FinL; 1] = [FinL::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum FinR {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
fin_r,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum FinR {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_FIN_RS: [FinR; 1] = [FinR::Default];
|
||||
|
@ -1,11 +1,16 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub torso: Torso,
|
||||
pub tail: Tail,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub torso: Torso,
|
||||
pub tail: Tail,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
let mut rng = thread_rng();
|
||||
@ -16,16 +21,24 @@ impl Body {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
torso,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
|
||||
const ALL_TORSOS: [Torso; 1] = [Torso::Default];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Tail {
|
||||
Default,
|
||||
}
|
||||
make_case_elim!(
|
||||
tail,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Tail {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
|
||||
const ALL_TAILS: [Tail; 1] = [Tail::Default];
|
||||
|
@ -1,11 +1,15 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
@ -25,11 +29,14 @@ impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::Golem(body) }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
StoneGolem = 0,
|
||||
}
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
StoneGolem = 0,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
@ -59,10 +66,14 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -1,20 +1,30 @@
|
||||
use crate::make_case_elim;
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng, Rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
pub hair_style: u8,
|
||||
pub beard: u8,
|
||||
pub eyes: u8,
|
||||
pub accessory: u8,
|
||||
pub hair_color: u8,
|
||||
pub skin: u8,
|
||||
pub eye_color: u8,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
#[typed(pure)]
|
||||
pub hair_style: u8,
|
||||
#[typed(pure)]
|
||||
pub beard: u8,
|
||||
#[typed(pure)]
|
||||
pub eyes: u8,
|
||||
#[typed(pure)]
|
||||
pub accessory: u8,
|
||||
#[typed(pure)]
|
||||
pub hair_color: u8,
|
||||
#[typed(pure)]
|
||||
pub skin: u8,
|
||||
#[typed(pure)]
|
||||
pub eye_color: u8,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
|
@ -1,70 +1,74 @@
|
||||
use crate::make_case_elim;
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Body {
|
||||
Arrow = 0,
|
||||
Bomb = 1,
|
||||
Scarecrow = 2,
|
||||
Cauldron = 3,
|
||||
ChestVines = 4,
|
||||
Chest = 5,
|
||||
ChestDark = 6,
|
||||
ChestDemon = 7,
|
||||
ChestGold = 8,
|
||||
ChestLight = 9,
|
||||
ChestOpen = 10,
|
||||
ChestSkull = 11,
|
||||
Pumpkin = 12,
|
||||
Pumpkin2 = 13,
|
||||
Pumpkin3 = 14,
|
||||
Pumpkin4 = 15,
|
||||
Pumpkin5 = 16,
|
||||
Campfire = 17,
|
||||
LanternGround = 18,
|
||||
LanternGroundOpen = 19,
|
||||
LanternStanding2 = 20,
|
||||
LanternStanding = 21,
|
||||
PotionBlue = 22,
|
||||
PotionGreen = 23,
|
||||
PotionRed = 24,
|
||||
Crate = 25,
|
||||
Tent = 26,
|
||||
WindowSpooky = 27,
|
||||
DoorSpooky = 28,
|
||||
Anvil = 29,
|
||||
Gravestone = 30,
|
||||
Gravestone2 = 31,
|
||||
Bench = 32,
|
||||
Chair = 33,
|
||||
Chair2 = 34,
|
||||
Chair3 = 35,
|
||||
Table = 36,
|
||||
Table2 = 37,
|
||||
Table3 = 38,
|
||||
Drawer = 39,
|
||||
BedBlue = 40,
|
||||
Carpet = 41,
|
||||
Bedroll = 42,
|
||||
CarpetHumanRound = 43,
|
||||
CarpetHumanSquare = 44,
|
||||
CarpetHumanSquare2 = 45,
|
||||
CarpetHumanSquircle = 46,
|
||||
Pouch = 47,
|
||||
CraftingBench = 48,
|
||||
BoltFire = 49,
|
||||
ArrowSnake = 50,
|
||||
CampfireLit = 51,
|
||||
BoltFireBig = 52,
|
||||
TrainingDummy = 53,
|
||||
FireworkBlue = 54,
|
||||
FireworkGreen = 55,
|
||||
FireworkPurple = 56,
|
||||
FireworkRed = 57,
|
||||
FireworkYellow = 58,
|
||||
MultiArrow = 59,
|
||||
}
|
||||
make_case_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Body {
|
||||
Arrow = 0,
|
||||
Bomb = 1,
|
||||
Scarecrow = 2,
|
||||
Cauldron = 3,
|
||||
ChestVines = 4,
|
||||
Chest = 5,
|
||||
ChestDark = 6,
|
||||
ChestDemon = 7,
|
||||
ChestGold = 8,
|
||||
ChestLight = 9,
|
||||
ChestOpen = 10,
|
||||
ChestSkull = 11,
|
||||
Pumpkin = 12,
|
||||
Pumpkin2 = 13,
|
||||
Pumpkin3 = 14,
|
||||
Pumpkin4 = 15,
|
||||
Pumpkin5 = 16,
|
||||
Campfire = 17,
|
||||
LanternGround = 18,
|
||||
LanternGroundOpen = 19,
|
||||
LanternStanding2 = 20,
|
||||
LanternStanding = 21,
|
||||
PotionBlue = 22,
|
||||
PotionGreen = 23,
|
||||
PotionRed = 24,
|
||||
Crate = 25,
|
||||
Tent = 26,
|
||||
WindowSpooky = 27,
|
||||
DoorSpooky = 28,
|
||||
Anvil = 29,
|
||||
Gravestone = 30,
|
||||
Gravestone2 = 31,
|
||||
Bench = 32,
|
||||
Chair = 33,
|
||||
Chair2 = 34,
|
||||
Chair3 = 35,
|
||||
Table = 36,
|
||||
Table2 = 37,
|
||||
Table3 = 38,
|
||||
Drawer = 39,
|
||||
BedBlue = 40,
|
||||
Carpet = 41,
|
||||
Bedroll = 42,
|
||||
CarpetHumanRound = 43,
|
||||
CarpetHumanSquare = 44,
|
||||
CarpetHumanSquare2 = 45,
|
||||
CarpetHumanSquircle = 46,
|
||||
Pouch = 47,
|
||||
CraftingBench = 48,
|
||||
BoltFire = 49,
|
||||
ArrowSnake = 50,
|
||||
CampfireLit = 51,
|
||||
BoltFireBig = 52,
|
||||
TrainingDummy = 53,
|
||||
FireworkBlue = 54,
|
||||
FireworkGreen = 55,
|
||||
FireworkPurple = 56,
|
||||
FireworkRed = 57,
|
||||
FireworkYellow = 58,
|
||||
MultiArrow = 59,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
|
@ -1,11 +1,15 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
@ -25,19 +29,22 @@ impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::QuadrupedLow(body) }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Crocodile = 0,
|
||||
Alligator = 1,
|
||||
Salamander = 2,
|
||||
Monitor = 3,
|
||||
Asp = 4,
|
||||
Tortoise = 5,
|
||||
Rocksnapper = 6,
|
||||
Pangolin = 7,
|
||||
Maneater = 8,
|
||||
}
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Crocodile = 0,
|
||||
Alligator = 1,
|
||||
Salamander = 2,
|
||||
Monitor = 3,
|
||||
Asp = 4,
|
||||
Tortoise = 5,
|
||||
Rocksnapper = 6,
|
||||
Pangolin = 7,
|
||||
Maneater = 8,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
@ -93,10 +100,13 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -1,11 +1,15 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
@ -25,21 +29,24 @@ impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::QuadrupedMedium(body) }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Grolgar = 0,
|
||||
Saber = 1,
|
||||
Tiger = 2,
|
||||
Tuskram = 3,
|
||||
Lion = 6,
|
||||
Tarasque = 7,
|
||||
Wolf = 8,
|
||||
Frostfang = 9,
|
||||
Mouflon = 10,
|
||||
Catoblepas = 11,
|
||||
Bonerattler = 12,
|
||||
}
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Grolgar = 0,
|
||||
Saber = 1,
|
||||
Tiger = 2,
|
||||
Tuskram = 3,
|
||||
Lion = 6,
|
||||
Tarasque = 7,
|
||||
Wolf = 8,
|
||||
Frostfang = 9,
|
||||
Mouflon = 10,
|
||||
Catoblepas = 11,
|
||||
Bonerattler = 12,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
@ -101,10 +108,14 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -1,11 +1,15 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
@ -25,26 +29,29 @@ impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::QuadrupedSmall(body) }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Pig = 0,
|
||||
Fox = 1,
|
||||
Sheep = 2,
|
||||
Boar = 3,
|
||||
Jackalope = 4,
|
||||
Skunk = 5,
|
||||
Cat = 6,
|
||||
Batfox = 7,
|
||||
Raccoon = 8,
|
||||
Quokka = 9,
|
||||
Dodarock = 10,
|
||||
Holladon = 11,
|
||||
Hyena = 12,
|
||||
Rabbit = 13,
|
||||
Truffler = 14,
|
||||
Frog = 15,
|
||||
}
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Pig = 0,
|
||||
Fox = 1,
|
||||
Sheep = 2,
|
||||
Boar = 3,
|
||||
Jackalope = 4,
|
||||
Skunk = 5,
|
||||
Cat = 6,
|
||||
Batfox = 7,
|
||||
Raccoon = 8,
|
||||
Quokka = 9,
|
||||
Dodarock = 10,
|
||||
Holladon = 11,
|
||||
Hyena = 12,
|
||||
Rabbit = 13,
|
||||
Truffler = 14,
|
||||
Frog = 15,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
@ -121,10 +128,14 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -1,4 +1,5 @@
|
||||
use core::marker::PhantomData;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub trait SubContext<Context> {
|
||||
fn sub_context(self) -> Context;
|
||||
@ -16,10 +17,52 @@ pub trait Typed<Context, Type, S> {
|
||||
fn reduce(self, context: Context) -> (Type, S);
|
||||
}
|
||||
|
||||
/// Given a head expression (Self) and a target type (Type),
|
||||
/// attempt to synthesize a term that reduces head into the target type.
|
||||
///
|
||||
/// How we do this depends on the type of the head expression:
|
||||
///
|
||||
/// - For enums, we synthesize a match on the current head. For each match arm,
|
||||
/// we then repeat this process on the constructor arguments; if there are no
|
||||
/// constructor arguments, we synthesize a literal (Pure term). (TODO: Handle
|
||||
/// > 1 tuple properly--for now we just synthesize a Pure term for these
|
||||
/// cases).
|
||||
///
|
||||
/// - For structs, we synthesize a projection on the current head. For each
|
||||
/// projection, we then repeat this process on the type of the projected
|
||||
/// field.
|
||||
///
|
||||
/// - For other types (which currently have to opt out during the field
|
||||
/// declaration), we synthesize a literal.
|
||||
///
|
||||
/// TODO: Differentiate between the context and the stack at some point; for
|
||||
/// now, we only use the context as a stack.
|
||||
pub trait SynthTyped<Context, Target> {
|
||||
type Expr;
|
||||
}
|
||||
|
||||
/// Weak head reduction type (equivalent to applying a reduction to the head
|
||||
/// variable, but this way we don't have to implement variable lookup and it
|
||||
/// doesn't serialize with variables).
|
||||
#[fundamental]
|
||||
#[serde(transparent)]
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct WeakHead<Reduction, Type> {
|
||||
pub red: Reduction,
|
||||
#[serde(skip)]
|
||||
pub ty: PhantomData<Type>,
|
||||
}
|
||||
|
||||
#[serde(transparent)]
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Pure<T>(pub T);
|
||||
|
||||
impl<Context: SubContext<S>, T, S> Typed<Context, Pure<T>, S> for T {
|
||||
fn reduce(self, context: Context) -> (Pure<T>, S) { (Pure(self), context.sub_context()) }
|
||||
impl<'a, Context: SubContext<S>, T, S> Typed<Context, &'a T, S> for &'a Pure<T> {
|
||||
fn reduce(self, context: Context) -> (&'a T, S) { (&self.0, context.sub_context()) }
|
||||
}
|
||||
|
||||
impl<Context, Target> SynthTyped<Context, Target> for WeakHead<Pure<Target>, Target> {
|
||||
type Expr = Pure<Target>;
|
||||
}
|
||||
|
||||
/// A lazy pattern match reified as a Rust type.
|
||||
@ -50,7 +93,7 @@ impl<Context: SubContext<S>, T, S> Typed<Context, Pure<T>, S> for T {
|
||||
/// #[derive(Clone,Copy)]
|
||||
/// pub enum MyType {
|
||||
/// Constr1 = 0,
|
||||
/// Constr2(arg : u8) = 1,
|
||||
/// #[typed(pure)] Constr2(arg : u8) = 1,
|
||||
/// /* ..., */
|
||||
/// }
|
||||
/// );
|
||||
@ -141,18 +184,26 @@ impl<Context: SubContext<S>, T, S> Typed<Context, Pure<T>, S> for T {
|
||||
///
|
||||
/// Limitations:
|
||||
///
|
||||
/// Unfortunately, due to restrictions on procedural macros, we currently always
|
||||
/// Unfortunately, due to restrictions on macro_rules, we currently always
|
||||
/// require the types defined to #[repr(inttype)] as you can see above. There
|
||||
/// are also some other current limitations that we hopefully will be able to
|
||||
/// lift at some point; struct variants are not yet supported, and neither
|
||||
/// attributes on fields.
|
||||
#[fundamental]
|
||||
pub struct ElimCase<Expr, Cases, Type> {
|
||||
pub expr: Expr,
|
||||
#[serde(transparent)]
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct ElimCase<Cases> {
|
||||
pub cases: Cases,
|
||||
pub ty: PhantomData<Type>,
|
||||
}
|
||||
|
||||
#[fundamental]
|
||||
#[serde(transparent)]
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct ElimProj<Proj> {
|
||||
pub proj: Proj,
|
||||
}
|
||||
pub type ElimWeak<Type, Elim> = <WeakHead<Type, Elim> as SynthTyped<((Type,), ()), Elim>>::Expr;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! as_item {
|
||||
($i:item) => {
|
||||
@ -160,10 +211,33 @@ macro_rules! as_item {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
/// This macro is used internally by typed.
|
||||
///
|
||||
/// We use this in order to reliably construct a "representative" type for the
|
||||
/// weak head reduction type. We need this because for some types of arguments
|
||||
/// (empty variants for an enum, fields or constructor arguments explicitly
|
||||
/// marked as #[typed(pure)], etc.) won't directly implement the WeakHead trait;
|
||||
/// in such cases, we just synthesize a literal of the appropriate type.
|
||||
macro_rules! make_weak_head_type {
|
||||
($Target:ty, $( #[$attr:meta] )* , ) => {
|
||||
$crate::typed::Pure<$Target>
|
||||
};
|
||||
($Target:ty, #[ typed(pure) ] , $( $extra:tt )*) => {
|
||||
$crate::typed::Pure<$Target>
|
||||
};
|
||||
($Target:ty, , $Type:ty, $( $extra:tt )*) => {
|
||||
$crate::typed::Pure<$Target>
|
||||
};
|
||||
($Target:ty, , $Type:ty) => {
|
||||
$Type
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! make_case_elim {
|
||||
($mod:ident, $( #[$ty_attr:meta] )* $vis:vis enum $ty:ident {
|
||||
$( $constr:ident $( ( $( $arg_name:ident : $arg_ty:ty ),* ) )? = $index:expr ),* $(,)?
|
||||
($mod:ident, $( #[ $ty_attr:meta ] )* $vis:vis enum $ty:ident {
|
||||
$( $( #[$( $constr_attr:tt )*] )* $constr:ident $( ( $( $arg_name:ident : $arg_ty:ty ),* ) )? = $index:expr ),* $(,)?
|
||||
}) => {
|
||||
$crate::as_item! {
|
||||
$( #[$ty_attr] )*
|
||||
@ -190,26 +264,48 @@ macro_rules! make_case_elim {
|
||||
$( pub $constr : Elim::$constr, )*
|
||||
}
|
||||
|
||||
impl<T> PackedElim for $crate::typed::Pure<T> {
|
||||
$( type $constr = T; )*
|
||||
}
|
||||
pub type PureCases<Elim> = $crate::typed::ElimCase<Cases<$crate::typed::Pure<Elim>>>;
|
||||
}
|
||||
|
||||
pub type PureCases<Elim> = Cases<$crate::typed::Pure<Elim>>;
|
||||
impl<T> $mod::PackedElim for $crate::typed::Pure<T> {
|
||||
$( type $constr = $crate::typed::Pure<T>; )*
|
||||
}
|
||||
|
||||
#[allow(unused_parens)]
|
||||
impl<Target> $mod::PackedElim for $crate::typed::WeakHead<$ty, Target>
|
||||
where $(
|
||||
$crate::typed::WeakHead<$crate::make_weak_head_type!(Target, $( #[$( $constr_attr )*] )* , $( $( $arg_ty ),* )?), Target> :
|
||||
$crate::typed::SynthTyped<($( ($( $arg_ty, )*), )? ()), Target>,
|
||||
)*
|
||||
{
|
||||
$( type $constr =
|
||||
<$crate::typed::WeakHead<$crate::make_weak_head_type!(Target, $( #[$( $constr_attr )*] )* , $( $( $arg_ty ),* )?), Target>
|
||||
as $crate::typed::SynthTyped<($( ($( $arg_ty, )*), )? ()), Target>>::Expr;
|
||||
)*
|
||||
}
|
||||
|
||||
#[allow(unused_parens)]
|
||||
impl<Context, Target> $crate::typed::SynthTyped<(($ty,), Context), Target> for $crate::typed::WeakHead<$ty, Target>
|
||||
where $(
|
||||
$crate::typed::WeakHead<$crate::make_weak_head_type!(Target, $( #[$( $constr_attr )*] )* , $( $( $arg_ty ),* )?), Target> :
|
||||
$crate::typed::SynthTyped<($( ($( $arg_ty, )*), )? ()), Target>,
|
||||
)*
|
||||
{
|
||||
type Expr = $crate::typed::ElimCase<$mod::Cases<$crate::typed::WeakHead<$ty, Target>>>;
|
||||
}
|
||||
|
||||
#[allow(unused_parens)]
|
||||
impl<'a, 'b, Elim: $mod::PackedElim, Context, Type, S>
|
||||
$crate::typed::Typed<Context, Type, S> for $crate::typed::ElimCase<&'a $ty, &'b $mod::Cases<Elim>, Type>
|
||||
$crate::typed::Typed<((&'a $ty,), Context), Type, S> for &'b $crate::typed::ElimCase<$mod::Cases<Elim>>
|
||||
where
|
||||
$( &'b Elim::$constr: $crate::typed::Typed<($( ($( &'a $arg_ty, )*), )? Context), Type, S>, )*
|
||||
$( &'b Elim::$constr: $crate::typed::Typed<($( ($( &'a $arg_ty, )*), )? Context), Type, S> ),*
|
||||
{
|
||||
fn reduce(self, context: Context) -> (Type, S)
|
||||
fn reduce(self, ((head,), context): ((&'a $ty,), Context)) -> (Type, S)
|
||||
{
|
||||
let Self { expr, cases, .. } = self;
|
||||
match expr {
|
||||
match head {
|
||||
$( $ty::$constr $( ($( $arg_name, )*) )? =>
|
||||
<_ as $crate::typed::Typed<_, Type, _>>::reduce(
|
||||
&cases.$constr,
|
||||
&self.cases.$constr,
|
||||
($( ($( $arg_name, )*), )? context),
|
||||
),
|
||||
)*
|
||||
@ -218,24 +314,132 @@ macro_rules! make_case_elim {
|
||||
}
|
||||
|
||||
impl $ty {
|
||||
pub fn elim_case<'a, 'b, Elim: $mod::PackedElim, Context, S, Type>(&'a self, cases: &'b $mod::Cases<Elim>, context: Context) ->
|
||||
(Type, S)
|
||||
pub fn elim<'a, Elim, Context, S, Type>(&'a self, elim: Elim, context: Context) -> (Type, S)
|
||||
where
|
||||
$crate::typed::ElimCase<&'a $ty, &'b $mod::Cases<Elim>, Type> : $crate::typed::Typed<Context, Type, S>,
|
||||
Elim : $crate::typed::Typed<((&'a $ty,), Context), Type, S>,
|
||||
{
|
||||
use $crate::typed::Typed;
|
||||
|
||||
let case = $crate::typed::ElimCase {
|
||||
expr: self,
|
||||
cases,
|
||||
ty: ::core::marker::PhantomData,
|
||||
};
|
||||
case.reduce(context)
|
||||
elim.reduce(((self,), context))
|
||||
}
|
||||
|
||||
pub fn elim_case_pure<'a, 'b, Type>(&'a self, cases: &'b $mod::PureCases<Type>) -> &'b Type
|
||||
{
|
||||
let ($crate::typed::Pure(expr), ()) = self.elim_case(cases, ());
|
||||
let (expr, ()) = self.elim(cases, ());
|
||||
expr
|
||||
}
|
||||
|
||||
#[allow(unused_parens)]
|
||||
pub fn elim_case_weak<'a, 'b, Type>(&'a self, cases: &'b $crate::typed::ElimWeak<Self, Type>) -> &'b Type
|
||||
where $(
|
||||
$crate::typed::WeakHead<$crate::make_weak_head_type!(Type, $( #[$( $constr_attr )*] )* , $( $( $arg_ty ),* )?), Type> :
|
||||
$crate::typed::SynthTyped<($( ($( $arg_ty, )*), )? ()), Type>,
|
||||
)*
|
||||
&'b $crate::typed::ElimWeak<Self, Type> : $crate::typed::Typed<((&'a $ty,), ()), &'b Type, ()>,
|
||||
{
|
||||
let (expr, ()) = self.elim(cases, ());
|
||||
expr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! make_proj_elim {
|
||||
($mod:ident, $( #[ $ty_attr:meta ] )* $vis:vis struct $ty:ident {
|
||||
$( $( #[$( $constr_attr:tt )*] )* $field_vis:vis $constr:ident : $arg_ty:ty ),* $(,)?
|
||||
}) => {
|
||||
$crate::as_item! {
|
||||
$( #[$ty_attr] )*
|
||||
$vis struct $ty {
|
||||
$( $field_vis $constr : $arg_ty, )*
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(dead_code)]
|
||||
$vis mod $mod {
|
||||
use ::serde::{Deserialize, Serialize};
|
||||
|
||||
pub trait PackedElim {
|
||||
$( type $constr; )*
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum Proj<Elim: PackedElim> {
|
||||
$( $constr(Elim::$constr), )*
|
||||
}
|
||||
|
||||
pub type PureProj<Elim> = $crate::typed::ElimProj<Proj<$crate::typed::Pure<Elim>>>;
|
||||
}
|
||||
|
||||
impl<T> $mod::PackedElim for $crate::typed::Pure<T> {
|
||||
$( type $constr = $crate::typed::Pure<T>; )*
|
||||
}
|
||||
|
||||
#[allow(unused_parens)]
|
||||
impl<Target> $mod::PackedElim for $crate::typed::WeakHead<$ty, Target>
|
||||
where $(
|
||||
$crate::typed::WeakHead<$crate::make_weak_head_type!(Target, $( #[$( $constr_attr )*] )* , $arg_ty), Target> :
|
||||
$crate::typed::SynthTyped<(($arg_ty,), ()), Target>,
|
||||
)*
|
||||
{
|
||||
$( type $constr =
|
||||
<$crate::typed::WeakHead<$crate::make_weak_head_type!(Target, $( #[$( $constr_attr )*] )* , $arg_ty), Target>
|
||||
as $crate::typed::SynthTyped<(($arg_ty,), ()), Target>>::Expr;
|
||||
)*
|
||||
}
|
||||
|
||||
#[allow(unused_parens)]
|
||||
impl<Context, Target> $crate::typed::SynthTyped<(($ty,), Context), Target> for $crate::typed::WeakHead<$ty, Target>
|
||||
where $(
|
||||
$crate::typed::WeakHead<$crate::make_weak_head_type!(Target, $( #[$( $constr_attr )*] )* , $arg_ty), Target> :
|
||||
$crate::typed::SynthTyped<(($arg_ty,), ()), Target>,
|
||||
)*
|
||||
{
|
||||
type Expr = $crate::typed::ElimProj<$mod::Proj<$crate::typed::WeakHead<$ty, Target>>>;
|
||||
}
|
||||
|
||||
#[allow(unused_parens)]
|
||||
impl<'a, 'b, Elim: $mod::PackedElim, Context, Type, S>
|
||||
$crate::typed::Typed<((&'a $ty,), Context), Type, S> for &'b $crate::typed::ElimProj<$mod::Proj<Elim>>
|
||||
where
|
||||
$( &'b Elim::$constr: $crate::typed::Typed<((&'a $arg_ty,), Context), Type, S> ),*
|
||||
{
|
||||
fn reduce(self, ((head,), context): ((&'a $ty,), Context)) -> (Type, S)
|
||||
{
|
||||
match self.proj {
|
||||
$( $mod::Proj::$constr(ref projection) =>
|
||||
<_ as $crate::typed::Typed<_, Type, _>>::reduce(
|
||||
projection,
|
||||
((&head.$constr,), context),
|
||||
),
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl $ty {
|
||||
pub fn elim<'a, Elim, Context, S, Type>(&'a self, elim: Elim, context: Context) -> (Type, S)
|
||||
where
|
||||
Elim : $crate::typed::Typed<((&'a $ty,), Context), Type, S>,
|
||||
{
|
||||
elim.reduce(((self,), context))
|
||||
}
|
||||
|
||||
pub fn elim_proj_pure<'a, 'b, Type>(&'a self, cases: &'b $mod::PureProj<Type>) -> &'b Type
|
||||
{
|
||||
let (expr, ()) = self.elim(cases, ());
|
||||
expr
|
||||
}
|
||||
|
||||
#[allow(unused_parens)]
|
||||
pub fn elim_proj_weak<'a, 'b, Type>(&'a self, cases: &'b $crate::typed::ElimWeak<Self, Type>) -> &'b Type
|
||||
where $(
|
||||
$crate::typed::WeakHead<$crate::make_weak_head_type!(Type, $( #[$( $constr_attr )*] )* , $arg_ty), Type> :
|
||||
$crate::typed::SynthTyped<(($arg_ty,), ()), Type>,
|
||||
)*
|
||||
&'b $crate::typed::ElimWeak<Self, Type> : $crate::typed::Typed<((&'a $ty,), ()), &'b Type, ()>,
|
||||
{
|
||||
let (expr, ()) = self.elim(cases, ());
|
||||
expr
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,9 @@ impl Skeleton for ObjectSkeleton {
|
||||
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
||||
) -> Vec3<f32> {
|
||||
buf[0] = make_bone(base_mat * Mat4::scaling_3d(SCALE));
|
||||
Vec3::default()
|
||||
// TODO: Make dependent on bone, when we find an easier way to make that
|
||||
// information available.
|
||||
Vec3::unit_z() * 0.5
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,10 +378,10 @@ impl FigureMgr {
|
||||
}
|
||||
let dt = ecs.fetch::<DeltaTime>().0;
|
||||
let updater = ecs.read_resource::<LazyUpdate>();
|
||||
for (entity, waypoint, light_emitter_opt, light_anim) in (
|
||||
for (entity, light_emitter_opt, body, light_anim) in (
|
||||
&ecs.entities(),
|
||||
ecs.read_storage::<common::comp::WaypointArea>().maybe(),
|
||||
ecs.read_storage::<LightEmitter>().maybe(),
|
||||
ecs.read_storage::<Body>().maybe(),
|
||||
&mut ecs.write_storage::<LightAnimation>(),
|
||||
)
|
||||
.join()
|
||||
@ -401,10 +401,7 @@ impl FigureMgr {
|
||||
} else {
|
||||
(vek::Rgb::zero(), 0.0, 0.0, true)
|
||||
};
|
||||
if let Some(_) = waypoint {
|
||||
light_anim.offset = vek::Vec3::unit_z() * 5.0;
|
||||
}
|
||||
if let Some(state) = self.states.character_states.get(&entity) {
|
||||
if let Some(state) = body.and_then(|body| self.states.get_mut(body, &entity)) {
|
||||
light_anim.offset = vek::Vec3::from(state.lantern_offset);
|
||||
}
|
||||
if !light_anim.strength.is_normal() {
|
||||
|
Loading…
Reference in New Issue
Block a user