<commit_before>use raw::*;
use libc::{c_char, c_int};
pub use error::Error;

// https://doc.rust-lang.org/book/error-handling.html#the-result-type-alias-idiom
pub type Result<T> = ::std::result::Result<T, Error>;

/// This struct holds the current context `ctx`
///
/// This logic is derived from that one libmodbus uses.
#[derive(Debug, Eq, PartialEq)]
pub struct Modbus { ctx: *mut modbus_t }

impl Modbus {
    /// Creates a new modbus context with the RTU backend
    ///
    /// # Attributes
    /// * `device`         - Device string e.g. "/dev/ttyUSB0"
    /// * `baud`           - Baud rate
    /// * `parity`         - Parity
    /// * `data_bit`       - Number of data bits
    /// * `stop_bit`       - Number of stop bits
    ///
    /// # Examples
    ///
    /// ```
    /// use libmodbus_rs::modbus::Modbus;
    ///
    /// let modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// ```
    pub fn new_rtu(device: &str, baud: i32, parity: char, data_bit: i32, stop_bit: i32) -> Self {
        Modbus {
            ctx: {
                unsafe {
                    ::raw::modbus_new_rtu(::std::ffi::CString::new(device).unwrap().as_ptr(), baud, parity as c_char, data_bit, stop_bit)
                }
            }
        }
    }

    /// Define the slave ID of the remote device to talk in master mode or set the
    /// internal slave ID in slave mode
    ///
    /// # Attributes
    /// * `slave_id`    - New modbus slave id (valid range: `>= 0 && <= 247`), `0` is broadcast address
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::InvalidSlaveID` is returned
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus, Error};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// assert_eq!(modbus.set_slave(10), Ok(0));
    /// assert_eq!(modbus.set_slave(255), Err(Error::InvalidSlaveID));
    /// ```
    pub fn set_slave(&mut self, slave_id: i32) -> Result<i32> {
        unsafe {
            match ::raw::modbus_set_slave(self.ctx, slave_id) {
                -1 => Err(Error::InvalidSlaveID),
                _ => Ok(0),
            }
        }
    }

    /// Set debug flag of the context
    ///
    /// # Attributes
    /// * `flag`    - boolean `true` or `false`
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::GenericError` is returned
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// assert_eq!(modbus.set_debug(true), Ok(0));
    /// ```
    pub fn set_debug(&mut self, flag: bool) -> Result<i32> {
        unsafe {
            match ::raw::modbus_set_debug(self.ctx, flag as c_int) {
                -1 => Err(Error::InvalidDebug),
                _ => Ok(0),
            }
        }
    }

    /// Set the serial mode
    ///
    /// # Attributes
    /// * `mode`    - serial mode
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::GenericError` is returned
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// ```
    pub fn rtu_set_serial_mode(&mut self, mode: i32) -> Result<i32> {
        unsafe {
            match ::raw::modbus_rtu_set_serial_mode(self.ctx, mode) {
                -1 => Err(Error::InvalidRTUSerialMode),
                _ => Ok(0),
            }
        }
    }

    /// Set the RTS mode in RTU
    ///
    /// # Attributes
    /// * `mode`    - serial mode
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::GenericError` is returned
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// modbus.set_slave(1);
    /// assert_eq!(modbus.rtu_set_rts(libmodbus_rs::MODBUS_RTU_RTS_DOWN), Ok(0));
    /// ```
    pub fn rtu_set_rts(&mut self, mode: i32) -> Result<i32> {
        unsafe {
            match ::raw::modbus_rtu_set_rts(self.ctx, mode) {
                -1 => Err(Error::InvalidRTURTS),
                _ => Ok(0),
            }
        }
    }

    /// Establish a Modbus connection
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::GenericError` is returned
    ///
    /// ```no_run
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// modbus.set_slave(1);
    /// assert_eq!(modbus.connect(), Ok(0));
    /// ```
    pub fn connect(&self) -> Result<i32> {
        unsafe {
            match ::raw::modbus_connect(self.ctx) {
                -1 => Err(Error::ConnectionError),
                _ => Ok(0),
            }
        }
    }

    /// modbus_close - close a Modbus connection
    ///
    /// The `modbus_close()` function shall close the connection established with the backend set in the context.
    ///
    /// # Examples
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// modbus.set_slave(1);
    /// match modbus.connect() {
    ///     Err(_) => { modbus.free(); }
    ///     Ok(_) => {
    ///         let _ = modbus.read_registers(0, 1);
    ///     }
    /// }
    /// modbus.close();
    /// modbus.free();
    /// ```
    pub fn close(&self) {
        unsafe {
            ::raw::modbus_close(self.ctx);
        }
    }

    /// Free a libmodbus context
    ///
    /// # Examples
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// modbus.set_slave(1);
    /// modbus.free();
    /// ```
    pub fn free(&self) {
        unsafe {
            ::raw::modbus_free(self.ctx);
        }
    }

    /// Read many registers
    ///
    /// # Attributes
    /// * `address`    - Start address from which the read should start
    /// * `num_reg`    - Number of holding registers to read from `address` of the remote device
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// let _ = modbus.set_slave(46);
    /// let _ = modbus.rtu_set_rts(libmodbus_rs::MODBUS_RTU_RTS_DOWN);
    /// let mut tab_reg: Vec<u16> = modbus.read_registers(0, 19);
    /// modbus.free();
    /// ```
    pub fn read_registers(&self, address: i32, num_reg: i32) -> Result<Vec<u16>> {
        let mut tab_reg = vec![0u16; num_reg as usize];
        unsafe {
            match ::raw::modbus_read_registers(self.ctx, address, num_reg, tab_reg.as_mut_ptr()) {
                -1 => { Err(Error::ConnectionError)}
                _ => { Ok(tab_reg) }
            }
        }
    }

    /// Read many registers
    ///
    /// # Attributes
    /// * `address`    - Start address from which the read should start
    /// * `num_reg`    - Number of holding registers to read from `address` of the remote device
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// let _ = modbus.set_slave(46);
    /// let _ = modbus.rtu_set_rts(libmodbus_rs::MODBUS_RTU_RTS_DOWN);
    /// let mut tab_reg: Vec<u16> = modbus.read_input_registers(0, 19);
    /// modbus.free();
    /// ```
    pub fn read_input_registers(&self, address: i32, num_reg: i32) -> Vec<u16> {
        let mut tab_reg = vec![0u16; num_reg as usize];
        unsafe {
            ::raw::modbus_read_input_registers(self.ctx, address, num_reg, tab_reg.as_mut_ptr());
        }
        tab_reg
    }

    pub fn write_bit(&self, address: i32, status: bool) -> i32 {
        unsafe {
            ::raw::modbus_write_bit(self.ctx, address, status as i32)
        }
    }

}

#[cfg(test)]
mod tests {
    use super::Modbus;

    #[test]
    fn crate_modbus() {
        let modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
        assert_eq!(modbus, modbus);
    }

}
<commit_msg>Fix tests<commit_after>use raw::*;
use libc::{c_char, c_int};
pub use error::Error;

// https://doc.rust-lang.org/book/error-handling.html#the-result-type-alias-idiom
pub type Result<T> = ::std::result::Result<T, Error>;

/// This struct holds the current context `ctx`
///
/// This logic is derived from that one libmodbus uses.
#[derive(Debug, Eq, PartialEq)]
pub struct Modbus { ctx: *mut modbus_t }

impl Modbus {
    /// Creates a new modbus context with the RTU backend
    ///
    /// # Attributes
    /// * `device`         - Device string e.g. "/dev/ttyUSB0"
    /// * `baud`           - Baud rate
    /// * `parity`         - Parity
    /// * `data_bit`       - Number of data bits
    /// * `stop_bit`       - Number of stop bits
    ///
    /// # Examples
    ///
    /// ```
    /// use libmodbus_rs::modbus::Modbus;
    ///
    /// let modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// ```
    pub fn new_rtu(device: &str, baud: i32, parity: char, data_bit: i32, stop_bit: i32) -> Self {
        Modbus {
            ctx: {
                unsafe {
                    ::raw::modbus_new_rtu(::std::ffi::CString::new(device).unwrap().as_ptr(), baud, parity as c_char, data_bit, stop_bit)
                }
            }
        }
    }

    /// Define the slave ID of the remote device to talk in master mode or set the
    /// internal slave ID in slave mode
    ///
    /// # Attributes
    /// * `slave_id`    - New modbus slave id (valid range: `>= 0 && <= 247`), `0` is broadcast address
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::InvalidSlaveID` is returned
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus, Error};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// assert_eq!(modbus.set_slave(10), Ok(0));
    /// assert_eq!(modbus.set_slave(255), Err(Error::InvalidSlaveID));
    /// ```
    pub fn set_slave(&mut self, slave_id: i32) -> Result<i32> {
        unsafe {
            match ::raw::modbus_set_slave(self.ctx, slave_id) {
                -1 => Err(Error::InvalidSlaveID),
                _ => Ok(0),
            }
        }
    }

    /// Set debug flag of the context
    ///
    /// # Attributes
    /// * `flag`    - boolean `true` or `false`
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::GenericError` is returned
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// assert_eq!(modbus.set_debug(true), Ok(0));
    /// ```
    pub fn set_debug(&mut self, flag: bool) -> Result<i32> {
        unsafe {
            match ::raw::modbus_set_debug(self.ctx, flag as c_int) {
                -1 => Err(Error::InvalidDebug),
                _ => Ok(0),
            }
        }
    }

    /// Set the serial mode
    ///
    /// # Attributes
    /// * `mode`    - serial mode
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::GenericError` is returned
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// ```
    pub fn rtu_set_serial_mode(&mut self, mode: i32) -> Result<i32> {
        unsafe {
            match ::raw::modbus_rtu_set_serial_mode(self.ctx, mode) {
                -1 => Err(Error::InvalidRTUSerialMode),
                _ => Ok(0),
            }
        }
    }

    /// Set the RTS mode in RTU
    ///
    /// # Attributes
    /// * `mode`    - serial mode
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::GenericError` is returned
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// modbus.set_slave(1);
    /// assert_eq!(modbus.rtu_set_rts(libmodbus_rs::MODBUS_RTU_RTS_DOWN), Ok(0));
    /// ```
    pub fn rtu_set_rts(&mut self, mode: i32) -> Result<i32> {
        unsafe {
            match ::raw::modbus_rtu_set_rts(self.ctx, mode) {
                -1 => Err(Error::InvalidRTURTS),
                _ => Ok(0),
            }
        }
    }

