use new style flag implementation

This commit is contained in:
Andelf
2014-04-26 22:41:52 +08:00
parent 6281272b5d
commit a7ec060657
3 changed files with 125 additions and 86 deletions
+4 -4
View File
@@ -5,7 +5,6 @@ extern crate sdl2;
extern crate sdl2_mixer;
use std::os;
use std::default::Default;
use mix = sdl2_mixer;
@@ -22,9 +21,10 @@ fn main() {
fn dump_info(filename: &Path) -> Result<(), ~str> {
println!("linked version: {}", mix::get_linked_version());
sdl2::init([sdl2::InitAudio, sdl2::InitTimer]);
println!("inited => {}", mix::init(Default::default()));
sdl2::init(sdl2::InitAudio | sdl2::InitTimer);
println!("inited => {}", mix::init(sdl2_mixer::InitMp3 | sdl2_mixer::InitFlac |
sdl2_mixer::InitMod | sdl2_mixer::InitFluidSynth |
sdl2_mixer::InitModPlug | sdl2_mixer::InitOgg).get());
// TODO: 0x8010 is SDL_audio flag
try!(mix::open_audio(mix::DEFAULT_FREQUENCY, 0x8010u16, 2, 1024));
mix::allocate_channels(0);
+109
View File
@@ -0,0 +1,109 @@
// Loosely based on zlib-licensed code from RustAllegro
// https://github.com/SiegeLord/RustAllegro
//
// Implements efficient, type-safe flags with support for bitwise operators.
//
// Usage:
//
// flag_type!(FlagTypeName {
// FlagName1 = FlagValue1,
// FlagName2 = FlagValue2,
// ...
// FlagNameN = FlagValueN
// })
//
// fn foo(flag: FlagTypeName) {
// let raw = (flag | FlagNameN).get();
// bar(raw);
// }
#![macro_escape]
macro_rules! flag_type(
($typename:ident : $supertype:ident { $($name:ident = $value:expr),* }) => {
pub struct $typename {
bits: $supertype
}
impl $typename {
#[inline]
pub fn new(bits: $supertype) -> $typename {
$typename { bits: bits }
}
#[inline]
pub fn get(self) -> $supertype {
self.bits
}
}
impl ::std::default::Default for $typename {
fn default() -> $typename {
$typename::new(0)
}
}
impl ::std::cmp::Eq for $typename {
fn eq(&self, other: &$typename) -> bool {
self.bits == other.bits
}
}
impl ::std::cmp::TotalEq for $typename {}
impl ::std::cmp::Ord for $typename {
fn lt(&self, other: &$typename) -> bool {
self.bits < other.bits
}
}
impl ::std::cmp::TotalOrd for $typename {
fn cmp(&self, other: &$typename) -> Ordering {
self.bits.cmp(&other.bits)
}
}
impl ::std::ops::Not<$typename> for $typename {
fn not(&self) -> $typename {
$typename { bits: !self.bits }
}
}
impl ::std::ops::BitAnd<$typename, $typename> for $typename {
fn bitand(&self, rhs: &$typename) -> $typename {
$typename { bits: self.bits & rhs.bits }
}
}
impl ::std::ops::BitOr<$typename, $typename> for $typename {
fn bitor(&self, rhs: &$typename) -> $typename {
$typename { bits: self.bits | rhs.bits }
}
}
impl ::std::ops::BitXor<$typename, $typename> for $typename {
fn bitxor(&self, rhs: &$typename) -> $typename {
$typename { bits: self.bits ^ rhs.bits }
}
}
impl ::std::ops::Shl<$supertype, $typename> for $typename {
fn shl(&self, rhs: &$supertype) -> $typename {
$typename { bits: self.bits << *rhs }
}
}
impl ::std::ops::Shr<$supertype, $typename> for $typename {
fn shr(&self, rhs: &$supertype) -> $typename {
$typename { bits: self.bits >> *rhs }
}
}
$(
pub static $name: $typename = $typename { bits: $value as $supertype };
)+
};
($typename:ident { $($name:ident = $value:expr),* }) => {
flag_type!($typename : u32 { $($name = $value),* })
}
)
+12 -82
View File
@@ -8,7 +8,7 @@ A binding for SDL2_mixer.
#![comment = "SDL2_mixer bindings and wrappers"]
#![license = "MIT"]
#![feature(globs)]
#![feature(globs, macro_rules)]
extern crate libc;
extern crate sdl2;
@@ -18,8 +18,6 @@ use std::ptr;
use std::cast;
use std::raw;
use std::c_str::CString;
use std::ops;
use std::num;
use libc::{c_int, uint16_t, c_double};
use sdl2::get_error;
use sdl2::rwops::RWops;
@@ -47,6 +45,7 @@ mod others {
#[allow(non_camel_case_types, dead_code)]
mod ffi;
mod flag;
// This comes from SDL_audio.h
#[allow(non_camel_case_types)]
@@ -111,89 +110,20 @@ pub fn get_linked_version() -> Version {
}
}
#[allow(visible_private_types)]
#[deriving(Clone, Eq, Hash, Show)]
pub enum InitFlag {
InitFlac,
InitMod,
InitModPlug,
InitMp3,
InitOgg,
InitFluidSynth,
InitRaw(ffi::MIX_InitFlags),
}
impl InitFlag {
#[inline]
fn to_ll(self) -> ffi::MIX_InitFlags {
match self {
InitFlac => ffi::MIX_INIT_FLAC,
InitMod => ffi::MIX_INIT_MOD,
InitModPlug => ffi::MIX_INIT_MODPLUG,
InitMp3 => ffi::MIX_INIT_MP3,
InitOgg => ffi::MIX_INIT_OGG,
InitFluidSynth => ffi::MIX_INIT_FLUIDSYNTH,
InitRaw(val) => val,
}
}
fn from_ll(cflag: ffi::MIX_InitFlags) -> InitFlag {
match cflag {
ffi::MIX_INIT_FLAC => InitFlac,
ffi::MIX_INIT_MOD => InitMod,
ffi::MIX_INIT_MODPLUG => InitModPlug,
ffi::MIX_INIT_MP3 => InitMp3,
ffi::MIX_INIT_OGG => InitOgg,
ffi::MIX_INIT_FLUIDSYNTH => InitFluidSynth,
val => InitRaw(val),
}
}
pub fn mask(self, flag: InitFlag) -> bool {
self.to_ll() & flag.to_ll() == flag.to_ll()
}
}
impl ops::BitOr<InitFlag, InitFlag> for InitFlag {
fn bitor(&self, rhs: &InitFlag) -> InitFlag {
InitFlag::from_ll(self.to_ll() | rhs.to_ll())
}
}
impl default::Default for InitFlag {
fn default() -> InitFlag {
InitFlag::from_ll((ffi::MIX_INIT_FLAC | ffi::MIX_INIT_MOD | ffi::MIX_INIT_MODPLUG |
ffi::MIX_INIT_MP3 | ffi::MIX_INIT_OGG | ffi::MIX_INIT_FLUIDSYNTH))
}
}
impl num::FromPrimitive for InitFlag {
#[inline]
fn from_i64(n: i64) -> Option<InitFlag> {
Some(InitFlag::from_ll(n as ffi::MIX_InitFlags))
}
#[inline]
fn from_u64(n: u64) -> Option<InitFlag> {
Some(InitFlag::from_ll(n as ffi::MIX_InitFlags))
}
}
impl num::ToPrimitive for InitFlag {
#[inline]
fn to_i64(&self) -> Option<i64> {
Some(self.to_ll() as i64)
}
#[inline]
fn to_u64(&self) -> Option<u64> {
Some(self.to_ll() as u64)
}
}
flag_type!(InitFlag : c_int {
InitFlac = ffi::MIX_INIT_FLAC,
InitMod = ffi::MIX_INIT_MOD,
InitModPlug = ffi::MIX_INIT_MODPLUG,
InitMp3 = ffi::MIX_INIT_MP3,
InitOgg = ffi::MIX_INIT_OGG,
InitFluidSynth = ffi::MIX_INIT_FLUIDSYNTH
})
/// Loads dynamic libraries and prepares them for use. Flags should be
/// one or more flags from InitFlag.
pub fn init(flags: InitFlag) -> InitFlag {
let ret = unsafe { ffi::Mix_Init(flags.to_ll() as c_int) };
InitFlag::from_ll(ret as ffi::MIX_InitFlags)
let ret = unsafe { ffi::Mix_Init(flags.get()) };
InitFlag::new(ret)
}
/// Cleans up all dynamically loaded library handles, freeing memory.