<commit_before>use crate::location::{Location, Portal};
use crate::map::MapCell;
use crate::sector::{self, Sector, WorldSkeleton};
use crate::spec::EntitySpawn;
use crate::terrain::Terrain;
use euclid::{vec2, vec3};
use log::info;
use serde;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::mem;

/// Convention for maps, player always starts at origin sector.
pub const PLAYER_START_SECTOR: Sector = Sector::new(0, 0, 0);

/// Lazy instantiator for the generated world defined by random seed and skeleton.
///
/// Uses interior mutability to update the cache. Probably very thread unsafe.
pub struct WorldCache {
    seed: u32,
    skeleton: WorldSkeleton,

    internal_cache: RefCell<InternalCache>,
}

impl WorldCache {
    /// Initiate the cache given the world description.
    pub fn new(seed: u32, skeleton: WorldSkeleton) -> WorldCache {
        WorldCache {
            seed,
            skeleton,
            internal_cache: Default::default(),
        }
    }

    pub fn seed(&self) -> u32 { self.seed }

    /// Get the location where the player enters the world.
    pub fn player_entrance(&self) -> Location {
        // Player start in sector 0. Expect generation logic to set player position when
        // constructing the sector.
        self.generate(PLAYER_START_SECTOR);
        self.internal_cache.borrow().player_entrance
    }

    pub fn get_terrain(&self, loc: Location) -> Terrain {
        const FALLBACK_TERRAIN: Terrain = Terrain::Rock;

        let sector = loc.sector();
        self.finalize(sector);
        if let Some(t) = self.internal_cache.borrow().terrain.get(&loc).cloned() {
            t
        } else {
            self.skeleton
                .get(&sector)
                .map_or(FALLBACK_TERRAIN, |s| s.default_terrain())
        }
    }

    pub fn get_portal(&self, loc: Location) -> Option<Location> {
        self.finalize(loc.sector());
        self.internal_cache
            .borrow()
            .portals
            .get(&loc)
            .map(|&p| loc + p)
    }

    /// Return latest list of spawns.
    ///
    /// `WorldCache` will return spawns from regions that have been loaded into cache. Caller will
    /// need to frequenty re-call spawns() method to see if new entities should be spawned. Caller
    /// is expected to keep track of which spawn items it has already seen and not re-instantiate
    /// them if the cache get regenerated.
    pub fn drain_spawns(&mut self) -> Vec<(Location, EntitySpawn)> {
        mem::replace(
            &mut self.internal_cache.borrow_mut().spawn_queue,
            Vec::new(),
        )
    }

    /// Activate location in cache
    ///
    /// If the location's sector has world data specified, that world data will become available in
    /// the cache.
    fn touch(&self, loc: Location) { self.finalize(loc.sector()); }

    fn generate(&self, sector: Sector) {
        if !self.skeleton.contains_key(&sector) {
            // Outside world, skip.
            return;
        }

        if self
            .internal_cache
            .borrow()
            .constructed_sectors
            .contains(&sector)
        {
            // Already constructed, skip.
            return;
        }
        info!("WorldCache generating sector {:?}", sector);

        let map = sector::generate(self.seed, sector, &self.skeleton);

        // Load generated map into cache
        for (
            vec,
            MapCell {
                terrain, spawns, ..
            },
        ) in &map
        {
            let loc = sector.origin() + *vec;

            if *terrain != Terrain::Empty {
                self.internal_cache
                    .borrow_mut()
                    .terrain
                    .insert(loc, *terrain);
            }

            // World cache uses (location, spawn string) as the key to see if it already has
            // created a spawn. Duplicate spawn strings from one location will be ignored after the
            // first one when mapgen wanted to create multiple entities.
            debug_assert!(
                spawns.iter().collect::<HashSet<_>>().len() == spawns.len(),
                "Duplicates in mapgen spawns will not be generated correctly"
            );

            // Put spawns in pending list, don't want them to go live yet because they'd trigger a
            // cache cascade once their AI starts running.
            for s in spawns {
                self.internal_cache
                    .borrow_mut()
                    .pending_spawns
                    .entry(sector)
                    .or_insert_with(|| Vec::new())
                    .push((loc, s.clone()));
            }
        }

        if sector == PLAYER_START_SECTOR {
            self.internal_cache.borrow_mut().player_entrance =
                sector.origin() + map.player_entrance();
        }

        self.internal_cache
            .borrow_mut()
            .constructed_sectors
            .insert(sector);
    }

    /// Finalize a sector and make it ready for play.
    ///
    /// This step generates stairway exits.
    fn finalize(&self, sector: Sector) {
        if !self.skeleton.contains_key(&sector) {
            return;
        }

        if self
            .internal_cache
            .borrow()
            .finalized_sectors
            .contains(&sector)
        {
            return;
        }

        info!("WorldCache finalizing sector {:?}", sector);

        // Make sure sectors above and below are generated so we can determine portal locations.
        let above = sector + vec3(0, 0, 1);
        let below = sector + vec3(0, 0, -1);
        self.generate(above);
        self.generate(below);
        self.generate(sector);

        if let Some(my_up) = self.upstairs(sector) {
            let their_down = self
                .downstairs(above)
                .expect("No matching downstairs found");
            self.make_stairs(their_down, my_up);
        }

        if let Some(my_down) = self.downstairs(sector) {
            let their_up = self.upstairs(below).expect("No matching upstairs found");
            self.make_stairs(my_down, their_up);
        }

        let pending_spawns = self
            .internal_cache
            .borrow_mut()
            .pending_spawns
            .remove(&sector);

        if let Some(mut pending_spawns) = pending_spawns {
            self.internal_cache
                .borrow_mut()
                .spawn_queue
                .append(&mut pending_spawns);
        }

        self.internal_cache
            .borrow_mut()
            .finalized_sectors
            .insert(sector);
    }

    /// Find location of stairs down on sector.
    fn downstairs(&self, sector: Sector) -> Option<Location> {
        self.generate(sector);
        for loc in sector.iter() {
            if let Some(Terrain::Exit) = self.internal_cache.borrow().terrain.get(&loc) {
                return Some(loc);
            }
        }
        None
    }

    fn upstairs(&self, sector: Sector) -> Option<Location> {
        self.generate(sector);
        for loc in sector.iter() {
            if let Some(Terrain::Entrance) = self.internal_cache.borrow().terrain.get(&loc) {
                return Some(loc);
            }
        }
        None
    }

    /// Make a two-way stairwell portal.
    fn make_stairs(&self, downstairs: Location, upstairs: Location) {
        self.portal(upstairs, downstairs - vec2(1, 1));
        self.portal(downstairs, upstairs + vec2(1, 1));
    }

    /// Punch a (one-way) portal between two points.
    fn portal(&self, origin: Location, destination: Location) {
        self.internal_cache
            .borrow_mut()
            .portals
            .insert(origin, Portal::new(origin, destination));
    }
}

impl serde::Serialize for WorldCache {
    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
        (self.seed, &self.skeleton).serialize(s)
    }
}

impl<'a> serde::Deserialize<'a> for WorldCache {
    fn deserialize<D: serde::Deserializer<'a>>(d: D) -> Result<Self, D::Error> {
        let (seed, skeleton) = serde::Deserialize::deserialize(d)?;
        Ok(WorldCache::new(seed, skeleton))
    }
}

#[derive(Default)]
struct InternalCache {
    /// Sectors for which the terrain and entities have been constructed
    constructed_sectors: HashSet<Sector>,

    /// Sectors for which portal data has been generated.
    ///
    /// Portal data requires that sectors above and below have been constructed to see the opposite
    /// end of a stairway, so there needs to be the separate construction and finalization steps.
    finalized_sectors: HashSet<Sector>,

    terrain: HashMap<Location, Terrain>,
    portals: HashMap<Location, Portal>,

    pending_spawns: HashMap<Sector, Vec<(Location, EntitySpawn)>>,
    spawn_queue: Vec<(Location, EntitySpawn)>,

    player_entrance: Location,
}
<commit_msg>Remove unused method<commit_after>use crate::location::{Location, Portal};
use crate::map::MapCell;
use crate::sector::{self, Sector, WorldSkeleton};
use crate::spec::EntitySpawn;
use crate::terrain::Terrain;
use euclid::{vec2, vec3};
use log::info;
use serde;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::mem;

/// Convention for maps, player always starts at origin sector.
pub const PLAYER_START_SECTOR: Sector = Sector::new(0, 0, 0);

/// Lazy instantiator for the generated world defined by random seed and skeleton.
///
/// Uses interior mutability to update the cache. Probably very thread unsafe.
pub struct WorldCache {
    seed: u32,
    skeleton: WorldSkeleton,

    internal_cache: RefCell<InternalCache>,
}

impl WorldCache {
    /// Initiate the cache given the world description.
    pub fn new(seed: u32, skeleton: WorldSkeleton) -> WorldCache {
        WorldCache {
            seed,
            skeleton,
            internal_cache: Default::default(),
        }
    }

    pub fn seed(&self) -> u32 { self.seed }

    /// Get the location where the player enters the world.
    pub fn player_entrance(&self) -> Location {
        // Player start in sector 0. Expect generation logic to set player position when
        // constructing the sector.
        self.generate(PLAYER_START_SECTOR);
        self.internal_cache.borrow().player_entrance
    }

    pub fn get_terrain(&self, loc: Location) -> Terrain {
        const FALLBACK_TERRAIN: Terrain = Terrain::Rock;

        let sector = loc.sector();
        self.finalize(sector);
        if let Some(t) = self.internal_cache.borrow().terrain.get(&loc).cloned() {
            t
        } else {
            self.skeleton
                .get(&sector)
                .map_or(FALLBACK_TERRAIN, |s| s.default_terrain())
        }
    }

    pub fn get_portal(&self, loc: Location) -> Option<Location> {
        self.finalize(loc.sector());
        self.internal_cache
            .borrow()
            .portals
            .get(&loc)
            .map(|&p| loc + p)
    }

    /// Return latest list of spawns.
    ///
    /// `WorldCache` will return spawns from regions that have been loaded into cache. Caller will
    /// need to frequenty re-call spawns() method to see if new entities should be spawned. Caller
    /// is expected to keep track of which spawn items it has already seen and not re-instantiate
    /// them if the cache get regenerated.
    pub fn drain_spawns(&mut self) -> Vec<(Location, EntitySpawn)> {
        mem::replace(
            &mut self.internal_cache.borrow_mut().spawn_queue,
            Vec::new(),
        )
    }

    fn generate(&self, sector: Sector) {
        if !self.skeleton.contains_key(&sector) {
            // Outside world, skip.
            return;
        }

        if self
            .internal_cache
            .borrow()
            .constructed_sectors
            .contains(&sector)
        {
            // Already constructed, skip.
            return;
        }
        info!("WorldCache generating sector {:?}", sector);

        let map = sector::generate(self.seed, sector, &self.skeleton);

        // Load generated map into cache
        for (
            vec,
            MapCell {
                terrain, spawns, ..
            },
        ) in &map
        {
            let loc = sector.origin() + *vec;

            if *terrain != Terrain::Empty {
                self.internal_cache
                    .borrow_mut()
                    .terrain
                    .insert(loc, *terrain);
            }

            // World cache uses (location, spawn string) as the key to see if it already has
            // created a spawn. Duplicate spawn strings from one location will be ignored after the
            // first one when mapgen wanted to create multiple entities.
            debug_assert!(
                spawns.iter().collect::<HashSet<_>>().len() == spawns.len(),
                "Duplicates in mapgen spawns will not be generated correctly"
            );

            // Put spawns in pending list, don't want them to go live yet because they'd trigger a
            // cache cascade once their AI starts running.
            for s in spawns {
                self.internal_cache
                    .borrow_mut()
                    .pending_spawns
                    .entry(sector)
                    .or_insert_with(|| Vec::new())
                    .push((loc, s.clone()));
            }
        }

        if sector == PLAYER_START_SECTOR {
            self.internal_cache.borrow_mut().player_entrance =
                sector.origin() + map.player_entrance();
        }

        self.internal_cache
            .borrow_mut()
            .constructed_sectors
            .insert(sector);
    }

