<commit_before>use std::intrinsics::TypeId;
use std::cell::RefCell;
use std::rc::{Rc, Weak};
use std::fmt::{Formatter, Show, Result};
use std::collections::hashmap::HashMap;
use std::any::{Any, AnyRefExt, AnyMutRefExt};
use std::hash::Hash;
use std::hash::sip::SipState;
use std::mem;
use uuid::Uuid;

/// Toplevel container of the entity component system.
pub struct World<T> {
    data: Rc<RefCell<WorldData<T>>>,
}

impl<T> Clone for World<T> {
    fn clone(&self) -> World<T> {
        World { data: self.data.clone() }
    }
}

impl<T: System> World<T> {
    /// Create a world coupled with an application specific system object.
    pub fn new(master_system: T) -> World<T> {
        let ret = World {
            data: Rc::new(RefCell::new(WorldData::new(master_system))),
        };
        ret.data.borrow_mut().master_system.register(&ret);
        ret
    }

    /// Wrap an EntityId struct into an entity handle that has a backreference
    /// to the world object.
    fn wrap(&self, id: EntityId) -> Entity<T> {
        Entity {
            world: self.data.downgrade(),
            id: id
        }
    }

    /// Create a new entity bound to this world.
    pub fn new_entity(&mut self) -> Entity<T> {
        let id = EntityId {
            idx: self.data.borrow_mut().get_idx(),
            uuid: Uuid::new_v4(),
        };
        self.data.borrow_mut().register_new_entity(id);
        let ret = self.wrap(id);
        self.data.borrow_mut().master_system.added(&ret);
        ret
    }

    pub fn delete_entity(&mut self, e: &Entity<T>) {
        self.data.borrow_mut().delete_entity(e);
    }

    pub fn system<'a>(&'a self) -> &'a T {
        unsafe { mem::transmute(&self.data.borrow().master_system) }
    }

    pub fn system_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe { mem::transmute(&self.data.borrow_mut().master_system) }
    }

    pub fn find_entity(&self, uuid: &Uuid) -> Option<Entity<T>> {
        match self.data.borrow().uuids.as_slice().position_elem(&Some(*uuid)) {
            Some(idx) => Some(self.wrap(EntityId { uuid: *uuid, idx: idx })),
            None => None
        }
    }

    /// Return an iterator for the entities. The iterator will not be
    /// invalidated if entities are added or removed during iteration.
    ///
    /// XXX: It is currently unspecified whether entities added during
    /// iteration will show up in the iteration or not.
    pub fn entities(&self) -> Entities<T> {
        Entities {
            idx: 0,
            world: self.data.downgrade(),
        }
    }
}

pub struct Entities<T> {
    idx: uint,
    world: Weak<RefCell<WorldData<T>>>,
}

impl<T> Iterator<Entity<T>> for Entities<T> {
    fn next(&mut self) -> Option<Entity<T>> {
        let w = self.world.upgrade().unwrap();
        loop {
            let uuids = &w.borrow().uuids;
            if self.idx >= uuids.len() { return None; }
            let (idx, uuid) = (self.idx, uuids[self.idx]);
            self.idx += 1;
            match uuid {
                Some(uuid) => return Some(Entity {
                    world: self.world.clone(),
                    id: EntityId {
                        uuid: uuid,
                        idx: idx
                    }
                }),
                _ => ()
            }
        }
    }
}

/// Callback interface for application data connected to the component system
/// world.
pub trait System {
    /// Callback for initially attaching the system to a world.
    fn register(&mut self, world: &World<Self>);
    /// Callback for adding a new entity to world.
    fn added(&mut self, e: &Entity<Self>);
    /// Callback for a component being added or removed in an entity. Note that
    /// this is not called when the data of an existing component is written
    /// to, only if the component is replaced or removed.
    fn changed<C>(&mut self, e: &Entity<Self>, component: Option<&C>);
    /// Callback for an entity being deleted.
    fn deleted(&mut self, e: &Entity<Self>);
}

pub struct Entity<T> {
    world: Weak<RefCell<WorldData<T>>>,
    id: EntityId,
}

impl <T> Hash for Entity<T> {
    fn hash(&self, state: &mut SipState) {
        self.id.hash(state);
    }
}

impl <T> PartialEq for Entity<T> {
    fn eq(&self, other: &Entity<T>) -> bool {
        self.id.eq(&other.id)
    }
}

impl <T> Eq for Entity<T> {}

impl<T> Clone for Entity<T> {
    fn clone(&self) -> Entity<T> {
        Entity { world: self.world.clone(), id: self.id }
    }
}

impl<T> Show for Entity<T> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}", self.id)
    }
}

impl<T: System> Entity<T> {
    /// Add or reset a component in the entity. Causes a "changed" call to the
    /// world system.
    pub fn set_component<C: 'static+Clone>(&mut self, comp: C) {
        self.world.upgrade().unwrap().borrow_mut().deref_mut()
            .set_component(self, Some(comp));
    }

    /// Remove a component from the entity. Causes a "changed" call to the
    /// world system.
    pub fn remove_component<C: 'static+Clone>(&mut self) {
        let comp : Option<C> = None;
        self.world.upgrade().unwrap().borrow_mut().deref_mut()
            .set_component(self, comp);
    }

    /// Delete the entity from the world. Causes a "deleted" call to the world
    /// system.
    pub fn delete(&mut self) {
        self.world.upgrade().unwrap().borrow_mut().deref_mut()
            .delete_entity(self);
    }

    /// Query whether the entity has a type of component.
    pub fn has<'a, C: 'static>(&self) -> bool {
        self.world.upgrade().unwrap().borrow()
            .comp_ref::<'a, C>(self.id).is_some()
    }

    /// Get an access proxy to the entity's component if the entity has that
    /// component.
    pub fn into<C: 'static>(&self) -> Option<CompProxyMut<T, C>> {
        if self.has::<C>() {
            Some(CompProxyMut {
                world: self.world.clone(),
                id: self.id
            })
        } else {
            None
        }
    }

    /// Return unique identifier for this entity.
    pub fn uuid(&self) -> Uuid {
        self.id.uuid
    }

    /// Return a handle to the world.
    pub fn world(&self) -> World<T> {
        World { data: self.world.upgrade().unwrap() }
    }
}

/// Access proxy to entity components. The implementation RefCell (mutable)
/// borrow internally, so using this carelessly may lead to runtime borrow
/// errors. You should generally keep access to the concrete entity data short
/// in scope and low in the call stack to prevent unexpected borrow failures.
pub struct CompProxyMut<T, C> {
    world: Weak<RefCell<WorldData<T>>>,
    id: EntityId,
}

impl<T: System, C: 'static> Deref<C> for CompProxyMut<T, C> {
    fn deref<'a>(&'a self) -> &'a C {
        self.world.upgrade().unwrap().borrow()
            .comp_ref::<'a, C>(self.id).unwrap()
    }
}

impl<T: System, C: 'static> DerefMut<C> for CompProxyMut<T, C> {
    fn deref_mut<'a>(&'a mut self) -> &'a mut C {
        self.world.upgrade().unwrap().borrow_mut()
            .comp_ref_mut::<'a, C>(self.id).unwrap()
    }
}

#[deriving(PartialEq, Clone, Hash, Show)]
struct EntityId {
    uuid: Uuid,
    idx: uint,
}

struct WorldData<T> {
    // XXX: This is much less efficient than it could be. A serious
    // implementation would use unboxed vecs for the components and would
    // provide lookup methods faster than a HashMap find to access the
    // components
    components: HashMap<TypeId, Vec<Option<Box<Any>>>>,

    next_idx: uint,
    reusable_idxs: Vec<uint>,
    uuids: Vec<Option<Uuid>>,

    master_system: T,
}

impl<T: System> WorldData<T> {
    fn new(master_system: T) -> WorldData<T> {
        WorldData {
            components: HashMap::new(),
            next_idx: 0,
            reusable_idxs: vec!(),
            uuids: vec!(),
            master_system: master_system,
        }
    }

    fn register_new_entity(&mut self, id: EntityId) {
        assert!(self.uuids.len() <= id.idx || self.uuids[id.idx].is_none(),
            "New entity clobbering existing one");

        self.uuids.grow_set(id.idx, &None, Some(id.uuid));
    }

    fn delete_entity(&mut self, e: &Entity<T>) {
        self.uuids.as_mut_slice()[e.id.idx] = None;

        for (_, c) in self.components.mut_iter() {
            if c.len() > e.id.idx {
                c.as_mut_slice()[e.id.idx] = None;
            }
        }

        self.reusable_idxs.push(e.id.idx);

        self.master_system.deleted(e);
    }

    /// Return the next unused reusable entity id.
    fn get_idx(&mut self) -> uint {
        match self.reusable_idxs.pop() {
            None => {
                let ret = self.next_idx;
                self.next_idx += 1;
                ret
            }
            Some(idx) => idx
        }
    }

    fn set_component<C: 'static+Clone>(&mut self, e: &Entity<T>, comp: Option<C>) {
        let type_id = TypeId::of::<C>();
        // We haven't seen this kind of component yet.
        if !self.components.contains_key(&type_id) {
            self.components.insert(type_id, vec!());
        }

        let bin = self.components.find_mut(&type_id).unwrap();

        // XXX: grow_set didn't work.
        while bin.len() <= e.id.idx { bin.push(None); }
        bin.as_mut_slice()[e.id.idx] = match comp {
            None => None,
            Some(c) => Some(box c as Box<Any>),
        };

        match bin.as_mut_slice()[e.id.idx] {
            None => self.master_system.changed::<C>(e, None),
            Some(ref c) => self.master_system.changed(e, Some(&c)),
        };
    }

    fn comp_ref<'a, C: 'static>(
        &self, id: EntityId) -> Option<&'a C> {
        let type_id = TypeId::of::<C>();
        match self.components.find(&type_id) {
            None => { None }
            Some(bin) => {
                if id.idx < bin.len() {
                    match bin.get(id.idx) {
                        &Some(ref c) => { unsafe { Some(mem::transmute(c.as_ref::<C>().unwrap())) } }
                        &None => None
                    }
                } else {
                    None
                }
            }
        }
    }

    fn comp_ref_mut<'a, C: 'static>(
        &mut self, id: EntityId) -> Option<&'a mut C> {
        let type_id = TypeId::of::<C>();
        match self.components.find_mut(&type_id) {
            None => { None }
            Some(bin) => {
                if id.idx < bin.len() {
                    match bin.get_mut(id.idx) {
                        &Some(ref mut c) => {
                            unsafe { Some(mem::transmute(c.as_mut::<C>().unwrap())) }
                        }
                        &None => None
                    }
                } else {
                    None
                }
            }
        }
    }
}

<commit_msg>Doc comment about 'static components<commit_after>use std::intrinsics::TypeId;
use std::cell::RefCell;
use std::rc::{Rc, Weak};
use std::fmt::{Formatter, Show, Result};
use std::collections::hashmap::HashMap;
use std::any::{Any, AnyRefExt, AnyMutRefExt};
use std::hash::Hash;
use std::hash::sip::SipState;
use std::mem;
use uuid::Uuid;

