Compare commits

...

4 Commits

30 changed files with 472 additions and 317 deletions

View File

@ -180,7 +180,7 @@ macro_rules! rd_impl {
/// argument. The function's result has the `?` operator applied to it, /// argument. The function's result has the `?` operator applied to it,
/// unless `OPTS` is `no_try`. /// unless `OPTS` is `no_try`.
/// - `OPT`, if not one of the things listed above, may be `enum TYPE` to apply /// - `OPT`, if not one of the things listed above, may be `enum TYPE` to apply
/// `TryFrom<TYPE>`, or `flag TYPE` to apply a bitfield made by `bitflags!`. /// `TryFrom<TYPE>`, or `flag TYPE` to apply a bitfield made by `c_bitfield!`.
/// - `INDEX` is either an integer literal which must be representable as /// - `INDEX` is either an integer literal which must be representable as
/// `usize`, or a range with the syntax `INDEX; SIZE` denoting the beginning /// `usize`, or a range with the syntax `INDEX; SIZE` denoting the beginning
/// and size of the range. /// and size of the range.

88
maraiah/cbitfield.rs Normal file
View File

@ -0,0 +1,88 @@
#![doc(hidden)]
/// A wrapper for `bitflags!` which adds a `FromStr` implementation.
#[macro_export]
macro_rules! c_bitfield
{
(
$(#[$outer:meta])*
pub struct $t:ident: $ti:ty {
$(
$(#[$inner:ident $($args:tt)*])*
$f:ident = $v:expr
),+
$(,)?
}
) => {
bitflags! {
$(#[$outer])*
pub struct $t: $ti {
$(
$(#[$inner $($args)*])*
const $f = 1 << $v;
)+
}
}
#[allow(unused_qualifications)]
impl std::str::FromStr for $t
{
type Err = $crate::err::ParseFlagError;
fn from_str(s: &str) -> Result<Self, Self::Err>
{
let mut flags = $t::empty();
for s in s.split('|') {
match s {
$(
stringify!($f) => flags.insert($t::$f),
)+
"(none)" => (),
_ => return Err(Self::Err::new(stringify!($t)))
}
}
Ok(flags)
}
}
}
}
#[cfg(test)]
mod test
{
use crate::err::ParseFlagError;
use std::str::FromStr;
c_bitfield! {
pub struct TestFlag: u16 {
ZERO = 0,
ONE = 1,
TWO = 2,
}
}
#[test]
fn c_bitfield()
{
assert_eq!(TestFlag::from_bits(0), Some(TestFlag::empty()));
assert_eq!(TestFlag::from_bits(1), Some(TestFlag::ZERO));
assert_eq!(TestFlag::from_bits(2), Some(TestFlag::ONE));
assert_eq!(TestFlag::from_bits(4), Some(TestFlag::TWO));
assert_eq!(TestFlag::from_bits(8), None);
assert_eq!(TestFlag::from_str("(none)"), Ok(TestFlag::empty()));
assert_eq!(TestFlag::from_str("ZERO"), Ok(TestFlag::ZERO));
assert_eq!(TestFlag::from_str("ONE"), Ok(TestFlag::ONE));
assert_eq!(TestFlag::from_str("TWO"), Ok(TestFlag::TWO));
assert_eq!(TestFlag::from_str("ZERO|ONE|TWO"), Ok(TestFlag::all()));
assert_eq!(TestFlag::from_str("TWO|ZERO|ONE"), Ok(TestFlag::all()));
assert_eq!(TestFlag::from_str("ONE|ONE|ONE"), Ok(TestFlag::ONE));
assert_eq!(TestFlag::from_str("(none)|(none)"), Ok(TestFlag::empty()));
assert_eq!(TestFlag::from_str("(none)|ONE"), Ok(TestFlag::ONE));
assert_eq!(TestFlag::from_str("THREE"),
Err(ParseFlagError::new("TestFlag")));
}
}
// EOF

View File

@ -3,8 +3,8 @@
/// Creates an enumeration and function for converting a representation into the /// Creates an enumeration and function for converting a representation into the
/// enumeration type. /// enumeration type.
/// ///
/// The syntax is similar to the `bitflags` macro, but each value has the syntax /// The syntax is similar to the `c_bitfield` macro, but each value has the
/// `value = enumeration`. `enum` is used instead of `struct`. /// syntax `value = enumeration`. `enum` is used instead of `struct`.
/// ///
/// This will generate an `enum $t` as well as implement `TryFrom` on it which /// This will generate an `enum $t` as well as implement `TryFrom` on it which
/// will return `Result<$t, ReprError>`. /// will return `Result<$t, ReprError>`.
@ -26,25 +26,31 @@
/// assert_eq!(MyEnum::try_from(0), Ok(MyEnum::Zero)); /// assert_eq!(MyEnum::try_from(0), Ok(MyEnum::Zero));
/// assert_eq!(MyEnum::try_from(1), Ok(MyEnum::One)); /// assert_eq!(MyEnum::try_from(1), Ok(MyEnum::One));
/// assert_eq!(MyEnum::try_from(2), Ok(MyEnum::Two)); /// assert_eq!(MyEnum::try_from(2), Ok(MyEnum::Two));
/// assert_eq!(MyEnum::try_from(3), Err(ReprError::new(3))); /// assert_eq!(MyEnum::try_from(3), Err(ReprError::new("MyEnum", 3)));
/// assert_eq!(MyEnum::try_from(4), Err(ReprError::new(4))); /// assert_eq!(MyEnum::try_from(4), Err(ReprError::new("MyEnum", 4)));
/// assert_eq!(MyEnum::try_from(5), Err(ReprError::new(5))); /// assert_eq!(MyEnum::try_from(5), Err(ReprError::new("MyEnum", 5)));
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! c_enum macro_rules! c_enum
{ {
( (
$(#[$outer:meta])* $(#[$outer:meta])*
$vi:vis enum $t:ident: $ti:ident $vi:vis enum $t:ident: $ti:ident {
{ $(
$($(#[$vouter:meta])* $en:ident = $va:expr),+ $(,)? $(#[$inner:meta])*
$en:ident = $va:expr
),+
$(,)?
} }
) => { ) => {
$(#[$outer])* $(#[$outer])*
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[repr($ti)] #[repr($ti)]
$vi enum $t { $vi enum $t {
$($(#[$vouter])* $en = $va,)+ $(
$(#[$inner])*
$en = $va,
)+
} }
#[allow(unused_qualifications)] #[allow(unused_qualifications)]
@ -61,14 +67,30 @@ macro_rules! c_enum
} }
} }
} }
#[allow(unused_qualifications)]
impl std::str::FromStr for $t
{
type Err = $crate::err::ParseEnumError;
fn from_str(s: &str) -> Result<Self, Self::Err>
{
match s {
$(
stringify!($en) => Ok($t::$en),
)+
_ => Err(Self::Err::new(stringify!($t)))
}
}
}
}; };
} }
#[cfg(test)] #[cfg(test)]
mod test mod test
{ {
use crate::err::ReprError; use crate::err::{ParseEnumError, ReprError};
use std::convert::TryFrom; use std::{convert::TryFrom, str::FromStr};
c_enum! { c_enum! {
enum TestEnum: u16 { enum TestEnum: u16 {
@ -79,19 +101,20 @@ mod test
} }
#[test] #[test]
fn c_enum_should_be_ok() fn c_enum()
{ {
assert_eq!(TestEnum::try_from(0), Ok(TestEnum::Zero)); assert_eq!(TestEnum::try_from(0), Ok(TestEnum::Zero));
assert_eq!(TestEnum::try_from(1), Ok(TestEnum::One)); assert_eq!(TestEnum::try_from(1), Ok(TestEnum::One));
assert_eq!(TestEnum::try_from(2), Ok(TestEnum::Two)); assert_eq!(TestEnum::try_from(2), Ok(TestEnum::Two));
assert_eq!(TestEnum::try_from(3), Err(ReprError::new(3))); assert_eq!(TestEnum::try_from(3), Err(ReprError::new("TestEnum", 3)));
assert_eq!(TestEnum::try_from(4), Err(ReprError::new(4))); assert_eq!(TestEnum::try_from(4), Err(ReprError::new("TestEnum", 4)));
assert_eq!(TestEnum::try_from(5), Err(ReprError::new(5))); assert_eq!(TestEnum::try_from(5), Err(ReprError::new("TestEnum", 5)));
assert_eq!(TestEnum::from_str("Zero"), Ok(TestEnum::Zero));
assert_eq!(TestEnum::from_str("One"), Ok(TestEnum::One));
assert_eq!(TestEnum::from_str("Two"), Ok(TestEnum::Two));
assert_eq!(TestEnum::from_str("Three"),
Err(ParseEnumError::new("TestEnum")));
} }
#[test]
#[should_panic]
fn c_enum_should_error() {TestEnum::try_from(3).unwrap();}
} }
// EOF // EOF

View File

@ -53,6 +53,42 @@ macro_rules! backtrace {
/// ``` /// ```
pub fn err_msg(msg: &'static str) -> Error {ErrMsg(msg).into()} pub fn err_msg(msg: &'static str) -> Error {ErrMsg(msg).into()}
impl ParseEnumError
{
/// Returns an `Error` with a message for enumeration parsing errata.
///
/// # Examples
///
/// ```
/// use maraiah::err::ParseEnumError;
///
/// assert_eq!(format!("{}", ParseEnumError::new("TypeName")),
/// "could not parse TypeName");
/// ```
pub fn new(t: &'static str) -> Self
{
Self(t)
}
}
impl ParseFlagError
{
/// Returns an `Error` with a message for flag parsing errata.
///
/// # Examples
///
/// ```
/// use maraiah::err::ParseFlagError;
///
/// assert_eq!(format!("{}", ParseFlagError::new("TypeName")),
/// "could not parse TypeName");
/// ```
pub fn new(t: &'static str) -> Self
{
Self(t)
}
}
impl ReprError impl ReprError
{ {
/// Returns an `Error` with a message for representation errata. /// Returns an `Error` with a message for representation errata.
@ -60,9 +96,9 @@ impl ReprError
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use maraiah::err::repr_error; /// use maraiah::err::ReprError;
/// ///
/// assert_eq!(format!("{}", repr_error("TypeName", 77)), /// assert_eq!(format!("{}", ReprError::new("TypeName", 77)),
/// "bad TypeName (77)"); /// "bad TypeName (77)");
/// ``` /// ```
pub fn new<T: Into<i64>>(t: &'static str, n: T) -> Self pub fn new<T: Into<i64>>(t: &'static str, n: T) -> Self
@ -71,8 +107,26 @@ impl ReprError
} }
} }
impl Fail for ReprError {}
impl Fail for ErrMsg {} impl Fail for ErrMsg {}
impl Fail for ParseEnumError {}
impl Fail for ParseFlagError {}
impl Fail for ReprError {}
impl fmt::Display for ParseEnumError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "could not parse {}", self.0)
}
}
impl fmt::Display for ParseFlagError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "could not parse {}", self.0)
}
}
impl fmt::Display for ReprError impl fmt::Display for ReprError
{ {
@ -90,13 +144,21 @@ impl fmt::Display for ErrMsg
} }
} }
/// A representation error for an integer. #[derive(Clone, Debug)]
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct ReprError(&'static str, i64);
#[derive(Debug)]
struct ErrMsg(&'static str); struct ErrMsg(&'static str);
/// A parser error for an enumeration.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct ParseEnumError(&'static str);
/// A parser error for a bit field.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct ParseFlagError(&'static str);
/// A representation error for an integer.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct ReprError(&'static str, i64);
/// A generic `failure` based `Result` type. /// A generic `failure` based `Result` type.
pub type ResultS<T> = Result<T, Error>; pub type ResultS<T> = Result<T, Error>;

View File

@ -63,16 +63,14 @@
#![deny(clippy::use_self)] #![deny(clippy::use_self)]
#![deny(clippy::used_underscore_binding)] #![deny(clippy::used_underscore_binding)]
#[macro_use] #[macro_use] extern crate bitflags;
mod doc;
#[macro_use] #[macro_use] mod cbitfield;
pub mod ffi; #[macro_use] mod cenum;
#[macro_use] #[macro_use] mod doc;
pub mod err; #[macro_use] pub mod err;
#[macro_use] #[macro_use] pub mod ffi;
mod cenum; #[macro_use] pub mod bin;
#[macro_use]
pub mod bin;
pub mod bit; pub mod bit;
pub mod cksum; pub mod cksum;

View File

@ -1,7 +1,6 @@
//! `SoundRand` type. //! `SoundRand` type.
use crate::{err::*, fixed::{Angle, Fixed}}; use crate::{err::*, fixed::{Angle, Fixed}};
use bitflags::bitflags;
/// Reads a `bonk` chunk. /// Reads a `bonk` chunk.
pub fn read(b: &[u8]) -> ResultS<(SoundRand, usize)> pub fn read(b: &[u8]) -> ResultS<(SoundRand, usize)>
@ -41,12 +40,12 @@ pub struct SoundRand {
pub pit_dta: Fixed, pub pit_dta: Fixed,
} }
bitflags! { c_bitfield! {
/// Flags for `SoundRand`. /// Flags for `SoundRand`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct SoundRandFlags: u16 { pub struct SoundRandFlags: u16 {
const NO_DIRECTION = 1; NO_DIRECTION = 0,
const _2 = 2; _2 = 1,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Damage` type. //! `Damage` type.
use crate::{err::*, fixed::Fixed}; use crate::{err::*, fixed::Fixed};
use bitflags::bitflags;
/// Reads a `Damage` object. /// Reads a `Damage` object.
pub fn read(b: &[u8]) -> ResultS<Damage> pub fn read(b: &[u8]) -> ResultS<Damage>
@ -30,42 +29,42 @@ pub struct Damage {
pub scale: Fixed, pub scale: Fixed,
} }
bitflags! { c_bitfield! {
/// The composite type of damage taken by something. /// The composite type of damage taken by something.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct DamageTypeFlags: u32 { pub struct DamageTypeFlags: u32 {
const EXPLOSION = 1; EXPLOSION = 0,
const ELECTRICAL_STAFF = 1 << 1; ELECTRICAL_STAFF = 1,
const PROJECTILE = 1 << 2; PROJECTILE = 2,
const ABSORBED = 1 << 3; ABSORBED = 3,
const FLAME = 1 << 4; FLAME = 4,
const HOUND_CLAWS = 1 << 5; HOUND_CLAWS = 5,
const ALIEN_PROJECTILE = 1 << 6; ALIEN_PROJECTILE = 6,
const HULK_SLAP = 1 << 7; HULK_SLAP = 7,
const COMPILER_BOLT = 1 << 8; COMPILER_BOLT = 8,
const FUSION_BOLT = 1 << 9; FUSION_BOLT = 9,
const HUNTER_BOLT = 1 << 10; HUNTER_BOLT = 10,
const FIST = 1 << 11; FIST = 11,
const TELEPORTER = 1 << 12; TELEPORTER = 12,
const DEFENDER = 1 << 13; DEFENDER = 13,
const YETI_CLAWS = 1 << 14; YETI_CLAWS = 14,
const YETI_PROJECTILE = 1 << 15; YETI_PROJECTILE = 15,
const CRUSHING = 1 << 16; CRUSHING = 16,
const LAVA = 1 << 17; LAVA = 17,
const SUFFOCATION = 1 << 18; SUFFOCATION = 18,
const GOO = 1 << 19; GOO = 19,
const ENERGY_DRAIN = 1 << 20; ENERGY_DRAIN = 20,
const OXYGEN_DRAIN = 1 << 21; OXYGEN_DRAIN = 21,
const HUMMER_BOLT = 1 << 22; HUMMER_BOLT = 22,
const SHOTGUN_PROJECTILE = 1 << 23; SHOTGUN_PROJECTILE = 23,
} }
} }
bitflags! { c_bitfield! {
/// Flags for `Damage`. /// Flags for `Damage`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct DamageFlags: u16 { pub struct DamageFlags: u16 {
const ALIEN = 1; ALIEN = 0,
} }
} }

View File

@ -2,7 +2,6 @@
use super::pnts; use super::pnts;
use crate::{err::*, fixed::Unit}; use crate::{err::*, fixed::Unit};
use bitflags::bitflags;
/// Reads an `EPNT` chunk. /// Reads an `EPNT` chunk.
pub fn read(b: &[u8]) -> ResultS<(Endpoint, usize)> pub fn read(b: &[u8]) -> ResultS<(Endpoint, usize)>
@ -37,13 +36,13 @@ pub struct Endpoint {
pub support: u16, pub support: u16,
} }
bitflags! { c_bitfield! {
/// Flags for `Endpoint`. /// Flags for `Endpoint`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct EndpointFlags: u16 { pub struct EndpointFlags: u16 {
const SOLID = 1; SOLID = 0,
const SAME_HEIGHT = 1 << 1; SAME_HEIGHT = 1,
const TRANSPARENT = 1 << 2; TRANSPARENT = 2,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Effect` type. //! `Effect` type.
use crate::{bin::OptU16, err::*, fixed::Fixed}; use crate::{bin::OptU16, err::*, fixed::Fixed};
use bitflags::bitflags;
/// Reads a `FXpx` chunk. /// Reads a `FXpx` chunk.
pub fn read(b: &[u8]) -> ResultS<(Effect, usize)> pub fn read(b: &[u8]) -> ResultS<(Effect, usize)>
@ -32,15 +31,15 @@ pub struct Effect {
pub delay_snd: OptU16, pub delay_snd: OptU16,
} }
bitflags! { c_bitfield! {
/// Flags for an effect. /// Flags for an effect.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct EffectFlags: u16 { pub struct EffectFlags: u16 {
const END_ON_LOOP = 1; END_ON_LOOP = 0,
const END_ON_XFER_LOOP = 1 << 1; END_ON_XFER_LOOP = 1,
const SOUND_ONLY = 1 << 2; SOUND_ONLY = 2,
const MAKE_TWIN_VISIBLE = 1 << 3; MAKE_TWIN_VISIBLE = 3,
const MEDIA_EFFECT = 1 << 4; MEDIA_EFFECT = 4,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Line` type. //! `Line` type.
use crate::{bin::OptU16, err::*}; use crate::{bin::OptU16, err::*};
use bitflags::bitflags;
/// Reads a `LINS` chunk. /// Reads a `LINS` chunk.
pub fn read(b: &[u8]) -> ResultS<(Line, usize)> pub fn read(b: &[u8]) -> ResultS<(Line, usize)>
@ -34,16 +33,16 @@ pub struct Line {
pub poly_bk: OptU16, pub poly_bk: OptU16,
} }
bitflags! { c_bitfield! {
/// Flags for `Line`. /// Flags for `Line`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct LineFlags: u16 { pub struct LineFlags: u16 {
const TRANS_SIDE = 1 << 9; TRANS_SIDE = 9,
const ELEV_VAR = 1 << 10; ELEV_VAR = 10,
const ELEVATION = 1 << 11; ELEVATION = 11,
const LANDSCAPE = 1 << 12; LANDSCAPE = 12,
const TRANSPARENT = 1 << 13; TRANSPARENT = 13,
const SOLID = 1 << 14; SOLID = 14,
} }
} }

View File

@ -2,7 +2,6 @@
use super::{ltfn, TICKS_PER_SECOND}; use super::{ltfn, TICKS_PER_SECOND};
use crate::{err::*, fixed::Fixed}; use crate::{err::*, fixed::Fixed};
use bitflags::bitflags;
/// Reads a `LITE` chunk. /// Reads a `LITE` chunk.
pub fn read(b: &[u8]) -> ResultS<(Light, usize)> pub fn read(b: &[u8]) -> ResultS<(Light, usize)>
@ -86,13 +85,13 @@ pub struct Light {
pub tag: u16, pub tag: u16,
} }
bitflags! { c_bitfield! {
/// Flags for `Light`. /// Flags for `Light`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct LightFlags: u16 { pub struct LightFlags: u16 {
const INIT_ACTIVE = 1; INIT_ACTIVE = 0,
const SLAVE_VALUE = 1 << 1; SLAVE_VALUE = 1,
const STATELESS = 1 << 2; STATELESS = 2,
} }
} }

View File

@ -5,7 +5,6 @@ use crate::{bin::OptU16,
err::*, err::*,
fixed::{Angle, Fixed, Unit}, fixed::{Angle, Fixed, Unit},
xfer::TransferMode}; xfer::TransferMode};
use bitflags::bitflags;
/// Reads a `medi` chunk. /// Reads a `medi` chunk.
pub fn read(b: &[u8]) -> ResultS<(Media, usize)> pub fn read(b: &[u8]) -> ResultS<(Media, usize)>
@ -61,11 +60,11 @@ c_enum! {
} }
} }
bitflags! { c_bitfield! {
/// Flags for `Media`. /// Flags for `Media`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct MediaFlags: u8 { pub struct MediaFlags: u8 {
const OBSTRUCT = 1; OBSTRUCT = 0,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Info` type. //! `Info` type.
use crate::{err::*, text::*}; use crate::{err::*, text::*};
use bitflags::bitflags;
/// Reads a `Minf` chunk. /// Reads a `Minf` chunk.
pub fn read(b: &[u8]) -> ResultS<Info> pub fn read(b: &[u8]) -> ResultS<Info>
@ -81,51 +80,51 @@ pub struct Info {
pub level_name: String, pub level_name: String,
} }
bitflags! { c_bitfield! {
/// Static environment flags. /// Static environment flags.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct EnvironmentFlags: u16 { pub struct EnvironmentFlags: u16 {
const VACUUM = 1; VACUUM = 0,
const MAGNETIC = 1 << 1; MAGNETIC = 1,
const REBELLION = 1 << 2; REBELLION = 2,
const LOW_GRAV = 1 << 3; LOW_GRAV = 3,
const M1_GLUE = 1 << 4; M1_GLUE = 4,
const LAVA_FLOOR = 1 << 5; LAVA_FLOOR = 5,
const REBELLION2 = 1 << 6; REBELLION2 = 6,
const MUSIC = 1 << 7; MUSIC = 7,
const TERM_PAUSE = 1 << 8; TERM_PAUSE = 8,
const M1_MONSTER = 1 << 9; M1_MONSTER = 9,
const M1_WEPS = 1 << 10; M1_WEPS = 10,
} }
} }
bitflags! { c_bitfield! {
/// Static entry point flags. /// Static entry point flags.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct EntryFlags: u32 { pub struct EntryFlags: u32 {
const SOLO = 1; SOLO = 0,
const CO_OP = 1 << 1; CO_OP = 1,
const CARNAGE = 1 << 2; CARNAGE = 2,
const KTMWTB = 1 << 3; KTMWTB = 3,
const KOTH = 1 << 4; KOTH = 4,
const DEFENSE = 1 << 5; DEFENSE = 5,
const RUGBY = 1 << 6; RUGBY = 6,
const CTF = 1 << 7; CTF = 7,
} }
} }
bitflags! { c_bitfield! {
/// Static mission flags. /// Static mission flags.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct MissionFlags: u16 { pub struct MissionFlags: u16 {
const EXTERMINATION = 1; EXTERMINATION = 0,
const EXPLORATION = 1 << 1; EXPLORATION = 1,
const RETRIEVAL = 1 << 2; RETRIEVAL = 2,
const REPAIR = 1 << 3; REPAIR = 3,
const RESCUE = 1 << 4; RESCUE = 4,
const M1_EXPLORATION = 1 << 5; M1_EXPLORATION = 5,
const M1_RESCUE = 1 << 6; M1_RESCUE = 6,
const M1_REPAIR = 1 << 7; M1_REPAIR = 7,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Monster` type. //! `Monster` type.
use crate::{bin::OptU16, err::*, fixed::{Fixed, Unit}}; use crate::{bin::OptU16, err::*, fixed::{Fixed, Unit}};
use bitflags::bitflags;
use super::{attk, damg}; use super::{attk, damg};
@ -140,61 +139,61 @@ pub struct Monster {
pub atk_range: attk::Attack, pub atk_range: attk::Attack,
} }
bitflags! { c_bitfield! {
/// Flags for a monster. /// Flags for a monster.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct MonsterFlags: u32 { pub struct MonsterFlags: u32 {
const IGNORE_LOS = 1; IGNORE_LOS = 0,
const FLYING = 1 << 1; FLYING = 1,
const ALIEN = 1 << 2; ALIEN = 2,
const MAJOR = 1 << 3; MAJOR = 3,
const MINOR = 1 << 4; MINOR = 4,
const NO_OMIT = 1 << 5; NO_OMIT = 5,
const FLOATS = 1 << 6; FLOATS = 6,
const NO_ATTACK = 1 << 7; NO_ATTACK = 7,
const SNIPE = 1 << 8; SNIPE = 8,
const INVISIBLE = 1 << 9; INVISIBLE = 9,
const SUBTLY_INVISIBLE = 1 << 10; SUBTLY_INVISIBLE = 10,
const KAMIKAZE = 1 << 11; KAMIKAZE = 11,
const BERSERKER = 1 << 12; BERSERKER = 12,
const ENLARGED = 1 << 13; ENLARGED = 13,
const DELAYED_DEATH = 1 << 14; DELAYED_DEATH = 14,
const FIRE_SYMMETRICAL = 1 << 15; FIRE_SYMMETRICAL = 15,
const NUCLEAR_DEATH = 1 << 16; NUCLEAR_DEATH = 16,
const NO_FIRE_BACKWARDS = 1 << 17; NO_FIRE_BACKWARDS = 17,
const CAN_DIE_IN_FLAMES = 1 << 18; CAN_DIE_IN_FLAMES = 18,
const WAIT_FOR_GOOD_SHOT = 1 << 19; WAIT_FOR_GOOD_SHOT = 19,
const TINY = 1 << 20; TINY = 20,
const FAST_ATTACK = 1 << 21; FAST_ATTACK = 21,
const LIKES_WATER = 1 << 22; LIKES_WATER = 22,
const LIKES_SEWAGE = 1 << 23; LIKES_SEWAGE = 23,
const LIKES_LAVA = 1 << 24; LIKES_LAVA = 24,
const LIKES_GOO = 1 << 25; LIKES_GOO = 25,
const TELE_UNDER_MEDIA = 1 << 26; TELE_UNDER_MEDIA = 26,
const USE_RANDOM_WEAPON = 1 << 27; USE_RANDOM_WEAPON = 27,
} }
} }
bitflags! { c_bitfield! {
/// The composite type of a monster. /// The composite type of a monster.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct MonsterClass: u32 { pub struct MonsterClass: u32 {
const PLAYER = 1; PLAYER = 0,
const CIVILIAN = 1 << 1; CIVILIAN = 1,
const MADD = 1 << 2; MADD = 2,
const POSSESSED_HUMMER = 1 << 3; POSSESSED_HUMMER = 3,
const DEFENDER = 1 << 4; DEFENDER = 4,
const FIGHTER = 1 << 5; FIGHTER = 5,
const TROOPER = 1 << 6; TROOPER = 6,
const HUNTER = 1 << 7; HUNTER = 7,
const ENFORCER = 1 << 8; ENFORCER = 8,
const JUGGERNAUT = 1 << 9; JUGGERNAUT = 9,
const HUMMER = 1 << 10; HUMMER = 10,
const COMPILER = 1 << 11; COMPILER = 11,
const CYBORG = 1 << 12; CYBORG = 12,
const ASSIMILATED = 1 << 13; ASSIMILATED = 13,
const TICK = 1 << 14; TICK = 14,
const YETI = 1 << 15; YETI = 15,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Object` type. //! `Object` type.
use crate::{err::*, fixed::{Angle, Unit}}; use crate::{err::*, fixed::{Angle, Unit}};
use bitflags::bitflags;
/// Reads an `OBJS` chunk. /// Reads an `OBJS` chunk.
pub fn read(b: &[u8]) -> ResultS<(Object, usize)> pub fn read(b: &[u8]) -> ResultS<(Object, usize)>
@ -42,16 +41,16 @@ pub struct Object {
pub bias: u16, pub bias: u16,
} }
bitflags! { c_bitfield! {
/// Flags for `Object`. /// Flags for `Object`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct ObjectFlags: u16 { pub struct ObjectFlags: u16 {
const INVISIBLE = 1; INVISIBLE = 0,
const CEILING = 1 << 1; CEILING = 1,
const BLIND = 1 << 2; BLIND = 2,
const DEAF = 1 << 3; DEAF = 3,
const FLOATING = 1 << 4; FLOATING = 4,
const NET_ONLY = 1 << 5; NET_ONLY = 5,
} }
} }