    /// Establish a Modbus connection
    ///
    /// # Examples
    /// A `Ok(0)` signals all right, on error a `Error::GenericError` is returned
    ///
    /// ```no_run
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// modbus.set_slave(1);
    /// assert_eq!(modbus.connect(), Ok(0));
    /// ```
    pub fn connect(&self) -> Result<i32> {
        unsafe {
            match ::raw::modbus_connect(self.ctx) {
                -1 => Err(Error::ConnectionError),
                _ => Ok(0),
            }
        }
    }

    /// modbus_close - close a Modbus connection
    ///
    /// The `modbus_close()` function shall close the connection established with the backend set in the context.
    ///
    /// # Examples
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// modbus.set_slave(1);
    /// match modbus.connect() {
    ///     Err(_) => { modbus.free(); }
    ///     Ok(_) => {
    ///         let _ = modbus.read_registers(0, 1);
    ///     }
    /// }
    /// modbus.close();
    /// modbus.free();
    /// ```
    pub fn close(&self) {
        unsafe {
            ::raw::modbus_close(self.ctx);
        }
    }

    /// Free a libmodbus context
    ///
    /// # Examples
    ///
    /// ```
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// modbus.set_slave(1);
    /// modbus.free();
    /// ```
    pub fn free(&self) {
        unsafe {
            ::raw::modbus_free(self.ctx);
        }
    }

    /// Read many registers
    ///
    /// # Attributes
    /// * `address`    - Start address from which the read should start
    /// * `num_reg`    - Number of holding registers to read from `address` of the remote device
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// let _ = modbus.set_slave(46);
    /// let _ = modbus.rtu_set_rts(libmodbus_rs::MODBUS_RTU_RTS_DOWN);
    /// let mut tab_reg: Vec<u16> = modbus.read_registers(0, 19).unwrap();
    /// modbus.free();
    /// ```
    pub fn read_registers(&self, address: i32, num_reg: i32) -> Result<Vec<u16>> {
        let mut tab_reg = vec![0u16; num_reg as usize];
        unsafe {
            match ::raw::modbus_read_registers(self.ctx, address, num_reg, tab_reg.as_mut_ptr()) {
                -1 => { Err(Error::ConnectionError)}
                _ => { Ok(tab_reg) }
            }
        }
    }

    /// Read many registers
    ///
    /// # Attributes
    /// * `address`    - Start address from which the read should start
    /// * `num_reg`    - Number of holding registers to read from `address` of the remote device
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use libmodbus_rs::modbus::{Modbus};
    ///
    /// let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    /// let _ = modbus.set_slave(46);
    /// let _ = modbus.rtu_set_rts(libmodbus_rs::MODBUS_RTU_RTS_DOWN);
    /// let mut tab_reg: Vec<u16> = modbus.read_input_registers(0, 19);
    /// modbus.free();
    /// ```
    pub fn read_input_registers(&self, address: i32, num_reg: i32) -> Vec<u16> {
        let mut tab_reg = vec![0u16; num_reg as usize];
        unsafe {
            ::raw::modbus_read_input_registers(self.ctx, address, num_reg, tab_reg.as_mut_ptr());
        }
        tab_reg
    }

    pub fn write_bit(&self, address: i32, status: bool) -> i32 {
        unsafe {
            ::raw::modbus_write_bit(self.ctx, address, status as i32)
        }
    }

}

#[cfg(test)]
mod tests {
    use super::Modbus;

    #[test]
    fn crate_modbus() {
        let modbus = Modbus::new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
        assert_eq!(modbus, modbus);
    }

}
<|endoftext|>


<commit_before>use cgmath;
use gfx;
use gfx::traits::{Device, FactoryExt};
#[cfg(feature = "opengl")]
use gfx_device_gl as back;
#[cfg(feature = "opengl")]
use gfx_window_glutin;
#[cfg(feature = "opengl")]
use glutin;

pub use self::back::Factory as BackendFactory;
pub use self::back::Resources as BackendResources;
use factory::Factory;
use scene::{Camera, Color, Material};
use {Scene};

pub type ColorFormat = gfx::format::Srgba8;
pub type DepthFormat = gfx::format::DepthStencil;

gfx_vertex_struct!(Vertex {
    pos: [f32; 4] = "a_Position",
});

gfx_pipeline!(pipe {
    vbuf: gfx::VertexBuffer<Vertex> = (),
    mx_vp: gfx::Global<[[f32; 4]; 4]> = "u_ViewProj",
    mx_world: gfx::Global<[[f32; 4]; 4]> = "u_World",
    color: gfx::Global<[f32; 4]> = "u_Color",
    out_color: gfx::RenderTarget<ColorFormat> = "Target0",
});

const LINE_VS: &'static [u8] = b"
    #version 150 core
    in vec4 a_Position;
    uniform mat4 u_ViewProj;
    uniform mat4 u_World;
    void main() {
        gl_Position = u_ViewProj * u_World * a_Position;
    }
";
const LINE_FS: &'static [u8] = b"
    #version 150 core
    uniform vec4 u_Color;
    void main() {
        gl_FragColor = u_Color;
    }
";

const MESH_VS: &'static [u8] = b"
    #version 150 core
    in vec4 a_Position;
    uniform mat4 u_ViewProj;
    uniform mat4 u_World;
    void main() {
        gl_Position = u_ViewProj * u_World * a_Position;
    }
";
const MESH_FS: &'static [u8] = b"
    #version 150 core
    uniform vec4 u_Color;
    void main() {
        gl_FragColor = u_Color;
    }
";

fn color_to_f32(c: Color) -> [f32; 4] {
    [((c>>16)&0xFF) as f32 / 255.0,
     ((c>>8) &0xFF) as f32 / 255.0,
     (c&0xFF) as f32 / 255.0,
     1.0]
}

//TODO: private fields?
#[derive(Clone)]
pub struct GpuData {
    pub slice: gfx::Slice<back::Resources>,
    pub vertices: gfx::handle::Buffer<back::Resources, Vertex>,
}

pub struct Renderer {
    device: back::Device,
    encoder: gfx::Encoder<back::Resources, back::CommandBuffer>,
    out_color: gfx::handle::RenderTargetView<back::Resources, ColorFormat>,
    out_depth: gfx::handle::DepthStencilView<back::Resources, DepthFormat>,
    pso_line_basic: gfx::PipelineState<back::Resources, pipe::Meta>,
    pso_mesh_basic: gfx::PipelineState<back::Resources, pipe::Meta>,
    size: (u32, u32),
    #[cfg(feature = "opengl")]
    window: glutin::Window,
}

impl Renderer {
    #[cfg(feature = "opengl")]
    pub fn new(builder: glutin::WindowBuilder, event_loop: &glutin::EventsLoop)
               -> (Self, Factory) {
        let (window, device, mut gl_factory, color, depth) =
            gfx_window_glutin::init(builder, event_loop);
        let prog_line = gl_factory.link_program(LINE_VS, LINE_FS).unwrap();
        let prog_mesh = gl_factory.link_program(MESH_VS, MESH_FS).unwrap();
        let rast_fill = gfx::state::Rasterizer::new_fill();
        let renderer = Renderer {
            device: device,
            encoder: gl_factory.create_command_buffer().into(),
            out_color: color,
            out_depth: depth,
            pso_line_basic: gl_factory.create_pipeline_from_program(&prog_line,
                    gfx::Primitive::LineStrip, rast_fill, pipe::new()
                ).unwrap(),
            pso_mesh_basic: gl_factory.create_pipeline_from_program(&prog_mesh,
                    gfx::Primitive::TriangleList, rast_fill, pipe::new()
                ).unwrap(),
            size: window.get_inner_size_pixels().unwrap(),
            window: window,
        };
        let factory = Factory::new(gl_factory);
        (renderer, factory)
    }

    pub fn resize(&mut self) {
        self.size = self.window.get_inner_size_pixels().unwrap();
        gfx_window_glutin::update_views(&self.window, &mut self.out_color, &mut self.out_depth);
    }

    pub fn get_aspect(&self) -> f32 {
        self.size.0 as f32 / self.size.1 as f32
    }

    pub fn render<C: Camera>(&mut self, scene: &Scene, cam: &C) {
        self.device.cleanup();
        self.encoder.clear(&self.out_color, [0.0, 0.0, 0.0, 1.0]);
        self.encoder.clear_depth(&self.out_depth, 1.0);

        let mx_vp = cam.to_view_proj();
        for visual in &scene.visuals {
            let (pso, color) = match visual.material {
                Material::LineBasic { color } => (&self.pso_line_basic, color),
                Material::MeshBasic { color } => (&self.pso_mesh_basic, color),
            };
            let mx_world = cgmath::Matrix4::from(scene.nodes[&visual.node].world);
            let data = pipe::Data {
                vbuf: visual.gpu_data.vertices.clone(),
                mx_vp: mx_vp.into(),
                mx_world: mx_world.into(),
                color: color_to_f32(color),
                out_color: self.out_color.clone(),
            };
            self.encoder.draw(&visual.gpu_data.slice, pso, &data);
        }

        self.encoder.flush(&mut self.device);
        self.window.swap_buffers().unwrap();
    }
}
<commit_msg>Sprite rendering<commit_after>use cgmath;
use gfx;
use gfx::traits::{Device, Factory as Factory_, FactoryExt};
#[cfg(feature = "opengl")]
use gfx_device_gl as back;
#[cfg(feature = "opengl")]
use gfx_window_glutin;
#[cfg(feature = "opengl")]
use glutin;

pub use self::back::Factory as BackendFactory;
pub use self::back::Resources as BackendResources;
use factory::{Factory, Texture};
use scene::{Camera, Color, Material};
use {Scene};

pub type ColorFormat = gfx::format::Srgba8;
pub type DepthFormat = gfx::format::DepthStencil;

//TODO: remove
const BLEND_REPLACE: gfx::state::Blend = gfx::state::Blend {
    color: gfx::state::BlendChannel {
        equation: gfx::state::Equation::Add,
        source: gfx::state::Factor::One,
        destination: gfx::state::Factor::Zero,
    },
    alpha: gfx::state::BlendChannel {
        equation: gfx::state::Equation::Add,
        source: gfx::state::Factor::One,
        destination: gfx::state::Factor::Zero,
    },
};

gfx_vertex_struct!(Vertex {
    pos: [f32; 4] = "a_Position",
});

gfx_pipeline!(pipe {
    vbuf: gfx::VertexBuffer<Vertex> = (),
    mx_vp: gfx::Global<[[f32; 4]; 4]> = "u_ViewProj",
    mx_world: gfx::Global<[[f32; 4]; 4]> = "u_World",
    color: gfx::Global<[f32; 4]> = "u_Color",
    tex_map: gfx::TextureSampler<[f32; 4]> = "t_Map",
    out_color: gfx::BlendTarget<ColorFormat> =
        ("Target0", gfx::state::MASK_ALL, BLEND_REPLACE),
});