/// Toplevel container of the entity component system.
pub struct World<T> {
    data: Rc<RefCell<WorldData<T>>>,
}

impl<T> Clone for World<T> {
    fn clone(&self) -> World<T> {
        World { data: self.data.clone() }
    }
}

impl<T: System> World<T> {
    /// Create a world coupled with an application specific system object.
    pub fn new(master_system: T) -> World<T> {
        let ret = World {
            data: Rc::new(RefCell::new(WorldData::new(master_system))),
        };
        ret.data.borrow_mut().master_system.register(&ret);
        ret
    }

    /// Wrap an EntityId struct into an entity handle that has a backreference
    /// to the world object.
    fn wrap(&self, id: EntityId) -> Entity<T> {
        Entity {
            world: self.data.downgrade(),
            id: id
        }
    }

    /// Create a new entity bound to this world.
    pub fn new_entity(&mut self) -> Entity<T> {
        let id = EntityId {
            idx: self.data.borrow_mut().get_idx(),
            uuid: Uuid::new_v4(),
        };
        self.data.borrow_mut().register_new_entity(id);
        let ret = self.wrap(id);
        self.data.borrow_mut().master_system.added(&ret);
        ret
    }

    pub fn delete_entity(&mut self, e: &Entity<T>) {
        self.data.borrow_mut().delete_entity(e);
    }

    pub fn system<'a>(&'a self) -> &'a T {
        unsafe { mem::transmute(&self.data.borrow().master_system) }
    }

    pub fn system_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe { mem::transmute(&self.data.borrow_mut().master_system) }
    }

    pub fn find_entity(&self, uuid: &Uuid) -> Option<Entity<T>> {
        match self.data.borrow().uuids.as_slice().position_elem(&Some(*uuid)) {
            Some(idx) => Some(self.wrap(EntityId { uuid: *uuid, idx: idx })),
            None => None
        }
    }

    /// Return an iterator for the entities. The iterator will not be
    /// invalidated if entities are added or removed during iteration.
    ///
    /// XXX: It is currently unspecified whether entities added during
    /// iteration will show up in the iteration or not.
    pub fn entities(&self) -> Entities<T> {
        Entities {
            idx: 0,
            world: self.data.downgrade(),
        }
    }
}

pub struct Entities<T> {
    idx: uint,
    world: Weak<RefCell<WorldData<T>>>,
}

impl<T> Iterator<Entity<T>> for Entities<T> {
    fn next(&mut self) -> Option<Entity<T>> {
        let w = self.world.upgrade().unwrap();
        loop {
            let uuids = &w.borrow().uuids;
            if self.idx >= uuids.len() { return None; }
            let (idx, uuid) = (self.idx, uuids[self.idx]);
            self.idx += 1;
            match uuid {
                Some(uuid) => return Some(Entity {
                    world: self.world.clone(),
                    id: EntityId {
                        uuid: uuid,
                        idx: idx
                    }
                }),
                _ => ()
            }
        }
    }
}

/// Callback interface for application data connected to the component system
/// world.
pub trait System {
    /// Callback for initially attaching the system to a world.
    fn register(&mut self, world: &World<Self>);
    /// Callback for adding a new entity to world.
    fn added(&mut self, e: &Entity<Self>);
    /// Callback for a component being added or removed in an entity. Note that
    /// this is not called when the data of an existing component is written
    /// to, only if the component is replaced or removed.
    fn changed<C>(&mut self, e: &Entity<Self>, component: Option<&C>);
    /// Callback for an entity being deleted.
    fn deleted(&mut self, e: &Entity<Self>);
}

pub struct Entity<T> {
    world: Weak<RefCell<WorldData<T>>>,
    id: EntityId,
}

impl <T> Hash for Entity<T> {
    fn hash(&self, state: &mut SipState) {
        self.id.hash(state);
    }
}

impl <T> PartialEq for Entity<T> {
    fn eq(&self, other: &Entity<T>) -> bool {
        self.id.eq(&other.id)
    }
}

impl <T> Eq for Entity<T> {}

impl<T> Clone for Entity<T> {
    fn clone(&self) -> Entity<T> {
        Entity { world: self.world.clone(), id: self.id }
    }
}

impl<T> Show for Entity<T> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}", self.id)
    }
}

impl<T: System> Entity<T> {
    /// Add or reset a component in the entity. Causes a "changed" call to the
    /// world system.
    ///
    /// Due to the system used to identify components, the component type
    /// needs to be a 'static one that doesn't include any reference values.
    /// Components are generally expected to be very plain data, like a
    /// database record.
    pub fn set_component<C: 'static+Clone>(&mut self, comp: C) {
        self.world.upgrade().unwrap().borrow_mut().deref_mut()
            .set_component(self, Some(comp));
    }

    /// Remove a component from the entity. Causes a "changed" call to the
    /// world system.
    pub fn remove_component<C: 'static+Clone>(&mut self) {
        let comp : Option<C> = None;
        self.world.upgrade().unwrap().borrow_mut().deref_mut()
            .set_component(self, comp);
    }

    /// Delete the entity from the world. Causes a "deleted" call to the world
    /// system.
    pub fn delete(&mut self) {
        self.world.upgrade().unwrap().borrow_mut().deref_mut()
            .delete_entity(self);
    }

    /// Query whether the entity has a type of component.
    pub fn has<'a, C: 'static>(&self) -> bool {
        self.world.upgrade().unwrap().borrow()
            .comp_ref::<'a, C>(self.id).is_some()
    }

    /// Get an access proxy to the entity's component if the entity has that
    /// component.
    pub fn into<C: 'static>(&self) -> Option<CompProxyMut<T, C>> {
        if self.has::<C>() {
            Some(CompProxyMut {
                world: self.world.clone(),
                id: self.id
            })
        } else {
            None
        }
    }

    /// Return unique identifier for this entity.
    pub fn uuid(&self) -> Uuid {
        self.id.uuid
    }

    /// Return a handle to the world.
    pub fn world(&self) -> World<T> {
        World { data: self.world.upgrade().unwrap() }
    }
}

/// Access proxy to entity components. The implementation RefCell (mutable)
/// borrow internally, so using this carelessly may lead to runtime borrow
/// errors. You should generally keep access to the concrete entity data short
/// in scope and low in the call stack to prevent unexpected borrow failures.
pub struct CompProxyMut<T, C> {
    world: Weak<RefCell<WorldData<T>>>,
    id: EntityId,
}

impl<T: System, C: 'static> Deref<C> for CompProxyMut<T, C> {
    fn deref<'a>(&'a self) -> &'a C {
        self.world.upgrade().unwrap().borrow()
            .comp_ref::<'a, C>(self.id).unwrap()
    }
}

impl<T: System, C: 'static> DerefMut<C> for CompProxyMut<T, C> {
    fn deref_mut<'a>(&'a mut self) -> &'a mut C {
        self.world.upgrade().unwrap().borrow_mut()
            .comp_ref_mut::<'a, C>(self.id).unwrap()
    }
}

#[deriving(PartialEq, Clone, Hash, Show)]
struct EntityId {
    uuid: Uuid,
    idx: uint,
}

struct WorldData<T> {
    // XXX: This is much less efficient than it could be. A serious
    // implementation would use unboxed vecs for the components and would
    // provide lookup methods faster than a HashMap find to access the
    // components
    components: HashMap<TypeId, Vec<Option<Box<Any>>>>,

    next_idx: uint,
    reusable_idxs: Vec<uint>,
    uuids: Vec<Option<Uuid>>,

    master_system: T,
}

impl<T: System> WorldData<T> {
    fn new(master_system: T) -> WorldData<T> {
        WorldData {
            components: HashMap::new(),
            next_idx: 0,
            reusable_idxs: vec!(),
            uuids: vec!(),
            master_system: master_system,
        }
    }

    fn register_new_entity(&mut self, id: EntityId) {
        assert!(self.uuids.len() <= id.idx || self.uuids[id.idx].is_none(),
            "New entity clobbering existing one");

        self.uuids.grow_set(id.idx, &None, Some(id.uuid));
    }

    fn delete_entity(&mut self, e: &Entity<T>) {
        self.uuids.as_mut_slice()[e.id.idx] = None;

        for (_, c) in self.components.mut_iter() {
            if c.len() > e.id.idx {
                c.as_mut_slice()[e.id.idx] = None;
            }
        }

        self.reusable_idxs.push(e.id.idx);

        self.master_system.deleted(e);
    }

    /// Return the next unused reusable entity id.
    fn get_idx(&mut self) -> uint {
        match self.reusable_idxs.pop() {
            None => {
                let ret = self.next_idx;
                self.next_idx += 1;
                ret
            }
            Some(idx) => idx
        }
    }

    fn set_component<C: 'static+Clone>(&mut self, e: &Entity<T>, comp: Option<C>) {
        let type_id = TypeId::of::<C>();
        // We haven't seen this kind of component yet.
        if !self.components.contains_key(&type_id) {
            self.components.insert(type_id, vec!());
        }

        let bin = self.components.find_mut(&type_id).unwrap();

        // XXX: grow_set didn't work.
        while bin.len() <= e.id.idx { bin.push(None); }
        bin.as_mut_slice()[e.id.idx] = match comp {
            None => None,
            Some(c) => Some(box c as Box<Any>),
        };

        match bin.as_mut_slice()[e.id.idx] {
            None => self.master_system.changed::<C>(e, None),
            Some(ref c) => self.master_system.changed(e, Some(&c)),
        };
    }

    fn comp_ref<'a, C: 'static>(
        &self, id: EntityId) -> Option<&'a C> {
        let type_id = TypeId::of::<C>();
        match self.components.find(&type_id) {
            None => { None }
            Some(bin) => {
                if id.idx < bin.len() {
                    match bin.get(id.idx) {
                        &Some(ref c) => { unsafe { Some(mem::transmute(c.as_ref::<C>().unwrap())) } }
                        &None => None
                    }
                } else {
                    None
                }
            }
        }
    }

    fn comp_ref_mut<'a, C: 'static>(
        &mut self, id: EntityId) -> Option<&'a mut C> {
        let type_id = TypeId::of::<C>();
        match self.components.find_mut(&type_id) {
            None => { None }
            Some(bin) => {
                if id.idx < bin.len() {
                    match bin.get_mut(id.idx) {
                        &Some(ref mut c) => {
                            unsafe { Some(mem::transmute(c.as_mut::<C>().unwrap())) }
                        }
                        &None => None
                    }
                } else {
                    None
                }
            }
        }
    }
}

<|endoftext|>


<commit_before>// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Basic test for liveness constraints: the region (`R1`) that appears
// in the type of `p` includes the points after `&v[0]` up to (but not
// including) the call to `use_x`. The `else` branch is not included.

// compile-flags:-Zborrowck-mir -Znll

#![allow(warnings)]
#![feature(rustc_attrs)]

struct MyStruct {
    field: String
}

fn main() {
    let mut my_struct = MyStruct { field: format!("Hello") };

    let value = &my_struct.field;
    if value.is_empty() {
        my_struct.field.push_str("Hello, world!");
        //~^ ERROR cannot borrow (Ast)
    }
}
<commit_msg>WIP patch `compile-fail/nll/region-ends-after-if-condition.rs`<commit_after>// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Basic test for liveness constraints: the region (`R1`) that appears
// in the type of `p` includes the points after `&v[0]` up to (but not
// including) the call to `use_x`. The `else` branch is not included.