View File

@ -1,7 +1,6 @@
//! `ObjectFreq` type. //! `ObjectFreq` type.
use crate::err::*; use crate::err::*;
use bitflags::bitflags;
/// Reads a `plac` chunk. /// Reads a `plac` chunk.
pub fn read(b: &[u8]) -> ResultS<(ObjectFreq, usize)> pub fn read(b: &[u8]) -> ResultS<(ObjectFreq, usize)>
@ -32,15 +31,15 @@ pub struct ObjectFreq {
pub chance: u16, pub chance: u16,
} }
bitflags! { c_bitfield! {
/// Flags for `ObjectFreq`. /// Flags for `ObjectFreq`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct ObjectFreqFlags: u16 { pub struct ObjectFreqFlags: u16 {
const RANDOM_LOCATION = 1; RANDOM_LOCATION = 0,
const _3 = 1 << 3; _3 = 3,
const _4 = 1 << 4; _4 = 4,
const _5 = 1 << 5; _5 = 5,
const _6 = 1 << 6; _6 = 6,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Platform` type. //! `Platform` type.
use crate::{err::*, fixed::Unit}; use crate::{err::*, fixed::Unit};
use bitflags::bitflags;
/// Reads a `plat` chunk. /// Reads a `plat` chunk.
pub fn read(b: &[u8]) -> ResultS<(Platform, usize)> pub fn read(b: &[u8]) -> ResultS<(Platform, usize)>
@ -36,37 +35,37 @@ pub struct Platform {
pub tag: u16, pub tag: u16,
} }
bitflags! { c_bitfield! {
/// Flags for `Platform`. /// Flags for `Platform`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct PlatformFlags: u32 { pub struct PlatformFlags: u32 {
const INIT_ACTIVE = 1; INIT_ACTIVE = 0,
const INIT_EXTENDED = 1 << 1; INIT_EXTENDED = 1,
const STOP_AT_EACH_LEVEL = 1 << 2; STOP_AT_EACH_LEVEL = 2,
const STOP_AT_INIT_LEVEL = 1 << 3; STOP_AT_INIT_LEVEL = 3,
const START_ADJ_ON_STOP = 1 << 4; START_ADJ_ON_STOP = 4,
const EXTENDS_FLOOR_TO_CEIL = 1 << 5; EXTENDS_FLOOR_TO_CEIL = 5,
const COMES_FROM_FLOOR = 1 << 6; COMES_FROM_FLOOR = 6,
const COMES_FROM_CEIL = 1 << 7; COMES_FROM_CEIL = 7,
const CAUSES_DAMAGE = 1 << 8; CAUSES_DAMAGE = 8,
const NO_ACTIVATE_PARENT = 1 << 9; NO_ACTIVATE_PARENT = 9,
const ACTIVATES_ONCE = 1 << 10; ACTIVATES_ONCE = 10,
const ACTIVATES_LIGHT = 1 << 11; ACTIVATES_LIGHT = 11,
const DEACTIVATES_LIGHT = 1 << 12; DEACTIVATES_LIGHT = 12,
const PLAYER_CONTROLS = 1 << 13; PLAYER_CONTROLS = 13,
const MONSTER_CONTROLS = 1 << 14; MONSTER_CONTROLS = 14,
const REVERSE_ON_OBSTRUCT = 1 << 15; REVERSE_ON_OBSTRUCT = 15,
const NO_EXT_DEACTIVATION = 1 << 16; NO_EXT_DEACTIVATION = 16,
const USE_POLYGON_HEIGHTS = 1 << 17; USE_POLYGON_HEIGHTS = 17,
const DELAYED_ACTIVATION = 1 << 18; DELAYED_ACTIVATION = 18,
const START_ADJ_ON_START = 1 << 19; START_ADJ_ON_START = 19,
const STOP_ADJ_ON_START = 1 << 20; STOP_ADJ_ON_START = 20,
const STOP_ADJ_ON_STOP = 1 << 21; STOP_ADJ_ON_STOP = 21,
const SLOW = 1 << 22; SLOW = 22,
const START_AT_EACH_LEVEL = 1 << 23; START_AT_EACH_LEVEL = 23,
const LOCKED = 1 << 24; LOCKED = 24,
const SECRET = 1 << 25; SECRET = 25,
const DOOR = 1 << 26; DOOR = 26,
} }
} }

View File

@ -2,7 +2,6 @@
use super::pnts; use super::pnts;
use crate::{bin::OptU16, err::*, fixed::Unit, xfer::TransferMode}; use crate::{bin::OptU16, err::*, fixed::Unit, xfer::TransferMode};
use bitflags::bitflags;
/// Reads a polygon for either M1 or M2. /// Reads a polygon for either M1 or M2.
pub fn read_poly_inter(b: &[u8]) -> ResultS<Polygon> pub fn read_poly_inter(b: &[u8]) -> ResultS<Polygon>
@ -180,11 +179,11 @@ pub enum PolygonType {
GlueSuper, GlueSuper,
} }
bitflags! { c_bitfield! {
/// Flags for `Polygon`. /// Flags for `Polygon`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct PolygonFlags: u16 { pub struct PolygonFlags: u16 {
const DETACHED = 1 << 14; DETACHED = 14,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Projectile` type. //! `Projectile` type.
use crate::{bin::OptU16, err::*, fixed::{Fixed, Unit}}; use crate::{bin::OptU16, err::*, fixed::{Fixed, Unit}};
use bitflags::bitflags;
use super::damg; use super::damg;
@ -58,32 +57,32 @@ pub struct Projectile {
pub snd_bounce: OptU16, pub snd_bounce: OptU16,
} }
bitflags! { c_bitfield! {
/// Flags for a projectile. /// Flags for a projectile.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct ProjectileFlags: u32 { pub struct ProjectileFlags: u32 {
const GUIDED = 1; GUIDED = 0,
const STOP_ON_LOOP = 1 << 1; STOP_ON_LOOP = 1,
const PERSISTENT = 1 << 2; PERSISTENT = 2,
const ALIEN = 1 << 3; ALIEN = 3,
const GRAVITY = 1 << 4; GRAVITY = 4,
const NO_HORZ_ERROR = 1 << 5; NO_HORZ_ERROR = 5,
const NO_VERT_ERROR = 1 << 6; NO_VERT_ERROR = 6,
const TOGGLE_PANELS = 1 << 7; TOGGLE_PANELS = 7,
const POS_VERT_ERROR = 1 << 8; POS_VERT_ERROR = 8,
const MELEE = 1 << 9; MELEE = 9,
const RIPPER = 1 << 10; RIPPER = 10,
const PASS_TRANS_RANDOM = 1 << 11; PASS_TRANS_RANDOM = 11,
const PASS_TRANS_MORE = 1 << 12; PASS_TRANS_MORE = 12,
const DOUBLE_GRAVITY = 1 << 13; DOUBLE_GRAVITY = 13,
const REBOUND_FLOOR = 1 << 14; REBOUND_FLOOR = 14,
const THROUGH_MEDIA = 1 << 15; THROUGH_MEDIA = 15,
const BECOME_ITEM = 1 << 16; BECOME_ITEM = 16,
const BLOODY = 1 << 17; BLOODY = 17,
const WANDER_HORZ = 1 << 18; WANDER_HORZ = 18,
const WANDER_VERT = 1 << 19; WANDER_VERT = 19,
const USE_LOW_GRAV = 1 << 20; USE_LOW_GRAV = 20,
const PASS_MEDIA = 1 << 21; PASS_MEDIA = 21,
} }
} }