const LINE_VS: &'static [u8] = b"
    #version 150 core
    in vec4 a_Position;
    uniform mat4 u_ViewProj;
    uniform mat4 u_World;
    void main() {
        gl_Position = u_ViewProj * u_World * a_Position;
    }
";
const LINE_FS: &'static [u8] = b"
    #version 150 core
    uniform vec4 u_Color;
    void main() {
        gl_FragColor = u_Color;
    }
";

const MESH_VS: &'static [u8] = b"
    #version 150 core
    in vec4 a_Position;
    uniform mat4 u_ViewProj;
    uniform mat4 u_World;
    void main() {
        gl_Position = u_ViewProj * u_World * a_Position;
    }
";
const MESH_FS: &'static [u8] = b"
    #version 150 core
    uniform vec4 u_Color;
    void main() {
        gl_FragColor = u_Color;
    }
";

const SPRITE_VS: &'static [u8] = b"
    #version 150 core
    in vec4 a_Position;
    out vec2 v_TexCoord;
    uniform mat4 u_ViewProj;
    uniform mat4 u_World;
    void main() {
        v_TexCoord = a_Position.xy*0.5 + 0.5;
        gl_Position = u_ViewProj * u_World * a_Position;
    }
";
const SPRITE_FS: &'static [u8] = b"
    #version 150 core
    in vec2 v_TexCoord;
    uniform sampler2D t_Map;
    void main() {
        gl_FragColor = texture(t_Map, v_TexCoord);
    }
";

fn color_to_f32(c: Color) -> [f32; 4] {
    [((c>>16)&0xFF) as f32 / 255.0,
     ((c>>8) &0xFF) as f32 / 255.0,
     (c&0xFF) as f32 / 255.0,
     1.0]
}

//TODO: private fields?
#[derive(Clone)]
pub struct GpuData {
    pub slice: gfx::Slice<back::Resources>,
    pub vertices: gfx::handle::Buffer<back::Resources, Vertex>,
}

pub struct Renderer {
    device: back::Device,
    encoder: gfx::Encoder<back::Resources, back::CommandBuffer>,
    out_color: gfx::handle::RenderTargetView<back::Resources, ColorFormat>,
    out_depth: gfx::handle::DepthStencilView<back::Resources, DepthFormat>,
    pso_line_basic: gfx::PipelineState<back::Resources, pipe::Meta>,
    pso_mesh_basic: gfx::PipelineState<back::Resources, pipe::Meta>,
    pso_sprite: gfx::PipelineState<back::Resources, pipe::Meta>,
    map_default: Texture,
    size: (u32, u32),
    #[cfg(feature = "opengl")]
    window: glutin::Window,
}

impl Renderer {
    #[cfg(feature = "opengl")]
    pub fn new(builder: glutin::WindowBuilder, event_loop: &glutin::EventsLoop)
               -> (Self, Factory) {
        let (window, device, mut gl_factory, color, depth) =
            gfx_window_glutin::init(builder, event_loop);
        let prog_line = gl_factory.link_program(LINE_VS, LINE_FS).unwrap();
        let prog_mesh = gl_factory.link_program(MESH_VS, MESH_FS).unwrap();
        let prog_sprite = gl_factory.link_program(SPRITE_VS, SPRITE_FS).unwrap();
        let rast_fill = gfx::state::Rasterizer::new_fill();
        let (_, srv_white) = gl_factory.create_texture_immutable::<gfx::format::Rgba8>(
            gfx::texture::Kind::D2(1, 1, gfx::texture::AaMode::Single), &[&[[0xFF; 4]]]
            ).unwrap();
        let sampler = gl_factory.create_sampler_linear();
        let renderer = Renderer {
            device: device,
            encoder: gl_factory.create_command_buffer().into(),
            out_color: color,
            out_depth: depth,
            pso_line_basic: gl_factory.create_pipeline_from_program(&prog_line,
                gfx::Primitive::LineStrip, rast_fill, pipe::new()
                ).unwrap(),
            pso_mesh_basic: gl_factory.create_pipeline_from_program(&prog_mesh,
                gfx::Primitive::TriangleList, rast_fill, pipe::new()
                ).unwrap(),
            pso_sprite: gl_factory.create_pipeline_from_program(&prog_sprite,
                gfx::Primitive::TriangleStrip, rast_fill, pipe::Init {
                    out_color: ("Target0", gfx::state::MASK_ALL, gfx::preset::blend::ALPHA),
                    .. pipe::new()
                }).unwrap(),
            map_default: Texture::new(srv_white, sampler),
            size: window.get_inner_size_pixels().unwrap(),
            window: window,
        };
        let factory = Factory::new(gl_factory);
        (renderer, factory)
    }

    pub fn resize(&mut self) {
        self.size = self.window.get_inner_size_pixels().unwrap();
        gfx_window_glutin::update_views(&self.window, &mut self.out_color, &mut self.out_depth);
    }

    pub fn get_aspect(&self) -> f32 {
        self.size.0 as f32 / self.size.1 as f32
    }

    pub fn render<C: Camera>(&mut self, scene: &Scene, cam: &C) {
        self.device.cleanup();
        self.encoder.clear(&self.out_color, [0.0, 0.0, 0.0, 1.0]);
        self.encoder.clear_depth(&self.out_depth, 1.0);

        let mx_vp = cam.to_view_proj();
        for visual in &scene.visuals {
            let (pso, color, map) = match visual.material {
                Material::LineBasic { color } => (&self.pso_line_basic, color, None),
                Material::MeshBasic { color } => (&self.pso_mesh_basic, color, None),
                Material::Sprite { ref map } => (&self.pso_sprite, !0, Some(map)),
            };
            let mx_world = cgmath::Matrix4::from(scene.nodes[&visual.node].world);
            let data = pipe::Data {
                vbuf: visual.gpu_data.vertices.clone(),
                mx_vp: mx_vp.into(),
                mx_world: mx_world.into(),
                color: color_to_f32(color),
                tex_map: map.unwrap_or(&self.map_default).to_param(),
                out_color: self.out_color.clone(),
            };
            self.encoder.draw(&visual.gpu_data.slice, pso, &data);
        }

        self.encoder.flush(&mut self.device);
        self.window.swap_buffers().unwrap();
    }
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use std::hash::Hash;
use std::collections::HashSet;

pub trait SearchSpace {
    type State: Ord + Hash + Eq + Clone + Debug;
    type Action: Clone;

    fn actions(&self, state: &Self::State) -> Vec<Self::Action>;
    fn next_state(&self, state: &Self::State, action: &Self::Action) -> Self::State;
    fn is_goal(&self, state: &Self::State) -> bool;
}

pub fn depth_first_search<S>(space: &S, start: S::State) -> Option<Vec<S::Action>>
where S: SearchSpace {
    let mut path = Vec::new();
    let start_actions = space.actions(&start);
    let mut frontier = vec![(start, start_actions.into_iter())];

    loop {
        let result = match frontier.last_mut() {
            None => return None,
            Some(&mut (ref mut state, ref mut actions)) => {
                if space.is_goal(&state) {
                    return Some(path);
                }
                match actions.next() {
                    None => None,
                    Some(action) => {
                        let next_state = space.next_state(&state, &action);
                        let next_actions = space.actions(&next_state).into_iter();
                        path.push(action);
                        Some((next_state, next_actions))
                    }
                }
            }
        };
        match result {
            None => {
                path.pop();
                frontier.pop();
            },
            Some((next_state, next_actions)) => {
                frontier.push((next_state, next_actions));
            },
        };
    }
}

#[cfg(test)]
pub mod tests {
    use super::*;

    #[test]
    pub fn test_depth_first_search() {
        struct S {
            goal: i32,
        }

        #[derive(Debug, Clone, PartialEq)]
        enum Direction {
            Left,
            Right
        }

        impl SearchSpace for S {
            type State = i32;
            type Action = Direction;

            fn actions(&self, state: &i32) -> Vec<Direction> {
                if *state == 0 || *state == 1 {
                    vec![Direction::Left, Direction::Right]
                } else {
                    vec![]
                }
            }

            fn next_state(&self, state: &i32, action: &Direction) -> i32 {
                match *state {
                    0 => match *action {
                        Direction::Left => 1,
                        Direction::Right => 2,
                    },
                    1 => match *action {
                        Direction::Left => 3,
                        Direction::Right => 4,
                    },
                    node => node
                }
            }

            fn is_goal(&self, state: &i32) -> bool {
                return self.goal == *state
            }
        }

        impl S {
            fn solve(start: i32, goal: i32) -> Option<Vec<Direction>> {
                let space = S { goal: goal };
                depth_first_search(&space, start)
            }
        }

        assert_eq!(S::solve(0, 0).unwrap(), vec![]);
        assert_eq!(S::solve(0, 1).unwrap(), vec![Direction::Left]);
        assert_eq!(S::solve(0, 2).unwrap(), vec![Direction::Right]);
        assert_eq!(S::solve(0, 3).unwrap(), vec![Direction::Left, Direction::Left]);
        assert_eq!(S::solve(0, 4).unwrap(), vec![Direction::Left, Direction::Right]);
        assert_eq!(S::solve(2, 2).unwrap(), vec![]);
        assert!(S::solve(5, 0).is_none());
    }
}
<commit_msg>Use iterator instead of vec for actions<commit_after>use std::fmt::Debug;
use std::hash::Hash;
use std::collections::HashSet;

pub trait SearchSpace {
    type State: Ord + Hash + Eq + Clone + Debug;
    type Action: Clone;
    type Iterator: Iterator<Item=Self::Action>;

    fn actions(&self, state: &Self::State) -> Self::Iterator;
    fn next_state(&self, state: &Self::State, action: &Self::Action) -> Self::State;
    fn is_goal(&self, state: &Self::State) -> bool;
}

pub fn depth_first_search<S>(space: &S, start: S::State) -> Option<Vec<S::Action>>
where S: SearchSpace {
    let mut path = Vec::new();
    let actions = space.actions(&start);
    let mut frontier = vec![(start, actions)];

    loop {
        let result = match frontier.last_mut() {
            None => return None,
            Some(&mut (ref mut state, ref mut actions)) => {
                if space.is_goal(&state) {
                    return Some(path);
                }
                match actions.next() {
                    None => None,
                    Some(action) => {
                        let next_state = space.next_state(&state, &action);
                        let next_actions = space.actions(&next_state);
                        path.push(action);
                        Some((next_state, next_actions))
                    }
                }
            }
        };
        match result {
            None => {
                path.pop();
                frontier.pop();
            },
            Some((next_state, next_actions)) => {
                frontier.push((next_state, next_actions));
            },
        };
    }
}

#[cfg(test)]
pub mod tests {
    use std::vec::IntoIter;
    use super::*;