// compile-flags:-Zborrowck-mir -Znll

#![allow(warnings)]
#![feature(rustc_attrs)]

struct MyStruct {
    field: String
}

fn foo1() {
    let mut my_struct = MyStruct { field: format!("Hello") };

    let value = &my_struct.field;
    if value.is_empty() {
        my_struct.field.push_str("Hello, world!");
        //~^ ERROR (Ast) [E0502]
    }
}

fn foo2() {
    let mut my_struct = MyStruct { field: format!("Hello") };

    let value = &my_struct.field;
    if value.is_empty() {
        my_struct.field.push_str("Hello, world!");
        //~^ ERROR (Ast) [E0502]
        //~| ERROR (Mir) [E0502]
    }
    drop(value);
}

fn main() { }
<|endoftext|>


<commit_before>//! ## Summary
//! One of cita's main core components is to execute transaction,
//! create contracts, maintain world state trees, and send executed
//! result block to chain.
//!
//! ### Message queuing situation
//!
//! 1. Subscribe channel
//!
//!     | Queue    | PubModule | Message Type       |
//!     | -------- | --------- | ------------------ |
//!     | executor | Chain     | Request            |
//!     | executor | Chain     | Richstatus         |
//!     | executor | Consensus | BlockWithProof     |
//!     | executor | Consensus | SignedProposal     |
//!     | executor | Consensus | MiscellaneousReq   |
//!     | executor | Net       | SyncResponse       |
//!     | executor | Net       | SignedProposal     |
//!     | executor | Snapshot  | SnapshotReq        |
//!
//! 2. Publish channel
//!
//!     | Queue    | PubModule | SubModule | Message Type   |
//!     | -------- | --------- | --------- | -------------- |
//!     | executor | Executor  | Snapshot  | SnapshotResp   |
//!     | executor | Executor  | Jsonrpc   | Response       |
//!     | executor | Executor  | Chain     | ExecutedResult |
//!     | executor | Executor  | Auth      | Miscellaneous  |
//!     | executor | Executor  | Auth      | BlackList      |
//!
//! ### Key behavior
//!
//! key struct:
//!
//! - `ExecutorInstance`: `executor_instance::ExecutorInstance`
//! - [`Executor`]
//! - [`GlobalSysConfig`]
//! - [`Genesis`]
//! - [`Contract`]
//! - [`Account`]
//! - `AccountEntry`: `core_executor::state::AccountEntry`
//! - [`State`]
//! - [`StateDB`]
//!
//! This is currently the most complex module that maintains the current state of
//! the entire chain and caches some data, keeps the hash values of the last 256
//! blocks and the information of each block (gas_limit/quota, etc.) in memory,
//! holds the current block map(heigh, block).
//!
//! Of course there is an evm interface in this module.
//!
//! The contract/transaction submission is first cached in memory before being committed
//! to the stateDB (disk).
//!
//! [`Executor`]: ../core_executor/libexecutor/executor/struct.Executor.html
//! [`GlobalSysConfig`]: ../core_executor/libexecutor/executor/struct.GlobalSysConfig.html
//! [`Genesis`]: ../core_executor/libexecutor/genesis/struct.Genesis.html
//! [`Contract`]: ../core_executor/libexecutor/genesis/struct.Contract.html
//! [`Account`]: ../core_executor/state/account/struct.Account.html
//! [`State`]: ../core_executor/state/struct.State.html
//! [`StateDB`]: ../core_executor/state_db/struct.StateDB.html
//!

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![feature(custom_attribute)]
#![allow(deprecated, unused_must_use, unused_mut, unused_assignments)]
#![feature(refcell_replace_swap)]
#![feature(try_from)]
extern crate bincode;
extern crate cita_types;
extern crate clap;
extern crate common_types as types;
extern crate core_executor as core;
extern crate dotenv;
extern crate error;
extern crate grpc;
extern crate jsonrpc_types;
#[macro_use]
extern crate libproto;
#[macro_use]
extern crate logger;
extern crate proof;
extern crate pubsub;
extern crate serde_json;
#[macro_use]
extern crate util;

mod executor_instance;

use clap::App;
use core::libexecutor::{vm_grpc_server, ServiceMap};
use executor_instance::ExecutorInstance;
use libproto::router::{MsgType, RoutingKey, SubModules};
use pubsub::start_pubsub;
use std::sync::mpsc::channel;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use util::set_panic_handler;

include!(concat!(env!("OUT_DIR"), "/build_info.rs"));

fn main() {
    micro_service_init!("cita-executor", "CITA:executor");
    info!("Version: {}", get_build_info_str(true));

    let matches = App::new("executor")
        .version(get_build_info_str(true))
        .long_version(get_build_info_str(false))
        .author("Cryptape")
        .about("CITA Block Chain Node powered by Rust")
        .arg_from_usage("-g, --genesis=[FILE] 'Sets a genesis config file")
        .arg_from_usage("-c, --config=[FILE] 'Sets a switch config file'")
        .get_matches();

    let genesis_path = matches.value_of("genesis").unwrap_or("genesis.json");

    let config_path = matches.value_of("config").unwrap_or("executor.toml");

    let (tx, rx) = channel();
    let (ctx_pub, crx_pub) = channel();
    let (write_sender, write_receiver) = channel();
    start_pubsub(
        "executor",
        routing_key!([
            Consensus >> BlockWithProof,
            Chain >> Request,
            Chain >> RichStatus,
            Consensus >> SignedProposal,
            Net >> SyncResponse,
            Net >> SignedProposal,
            Snapshot >> SnapshotReq,
            Auth >> MiscellaneousReq,
        ]),
        tx,
        crx_pub,
    );

    let service_map = Arc::new(ServiceMap::new());
    let mut ext_instance = ExecutorInstance::new(
        ctx_pub.clone(),
        write_sender,
        config_path,
        genesis_path,
        Arc::clone(&service_map),
    );
    let mut distribute_ext = ext_instance.clone();

    thread::spawn(move || loop {
        if let Ok((key, msg)) = rx.recv() {
            distribute_ext.distribute_msg(&key, &msg);
        }
    });
    let mut server: Option<::grpc::Server> = None;
    let grpc_ext = ext_instance.clone();
    thread::spawn(move || loop {
        if server.is_none() {
            server = vm_grpc_server(
                grpc_ext.grpc_port,
                Arc::clone(&service_map),
                Arc::clone(&grpc_ext.ext),
            );
        } else {
            thread::sleep(Duration::new(8, 0));
        }
    });

    let mut timeout_factor = 0u8;
    loop {
        if let Ok(number) =
            write_receiver.recv_timeout(Duration::new(18 * (2u64.pow(timeout_factor as u32)), 0))
        {
            ext_instance.execute_block(number);
            timeout_factor = 0;
        } else {
            for height in ext_instance.ext.executed_result.read().keys() {
                ext_instance
                    .ext
                    .send_executed_info_to_chain(*height, &ctx_pub);
            }
            if timeout_factor < 6 {
                timeout_factor += 1
            }
        }
    }
}
<commit_msg>sort the order of receiving msg types.<commit_after>//! ## Summary
//! One of cita's main core components is to execute transaction,
//! create contracts, maintain world state trees, and send executed
//! result block to chain.
//!
//! ### Message queuing situation
//!
//! 1. Subscribe channel
//!
//!     | Queue    | PubModule | Message Type       |
//!     | -------- | --------- | ------------------ |
//!     | executor | Chain     | Request            |
//!     | executor | Chain     | Richstatus         |
//!     | executor | Consensus | BlockWithProof     |
//!     | executor | Consensus | SignedProposal     |
//!     | executor | Consensus | MiscellaneousReq   |
//!     | executor | Net       | SyncResponse       |
//!     | executor | Net       | SignedProposal     |
//!     | executor | Snapshot  | SnapshotReq        |
//!
//! 2. Publish channel
//!
//!     | Queue    | PubModule | SubModule | Message Type   |
//!     | -------- | --------- | --------- | -------------- |
//!     | executor | Executor  | Snapshot  | SnapshotResp   |
//!     | executor | Executor  | Jsonrpc   | Response       |
//!     | executor | Executor  | Chain     | ExecutedResult |
//!     | executor | Executor  | Auth      | Miscellaneous  |
//!     | executor | Executor  | Auth      | BlackList      |
//!
//! ### Key behavior
//!
//! key struct:
//!
//! - `ExecutorInstance`: `executor_instance::ExecutorInstance`
//! - [`Executor`]
//! - [`GlobalSysConfig`]
//! - [`Genesis`]
//! - [`Contract`]
//! - [`Account`]
//! - `AccountEntry`: `core_executor::state::AccountEntry`
//! - [`State`]
//! - [`StateDB`]
//!
//! This is currently the most complex module that maintains the current state of
//! the entire chain and caches some data, keeps the hash values of the last 256
//! blocks and the information of each block (gas_limit/quota, etc.) in memory,
//! holds the current block map(heigh, block).
//!
//! Of course there is an evm interface in this module.
//!
//! The contract/transaction submission is first cached in memory before being committed
//! to the stateDB (disk).
//!
//! [`Executor`]: ../core_executor/libexecutor/executor/struct.Executor.html
//! [`GlobalSysConfig`]: ../core_executor/libexecutor/executor/struct.GlobalSysConfig.html
//! [`Genesis`]: ../core_executor/libexecutor/genesis/struct.Genesis.html
//! [`Contract`]: ../core_executor/libexecutor/genesis/struct.Contract.html
//! [`Account`]: ../core_executor/state/account/struct.Account.html
//! [`State`]: ../core_executor/state/struct.State.html
//! [`StateDB`]: ../core_executor/state_db/struct.StateDB.html
//!

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![feature(custom_attribute)]
#![allow(deprecated, unused_must_use, unused_mut, unused_assignments)]
#![feature(refcell_replace_swap)]
#![feature(try_from)]
extern crate bincode;
extern crate cita_types;
extern crate clap;
extern crate common_types as types;
extern crate core_executor as core;
extern crate dotenv;
extern crate error;
extern crate grpc;
extern crate jsonrpc_types;
#[macro_use]
extern crate libproto;
#[macro_use]
extern crate logger;
extern crate proof;
extern crate pubsub;
extern crate serde_json;
#[macro_use]
extern crate util;

mod executor_instance;

use clap::App;
use core::libexecutor::{vm_grpc_server, ServiceMap};
use executor_instance::ExecutorInstance;
use libproto::router::{MsgType, RoutingKey, SubModules};
use pubsub::start_pubsub;
use std::sync::mpsc::channel;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use util::set_panic_handler;

include!(concat!(env!("OUT_DIR"), "/build_info.rs"));