    /// Finalize a sector and make it ready for play.
    ///
    /// This step generates stairway exits.
    fn finalize(&self, sector: Sector) {
        if !self.skeleton.contains_key(&sector) {
            return;
        }

        if self
            .internal_cache
            .borrow()
            .finalized_sectors
            .contains(&sector)
        {
            return;
        }

        info!("WorldCache finalizing sector {:?}", sector);

        // Make sure sectors above and below are generated so we can determine portal locations.
        let above = sector + vec3(0, 0, 1);
        let below = sector + vec3(0, 0, -1);
        self.generate(above);
        self.generate(below);
        self.generate(sector);

        if let Some(my_up) = self.upstairs(sector) {
            let their_down = self
                .downstairs(above)
                .expect("No matching downstairs found");
            self.make_stairs(their_down, my_up);
        }

        if let Some(my_down) = self.downstairs(sector) {
            let their_up = self.upstairs(below).expect("No matching upstairs found");
            self.make_stairs(my_down, their_up);
        }

        let pending_spawns = self
            .internal_cache
            .borrow_mut()
            .pending_spawns
            .remove(&sector);

        if let Some(mut pending_spawns) = pending_spawns {
            self.internal_cache
                .borrow_mut()
                .spawn_queue
                .append(&mut pending_spawns);
        }

        self.internal_cache
            .borrow_mut()
            .finalized_sectors
            .insert(sector);
    }

    /// Find location of stairs down on sector.
    fn downstairs(&self, sector: Sector) -> Option<Location> {
        self.generate(sector);
        for loc in sector.iter() {
            if let Some(Terrain::Exit) = self.internal_cache.borrow().terrain.get(&loc) {
                return Some(loc);
            }
        }
        None
    }

    fn upstairs(&self, sector: Sector) -> Option<Location> {
        self.generate(sector);
        for loc in sector.iter() {
            if let Some(Terrain::Entrance) = self.internal_cache.borrow().terrain.get(&loc) {
                return Some(loc);
            }
        }
        None
    }

    /// Make a two-way stairwell portal.
    fn make_stairs(&self, downstairs: Location, upstairs: Location) {
        self.portal(upstairs, downstairs - vec2(1, 1));
        self.portal(downstairs, upstairs + vec2(1, 1));
    }

    /// Punch a (one-way) portal between two points.
    fn portal(&self, origin: Location, destination: Location) {
        self.internal_cache
            .borrow_mut()
            .portals
            .insert(origin, Portal::new(origin, destination));
    }
}

impl serde::Serialize for WorldCache {
    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
        (self.seed, &self.skeleton).serialize(s)
    }
}

impl<'a> serde::Deserialize<'a> for WorldCache {
    fn deserialize<D: serde::Deserializer<'a>>(d: D) -> Result<Self, D::Error> {
        let (seed, skeleton) = serde::Deserialize::deserialize(d)?;
        Ok(WorldCache::new(seed, skeleton))
    }
}

#[derive(Default)]
struct InternalCache {
    /// Sectors for which the terrain and entities have been constructed
    constructed_sectors: HashSet<Sector>,

    /// Sectors for which portal data has been generated.
    ///
    /// Portal data requires that sectors above and below have been constructed to see the opposite
    /// end of a stairway, so there needs to be the separate construction and finalization steps.
    finalized_sectors: HashSet<Sector>,

    terrain: HashMap<Location, Terrain>,
    portals: HashMap<Location, Portal>,

    pending_spawns: HashMap<Sector, Vec<(Location, EntitySpawn)>>,
    spawn_queue: Vec<(Location, EntitySpawn)>,

    player_entrance: Location,
}
<|endoftext|>


<commit_before>use webcore::value::Reference;
use webcore::try_from::TryInto;
use webapi::event_target::{IEventTarget, EventTarget};
use webapi::node::{INode, Node};
use webapi::element::{IElement, Element};
use webapi::html_element::{IHtmlElement, HtmlElement};

/// The HTML <textarea> element represents a multi-line plain-text editing control.
///
/// [(JavaScript docs)](https://developer.mozilla.org/en/docs/Web/HTML/Element/textarea)
// https://html.spec.whatwg.org/#htmltextareaelement
#[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
#[reference(instance_of = "HTMLTextAreaElement")]
#[reference(subclass_of(EventTarget, Node, Element, HtmlElement))]
pub struct TextAreaElement( Reference );

impl IEventTarget for TextAreaElement {}
impl INode for TextAreaElement {}
impl IElement for TextAreaElement {}
impl IHtmlElement for TextAreaElement {}

impl TextAreaElement {
    /// The value of the control.
    // https://html.spec.whatwg.org/#the-textarea-element:dom-textarea-value
    #[inline]
    pub fn value( &self ) -> String {
        js! (
            return @{self}.value;
        ).try_into().unwrap()
    }

    /// Sets the value of the control.
    // https://html.spec.whatwg.org/#the-textarea-element:dom-textarea-value
    #[inline]
    pub fn set_value( &self, value: &str ) {
        js! { @(no_return)
            @{self}.value = @{value};
        }
    }
}
<commit_msg>Escape `<textarea>`<commit_after>use webcore::value::Reference;
use webcore::try_from::TryInto;
use webapi::event_target::{IEventTarget, EventTarget};
use webapi::node::{INode, Node};
use webapi::element::{IElement, Element};
use webapi::html_element::{IHtmlElement, HtmlElement};

/// The HTML `<textarea>` element represents a multi-line plain-text editing control.
///
/// [(JavaScript docs)](https://developer.mozilla.org/en/docs/Web/HTML/Element/textarea)
// https://html.spec.whatwg.org/#htmltextareaelement
#[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
#[reference(instance_of = "HTMLTextAreaElement")]
#[reference(subclass_of(EventTarget, Node, Element, HtmlElement))]
pub struct TextAreaElement( Reference );

impl IEventTarget for TextAreaElement {}
impl INode for TextAreaElement {}
impl IElement for TextAreaElement {}
impl IHtmlElement for TextAreaElement {}

impl TextAreaElement {
    /// The value of the control.
    // https://html.spec.whatwg.org/#the-textarea-element:dom-textarea-value
    #[inline]
    pub fn value( &self ) -> String {
        js! (
            return @{self}.value;
        ).try_into().unwrap()
    }

    /// Sets the value of the control.
    // https://html.spec.whatwg.org/#the-textarea-element:dom-textarea-value
    #[inline]
    pub fn set_value( &self, value: &str ) {
        js! { @(no_return)
            @{self}.value = @{value};
        }
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2017 Sreejith Krishnan R
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

use ::props::*;
use ::layout::PresentationLayout;
use super::{Property, Element, InheritedProps, StyleProps};
use ::platform::Context;

#[derive(Default)]
pub struct SpecifiedPresentationProps {
    pub(crate) math_color: Option<Color>,
    pub(crate) math_background: Option<Color>,
}

pub trait PresentationPrivate<T: Element> {
    const PROP_MATH_COLOR: Property<Color, T> = Property::Inherited {
        reader:                 |p| p.math_color(),
    };

    const PROP_MATH_BACKGROUND: Property<Color, T> = Property::Specified {
        default:                || Color::transparent(),
        reader:                 |s| s.math_background(),
    };

    const PROP_DISPLAY_STYLE: Property<DisplayStyle, T> = Property::Inherited {
        reader:                 |p| p.display_style(),
    };

    const PROP_SCRIPT_LEVEL: Property<ScriptLevel, T> = Property::Inherited {
        reader:                 |p| p.script_level(),
    };

    const PROP_SCRIPT_MIN_SIZE: Property<ScriptMinSize, T> = Property::Inherited {
        reader:                 |p| p.script_min_size(),
    };

    const PROP_SCRIPT_SIZE_MULTIPLIER: Property<ScriptSizeMultiplier, T> = Property::Inherited {
        reader:                 |p| p.script_size_multiplier(),
    };

    fn get_specified_presentation_props(&self) -> &SpecifiedPresentationProps;
    fn get_specified_presentation_props_mut(&mut self) -> &mut SpecifiedPresentationProps;

    fn layout_presentation(
        &self, element: &T, context: &Context, parent: Option<&Element>, inherited: &InheritedProps,
        style: &Option<&StyleProps>) -> PresentationLayout {
        let specified = self.get_specified_presentation_props();

        PresentationLayout {
            math_color: Self::PROP_MATH_COLOR.calculate(
                context, element, specified.math_color.as_ref(), &parent, inherited, style),
            math_background: Self::PROP_MATH_BACKGROUND.calculate(
                context, element, specified.math_color.as_ref(), &parent, inherited, style),
            display_style: Self::PROP_DISPLAY_STYLE.calculate(
                context, element, None, &parent, inherited, style),
            script_level: Self::PROP_SCRIPT_LEVEL.calculate(
                context, element, None, &parent, inherited, style),
            script_min_size: Self::PROP_SCRIPT_MIN_SIZE.calculate(
                context, element, None, &parent, inherited, style),
            script_size_multiplier: Self::PROP_SCRIPT_SIZE_MULTIPLIER.calculate(
                context, element, None, &parent, inherited, style),
        }
    }
}

pub trait Presentation<T: Element> : PresentationPrivate<T> + Sized {
    fn with_math_color<'a>(&'a mut self, color: Option<Color>) -> &'a mut Self {
        self.get_specified_presentation_props_mut().math_color = color;
        self
    }