    #[test]
    pub fn test_depth_first_search() {
        struct S {
            goal: i32,
        }

        #[derive(Debug, Clone, PartialEq)]
        enum Direction {
            Left,
            Right
        }

        impl SearchSpace for S {
            type State = i32;
            type Action = Direction;
            type Iterator = IntoIter<Self::Action>;

            fn actions(&self, state: &i32) -> Self::Iterator {
                if *state == 0 || *state == 1 {
                    vec![Direction::Left, Direction::Right].into_iter()
                } else {
                    vec![].into_iter()
                }
            }

            fn next_state(&self, state: &i32, action: &Direction) -> i32 {
                match *state {
                    0 => match *action {
                        Direction::Left => 1,
                        Direction::Right => 2,
                    },
                    1 => match *action {
                        Direction::Left => 3,
                        Direction::Right => 4,
                    },
                    node => node
                }
            }

            fn is_goal(&self, state: &i32) -> bool {
                return self.goal == *state
            }
        }

        impl S {
            fn solve(start: i32, goal: i32) -> Option<Vec<Direction>> {
                let space = S { goal: goal };
                depth_first_search(&space, start)
            }
        }

        assert_eq!(S::solve(0, 0).unwrap(), vec![]);
        assert_eq!(S::solve(0, 1).unwrap(), vec![Direction::Left]);
        assert_eq!(S::solve(0, 2).unwrap(), vec![Direction::Right]);
        assert_eq!(S::solve(0, 3).unwrap(), vec![Direction::Left, Direction::Left]);
        assert_eq!(S::solve(0, 4).unwrap(), vec![Direction::Left, Direction::Right]);
        assert_eq!(S::solve(2, 2).unwrap(), vec![]);
        assert!(S::solve(5, 0).is_none());
    }
}
<|endoftext|>


<commit_before>use score;
use score::Match;
use sorted_result_set::SortedResultSet;
use std::ascii::AsciiExt;

#[derive(Debug)]
pub struct Search<'s> {
    pub query: String,
    pub current: usize,
    pub result: Vec<Match<'s>>,
    choice_stack: ChoiceStack<'s>,
    pub visible_limit: usize,
    done: bool,
}

#[derive(Debug)]
struct ChoiceStack<'s> {
    content: Vec<Vec<&'s String>>,
}

impl <'s>ChoiceStack<'s> {
    pub fn new(input: &'s Vec<String>) -> ChoiceStack<'s> {
        let initial_choices = input.iter().map(|x| x).collect();

        ChoiceStack { content: vec![initial_choices] }
    }

    pub fn push(&mut self, frame: Vec<&'s String>) {
        self.content.push(frame);
    }

    pub fn pop(&mut self) {
        if self.content.len() > 1 {
            self.content.pop();
        }
    }

    pub fn peek(&self) -> &Vec<&'s String> {
        self.content.last().unwrap()
    }

    pub fn last_size(&self) -> usize {
        self.peek().len()
    }
}

impl<'s> Search<'s> {
    pub fn blank(choices: &'s Vec<String>,
                 initial_search: Option<String>,
                 visible_limit: usize) -> Search<'s> {
        let query = initial_search.unwrap_or("".to_string());

        let choice_stack = ChoiceStack::new(&choices);

        let result = choices.iter().take(visible_limit).map(|x| Match::with_empty_range(x)).collect();

        Search::new(query, choice_stack, result, 0, visible_limit, false)
    }

    fn new(query: String, choice_stack: ChoiceStack<'s>, result: Vec<Match<'s>>, index: usize, visible_limit: usize, done: bool) -> Search<'s> {
        Search { current: index,
                 query: query,
                 result: result,
                 choice_stack: choice_stack,
                 visible_limit: visible_limit,
                 done: done}
    }

    pub fn is_done(&self) -> bool {
        self.done
    }

    pub fn done(self) -> Search<'s> {
        Search::new(self.query, self.choice_stack, self.result, self.current, self.visible_limit, true)
    }

    pub fn selection(&self) -> Option<String> {
        self.result.get(self.current).map( |t| t.original.clone())
    }

    fn new_for_index(self, index: usize) -> Search<'s> {
        Search::new(self.query, self.choice_stack, self.result, index,self.visible_limit, self.done)
    }

    pub fn iter_matches<F: FnMut(Match<'s>)>(query: &str, choices: &Vec<&'s String>, mut f: F) {
        let lower_query = query.to_ascii_lowercase();

        for choice in choices.iter() {
            match score::score(&choice, &lower_query) {
                None     => continue,
                Some(m) => f(m),
            };
        }
    }

    pub fn down(self) -> Search<'s> {
        let next_index = self.next_index();
        self.new_for_index(next_index)
    }

    pub fn up(self) -> Search<'s> {
        let next_index = self.prev_index();
        self.new_for_index(next_index)
    }

    pub fn append_to_search(mut self, input: &str) -> Search<'s> {
        let mut new_query = self.query.clone();
        new_query.push_str(input.as_ref());

        let mut result = SortedResultSet::new(self.visible_limit);
        let mut filtered_choices: Vec<&String> = Vec::new();
        Search::iter_matches(new_query.as_ref(), &self.choice_stack.peek(),
                        |matching| {
                                               let quality = matching.quality.to_f32();
                                               let choice = matching.original;
                                               result.push(matching.clone(), quality);
                                               filtered_choices.push(&choice)
                                             });

        self.choice_stack.push(filtered_choices);

        Search::new(new_query, self.choice_stack, result.as_sorted_vec(), 0, self.visible_limit, self.done)
    }

    pub fn backspace(mut self) -> Search<'s> {
        let mut new_query = self.query.clone();
        new_query.pop();

        self.choice_stack.pop();

        let mut result = SortedResultSet::new(self.visible_limit);
        Search::iter_matches(new_query.as_ref(), &self.choice_stack.peek(),
                             |matching| {
                                 let quality = matching.quality.to_f32();
                                 result.push(matching, quality)
                             } );

        Search::new(new_query, self.choice_stack, result.as_sorted_vec(), 0, self.visible_limit, self.done)
    }

    fn next_index(&self) -> usize {
        // TODO: fix this!
        // current is an index -> zero based
        // num_matches is a length -> 1 based
        if self.num_matches() == 0 {
            0
        } else if self.current == self.num_matches()-1 {
            0
        } else {
            self.current+1
        }
    }

    fn prev_index(&self) -> usize {
        if self.num_matches() == 0 {
            0
        } else if self.current == 0 {
            self.num_matches() -1
        } else {
            self.current-1
        }
    }

    pub fn num_matches(&self) -> usize {
        self.choice_stack.last_size()
    }
}
<commit_msg>Collaps case where scrolling down starts at the top again<commit_after>use score;
use score::Match;
use sorted_result_set::SortedResultSet;
use std::ascii::AsciiExt;

#[derive(Debug)]
pub struct Search<'s> {
    pub query: String,
    pub current: usize,
    pub result: Vec<Match<'s>>,
    choice_stack: ChoiceStack<'s>,
    pub visible_limit: usize,
    done: bool,
}

#[derive(Debug)]
struct ChoiceStack<'s> {
    content: Vec<Vec<&'s String>>,
}

impl <'s>ChoiceStack<'s> {
    pub fn new(input: &'s Vec<String>) -> ChoiceStack<'s> {
        let initial_choices = input.iter().map(|x| x).collect();

        ChoiceStack { content: vec![initial_choices] }
    }

    pub fn push(&mut self, frame: Vec<&'s String>) {
        self.content.push(frame);
    }

    pub fn pop(&mut self) {
        if self.content.len() > 1 {
            self.content.pop();
        }
    }

    pub fn peek(&self) -> &Vec<&'s String> {
        self.content.last().unwrap()
    }

    pub fn last_size(&self) -> usize {
        self.peek().len()
    }
}

impl<'s> Search<'s> {
    pub fn blank(choices: &'s Vec<String>,
                 initial_search: Option<String>,
                 visible_limit: usize) -> Search<'s> {
        let query = initial_search.unwrap_or("".to_string());

        let choice_stack = ChoiceStack::new(&choices);

        let result = choices.iter().take(visible_limit).map(|x| Match::with_empty_range(x)).collect();

        Search::new(query, choice_stack, result, 0, visible_limit, false)
    }

    fn new(query: String, choice_stack: ChoiceStack<'s>, result: Vec<Match<'s>>, index: usize, visible_limit: usize, done: bool) -> Search<'s> {
        Search { current: index,
                 query: query,
                 result: result,
                 choice_stack: choice_stack,
                 visible_limit: visible_limit,
                 done: done}
    }

    pub fn is_done(&self) -> bool {
        self.done
    }

    pub fn done(self) -> Search<'s> {
        Search::new(self.query, self.choice_stack, self.result, self.current, self.visible_limit, true)
    }

    pub fn selection(&self) -> Option<String> {
        self.result.get(self.current).map( |t| t.original.clone())
    }

    fn new_for_index(self, index: usize) -> Search<'s> {
        Search::new(self.query, self.choice_stack, self.result, index,self.visible_limit, self.done)
    }

    pub fn iter_matches<F: FnMut(Match<'s>)>(query: &str, choices: &Vec<&'s String>, mut f: F) {
        let lower_query = query.to_ascii_lowercase();

        for choice in choices.iter() {
            match score::score(&choice, &lower_query) {
                None     => continue,
                Some(m) => f(m),
            };
        }
    }

    pub fn down(self) -> Search<'s> {
        let next_index = self.next_index();
        self.new_for_index(next_index)
    }

    pub fn up(self) -> Search<'s> {
        let next_index = self.prev_index();
        self.new_for_index(next_index)
    }

    pub fn append_to_search(mut self, input: &str) -> Search<'s> {
        let mut new_query = self.query.clone();
        new_query.push_str(input.as_ref());

        let mut result = SortedResultSet::new(self.visible_limit);
        let mut filtered_choices: Vec<&String> = Vec::new();
        Search::iter_matches(new_query.as_ref(), &self.choice_stack.peek(),
                        |matching| {
                                               let quality = matching.quality.to_f32();
                                               let choice = matching.original;
                                               result.push(matching.clone(), quality);
                                               filtered_choices.push(&choice)
                                             });

        self.choice_stack.push(filtered_choices);

        Search::new(new_query, self.choice_stack, result.as_sorted_vec(), 0, self.visible_limit, self.done)
    }

    pub fn backspace(mut self) -> Search<'s> {
        let mut new_query = self.query.clone();
        new_query.pop();

        self.choice_stack.pop();

        let mut result = SortedResultSet::new(self.visible_limit);
        Search::iter_matches(new_query.as_ref(), &self.choice_stack.peek(),
                             |matching| {
                                 let quality = matching.quality.to_f32();
                                 result.push(matching, quality)
                             } );

        Search::new(new_query, self.choice_stack, result.as_sorted_vec(), 0, self.visible_limit, self.done)
    }

    fn next_index(&self) -> usize {
        // TODO: fix this!
        // current is an index -> zero based
        // num_matches is a length -> 1 based
        if self.current + 1 == self.num_matches() {
            0
        } else {
            self.current+1
        }
    }

    fn prev_index(&self) -> usize {
        if self.num_matches() == 0 {
            0
        } else if self.current == 0 {
            self.num_matches() - 1
        } else {
            self.current-1
        }
    }

    pub fn num_matches(&self) -> usize {
        self.choice_stack.last_size()
    }
}
<|endoftext|>