fn main() {
    micro_service_init!("cita-executor", "CITA:executor");
    info!("Version: {}", get_build_info_str(true));

    let matches = App::new("executor")
        .version(get_build_info_str(true))
        .long_version(get_build_info_str(false))
        .author("Cryptape")
        .about("CITA Block Chain Node powered by Rust")
        .arg_from_usage("-g, --genesis=[FILE] 'Sets a genesis config file")
        .arg_from_usage("-c, --config=[FILE] 'Sets a switch config file'")
        .get_matches();

    let genesis_path = matches.value_of("genesis").unwrap_or("genesis.json");

    let config_path = matches.value_of("config").unwrap_or("executor.toml");

    let (tx, rx) = channel();
    let (ctx_pub, crx_pub) = channel();
    let (write_sender, write_receiver) = channel();
    start_pubsub(
        "executor",
        routing_key!([
            Chain >> Request,
            Chain >> RichStatus,
            Consensus >> BlockWithProof,
            Consensus >> SignedProposal,
            Net >> SyncResponse,
            Net >> SignedProposal,
            Snapshot >> SnapshotReq,
            Auth >> MiscellaneousReq,
        ]),
        tx,
        crx_pub,
    );

    let service_map = Arc::new(ServiceMap::new());
    let mut ext_instance = ExecutorInstance::new(
        ctx_pub.clone(),
        write_sender,
        config_path,
        genesis_path,
        Arc::clone(&service_map),
    );
    let mut distribute_ext = ext_instance.clone();

    thread::spawn(move || loop {
        if let Ok((key, msg)) = rx.recv() {
            distribute_ext.distribute_msg(&key, &msg);
        }
    });
    let mut server: Option<::grpc::Server> = None;
    let grpc_ext = ext_instance.clone();
    thread::spawn(move || loop {
        if server.is_none() {
            server = vm_grpc_server(
                grpc_ext.grpc_port,
                Arc::clone(&service_map),
                Arc::clone(&grpc_ext.ext),
            );
        } else {
            thread::sleep(Duration::new(8, 0));
        }
    });

    let mut timeout_factor = 0u8;
    loop {
        if let Ok(number) =
            write_receiver.recv_timeout(Duration::new(18 * (2u64.pow(timeout_factor as u32)), 0))
        {
            ext_instance.execute_block(number);
            timeout_factor = 0;
        } else {
            for height in ext_instance.ext.executed_result.read().keys() {
                ext_instance
                    .ext
                    .send_executed_info_to_chain(*height, &ctx_pub);
            }
            if timeout_factor < 6 {
                timeout_factor += 1
            }
        }
    }
}
<|endoftext|>


<commit_before>//! See `AssistContext`

use algo::find_covering_element;
use hir::Semantics;
use ra_db::{FileId, FileRange};
use ra_fmt::{leading_indent, reindent};
use ra_ide_db::{
    source_change::{SingleFileChange, SourceChange},
    RootDatabase,
};
use ra_syntax::{
    algo::{self, find_node_at_offset, SyntaxRewriter},
    AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize,
    TokenAtOffset,
};
use ra_text_edit::TextEditBuilder;

use crate::{Assist, AssistId, GroupLabel, ResolvedAssist};

/// `AssistContext` allows to apply an assist or check if it could be applied.
///
/// Assists use a somewhat over-engineered approach, given the current needs.
/// The assists workflow consists of two phases. In the first phase, a user asks
/// for the list of available assists. In the second phase, the user picks a
/// particular assist and it gets applied.
///
/// There are two peculiarities here:
///
/// * first, we ideally avoid computing more things then necessary to answer "is
///   assist applicable" in the first phase.
/// * second, when we are applying assist, we don't have a guarantee that there
///   weren't any changes between the point when user asked for assists and when
///   they applied a particular assist. So, when applying assist, we need to do
///   all the checks from scratch.
///
/// To avoid repeating the same code twice for both "check" and "apply"
/// functions, we use an approach reminiscent of that of Django's function based
/// views dealing with forms. Each assist receives a runtime parameter,
/// `resolve`. It first check if an edit is applicable (potentially computing
/// info required to compute the actual edit). If it is applicable, and
/// `resolve` is `true`, it then computes the actual edit.
///
/// So, to implement the original assists workflow, we can first apply each edit
/// with `resolve = false`, and then applying the selected edit again, with
/// `resolve = true` this time.
///
/// Note, however, that we don't actually use such two-phase logic at the
/// moment, because the LSP API is pretty awkward in this place, and it's much
/// easier to just compute the edit eagerly :-)
pub(crate) struct AssistContext<'a> {
    pub(crate) sema: Semantics<'a, RootDatabase>,
    pub(super) db: &'a RootDatabase,
    pub(crate) frange: FileRange,
    source_file: SourceFile,
}

impl<'a> AssistContext<'a> {
    pub fn new(sema: Semantics<'a, RootDatabase>, frange: FileRange) -> AssistContext<'a> {
        let source_file = sema.parse(frange.file_id);
        let db = sema.db;
        AssistContext { sema, db, frange, source_file }
    }

    // NB, this ignores active selection.
    pub(crate) fn offset(&self) -> TextSize {
        self.frange.range.start()
    }

    pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> {
        self.source_file.syntax().token_at_offset(self.offset())
    }
    pub(crate) fn find_token_at_offset(&self, kind: SyntaxKind) -> Option<SyntaxToken> {
        self.token_at_offset().find(|it| it.kind() == kind)
    }
    pub(crate) fn find_node_at_offset<N: AstNode>(&self) -> Option<N> {
        find_node_at_offset(self.source_file.syntax(), self.offset())
    }
    pub(crate) fn find_node_at_offset_with_descend<N: AstNode>(&self) -> Option<N> {
        self.sema.find_node_at_offset_with_descend(self.source_file.syntax(), self.offset())
    }
    pub(crate) fn covering_element(&self) -> SyntaxElement {
        find_covering_element(self.source_file.syntax(), self.frange.range)
    }
    // FIXME: remove
    pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement {
        find_covering_element(self.source_file.syntax(), range)
    }
}

pub(crate) struct Assists {
    resolve: bool,
    file: FileId,
    buf: Vec<(Assist, Option<SourceChange>)>,
}

impl Assists {
    pub(crate) fn new_resolved(ctx: &AssistContext) -> Assists {
        Assists { resolve: true, file: ctx.frange.file_id, buf: Vec::new() }
    }
    pub(crate) fn new_unresolved(ctx: &AssistContext) -> Assists {
        Assists { resolve: false, file: ctx.frange.file_id, buf: Vec::new() }
    }

    pub(crate) fn finish_unresolved(self) -> Vec<Assist> {
        assert!(!self.resolve);
        self.finish()
            .into_iter()
            .map(|(label, edit)| {
                assert!(edit.is_none());
                label
            })
            .collect()
    }

    pub(crate) fn finish_resolved(self) -> Vec<ResolvedAssist> {
        assert!(self.resolve);
        self.finish()
            .into_iter()
            .map(|(label, edit)| ResolvedAssist { assist: label, source_change: edit.unwrap() })
            .collect()
    }

    pub(crate) fn add(
        &mut self,
        id: AssistId,
        label: impl Into<String>,
        target: TextRange,
        f: impl FnOnce(&mut AssistBuilder),
    ) -> Option<()> {
        let label = Assist::new(id, label.into(), None, target);
        self.add_impl(label, f)
    }
    pub(crate) fn add_group(
        &mut self,
        group: &GroupLabel,
        id: AssistId,
        label: impl Into<String>,
        target: TextRange,
        f: impl FnOnce(&mut AssistBuilder),
    ) -> Option<()> {
        let label = Assist::new(id, label.into(), Some(group.clone()), target);
        self.add_impl(label, f)
    }
    fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> {
        let change_label = label.label.clone();
        let source_change = if self.resolve {
            let mut builder = AssistBuilder::new(self.file);
            f(&mut builder);
            Some(builder.finish(change_label))
        } else {
            None
        };

        self.buf.push((label, source_change));
        Some(())
    }

    fn finish(mut self) -> Vec<(Assist, Option<SourceChange>)> {
        self.buf.sort_by_key(|(label, _edit)| label.target.len());
        self.buf
    }
}

pub(crate) struct AssistBuilder {
    edit: TextEditBuilder,
    cursor_position: Option<TextSize>,
    file: FileId,
}

impl AssistBuilder {
    pub(crate) fn new(file: FileId) -> AssistBuilder {
        AssistBuilder { edit: TextEditBuilder::default(), cursor_position: None, file }
    }

    /// Remove specified `range` of text.
    pub(crate) fn delete(&mut self, range: TextRange) {
        self.edit.delete(range)
    }
    /// Append specified `text` at the given `offset`
    pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
        self.edit.insert(offset, text.into())
    }
    /// Replaces specified `range` of text with a given string.
    pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
        self.edit.replace(range, replace_with.into())
    }
    pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
        algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
    }
    /// Replaces specified `node` of text with a given string, reindenting the
    /// string to maintain `node`'s existing indent.
    // FIXME: remove in favor of ra_syntax::edit::IndentLevel::increase_indent
    pub(crate) fn replace_node_and_indent(
        &mut self,
        node: &SyntaxNode,
        replace_with: impl Into<String>,
    ) {
        let mut replace_with = replace_with.into();
        if let Some(indent) = leading_indent(node) {
            replace_with = reindent(&replace_with, &indent)
        }
        self.replace(node.text_range(), replace_with)
    }
    pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) {
        let node = rewriter.rewrite_root().unwrap();
        let new = rewriter.rewrite(&node);
        algo::diff(&node, &new).into_text_edit(&mut self.edit)
    }

    /// Specify desired position of the cursor after the assist is applied.
    pub(crate) fn set_cursor(&mut self, offset: TextSize) {
        self.cursor_position = Some(offset)
    }
    // FIXME: better API
    pub(crate) fn set_file(&mut self, assist_file: FileId) {
        self.file = assist_file;
    }

    // FIXME: kill this API
    /// Get access to the raw `TextEditBuilder`.
    pub(crate) fn text_edit_builder(&mut self) -> &mut TextEditBuilder {
        &mut self.edit
    }

    fn finish(self, change_label: String) -> SourceChange {
        let edit = self.edit.finish();
        if edit.is_empty() && self.cursor_position.is_none() {
            panic!("Only call `add_assist` if the assist can be applied")
        }
        SingleFileChange { label: change_label, edit, cursor_position: self.cursor_position }
            .into_source_change(self.file)
    }
}
<commit_msg>Fix visibility<commit_after>//! See `AssistContext`

use algo::find_covering_element;
use hir::Semantics;
use ra_db::{FileId, FileRange};
use ra_fmt::{leading_indent, reindent};
use ra_ide_db::{
    source_change::{SingleFileChange, SourceChange},
    RootDatabase,
};
use ra_syntax::{
    algo::{self, find_node_at_offset, SyntaxRewriter},
    AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize,
    TokenAtOffset,
};
use ra_text_edit::TextEditBuilder;

use crate::{Assist, AssistId, GroupLabel, ResolvedAssist};