    fn with_math_background<'a>(&'a mut self, color: Option<Color>) -> &'a Self {
        self.get_specified_presentation_props_mut().math_background = color;
        self
    }

    fn get_math_color(&self) -> Option<&Color> {
        self.get_specified_presentation_props().math_color.as_ref()
    }

    fn get_math_background(&self) -> Option<&Color> {
        self.get_specified_presentation_props().math_background.as_ref()
    }
}<commit_msg>Fix math background not displayed<commit_after>/*
 * Copyright 2017 Sreejith Krishnan R
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

use ::props::*;
use ::layout::PresentationLayout;
use super::{Property, Element, InheritedProps, StyleProps};
use ::platform::Context;

#[derive(Default)]
pub struct SpecifiedPresentationProps {
    pub(crate) math_color: Option<Color>,
    pub(crate) math_background: Option<Color>,
}

pub trait PresentationPrivate<T: Element> {
    const PROP_MATH_COLOR: Property<Color, T> = Property::Inherited {
        reader:                 |p| p.math_color(),
    };

    const PROP_MATH_BACKGROUND: Property<Color, T> = Property::Specified {
        default:                || Color::transparent(),
        reader:                 |s| s.math_background(),
    };

    const PROP_DISPLAY_STYLE: Property<DisplayStyle, T> = Property::Inherited {
        reader:                 |p| p.display_style(),
    };

    const PROP_SCRIPT_LEVEL: Property<ScriptLevel, T> = Property::Inherited {
        reader:                 |p| p.script_level(),
    };

    const PROP_SCRIPT_MIN_SIZE: Property<ScriptMinSize, T> = Property::Inherited {
        reader:                 |p| p.script_min_size(),
    };

    const PROP_SCRIPT_SIZE_MULTIPLIER: Property<ScriptSizeMultiplier, T> = Property::Inherited {
        reader:                 |p| p.script_size_multiplier(),
    };

    fn get_specified_presentation_props(&self) -> &SpecifiedPresentationProps;
    fn get_specified_presentation_props_mut(&mut self) -> &mut SpecifiedPresentationProps;

    fn layout_presentation(
        &self, element: &T, context: &Context, parent: Option<&Element>, inherited: &InheritedProps,
        style: &Option<&StyleProps>) -> PresentationLayout {
        let specified = self.get_specified_presentation_props();

        PresentationLayout {
            math_color: Self::PROP_MATH_COLOR.calculate(
                context, element, specified.math_color.as_ref(), &parent, inherited, style),
            math_background: Self::PROP_MATH_BACKGROUND.calculate(
                context, element, specified.math_background.as_ref(), &parent, inherited, style),
            display_style: Self::PROP_DISPLAY_STYLE.calculate(
                context, element, None, &parent, inherited, style),
            script_level: Self::PROP_SCRIPT_LEVEL.calculate(
                context, element, None, &parent, inherited, style),
            script_min_size: Self::PROP_SCRIPT_MIN_SIZE.calculate(
                context, element, None, &parent, inherited, style),
            script_size_multiplier: Self::PROP_SCRIPT_SIZE_MULTIPLIER.calculate(
                context, element, None, &parent, inherited, style),
        }
    }
}

pub trait Presentation<T: Element> : PresentationPrivate<T> + Sized {
    fn with_math_color<'a>(&'a mut self, color: Option<Color>) -> &'a mut Self {
        self.get_specified_presentation_props_mut().math_color = color;
        self
    }

    fn with_math_background<'a>(&'a mut self, color: Option<Color>) -> &'a Self {
        self.get_specified_presentation_props_mut().math_background = color;
        self
    }

    fn get_math_color(&self) -> Option<&Color> {
        self.get_specified_presentation_props().math_color.as_ref()
    }

    fn get_math_background(&self) -> Option<&Color> {
        self.get_specified_presentation_props().math_background.as_ref()
    }
}<|endoftext|>


<commit_before>#![crate_id = "argparse"]
#![crate_type = "lib"]

use std::os;
use std::rc::Rc;
use std::cell::RefCell;
use std::slice::Items;

pub enum Action<'a> {
    StoreTrue(Rc<RefCell<&'a mut bool>>),
    StoreFalse(Rc<RefCell<&'a mut bool>>),
}

struct DashOption<'a> {
    options: ~[&'a str],
    help: &'a str,
    action: Action<'a>,
}

struct Argument<'a> {
    name: &'a str,
    help: &'a str,
    action: Action<'a>,
}

pub struct ArgumentParser<'a> {
    priv options: ~[DashOption<'a>],
    priv arguments: ~[Argument<'a>],
}

struct Context<'a, 'b> {
    //parser: &'a ArgumentParser<'b>,
    options: &'a [DashOption<'b>],
    arguments: &'a [Argument<'b>],
    iter: Items<'a, ~str>,
}

impl<'a, 'b> Context<'a, 'b> {
    fn parse_argument(&mut self, arg: &str) {
    }

    fn parse_option(&mut self, opt: &DashOption) {
        match opt.action {
            StoreTrue(ref cell) => {
                **cell.borrow_mut() = true;
            }
            StoreFalse(ref cell) => {
                **cell.borrow_mut() = false;
            }
        }
    }

    fn parse_long_option<'c>(&'c mut self, arg: &str) {
        for opt in self.options.iter() {
            for tname in opt.options.iter() {
                if arg.eq(tname) {
                    self.parse_option(opt);
                    return;
                }
            }
        }
    }

    fn new<'c, 'd>(parser: &'c ArgumentParser<'d>, args: &'c[~str])
        -> Context<'c, 'd>
    {
        return Context {
            options: parser.options,
            arguments: parser.arguments,
            iter: args.iter(),
        };
    }

    fn parse(&mut self) {
        loop {
            let next = self.iter.next();
            match next {
                Some(arg) => {
                    // positional args: ^$, ^-$, ^[^-].*
                    if arg.len() < 2 || arg[0] != ('-' as u8) {
                        self.parse_argument(*arg);
                    } else if arg[1] == ('-' as u8) {
                        self.parse_long_option(*arg);
                    }
                }
                None => {
                    break;
                }
            }
        }
    }
}

impl<'a> ArgumentParser<'a> {
    fn new() -> ArgumentParser {
        return ArgumentParser {
            arguments: ~[],
            options: ~[],
            };
    }
    fn add_option<'c>(&'c mut self, names: ~[&'a str],
        help: &'a str, action: Action<'a>) {
        self.options.push(DashOption {
            options: names,
            help: help,
            action: action,
            });
    }
    /*
    fn add_argument<'b>(&'b mut self, name: &'a str,
        help: &'a str, action: Action<'a>) {
        self.arguments.push(Argument {
            name: name,
            help: help,
            action: action,
        })
    }
    */

    fn parse_args(&self, args: ~[~str]) {
        Context::new(self, args).parse();
    }
}

fn cell<'a, T>(val: &'a mut T) -> Rc<RefCell<&'a mut T>> {
    return Rc::new(RefCell::new(val));
}

#[test]
fn test_no_arg() {
    let ap = ArgumentParser::new();
    ap.parse_args(os::args());
}

#[test]
fn test_store_true() {
    let mut verbose = false;
    let mut ap = ArgumentParser::new();
    ap.add_option(~["-t", "--true"],
        "Store true action",
        StoreTrue(cell(&mut verbose)));
    assert!(!verbose);
    ap.parse_args(~[~"./argparse_test"]);
    assert!(!verbose);
    ap.parse_args(~[~"./argparse_test", ~"--true"]);
    assert!(verbose);
}

#[test]
fn test_store_false() {
    let mut verbose = true;
    let mut ap = ArgumentParser::new();
    ap.add_option(~["-f", "--false"],
        "Store false action",
        StoreFalse(cell(&mut verbose)));
    assert!(verbose);
    ap.parse_args(~[~"./argparse_test"]);
    assert!(verbose);
    ap.parse_args(~[~"./argparse_test", ~"--false"]);
    assert!(!verbose);
}

/*
#[test]
fn test_verbose() {
    let mut opt = Options {
        verbose: false,
        debug: false,
        };
    {
        let mut ap = ArgumentParser::new();
        let vcell = cell(&mut opt.verbose);
        ap.add_option(~["-v", "--verbose"],
            "Turn on verbose mode",
            StoreTrue(vcell.clone()));
        ap.add_option(~["-q", "--quiet"],
            "Turn on quiet mode",
            StoreFalse(vcell.clone()));
        ap.add_option(~["-d", "--debug"],
            "Enable debugging",
            StoreTrue(cell(&mut opt.debug)));
        ap.parse_args(~[~"./argparse_test", ~"-v"]);
    }
    assert!(opt.verbose);
    assert!(opt.debug);
}

*/
<commit_msg>Implement short option parsing<commit_after>#![crate_id = "argparse"]
#![crate_type = "lib"]

extern crate collections;

use std::os;
use std::rc::Rc;
use std::cell::RefCell;
use std::slice::Items;
use collections::hashmap::HashMap;

pub enum Action<'a> {
    StoreTrue(Rc<RefCell<&'a mut bool>>),
    StoreFalse(Rc<RefCell<&'a mut bool>>),
}

struct DashOption<'a> {
    options: ~[&'a str],
    help: &'a str,
    action: Action<'a>,
}

struct Argument<'a> {
    name: &'a str,
    help: &'a str,
    action: Action<'a>,
}

pub struct ArgumentParser<'a> {
    priv options: ~[Rc<DashOption<'a>>],
    priv arguments: ~[Rc<Argument<'a>>],
    priv short_options: HashMap<char, Rc<DashOption<'a>>>,
    priv long_options: HashMap<&'a str, Rc<DashOption<'a>>>,
}

struct Context<'a, 'b> {
    parser: &'a ArgumentParser<'b>,
    iter: Items<'a, ~str>,
}

impl<'a> Action<'a> {
    fn has_arg(&self) -> bool {
        return match *self {
            StoreTrue(_) => false,
            StoreFalse(_) => false,
        }
    }
}

impl<'a, 'b> Context<'a, 'b> {
    fn parse_argument(&mut self, arg: &str) {
    }

    fn parse_option(&mut self, opt: &DashOption) {
        match opt.action {
            StoreTrue(ref cell) => {
                **cell.borrow_mut() = true;
            }
            StoreFalse(ref cell) => {
                **cell.borrow_mut() = false;
            }
        }
    }

    fn parse_long_option<'c>(&'c mut self, arg: &str) {
        for (name, opt) in self.parser.long_options.iter() {
            if arg.eq(name) {
                self.parse_option(&**opt);
                return;
            }
        }
    }

    fn parse_short_options<'c>(&'c mut self, arg: &str) {
        let mut iter = arg.chars();
        iter.next();
        for ch in iter {
            match self.parser.short_options.find(&ch) {
                Some(opt) => {
                    self.parse_option(&**opt);
                }
                None => {
                    fail!("Unknown short option \"{}\"", ch);
                }
            }
        }
    }

    fn new<'c, 'd>(parser: &'c ArgumentParser<'d>, args: &'c[~str])
        -> Context<'c, 'd>
    {
        return Context {
            parser: parser,
            iter: args.iter(),
        };
    }

    fn parse(&mut self) {
        loop {
            let next = self.iter.next();
            match next {
                Some(arg) => {
                    if is_argument(*arg) {
                        self.parse_argument(*arg);
                    } else if arg[1] == ('-' as u8) {
                        self.parse_long_option(*arg);
                    } else {
                        self.parse_short_options(*arg);
                    }
                }
                None => {
                    break;
                }
            }
        }
    }
}

impl<'a> ArgumentParser<'a> {
    fn new() -> ArgumentParser {
        return ArgumentParser {
            arguments: ~[],
            options: ~[],
            short_options: HashMap::new(),
            long_options: HashMap::new(),
            };
    }
    fn add_option<'c>(&'c mut self, names: ~[&'a str],
        help: &'a str, action: Action<'a>) {
        let opt = Rc::new(DashOption {
            options: names,
            help: help,
            action: action,
            });
        self.options.push(opt.clone());
        for _n in opt.options.iter() {
            let name = *_n;
            if is_argument(name) {
                fail!("Bad argument name {}", name);
            } else if name[1] == ('-' as u8) {
                self.long_options.insert(name, opt.clone());
            } else if name.len() > 2 {
                fail!("Bad short option {}", name);
            } else {
                self.short_options.insert(name[1] as char, opt.clone());
            }
        }
    }
    /*
    fn add_argument<'b>(&'b mut self, name: &'a str,
        help: &'a str, action: Action<'a>) {
        self.arguments.push(Argument {
            name: name,
            help: help,
            action: action,
        })
    }
    */