<commit_before>extern crate dbus;
use self::dbus::{Connection, ConnectionItem, Message, NameFlag, ReleaseNameReply};
use self::dbus::obj::ObjectPath;

use super::error::DBusError;
use super::target::DBusTarget;

use std::collections::btree_map::{BTreeMap, Entry};
use std::error::Error;

pub struct DBusServer<'a> {
    conn: &'a Connection,
    name: String,

    objects: BTreeMap<String, ObjectPath<'a>>,
    signals: BTreeMap<DBusTarget, Vec<fn (&Connection, &DBusTarget) -> ()>>
}

impl<'a> DBusServer<'a> {
    pub fn new(conn: &'a Connection, name: &str) -> Result<DBusServer<'a>, dbus::Error> {
        try!(conn.register_name(name, NameFlag::DoNotQueue as u32));

        Ok(DBusServer {
            conn: conn,
            name: name.to_owned(),

            objects: BTreeMap::new(),
            signals: BTreeMap::new(),
        })
    }

    pub fn add_object(&mut self, path: &str, add_interfaces: fn (&mut ObjectPath<'a>) -> ()) -> Result<(), Box<Error>> {
        match self.objects.entry(path.to_owned()) {
            Entry::Vacant(v)    => {
                let mut obj = ObjectPath::new(self.conn, path, true);
                try!(obj.set_registered(true));

                // Add interfaces.
                add_interfaces(&mut obj);

                v.insert(obj);

                Ok(())
            },
            Entry::Occupied(_)  => Err(Box::new(DBusError::PathAlreadyRegistered(path.to_owned()))),
        }
    }

    pub fn remove_object(&mut self, path: &str) -> Result<(), DBusError> {
        match self.objects.remove(path) {
            Some(_) => Ok(()),
            None    => Err(DBusError::NoSuchPath(path.to_owned())),
        }
    }

    pub fn connect(&mut self, signal: DBusTarget, callback: fn (&Connection, &DBusTarget) -> ()) -> () {
        match self.signals.entry(signal) {
            Entry::Vacant(v)    => { v.insert(vec![callback]); },
            Entry::Occupied(o)  => o.into_mut().push(callback),
        };
    }

    pub fn run(&mut self) -> () {
        self.conn.iter(100).fold((), |_, item| {
            match item {
                ConnectionItem::MethodCall(m)   => self._call_method(m),
                ConnectionItem::Signal(s)       => self._match_signal(s),
                ConnectionItem::Nothing         => (),
            }
        });
    }

    fn _call_method(&mut self, m: Message) -> () {
        self.objects.iter_mut().fold(Some(m), |opt_m, (_, object)| {
            opt_m.and_then(|mut m| {
                match object.handle_message(&mut m) {
                    None          => Some(m),
                    Some(Ok(()))  => None,
                    Some(Err(())) => {
                        println!("failed to send a reply for {:?}", m);
                        None
                    },
                }
            })
        });
    }

    fn _match_signal(&self, m: Message) -> () {
        let ref signals = self.signals;
        let conn = self.conn;

        DBusTarget::extract(&m).and_then(|signal| {
            signals.get(&signal).map(|fs| {
                fs.iter().fold((conn, signal), |(conn, signal), f| {
                    f(&conn, &signal);
                    (conn, signal)
                })
            })
        });
    }
}

impl<'a> Drop for DBusServer<'a> {
    fn drop(&mut self) {
        let res = self.conn.release_name(&self.name);
        match res {
            Ok(reply) =>
                match reply {
                    ReleaseNameReply::Released    => (),
                    ReleaseNameReply::NonExistent => panic!("internal error: non-existent name {}?!", self.name),
                    ReleaseNameReply::NotOwner    => panic!("internal error: not the owner of {}?!", self.name),
                },
            Err(err) => println!("failed to release {}: {:?}: {:?}", self.name, err.name(), err.message()),
        }
    }
}
<commit_msg>server: make handler methods follow a builder pattern<commit_after>extern crate dbus;
use self::dbus::{Connection, ConnectionItem, Message, NameFlag, ReleaseNameReply};
use self::dbus::obj::ObjectPath;

use super::error::DBusError;
use super::target::DBusTarget;

use std::collections::btree_map::{BTreeMap, Entry};
use std::error::Error;

pub struct DBusServer<'a> {
    conn: &'a Connection,
    name: String,

    objects: BTreeMap<String, ObjectPath<'a>>,
    signals: BTreeMap<DBusTarget, Vec<fn (&Connection, &DBusTarget) -> ()>>
}

impl<'a> DBusServer<'a> {
    pub fn new(conn: &'a Connection, name: &str) -> Result<DBusServer<'a>, dbus::Error> {
        try!(conn.register_name(name, NameFlag::DoNotQueue as u32));

        Ok(DBusServer {
            conn: conn,
            name: name.to_owned(),

            objects: BTreeMap::new(),
            signals: BTreeMap::new(),
        })
    }

    pub fn add_object(&mut self, path: &str, add_interfaces: fn (&mut ObjectPath<'a>) -> ()) -> Result<&mut Self, Box<Error>> {
        // XXX: Use `.map` when type resolution works better. Currently, `.map` causes the caller
        // type to be set in stone due to eager type resolution and no fluidity in setting it. This
        // causes the type to be too concrete on the caller side which then fails to map to the end
        // result type of `.map` even though `.map` is "transparent" to the error type.
        Result::map(match self.objects.entry(path.to_owned()) {
            Entry::Vacant(v)    => {
                let mut obj = ObjectPath::new(self.conn, path, true);
                try!(obj.set_registered(true));

                // Add interfaces.
                add_interfaces(&mut obj);

                v.insert(obj);

                Ok(())
            },
            Entry::Occupied(_)  => Err(Box::new(DBusError::PathAlreadyRegistered(path.to_owned()))),
        }, |_| self)
    }

    pub fn remove_object(&mut self, path: &str) -> Result<&mut Self, DBusError> {
        match self.objects.remove(path) {
            Some(_) => Ok(self),
            None    => Err(DBusError::NoSuchPath(path.to_owned())),
        }
    }

    pub fn connect(&mut self, signal: DBusTarget, callback: fn (&Connection, &DBusTarget) -> ()) -> &mut Self {
        match self.signals.entry(signal) {
            Entry::Vacant(v)    => { v.insert(vec![callback]); },
            Entry::Occupied(o)  => o.into_mut().push(callback),
        };

        self
    }

    pub fn run(&mut self) -> () {
        self.conn.iter(100).fold((), |_, item| {
            match item {
                ConnectionItem::MethodCall(m)   => self._call_method(m),
                ConnectionItem::Signal(s)       => self._match_signal(s),
                ConnectionItem::Nothing         => (),
            }
        });
    }

    fn _call_method(&mut self, m: Message) -> () {
        self.objects.iter_mut().fold(Some(m), |opt_m, (_, object)| {
            opt_m.and_then(|mut m| {
                match object.handle_message(&mut m) {
                    None          => Some(m),
                    Some(Ok(()))  => None,
                    Some(Err(())) => {
                        println!("failed to send a reply for {:?}", m);
                        None
                    },
                }
            })
        });
    }

    fn _match_signal(&self, m: Message) -> () {
        let ref signals = self.signals;
        let conn = self.conn;

        DBusTarget::extract(&m).and_then(|signal| {
            signals.get(&signal).map(|fs| {
                fs.iter().fold((conn, signal), |(conn, signal), f| {
                    f(&conn, &signal);
                    (conn, signal)
                })
            })
        });
    }
}

impl<'a> Drop for DBusServer<'a> {
    fn drop(&mut self) {
        let res = self.conn.release_name(&self.name);
        match res {
            Ok(reply) =>
                match reply {
                    ReleaseNameReply::Released    => (),
                    ReleaseNameReply::NonExistent => panic!("internal error: non-existent name {}?!", self.name),
                    ReleaseNameReply::NotOwner    => panic!("internal error: not the owner of {}?!", self.name),
                },
            Err(err) => println!("failed to release {}: {:?}: {:?}", self.name, err.name(), err.message()),
        }
    }
}
<|endoftext|>


<commit_before>use std::thread;
use std::collections::HashSet;
use std::net::SocketAddr;
use std::ops::Deref;
use std::io;
use std::error::FromError;

// MIO
use mio::tcp::{listen, TcpListener, TcpStream};
use mio::util::Slab;
use mio::Socket;
use mio::buf::{RingBuf};
use mio::{Interest, PollOpt, NonBlock, Token, EventLoop, Handler, ReadHint};
use mio::buf::Buf;
use mio::{TryRead, TryWrite};

use rand::{self, Rng};

// Data structures.
use store::Store;
use replica::{Replica, Emit, Broadcast};
use state_machine::StateMachine;

// Cap'n Proto
use capnp::serialize_packed;
use capnp::{
    MessageBuilder,
    MessageReader,
    ReaderOptions,
    MallocMessageBuilder,
    Word,
    OwnedSpaceMessageReader,
};
use messages_capnp::{
    rpc_request,
    rpc_response,
    client_request,
    client_response,
    request_vote_response,
    append_entries_response,
    append_entries_request,
};
use super::{Error, Result};

// MIO Tokens
const ELECTION_TIMEOUT: Token = Token(0);
const HEARTBEAT_TIMEOUT: Token = Token(1);
const LISTENER:  Token = Token(2);

const ELECTION_MIN: u64 = 150;
const ELECTION_MAX: u64 = 300;
const HEARTBEAT_DURATION: u64 = 50;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
/// A `Server` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
///
/// Currently, the `Server` API is not well defined. **We are looking for feedback and suggestions.**
pub struct Server<S, M> where S: Store, M: StateMachine {
    replica: Replica<S, M>,
    // Channels and Sockets
    listener: NonBlock<TcpListener>,
    connections: Slab<Connection>,
}

/// The implementation of the Server. In most use cases, creating a `Server` should just be
/// done via `::new()`.
impl<S, M> Server<S, M> where S: Store, M: StateMachine {

    /// Creates a new Raft node with the cluster members specified.
    ///
    /// # Arguments
    ///
    /// * `addr` - The address of the new node.
    /// * `peers` - The address of all peers in the Raft cluster.
    /// * `store` - The persitent log store.
    /// * `state_machine` - The client state machine to which client commands will be applied.
    pub fn spawn(addr: SocketAddr,
                 peers: HashSet<SocketAddr>,
                 store: S,
                 state_machine: M) {
        // Create an event loop
        let mut event_loop = EventLoop::<Server<S, M>>::new().unwrap();
        // Setup the socket, make it not block.
        let listener = listen(&addr).unwrap();
        listener.set_reuseaddr(true);
        event_loop.register(&listener, LISTENER).unwrap();
        let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
        event_loop.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
        event_loop.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION);
        let replica = Replica::new(addr, peers, store, state_machine);
        // Fire up the thread.
        thread::Builder::new().name(format!("Server {}", addr)).spawn(move || {
            let mut raft_node = Server {
                listener: listener,
                replica: replica,
                connections: Slab::new_starting_at(Token(2), 128),
            };
            event_loop.run(&mut raft_node).unwrap();
        }).unwrap();
    }
}

impl<S, M> Handler for Server<S, M> where S: Store, M: StateMachine {