/// `AssistContext` allows to apply an assist or check if it could be applied.
///
/// Assists use a somewhat over-engineered approach, given the current needs.
/// The assists workflow consists of two phases. In the first phase, a user asks
/// for the list of available assists. In the second phase, the user picks a
/// particular assist and it gets applied.
///
/// There are two peculiarities here:
///
/// * first, we ideally avoid computing more things then necessary to answer "is
///   assist applicable" in the first phase.
/// * second, when we are applying assist, we don't have a guarantee that there
///   weren't any changes between the point when user asked for assists and when
///   they applied a particular assist. So, when applying assist, we need to do
///   all the checks from scratch.
///
/// To avoid repeating the same code twice for both "check" and "apply"
/// functions, we use an approach reminiscent of that of Django's function based
/// views dealing with forms. Each assist receives a runtime parameter,
/// `resolve`. It first check if an edit is applicable (potentially computing
/// info required to compute the actual edit). If it is applicable, and
/// `resolve` is `true`, it then computes the actual edit.
///
/// So, to implement the original assists workflow, we can first apply each edit
/// with `resolve = false`, and then applying the selected edit again, with
/// `resolve = true` this time.
///
/// Note, however, that we don't actually use such two-phase logic at the
/// moment, because the LSP API is pretty awkward in this place, and it's much
/// easier to just compute the edit eagerly :-)
pub(crate) struct AssistContext<'a> {
    pub(crate) sema: Semantics<'a, RootDatabase>,
    pub(crate) db: &'a RootDatabase,
    pub(crate) frange: FileRange,
    source_file: SourceFile,
}

impl<'a> AssistContext<'a> {
    pub fn new(sema: Semantics<'a, RootDatabase>, frange: FileRange) -> AssistContext<'a> {
        let source_file = sema.parse(frange.file_id);
        let db = sema.db;
        AssistContext { sema, db, frange, source_file }
    }

    // NB, this ignores active selection.
    pub(crate) fn offset(&self) -> TextSize {
        self.frange.range.start()
    }

    pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> {
        self.source_file.syntax().token_at_offset(self.offset())
    }
    pub(crate) fn find_token_at_offset(&self, kind: SyntaxKind) -> Option<SyntaxToken> {
        self.token_at_offset().find(|it| it.kind() == kind)
    }
    pub(crate) fn find_node_at_offset<N: AstNode>(&self) -> Option<N> {
        find_node_at_offset(self.source_file.syntax(), self.offset())
    }
    pub(crate) fn find_node_at_offset_with_descend<N: AstNode>(&self) -> Option<N> {
        self.sema.find_node_at_offset_with_descend(self.source_file.syntax(), self.offset())
    }
    pub(crate) fn covering_element(&self) -> SyntaxElement {
        find_covering_element(self.source_file.syntax(), self.frange.range)
    }
    // FIXME: remove
    pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement {
        find_covering_element(self.source_file.syntax(), range)
    }
}

pub(crate) struct Assists {
    resolve: bool,
    file: FileId,
    buf: Vec<(Assist, Option<SourceChange>)>,
}

impl Assists {
    pub(crate) fn new_resolved(ctx: &AssistContext) -> Assists {
        Assists { resolve: true, file: ctx.frange.file_id, buf: Vec::new() }
    }
    pub(crate) fn new_unresolved(ctx: &AssistContext) -> Assists {
        Assists { resolve: false, file: ctx.frange.file_id, buf: Vec::new() }
    }

    pub(crate) fn finish_unresolved(self) -> Vec<Assist> {
        assert!(!self.resolve);
        self.finish()
            .into_iter()
            .map(|(label, edit)| {
                assert!(edit.is_none());
                label
            })
            .collect()
    }

    pub(crate) fn finish_resolved(self) -> Vec<ResolvedAssist> {
        assert!(self.resolve);
        self.finish()
            .into_iter()
            .map(|(label, edit)| ResolvedAssist { assist: label, source_change: edit.unwrap() })
            .collect()
    }

    pub(crate) fn add(
        &mut self,
        id: AssistId,
        label: impl Into<String>,
        target: TextRange,
        f: impl FnOnce(&mut AssistBuilder),
    ) -> Option<()> {
        let label = Assist::new(id, label.into(), None, target);
        self.add_impl(label, f)
    }
    pub(crate) fn add_group(
        &mut self,
        group: &GroupLabel,
        id: AssistId,
        label: impl Into<String>,
        target: TextRange,
        f: impl FnOnce(&mut AssistBuilder),
    ) -> Option<()> {
        let label = Assist::new(id, label.into(), Some(group.clone()), target);
        self.add_impl(label, f)
    }
    fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> {
        let change_label = label.label.clone();
        let source_change = if self.resolve {
            let mut builder = AssistBuilder::new(self.file);
            f(&mut builder);
            Some(builder.finish(change_label))
        } else {
            None
        };

        self.buf.push((label, source_change));
        Some(())
    }

    fn finish(mut self) -> Vec<(Assist, Option<SourceChange>)> {
        self.buf.sort_by_key(|(label, _edit)| label.target.len());
        self.buf
    }
}

pub(crate) struct AssistBuilder {
    edit: TextEditBuilder,
    cursor_position: Option<TextSize>,
    file: FileId,
}

impl AssistBuilder {
    pub(crate) fn new(file: FileId) -> AssistBuilder {
        AssistBuilder { edit: TextEditBuilder::default(), cursor_position: None, file }
    }

    /// Remove specified `range` of text.
    pub(crate) fn delete(&mut self, range: TextRange) {
        self.edit.delete(range)
    }
    /// Append specified `text` at the given `offset`
    pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
        self.edit.insert(offset, text.into())
    }
    /// Replaces specified `range` of text with a given string.
    pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
        self.edit.replace(range, replace_with.into())
    }
    pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
        algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
    }
    /// Replaces specified `node` of text with a given string, reindenting the
    /// string to maintain `node`'s existing indent.
    // FIXME: remove in favor of ra_syntax::edit::IndentLevel::increase_indent
    pub(crate) fn replace_node_and_indent(
        &mut self,
        node: &SyntaxNode,
        replace_with: impl Into<String>,
    ) {
        let mut replace_with = replace_with.into();
        if let Some(indent) = leading_indent(node) {
            replace_with = reindent(&replace_with, &indent)
        }
        self.replace(node.text_range(), replace_with)
    }
    pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) {
        let node = rewriter.rewrite_root().unwrap();
        let new = rewriter.rewrite(&node);
        algo::diff(&node, &new).into_text_edit(&mut self.edit)
    }

    /// Specify desired position of the cursor after the assist is applied.
    pub(crate) fn set_cursor(&mut self, offset: TextSize) {
        self.cursor_position = Some(offset)
    }
    // FIXME: better API
    pub(crate) fn set_file(&mut self, assist_file: FileId) {
        self.file = assist_file;
    }

    // FIXME: kill this API
    /// Get access to the raw `TextEditBuilder`.
    pub(crate) fn text_edit_builder(&mut self) -> &mut TextEditBuilder {
        &mut self.edit
    }

    fn finish(self, change_label: String) -> SourceChange {
        let edit = self.edit.finish();
        if edit.is_empty() && self.cursor_position.is_none() {
            panic!("Only call `add_assist` if the assist can be applied")
        }
        SingleFileChange { label: change_label, edit, cursor_position: self.cursor_position }
            .into_source_change(self.file)
    }
}
<|endoftext|>


<commit_before>use mio::*;
use mio::tcp::TcpStream;
use mio::channel::channel;
use mio::channel::{Sender, Receiver};
use std::collections::HashMap;
use std::net::IpAddr;
use std::net::SocketAddr;
use std::io::{Read, Write};
use std::io;
use std::error::Error;
use metainfo::MetaInfo;
use metainfo::SHA1Hash20b;

use wire::handler::{ServerHandler, BasicHandler, PeerHandler, PeerAction, PeerStreamAction};
use wire::data::{PeerMsg, parse_peermsg};
use wire::protocol_handler::PeerServer;

const OUTSIDE_MSG: Token = Token(0);
type StreamId = u32;

pub struct Protocol {
    streams: HashMap<StreamId, (TcpStream, PeerStream)>,
    handler: PeerServer,
    poll: Poll,
    sender: Sender<ChanMsg>,
    receiver: Receiver<ChanMsg>,
    info: MetaInfo,
    info_hash: SHA1Hash20b,
    pending_actions: Vec<PeerAction>,
    stats: Stats,
    next_peer_id: usize,
}

struct PeerStream {
    id: StreamId,
    bytes_in: Vec<u8>,
    bytes_out: Vec<u8>,
    handshake_sent: bool,
    handshake_received: bool,
}

#[derive(Debug, Copy, Clone)]
pub struct Stats {
    pub uploaded: usize,
    pub downloaded: usize,
    pub peer_count: usize,
}

impl Stats {
    pub fn new() -> Stats {
        Stats {
            uploaded: 0,
            downloaded: 0,
            peer_count: 0,
        }
    }
}

impl PeerStream {
    fn new(id: StreamId) -> PeerStream {
        PeerStream {
            id: id,
            bytes_in: Vec::new(),
            bytes_out: Vec::new(),
            handshake_sent: false,
            handshake_received: false,
        }
    }

    fn write_in(&mut self, mut bytes: Vec<u8>) {
        self.bytes_in.append(&mut bytes);
    }

    fn write_out(&mut self, mut bytes: Vec<u8>) {
        println!("This goes out {:?}", bytes);
        self.bytes_out.append(&mut bytes);
    }

    fn message(&mut self) -> Option<PeerMsg> {
        if self.bytes_in.len() == 0 {
            return None;
        }

        match parse_peermsg(&self.bytes_in) {
            Ok((msg, offset)) => {
                if offset < self.bytes_in.len() {
                    self.bytes_in.split_off(offset);
                } else {
                    self.bytes_in = Vec::new();
                }
                Some(msg)
            }
            Err(_) => {
                // TODO It needs to distinguish between recoverable and non-recoverable
                None
            }
        }
    }

    fn take(&mut self, out: &mut Write) -> io::Result<usize> {
        const MAX_BYTES_WRITE: usize = 1024 * 128;
        info!("Attempting to write {} bytes", self.bytes_out.len());
        let result = out.write(&self.bytes_out);
        match result {
            Ok(offset) => {
                info!("Wrote {} bytes", offset);
                self.bytes_out = self.bytes_out.split_off(offset);
            }
            Err(ref err) => {
                info!("Writing failed: {}", err);
            }
        };
        result
    }
}

#[derive(Debug)]
pub enum ChanMsg {
    NewPeer(IpAddr, u16),
    StatsRequest,
    StatsResponse(Stats),
}

impl Protocol {
    pub fn new(info: &MetaInfo,
               hash: SHA1Hash20b,
               our_peer_id: &str)
               -> (Protocol, Sender<ChanMsg>, Receiver<ChanMsg>) {
        let poll = Poll::new().unwrap();

        match (channel(), channel()) {
            ((to_inside, from_outside), (to_outside, from_inside)) => {

                poll.register(&from_outside,
                              OUTSIDE_MSG,
                              Ready::readable(),
                              PollOpt::level())
                    .unwrap();

                let proto = Protocol {
                    streams: HashMap::new(),
                    poll: poll,
                    sender: to_outside,
                    receiver: from_outside,
                    info: info.clone(),
                    info_hash: hash.clone(),
                    pending_actions: Vec::new(),
                    stats: Stats::new(),
                    handler: ServerHandler::new(info.clone(), hash.clone(), our_peer_id),
                    next_peer_id: 1,
                };

                (proto, to_inside, from_inside)
            }
        }
    }