    fn parse_args(&self, args: ~[~str]) {
        Context::new(self, args).parse();
    }
}

fn is_argument(name: &str) -> bool {
    return name.len() < 2 || name[0] != ('-' as u8);
}

pub fn cell<'a, T>(val: &'a mut T) -> Rc<RefCell<&'a mut T>> {
    return Rc::new(RefCell::new(val));
}

#[test]
fn test_no_arg() {
    let ap = ArgumentParser::new();
    ap.parse_args(os::args());
}

#[test]
fn test_store_true() {
    let mut verbose = false;
    let mut ap = ArgumentParser::new();
    ap.add_option(~["-t", "--true"],
        "Store true action",
        StoreTrue(cell(&mut verbose)));
    assert!(!verbose);
    ap.parse_args(~[~"./argparse_test"]);
    assert!(!verbose);
    ap.parse_args(~[~"./argparse_test", ~"--true"]);
    assert!(verbose);
}

#[test]
fn test_store_false() {
    let mut verbose = true;
    let mut ap = ArgumentParser::new();
    ap.add_option(~["-f", "--false"],
        "Store false action",
        StoreFalse(cell(&mut verbose)));
    assert!(verbose);
    ap.parse_args(~[~"./argparse_test"]);
    assert!(verbose);
    ap.parse_args(~[~"./argparse_test", ~"--false"]);
    assert!(!verbose);
}

#[test]
fn test_bool() {
    let mut verbose = false;
    let mut ap = ArgumentParser::new();
    let c = cell(&mut verbose);
    ap.add_option(~["-f", "--false"],
        "Store false action",
        StoreFalse(c.clone()));
    ap.add_option(~["-t", "--true"],
        "Store false action",
        StoreTrue(c.clone()));
    assert!(!verbose);
    ap.parse_args(~[~"./argparse_test"]);
    assert!(!verbose);
    ap.parse_args(~[~"./argparse_test", ~"-t"]);
    assert!(verbose);
    ap.parse_args(~[~"./argparse_test", ~"-f"]);
    assert!(!verbose);
    ap.parse_args(~[~"./argparse_test", ~"-fft"]);
    assert!(verbose);
    ap.parse_args(~[~"./argparse_test", ~"-fffft", ~"-f"]);
    assert!(!verbose);
    ap.parse_args(~[~"./argparse_test", ~"--false", ~"-fffft", ~"-f",
                    ~"--true"]);
    assert!(verbose);
}

/*
#[test]
fn test_verbose() {
    let mut opt = Options {
        verbose: false,
        debug: false,
        };
    {
        let mut ap = ArgumentParser::new();
        let vcell = cell(&mut opt.verbose);
        ap.add_option(~["-v", "--verbose"],
            "Turn on verbose mode",
            StoreTrue(vcell.clone()));
        ap.add_option(~["-q", "--quiet"],
            "Turn on quiet mode",
            StoreFalse(vcell.clone()));
        ap.add_option(~["-d", "--debug"],
            "Enable debugging",
            StoreTrue(cell(&mut opt.debug)));
        ap.parse_args(~[~"./argparse_test", ~"-v"]);
    }
    assert!(opt.verbose);
    assert!(opt.debug);
}

*/
<|endoftext|>


<commit_before>use std::{cell::RefCell, collections::BTreeMap};

use dces::prelude::*;

use crate::{
    prelude::*, proc_macros::IntoLayout, render::RenderContext2D, theming::*, tree::Tree,
    utils::prelude::*,
};

use super::{component, component_or_default, component_try_mut, try_component, Layout};

/// The `PopupLayout` handles measuring and arrangement of a `Popup` widget.
#[derive(Default, IntoLayout)]
pub struct PopupLayout {
    // TODO: Add padding to the widget.
    desired_size: RefCell<DirtySize>,
}

/// Associated functions, that react on any given state change inside the `Popup` widget.
impl PopupLayout {
    /// Instatiate a new PopupLayout object.
    pub fn new() -> Self {
	PopupLayout::default()
    }
}

impl Layout for PopupLayout {
    fn measure(
	&self,
	render_context_2_d: &mut RenderContext2D,
	entity: Entity,
	ecm: &mut EntityComponentManager<Tree>,
	layouts: &BTreeMap<Entity, Box<dyn Layout>>,
	theme: &Theme,
    ) -> DirtySize {
	// if visibility is collapsed, the entity is rendered but
	// shouldn't consume any size in the render buffer.
	if component::<Visibility>(ecm, entity, "visibility") == Visibility::Collapsed {
	    self.desired_size.borrow_mut().set_size(0.0, 0.0);
	    return *self.desired_size.borrow();
	}

	if let Some(target) = try_component::<PopupTarget>(ecm, entity, "target") {
	    let current_bounds: Rectangle = component(ecm, entity, "bounds");
	    let current_constraint: Constraint = component(ecm, entity, "constraint");

	    let real_target_bounds = match target {
		PopupTarget::Entity(entity) => {
		    let target_position: Point = component(ecm, entity, "position");

		    // WARNING: widget bounds (width an height values)
		    // will be measured as available space for the
		    // widget. Only in state `post_layout_update` it
		    // will reflect the effective size of the given
		    // entity.
		    let mut target_bounds: Rectangle = component(ecm, entity, "bounds");
		    target_bounds.set_position(target_position);
		    target_bounds
		}
		PopupTarget::Point(mut point) => {
		    point.set_x(point.x() + current_bounds.width() / 2.0);
		    point.set_y(point.y() + current_bounds.height() / 2.0);
		    Rectangle::new(point, (0.0, 0.0))
		}
	    };

	    let placement: Placement = component_or_default(ecm, entity, "placement");

	    let new_popup_size = match placement {
		Placement::Bottom => {
		    let current_h_align: Alignment = component(ecm, entity, "h_align");

		    let width = current_h_align.align_measure(
			real_target_bounds.width(),
			current_bounds.width(),
			0.0,
			0.0,
		    );
		    let height = current_bounds.height();

		    //let y = real_target_bounds.y() - current_bounds.height();

		    current_constraint.perform((width, height))
		}
		Placement::BottomLeft => {
		    let current_h_align: Alignment = component(ecm, entity, "h_align");

		    let width = current_h_align.align_measure(
			real_target_bounds.width(),
			current_bounds.width(),
			0.0,
			0.0,
		    );
		    let height = current_bounds.height();

		    current_constraint.perform((width, height))
		}
		Placement::BottomRight => {
		    let current_h_align: Alignment = component(ecm, entity, "h_align");

		    let width = current_h_align.align_measure(
			real_target_bounds.width(),
			current_bounds.width(),
			0.0,
			0.0,
		    );
		    let height = current_bounds.height();

		    current_constraint.perform((width, height))
		}
		Placement::Left => {
		    let current_v_align: Alignment = component(ecm, entity, "v_align");

		    let width = current_bounds.width();
		    let height = current_v_align.align_measure(
			real_target_bounds.height(),
			current_bounds.height(),
			0.0,
			0.0,
		    );

		    // respect given bound constraints
		    current_constraint.perform((width, height))
		}
		Placement::Right => {
		    let current_v_align: Alignment = component(ecm, entity, "v_align");

		    let width = current_bounds.width();
		    let height = current_v_align.align_measure(
			real_target_bounds.height(),
			current_bounds.height(),
			0.0,
			0.0,
		    );

		    current_constraint.perform((width, height))
		}
		Placement::Top => {
		    let current_h_align: Alignment = component(ecm, entity, "h_align");

		    let width = current_h_align.align_measure(
			real_target_bounds.width(),
			current_bounds.width(),
			0.0,
			0.0,
		    );
		    let height = current_bounds.height();

		    current_constraint.perform((width, height))
		}
		Placement::TopLeft => {
		    let current_h_align: Alignment = component(ecm, entity, "h_align");

		    let width = current_h_align.align_measure(
			real_target_bounds.width(),
			current_bounds.width(),
			0.0,
			0.0,
		    );
		    let height = current_bounds.height();

		    current_constraint.perform((width, height))
		}
		Placement::TopRight => {
		    let current_h_align: Alignment = component(ecm, entity, "h_align");

		    let width = current_h_align.align_measure(
			real_target_bounds.width(),
			current_bounds.width(),
			0.0,
			0.0,
		    );
		    let height = current_bounds.height();

		    current_constraint.perform((width, height))
		}
	    };

	    {
		let mut desired_size = self.desired_size.borrow_mut();
		desired_size.set_width(new_popup_size.0);
		desired_size.set_height(new_popup_size.1);
	    }

	    let padding: Thickness = component(ecm, entity, "padding");
	    for index in 0..ecm.entity_store().children[&entity].len() {
		let child = ecm.entity_store().children[&entity][index];

		if let Some(child_layout) = layouts.get(&child) {
		    let child_desired_size =
			child_layout.measure(render_context_2_d, child, ecm, layouts, theme);
		    let mut desired_size = self.desired_size.borrow().size();

		    let dirty = child_desired_size.dirty() || self.desired_size.borrow().dirty();
		    self.desired_size.borrow_mut().set_dirty(dirty);

		    let child_margin = *ecm
			.component_store()
			.get::<Thickness>("margin", child)
			.unwrap();

		    desired_size.0 = desired_size.0.max(
			child_desired_size.width()
			    + padding.left()
			    + padding.right()
			    + child_margin.left()
			    + child_margin.right(),
		    );
		    desired_size.1 = desired_size.1.max(
			child_desired_size.height()
			    + padding.top()
			    + padding.bottom()
			    + child_margin.top()
			    + child_margin.left(),
		    );

		    self.desired_size
			.borrow_mut()
			.set_size(desired_size.0, desired_size.1);
		}
	    }
	} else {
	    println!("Target not found");
	}

	*self.desired_size.borrow()
    }