    type Message = ();
    type Timeout = Token;

    /// A registered IoHandle has available writing space.
    fn writable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => unreachable!(),
            tok => {
                self.connections[tok].writable(reactor, &mut self.replica);
            }
        }
    }

    /// A registered IoHandle has available data to read
    fn readable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token, hint: ReadHint) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => {
                let stream = self.listener.accept().unwrap().unwrap(); // Result<Option<_>,_>
                let conn = Connection::new(stream);
                let tok = self.connections.insert(conn)
                    .ok().expect("Could not add connection to slab.");

                // Register the connection
                self.connections[tok].token = tok;
                reactor.register_opt(&self.connections[tok].stream, tok, Interest::readable(), PollOpt::edge() | PollOpt::oneshot())
                    .ok().expect("Could not register socket with event loop.");
            },
            tok => {
                self.connections[tok].readable(reactor, &mut self.replica);
            }
        }
    }

    /// A registered timer has expired
    fn timeout(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        let mut message = MallocMessageBuilder::new_default();
        let request = message.init_root::<rpc_request::Builder>();

        match token {
            ELECTION_TIMEOUT => {
                let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
                let _send_message = self.replica.election_timeout(request.init_request_vote());
                reactor.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
                // TODO: send messages if necessary
                unimplemented!();
                // self.broadcast(&mut builder_message);
            },
            HEARTBEAT_TIMEOUT => {
                let _send_message = self.replica.heartbeat_timeout(request.init_append_entries());
                reactor.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION).unwrap();
                // TODO: send messages if necessary
                unimplemented!();
                // self.broadcast(&mut builder_message);
            },
            _ => unreachable!(),
        }
    }
}

struct Connection {
    stream: NonBlock<TcpStream>,
    token: Token,
    interest: Interest,
    current_read: RingBuf,
    current_write: RingBuf,
    next_write: Option<MallocMessageBuilder>,
}

impl Connection {
    fn new(sock: NonBlock<TcpStream>) -> Connection {
        Connection {
            stream: sock,
            token: Token(-1),
            interest: Interest::hup(),
            current_read: RingBuf::new(4096),
            current_write: RingBuf::new(4096),
            next_write: None,
        }
    }

    fn writable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        // Attempt to write data.
        // The `current_write` buffer will be advanced based on how much we wrote.
        match self.stream.write(&mut self.current_write) {
            Ok(None) => {
                // This is a buffer flush. WOULDBLOCK
                self.interest.insert(Interest::writable());
            },
            Ok(Some(r)) => {
                // We managed to write data!
                // TODO: We're *probably* not ready to shoot data again?
                match (self.current_write.has_remaining(), self.next_write.is_some()) {
                    // Need to write more of what we have.
                    (true, _) => (),
                    // Need to roll over.
                    (false, true) => try!(
                        serialize_packed::write_packed_message_unbuffered(&mut self.current_write,
                                                                          self.next_write.as_mut().unwrap())
                    ),
                    // We're done writing for now.
                    (false, false) => self.interest.remove(Interest::writable()),

                }
            },
            Err(e) => panic!("Couldn't write!"),
        }

        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge() | PollOpt::oneshot()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from_error(e)),
        }
    }

    fn readable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        let mut read = 0;
        let from = self.stream.peer_addr().unwrap();
        match self.stream.read(&mut self.current_read) {
            Ok(Some(r)) => {
                // Just read `r` bytes.
                read = r;
            },
            Ok(None) => panic!("We just got readable, but were unable to read from the socket?"),
            Err(e) => panic!("Error on reading."),
        };
        if read > 0 {
            match serialize_packed::new_reader_unbuffered(&mut self.current_read, ReaderOptions::new()) {
                // We have something reasonably interesting in the buffer!
                Ok(reader) => {
                    self.handle_reader(from, reader, event_loop, replica);
                },
                // It's not read entirely yet.
                // Should roll back, pending changes to bytes upstream.
                Err(_) => unimplemented!(),
            }
        }
        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from_error(e)),
        }
    }

    fn handle_reader<S, M>(&mut self, from: SocketAddr, reader: OwnedSpaceMessageReader,
                           event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
    where S: Store, M: StateMachine {
        let mut builder_message = MallocMessageBuilder::new_default();
        let from = self.stream.peer_addr().unwrap();
        if let Ok(request) = reader.get_root::<rpc_request::Reader>() {
            // Because messages are passed asyncronously between Server instances, a Server could
            // get into a situation where multiple events are ready to be dispatched to a single
            // remote Server. In this situation, the Server will replace the existing event with
            // the new event, except in one special circumstance: if the new and existing messages
            // are both AppendEntryRequests with the same term, then the new message will be
            // dropped.
            match request.which().unwrap() {
                // TODO: Move these into replica?
                rpc_request::Which::AppendEntries(Ok(call)) => {
                    let builder = builder_message.init_root::<append_entries_response::Builder>();
                    match replica.append_entries_request(from, call, builder) {
                        Some(Emit) => {
                            // Special Cirsumstance Detection
                            unimplemented!();
                        },
                        None => (),
                    }
                },
                rpc_request::Which::RequestVote(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<request_vote_response::Builder>();
                        replica.request_vote_request(from, call, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            // TODO
                            self.emit(&mut builder_message);
                        },
                        None            => (),
                    }
                },
                _ => unimplemented!(),
            };
        } else if let Ok(response) = reader.get_root::<rpc_response::Reader>() {
            // We won't be responding. This is already a response.
            match response.which().unwrap() {
                rpc_response::Which::AppendEntries(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<append_entries_request::Builder>();
                        replica.append_entries_response(from, call, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            // TODO
                            self.emit(&mut builder_message);
                        },
                        None => (),
                    }
                },
                rpc_response::Which::RequestVote(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<append_entries_request::Builder>();
                        replica.request_vote_response(from, call, builder)
                    };
                    match respond {
                        Some(Broadcast) => {
                            // Won an election!
                            self.broadcast(&mut builder_message);
                        },
                        None => (),
                    }

                },
                _ => unimplemented!(),
            }
        } else if let Ok(client_req) = reader.get_root::<client_request::Reader>() {
            let mut should_die = false;
            // We will be responding.
            match client_req.which().unwrap() {
                client_request::Which::Append(Ok(call)) => {
                    let respond = {
                        let mut builder = builder_message.init_root::<client_response::Builder>();
                        replica.client_append(from, call, builder)
                    };
                    match respond {
                        Some(emit) => {
                            self.emit(&mut builder_message);
                        },
                        None => (),
                    }

                },
                client_request::Which::Die(Ok(call)) => {
                    should_die = true;
                    let mut res = builder_message.init_root::<client_response::Builder>();
                    res.set_success(());
                    self.interest.insert(Interest::writable());
                    debug!("Got a Die request from Client({}). Reason: {}", from, call);
                },
                client_request::Which::LeaderRefresh(()) => {
                    let respond = {
                        let mut builder = builder_message.init_root::<client_response::Builder>();
                        replica.client_leader_refresh(from, builder)
                    };
                    match respond {
                        Some(emit) => {
                            self.emit(&mut builder_message);
                        },
                        None => (),
                    }
                },
                _ => unimplemented!(),
            };

            // Do this here so that we can send the response.
            if should_die {
                panic!("Got a Die request.");
            }

        } else {
            // It's something we don't understand.
            unimplemented!();
        }
    }

    fn broadcast(&self, builder: &mut MallocMessageBuilder) {
        unimplemented!();
    }

    fn emit(&self, builder: &mut MallocMessageBuilder) {
        unimplemented!();
    }
}
<commit_msg>impl emit<commit_after>use std::thread;
use std::collections::HashSet;
use std::net::SocketAddr;
use std::ops::Deref;
use std::io;
use std::error::FromError;

// MIO
use mio::tcp::{listen, TcpListener, TcpStream};
use mio::util::Slab;
use mio::Socket;
use mio::buf::{RingBuf};
use mio::{Interest, PollOpt, NonBlock, Token, EventLoop, Handler, ReadHint};
use mio::buf::Buf;
use mio::{TryRead, TryWrite};

use rand::{self, Rng};

// Data structures.
use store::Store;
use replica::{Replica, Emit, Broadcast};
use state_machine::StateMachine;

// Cap'n Proto
use capnp::serialize_packed;
use capnp::{
    MessageBuilder,
    MessageReader,
    ReaderOptions,
    MallocMessageBuilder,
    Word,
    OwnedSpaceMessageReader,
};
use messages_capnp::{
    rpc_request,
    rpc_response,
    client_request,
    client_response,
    request_vote_response,
    append_entries_response,
    append_entries_request,
};
use super::{Error, Result};

// MIO Tokens
const ELECTION_TIMEOUT: Token = Token(0);
const HEARTBEAT_TIMEOUT: Token = Token(1);
const LISTENER:  Token = Token(2);

const ELECTION_MIN: u64 = 150;
const ELECTION_MAX: u64 = 300;
const HEARTBEAT_DURATION: u64 = 50;