    pub fn run(&mut self) {
        const EVENT_CAPACITY: usize = 32;
        let mut events = Events::with_capacity(EVENT_CAPACITY);
        loop {
            self.poll.poll(&mut events, None).unwrap();
            for event in events.iter() {
                match event.token() {
                    OUTSIDE_MSG => {
                        loop {
                            match self.receiver.try_recv() {
                                Ok(msg) => self._handle_outside_msg(msg),
                                _ => break,
                            }
                        }
                    }
                    _ => self._handle_socket_event(event),
                }
            }
            self.handler.on_loop();
        }
    }

    fn _get_stream_id(&self, token: Token) -> Option<StreamId> {
        Some(match token {
            Token(id) => id as StreamId,
        })
    }

    fn _perform_action(&mut self, action: PeerAction) {
        let id = action.0;
        match action.1 {
            PeerStreamAction::Nothing => (),
            PeerStreamAction::SendMessages(msgs) => {
                for msg in msgs {
                    info!("Writing message {:?}", msg);
                    let bytes: Vec<u8> = msg.into();
                    match self.streams.get_mut(&id) {
                        Some(&mut (_, ref mut peer)) => {
                            peer.write_out(bytes);
                        }
                        None => {
                            // this peer already disconnected
                        }
                    }
                }
            }
            PeerStreamAction::Disconnect => {
                self.streams.remove(&id);
            }
        }
    }

    fn _handle_socket_event(&mut self, event: Event) {
        let kind = event.kind();
        let peer_id: StreamId = match self._get_stream_id(event.token()) {
            Some(p_id) => p_id,
            None => return,
        };

        if let Some((mut tcp_stream, mut peer_stream)) = self.streams.remove(&peer_id) {
            info!("Got event {:?} from peer id {}", event, peer_id);
            if (kind.is_readable()) {
                let read_result =
                    Protocol::_handle_read(&mut tcp_stream, &mut peer_stream, &mut self.handler);

                match read_result.0 {
                    Some(action) => self._perform_action(action),
                    None => (),
                }

                self.stats.uploaded += read_result.1;
            }

            let mut fatal_error_happened = false;
            if kind.is_writable() {
                // write pending messages
                let write_result =
                    Protocol::_handle_write(&mut tcp_stream, &mut peer_stream, &mut self.handler);

                if write_result.is_err() {
                    fatal_error_happened = true;
                }
            }

            if kind.is_hup() || kind.is_error() || fatal_error_happened {
                info!("Disconnected from peer id {}", peer_stream.id);
                self.poll.deregister(&tcp_stream);
                Protocol::_handle_hup(&mut tcp_stream, &mut peer_stream, &mut self.handler);

                // do not return socket to collection
                return;
            }

            self.streams.insert(peer_stream.id, (tcp_stream, peer_stream));
        }

    }

    fn _handle_read(socket: &mut TcpStream,
                    peer: &mut PeerStream,
                    handler: &mut PeerServer)
                    -> (Option<PeerAction>, usize) {
        let mut buf = Vec::with_capacity(1024);
        let bytes_read = match socket.read(&mut buf) {
            Ok(bytes_read) => {
                peer.write_in(buf);
                info!("Read {} bytes from {}", bytes_read, peer.id);//, socket.peer_addr());
                bytes_read
            }
            _ => 0,
        };

        let action = match peer.message() {
            Some(msg) => {
                info!("Received from peer {:?}", msg);
                Some(handler.on_message_receive(peer.id, msg))
            }
            _ => return (None, bytes_read),
        };

        info!("Read {} bytes", bytes_read);

        (action, bytes_read)
    }

    fn _handle_write(socket: &mut TcpStream,
                     peer: &mut PeerStream,
                     handler: &mut PeerServer)
                     -> io::Result<usize> {
        peer.take(socket)
    }

    fn _handle_hup(socket: &mut TcpStream, peer: &mut PeerStream, handler: &mut PeerServer) {
        handler.on_peer_disconnect(peer.id);
    }

    fn _handle_outside_msg(&mut self, msg: ChanMsg) {
        match msg {
            ChanMsg::NewPeer(ip, port) => self._handle_new_peer(ip, port),
            ChanMsg::StatsRequest => {
                self.sender.send(ChanMsg::StatsResponse(self.stats));
            }
            _ => (),
        }
    }

    fn _handle_new_peer(&mut self, addr: IpAddr, port: u16) {
        for (id, &(ref socket, _)) in &self.streams {
            match (socket.peer_addr(), addr) {
                (Ok(SocketAddr::V4(peer)), IpAddr::V4(p)) => {
                    if peer.port() == port && peer.ip().octets() == p.octets() {
                        return;
                    }
                }
                (Ok(SocketAddr::V6(peer)), IpAddr::V6(p)) => unimplemented!(),
                (Err(e), _) => {
                    continue;
                }
                _ => continue,
            }
        }

        match self._connect_to_peer(addr, port) {
            Some((sock, Token(id))) => {
                self.streams.insert(id, (sock, PeerStream::new(id)));
                let action = self.handler.on_peer_connect(id);
                self._perform_action(action);
            }
            None => (),
        }
    }

    fn _connect_to_peer(&mut self, addr: IpAddr, port: u16) -> Option<(TcpStream, Token)> {
        let sock_addr = SocketAddr::new(addr, port);
        let token = Token(self.next_peer_id);
        info!("Trying to connect to {} on port {}", addr, port);
        match TcpStream::connect(&sock_addr) {
            Ok(sock) => {
                self.poll
                    .register(&sock,
                              token,
                              Ready::all(),
                              PollOpt::edge());

                self.next_peer_id += 1;
                return Some((sock, token));
            },
            Err(e) => {
                info!("Could not connect: {}", e);
                return None;
            }
        }
    }
}
<commit_msg>Fix issue with reading<commit_after>use mio::*;
use mio::tcp::TcpStream;
use mio::channel::channel;
use mio::channel::{Sender, Receiver};
use std::collections::HashMap;
use std::net::IpAddr;
use std::net::SocketAddr;
use std::io::{Read, Write};
use std::io;
use std::error::Error;
use metainfo::MetaInfo;
use metainfo::SHA1Hash20b;

use wire::handler::{ServerHandler, BasicHandler, PeerHandler, PeerAction, PeerStreamAction};
use wire::data::{PeerMsg, parse_peermsg};
use wire::protocol_handler::PeerServer;

const OUTSIDE_MSG: Token = Token(0);
type StreamId = u32;

pub struct Protocol {
    streams: HashMap<StreamId, (TcpStream, PeerStream)>,
    handler: PeerServer,
    poll: Poll,
    sender: Sender<ChanMsg>,
    receiver: Receiver<ChanMsg>,
    info: MetaInfo,
    info_hash: SHA1Hash20b,
    pending_actions: Vec<PeerAction>,
    stats: Stats,
    next_peer_id: usize,
}

struct PeerStream {
    id: StreamId,
    bytes_in: Vec<u8>,
    bytes_out: Vec<u8>,
    handshake_sent: bool,
    handshake_received: bool,
}

#[derive(Debug, Copy, Clone)]
pub struct Stats {
    pub uploaded: usize,
    pub downloaded: usize,
    pub peer_count: usize,
}

impl Stats {
    pub fn new() -> Stats {
        Stats {
            uploaded: 0,
            downloaded: 0,
            peer_count: 0,
        }
    }
}

impl PeerStream {
    fn new(id: StreamId) -> PeerStream {
        PeerStream {
            id: id,
            bytes_in: Vec::new(),
            bytes_out: Vec::new(),
            handshake_sent: false,
            handshake_received: false,
        }
    }

    fn write_in(&mut self, mut bytes: Vec<u8>) {
        self.bytes_in.append(&mut bytes);
    }

    fn write_out(&mut self, mut bytes: Vec<u8>) {
        println!("This goes out {:?}", bytes);
        self.bytes_out.append(&mut bytes);
    }

    fn message(&mut self) -> Option<PeerMsg> {
        if self.bytes_in.len() == 0 {
            return None;
        }

        match parse_peermsg(&self.bytes_in) {
            Ok((msg, offset)) => {
                if offset < self.bytes_in.len() {
                    self.bytes_in.split_off(offset);
                } else {
                    self.bytes_in = Vec::new();
                }
                Some(msg)
            }
            Err(_) => {
                // TODO It needs to distinguish between recoverable and non-recoverable
                None
            }
        }
    }

    fn take(&mut self, out: &mut Write) -> io::Result<usize> {
        const MAX_BYTES_WRITE: usize = 1024 * 128;
        info!("Attempting to write {} bytes", self.bytes_out.len());
        let result = out.write(&self.bytes_out);
        match result {
            Ok(offset) => {
                info!("Wrote {} bytes", offset);
                self.bytes_out = self.bytes_out.split_off(offset);
            }
            Err(ref err) => {
                info!("Writing failed: {}", err);
            }
        };
        result
    }
}

#[derive(Debug)]
pub enum ChanMsg {
    NewPeer(IpAddr, u16),
    StatsRequest,
    StatsResponse(Stats),
}

impl Protocol {
    pub fn new(info: &MetaInfo,
               hash: SHA1Hash20b,
               our_peer_id: &str)
               -> (Protocol, Sender<ChanMsg>, Receiver<ChanMsg>) {
        let poll = Poll::new().unwrap();

        match (channel(), channel()) {
            ((to_inside, from_outside), (to_outside, from_inside)) => {

                poll.register(&from_outside,
                              OUTSIDE_MSG,
                              Ready::readable(),
                              PollOpt::level())
                    .unwrap();

                let proto = Protocol {
                    streams: HashMap::new(),
                    poll: poll,
                    sender: to_outside,
                    receiver: from_outside,
                    info: info.clone(),
                    info_hash: hash.clone(),
                    pending_actions: Vec::new(),
                    stats: Stats::new(),
                    handler: ServerHandler::new(info.clone(), hash.clone(), our_peer_id),
                    next_peer_id: 1,
                };

                (proto, to_inside, from_inside)
            }
        }
    }

    pub fn run(&mut self) {
        const EVENT_CAPACITY: usize = 32;
        let mut events = Events::with_capacity(EVENT_CAPACITY);
        loop {
            self.poll.poll(&mut events, None).unwrap();
            for event in events.iter() {
                match event.token() {
                    OUTSIDE_MSG => {
                        loop {
                            match self.receiver.try_recv() {
                                Ok(msg) => self._handle_outside_msg(msg),
                                _ => break,
                            }
                        }
                    }
                    _ => self._handle_socket_event(event),
                }
            }
            self.handler.on_loop();
        }
    }

    fn _get_stream_id(&self, token: Token) -> Option<StreamId> {
        Some(match token {
            Token(id) => id as StreamId,
        })
    }