    fn arrange(
	&self,
	render_context_2_d: &mut RenderContext2D,
	parent_size: (f64, f64),
	entity: Entity,
	ecm: &mut EntityComponentManager<Tree>,
	layouts: &BTreeMap<Entity, Box<dyn Layout>>,
	theme: &Theme,
    ) -> (f64, f64) {
	if component::<Visibility>(ecm, entity, "visibility") == Visibility::Collapsed {
	    self.desired_size.borrow_mut().set_size(0.0, 0.0);
	    return (0.0, 0.0);
	}

	if !self.desired_size.borrow().dirty() {
	    return self.desired_size.borrow().size();
	}

	let horizontal_alignment: Alignment = component(ecm, entity, "h_align");
	let vertical_alignment: Alignment = component(ecm, entity, "v_align");
	let margin = *ecm
	    .component_store()
	    .get::<Thickness>("margin", entity)
	    .unwrap();
	let padding: Thickness = component(ecm, entity, "padding");
	let constraint: Constraint = component(ecm, entity, "constraint");

	let size = constraint.perform((
	    horizontal_alignment.align_measure(
		parent_size.0,
		self.desired_size.borrow().width(),
		margin.left(),
		margin.right(),
	    ),
	    vertical_alignment.align_measure(
		parent_size.1,
		self.desired_size.borrow().height(),
		margin.top(),
		margin.bottom(),
	    ),
	));

	if let Some(bounds) = component_try_mut::<Rectangle>(ecm, entity, "bounds") {
	    bounds.set_width(size.0);
	    bounds.set_height(size.1);
	}

	mark_as_dirty("bounds", entity, ecm);

	let available_size = (
	    size.0 - padding.left() - padding.right(),
	    size.1 - padding.top() - padding.bottom(),
	);

	for index in 0..ecm.entity_store().children[&entity].len() {
	    let child = ecm.entity_store().children[&entity][index];

	    let child_margin: Thickness = component(ecm, entity, "margin");

	    if let Some(child_layout) = layouts.get(&child) {
		child_layout.arrange(
		    render_context_2_d,
		    available_size,
		    child,
		    ecm,
		    layouts,
		    theme,
		);
	    }

	    let child_horizontal_alignment: Alignment =
		*ecm.component_store().get("h_align", child).unwrap();
	    let child_vertical_alignment: Alignment =
		*ecm.component_store().get("v_align", child).unwrap();
	    if let Ok(child_bounds) = ecm
		.component_store_mut()
		.get_mut::<Rectangle>("bounds", child)
	    {
		child_bounds.set_x(
		    padding.left()
			+ child_horizontal_alignment.align_position(
			    available_size.0,
			    child_bounds.width(),
			    child_margin.left(),
			    child_margin.right(),
			),
		);
		child_bounds.set_y(
		    padding.top()
			+ child_vertical_alignment.align_position(
			    available_size.1,
			    child_bounds.height(),
			    child_margin.top(),
			    child_margin.bottom(),
			),
		);
	    }

	    mark_as_dirty("bounds", child, ecm);
	}

	self.desired_size.borrow_mut().set_dirty(false);
	size
    }
}
<commit_msg>orbtk_core: layout popup update<commit_after>use std::{cell::RefCell, collections::BTreeMap};

use dces::prelude::*;

use crate::{
    prelude::*, proc_macros::IntoLayout, render::RenderContext2D, theming::*, tree::Tree,
    utils::prelude::*,
};

use super::{component, component_or_default, component_try_mut, try_component, Layout};

/// The `PopupLayout` handles measuring and arrangement of a `Popup` widget.
#[derive(Default, IntoLayout)]
pub struct PopupLayout {
    // TODO: Add padding to the widget.
    desired_size: RefCell<DirtySize>,
}

/// Associated functions, that react on any given state change inside the `Popup` widget.
impl PopupLayout {
    /// Instatiate a new PopupLayout object.
    pub fn new() -> Self {
	PopupLayout::default()
    }
}

impl Layout for PopupLayout {
    fn measure(
	&self,
	render_context_2_d: &mut RenderContext2D,
	entity: Entity,
	ecm: &mut EntityComponentManager<Tree>,
	layouts: &BTreeMap<Entity, Box<dyn Layout>>,
	theme: &Theme,
    ) -> DirtySize {
	// if visibility is collapsed, the entity is rendered but
	// shouldn't consume any size in the render buffer.
	if component::<Visibility>(ecm, entity, "visibility") == Visibility::Collapsed {
	    self.desired_size.borrow_mut().set_size(0.0, 0.0);
	    return *self.desired_size.borrow();
	}

	if let Some(target) = try_component::<PopupTarget>(ecm, entity, "target") {
	    let current_bounds: Rectangle = component(ecm, entity, "bounds");
	    let current_constraint: Constraint = component(ecm, entity, "constraint");

	    let real_target_bounds = match target {
		PopupTarget::Entity(entity) => {
		    let target_position: Point = component(ecm, entity, "position");

		    // WARNING: widget bounds (width an height values)
		    // will be measured as available space for the
		    // widget. Only in state `post_layout_update` it
		    // will reflect the effective size of the given
		    // entity.
		    let mut target_bounds: Rectangle = component(ecm, entity, "bounds");
		    target_bounds.set_position(target_position);
		    target_bounds
		}
		PopupTarget::Point(mut point) => {
		    point.set_x(point.x() + current_bounds.width() / 2.0);
		    point.set_y(point.y() + current_bounds.height() / 2.0);
		    Rectangle::new(point, (0.0, 0.0))
		}
	    };

	    let placement: Placement = component_or_default(ecm, entity, "placement");

	    let new_popup_size = match placement {
		Placement::Bottom => {
		    let current_h_align: Alignment = component(ecm, entity, "h_align");

		    let width = current_h_align.align_measure(
			real_target_bounds.width(),
			current_bounds.width(),
			0.0,
			0.0,
		    );
		    let height = current_bounds.height();

		    //let y = real_target_bounds.y() - current_bounds.height();

		    current_constraint.perform((width, height))
		}
		Placement::Left => {
		    let current_v_align: Alignment = component(ecm, entity, "v_align");

		    let width = current_bounds.width();
		    let height = current_v_align.align_measure(
			real_target_bounds.height(),
			current_bounds.height(),
			0.0,
			0.0,
		    );

		    // respect given bound constraints
		    current_constraint.perform((width, height))
		}
		Placement::Right => {
		    let current_v_align: Alignment = component(ecm, entity, "v_align");

		    let width = current_bounds.width();
		    let height = current_v_align.align_measure(
			real_target_bounds.height(),
			current_bounds.height(),
			0.0,
			0.0,
		    );

		    current_constraint.perform((width, height))
		}
		Placement::Top => {
		    let current_h_align: Alignment = component(ecm, entity, "h_align");

		    let width = current_h_align.align_measure(
			real_target_bounds.width(),
			current_bounds.width(),
			0.0,
			0.0,
		    );
		    let height = current_bounds.height();

		    current_constraint.perform((width, height))
		}
	    };

	    {
		let mut desired_size = self.desired_size.borrow_mut();
		desired_size.set_width(new_popup_size.0);
		desired_size.set_height(new_popup_size.1);
	    }

	    let padding: Thickness = component(ecm, entity, "padding");
	    for index in 0..ecm.entity_store().children[&entity].len() {
		let child = ecm.entity_store().children[&entity][index];

		if let Some(child_layout) = layouts.get(&child) {
		    let child_desired_size =
			child_layout.measure(render_context_2_d, child, ecm, layouts, theme);
		    let mut desired_size = self.desired_size.borrow().size();

		    let dirty = child_desired_size.dirty() || self.desired_size.borrow().dirty();
		    self.desired_size.borrow_mut().set_dirty(dirty);

		    let child_margin = *ecm
			.component_store()
			.get::<Thickness>("margin", child)
			.unwrap();

		    desired_size.0 = desired_size.0.max(
			child_desired_size.width()
			    + padding.left()
			    + padding.right()
			    + child_margin.left()
			    + child_margin.right(),
		    );
		    desired_size.1 = desired_size.1.max(
			child_desired_size.height()
			    + padding.top()
			    + padding.bottom()
			    + child_margin.top()
			    + child_margin.left(),
		    );

		    self.desired_size
			.borrow_mut()
			.set_size(desired_size.0, desired_size.1);
		}
	    }
	} else {
	    println!("Target not found");
	}

	*self.desired_size.borrow()
    }

    fn arrange(
	&self,
	render_context_2_d: &mut RenderContext2D,
	parent_size: (f64, f64),
	entity: Entity,
	ecm: &mut EntityComponentManager<Tree>,
	layouts: &BTreeMap<Entity, Box<dyn Layout>>,
	theme: &Theme,
    ) -> (f64, f64) {
	if component::<Visibility>(ecm, entity, "visibility") == Visibility::Collapsed {
	    self.desired_size.borrow_mut().set_size(0.0, 0.0);
	    return (0.0, 0.0);
	}

	if !self.desired_size.borrow().dirty() {
	    return self.desired_size.borrow().size();
	}

	let horizontal_alignment: Alignment = component(ecm, entity, "h_align");
	let vertical_alignment: Alignment = component(ecm, entity, "v_align");
	let margin = *ecm
	    .component_store()
	    .get::<Thickness>("margin", entity)
	    .unwrap();
	let padding: Thickness = component(ecm, entity, "padding");
	let constraint: Constraint = component(ecm, entity, "constraint");

	let size = constraint.perform((
	    horizontal_alignment.align_measure(
		parent_size.0,
		self.desired_size.borrow().width(),
		margin.left(),
		margin.right(),
	    ),
	    vertical_alignment.align_measure(
		parent_size.1,
		self.desired_size.borrow().height(),
		margin.top(),
		margin.bottom(),
	    ),
	));

	if let Some(bounds) = component_try_mut::<Rectangle>(ecm, entity, "bounds") {
	    bounds.set_width(size.0);
	    bounds.set_height(size.1);
	}

	mark_as_dirty("bounds", entity, ecm);

	let available_size = (
	    size.0 - padding.left() - padding.right(),
	    size.1 - padding.top() - padding.bottom(),
	);

	for index in 0..ecm.entity_store().children[&entity].len() {
	    let child = ecm.entity_store().children[&entity][index];

	    let child_margin: Thickness = component(ecm, entity, "margin");

	    if let Some(child_layout) = layouts.get(&child) {
		child_layout.arrange(
		    render_context_2_d,
		    available_size,
		    child,
		    ecm,
		    layouts,
		    theme,
		);
	    }

	    let child_horizontal_alignment: Alignment =
		*ecm.component_store().get("h_align", child).unwrap();
	    let child_vertical_alignment: Alignment =
		*ecm.component_store().get("v_align", child).unwrap();
	    if let Ok(child_bounds) = ecm
		.component_store_mut()
		.get_mut::<Rectangle>("bounds", child)
	    {
		child_bounds.set_x(
		    padding.left()
			+ child_horizontal_alignment.align_position(
			    available_size.0,
			    child_bounds.width(),
			    child_margin.left(),
			    child_margin.right(),
			),
		);
		child_bounds.set_y(
		    padding.top()
			+ child_vertical_alignment.align_position(
			    available_size.1,
			    child_bounds.height(),
			    child_margin.top(),
			    child_margin.bottom(),
			),
		);
	    }

	    mark_as_dirty("bounds", child, ecm);
	}

	self.desired_size.borrow_mut().set_dirty(false);
	size
    }
}
<|endoftext|>


<commit_before>// spell-checker:ignore (ToDO) scanutil qzxc dqzxc

pub use super::*;