/// The Raft Distributed Consensus Algorithm requires two RPC calls to be available:
///
///   * `append_entries` which is used as both a heartbeat (with no payload) and the primary
///     interface for requests.
///   * `request_vote` which is used by candidates during campaigns to obtain a vote.
///
/// A `Server` acts as a replicated state machine. The server's role in the cluster depends on it's
/// own status. It will maintain both volatile state (which can be safely lost) and persistent
/// state (which must be carefully stored and kept safe).
///
/// Currently, the `Server` API is not well defined. **We are looking for feedback and suggestions.**
pub struct Server<S, M> where S: Store, M: StateMachine {
    replica: Replica<S, M>,
    // Channels and Sockets
    listener: NonBlock<TcpListener>,
    connections: Slab<Connection>,
}

/// The implementation of the Server. In most use cases, creating a `Server` should just be
/// done via `::new()`.
impl<S, M> Server<S, M> where S: Store, M: StateMachine {

    /// Creates a new Raft node with the cluster members specified.
    ///
    /// # Arguments
    ///
    /// * `addr` - The address of the new node.
    /// * `peers` - The address of all peers in the Raft cluster.
    /// * `store` - The persitent log store.
    /// * `state_machine` - The client state machine to which client commands will be applied.
    pub fn spawn(addr: SocketAddr,
                 peers: HashSet<SocketAddr>,
                 store: S,
                 state_machine: M) {
        // Create an event loop
        let mut event_loop = EventLoop::<Server<S, M>>::new().unwrap();
        // Setup the socket, make it not block.
        let listener = listen(&addr).unwrap();
        listener.set_reuseaddr(true);
        event_loop.register(&listener, LISTENER).unwrap();
        let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
        event_loop.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
        event_loop.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION);
        let replica = Replica::new(addr, peers, store, state_machine);
        // Fire up the thread.
        thread::Builder::new().name(format!("Server {}", addr)).spawn(move || {
            let mut raft_node = Server {
                listener: listener,
                replica: replica,
                connections: Slab::new_starting_at(Token(2), 128),
            };
            event_loop.run(&mut raft_node).unwrap();
        }).unwrap();
    }
}

impl<S, M> Handler for Server<S, M> where S: Store, M: StateMachine {

    type Message = ();
    type Timeout = Token;

    /// A registered IoHandle has available writing space.
    fn writable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => unreachable!(),
            tok => {
                self.connections[tok].writable(reactor, &mut self.replica);
            }
        }
    }

    /// A registered IoHandle has available data to read
    fn readable(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token, hint: ReadHint) {
        match token {
            ELECTION_TIMEOUT => unreachable!(),
            HEARTBEAT_TIMEOUT => unreachable!(),
            LISTENER => {
                let stream = self.listener.accept().unwrap().unwrap(); // Result<Option<_>,_>
                let conn = Connection::new(stream);
                let tok = self.connections.insert(conn)
                    .ok().expect("Could not add connection to slab.");

                // Register the connection
                self.connections[tok].token = tok;
                reactor.register_opt(&self.connections[tok].stream, tok, Interest::readable(), PollOpt::edge() | PollOpt::oneshot())
                    .ok().expect("Could not register socket with event loop.");
            },
            tok => {
                self.connections[tok].readable(reactor, &mut self.replica);
            }
        }
    }

    /// A registered timer has expired
    fn timeout(&mut self, reactor: &mut EventLoop<Server<S, M>>, token: Token) {
        let mut message = MallocMessageBuilder::new_default();
        let request = message.init_root::<rpc_request::Builder>();

        match token {
            ELECTION_TIMEOUT => {
                let timeout = rand::thread_rng().gen_range::<u64>(ELECTION_MIN, ELECTION_MAX);
                let _send_message = self.replica.election_timeout(request.init_request_vote());
                reactor.timeout_ms(ELECTION_TIMEOUT, timeout).unwrap();
                // TODO: send messages if necessary
                unimplemented!();
                // self.broadcast(&mut builder_message);
            },
            HEARTBEAT_TIMEOUT => {
                let _send_message = self.replica.heartbeat_timeout(request.init_append_entries());
                reactor.timeout_ms(HEARTBEAT_TIMEOUT, HEARTBEAT_DURATION).unwrap();
                // TODO: send messages if necessary
                unimplemented!();
                // self.broadcast(&mut builder_message);
            },
            _ => unreachable!(),
        }
    }
}

struct Connection {
    stream: NonBlock<TcpStream>,
    token: Token,
    interest: Interest,
    current_read: RingBuf,
    current_write: RingBuf,
    next_write: Option<MallocMessageBuilder>,
}

impl Connection {
    fn new(sock: NonBlock<TcpStream>) -> Connection {
        Connection {
            stream: sock,
            token: Token(-1),
            interest: Interest::hup(),
            current_read: RingBuf::new(4096),
            current_write: RingBuf::new(4096),
            next_write: None,
        }
    }

    fn writable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        // Attempt to write data.
        // The `current_write` buffer will be advanced based on how much we wrote.
        match self.stream.write(&mut self.current_write) {
            Ok(None) => {
                // This is a buffer flush. WOULDBLOCK
                self.interest.insert(Interest::writable());
            },
            Ok(Some(r)) => {
                // We managed to write data!
                // TODO: We're *probably* not ready to shoot data again?
                match (self.current_write.has_remaining(), self.next_write.is_some()) {
                    // Need to write more of what we have.
                    (true, _) => (),
                    // Need to roll over.
                    (false, true) => try!(
                        serialize_packed::write_packed_message_unbuffered(&mut self.current_write,
                                                                          self.next_write.as_mut().unwrap())
                    ),
                    // We're done writing for now.
                    (false, false) => self.interest.remove(Interest::writable()),

                }
            },
            Err(e) => panic!("Couldn't write!"),
        }

        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge() | PollOpt::oneshot()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from_error(e)),
        }
    }

    fn readable<S, M>(&mut self, event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
                      -> Result<()>
    where S: Store, M: StateMachine {
        let mut read = 0;
        let from = self.stream.peer_addr().unwrap();
        match self.stream.read(&mut self.current_read) {
            Ok(Some(r)) => {
                // Just read `r` bytes.
                read = r;
            },
            Ok(None) => panic!("We just got readable, but were unable to read from the socket?"),
            Err(e) => panic!("Error on reading."),
        };
        if read > 0 {
            match serialize_packed::new_reader_unbuffered(&mut self.current_read, ReaderOptions::new()) {
                // We have something reasonably interesting in the buffer!
                Ok(reader) => {
                    self.handle_reader(from, reader, event_loop, replica);
                },
                // It's not read entirely yet.
                // Should roll back, pending changes to bytes upstream.
                Err(_) => unimplemented!(),
            }
        }
        match event_loop.reregister(&self.stream, self.token, self.interest, PollOpt::edge()) {
            Ok(()) => Ok(()),
            Err(e) => Err(Error::from_error(e)),
        }
    }

    fn handle_reader<S, M>(&mut self, from: SocketAddr, reader: OwnedSpaceMessageReader,
                           event_loop: &mut EventLoop<Server<S, M>>, replica: &mut Replica<S,M>)
    where S: Store, M: StateMachine {
        let mut builder_message = MallocMessageBuilder::new_default();
        let from = self.stream.peer_addr().unwrap();
        if let Ok(request) = reader.get_root::<rpc_request::Reader>() {
            match request.which().unwrap() {
                // TODO: Move these into replica?
                rpc_request::Which::AppendEntries(Ok(call)) => {
                    let builder = builder_message.init_root::<append_entries_response::Builder>();
                    match replica.append_entries_request(from, call, builder) {
                        Some(Emit) => {
                            // Special Cirsumstance Detection
                            unimplemented!();
                        },
                        None => (),
                    }
                },
                rpc_request::Which::RequestVote(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<request_vote_response::Builder>();
                        replica.request_vote_request(from, call, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            // TODO
                            self.emit(builder_message);
                        },
                        None            => (),
                    }
                },
                _ => unimplemented!(),
            };
        } else if let Ok(response) = reader.get_root::<rpc_response::Reader>() {
            // We won't be responding. This is already a response.
            match response.which().unwrap() {
                rpc_response::Which::AppendEntries(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<append_entries_request::Builder>();
                        replica.append_entries_response(from, call, builder)
                    };
                    match respond {
                        Some(Emit) => {
                            // TODO
                            self.emit(builder_message);
                        },
                        None => (),
                    }
                },
                rpc_response::Which::RequestVote(Ok(call)) => {
                    let respond = {
                        let builder = builder_message.init_root::<append_entries_request::Builder>();
                        replica.request_vote_response(from, call, builder)
                    };
                    match respond {
                        Some(Broadcast) => {
                            // Won an election!
                            self.broadcast(builder_message);
                        },
                        None => (),
                    }

                },
                _ => unimplemented!(),
            }
        } else if let Ok(client_req) = reader.get_root::<client_request::Reader>() {
            let mut should_die = false;
            // We will be responding.
            match client_req.which().unwrap() {
                client_request::Which::Append(Ok(call)) => {
                    let respond = {
                        let mut builder = builder_message.init_root::<client_response::Builder>();
                        replica.client_append(from, call, builder)
                    };
                    match respond {
                        Some(emit) => {
                            self.emit(builder_message);
                        },
                        None => (),
                    }

                },
                client_request::Which::Die(Ok(call)) => {
                    should_die = true;
                    let mut res = builder_message.init_root::<client_response::Builder>();
                    res.set_success(());
                    self.interest.insert(Interest::writable());
                    debug!("Got a Die request from Client({}). Reason: {}", from, call);
                },
                client_request::Which::LeaderRefresh(()) => {
                    let respond = {
                        let mut builder = builder_message.init_root::<client_response::Builder>();
                        replica.client_leader_refresh(from, builder)
                    };
                    match respond {
                        Some(emit) => {
                            self.emit(builder_message);
                        },
                        None => (),
                    }
                },
                _ => unimplemented!(),
            };

            // Do this here so that we can send the response.
            if should_die {
                panic!("Got a Die request.");
            }

        } else {
            // It's something we don't understand.
            unimplemented!();
        }
    }

    fn broadcast(&mut self, builder: MallocMessageBuilder) {
        unimplemented!();
    }

    /// If applicable, push the new message into `self.next_write`.
    ///
    // Because messages are passed asyncronously between Server instances, a Server could
    // get into a situation where multiple events are ready to be dispatched to a single
    // remote Server. In this situation, the Server will replace the existing event with
    // the new event, except in one special circumstance: if the new and existing messages
    // are both AppendEntryRequests with the same term, then the new message will be
    // dropped.
    fn emit(&mut self, mut builder: MallocMessageBuilder) {
        let overwrite = match self.next_write {
            Some(ref mut next) => {
                let opt_incoming = builder.get_root::<append_entries_request::Builder>();
                let opt_next = next.get_root::<append_entries_request::Builder>();
                match (opt_incoming, opt_next) {
                    (Ok(incoming), Ok(next)) => {
                        if incoming.get_term() == next.get_term() {
                            false
                        } else {
                            true
                        }
                    },
                    _ => true,
                }
            },
            None => true,
        };
        if overwrite {
            self.next_write = Some(builder);
        }
    }
}
<|endoftext|>