    fn _perform_action(&mut self, action: PeerAction) {
        let id = action.0;
        match action.1 {
            PeerStreamAction::Nothing => (),
            PeerStreamAction::SendMessages(msgs) => {
                for msg in msgs {
                    info!("Writing message {:?}", msg);
                    let bytes: Vec<u8> = msg.into();
                    match self.streams.get_mut(&id) {
                        Some(&mut (_, ref mut peer)) => {
                            peer.write_out(bytes);
                        }
                        None => {
                            // this peer already disconnected
                        }
                    }
                }
            }
            PeerStreamAction::Disconnect => {
                self.streams.remove(&id);
            }
        }
    }

    fn _handle_socket_event(&mut self, event: Event) {
        let kind = event.kind();
        let peer_id: StreamId = match self._get_stream_id(event.token()) {
            Some(p_id) => p_id,
            None => return,
        };

        if let Some((mut tcp_stream, mut peer_stream)) = self.streams.remove(&peer_id) {
            info!("Got event {:?} from peer id {}", event, peer_id);
            if (kind.is_readable()) {
                let read_result =
                    Protocol::_handle_read(&mut tcp_stream, &mut peer_stream, &mut self.handler);

                match read_result.0 {
                    Some(action) => self._perform_action(action),
                    None => (),
                }

                self.stats.uploaded += read_result.1;
            }

            let mut fatal_error_happened = false;
            if kind.is_writable() {
                // write pending messages
                let write_result =
                    Protocol::_handle_write(&mut tcp_stream, &mut peer_stream, &mut self.handler);

                if write_result.is_err() {
                    fatal_error_happened = true;
                }
            }

            if kind.is_hup() || kind.is_error() || fatal_error_happened {
                info!("Disconnected from peer id {}", peer_stream.id);
                self.poll.deregister(&tcp_stream);
                Protocol::_handle_hup(&mut tcp_stream, &mut peer_stream, &mut self.handler);

                // do not return socket to collection
                return;
            }

            self.streams.insert(peer_stream.id, (tcp_stream, peer_stream));
        }

    }

    fn _handle_read(socket: &mut TcpStream,
                    peer: &mut PeerStream,
                    handler: &mut PeerServer)
                    -> (Option<PeerAction>, usize) {
        const READ_BUF_SIZE: usize = 1024;
        let mut buf = Vec::with_capacity(READ_BUF_SIZE);
        buf.resize(READ_BUF_SIZE, 0);
        let bytes_read = match socket.read(&mut buf) {
            Ok(bytes_read) => {
                peer.write_in(buf);
                info!("Read {} bytes from {}", bytes_read, peer.id);//, socket.peer_addr());
                bytes_read
            }
            _ => 0,
        };

        let action = match peer.message() {
            Some(msg) => {
                info!("Received from peer {:?}", msg);
                Some(handler.on_message_receive(peer.id, msg))
            }
            _ => return (None, bytes_read),
        };

        info!("Read {} bytes", bytes_read);

        (action, bytes_read)
    }

    fn _handle_write(socket: &mut TcpStream,
                     peer: &mut PeerStream,
                     handler: &mut PeerServer)
                     -> io::Result<usize> {
        peer.take(socket)
    }

    fn _handle_hup(socket: &mut TcpStream, peer: &mut PeerStream, handler: &mut PeerServer) {
        handler.on_peer_disconnect(peer.id);
    }

    fn _handle_outside_msg(&mut self, msg: ChanMsg) {
        match msg {
            ChanMsg::NewPeer(ip, port) => self._handle_new_peer(ip, port),
            ChanMsg::StatsRequest => {
                self.sender.send(ChanMsg::StatsResponse(self.stats));
            }
            _ => (),
        }
    }

    fn _handle_new_peer(&mut self, addr: IpAddr, port: u16) {
        for (id, &(ref socket, _)) in &self.streams {
            match (socket.peer_addr(), addr) {
                (Ok(SocketAddr::V4(peer)), IpAddr::V4(p)) => {
                    if peer.port() == port && peer.ip().octets() == p.octets() {
                        return;
                    }
                }
                (Ok(SocketAddr::V6(peer)), IpAddr::V6(p)) => unimplemented!(),
                (Err(e), _) => {
                    continue;
                }
                _ => continue,
            }
        }

        match self._connect_to_peer(addr, port) {
            Some((sock, Token(id_usize))) => {
                let id = id_usize as u32;
                self.streams.insert(id, (sock, PeerStream::new(id)));
                let action = self.handler.on_peer_connect(id);
                self._perform_action(action);
            }
            None => (),
        }
    }

    fn _connect_to_peer(&mut self, addr: IpAddr, port: u16) -> Option<(TcpStream, Token)> {
        let sock_addr = SocketAddr::new(addr, port);
        let token = Token(self.next_peer_id);
        info!("Trying to connect to {} on port {}", addr, port);
        match TcpStream::connect(&sock_addr) {
            Ok(sock) => {
                self.poll
                    .register(&sock,
                              token,
                              Ready::all(),
                              PollOpt::edge());

                self.next_peer_id += 1;
                return Some((sock, token));
            },
            Err(e) => {
                info!("Could not connect: {}", e);
                return None;
            }
        }
    }
}
<|endoftext|>


<commit_before>//! The simplest possible example that does something.
#![allow(clippy::unnecessary_wraps)]

use ggez::graphics::{
    self,
    draw::DrawParam,
    image::Image,
    mesh::{Mesh, MeshBuilder},
    text::{FontData, Text, TextLayout},
    Color, Rect,
};
use ggez::{
    event, filesystem,
    graphics::{
        canvas::{Canvas, CanvasLoadOp},
        image::{ImageFormat, ScreenImage},
        sampler::Sampler,
    },
};
use ggez::{Context, GameResult};
use glam::*;

struct MainState {
    pos_x: f32,
    circle: Mesh,
    frame: ScreenImage,
}

impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {
        let circle = Mesh::from_data(
            &ctx.gfx,
            MeshBuilder::new()
                .circle(
                    graphics::DrawMode::fill(),
                    vec2(0., 0.),
                    100.,
                    2.0,
                    Color::WHITE,
                )?
                .build(),
        );

        Ok(MainState {
            pos_x: 0.0,
            circle,
            frame: ScreenImage::new(&ctx.gfx, None, 1., 1., 1),
        })
    }
}

impl event::EventHandler<ggez::GameError> for MainState {
    fn update(&mut self, _ctx: &mut Context) -> GameResult {
        self.pos_x = self.pos_x % 800.0 + 1.0;
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        let frame = self.frame.image(&ctx.gfx);

        let mut canvas = Canvas::from_image(
            &mut ctx.gfx,
            CanvasLoadOp::Clear([0.1, 0.2, 0.3, 1.0].into()),
            &frame,
            None,
        );

        canvas.draw_mesh(
            &self.circle,
            None,
            DrawParam::new().offset(vec2(self.pos_x, 300.)),
        );

        canvas.finish()?;
        ctx.gfx.present(&frame)?;

        Ok(())
    }
}

pub fn main() -> GameResult {
    env_logger::init();
    let cb = ggez::ContextBuilder::new("super_simple", "ggez");
    let (mut ctx, event_loop) = cb.build()?;
    let state = MainState::new(&mut ctx)?;
    event::run(ctx, event_loop, state)
}
<commit_msg>fix example 01<commit_after>//! The simplest possible example that does something.
#![allow(clippy::unnecessary_wraps)]

use ggez::{
    event,
    graphics::{
        self,
        canvas::{Canvas, CanvasLoadOp},
        draw::DrawParam,
        image::ScreenImage,
        mesh::{Mesh, MeshBuilder},
        Color,
    },
    Context, GameResult,
};
use glam::*;

struct MainState {
    pos_x: f32,
    circle: Mesh,
    frame: ScreenImage,
}

impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {
        let circle = Mesh::from_data(
            &ctx.gfx,
            MeshBuilder::new()
                .circle(
                    graphics::DrawMode::fill(),
                    vec2(0., 0.),
                    100.,
                    2.0,
                    Color::WHITE,
                )?
                .build(),
        );

        Ok(MainState {
            pos_x: 0.0,
            circle,
            frame: ScreenImage::new(&ctx.gfx, None, 1., 1., 1),
        })
    }
}

impl event::EventHandler<ggez::GameError> for MainState {
    fn update(&mut self, _ctx: &mut Context) -> GameResult {
        self.pos_x = self.pos_x % 800.0 + 1.0;
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        let frame = self.frame.image(&ctx.gfx);

        let mut canvas = Canvas::from_image(
            &mut ctx.gfx,
            CanvasLoadOp::Clear([0.1, 0.2, 0.3, 1.0].into()),
            &frame,
        );

        canvas.draw_mesh(
            &self.circle,
            None,
            DrawParam::new().offset(vec2(self.pos_x, 300.)),
        );

        canvas.finish();
        ctx.gfx.present(&frame)?;

        Ok(())
    }
}

pub fn main() -> GameResult {
    env_logger::init();
    let cb = ggez::ContextBuilder::new("super_simple", "ggez");
    let (mut ctx, event_loop) = cb.build()?;
    let state = MainState::new(&mut ctx)?;
    event::run(ctx, event_loop, state)
}
<|endoftext|>


<commit_before>use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::ptr;
use std::str::{self, FromStr};

use libc;

use glib::translate::*;
use glib_sys::{gboolean, gpointer, GList};

use attributes::Attribute;
use croco::*;
use handle::{self, RsvgHandle};
use state::State;
use util::utf8_cstr;

pub enum RsvgCssStyles {}

struct Declaration {
    prop_value: String,
    important: bool,
}

// Maps property_name -> Declaration
type DeclarationList = HashMap<String, Declaration>;

pub struct CssStyles {
    selectors_to_declarations: HashMap<String, DeclarationList>,
}

impl CssStyles {
    fn new() -> CssStyles {
        CssStyles {
            selectors_to_declarations: HashMap::new(),
        }
    }

    fn define(&mut self, selector: &str, prop_name: &str, prop_value: &str, important: bool) {
        let decl_list = self
            .selectors_to_declarations
            .entry(selector.to_string())
            .or_insert_with(|| DeclarationList::new());

        match decl_list.entry(prop_name.to_string()) {
            Entry::Occupied(mut e) => {
                let decl = e.get_mut();

                if !decl.important {
                    decl.prop_value = prop_value.to_string();
                    decl.important = important;
                }
            }

            Entry::Vacant(v) => {
                v.insert(Declaration {
                    prop_value: prop_value.to_string(),
                    important,
                });
            }
        }
    }

    pub fn lookup_apply(&self, selector: &str, state: &mut State) -> bool {
        if let Some(decl_list) = self.selectors_to_declarations.get(selector) {
            for (prop_name, declaration) in decl_list.iter() {
                if let Ok(attr) = Attribute::from_str(prop_name) {
                    // FIXME: this is ignoring errors
                    let _ = state.parse_style_pair(
                        attr,
                        &declaration.prop_value,
                        declaration.important,
                    );
                }
            }

            true
        } else {
            false
        }
    }
}

struct DocHandlerData {
    handle: *mut RsvgHandle,
    selector: *mut CRSelector,
}