#[test]
fn test_scanutil() {
    assert_eq!(Some((-5, 2)), "-5zxc".scan_num::<i32>());
    assert_eq!(Some((51, 2)), "51zxc".scan_num::<u32>());
    assert_eq!(Some((192, 4)), "+192zxc".scan_num::<i32>());
    assert_eq!(None, "z192zxc".scan_num::<i32>());

    assert_eq!(Some(('a', 3)), "141zxc".scan_char(8));
    assert_eq!(Some(('\n', 2)), "12qzxc".scan_char(8));
    assert_eq!(Some(('\r', 1)), "dqzxc".scan_char(16));
    assert_eq!(None, "z2qzxc".scan_char(8));
}

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

    #[test]
    fn test_normal_format() {
        let s = "%10.2ac%-5.w\n";
        let expected = vec![
            Token::Directive {
                flag: 0,
                width: 10,
                precision: 2,
                format: 'a',
            },
            Token::Char('c'),
            Token::Directive {
                flag: F_LEFT,
                width: 5,
                precision: 0,
                format: 'w',
            },
            Token::Char('\n'),
        ];
        assert_eq!(&expected, &Stater::generate_tokens(s, false).unwrap());
    }

    #[test]
    fn test_printf_format() {
        let s = "%-# 15a\\r\\\"\\\\\\a\\b\\e\\f\\v%+020.-23w\\x12\\167\\132\\112\\n";
        let expected = vec![
            Token::Directive {
                flag: F_LEFT | F_ALTER | F_SPACE,
                width: 15,
                precision: -1,
                format: 'a',
            },
            Token::Char('\r'),
            Token::Char('"'),
            Token::Char('\\'),
            Token::Char('\x07'),
            Token::Char('\x08'),
            Token::Char('\x1B'),
            Token::Char('\x0C'),
            Token::Char('\x0B'),
            Token::Directive {
                flag: F_SIGN | F_ZERO,
                width: 20,
                precision: -1,
                format: 'w',
            },
            Token::Char('\x12'),
            Token::Char('w'),
            Token::Char('Z'),
            Token::Char('J'),
            Token::Char('\n'),
        ];
        assert_eq!(&expected, &Stater::generate_tokens(s, true).unwrap());
    }
}
<commit_msg>stat: remove unused/duplicate tests<commit_after><|endoftext|>


<commit_before>use llvm_sys::core::{LLVMIsAMDNode, LLVMIsAMDString, LLVMGetMDString, LLVMGetMDNodeNumOperands, LLVMGetMDNodeOperands};
use llvm_sys::prelude::LLVMValueRef;

#[llvm_versions(7.0..=latest)]
use llvm_sys::prelude::LLVMMetadataRef;
#[llvm_versions(7.0..=latest)]
use llvm_sys::core::LLVMValueAsMetadata;

use crate::support::LLVMString;
use crate::values::traits::AsValueRef;
use crate::values::{BasicMetadataValueEnum, Value};

use std::ffi::CStr;
use std::fmt;
use std::mem::forget;
use std::slice::from_raw_parts;

// TODOC: Varies by version
#[cfg(feature = "llvm3-6")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 12;
#[cfg(feature = "llvm3-7")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 14;
#[cfg(feature = "llvm3-8")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 18;
#[cfg(feature = "llvm3-9")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 20;
#[cfg(feature = "llvm4-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 22;
#[cfg(feature = "llvm5-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 23;
#[cfg(feature = "llvm6-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 25;
#[cfg(feature = "llvm7-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 25;
#[cfg(feature = "llvm8-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 26;
#[cfg(feature = "llvm9-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 28;
#[cfg(feature = "llvm10-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 30;

#[derive(PartialEq, Eq, Clone, Copy, Hash)]
pub struct MetadataValue<'ctx> {
    metadata_value: Value<'ctx>,
}

impl<'ctx> MetadataValue<'ctx> {
    pub(crate) fn new(value: LLVMValueRef) -> Self {
        assert!(!value.is_null());

        unsafe {
            assert!(!LLVMIsAMDNode(value).is_null() || !LLVMIsAMDString(value).is_null());
        }

        MetadataValue {
            metadata_value: Value::new(value),
        }
    }

    #[llvm_versions(7.0..=latest)]
    pub(crate) fn as_metadata_ref(self) -> LLVMMetadataRef {
        unsafe {
            LLVMValueAsMetadata(self.as_value_ref())
        }
    }

    // SubTypes: This can probably go away with subtypes
    pub fn is_node(self) -> bool {
        unsafe {
            LLVMIsAMDNode(self.as_value_ref()) == self.as_value_ref()
        }
    }

    // SubTypes: This can probably go away with subtypes
    pub fn is_string(self) -> bool {
        unsafe {
            LLVMIsAMDString(self.as_value_ref()) == self.as_value_ref()
        }
    }

    pub fn get_string_value(&self) -> Option<&CStr> {
        if self.is_node() {
            return None;
        }

        let mut len = 0;
        let c_str = unsafe {
            CStr::from_ptr(LLVMGetMDString(self.as_value_ref(), &mut len))
        };

        Some(c_str)
    }

    // SubTypes: Node only one day
    pub fn get_node_size(self) -> u32 {
        if self.is_string() {
            return 0;
        }

        unsafe {
            LLVMGetMDNodeNumOperands(self.as_value_ref())
        }
    }

    // SubTypes: Node only one day
    // REVIEW: BasicMetadataValueEnum only if you can put metadata in metadata...
    pub fn get_node_values(self) -> Vec<BasicMetadataValueEnum<'ctx>> {
        if self.is_string() {
            return Vec::new();
        }

        let count = self.get_node_size();
        let mut raw_vec: Vec<LLVMValueRef> = Vec::with_capacity(count as usize);
        let ptr = raw_vec.as_mut_ptr();

        forget(raw_vec);

        let slice = unsafe {
            LLVMGetMDNodeOperands(self.as_value_ref(), ptr);

            from_raw_parts(ptr, count as usize)
        };

        slice.iter().map(|val| BasicMetadataValueEnum::new(*val)).collect()
    }

    pub fn print_to_string(self) -> LLVMString {
        self.metadata_value.print_to_string()
    }

    pub fn print_to_stderr(self) {
        self.metadata_value.print_to_stderr()
    }

    pub fn replace_all_uses_with(self, other: &MetadataValue<'ctx>) {
        self.metadata_value.replace_all_uses_with(other.as_value_ref())
    }
}

impl AsValueRef for MetadataValue<'_> {
    fn as_value_ref(&self) -> LLVMValueRef {
        self.metadata_value.value
    }
}

impl fmt::Debug for MetadataValue<'_> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut d = f.debug_struct("MetadataValue");
        d.field("address", &self.as_value_ref());

        if self.is_string() {
            d.field("value", &self.get_string_value().unwrap());
        } else {
            d.field("values", &self.get_node_values());
        }

        d.field("repr", &self.print_to_string());

        d.finish()
    }
}
<commit_msg>fix(values) Fix memory leak inside `get_node_values`.<commit_after>use llvm_sys::core::{LLVMIsAMDNode, LLVMIsAMDString, LLVMGetMDString, LLVMGetMDNodeNumOperands, LLVMGetMDNodeOperands};
use llvm_sys::prelude::LLVMValueRef;

#[llvm_versions(7.0..=latest)]
use llvm_sys::prelude::LLVMMetadataRef;
#[llvm_versions(7.0..=latest)]
use llvm_sys::core::LLVMValueAsMetadata;

use crate::support::LLVMString;
use crate::values::traits::AsValueRef;
use crate::values::{BasicMetadataValueEnum, Value};

use std::ffi::CStr;
use std::fmt;
use std::mem::forget;
use std::slice::from_raw_parts;

// TODOC: Varies by version
#[cfg(feature = "llvm3-6")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 12;
#[cfg(feature = "llvm3-7")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 14;
#[cfg(feature = "llvm3-8")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 18;
#[cfg(feature = "llvm3-9")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 20;
#[cfg(feature = "llvm4-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 22;
#[cfg(feature = "llvm5-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 23;
#[cfg(feature = "llvm6-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 25;
#[cfg(feature = "llvm7-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 25;
#[cfg(feature = "llvm8-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 26;
#[cfg(feature = "llvm9-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 28;
#[cfg(feature = "llvm10-0")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 30;

#[derive(PartialEq, Eq, Clone, Copy, Hash)]
pub struct MetadataValue<'ctx> {
    metadata_value: Value<'ctx>,
}

impl<'ctx> MetadataValue<'ctx> {
    pub(crate) fn new(value: LLVMValueRef) -> Self {
        assert!(!value.is_null());

        unsafe {
            assert!(!LLVMIsAMDNode(value).is_null() || !LLVMIsAMDString(value).is_null());
        }

        MetadataValue {
            metadata_value: Value::new(value),
        }
    }

    #[llvm_versions(7.0..=latest)]
    pub(crate) fn as_metadata_ref(self) -> LLVMMetadataRef {
        unsafe {
            LLVMValueAsMetadata(self.as_value_ref())
        }
    }

    // SubTypes: This can probably go away with subtypes
    pub fn is_node(self) -> bool {
        unsafe {
            LLVMIsAMDNode(self.as_value_ref()) == self.as_value_ref()
        }
    }

    // SubTypes: This can probably go away with subtypes
    pub fn is_string(self) -> bool {
        unsafe {
            LLVMIsAMDString(self.as_value_ref()) == self.as_value_ref()
        }
    }

    pub fn get_string_value(&self) -> Option<&CStr> {
        if self.is_node() {
            return None;
        }

        let mut len = 0;
        let c_str = unsafe {
            CStr::from_ptr(LLVMGetMDString(self.as_value_ref(), &mut len))
        };

        Some(c_str)
    }

    // SubTypes: Node only one day
    pub fn get_node_size(self) -> u32 {
        if self.is_string() {
            return 0;
        }

        unsafe {
            LLVMGetMDNodeNumOperands(self.as_value_ref())
        }
    }

    // SubTypes: Node only one day
    // REVIEW: BasicMetadataValueEnum only if you can put metadata in metadata...
    pub fn get_node_values(self) -> Vec<BasicMetadataValueEnum<'ctx>> {
        if self.is_string() {
            return Vec::new();
        }

        let count = self.get_node_size() as usize;
        let mut raw_vec: Vec<LLVMValueRef> = Vec::with_capacity(count);
        let ptr = raw_vec.as_mut_ptr();

        forget(raw_vec);

        let vec = unsafe {
            LLVMGetMDNodeOperands(self.as_value_ref(), ptr);

            Vec::from_raw_parts(ptr, count, count)
        };

        vec.iter()
            .map(|val| BasicMetadataValueEnum::new(*val))
            .collect()
    }

    pub fn print_to_string(self) -> LLVMString {
        self.metadata_value.print_to_string()
    }

    pub fn print_to_stderr(self) {
        self.metadata_value.print_to_stderr()
    }

    pub fn replace_all_uses_with(self, other: &MetadataValue<'ctx>) {
        self.metadata_value.replace_all_uses_with(other.as_value_ref())
    }
}

impl AsValueRef for MetadataValue<'_> {
    fn as_value_ref(&self) -> LLVMValueRef {
        self.metadata_value.value
    }
}

impl fmt::Debug for MetadataValue<'_> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut d = f.debug_struct("MetadataValue");
        d.field("address", &self.as_value_ref());

        if self.is_string() {
            d.field("value", &self.get_string_value().unwrap());
        } else {
            d.field("values", &self.get_node_values());
        }

        d.field("repr", &self.print_to_string());

        d.finish()
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Sorting_algorithms/Pancake_sort

fn pancake_sort<T: Ord>(mut v: &mut [T]) {

    let len = v.len();

    // trivial case -- no flips
    if len < 2 {
        return;
    }

    for i in (1..len + 1).rev() {

        // find index of maximum from 0 to i
        let mut max_index = 0;
        for j in 0..i {
            if v[max_index] < v[j] {
                max_index = j;
            }
        }

        // if max_index is not where it's supposed to be
        // do two flips to move it to i - 1
        if max_index != i - 1 {
            flip(&mut v, max_index);
            flip(&mut v, i - 1);
        }
    }
}

// function to flip a section of a mutable collection from 0..num
fn flip<E: PartialOrd>(v: &mut [E], num: usize) {

    for i in 0..(num + 1) / 2 {
        v.swap(i, num - i);
    }

}