<commit_before>use gl;
use gl::types::*;
use gl_context::{GLContext, GLContextExistence};
use std::collections::HashMap;
use std::kinds::marker::ContravariantLifetime;
use std::ptr;
use std::str;

pub struct ProgramHandle<'a> {
  pub gl_id: GLuint,
  pub lifetime: ContravariantLifetime<'a>,
}

impl<'a> ProgramHandle<'a> {
  pub fn new(_gl: &'a GLContextExistence) -> ProgramHandle<'a> {
    let gl_id = unsafe {
      gl::CreateProgram()
    };

    assert!(gl_id != 0);

    ProgramHandle {
      gl_id: gl_id,
      lifetime: ContravariantLifetime,
    }
  }
}

#[unsafe_destructor]
impl<'a> Drop for ProgramHandle<'a> {
  fn drop(&mut self) {
    unsafe {
      gl::DeleteProgram(self.gl_id);
    }
  }
}

pub struct ShaderHandle<'a> {
  pub gl_id: GLuint,
  pub lifetime: ContravariantLifetime<'a>,
}

impl<'a> ShaderHandle<'a> {
  pub fn compile_from(
    _gl: &'a GLContextExistence,
    shader_source: String,
    typ: GLenum
  ) -> ShaderHandle<'a> {
    let gl_id = unsafe {
      gl::CreateShader(typ)
    };

    assert!(gl_id != 0);

    // Attempt to compile the shader
    shader_source.with_c_str(|ptr| unsafe { gl::ShaderSource(gl_id, 1, &ptr, ptr::null()) });
    unsafe {
      gl::CompileShader(gl_id);
    }

    // Get the compile status
    let mut status = gl::FALSE as GLint;
    unsafe {
      gl::GetShaderiv(gl_id, gl::COMPILE_STATUS, &mut status);
    }

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len = 0;
      unsafe {
        gl::GetShaderiv(gl_id, gl::INFO_LOG_LENGTH, &mut len);
      }
      let mut buf = Vec::from_elem(len as uint - 1, 0u8); // subtract 1 to skip the trailing null character
      unsafe {
        gl::GetShaderInfoLog(gl_id, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
      }
      panic!("error compiling 0x{:x} shader: {}", typ, str::from_utf8(buf.as_slice()).expect("ShaderInfoLog not valid utf8"));
    }

    ShaderHandle {
      gl_id: gl_id,
      lifetime: ContravariantLifetime,
    }
  }
}

#[unsafe_destructor]
impl<'a> Drop for ShaderHandle<'a> {
  fn drop(&mut self) {
    unsafe {
      gl::DeleteShader(self.gl_id);
    }
  }
}

pub struct Shader<'a> {
  pub handle: ProgramHandle<'a>,
  pub components: Vec<ShaderHandle<'a>>,
  pub uniforms: HashMap<String, GLint>,
  pub lifetime: ContravariantLifetime<'a>,
}

impl<'a> Shader<'a> {
  pub fn new<T: Iterator<(String, GLenum)>>(
    gl: &'a GLContextExistence,
    shader_components: T,
  ) -> Shader<'a> {
    let mut shader_components = shader_components;
    let handle = ProgramHandle::new(gl);

    let mut components = Vec::new();
    for (content, component) in shader_components {
      let s = ShaderHandle::compile_from(gl, content, component);
      unsafe { gl::AttachShader(handle.gl_id, s.gl_id) };
      components.push(s);
    }

    unsafe {
      gl::LinkProgram(handle.gl_id);
    }

    // Get the link status
    let mut status = gl::FALSE as GLint;
    unsafe {
      gl::GetProgramiv(handle.gl_id, gl::LINK_STATUS, &mut status);
    }

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len: GLint = 0;
      unsafe {
        gl::GetProgramiv(handle.gl_id, gl::INFO_LOG_LENGTH, &mut len);
      }
      let mut buf = Vec::from_elem(len as uint - 1, 0u8); // subtract 1 to skip the trailing null character
      unsafe {
        gl::GetProgramInfoLog(handle.gl_id, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
      }
      panic!("{}", str::from_utf8(buf.as_slice()).expect("ProgramInfoLog not valid utf8"));
    }

    Shader {
      handle: handle,
      components: components,
      uniforms: HashMap::new(),
      lifetime: ContravariantLifetime,
    }
  }

  pub fn use_shader(&self, _gl: &mut GLContext) {
    unsafe {
      gl::UseProgram(self.handle.gl_id)
    }
  }

  pub fn get_uniform_location(
    &mut self,
    name: &'static str,
  ) -> GLint {
    let s_name = String::from_str(name);
    let name = name.to_c_str().as_ptr();
    match self.uniforms.get(&s_name) {
      None => {
        let loc = unsafe {
          gl::GetUniformLocation(self.handle.gl_id, name)
        };
        assert!(loc != -1, "couldn't find shader uniform: {}", s_name);

        self.uniforms.insert(s_name, loc);
        loc
      },
      Some(&loc) => loc,
    }
  }
}
<commit_msg>fix cstr freeing bug in Shader::get_uniform_location<commit_after>use gl;
use gl::types::*;
use gl_context::{GLContext, GLContextExistence};
use std::collections::HashMap;
use std::kinds::marker::ContravariantLifetime;
use std::ptr;
use std::str;

pub struct ProgramHandle<'a> {
  pub gl_id: GLuint,
  pub lifetime: ContravariantLifetime<'a>,
}

impl<'a> ProgramHandle<'a> {
  pub fn new(_gl: &'a GLContextExistence) -> ProgramHandle<'a> {
    let gl_id = unsafe {
      gl::CreateProgram()
    };

    assert!(gl_id != 0);

    ProgramHandle {
      gl_id: gl_id,
      lifetime: ContravariantLifetime,
    }
  }
}

#[unsafe_destructor]
impl<'a> Drop for ProgramHandle<'a> {
  fn drop(&mut self) {
    unsafe {
      gl::DeleteProgram(self.gl_id);
    }
  }
}

pub struct ShaderHandle<'a> {
  pub gl_id: GLuint,
  pub lifetime: ContravariantLifetime<'a>,
}

impl<'a> ShaderHandle<'a> {
  pub fn compile_from(
    _gl: &'a GLContextExistence,
    shader_source: String,
    typ: GLenum
  ) -> ShaderHandle<'a> {
    let gl_id = unsafe {
      gl::CreateShader(typ)
    };

    assert!(gl_id != 0);

    // Attempt to compile the shader
    shader_source.with_c_str(|ptr| unsafe { gl::ShaderSource(gl_id, 1, &ptr, ptr::null()) });
    unsafe {
      gl::CompileShader(gl_id);
    }

    // Get the compile status
    let mut status = gl::FALSE as GLint;
    unsafe {
      gl::GetShaderiv(gl_id, gl::COMPILE_STATUS, &mut status);
    }

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len = 0;
      unsafe {
        gl::GetShaderiv(gl_id, gl::INFO_LOG_LENGTH, &mut len);
      }
      let mut buf = Vec::from_elem(len as uint - 1, 0u8); // subtract 1 to skip the trailing null character
      unsafe {
        gl::GetShaderInfoLog(gl_id, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
      }
      panic!("error compiling 0x{:x} shader: {}", typ, str::from_utf8(buf.as_slice()).expect("ShaderInfoLog not valid utf8"));
    }

    ShaderHandle {
      gl_id: gl_id,
      lifetime: ContravariantLifetime,
    }
  }
}

#[unsafe_destructor]
impl<'a> Drop for ShaderHandle<'a> {
  fn drop(&mut self) {
    unsafe {
      gl::DeleteShader(self.gl_id);
    }
  }
}

pub struct Shader<'a> {
  pub handle: ProgramHandle<'a>,
  pub components: Vec<ShaderHandle<'a>>,
  pub uniforms: HashMap<String, GLint>,
  pub lifetime: ContravariantLifetime<'a>,
}

impl<'a> Shader<'a> {
  pub fn new<T: Iterator<(String, GLenum)>>(
    gl: &'a GLContextExistence,
    mut shader_components: T,
  ) -> Shader<'a> {
    let handle = ProgramHandle::new(gl);

    let mut components = Vec::new();
    for (content, component) in shader_components {
      let s = ShaderHandle::compile_from(gl, content, component);
      unsafe {
        gl::AttachShader(handle.gl_id, s.gl_id);
      }
      components.push(s);
    }

    unsafe {
      gl::LinkProgram(handle.gl_id);
    }

    // Get the link status
    let mut status = gl::FALSE as GLint;
    unsafe {
      gl::GetProgramiv(handle.gl_id, gl::LINK_STATUS, &mut status);
    }

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len: GLint = 0;
      unsafe {
        gl::GetProgramiv(handle.gl_id, gl::INFO_LOG_LENGTH, &mut len);
      }
      let mut buf = Vec::from_elem(len as uint - 1, 0u8); // subtract 1 to skip the trailing null character
      unsafe {
        gl::GetProgramInfoLog(handle.gl_id, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
      }
      panic!("{}", str::from_utf8(buf.as_slice()).expect("ProgramInfoLog not valid utf8"));
    }

    Shader {
      handle: handle,
      components: components,
      uniforms: HashMap::new(),
      lifetime: ContravariantLifetime,
    }
  }

  pub fn use_shader(&self, _gl: &mut GLContext) {
    unsafe {
      gl::UseProgram(self.handle.gl_id)
    }
  }

  pub fn get_uniform_location(
    &mut self,
    name: &'static str,
  ) -> GLint {
    let s_name = String::from_str(name);
    let c_name = name.to_c_str();
    let p_name = c_name.as_ptr();
    match self.uniforms.get(&s_name) {
      None => {
        let loc = unsafe {
          gl::GetUniformLocation(self.handle.gl_id, p_name)
        };
        assert!(loc != -1, "couldn't find shader uniform: {}", s_name);

        self.uniforms.insert(s_name, loc);
        loc
      },
      Some(&loc) => loc,
    }
  }
}
<|endoftext|>