pub fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) {
    if buf.len() == 0 {
        return; // libcroco doesn't like empty strings :(
    }

    unsafe {
        let handler_data = DocHandlerData {
            handle,
            selector: ptr::null_mut(),
        };

        let doc_handler = cr_doc_handler_new();
        init_cr_doc_handler(&mut *doc_handler);

        (*doc_handler).app_data = &handler_data as *const _ as gpointer;

        let buf_ptr = buf.as_ptr() as *mut _;
        let buf_len = buf.len() as libc::c_ulong;

        let parser = cr_parser_new_from_buf(buf_ptr, buf_len, CR_UTF_8, false.to_glib());
        if parser.is_null() {
            cr_doc_handler_unref(doc_handler);
            return;
        }

        cr_parser_set_sac_handler(parser, doc_handler);
        cr_doc_handler_unref(doc_handler);

        cr_parser_set_use_core_grammar(parser, false.to_glib());
        cr_parser_parse(parser);

        cr_parser_destroy(parser);
    }
}

fn init_cr_doc_handler(handler: &mut CRDocHandler) {
    handler.import_style = Some(css_import_style);
    handler.start_selector = Some(css_start_selector);
    handler.end_selector = Some(css_end_selector);
    handler.property = Some(css_property);
    handler.error = Some(css_error);
    handler.unrecoverable_error = Some(css_unrecoverable_error);
}

unsafe extern "C" fn css_import_style(
    a_this: *mut CRDocHandler,
    _a_media_list: *mut GList,
    a_uri: CRString,
    _a_uri_default_ns: CRString,
    _a_location: CRParsingLocation,
) {
    let handler_data = get_doc_handler_data(a_this);

    if a_uri.is_null() {
        return;
    }

    let raw_uri = cr_string_peek_raw_str(a_uri);
    let uri = utf8_cstr(raw_uri);

    handle::load_css(handler_data.handle, uri);
}

unsafe fn get_doc_handler_data<'a>(doc_handler: *mut CRDocHandler) -> &'a mut DocHandlerData {
    &mut *((*doc_handler).app_data as *mut DocHandlerData)
}

unsafe extern "C" fn css_start_selector(
    a_this: *mut CRDocHandler,
    a_selector_list: *mut CRSelector,
) {
    let handler_data = get_doc_handler_data(a_this);

    cr_selector_ref(a_selector_list);
    handler_data.selector = a_selector_list;
}

unsafe extern "C" fn css_end_selector(
    a_this: *mut CRDocHandler,
    _a_selector_list: *mut CRSelector,
) {
    let handler_data = get_doc_handler_data(a_this);

    cr_selector_unref(handler_data.selector);
    handler_data.selector = ptr::null_mut();
}

unsafe extern "C" fn css_property(
    a_this: *mut CRDocHandler,
    a_name: CRString,
    a_expression: CRTerm,
    a_is_important: gboolean,
) {
    let handler_data = get_doc_handler_data(a_this);

    if a_name.is_null() || a_expression.is_null() || handler_data.selector.is_null() {
        return;
    }

    let mut cur_sel = handler_data.selector;
    while !cur_sel.is_null() {
        let simple_sel = (*cur_sel).simple_sel;

        if !simple_sel.is_null() {
            let raw_selector_name = cr_simple_sel_to_string(simple_sel) as *mut libc::c_char;

            if !raw_selector_name.is_null() {
                let raw_prop_name = cr_string_peek_raw_str(a_name);
                let prop_name = utf8_cstr(raw_prop_name);

                let prop_value =
                    <String as FromGlibPtrFull<_>>::from_glib_full(cr_term_to_string(a_expression));

                let selector_name =
                    <String as FromGlibPtrFull<_>>::from_glib_full(raw_selector_name);

                let important = from_glib(a_is_important);

                let styles = handle::get_css_styles_mut(handler_data.handle);

                styles.define(&selector_name, prop_name, &prop_value, important);
            }
        }

        cur_sel = (*cur_sel).next;
    }
}

unsafe extern "C" fn css_error(_a_this: *mut CRDocHandler) {
    println!("CSS parsing error");
}

unsafe extern "C" fn css_unrecoverable_error(_a_this: *mut CRDocHandler) {
    println!("CSS unrecoverable error");
}

#[no_mangle]
pub extern "C" fn rsvg_css_styles_new() -> *mut RsvgCssStyles {
    Box::into_raw(Box::new(CssStyles::new())) as *mut RsvgCssStyles
}

#[no_mangle]
pub unsafe extern "C" fn rsvg_css_styles_free(raw_styles: *mut RsvgCssStyles) {
    assert!(!raw_styles.is_null());

    Box::from_raw(raw_styles as *mut CssStyles);
}
<commit_msg>css: The DocHandlerData is our closure data; it should be mutable<commit_after>use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::ptr;
use std::str::{self, FromStr};

use libc;

use glib::translate::*;
use glib_sys::{gboolean, gpointer, GList};

use attributes::Attribute;
use croco::*;
use handle::{self, RsvgHandle};
use state::State;
use util::utf8_cstr;

pub enum RsvgCssStyles {}

struct Declaration {
    prop_value: String,
    important: bool,
}

// Maps property_name -> Declaration
type DeclarationList = HashMap<String, Declaration>;

pub struct CssStyles {
    selectors_to_declarations: HashMap<String, DeclarationList>,
}

impl CssStyles {
    fn new() -> CssStyles {
        CssStyles {
            selectors_to_declarations: HashMap::new(),
        }
    }

    fn define(&mut self, selector: &str, prop_name: &str, prop_value: &str, important: bool) {
        let decl_list = self
            .selectors_to_declarations
            .entry(selector.to_string())
            .or_insert_with(|| DeclarationList::new());

        match decl_list.entry(prop_name.to_string()) {
            Entry::Occupied(mut e) => {
                let decl = e.get_mut();

                if !decl.important {
                    decl.prop_value = prop_value.to_string();
                    decl.important = important;
                }
            }

            Entry::Vacant(v) => {
                v.insert(Declaration {
                    prop_value: prop_value.to_string(),
                    important,
                });
            }
        }
    }

    pub fn lookup_apply(&self, selector: &str, state: &mut State) -> bool {
        if let Some(decl_list) = self.selectors_to_declarations.get(selector) {
            for (prop_name, declaration) in decl_list.iter() {
                if let Ok(attr) = Attribute::from_str(prop_name) {
                    // FIXME: this is ignoring errors
                    let _ = state.parse_style_pair(
                        attr,
                        &declaration.prop_value,
                        declaration.important,
                    );
                }
            }

            true
        } else {
            false
        }
    }
}

struct DocHandlerData {
    handle: *mut RsvgHandle,
    selector: *mut CRSelector,
}

pub fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) {
    if buf.len() == 0 {
        return; // libcroco doesn't like empty strings :(
    }

    unsafe {
        let mut handler_data = DocHandlerData {
            handle,
            selector: ptr::null_mut(),
        };

        let doc_handler = cr_doc_handler_new();
        init_cr_doc_handler(&mut *doc_handler);

        (*doc_handler).app_data = &mut handler_data as *mut _ as gpointer;

        let buf_ptr = buf.as_ptr() as *mut _;
        let buf_len = buf.len() as libc::c_ulong;

        let parser = cr_parser_new_from_buf(buf_ptr, buf_len, CR_UTF_8, false.to_glib());
        if parser.is_null() {
            cr_doc_handler_unref(doc_handler);
            return;
        }

        cr_parser_set_sac_handler(parser, doc_handler);
        cr_doc_handler_unref(doc_handler);

        cr_parser_set_use_core_grammar(parser, false.to_glib());
        cr_parser_parse(parser);

        cr_parser_destroy(parser);
    }
}

fn init_cr_doc_handler(handler: &mut CRDocHandler) {
    handler.import_style = Some(css_import_style);
    handler.start_selector = Some(css_start_selector);
    handler.end_selector = Some(css_end_selector);
    handler.property = Some(css_property);
    handler.error = Some(css_error);
    handler.unrecoverable_error = Some(css_unrecoverable_error);
}

unsafe extern "C" fn css_import_style(
    a_this: *mut CRDocHandler,
    _a_media_list: *mut GList,
    a_uri: CRString,
    _a_uri_default_ns: CRString,
    _a_location: CRParsingLocation,
) {
    let handler_data = get_doc_handler_data(a_this);

    if a_uri.is_null() {
        return;
    }

    let raw_uri = cr_string_peek_raw_str(a_uri);
    let uri = utf8_cstr(raw_uri);

    handle::load_css(handler_data.handle, uri);
}

unsafe fn get_doc_handler_data<'a>(doc_handler: *mut CRDocHandler) -> &'a mut DocHandlerData {
    &mut *((*doc_handler).app_data as *mut DocHandlerData)
}

unsafe extern "C" fn css_start_selector(
    a_this: *mut CRDocHandler,
    a_selector_list: *mut CRSelector,
) {
    let handler_data = get_doc_handler_data(a_this);

    cr_selector_ref(a_selector_list);
    handler_data.selector = a_selector_list;
}

unsafe extern "C" fn css_end_selector(
    a_this: *mut CRDocHandler,
    _a_selector_list: *mut CRSelector,
) {
    let handler_data = get_doc_handler_data(a_this);

    cr_selector_unref(handler_data.selector);
    handler_data.selector = ptr::null_mut();
}

unsafe extern "C" fn css_property(
    a_this: *mut CRDocHandler,
    a_name: CRString,
    a_expression: CRTerm,
    a_is_important: gboolean,
) {
    let handler_data = get_doc_handler_data(a_this);

    if a_name.is_null() || a_expression.is_null() || handler_data.selector.is_null() {
        return;
    }

    let mut cur_sel = handler_data.selector;
    while !cur_sel.is_null() {
        let simple_sel = (*cur_sel).simple_sel;

        if !simple_sel.is_null() {
            let raw_selector_name = cr_simple_sel_to_string(simple_sel) as *mut libc::c_char;

            if !raw_selector_name.is_null() {
                let raw_prop_name = cr_string_peek_raw_str(a_name);
                let prop_name = utf8_cstr(raw_prop_name);

                let prop_value =
                    <String as FromGlibPtrFull<_>>::from_glib_full(cr_term_to_string(a_expression));

                let selector_name =
                    <String as FromGlibPtrFull<_>>::from_glib_full(raw_selector_name);

                let important = from_glib(a_is_important);

                let styles = handle::get_css_styles_mut(handler_data.handle);

                styles.define(&selector_name, prop_name, &prop_value, important);
            }
        }

        cur_sel = (*cur_sel).next;
    }
}

unsafe extern "C" fn css_error(_a_this: *mut CRDocHandler) {
    println!("CSS parsing error");
}

unsafe extern "C" fn css_unrecoverable_error(_a_this: *mut CRDocHandler) {
    println!("CSS unrecoverable error");
}

#[no_mangle]
pub extern "C" fn rsvg_css_styles_new() -> *mut RsvgCssStyles {
    Box::into_raw(Box::new(CssStyles::new())) as *mut RsvgCssStyles
}

#[no_mangle]
pub unsafe extern "C" fn rsvg_css_styles_free(raw_styles: *mut RsvgCssStyles) {
    assert!(!raw_styles.is_null());

    Box::from_raw(raw_styles as *mut CssStyles);
}
<|endoftext|>