fn main() {
    // Sort numbers
    let mut numbers = [4i32, 65, 2, -31, 0, 99, 2, 83, 782, 1];
    println!("Before: {:?}", numbers);

    pancake_sort(&mut numbers);
    println!("After: {:?}", numbers);

    // Sort strings
    let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"];
    println!("Before: {:?}", strings);

    pancake_sort(&mut strings);
    println!("After: {:?}", strings);
}
<commit_msg>remove whitespace<commit_after>// http://rosettacode.org/wiki/Sorting_algorithms/Pancake_sort
fn pancake_sort<T: Ord>(mut v: &mut [T]) {
    let len = v.len();
    // trivial case -- no flips
    if len < 2 {
        return;
    }
    for i in (1..len + 1).rev() {
        // find index of maximum from 0 to i
        let mut max_index = 0;
        for j in 0..i {
            if v[max_index] < v[j] {
                max_index = j;
            }
        }
        // if max_index is not where it's supposed to be
        // do two flips to move it to i - 1
        if max_index != i - 1 {
            flip(&mut v, max_index);
            flip(&mut v, i - 1);
        }
    }
}
// function to flip a section of a mutable collection from 0..num
fn flip<E: PartialOrd>(v: &mut [E], num: usize) {
    for i in 0..(num + 1) / 2 {
        v.swap(i, num - i);
    }
}
fn main() {
    // Sort numbers
    let mut numbers = [4i32, 65, 2, -31, 0, 99, 2, 83, 782, 1];
    println!("Before: {:?}", numbers);
    pancake_sort(&mut numbers);
    println!("After: {:?}", numbers);
    // Sort strings
    let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"];
    println!("Before: {:?}", strings);
    pancake_sort(&mut strings);
    println!("After: {:?}", strings);
}
// #[test]
<|endoftext|>


<commit_before>use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr;
use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN};
use libc;

#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
    #[inline]
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
            libc::malloc(layout.size()) as *mut u8
        } else {
            libc::aligned_alloc(layout.size(), layout.align()) as *mut u8
        }
    }

    #[inline]
    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
            libc::calloc(layout.size(), 1) as *mut u8
        } else {
            let ptr = self.alloc(layout.clone());
            if !ptr.is_null() {
                ptr::write_bytes(ptr, 0, layout.size());
            }
            ptr
        }
    }

    #[inline]
    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
        libc::free(ptr as *mut libc::c_void)
    }

    #[inline]
    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
        if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
            libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
        } else {
            realloc_fallback(self, ptr, layout, new_size)
        }
    }
}
<commit_msg>Rollup merge of #70585 - alexcrichton:fix-wasi-align-alloc, r=Mark-Simulacrum<commit_after>use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr;
use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN};
use libc;

#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
    #[inline]
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
            libc::malloc(layout.size()) as *mut u8
        } else {
            libc::aligned_alloc(layout.align(), layout.size()) as *mut u8
        }
    }

    #[inline]
    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
            libc::calloc(layout.size(), 1) as *mut u8
        } else {
            let ptr = self.alloc(layout.clone());
            if !ptr.is_null() {
                ptr::write_bytes(ptr, 0, layout.size());
            }
            ptr
        }
    }

    #[inline]
    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
        libc::free(ptr as *mut libc::c_void)
    }

    #[inline]
    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
        if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
            libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
        } else {
            realloc_fallback(self, ptr, layout, new_size)
        }
    }
}
<|endoftext|>


<commit_before>#![allow(
    clippy::cognitive_complexity,
    clippy::inherent_to_string,
    clippy::large_enum_variant,
    clippy::new_without_default,
    clippy::toplevel_ref_arg
)]

mod gen;
mod syntax;

use gen::include;
use std::io::{self, Write};
use std::path::PathBuf;
use structopt::StructOpt;

#[derive(StructOpt, Debug)]
#[structopt(
    name = "cxxbridge",
    author = "dtolnay@gmail.com",
    about = "https://github.com/dtolnay/cxx",
    usage = "\
    cxxbridge <input>.rs              Emit .cc file for bridge to stdout
    cxxbridge <input>.rs --header     Emit .h file for bridge to stdout
    cxxbridge --header                Emit rust/cxx.h header to stdout",
    help_message = "Print help information",
    version_message = "Print version information"
)]
struct Opt {
    /// Input Rust source file containing #[cxx::bridge]
    #[structopt(parse(from_os_str), required_unless = "header")]
    input: Option<PathBuf>,

    /// Emit header with declarations only
    #[structopt(long)]
    header: bool,

    /// Any additional headers to #include
    #[structopt(short, long)]
    include: Vec<String>,
}

fn write(content: impl AsRef<[u8]>) {
    let _ = io::stdout().lock().write_all(content.as_ref());
}

fn main() {
    let opt = Opt::from_args();

    let gen = gen::Opt {
        include: opt.include,
    };

    match (opt.input, opt.header) {
        (Some(input), true) => write(gen::do_generate_header(&input, gen)),
        (Some(input), false) => write(gen::do_generate_bridge(&input, gen)),
        (None, true) => write(include::HEADER),
        (None, false) => unreachable!(), // enforced by required_unless
    }
}
<commit_msg>Update cmd author to match author in Cargo.toml<commit_after>#![allow(
    clippy::cognitive_complexity,
    clippy::inherent_to_string,
    clippy::large_enum_variant,
    clippy::new_without_default,
    clippy::toplevel_ref_arg
)]

mod gen;
mod syntax;

use gen::include;
use std::io::{self, Write};
use std::path::PathBuf;
use structopt::StructOpt;

#[derive(StructOpt, Debug)]
#[structopt(
    name = "cxxbridge",
    author = "David Tolnay <dtolnay@gmail.com>",
    about = "https://github.com/dtolnay/cxx",
    usage = "\
    cxxbridge <input>.rs              Emit .cc file for bridge to stdout
    cxxbridge <input>.rs --header     Emit .h file for bridge to stdout
    cxxbridge --header                Emit rust/cxx.h header to stdout",
    help_message = "Print help information",
    version_message = "Print version information"
)]
struct Opt {
    /// Input Rust source file containing #[cxx::bridge]
    #[structopt(parse(from_os_str), required_unless = "header")]
    input: Option<PathBuf>,

    /// Emit header with declarations only
    #[structopt(long)]
    header: bool,

    /// Any additional headers to #include
    #[structopt(short, long)]
    include: Vec<String>,
}

fn write(content: impl AsRef<[u8]>) {
    let _ = io::stdout().lock().write_all(content.as_ref());
}

fn main() {
    let opt = Opt::from_args();

    let gen = gen::Opt {
        include: opt.include,
    };

    match (opt.input, opt.header) {
        (Some(input), true) => write(gen::do_generate_header(&input, gen)),
        (Some(input), false) => write(gen::do_generate_bridge(&input, gen)),
        (None, true) => write(include::HEADER),
        (None, false) => unreachable!(), // enforced by required_unless
    }
}
<|endoftext|>


<commit_before>//! This module is for everything about the rules of chess.

#![feature(core, collections, unicode)]
#![feature(plugin)]

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate log;

pub use color::{Color, White, Black};
pub use piece::Piece;
pub use piece::Type as PieceType;
pub use piece::Type::*;
pub use moves::{Move, FromTo};
pub use moves::{NumPlies, NumMoves};

pub use pos::Position;
pub use pos::ExtraData as PosExtraData;
pub use pos::{ScoreUnit, Score};

mod color;
mod piece;
mod square;
mod moves;
mod castle;
mod pos;
<commit_msg>Remove unnecessary feature(plugin)<commit_after>//! This module is for everything about the rules of chess.

#![feature(core, collections, unicode)]

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate log;

pub use color::{Color, White, Black};
pub use piece::Piece;
pub use piece::Type as PieceType;
pub use piece::Type::*;
pub use moves::{Move, FromTo};
pub use moves::{NumPlies, NumMoves};

pub use pos::Position;
pub use pos::ExtraData as PosExtraData;
pub use pos::{ScoreUnit, Score};

mod color;
mod piece;
mod square;
mod moves;
mod castle;
mod pos;
<|endoftext|>


<commit_before>//! Formats a DOM structure to a Writer
//!
//! ### Example
//! ```
//! use document::Document;
//! use document::writer::format_document;
//!
//! let doc = Document::new();
//!
//! let hello = doc.new_element("hello".to_string());
//! hello.set_attribute("planet".to_string(), "Earth".to_string());
//! doc.root().append_child(hello);
//!
//! let mut output = std::io::stdio::stdout();
//! format_document(&doc, &mut output).ok().expect("unable to output XML");
//! ```
//!
//! ### Known issues
//!
//! Output is not escaped in any way,
//! it's very easy to create malformed XML!
//!
//! ### Potential options to support
//!
//! - Space before `/>`
//! - Single vs double quotes
//! - Fixed ordering of attributes

use std::io::IoResult;

use super::{ElementElementChild,TextElementChild,CommentElementChild,PIElementChild};
use super::{ElementRootChild,CommentRootChild,PIRootChild};

enum Content {
    Element(super::Element),
    ElementEnd(String),
    Text(super::Text),
    Comment(super::Comment),
    ProcessingInstruction(super::ProcessingInstruction),
}

fn format_element<W : Writer>(element: super::Element, todo: &mut Vec<Content>, writer: &mut W) -> IoResult<()> {
    try!(write!(writer, "<{}", element.name()));

    for attr in element.attributes().iter() {
        try!(write!(writer, " {}='{}'", attr.name(), attr.value()));
    }

    let mut children = element.children();
    if children.is_empty() {
        writer.write_str("/>")
    } else {
        try!(writer.write_str(">"));

        todo.push(ElementEnd(element.name()));
        children.reverse();
        let x = children.into_iter().map(|c| match c {
            ElementElementChild(element) => Element(element),
            TextElementChild(t)          => Text(t),
            CommentElementChild(c)       => Comment(c),
            PIElementChild(p)            => ProcessingInstruction(p),
        }).collect();
        todo.push_all_move(x);

        Ok(())
    }
}

fn format_comment<W : Writer>(comment: super::Comment, writer: &mut W) -> IoResult<()> {
    write!(writer, "<!--{}-->", comment.text())
}

fn format_processing_instruction<W : Writer>(pi: super::ProcessingInstruction, writer: &mut W) -> IoResult<()> {
    match pi.value() {
        None    => write!(writer, "<?{}?>", pi.target()),
        Some(v) => write!(writer, "<?{} {}?>", pi.target(), v),
    }
}

fn format_one<W : Writer>(content: Content, todo: &mut Vec<Content>, writer: &mut W) -> IoResult<()> {
    match content {
        Element(e)               => format_element(e, todo, writer),
        ElementEnd(name)         => write!(writer, "</{}>", name),
        Text(t)                  => writer.write_str(t.text().as_slice()),
        Comment(c)               => format_comment(c, writer),
        ProcessingInstruction(p) => format_processing_instruction(p, writer),
    }
}

fn format_body<W : Writer>(element: super::Element, writer: &mut W) -> IoResult<()> {
    let mut todo = vec![Element(element)];

    while ! todo.is_empty() {
        try!(format_one(todo.pop().unwrap(), &mut todo, writer));
    }

    Ok(())
}