View File

@ -2,7 +2,6 @@
use super::stex; use super::stex;
use crate::{bin::OptU16, err::*, fixed::Fixed, xfer::TransferMode}; use crate::{bin::OptU16, err::*, fixed::Fixed, xfer::TransferMode};
use bitflags::bitflags;
/// Reads a `SIDS` chunk. /// Reads a `SIDS` chunk.
pub fn read(b: &[u8]) -> ResultS<(Side, usize)> pub fn read(b: &[u8]) -> ResultS<(Side, usize)>
@ -55,18 +54,18 @@ pub struct Side {
pub shade: Fixed, pub shade: Fixed,
} }
bitflags! { c_bitfield! {
/// Flags for `Side`. /// Flags for `Side`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct SideFlags: u8 { pub struct SideFlags: u8 {
const STATUS = 1; STATUS = 0,
const PANEL = 1 << 1; PANEL = 1,
const REPAIR = 1 << 2; REPAIR = 2,
const ITEM_USE = 1 << 3; ITEM_USE = 3,
const LIGHTED = 1 << 4; LIGHTED = 4,
const CAN_DESTROY = 1 << 5; CAN_DESTROY = 5,
const HIT_ONLY = 1 << 6; HIT_ONLY = 6,
const ITEM_OPT = 1 << 7; ITEM_OPT = 7,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Group` type. //! `Group` type.
use crate::err::*; use crate::err::*;
use bitflags::bitflags;
/// Reads an `InterGroup`. /// Reads an `InterGroup`.
pub fn read(b: &[u8]) -> ResultS<(InterGroup, usize)> pub fn read(b: &[u8]) -> ResultS<(InterGroup, usize)>
@ -89,14 +88,14 @@ pub enum GroupType {
Tag(u16), Tag(u16),
} }
bitflags! { c_bitfield! {
/// Flags for `Group`. /// Flags for `Group`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct GroupFlags: u16 { pub struct GroupFlags: u16 {
/// Draws the picture on the right. /// Draws the picture on the right.
const DRAW_ON_RIGHT = 1; DRAW_ON_RIGHT = 0,
/// Draws the picture in the center. /// Draws the picture in the center.
const DRAW_CENTER = 1 << 1; DRAW_CENTER = 1,
} }
} }

View File

@ -1,7 +1,6 @@
//! `Weapon` type. //! `Weapon` type.
use crate::{bin::OptU16, err::*, fixed::Fixed}; use crate::{bin::OptU16, err::*, fixed::Fixed};
use bitflags::bitflags;
use super::trig; use super::trig;
@ -76,21 +75,21 @@ pub struct Weapon {
pub wid_idle: Fixed, pub wid_idle: Fixed,
} }
bitflags! { c_bitfield! {
/// Flags for a weapon. /// Flags for a weapon.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct WeaponFlags: u16 { pub struct WeaponFlags: u16 {
const AUTOMATIC = 1; AUTOMATIC = 0,
const REMOVE_AFTER_USE = 1 << 1; REMOVE_AFTER_USE = 1,
const INSTANT_CASING = 1 << 2; INSTANT_CASING = 2,
const OVERLOADS = 1 << 3; OVERLOADS = 3,
const RANDOM_AMMO = 1 << 4; RANDOM_AMMO = 4,
const TEMPORARY_POWER = 1 << 5; TEMPORARY_POWER = 5,
const RELOAD_ONE_HAND = 1 << 6; RELOAD_ONE_HAND = 6,
const FIRE_OUT_OF_PHASE = 1 << 7; FIRE_OUT_OF_PHASE = 7,
const FIRE_UNDER_MEDIA = 1 << 8; FIRE_UNDER_MEDIA = 8,
const TRIGGER_SAME_AMMO = 1 << 9; TRIGGER_SAME_AMMO = 9,
const SECONDARY_FLIP = 1 << 10; SECONDARY_FLIP = 10,
} }
} }

View File

@ -2,7 +2,6 @@
use crate::{err::*, image::Image}; use crate::{err::*, image::Image};
use super::clut; use super::clut;
use bitflags::bitflags;
/// Reads a `Bitmap`. /// Reads a `Bitmap`.
pub fn read(b: &[u8]) -> ResultS<Bitmap> pub fn read(b: &[u8]) -> ResultS<Bitmap>
@ -130,10 +129,10 @@ pub struct ImageShp<'a, 'b> {
clut: &'b [clut::ColorShp], clut: &'b [clut::ColorShp],
} }
bitflags! { c_bitfield! {
struct BmpFlags: u16 { pub struct BmpFlags: u16 {
const TRANSPARENT = 1 << 14; TRANSPARENT = 14,
const COLUMN_MAJOR = 1 << 15; COLUMN_MAJOR = 15,
} }
} }

View File

@ -1,7 +1,6 @@
//! Shapes file frame type. //! Shapes file frame type.
use crate::{err::*, fixed::*}; use crate::{err::*, fixed::*};
use bitflags::bitflags;
/// Reads a `Frame`. /// Reads a `Frame`.
pub fn read(b: &[u8]) -> ResultS<Frame> pub fn read(b: &[u8]) -> ResultS<Frame>
@ -55,16 +54,16 @@ pub struct Frame {
pub wrl_y: Unit, pub wrl_y: Unit,
} }
bitflags! { c_bitfield! {
/// Flags for `Frame`. /// Flags for `Frame`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct FrameFlags: u16 { pub struct FrameFlags: u16 {
/// The player's torso will obscure the player's legs. /// The player's torso will obscure the player's legs.
const OBSCURE = 1 << 13; OBSCURE = 13,
/// The bitmap will be flipped on the vertical axis. /// The bitmap will be flipped on the vertical axis.
const FLIP_Y = 1 << 14; FLIP_Y = 14,
/// The bitmap will be flipped on the horizontal axis. /// The bitmap will be flipped on the horizontal axis.
const FLIP_X = 1 << 15; FLIP_X = 15,
} }
} }

View File

@ -1,7 +1,6 @@
//! Sounds format definition type. //! Sounds format definition type.
use crate::{bin::{u32b, usize_from_u32}, err::*, fixed::*, sound::Sound16}; use crate::{bin::{u32b, usize_from_u32}, err::*, fixed::*, sound::Sound16};
use bitflags::bitflags;
/// Reads a sound definition. /// Reads a sound definition.
pub fn read(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>> pub fn read(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
@ -63,24 +62,24 @@ pub struct SoundDef {
pub sounds: Vec<Sound16>, pub sounds: Vec<Sound16>,
} }
bitflags! { c_bitfield! {
/// Flags for `SoundDef`. /// Flags for `SoundDef`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct SoundFlags: u16 { pub struct SoundFlags: u16 {
/// The sound will not restart when trying to play over itself. /// The sound will not restart when trying to play over itself.
const NO_RESTART = 1; NO_RESTART = 0,
/// The sound will not switch channels when trying to play over itself. /// The sound will not switch channels when trying to play over itself.
const NO_CHANNEL_SWITCH = 1 << 1; NO_CHANNEL_SWITCH = 1,
/// The pitch variance will be halved. /// The pitch variance will be halved.
const LESS_PITCH_CHANGE = 1 << 2; LESS_PITCH_CHANGE = 2,
/// The pitch variance will be nullified. /// The pitch variance will be nullified.
const NO_PITCH_CHANGE = 1 << 3; NO_PITCH_CHANGE = 3,
/// The sound will play even when completely obstructed by walls. /// The sound will play even when completely obstructed by walls.
const NO_OBSTRUCTION = 1 << 4; NO_OBSTRUCTION = 4,
/// The sound will play even when completely obstructed by media. /// The sound will play even when completely obstructed by media.
const NO_MEDIA_OBSTRUCT = 1 << 5; NO_MEDIA_OBSTRUCT = 5,
/// The sound will have special stereo effects. /// The sound will have special stereo effects.
const AMBIENT = 1 << 6; AMBIENT = 6,
} }
} }

View File

@ -12,9 +12,9 @@ MapModel::~MapModel()
dbgPrintFunc(); dbgPrintFunc();
} }
ProjectModel::Type MapModel::type() const ProjectModelType MapModel::type() const
{ {
return ProjectModel::Map; return ProjectModelType::Map;
} }
bool MapModel::isDirty() const bool MapModel::isDirty() const

View File

@ -22,7 +22,7 @@ Menu::~Menu()
void Menu::mapNew() void Menu::mapNew()
{ {
QScopedPointer proj{new Project(new MapModel)}; QScopedPointer proj{new Project(ProjectModelType::Map)};
addProject(proj.take()); addProject(proj.take());
} }
@ -40,7 +40,7 @@ void Menu::mapOpen()
"All files (*)")); "All files (*)"));
if(!fname.isEmpty()) { if(!fname.isEmpty()) {
QScopedPointer proj{new Project(new MapModel)}; QScopedPointer proj{new Project(ProjectModelType::Map)};
if(proj->getModel()->open(fname)) { if(proj->getModel()->open(fname)) {
addProject(proj.take()); addProject(proj.take());
@ -98,7 +98,7 @@ void Menu::openMapProperties()
{ {
auto proj = activeProject(); auto proj = activeProject();
if(proj && proj->getModel()->type() == ProjectModel::Map) { if(proj && proj->getModel()->type() == ProjectModelType::Map) {
MapProps props{proj->getMapModel(), proj}; MapProps props{proj->getMapModel(), proj};
props.exec(); props.exec();
} }
@ -111,8 +111,6 @@ void Menu::updateActions()
actionClose->setEnabled(active); actionClose->setEnabled(active);
actionMapProps->setEnabled(active); actionMapProps->setEnabled(active);
dbgPrintFunc();
} }
void Menu::closeEvent(QCloseEvent *event) void Menu::closeEvent(QCloseEvent *event)

View File

@ -1,8 +1,9 @@
#include "tycho.h" #include "tycho.h"
Project::Project(ProjectModel *_model, QWidget *parent) : Project::Project(ProjectModelType type) :
QMdiSubWindow(parent), QMdiSubWindow(),
model(_model) model(nullptr),
view(nullptr)
{ {
auto widget = new QWidget(this); auto widget = new QWidget(this);
@ -11,7 +12,15 @@ Project::Project(ProjectModel *_model, QWidget *parent) :
setWidget(widget); setWidget(widget);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
switch(type) {
case ProjectModelType::Map:
model.reset(new MapModel(this));
view = new MapView(getMapModel(), this);
break;
}
listView->setModel(dynamic_cast<QAbstractItemModel *>(model.get())); listView->setModel(dynamic_cast<QAbstractItemModel *>(model.get()));
verticalLayout->insertWidget(0, view);
dbgPrintFunc(); dbgPrintFunc();
} }

View File

@ -31,17 +31,17 @@ class MapView;
class Menu; class Menu;
class Project; class Project;
enum class ProjectModelType
{
Map,
};
class ProjectModel class ProjectModel
{ {
public: public:
enum Type
{
Map,
};
virtual ~ProjectModel() {} virtual ~ProjectModel() {}
virtual Type type() const = 0; virtual ProjectModelType type() const = 0;
virtual bool isDirty() const = 0; virtual bool isDirty() const = 0;
virtual bool open(QString const &path) = 0; virtual bool open(QString const &path) = 0;
@ -57,7 +57,7 @@ public:
explicit MapModel(QObject *parent = nullptr); explicit MapModel(QObject *parent = nullptr);
~MapModel() override; ~MapModel() override;
ProjectModel::Type type() const override; ProjectModelType type() const override;
bool isDirty() const override; bool isDirty() const override;
bool open(QString const &path) override; bool open(QString const &path) override;
@ -126,18 +126,18 @@ class Project final : public QMdiSubWindow, private Ui::Project
Q_OBJECT Q_OBJECT
public: public:
explicit Project(ProjectModel *model, QWidget *parent = nullptr); explicit Project(ProjectModelType type);
~Project(); ~Project();
std::shared_ptr<ProjectModel> getModel(); std::shared_ptr<ProjectModel> getModel();
std::shared_ptr<MapModel> getMapModel(); std::shared_ptr<MapModel> getMapModel();
std::shared_ptr<QAbstractItemModel> getAbstractModel();
protected: protected:
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
private: private:
std::shared_ptr<ProjectModel> model; std::shared_ptr<ProjectModel> model;
QWidget *view;
}; };
template<typename... VA> template<typename... VA>

View File

@ -14,9 +14,6 @@
<string>Project</string> <string>Project</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true"/>
</item>
<item> <item>
<widget class="QListView" name="listView"> <widget class="QListView" name="listView">
<property name="frameShape"> <property name="frameShape">