/// Formats a document into a Writer
pub fn format_document<W : Writer>(doc: &super::Document, writer: &mut W) -> IoResult<()> {
    try!(writer.write_str("<?xml version='1.0'?>"));

    for child in doc.root().children().into_iter() {
        try!(match child {
            ElementRootChild(e) => format_body(e, writer),
            CommentRootChild(c) => format_comment(c, writer),
            PIRootChild(p)      => format_processing_instruction(p, writer),
        })
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use std::io::MemWriter;

    use super::super::Document;
    use super::format_document;

    macro_rules! assert_str_eq(
        ($l:expr, $r:expr) => (assert_eq!($l.as_slice(), $r.as_slice()));
    )

    fn format_xml(doc: &Document) -> String {
        let mut w = MemWriter::new();
        format_document(doc, &mut w).ok().expect("Not formatted");
        String::from_utf8(w.unwrap()).ok().expect("Not a string")
    }

    #[test]
    fn top_element() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello/>");
    }

    #[test]
    fn element_with_attributes() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        e.set_attribute("a".to_string(), "b".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello a='b'/>");
    }

    #[test]
    fn nested_element() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let world = d.new_element("world".to_string());
        hello.append_child(world);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><world/></hello>");
    }

    #[test]
    fn nested_text() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let text = d.new_text("A fine day to you!".to_string());
        hello.append_child(text);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello>A fine day to you!</hello>");
    }

    #[test]
    fn nested_comment() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let comment = d.new_comment(" Fill this in ".to_string());
        hello.append_child(comment);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><!-- Fill this in --></hello>");
    }

    #[test]
    fn nested_processing_instruction_without_value() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let pi = d.new_processing_instruction("display".to_string(), None);
        hello.append_child(pi);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><?display?></hello>");
    }

    #[test]
    fn nested_processing_instruction_with_value() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let pi = d.new_processing_instruction("display".to_string(), Some("screen".to_string()));
        hello.append_child(pi);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><?display screen?></hello>");
    }

    #[test]
    fn top_level_comment() {
        let d = Document::new();
        let comment = d.new_comment(" Fill this in ".to_string());
        d.root().append_child(comment);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><!-- Fill this in -->");
    }

    #[test]
    fn top_level_processing_instruction() {
        let d = Document::new();
        let pi = d.new_processing_instruction("display".to_string(), None);
        d.root().append_child(pi);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><?display?>");
    }
}
<commit_msg>Remove deprecated `Vec.push_all_move` call<commit_after>//! Formats a DOM structure to a Writer
//!
//! ### Example
//! ```
//! use document::Document;
//! use document::writer::format_document;
//!
//! let doc = Document::new();
//!
//! let hello = doc.new_element("hello".to_string());
//! hello.set_attribute("planet".to_string(), "Earth".to_string());
//! doc.root().append_child(hello);
//!
//! let mut output = std::io::stdio::stdout();
//! format_document(&doc, &mut output).ok().expect("unable to output XML");
//! ```
//!
//! ### Known issues
//!
//! Output is not escaped in any way,
//! it's very easy to create malformed XML!
//!
//! ### Potential options to support
//!
//! - Space before `/>`
//! - Single vs double quotes
//! - Fixed ordering of attributes

use std::io::IoResult;

use super::{ElementElementChild,TextElementChild,CommentElementChild,PIElementChild};
use super::{ElementRootChild,CommentRootChild,PIRootChild};

enum Content {
    Element(super::Element),
    ElementEnd(String),
    Text(super::Text),
    Comment(super::Comment),
    ProcessingInstruction(super::ProcessingInstruction),
}

fn format_element<W : Writer>(element: super::Element, todo: &mut Vec<Content>, writer: &mut W) -> IoResult<()> {
    try!(write!(writer, "<{}", element.name()));

    for attr in element.attributes().iter() {
        try!(write!(writer, " {}='{}'", attr.name(), attr.value()));
    }

    let mut children = element.children();
    if children.is_empty() {
        writer.write_str("/>")
    } else {
        try!(writer.write_str(">"));

        todo.push(ElementEnd(element.name()));
        children.reverse();
        let x = children.into_iter().map(|c| match c {
            ElementElementChild(element) => Element(element),
            TextElementChild(t)          => Text(t),
            CommentElementChild(c)       => Comment(c),
            PIElementChild(p)            => ProcessingInstruction(p),
        });
        todo.extend(x);

        Ok(())
    }
}

fn format_comment<W : Writer>(comment: super::Comment, writer: &mut W) -> IoResult<()> {
    write!(writer, "<!--{}-->", comment.text())
}

fn format_processing_instruction<W : Writer>(pi: super::ProcessingInstruction, writer: &mut W) -> IoResult<()> {
    match pi.value() {
        None    => write!(writer, "<?{}?>", pi.target()),
        Some(v) => write!(writer, "<?{} {}?>", pi.target(), v),
    }
}

fn format_one<W : Writer>(content: Content, todo: &mut Vec<Content>, writer: &mut W) -> IoResult<()> {
    match content {
        Element(e)               => format_element(e, todo, writer),
        ElementEnd(name)         => write!(writer, "</{}>", name),
        Text(t)                  => writer.write_str(t.text().as_slice()),
        Comment(c)               => format_comment(c, writer),
        ProcessingInstruction(p) => format_processing_instruction(p, writer),
    }
}

fn format_body<W : Writer>(element: super::Element, writer: &mut W) -> IoResult<()> {
    let mut todo = vec![Element(element)];

    while ! todo.is_empty() {
        try!(format_one(todo.pop().unwrap(), &mut todo, writer));
    }

    Ok(())
}

/// Formats a document into a Writer
pub fn format_document<W : Writer>(doc: &super::Document, writer: &mut W) -> IoResult<()> {
    try!(writer.write_str("<?xml version='1.0'?>"));

    for child in doc.root().children().into_iter() {
        try!(match child {
            ElementRootChild(e) => format_body(e, writer),
            CommentRootChild(c) => format_comment(c, writer),
            PIRootChild(p)      => format_processing_instruction(p, writer),
        })
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use std::io::MemWriter;

    use super::super::Document;
    use super::format_document;

    macro_rules! assert_str_eq(
        ($l:expr, $r:expr) => (assert_eq!($l.as_slice(), $r.as_slice()));
    )

    fn format_xml(doc: &Document) -> String {
        let mut w = MemWriter::new();
        format_document(doc, &mut w).ok().expect("Not formatted");
        String::from_utf8(w.unwrap()).ok().expect("Not a string")
    }

    #[test]
    fn top_element() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello/>");
    }

    #[test]
    fn element_with_attributes() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        e.set_attribute("a".to_string(), "b".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello a='b'/>");
    }

    #[test]
    fn nested_element() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let world = d.new_element("world".to_string());
        hello.append_child(world);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><world/></hello>");
    }

    #[test]
    fn nested_text() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let text = d.new_text("A fine day to you!".to_string());
        hello.append_child(text);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello>A fine day to you!</hello>");
    }

    #[test]
    fn nested_comment() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let comment = d.new_comment(" Fill this in ".to_string());
        hello.append_child(comment);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><!-- Fill this in --></hello>");
    }

    #[test]
    fn nested_processing_instruction_without_value() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let pi = d.new_processing_instruction("display".to_string(), None);
        hello.append_child(pi);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><?display?></hello>");
    }

    #[test]
    fn nested_processing_instruction_with_value() {
        let d = Document::new();
        let hello = d.new_element("hello".to_string());
        let pi = d.new_processing_instruction("display".to_string(), Some("screen".to_string()));
        hello.append_child(pi);
        d.root().append_child(hello);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello><?display screen?></hello>");
    }

    #[test]
    fn top_level_comment() {
        let d = Document::new();
        let comment = d.new_comment(" Fill this in ".to_string());
        d.root().append_child(comment);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><!-- Fill this in -->");
    }

    #[test]
    fn top_level_processing_instruction() {
        let d = Document::new();
        let pi = d.new_processing_instruction("display".to_string(), None);
        d.root().append_child(pi);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><?display?>");
    }
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
#![feature(phase)]

#![unstable]

#[phase(plugin)]
extern crate compile_msg;

extern crate libc;

#[doc(hidden)]
pub mod ffi;

///
#[doc(hidden)]
pub static mut android_app: *mut ffi::android_app = 0 as *mut ffi::android_app;

#[cfg(not(target_os = "android"))]
compile_note!("You are not compiling for Android")

#[macro_export]
macro_rules! android_start(
    ($main: ident) => (
        pub mod __android_start {
            extern crate android_glue;
            extern crate libc;
            extern crate native;

            #[no_mangle]
            #[inline(never)]
            #[allow(non_snake_case)]
            pub extern "C" fn android_main(app: *mut android_glue::ffi::android_app) {
                use self::native::NativeTaskBuilder;
                use std::task::TaskBuilder;

                unsafe { android_glue::android_app = app };

                android_glue::write_log("ANativeActivity_onCreate has been called");

                unsafe { android_glue::ffi::app_dummy() };

                native::start(1, &b"".as_ptr(), proc() {
                    TaskBuilder::new().native().spawn(proc() {
                        super::$main();
                    });
                });
            }
        }
    )
)

/// Returns a handle to the native window.
pub fn get_native_window() -> ffi::NativeWindowType {
    unsafe { (*android_app).window }
}

///
pub fn write_log(message: &str) {
    message.with_c_str(|message| {
        b"RustAndroidGlue".with_c_str(|tag| {
            unsafe { ffi::__android_log_write(3, tag, message) };
        });
    });
}
<commit_msg>Fix native activity glue not being included<commit_after>#![feature(macro_rules)]
#![feature(phase)]

#![unstable]

#[phase(plugin)]
extern crate compile_msg;

extern crate libc;

#[doc(hidden)]
pub mod ffi;

///
#[doc(hidden)]
pub static mut android_app: *mut ffi::android_app = 0 as *mut ffi::android_app;

#[cfg(not(target_os = "android"))]
compile_note!("You are not compiling for Android")

#[macro_export]
macro_rules! android_start(
    ($main: ident) => (
        pub mod __android_start {
            extern crate android_glue;
            extern crate libc;
            extern crate native;

            // this function is here because we are sure that it will be included by the linker
            // so we call app_dummy in it, in order to be sure that the native glue will be included
            #[start]
            pub fn start(_: int, _: *const *const u8) -> int {
                unsafe { android_glue::ffi::app_dummy() };
                1
            }

            #[no_mangle]
            #[inline(never)]
            #[allow(non_snake_case)]
            pub extern "C" fn android_main(app: *mut android_glue::ffi::android_app) {
                use self::native::NativeTaskBuilder;
                use std::task::TaskBuilder;

                unsafe { android_glue::android_app = app };

                android_glue::write_log("ANativeActivity_onCreate has been called");

                unsafe { android_glue::ffi::app_dummy() };

                native::start(1, &b"".as_ptr(), proc() {
                    TaskBuilder::new().native().spawn(proc() {
                        super::$main();
                    });
                });
            }
        }
    )
)

/// Returns a handle to the native window.
pub fn get_native_window() -> ffi::NativeWindowType {
    unsafe { (*android_app).window }
}

///
pub fn write_log(message: &str) {
    message.with_c_str(|message| {
        b"RustAndroidGlue".with_c_str(|tag| {
            unsafe { ffi::__android_log_write(3, tag, message) };
        });
    });
}
<|endoftext|>