<commit_before>/***********************************************************************
    created:    Sun Jun 19 2005
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/falagard/TextComponent.h"
#include "CEGUI/falagard/XMLEnumHelper.h"
#include "CEGUI/falagard/XMLHandler.h"
#include "CEGUI/FontManager.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/PropertyHelper.h"
#include "CEGUI/Font.h"
#include "CEGUI/LeftAlignedRenderedString.h"
#include "CEGUI/RightAlignedRenderedString.h"
#include "CEGUI/CentredRenderedString.h"
#include "CEGUI/JustifiedRenderedString.h"
#include "CEGUI/RenderedStringWordWrapper.h"
#include <iostream>

#if defined (CEGUI_USE_FRIBIDI)
    #include "CEGUI/FribidiVisualMapping.h"
#elif defined (CEGUI_USE_MINIBIDI)
    #include "CEGUI/MinibidiVisualMapping.h"
#else
    #include "CEGUI/BidiVisualMapping.h"
#endif

// Start of CEGUI namespace section
namespace CEGUI
{
    TextComponent::TextComponent() :
#ifndef CEGUI_BIDI_SUPPORT
        d_bidiVisualMapping(0),
#elif defined (CEGUI_USE_FRIBIDI)
        d_bidiVisualMapping(CEGUI_NEW_AO FribidiVisualMapping),
#elif defined (CEGUI_USE_MINIBIDI)
        d_bidiVisualMapping(CEGUI_NEW_AO MinibidiVisualMapping),
#else
    #error "BIDI Configuration is inconsistant, check your config!"
#endif
        d_bidiDataValid(false),
        d_formattedRenderedString(CEGUI_NEW_AO LeftAlignedRenderedString(d_renderedString)),
        d_lastHorzFormatting(HTF_LEFT_ALIGNED),
        d_vertFormatting(VTF_TOP_ALIGNED),
        d_horzFormatting(HTF_LEFT_ALIGNED)
    {}

    TextComponent::~TextComponent()
    {
        CEGUI_DELETE_AO d_bidiVisualMapping;
    }

    TextComponent::TextComponent(const TextComponent& obj) :
        FalagardComponentBase(obj),
        d_textLogical(obj.d_textLogical),
#ifndef CEGUI_BIDI_SUPPORT
        d_bidiVisualMapping(0),
#elif defined (CEGUI_USE_FRIBIDI)
        d_bidiVisualMapping(CEGUI_NEW_AO FribidiVisualMapping),
#elif defined (CEGUI_USE_MINIBIDI)
        d_bidiVisualMapping(CEGUI_NEW_AO MinibidiVisualMapping),
#endif
        d_bidiDataValid(false),
        d_renderedString(obj.d_renderedString),
        d_formattedRenderedString(obj.d_formattedRenderedString),
        d_lastHorzFormatting(obj.d_lastHorzFormatting),
        d_font(obj.d_font),
        d_vertFormatting(obj.d_vertFormatting),
        d_horzFormatting(obj.d_horzFormatting),
        d_textPropertyName(obj.d_textPropertyName),
        d_fontPropertyName(obj.d_fontPropertyName)
    {
    }

    TextComponent& TextComponent::operator=(const TextComponent& other)
    {
        if (this == &other)
            return *this;

        FalagardComponentBase::operator=(other);

        d_textLogical = other.d_textLogical;
        // note we do not assign the BidiVisualMapping object, we just mark our
        // existing one as invalid so it's data gets regenerated next time it's
        // needed.
        d_bidiDataValid = false;
        d_renderedString = other.d_renderedString;
        d_formattedRenderedString = other.d_formattedRenderedString;
        d_lastHorzFormatting = other.d_lastHorzFormatting;
        d_font = other.d_font;
        d_vertFormatting = other.d_vertFormatting;
        d_horzFormatting = other.d_horzFormatting;
        d_textPropertyName = other.d_textPropertyName;
        d_fontPropertyName = other.d_fontPropertyName;

        return *this;
    }

    const String& TextComponent::getText() const
    {
        return d_textLogical;
    }

    void TextComponent::setText(const String& text)
    {
        d_textLogical = text;
        d_bidiDataValid = false;
    }

    const String& TextComponent::getFont() const
    {
        return d_font;
    }

    void TextComponent::setFont(const String& font)
    {
        d_font = font;
    }

    VerticalTextFormatting TextComponent::getVerticalFormatting(const Window& wnd) const
    {
        return d_vertFormatting.get(wnd);
    }

    VerticalTextFormatting TextComponent::getVerticalFormattingFromComponent() const
    {
        return d_vertFormatting.getValue();
    }

    void TextComponent::setVerticalFormatting(VerticalTextFormatting fmt)
    {
        d_vertFormatting.set(fmt);
    }

    HorizontalTextFormatting TextComponent::getHorizontalFormatting(const Window& wnd) const
    {
        return d_horzFormatting.get(wnd);
    }

    HorizontalTextFormatting TextComponent::getHorizontalFormattingFromComponent() const
    {
        return d_horzFormatting.getValue();
    }

    void TextComponent::setHorizontalFormatting(HorizontalTextFormatting fmt)
    {
        d_horzFormatting.set(fmt);
    }

    void TextComponent::setHorizontalFormattingPropertySource(
                                                const String& property_name)
    {
        d_horzFormatting.setPropertySource(property_name);
    }

    void TextComponent::setVerticalFormattingPropertySource(
                                                const String& property_name)
    {
        d_vertFormatting.setPropertySource(property_name);
    }

    void TextComponent::setupStringFormatter(const Window& window,
                                             const RenderedString& rendered_string) const
    {
        const HorizontalTextFormatting horzFormatting = d_horzFormatting.get(window);

        // no formatting change
        if (horzFormatting == d_lastHorzFormatting)
        {
            d_formattedRenderedString->setRenderedString(rendered_string);
            return;
        }

        d_lastHorzFormatting = horzFormatting;

        switch(horzFormatting)
        {
        case HTF_LEFT_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO LeftAlignedRenderedString(rendered_string);
            break;

        case HTF_CENTRE_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO CentredRenderedString(rendered_string);
            break;

        case HTF_RIGHT_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RightAlignedRenderedString(rendered_string);
            break;

        case HTF_JUSTIFIED:
            d_formattedRenderedString =
                CEGUI_NEW_AO JustifiedRenderedString(rendered_string);
            break;

        case HTF_WORDWRAP_LEFT_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RenderedStringWordWrapper
                    <LeftAlignedRenderedString>(rendered_string);
            break;

        case HTF_WORDWRAP_CENTRE_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RenderedStringWordWrapper
                    <CentredRenderedString>(rendered_string);
            break;

        case HTF_WORDWRAP_RIGHT_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RenderedStringWordWrapper
                    <RightAlignedRenderedString>(rendered_string);
            break;

        case HTF_WORDWRAP_JUSTIFIED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RenderedStringWordWrapper
                    <JustifiedRenderedString>(rendered_string);
            break;
        }
    }

    void TextComponent::render_impl(Window& srcWindow, Rectf& destRect, const CEGUI::ColourRect* modColours, const Rectf* clipper, bool /*clipToDisplay*/) const
    {
        const Font* font = getFontObject(srcWindow);

        // exit if we have no font to use.
        if (!font)
            return;

        const RenderedString* rs = &d_renderedString;
        // do we fetch text from a property
        if (!d_textPropertyName.empty())
        {
            // fetch text & do bi-directional reordering as needed
            String vis;
            #ifdef CEGUI_BIDI_SUPPORT
                BidiVisualMapping::StrIndexList l2v, v2l;
                d_bidiVisualMapping->reorderFromLogicalToVisual(
                    srcWindow.getProperty(d_textPropertyName), vis, l2v, v2l);
            #else
                vis = srcWindow.getProperty(d_textPropertyName);
            #endif
            // parse string using parser from Window.
            d_renderedString =
                srcWindow.getRenderedStringParser().parse(vis, font, 0);
        }
        // do we use a static text string from the looknfeel
        else if (!getTextVisual().empty())
            // parse string using parser from Window.
            d_renderedString = srcWindow.getRenderedStringParser().
                parse(getTextVisual(), font, 0);
        // do we have to override the font?
        else if (font != srcWindow.getFont())
            d_renderedString = srcWindow.getRenderedStringParser().
                parse(srcWindow.getTextVisual(), font, 0);
        // use ready-made RenderedString from the Window itself
        else
            rs = &srcWindow.getRenderedString();

        setupStringFormatter(srcWindow, *rs);
        d_formattedRenderedString->format(&srcWindow, destRect.getSize());

        // Get total formatted height.
        const float textHeight = d_formattedRenderedString->getVerticalExtent(&srcWindow);

        // handle dest area adjustments for vertical formatting.
        const VerticalTextFormatting vertFormatting = d_vertFormatting.get(srcWindow);

        switch(vertFormatting)
        {
        case VTF_CENTRE_ALIGNED:
            destRect.d_min.d_y += (destRect.getHeight() - textHeight) * 0.5f;
            break;

        case VTF_BOTTOM_ALIGNED:
            destRect.d_min.d_y = destRect.d_max.d_y - textHeight;
            break;

        default:
            // default is VTF_TOP_ALIGNED, for which we take no action.
            break;
        }

        // calculate final colours to be used
        ColourRect finalColours;
        initColoursRect(srcWindow, modColours, finalColours);

        // add geometry for text to the target window.
        d_formattedRenderedString->draw(&srcWindow, srcWindow.getGeometryBuffer(),
                                        destRect.getPosition(),
                                        &finalColours, clipper);
    }

    const Font* TextComponent::getFontObject(const Window& window) const
    {
        CEGUI_TRY
        {
            return d_fontPropertyName.empty() ?
                (d_font.empty() ? window.getFont() : &FontManager::getSingleton().get(d_font))
                : &FontManager::getSingleton().get(window.getProperty(d_fontPropertyName));
        }
        CEGUI_CATCH (UnknownObjectException&)
        {
            return 0;
        }
    }

    void TextComponent::writeXMLToStream(XMLSerializer& xml_stream) const
    {
        // opening tag
        xml_stream.openTag(Falagard_xmlHandler::TextComponentElement);
        // write out area
        d_area.writeXMLToStream(xml_stream);

        // write text element
        if (!d_font.empty() && !getText().empty())
        {
            xml_stream.openTag(Falagard_xmlHandler::TextElement);
            if (!d_font.empty())
                xml_stream.attribute(Falagard_xmlHandler::FontAttribute, d_font);
            if (!getText().empty())
                xml_stream.attribute(Falagard_xmlHandler::StringAttribute, getText());
            xml_stream.closeTag();
        }

        // write text property element
        if (!d_textPropertyName.empty())
        {
            xml_stream.openTag(Falagard_xmlHandler::TextPropertyElement)
                .attribute(Falagard_xmlHandler::NameAttribute, d_textPropertyName)
                .closeTag();
        }

        // write font property element
        if (!d_fontPropertyName.empty())
        {
            xml_stream.openTag(Falagard_xmlHandler::FontPropertyElement)
                .attribute(Falagard_xmlHandler::NameAttribute, d_fontPropertyName)
                .closeTag();
        }

        // get base class to write colours
        writeColoursXML(xml_stream);

        d_vertFormatting.writeXMLToStream(xml_stream);
        d_horzFormatting.writeXMLToStream(xml_stream);

        // closing tag
        xml_stream.closeTag();
    }

    bool TextComponent::isTextFetchedFromProperty() const
    {
        return !d_textPropertyName.empty();
    }

    const String& TextComponent::getTextPropertySource() const
    {
        return d_textPropertyName;
    }

    void TextComponent::setTextPropertySource(const String& property)
    {
        d_textPropertyName = property;
    }

    bool TextComponent::isFontFetchedFromProperty() const
    {
        return !d_fontPropertyName.empty();
    }

    const String& TextComponent::getFontPropertySource() const
    {
        return d_fontPropertyName;
    }

    void TextComponent::setFontPropertySource(const String& property)
    {
        d_fontPropertyName = property;
    }

    const String& TextComponent::getTextVisual() const
    {
        // no bidi support
        if (!d_bidiVisualMapping)
            return d_textLogical;

        if (!d_bidiDataValid)
        {
            d_bidiVisualMapping->updateVisual(d_textLogical);
            d_bidiDataValid = true;
        }

        return d_bidiVisualMapping->getTextVisual();
    }

    float TextComponent::getHorizontalTextExtent(const Window& window) const
    {
        return d_formattedRenderedString->getHorizontalExtent(&window);
    }

    float TextComponent::getVerticalTextExtent(const Window& window) const
    {
        return d_formattedRenderedString->getVerticalExtent(&window);
    }

    bool TextComponent::handleFontRenderSizeChange(Window& window,
                                                   const Font* font) const
    {
        const bool res =
            FalagardComponentBase::handleFontRenderSizeChange(window, font);

        if (font == getFontObject(window))
        {
            window.invalidate();
            return true;
        }

        return res;
    }

//----------------------------------------------------------------------------//
String TextComponent::getEffectiveText(const Window& wnd) const
{
    if (!d_textPropertyName.empty())
        return wnd.getProperty(d_textPropertyName);
    else if (d_textLogical.empty())
        return wnd.getText();
    else
        return d_textLogical;
}

//----------------------------------------------------------------------------//
String TextComponent::getEffectiveVisualText(const Window& wnd) const
{
#ifndef CEGUI_BIDI_SUPPORT
    return getEffectiveText(wnd);
#else
    if (!d_textPropertyName.empty())
    {
        String visual;
        BidiVisualMapping::StrIndexList l2v, v2l;
        d_bidiVisualMapping->reorderFromLogicalToVisual(
            wnd.getProperty(d_textPropertyName), visual, l2v, v2l);

        return visual;
    }
    // do we use a static text string from the looknfeel
    else if (d_textLogical.empty())
        return wnd.getTextVisual();
    else
        getTextVisual();
#endif
}

//----------------------------------------------------------------------------//
String TextComponent::getEffectiveFont(const Window& wnd) const
{
    if (!d_fontPropertyName.empty())
        return wnd.getProperty(d_fontPropertyName);
    else if (d_font.empty())
    {
        if (const Font* font = wnd.getFont())
            return font->getName();
        else
            return String();
    }
    else
        return d_font;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<commit_msg>MOD: Adding missing functions to TextComponent.cpp<commit_after>/***********************************************************************
    created:    Sun Jun 19 2005
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/falagard/TextComponent.h"
#include "CEGUI/falagard/XMLEnumHelper.h"
#include "CEGUI/falagard/XMLHandler.h"
#include "CEGUI/FontManager.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/PropertyHelper.h"
#include "CEGUI/Font.h"
#include "CEGUI/LeftAlignedRenderedString.h"
#include "CEGUI/RightAlignedRenderedString.h"
#include "CEGUI/CentredRenderedString.h"
#include "CEGUI/JustifiedRenderedString.h"
#include "CEGUI/RenderedStringWordWrapper.h"
#include <iostream>

#if defined (CEGUI_USE_FRIBIDI)
    #include "CEGUI/FribidiVisualMapping.h"
#elif defined (CEGUI_USE_MINIBIDI)
    #include "CEGUI/MinibidiVisualMapping.h"
#else
    #include "CEGUI/BidiVisualMapping.h"
#endif

// Start of CEGUI namespace section
namespace CEGUI
{
    TextComponent::TextComponent() :
#ifndef CEGUI_BIDI_SUPPORT
        d_bidiVisualMapping(0),
#elif defined (CEGUI_USE_FRIBIDI)
        d_bidiVisualMapping(CEGUI_NEW_AO FribidiVisualMapping),
#elif defined (CEGUI_USE_MINIBIDI)
        d_bidiVisualMapping(CEGUI_NEW_AO MinibidiVisualMapping),
#else
    #error "BIDI Configuration is inconsistant, check your config!"
#endif
        d_bidiDataValid(false),
        d_formattedRenderedString(CEGUI_NEW_AO LeftAlignedRenderedString(d_renderedString)),
        d_lastHorzFormatting(HTF_LEFT_ALIGNED),
        d_vertFormatting(VTF_TOP_ALIGNED),
        d_horzFormatting(HTF_LEFT_ALIGNED)
    {}

    TextComponent::~TextComponent()
    {
        CEGUI_DELETE_AO d_bidiVisualMapping;
    }

    TextComponent::TextComponent(const TextComponent& obj) :
        FalagardComponentBase(obj),
        d_textLogical(obj.d_textLogical),
#ifndef CEGUI_BIDI_SUPPORT
        d_bidiVisualMapping(0),
#elif defined (CEGUI_USE_FRIBIDI)
        d_bidiVisualMapping(CEGUI_NEW_AO FribidiVisualMapping),
#elif defined (CEGUI_USE_MINIBIDI)
        d_bidiVisualMapping(CEGUI_NEW_AO MinibidiVisualMapping),
#endif
        d_bidiDataValid(false),
        d_renderedString(obj.d_renderedString),
        d_formattedRenderedString(obj.d_formattedRenderedString),
        d_lastHorzFormatting(obj.d_lastHorzFormatting),
        d_font(obj.d_font),
        d_vertFormatting(obj.d_vertFormatting),
        d_horzFormatting(obj.d_horzFormatting),
        d_textPropertyName(obj.d_textPropertyName),
        d_fontPropertyName(obj.d_fontPropertyName)
    {
    }

    TextComponent& TextComponent::operator=(const TextComponent& other)
    {
        if (this == &other)
            return *this;

        FalagardComponentBase::operator=(other);

        d_textLogical = other.d_textLogical;
        // note we do not assign the BidiVisualMapping object, we just mark our
        // existing one as invalid so it's data gets regenerated next time it's
        // needed.
        d_bidiDataValid = false;
        d_renderedString = other.d_renderedString;
        d_formattedRenderedString = other.d_formattedRenderedString;
        d_lastHorzFormatting = other.d_lastHorzFormatting;
        d_font = other.d_font;
        d_vertFormatting = other.d_vertFormatting;
        d_horzFormatting = other.d_horzFormatting;
        d_textPropertyName = other.d_textPropertyName;
        d_fontPropertyName = other.d_fontPropertyName;

        return *this;
    }

    const String& TextComponent::getText() const
    {
        return d_textLogical;
    }

    void TextComponent::setText(const String& text)
    {
        d_textLogical = text;
        d_bidiDataValid = false;
    }

    const String& TextComponent::getFont() const
    {
        return d_font;
    }

    void TextComponent::setFont(const String& font)
    {
        d_font = font;
    }

    VerticalTextFormatting TextComponent::getVerticalFormatting(const Window& wnd) const
    {
        return d_vertFormatting.get(wnd);
    }

    VerticalTextFormatting TextComponent::getVerticalFormattingFromComponent() const
    {
        return d_vertFormatting.getValue();
    }

    void TextComponent::setVerticalFormatting(VerticalTextFormatting fmt)
    {
        d_vertFormatting.set(fmt);
    }

    HorizontalTextFormatting TextComponent::getHorizontalFormatting(const Window& wnd) const
    {
        return d_horzFormatting.get(wnd);
    }

    HorizontalTextFormatting TextComponent::getHorizontalFormattingFromComponent() const
    {
        return d_horzFormatting.getValue();
    }

    void TextComponent::setHorizontalFormatting(HorizontalTextFormatting fmt)
    {
        d_horzFormatting.set(fmt);
    }

    const String& TextComponent::getHorizontalFormattingPropertySource() const
    {
        return d_horzFormatting.getPropertySource();
    }

    void TextComponent::setHorizontalFormattingPropertySource(
                                                const String& property_name)
    {
        d_horzFormatting.setPropertySource(property_name);
    }

    const String& TextComponent::getVerticalFormattingPropertySource() const
    {
        return d_vertFormatting.getPropertySource();
    }

    void TextComponent::setVerticalFormattingPropertySource(
                                                const String& property_name)
    {
        d_vertFormatting.setPropertySource(property_name);
    }

    void TextComponent::setupStringFormatter(const Window& window,
                                             const RenderedString& rendered_string) const
    {
        const HorizontalTextFormatting horzFormatting = d_horzFormatting.get(window);

        // no formatting change
        if (horzFormatting == d_lastHorzFormatting)
        {
            d_formattedRenderedString->setRenderedString(rendered_string);
            return;
        }

        d_lastHorzFormatting = horzFormatting;

        switch(horzFormatting)
        {
        case HTF_LEFT_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO LeftAlignedRenderedString(rendered_string);
            break;

        case HTF_CENTRE_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO CentredRenderedString(rendered_string);
            break;

        case HTF_RIGHT_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RightAlignedRenderedString(rendered_string);
            break;

        case HTF_JUSTIFIED:
            d_formattedRenderedString =
                CEGUI_NEW_AO JustifiedRenderedString(rendered_string);
            break;

        case HTF_WORDWRAP_LEFT_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RenderedStringWordWrapper
                    <LeftAlignedRenderedString>(rendered_string);
            break;

        case HTF_WORDWRAP_CENTRE_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RenderedStringWordWrapper
                    <CentredRenderedString>(rendered_string);
            break;

        case HTF_WORDWRAP_RIGHT_ALIGNED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RenderedStringWordWrapper
                    <RightAlignedRenderedString>(rendered_string);
            break;

        case HTF_WORDWRAP_JUSTIFIED:
            d_formattedRenderedString =
                CEGUI_NEW_AO RenderedStringWordWrapper
                    <JustifiedRenderedString>(rendered_string);
            break;
        }
    }

    void TextComponent::render_impl(Window& srcWindow, Rectf& destRect, const CEGUI::ColourRect* modColours, const Rectf* clipper, bool /*clipToDisplay*/) const
    {
        const Font* font = getFontObject(srcWindow);

        // exit if we have no font to use.
        if (!font)
            return;

        const RenderedString* rs = &d_renderedString;
        // do we fetch text from a property
        if (!d_textPropertyName.empty())
        {
            // fetch text & do bi-directional reordering as needed
            String vis;
            #ifdef CEGUI_BIDI_SUPPORT
                BidiVisualMapping::StrIndexList l2v, v2l;
                d_bidiVisualMapping->reorderFromLogicalToVisual(
                    srcWindow.getProperty(d_textPropertyName), vis, l2v, v2l);
            #else
                vis = srcWindow.getProperty(d_textPropertyName);
            #endif
            // parse string using parser from Window.
            d_renderedString =
                srcWindow.getRenderedStringParser().parse(vis, font, 0);
        }
        // do we use a static text string from the looknfeel
        else if (!getTextVisual().empty())
            // parse string using parser from Window.
            d_renderedString = srcWindow.getRenderedStringParser().
                parse(getTextVisual(), font, 0);
        // do we have to override the font?
        else if (font != srcWindow.getFont())
            d_renderedString = srcWindow.getRenderedStringParser().
                parse(srcWindow.getTextVisual(), font, 0);
        // use ready-made RenderedString from the Window itself
        else
            rs = &srcWindow.getRenderedString();

        setupStringFormatter(srcWindow, *rs);
        d_formattedRenderedString->format(&srcWindow, destRect.getSize());

        // Get total formatted height.
        const float textHeight = d_formattedRenderedString->getVerticalExtent(&srcWindow);

        // handle dest area adjustments for vertical formatting.
        const VerticalTextFormatting vertFormatting = d_vertFormatting.get(srcWindow);

        switch(vertFormatting)
        {
        case VTF_CENTRE_ALIGNED:
            destRect.d_min.d_y += (destRect.getHeight() - textHeight) * 0.5f;
            break;

        case VTF_BOTTOM_ALIGNED:
            destRect.d_min.d_y = destRect.d_max.d_y - textHeight;
            break;

        default:
            // default is VTF_TOP_ALIGNED, for which we take no action.
            break;
        }

        // calculate final colours to be used
        ColourRect finalColours;
        initColoursRect(srcWindow, modColours, finalColours);

        // add geometry for text to the target window.
        d_formattedRenderedString->draw(&srcWindow, srcWindow.getGeometryBuffer(),
                                        destRect.getPosition(),
                                        &finalColours, clipper);
    }

    const Font* TextComponent::getFontObject(const Window& window) const
    {
        CEGUI_TRY
        {
            return d_fontPropertyName.empty() ?
                (d_font.empty() ? window.getFont() : &FontManager::getSingleton().get(d_font))
                : &FontManager::getSingleton().get(window.getProperty(d_fontPropertyName));
        }
        CEGUI_CATCH (UnknownObjectException&)
        {
            return 0;
        }
    }

    void TextComponent::writeXMLToStream(XMLSerializer& xml_stream) const
    {
        // opening tag
        xml_stream.openTag(Falagard_xmlHandler::TextComponentElement);
        // write out area
        d_area.writeXMLToStream(xml_stream);

        // write text element
        if (!d_font.empty() && !getText().empty())
        {
            xml_stream.openTag(Falagard_xmlHandler::TextElement);
            if (!d_font.empty())
                xml_stream.attribute(Falagard_xmlHandler::FontAttribute, d_font);
            if (!getText().empty())
                xml_stream.attribute(Falagard_xmlHandler::StringAttribute, getText());
            xml_stream.closeTag();
        }

        // write text property element
        if (!d_textPropertyName.empty())
        {
            xml_stream.openTag(Falagard_xmlHandler::TextPropertyElement)
                .attribute(Falagard_xmlHandler::NameAttribute, d_textPropertyName)
                .closeTag();
        }

        // write font property element
        if (!d_fontPropertyName.empty())
        {
            xml_stream.openTag(Falagard_xmlHandler::FontPropertyElement)
                .attribute(Falagard_xmlHandler::NameAttribute, d_fontPropertyName)
                .closeTag();
        }

        // get base class to write colours
        writeColoursXML(xml_stream);

        d_vertFormatting.writeXMLToStream(xml_stream);
        d_horzFormatting.writeXMLToStream(xml_stream);

        // closing tag
        xml_stream.closeTag();
    }

    bool TextComponent::isTextFetchedFromProperty() const
    {
        return !d_textPropertyName.empty();
    }

    const String& TextComponent::getTextPropertySource() const
    {
        return d_textPropertyName;
    }

    void TextComponent::setTextPropertySource(const String& property)
    {
        d_textPropertyName = property;
    }

    bool TextComponent::isFontFetchedFromProperty() const
    {
        return !d_fontPropertyName.empty();
    }

    const String& TextComponent::getFontPropertySource() const
    {
        return d_fontPropertyName;
    }

    void TextComponent::setFontPropertySource(const String& property)
    {
        d_fontPropertyName = property;
    }

    const String& TextComponent::getTextVisual() const
    {
        // no bidi support
        if (!d_bidiVisualMapping)
            return d_textLogical;

        if (!d_bidiDataValid)
        {
            d_bidiVisualMapping->updateVisual(d_textLogical);
            d_bidiDataValid = true;
        }

        return d_bidiVisualMapping->getTextVisual();
    }

    float TextComponent::getHorizontalTextExtent(const Window& window) const
    {
        return d_formattedRenderedString->getHorizontalExtent(&window);
    }

    float TextComponent::getVerticalTextExtent(const Window& window) const
    {
        return d_formattedRenderedString->getVerticalExtent(&window);
    }

    bool TextComponent::handleFontRenderSizeChange(Window& window,
                                                   const Font* font) const
    {
        const bool res =
            FalagardComponentBase::handleFontRenderSizeChange(window, font);

        if (font == getFontObject(window))
        {
            window.invalidate();
            return true;
        }

        return res;
    }

//----------------------------------------------------------------------------//
String TextComponent::getEffectiveText(const Window& wnd) const
{
    if (!d_textPropertyName.empty())
        return wnd.getProperty(d_textPropertyName);
    else if (d_textLogical.empty())
        return wnd.getText();
    else
        return d_textLogical;
}

//----------------------------------------------------------------------------//
String TextComponent::getEffectiveVisualText(const Window& wnd) const
{
#ifndef CEGUI_BIDI_SUPPORT
    return getEffectiveText(wnd);
#else
    if (!d_textPropertyName.empty())
    {
        String visual;
        BidiVisualMapping::StrIndexList l2v, v2l;
        d_bidiVisualMapping->reorderFromLogicalToVisual(
            wnd.getProperty(d_textPropertyName), visual, l2v, v2l);

        return visual;
    }
    // do we use a static text string from the looknfeel
    else if (d_textLogical.empty())
        return wnd.getTextVisual();
    else
        getTextVisual();
#endif
}

//----------------------------------------------------------------------------//
String TextComponent::getEffectiveFont(const Window& wnd) const
{
    if (!d_fontPropertyName.empty())
        return wnd.getProperty(d_fontPropertyName);
    else if (d_font.empty())
    {
        if (const Font* font = wnd.getFont())
            return font->getName();
        else
            return String();
    }
    else
        return d_font;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before>// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/coverage.h"

#include "include/dart_api.h"

#include "vm/compiler.h"
#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"

namespace dart {

DEFINE_FLAG(charp, coverage_dir, NULL,
            "Enable writing coverage data into specified directory.");

class CoverageFilterAll : public CoverageFilter {
 public:
  bool ShouldOutputCoverageFor(const Library& lib,
                               const Script& script,
                               const Class& cls,
                               const Function& func) const {
    return true;
  }
};

// map[token_pos] -> line-number.
static void ComputeTokenPosToLineNumberMap(const Script& script,
                                           GrowableArray<intptr_t>* map) {
  const TokenStream& tkns = TokenStream::Handle(script.tokens());
  const intptr_t len = ExternalTypedData::Handle(tkns.GetStream()).Length();
  map->SetLength(len);
#if defined(DEBUG)
  for (intptr_t i = 0; i < len; i++) {
    (*map)[i] = -1;
  }
#endif
  TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
  intptr_t cur_line = script.line_offset() + 1;
  while (tkit.CurrentTokenKind() != Token::kEOS) {
    (*map)[tkit.CurrentPosition()] = cur_line;
    if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
      cur_line++;
    }
    tkit.Advance();
  }
}

void CodeCoverage::CompileAndAdd(const Function& function,
                                 const JSONArray& hits_or_sites,
                                 const GrowableArray<intptr_t>& pos_to_line,
                                 bool as_call_sites) {
  // If the function should not be compiled for coverage analysis, then just
  // skip this method.
  // TODO(iposva): Maybe we should skip synthesized methods in general too.
  if (function.is_abstract() || function.IsRedirectingFactory()) {
    return;
  }
  if (function.IsNonImplicitClosureFunction() &&
      (function.context_scope() == ContextScope::null())) {
    // TODO(iposva): This can arise if we attempt to compile an inner function
    // before we have compiled its enclosing function or if the enclosing
    // function failed to compile.
    return;
  }
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  // Make sure we have the unoptimized code for this function available.
  if (Compiler::EnsureUnoptimizedCode(thread, function) != Error::null()) {
    // Ignore the error and this function entirely.
    return;
  }
  const Code& code = Code::Handle(zone, function.unoptimized_code());
  ASSERT(!code.IsNull());

  // Print the hit counts for all IC datas.
  ZoneGrowableArray<const ICData*>* ic_data_array =
      new(zone) ZoneGrowableArray<const ICData*>();
  function.RestoreICDataMap(ic_data_array);
  const PcDescriptors& descriptors = PcDescriptors::Handle(
      zone, code.pc_descriptors());

  const intptr_t begin_pos = function.token_pos();
  const intptr_t end_pos = function.end_token_pos();
  intptr_t last_line = -1;
  intptr_t last_count = 0;
  // Only IC based calls have counting.
  PcDescriptors::Iterator iter(descriptors,
      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
  while (iter.MoveNext()) {
    HANDLESCOPE(thread);
    const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
    if (!ic_data->IsNull()) {
      const intptr_t token_pos = iter.TokenPos();
      // Filter out descriptors that do not map to tokens in the source code.
      if ((token_pos < begin_pos) || (token_pos > end_pos)) {
        continue;
      }
      intptr_t line = pos_to_line[token_pos];
#if defined(DEBUG)
      const Script& script = Script::Handle(zone, function.script());
      intptr_t test_line = -1;
      script.GetTokenLocation(token_pos, &test_line, NULL);
      ASSERT(test_line == line);
#endif
      // Merge hit data where possible.
      if (last_line == line) {
        last_count += ic_data->AggregateCount();
      } else {
        if ((last_line != -1) && !as_call_sites) {
          hits_or_sites.AddValue(last_line);
          hits_or_sites.AddValue(last_count);
        }
        last_count = ic_data->AggregateCount();
        last_line = line;
      }
      if (as_call_sites) {
        bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall;
        ic_data->PrintToJSONArray(hits_or_sites, token_pos, is_static_call);
      }
    }
  }
  // Write last hit value if needed.
  if ((last_line != -1) && !as_call_sites) {
    hits_or_sites.AddValue(last_line);
    hits_or_sites.AddValue(last_count);
  }
}

void CodeCoverage::PrintClass(const Library& lib,
                              const Class& cls,
                              const JSONArray& jsarr,
                              CoverageFilter* filter,
                              bool as_call_sites) {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  if (cls.EnsureIsFinalized(isolate) != Error::null()) {
    // Only classes that have been finalized do have a meaningful list of
    // functions.
    return;
  }
  Array& functions = Array::Handle(cls.functions());
  ASSERT(!functions.IsNull());
  Function& function = Function::Handle();
  Script& script = Script::Handle();
  String& saved_url = String::Handle();
  String& url = String::Handle();
  GrowableArray<intptr_t> pos_to_line;
  int i = 0;
  while (i < functions.Length()) {
    HANDLESCOPE(thread);
    function ^= functions.At(i);
    script = function.script();
    saved_url = script.url();
    if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
      i++;
      continue;
    }
    ComputeTokenPosToLineNumberMap(script, &pos_to_line);
    JSONObject jsobj(&jsarr);
    jsobj.AddProperty("source", saved_url.ToCString());
    jsobj.AddProperty("script", script);
    JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");

    // We stay within this loop while we are seeing functions from the same
    // source URI.
    while (i < functions.Length()) {
      function ^= functions.At(i);
      script = function.script();
      url = script.url();
      if (!url.Equals(saved_url)) {
        pos_to_line.Clear();
        break;
      }
      if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
        i++;
        continue;
      }
      CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
      i++;
    }
  }

  GrowableObjectArray& closures =
      GrowableObjectArray::Handle(cls.closures());
  if (!closures.IsNull()) {
    i = 0;
    pos_to_line.Clear();
    // We need to keep rechecking the length of the closures array, as handling
    // a closure potentially adds new entries to the end.
    while (i < closures.Length()) {
      HANDLESCOPE(thread);
      function ^= closures.At(i);
      script = function.script();
      saved_url = script.url();
      if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
        i++;
        continue;
      }
      ComputeTokenPosToLineNumberMap(script, &pos_to_line);
      JSONObject jsobj(&jsarr);
      jsobj.AddProperty("source", saved_url.ToCString());
      jsobj.AddProperty("script", script);
      JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");

      // We stay within this loop while we are seeing functions from the same
      // source URI.
      while (i < closures.Length()) {
        function ^= closures.At(i);
        script = function.script();
        url = script.url();
        if (!url.Equals(saved_url)) {
          pos_to_line.Clear();
          break;
        }
        CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
        i++;
      }
    }
  }
}

void CodeCoverage::Write(Isolate* isolate) {
  if (FLAG_coverage_dir == NULL) {
    return;
  }

  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
  Dart_FileWriteCallback file_write = Isolate::file_write_callback();
  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
  if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
    return;
  }

  JSONStream stream;
  PrintJSON(isolate, &stream, NULL, false);

  const char* format = "%s/dart-cov-%" Pd "-%" Pd64 ".json";
  intptr_t pid = OS::ProcessId();
  intptr_t len = OS::SNPrint(NULL, 0, format,
                             FLAG_coverage_dir, pid, isolate->main_port());
  char* filename = Thread::Current()->zone()->Alloc<char>(len + 1);
  OS::SNPrint(filename, len + 1, format,
              FLAG_coverage_dir, pid, isolate->main_port());
  void* file = (*file_open)(filename, true);
  if (file == NULL) {
    OS::Print("Failed to write coverage file: %s\n", filename);
    return;
  }
  (*file_write)(stream.buffer()->buf(), stream.buffer()->length(), file);
  (*file_close)(file);
}

void CodeCoverage::PrintJSON(Isolate* isolate,
                             JSONStream* stream,
                             CoverageFilter* filter,
                             bool as_call_sites) {
  CoverageFilterAll default_filter;
  if (filter == NULL) {
    filter = &default_filter;
  }
  const GrowableObjectArray& libs = GrowableObjectArray::Handle(
      isolate, isolate->object_store()->libraries());
  Library& lib = Library::Handle();
  Class& cls = Class::Handle();
  JSONObject coverage(stream);
  coverage.AddProperty("type", "CodeCoverage");
  {
    JSONArray jsarr(&coverage, "coverage");
    for (int i = 0; i < libs.Length(); i++) {
      lib ^= libs.At(i);
      ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
      while (it.HasNext()) {
        cls = it.GetNextClass();
        ASSERT(!cls.IsNull());
        PrintClass(lib, cls, jsarr, filter, as_call_sites);
      }
    }
  }
}

}  // namespace dart
<commit_msg>Do less work while computing call site info.<commit_after>// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/coverage.h"

#include "include/dart_api.h"

#include "vm/compiler.h"
#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"

namespace dart {

DEFINE_FLAG(charp, coverage_dir, NULL,
            "Enable writing coverage data into specified directory.");

class CoverageFilterAll : public CoverageFilter {
 public:
  bool ShouldOutputCoverageFor(const Library& lib,
                               const Script& script,
                               const Class& cls,
                               const Function& func) const {
    return true;
  }
};

// map[token_pos] -> line-number.
static void ComputeTokenPosToLineNumberMap(const Script& script,
                                           GrowableArray<intptr_t>* map) {
  const TokenStream& tkns = TokenStream::Handle(script.tokens());
  const intptr_t len = ExternalTypedData::Handle(tkns.GetStream()).Length();
  map->SetLength(len);
#if defined(DEBUG)
  for (intptr_t i = 0; i < len; i++) {
    (*map)[i] = -1;
  }
#endif
  TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
  intptr_t cur_line = script.line_offset() + 1;
  while (tkit.CurrentTokenKind() != Token::kEOS) {
    (*map)[tkit.CurrentPosition()] = cur_line;
    if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
      cur_line++;
    }
    tkit.Advance();
  }
}

void CodeCoverage::CompileAndAdd(const Function& function,
                                 const JSONArray& hits_or_sites,
                                 const GrowableArray<intptr_t>& pos_to_line,
                                 bool as_call_sites) {
  // If the function should not be compiled for coverage analysis, then just
  // skip this method.
  // TODO(iposva): Maybe we should skip synthesized methods in general too.
  if (function.is_abstract() || function.IsRedirectingFactory()) {
    return;
  }
  if (function.IsNonImplicitClosureFunction() &&
      (function.context_scope() == ContextScope::null())) {
    // TODO(iposva): This can arise if we attempt to compile an inner function
    // before we have compiled its enclosing function or if the enclosing
    // function failed to compile.
    return;
  }
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  // Make sure we have the unoptimized code for this function available.
  if (Compiler::EnsureUnoptimizedCode(thread, function) != Error::null()) {
    // Ignore the error and this function entirely.
    return;
  }
  const Code& code = Code::Handle(zone, function.unoptimized_code());
  ASSERT(!code.IsNull());

  // Print the hit counts for all IC datas.
  ZoneGrowableArray<const ICData*>* ic_data_array =
      new(zone) ZoneGrowableArray<const ICData*>();
  function.RestoreICDataMap(ic_data_array);
  const PcDescriptors& descriptors = PcDescriptors::Handle(
      zone, code.pc_descriptors());

  const intptr_t begin_pos = function.token_pos();
  const intptr_t end_pos = function.end_token_pos();
  intptr_t last_line = -1;
  intptr_t last_count = 0;
  // Only IC based calls have counting.
  PcDescriptors::Iterator iter(descriptors,
      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
  while (iter.MoveNext()) {
    HANDLESCOPE(thread);
    const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
    if (!ic_data->IsNull()) {
      const intptr_t token_pos = iter.TokenPos();
      // Filter out descriptors that do not map to tokens in the source code.
      if ((token_pos < begin_pos) || (token_pos > end_pos)) {
        continue;
      }
      if (as_call_sites) {
        bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall;
        ic_data->PrintToJSONArray(hits_or_sites, token_pos, is_static_call);
      } else {
        intptr_t line = pos_to_line[token_pos];
#if defined(DEBUG)
        const Script& script = Script::Handle(zone, function.script());
        intptr_t test_line = -1;
        script.GetTokenLocation(token_pos, &test_line, NULL);
        ASSERT(test_line == line);
#endif
        // Merge hit data where possible.
        if (last_line == line) {
          last_count += ic_data->AggregateCount();
        } else {
          if ((last_line != -1)) {
            hits_or_sites.AddValue(last_line);
            hits_or_sites.AddValue(last_count);
          }
          last_count = ic_data->AggregateCount();
          last_line = line;
        }
      }
    }
  }
  // Write last hit value if needed.
  if (!as_call_sites && (last_line != -1)) {
    hits_or_sites.AddValue(last_line);
    hits_or_sites.AddValue(last_count);
  }
}

void CodeCoverage::PrintClass(const Library& lib,
                              const Class& cls,
                              const JSONArray& jsarr,
                              CoverageFilter* filter,
                              bool as_call_sites) {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  if (cls.EnsureIsFinalized(isolate) != Error::null()) {
    // Only classes that have been finalized do have a meaningful list of
    // functions.
    return;
  }
  Array& functions = Array::Handle(cls.functions());
  ASSERT(!functions.IsNull());
  Function& function = Function::Handle();
  Script& script = Script::Handle();
  String& saved_url = String::Handle();
  String& url = String::Handle();
  GrowableArray<intptr_t> pos_to_line;
  int i = 0;
  while (i < functions.Length()) {
    HANDLESCOPE(thread);
    function ^= functions.At(i);
    script = function.script();
    saved_url = script.url();
    if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
      i++;
      continue;
    }
    if (!as_call_sites) {
      ComputeTokenPosToLineNumberMap(script, &pos_to_line);
    }
    JSONObject jsobj(&jsarr);
    jsobj.AddProperty("source", saved_url.ToCString());
    jsobj.AddProperty("script", script);
    JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");

    // We stay within this loop while we are seeing functions from the same
    // source URI.
    while (i < functions.Length()) {
      function ^= functions.At(i);
      script = function.script();
      url = script.url();
      if (!url.Equals(saved_url)) {
        pos_to_line.Clear();
        break;
      }
      if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
        i++;
        continue;
      }
      CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
      i++;
    }
  }

  GrowableObjectArray& closures =
      GrowableObjectArray::Handle(cls.closures());
  if (!closures.IsNull()) {
    i = 0;
    pos_to_line.Clear();
    // We need to keep rechecking the length of the closures array, as handling
    // a closure potentially adds new entries to the end.
    while (i < closures.Length()) {
      HANDLESCOPE(thread);
      function ^= closures.At(i);
      script = function.script();
      saved_url = script.url();
      if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
        i++;
        continue;
      }
      ComputeTokenPosToLineNumberMap(script, &pos_to_line);
      JSONObject jsobj(&jsarr);
      jsobj.AddProperty("source", saved_url.ToCString());
      jsobj.AddProperty("script", script);
      JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");

      // We stay within this loop while we are seeing functions from the same
      // source URI.
      while (i < closures.Length()) {
        function ^= closures.At(i);
        script = function.script();
        url = script.url();
        if (!url.Equals(saved_url)) {
          pos_to_line.Clear();
          break;
        }
        CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
        i++;
      }
    }
  }
}

void CodeCoverage::Write(Isolate* isolate) {
  if (FLAG_coverage_dir == NULL) {
    return;
  }

  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
  Dart_FileWriteCallback file_write = Isolate::file_write_callback();
  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
  if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
    return;
  }

  JSONStream stream;
  PrintJSON(isolate, &stream, NULL, false);

  const char* format = "%s/dart-cov-%" Pd "-%" Pd64 ".json";
  intptr_t pid = OS::ProcessId();
  intptr_t len = OS::SNPrint(NULL, 0, format,
                             FLAG_coverage_dir, pid, isolate->main_port());
  char* filename = Thread::Current()->zone()->Alloc<char>(len + 1);
  OS::SNPrint(filename, len + 1, format,
              FLAG_coverage_dir, pid, isolate->main_port());
  void* file = (*file_open)(filename, true);
  if (file == NULL) {
    OS::Print("Failed to write coverage file: %s\n", filename);
    return;
  }
  (*file_write)(stream.buffer()->buf(), stream.buffer()->length(), file);
  (*file_close)(file);
}

void CodeCoverage::PrintJSON(Isolate* isolate,
                             JSONStream* stream,
                             CoverageFilter* filter,
                             bool as_call_sites) {
  CoverageFilterAll default_filter;
  if (filter == NULL) {
    filter = &default_filter;
  }
  const GrowableObjectArray& libs = GrowableObjectArray::Handle(
      isolate, isolate->object_store()->libraries());
  Library& lib = Library::Handle();
  Class& cls = Class::Handle();
  JSONObject coverage(stream);
  coverage.AddProperty("type", "CodeCoverage");
  {
    JSONArray jsarr(&coverage, "coverage");
    for (int i = 0; i < libs.Length(); i++) {
      lib ^= libs.At(i);
      ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
      while (it.HasNext()) {
        cls = it.GetNextClass();
        ASSERT(!cls.IsNull());
        PrintClass(lib, cls, jsarr, filter, as_call_sites);
      }
    }
  }
}

}  // namespace dart
<|endoftext|>


<commit_before>#include "TaskFS.hpp"
#include <iostream>
#include "Task.hpp"
#include "Category.hpp"
#include <cstdlib>
#include <posix/sys/stat.h>
#include <kernel/fs_index.h>

TaskFS::TaskFS()
{
	error=new BAlert("FileSystem error",
		"There was an error in the BeFS backend",
		"OK",NULL,NULL,B_WIDTH_AS_USUAL,B_OFFSET_SPACING, B_STOP_ALERT);
	BPath path;
	if(find_directory(B_USER_SETTINGS_DIRECTORY,&path)!=B_OK)
	{
		error->Go();
		exit(2);
	}
	BDirectory storage;
	BDirectory tasksDir;
	BDirectory categoriesDir;
	BDirectory settings(path.Path());
	settings.CreateDirectory("HaikuToDo",&storage);
	storage.CreateDirectory("Tasks",&tasksDir);
	storage.CreateDirectory("Categories",&categoriesDir);
	path.Append("HaikuToDo");
	BPath taskPath=path;
	taskPath.Append("Tasks");
	BPath categoriesPath=path;
	categoriesPath.Append("Categories");
	tasks=BString(taskPath.Path());
	categories=BString(categoriesPath.Path());

	struct stat st;
	settings.GetStat(&st);

	volume=st.st_dev;

	fs_create_index(st.st_dev,"HAIKU_TO_DO:Category",B_STRING_TYPE,0);

}

TaskFS::~TaskFS()
{

}

void
TaskFS::LoadTasks(const char* category, BListView* tasksList)
{
	BString predicate("HAIKU_TO_DO:Category=**");
	if(strcmp(category,"ALL")==0)
		predicate.Append("**");
	else
		predicate.Append(category);
	BQuery query;
	BVolume volume;
	BVolumeRoster volumeRoster;
	while(volumeRoster.GetNextVolume(&volume)==B_OK)
	{
		if(volume.KnowsQuery())
		{
			query.Clear();
			query.SetVolume(&volume);
			query.SetPredicate(predicate.String());
			status_t rc=query.Fetch();
			if(rc!=B_OK)
			{
				error->Go();
			}
			BEntry entry;
			while(query.GetNextEntry(&entry)==B_OK)
			{
				char name[8192];
				entry.GetName(name);
				BFile file(&entry,B_READ_ONLY);
				off_t file_size=0;
				file.GetSize(&file_size);
				char buffer[file_size+1024];
				file.Read(buffer,file_size);
				BString finished;
				file.ReadAttrString("HAIKU_TO_DO:Finished",&finished);
				bool fin;
				if(finished.Compare("FINISHED")==0)
				{
					fin=true;
				}
				else
				{
					fin=false;
				}
				Task* tk=new Task((const char*)name,(const char*)buffer,"ALL",fin);
				tasksList->AddItem(tk);
			}
		}
	}

}

void
TaskFS::LoadCategories(BListView* categoriesList)
{
		BDirectory dir(categories);
		int32 entries=dir.CountEntries();
		for(int32 i=0;i<entries;i++)
		{
			char name[8192];
			BEntry entry;
			dir.GetNextEntry(&entry);
			entry.GetName(name);
			BFile file(&entry,B_READ_ONLY);
			off_t file_size=0;
			file.GetSize(&file_size);
			char buffer[file_size+1024];
			file.Read(buffer,file_size);
			Category* cat=new Category((const char*)name,(const char*)buffer);
			categoriesList->AddItem(cat);
		}
}

bool
TaskFS::AddCategory(const char* name, const char* filename)
{
	BString filn(filename);
	BDirectory dir(categories);
	BFile file;
	dir.CreateFile(name,&file);
	file.Write(filn,filn.Length());
}

bool
TaskFS::AddTask(const char* title, const char* description, const char* category)
{
	BString desc(description);
	BDirectory dir(tasks);
	BFile file;
	dir.CreateFile(title,&file);
	file.Write(desc,desc.Length());
	file.WriteAttrString("HAIKU_TO_DO:Category",new BString(category));
	file.WriteAttrString("HAIKU_TO_DO:Finished",new BString("UNFINISHED"));
}

bool
TaskFS::RemoveTask(const char* title, const char* description, const char* category)
{
	BString predicate("(HAIKU_TO_DO:Category=**)&&(name=");
	predicate.Append(title);
	predicate.Append(")");

	BQuery query;
	BVolume volume;
	BVolumeRoster volumeRoster;
	while(volumeRoster.GetNextVolume(&volume)==B_OK)
	{
		if(volume.KnowsQuery())
		{
			query.Clear();
			query.SetVolume(&volume);
			query.SetPredicate(predicate.String());
			status_t rc=query.Fetch();
			if(rc!=B_OK)
			{
				error->Go();
			}
			BEntry entry;
			while(query.GetNextEntry(&entry)==B_OK)
			{
				entry.Remove();
			}
		}
	}
}

bool
TaskFS::MarkAsComplete(const char* title, const char* description, const char* category)
{
	BString predicate("(HAIKU_TO_DO:Category=**)&&(name=");
	predicate.Append(title);
	predicate.Append(")");

	BQuery query;
	BVolume volume;
	BVolumeRoster volumeRoster;
	while(volumeRoster.GetNextVolume(&volume)==B_OK)
	{
		if(volume.KnowsQuery())
		{
			query.Clear();
			query.SetVolume(&volume);
			query.SetPredicate(predicate.String());
			status_t rc=query.Fetch();
			if(rc!=B_OK)
			{
				error->Go();
			}
			BEntry entry;
			while(query.GetNextEntry(&entry)==B_OK)
			{
				BFile file(&entry,B_READ_ONLY);
				file.WriteAttrString("HAIKU_TO_DO:Finished",new BString("FINISHED"));
			}
		}
	}
}

<commit_msg>HAIKU_TO_DO:Finished is now a boolean type<commit_after>#include "TaskFS.hpp"
#include <iostream>
#include "Task.hpp"
#include "Category.hpp"
#include <cstdlib>
#include <TypeConstants.h>
#include <posix/sys/stat.h>
#include <kernel/fs_index.h>

TaskFS::TaskFS()
{
	error=new BAlert("FileSystem error",
		"There was an error in the BeFS backend",
		"OK",NULL,NULL,B_WIDTH_AS_USUAL,B_OFFSET_SPACING, B_STOP_ALERT);
	BPath path;
	if(find_directory(B_USER_SETTINGS_DIRECTORY,&path)!=B_OK)
	{
		error->Go();
		exit(2);
	}
	BDirectory storage;
	BDirectory tasksDir;
	BDirectory categoriesDir;
	BDirectory settings(path.Path());
	settings.CreateDirectory("HaikuToDo",&storage);
	storage.CreateDirectory("Tasks",&tasksDir);
	storage.CreateDirectory("Categories",&categoriesDir);
	path.Append("HaikuToDo");
	BPath taskPath=path;
	taskPath.Append("Tasks");
	BPath categoriesPath=path;
	categoriesPath.Append("Categories");
	tasks=BString(taskPath.Path());
	categories=BString(categoriesPath.Path());

	struct stat st;
	settings.GetStat(&st);

	volume=st.st_dev;

	fs_create_index(st.st_dev,"HAIKU_TO_DO:Category",B_STRING_TYPE,0);

}

TaskFS::~TaskFS()
{

}

void
TaskFS::LoadTasks(const char* category, BListView* tasksList)
{
	BString predicate("HAIKU_TO_DO:Category=**");
	if(strcmp(category,"ALL")==0)
		predicate.Append("**");
	else
		predicate.Append(category);
	BQuery query;
	BVolume volume;
	BVolumeRoster volumeRoster;
	while(volumeRoster.GetNextVolume(&volume)==B_OK)
	{
		if(volume.KnowsQuery())
		{
			query.Clear();
			query.SetVolume(&volume);
			query.SetPredicate(predicate.String());
			status_t rc=query.Fetch();
			if(rc!=B_OK)
			{
				error->Go();
			}
			BEntry entry;
			while(query.GetNextEntry(&entry)==B_OK)
			{
				char name[8192];
				entry.GetName(name);
				BFile file(&entry,B_READ_ONLY);
				off_t file_size=0;
				file.GetSize(&file_size);
				char buffer[file_size+1024];
				file.Read(buffer,file_size);
				bool finished;
				file.ReadAttr("HAIKU_TO_DO:Finished",B_BOOL_TYPE,0,&finished,sizeof(bool));
				Task* tk=new Task((const char*)name,(const char*)buffer,"ALL",finished);
				tasksList->AddItem(tk);
			}
		}
	}

}

void
TaskFS::LoadCategories(BListView* categoriesList)
{
		BDirectory dir(categories);
		int32 entries=dir.CountEntries();
		for(int32 i=0;i<entries;i++)
		{
			char name[8192];
			BEntry entry;
			dir.GetNextEntry(&entry);
			entry.GetName(name);
			BFile file(&entry,B_READ_ONLY);
			off_t file_size=0;
			file.GetSize(&file_size);
			char buffer[file_size+1024];
			file.Read(buffer,file_size);
			Category* cat=new Category((const char*)name,(const char*)buffer);
			categoriesList->AddItem(cat);
		}
}

bool
TaskFS::AddCategory(const char* name, const char* filename)
{
	BString filn(filename);
	BDirectory dir(categories);
	BFile file;
	dir.CreateFile(name,&file);
	file.Write(filn,filn.Length());
}

bool
TaskFS::AddTask(const char* title, const char* description, const char* category)
{
	BString desc(description);
	BDirectory dir(tasks);
	BFile file;
	dir.CreateFile(title,&file);
	file.Write(desc,desc.Length());
	file.WriteAttrString("HAIKU_TO_DO:Category",new BString(category));
	bool finished=false;
	file.WriteAttr("HAIKU_TO_DO:Finished",B_BOOL_TYPE,0,&finished,sizeof(bool));
}

bool
TaskFS::RemoveTask(const char* title, const char* description, const char* category)
{
	BString predicate("(HAIKU_TO_DO:Category=**)&&(name=");
	predicate.Append(title);
	predicate.Append(")");

	BQuery query;
	BVolume volume;
	BVolumeRoster volumeRoster;
	while(volumeRoster.GetNextVolume(&volume)==B_OK)
	{
		if(volume.KnowsQuery())
		{
			query.Clear();
			query.SetVolume(&volume);
			query.SetPredicate(predicate.String());
			status_t rc=query.Fetch();
			if(rc!=B_OK)
			{
				error->Go();
			}
			BEntry entry;
			while(query.GetNextEntry(&entry)==B_OK)
			{
				entry.Remove();
			}
		}
	}
}

bool
TaskFS::MarkAsComplete(const char* title, const char* description, const char* category)
{
	BString predicate("(HAIKU_TO_DO:Category=**)&&(name=");
	predicate.Append(title);
	predicate.Append(")");

	BQuery query;
	BVolume volume;
	BVolumeRoster volumeRoster;
	while(volumeRoster.GetNextVolume(&volume)==B_OK)
	{
		if(volume.KnowsQuery())
		{
			query.Clear();
			query.SetVolume(&volume);
			query.SetPredicate(predicate.String());
			status_t rc=query.Fetch();
			if(rc!=B_OK)
			{
				error->Go();
			}
			BEntry entry;
			while(query.GetNextEntry(&entry)==B_OK)
			{
				BFile file(&entry,B_READ_ONLY);
				bool finished=true;
				file.WriteAttr("HAIKU_TO_DO:Finished",B_BOOL_TYPE,0,&finished,sizeof(bool));
			}
		}
	}
}

<|endoftext|>


<commit_before>#pragma once

#include <stdint.h>
#include <vector>

#include "Vector.hpp"
#include "APIQuadcopter.hpp"
#include "APIFormation.hpp"
#include "APICamera.hpp"
#include "APICameraSystem.hpp"
#include "APIMessageListener.hpp"

#include "api_application/Announce.h"

namespace kitrokopter {

    class API {

    public:

	API(int argc, char **argv);
	~API();

	bool announce(
	    api_application::Announce::Request &req,
	    api_application::Announce::Response &res);

	void initializeCameras();

	/* Quadcopter mutation */
	APIQuadcopter* getQuadcpoter(int id);
	bool removeQuadcopter(int id);

	/* Formation */
	void setFormation(APIFormation formation);
	APIFormation* getFormation();

	/* Cameras */
	APICameraSystem* getCameraSystem();
	std::vector<APICamera*> getCameras();
	std::vector<APICamera*> getCalibratedCameras();
	std::vector<APICamera*> getUncalibratedCameras();
	int getCameraAmount();
	int getCalibratedCameraAmount();
	int getUncalibratedCameraAmount();

	/* Quadcopter getters */
	std::vector<APIQuadcopter*> getQuadcopters();
	std::vector<APIQuadcopter*> getQuadcoptersSelectedForFlight();
	std::vector<APIQuadcopter*> getQuadcoptersNotSelectedForFlight();
        /* TODO: Also selectors for quadcopters currently flying or on the ground? */
	std::vector<APIQuadcopter*> getQuadcoptersTracked();
	std::vector<APIQuadcopter*> getQuadcoptersUntracked();
	std::vector<APIQuadcopter*> getQuadcoptersInFormation();
	std::vector<APIQuadcopter*> getQuadcoptersNotInFormation();

	int* scanChannels();

	/* Quadcopter amount */
	int getQuadcopterAmount();
	int getQuadcoptersFlyingAmount();
	int getQuadcoptersOnGroundAmount();
	int getQuadcoptersTrackedAmount();
	int getQuadcoptersUntrackedAmount();
	int getQuadcoptersInFormationAmount();
	int getQuadcoptersNotInFormationAmount();

	/* message listeners */
	void addMessageListener(APIMessageListener*);
	void removeMessageListener(APIMessageListener*);

	/* Launch / Land */
	// TODO
	void launchQuadcopters(int height) {}
	double getLaunchProgress();
	bool quadcoptersLaunched();
	void landQuadcopters();

	void shutdownSystem();

	/* Settings */
	Cuboid getMaximumOperatingArea();
	bool setOperatingArea(Cuboid);
	int getMaximumHorizontalSpeed();
	int getMaximumVerticalSpeed();
	int getMaximumHorizontalAcceleration();
	int getMaximumVerticalAcceleration();
	void setReceiveTargetMovementData(bool);
	void setReceiveActualMovementData(bool);
	void setReceiveQuadcopterState(bool);

	/* Movement */
	void moveFormation(Vector);
	void rotateFormation(Vector);

    private:
	int idCounter;
	ros::AsyncSpinner *spinner;

	//the ids of modules by category
	std::vector<int> controllerIds;
	std::vector<int> positionIds;

	APICameraSystem cameraSystem;
	std::map <uint32_t, APIQuadcopter> quadcopters;

	APIFormation formation;
    };
}
<commit_msg>Add shutdownSystem() dummy<commit_after>#pragma once

#include <stdint.h>
#include <vector>

#include "Vector.hpp"
#include "APIQuadcopter.hpp"
#include "APIFormation.hpp"
#include "APICamera.hpp"
#include "APICameraSystem.hpp"
#include "APIMessageListener.hpp"

#include "api_application/Announce.h"

namespace kitrokopter {

    class API {

    public:

	API(int argc, char **argv);
	~API();

	bool announce(
	    api_application::Announce::Request &req,
	    api_application::Announce::Response &res);

	void initializeCameras();

	/* Quadcopter mutation */
	APIQuadcopter* getQuadcpoter(int id);
	bool removeQuadcopter(int id);

	/* Formation */
	void setFormation(APIFormation formation);
	APIFormation* getFormation();

	/* Cameras */
	APICameraSystem* getCameraSystem();
	std::vector<APICamera*> getCameras();
	std::vector<APICamera*> getCalibratedCameras();
	std::vector<APICamera*> getUncalibratedCameras();
	int getCameraAmount();
	int getCalibratedCameraAmount();
	int getUncalibratedCameraAmount();

	/* Quadcopter getters */
	std::vector<APIQuadcopter*> getQuadcopters();
	std::vector<APIQuadcopter*> getQuadcoptersSelectedForFlight();
	std::vector<APIQuadcopter*> getQuadcoptersNotSelectedForFlight();
        /* TODO: Also selectors for quadcopters currently flying or on the ground? */
	std::vector<APIQuadcopter*> getQuadcoptersTracked();
	std::vector<APIQuadcopter*> getQuadcoptersUntracked();
	std::vector<APIQuadcopter*> getQuadcoptersInFormation();
	std::vector<APIQuadcopter*> getQuadcoptersNotInFormation();

	int* scanChannels();

	/* Quadcopter amount */
	int getQuadcopterAmount();
	int getQuadcoptersFlyingAmount();
	int getQuadcoptersOnGroundAmount();
	int getQuadcoptersTrackedAmount();
	int getQuadcoptersUntrackedAmount();
	int getQuadcoptersInFormationAmount();
	int getQuadcoptersNotInFormationAmount();

	/* message listeners */
	void addMessageListener(APIMessageListener*);
	void removeMessageListener(APIMessageListener*);

	/* Launch / Land */
	// TODO
	void launchQuadcopters(int height) {}
	double getLaunchProgress();
	bool quadcoptersLaunched();
	void landQuadcopters();

	// TODO
	void shutdownSystem() {}

	/* Settings */
	Cuboid getMaximumOperatingArea();
	bool setOperatingArea(Cuboid);
	int getMaximumHorizontalSpeed();
	int getMaximumVerticalSpeed();
	int getMaximumHorizontalAcceleration();
	int getMaximumVerticalAcceleration();
	void setReceiveTargetMovementData(bool);
	void setReceiveActualMovementData(bool);
	void setReceiveQuadcopterState(bool);

	/* Movement */
	void moveFormation(Vector);
	void rotateFormation(Vector);

    private:
	int idCounter;
	ros::AsyncSpinner *spinner;

	//the ids of modules by category
	std::vector<int> controllerIds;
	std::vector<int> positionIds;

	APICameraSystem cameraSystem;
	std::map <uint32_t, APIQuadcopter> quadcopters;

	APIFormation formation;
    };
}
<|endoftext|>


<commit_before>#include "ImageThresholder.h"
#include <chrono>
#include <thread>

#define EDSIZE 24
#define ERODESIZE 10

//#define IMAGETHRESHOLDER_PARALLEL_FOR
//#define IMAGETHRESHOLDER_PARALLEL_THREADS
#define IMAGETHRESHOLDER_PARALLEL_INRANGE

#ifdef IMAGETHRESHOLDER_PARALLEL_FOR
#include <ppl.h>
#endif

ImageThresholder::ImageThresholder(ThresholdedImages &images, HSVColorRangeMap &objectMap) : ThreadedClass("ImageThresholder"), thresholdedImages(images), objectMap(objectMap)
{
	stop_thread = false;
	running = false;
	m_iWorkersInProgress = 0;

#if defined(IMAGETHRESHOLDER_PARALLEL_THREADS)
	for (auto objectRange : objectMap) {
		auto object = objectRange.first;
		//threads.create_thread(boost::bind(&ImageThresholder::Run2, this, objectRange.first));
		threads.add_thread(new boost::thread(&ImageThresholder::Run2, this, objectRange.first));

	}
#endif

	elemDilate = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(EDSIZE, EDSIZE)); //millega hiljem erode ja dilatet teha
	elemErode = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(EDSIZE + 6, EDSIZE + 6));
	elemErode2 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(ERODESIZE, ERODESIZE));

};

ImageThresholder::~ImageThresholder(){
	WaitForStop();
};

void ImageThresholder::Start(cv::Mat &frameHSV, std::vector<OBJECT> objectList) {
#if defined(IMAGETHRESHOLDER_PARALLEL_FOR)
		concurrency::parallel_for_each(begin(objectList), end(objectList), [&frameHSV, this](OBJECT object) {
			auto r = objectMap[object];
			inRange(frameHSV, cv::Scalar(r.hue.low, r.sat.low, r.val.low), cv::Scalar(r.hue.high, r.sat.high, r.val.high), thresholdedImages[object]);
		});
#elif defined(IMAGETHRESHOLDER_PARALLEL_THREADS)
	if (m_iWorkersInProgress > 0) {
		std::cout << "Still working" << std::endl;
	}
	frame = frameHSV;
	int mask = 0;
	for (auto &object : objectList) {
		//std::cout << "mask " << (1 << object) << " " <<( mask | (1 << object)) << std::endl;
		mask = mask | (1 << object);
	}
	m_iWorkersInProgress = mask;

	while (m_iWorkersInProgress > 0) {
		std::this_thread::sleep_for(std::chrono::milliseconds(1)); // limit fps to about 50fps
	}
	/*
		for (auto &object : objectList) {
			threads.create_thread([&frameHSV, object, this]{
				auto r = objectMap[object];
				do {
					inRange(frameHSV, cv::Scalar(r.hue.low, r.sat.low, r.val.low), cv::Scalar(r.hue.high, r.sat.high, r.val.high), thresholdedImages[object]);
				} while (thresholdedImages[object].size().height == 0);
			});
		}
	*/
#elif defined(IMAGETHRESHOLDER_PARALLEL_INRANGE)
	for (auto &object : objectList) {
		auto r = objectMap[object];
		thresholdedImages[object] = cv::Mat(frameHSV.rows, frameHSV.cols, CV_8U, cv::Scalar::all(0));
		int lhue = r.hue.low;
		int hhue = r.hue.high;
		int lsat = r.sat.low;
		int hsat = r.sat.high;
		int lval = r.val.low;
		int hval = r.val.high;
		for (int row = 0; row < frameHSV.rows; ++row) {
			uchar * p_src = frameHSV.ptr(row);
			uchar * p_dst = thresholdedImages[object].ptr(row);
			for (int col = 0; col < frameHSV.cols; ++col) {
				int srcH = *p_src++;
				int srcS = *p_src++;
				int srcV = *p_src++;

				if (srcH >= lhue && srcH <= hhue &&
					srcS >= lsat && srcS <= hsat &&
					srcV >= lval && srcV <= hval) {
					*p_dst = 255;
				}
				*p_dst++;
			}
		}
		/*
		for (int i = 0; i < frameHSV.rows; i++) {
			for (int j = 0; j < frameHSV.cols; j++) {
				cv::Vec3b p = frameHSV.at<cv::Vec3b>(i, j);
				if (p[0] >= lhue && p[0] <= hhue &&
					p[1] >= lsat && p[1] <= hsat &&
					p[2] >= lval && p[2] <= hval) {
					thresholdedImages[object].at<unsigned char>(i, j) = 255;
				}
			}
		}
		*/
}
#else
		for (auto &object : objectList) {
			auto r = objectMap[object];
			inRange(frameHSV, cv::Scalar(r.hue.low, r.sat.low, r.val.low), cv::Scalar(r.hue.high, r.sat.high, r.val.high), thresholdedImages[object]);
		}
#endif
		/*
		if (object == BLUE_GATE || object == YELLOW_GATE) {
		cv::erode(thresholdedImages[object],thresholdedImages[object],elemErode2);
		}
		cv::dilate(thresholdedImages[object],thresholdedImages[object],elemErode2);

		*/
	}

void  ImageThresholder::Run2(OBJECT object){
	while (!stop_thread) {
		if (m_iWorkersInProgress & (1 << object)) {
			auto r = objectMap[object];
			inRange(frame, cv::Scalar(r.hue.low, r.sat.low, r.val.low), cv::Scalar(r.hue.high, r.sat.high, r.val.high), thresholdedImages[object]);
			m_iWorkersInProgress &= ~(1 << object);
		}
		else {
			std::this_thread::sleep_for(std::chrono::milliseconds(1));
		}
	}
};

<commit_msg>try nr2<commit_after>#include "ImageThresholder.h"
#include <chrono>
#include <thread>

#define EDSIZE 24
#define ERODESIZE 10

//#define IMAGETHRESHOLDER_PARALLEL_FOR
//#define IMAGETHRESHOLDER_PARALLEL_THREADS
#define IMAGETHRESHOLDER_PARALLEL_INRANGE

#ifdef IMAGETHRESHOLDER_PARALLEL_FOR
#include <ppl.h>
#endif

ImageThresholder::ImageThresholder(ThresholdedImages &images, HSVColorRangeMap &objectMap) : ThreadedClass("ImageThresholder"), thresholdedImages(images), objectMap(objectMap)
{
	stop_thread = false;
	running = false;
	m_iWorkersInProgress = 0;

#if defined(IMAGETHRESHOLDER_PARALLEL_THREADS)
	for (auto objectRange : objectMap) {
		auto object = objectRange.first;
		//threads.create_thread(boost::bind(&ImageThresholder::Run2, this, objectRange.first));
		threads.add_thread(new boost::thread(&ImageThresholder::Run2, this, objectRange.first));

	}
#endif

	elemDilate = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(EDSIZE, EDSIZE)); //millega hiljem erode ja dilatet teha
	elemErode = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(EDSIZE + 6, EDSIZE + 6));
	elemErode2 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(ERODESIZE, ERODESIZE));

};

ImageThresholder::~ImageThresholder(){
	WaitForStop();
};

void ImageThresholder::Start(cv::Mat &frameHSV, std::vector<OBJECT> objectList) {
#if defined(IMAGETHRESHOLDER_PARALLEL_FOR)
		concurrency::parallel_for_each(begin(objectList), end(objectList), [&frameHSV, this](OBJECT object) {
			auto r = objectMap[object];
			inRange(frameHSV, cv::Scalar(r.hue.low, r.sat.low, r.val.low), cv::Scalar(r.hue.high, r.sat.high, r.val.high), thresholdedImages[object]);
		});
#elif defined(IMAGETHRESHOLDER_PARALLEL_THREADS)
	if (m_iWorkersInProgress > 0) {
		std::cout << "Still working" << std::endl;
	}
	frame = frameHSV;
	int mask = 0;
	for (auto &object : objectList) {
		//std::cout << "mask " << (1 << object) << " " <<( mask | (1 << object)) << std::endl;
		mask = mask | (1 << object);
	}
	m_iWorkersInProgress = mask;

	while (m_iWorkersInProgress > 0) {
		std::this_thread::sleep_for(std::chrono::milliseconds(1)); // limit fps to about 50fps
	}
	/*
		for (auto &object : objectList) {
			threads.create_thread([&frameHSV, object, this]{
				auto r = objectMap[object];
				do {
					inRange(frameHSV, cv::Scalar(r.hue.low, r.sat.low, r.val.low), cv::Scalar(r.hue.high, r.sat.high, r.val.high), thresholdedImages[object]);
				} while (thresholdedImages[object].size().height == 0);
			});
		}
	*/
#elif defined(IMAGETHRESHOLDER_PARALLEL_INRANGE)
	for (auto &object : objectList) {
		thresholdedImages[object] = cv::Mat(frameHSV.rows, frameHSV.cols, CV_8U, cv::Scalar::all(0));
	}
	std::map<OBJECT, uchar*> pMap;
	for (int row = 0; row < frameHSV.rows; ++row) {
		uchar * p_src = frameHSV.ptr(row);
		for (auto &object : objectList) {
			pMap[object] = thresholdedImages[object].ptr(row);
		}
		for (int col = 0; col < frameHSV.cols; ++col) {
			int srcH = *p_src++;
			int srcS = *p_src++;
			int srcV = *p_src++;
			for (auto &object : objectList) {
				auto r = objectMap[object];
				int lhue = r.hue.low;
				int hhue = r.hue.high;
				int lsat = r.sat.low;
				int hsat = r.sat.high;
				int lval = r.val.low;
				int hval = r.val.high;
				if (srcH >= lhue && srcH <= hhue &&
					srcS >= lsat && srcS <= hsat &&
					srcV >= lval && srcV <= hval) {
					*(pMap[object]) = 255;
				}
				(*pMap[object])++;
			}
		}
		/*
		for (int i = 0; i < frameHSV.rows; i++) {
			for (int j = 0; j < frameHSV.cols; j++) {
				cv::Vec3b p = frameHSV.at<cv::Vec3b>(i, j);
				if (p[0] >= lhue && p[0] <= hhue &&
					p[1] >= lsat && p[1] <= hsat &&
					p[2] >= lval && p[2] <= hval) {
					thresholdedImages[object].at<unsigned char>(i, j) = 255;
				}
			}
		}
		*/
}
#else
		for (auto &object : objectList) {
			auto r = objectMap[object];
			inRange(frameHSV, cv::Scalar(r.hue.low, r.sat.low, r.val.low), cv::Scalar(r.hue.high, r.sat.high, r.val.high), thresholdedImages[object]);
		}
#endif
		/*
		if (object == BLUE_GATE || object == YELLOW_GATE) {
		cv::erode(thresholdedImages[object],thresholdedImages[object],elemErode2);
		}
		cv::dilate(thresholdedImages[object],thresholdedImages[object],elemErode2);

		*/
	}

void  ImageThresholder::Run2(OBJECT object){
	while (!stop_thread) {
		if (m_iWorkersInProgress & (1 << object)) {
			auto r = objectMap[object];
			inRange(frame, cv::Scalar(r.hue.low, r.sat.low, r.val.low), cv::Scalar(r.hue.high, r.sat.high, r.val.high), thresholdedImages[object]);
			m_iWorkersInProgress &= ~(1 << object);
		}
		else {
			std::this_thread::sleep_for(std::chrono::milliseconds(1));
		}
	}
};

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MutexContainer.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 18:19:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef CHART_MUTEXCONTAINER_HXX
#define CHART_MUTEXCONTAINER_HXX

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

namespace chart
{

class MutexContainer
{
public:
    virtual ~MutexContainer();

protected:
    mutable ::osl::Mutex m_aMutex;

    virtual ::osl::Mutex & GetMutex() const;
};

} //  namespace chart

// CHART_MUTEXCONTAINER_HXX
#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.3.126); FILE MERGED 2008/04/01 15:04:13 thb 1.3.126.2: #i85898# Stripping all external header guards 2008/03/28 16:43:55 rt 1.3.126.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: MutexContainer.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef CHART_MUTEXCONTAINER_HXX
#define CHART_MUTEXCONTAINER_HXX

#include <osl/mutex.hxx>

namespace chart
{

class MutexContainer
{
public:
    virtual ~MutexContainer();

protected:
    mutable ::osl::Mutex m_aMutex;

    virtual ::osl::Mutex & GetMutex() const;
};

} //  namespace chart

// CHART_MUTEXCONTAINER_HXX
#endif
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"

class PreferenceServiceTest : public UITest {
public:
  void SetUp() {
    PathService::Get(base::DIR_TEMP, &tmp_profile_);
    tmp_profile_ = tmp_profile_.AppendASCII("tmp_profile");

    // Create a fresh, empty copy of this directory.
    file_util::Delete(tmp_profile_, true);
    file_util::CreateDirectory(tmp_profile_);

    FilePath reference_pref_file =
        test_data_directory_
            .AppendASCII("profiles")
            .AppendASCII("window_placement")
            .Append(chrome::kLocalStateFilename);

    tmp_pref_file_ = tmp_profile_.Append(chrome::kLocalStateFilename);

    ASSERT_TRUE(file_util::PathExists(reference_pref_file));

    // Copy only the Local State file, the rest will be automatically created
    ASSERT_TRUE(file_util::CopyFile(reference_pref_file, tmp_pref_file_));

#if defined(OS_WIN)
    // Make the copy writable.  On POSIX we assume the umask allows files
    // we create to be writable.
    ASSERT_TRUE(::SetFileAttributesW(tmp_pref_file_.value().c_str(),
        FILE_ATTRIBUTE_NORMAL));
#endif

    launch_arguments_.AppendSwitchWithValue(switches::kUserDataDir,
                                            tmp_profile_.ToWStringHack());
  }

  bool LaunchAppWithProfile() {
    if (!file_util::PathExists(tmp_pref_file_))
      return false;
    UITest::SetUp();
    return true;
  }

  void TearDown() {
    UITest::TearDown();

    EXPECT_TRUE(DieFileDie(tmp_profile_, true));
  }

public:
  FilePath tmp_pref_file_;
  FilePath tmp_profile_;
};

#if defined(OS_WIN)
// This test verifies that the window position from the prefs file is restored
// when the app restores.  This doesn't really make sense on Linux, where
// the window manager might fight with you over positioning.  However, we
// might be able to make this work on buildbots.
// Also, not sure what should happen on the mac.  In any case, the code below
// (minus the Windows bits) compiles fine on my Linux box now.
// TODO(port): revisit this.
TEST_F(PreferenceServiceTest, PreservedWindowPlacementIsLoaded) {
  // The window should open with the reference profile
  ASSERT_TRUE(LaunchAppWithProfile());

  ASSERT_TRUE(file_util::PathExists(tmp_pref_file_));

  JSONFileValueSerializer deserializer(tmp_pref_file_);
  scoped_ptr<Value> root(deserializer.Deserialize(NULL));

  ASSERT_TRUE(root.get());
  ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY));

  DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get());

  // Retrieve the screen rect for the launched window
  scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  scoped_ptr<WindowProxy> window(browser->GetWindow());

  HWND hWnd;
  ASSERT_TRUE(window->GetHWND(&hWnd));

  WINDOWPLACEMENT window_placement;
  ASSERT_TRUE(GetWindowPlacement(hWnd, &window_placement));

  // Retrieve the expected rect values from "Preferences"
  int bottom = 0;
  std::wstring kBrowserWindowPlacement(prefs::kBrowserWindowPlacement);
  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + L".bottom",
      &bottom));
  EXPECT_EQ(bottom, window_placement.rcNormalPosition.bottom);

  int top = 0;
  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + L".top",
      &top));
  EXPECT_EQ(top, window_placement.rcNormalPosition.top);

  int left = 0;
  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + L".left",
      &left));
  EXPECT_EQ(left, window_placement.rcNormalPosition.left);

  int right = 0;
  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + L".right",
      &right));
  EXPECT_EQ(right, window_placement.rcNormalPosition.right);

  // Find if launched window is maximized
  bool is_window_maximized = (window_placement.showCmd == SW_MAXIMIZE);

  bool is_maximized = false;
  EXPECT_TRUE(root_dict->GetBoolean(kBrowserWindowPlacement + L".maximized",
      &is_maximized));
  EXPECT_EQ(is_maximized, is_window_maximized);
}
#endif
<commit_msg>Re-disable the PrefService PreservedWindowPlacementIsLoaded UI test until I figure out why the official builder doesn't like it.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"

class PreferenceServiceTest : public UITest {
public:
  void SetUp() {
    PathService::Get(base::DIR_TEMP, &tmp_profile_);
    tmp_profile_ = tmp_profile_.AppendASCII("tmp_profile");

    // Create a fresh, empty copy of this directory.
    file_util::Delete(tmp_profile_, true);
    file_util::CreateDirectory(tmp_profile_);

    FilePath reference_pref_file =
        test_data_directory_
            .AppendASCII("profiles")
            .AppendASCII("window_placement")
            .Append(chrome::kLocalStateFilename);

    tmp_pref_file_ = tmp_profile_.Append(chrome::kLocalStateFilename);

    ASSERT_TRUE(file_util::PathExists(reference_pref_file));

    // Copy only the Local State file, the rest will be automatically created
    ASSERT_TRUE(file_util::CopyFile(reference_pref_file, tmp_pref_file_));

#if defined(OS_WIN)
    // Make the copy writable.  On POSIX we assume the umask allows files
    // we create to be writable.
    ASSERT_TRUE(::SetFileAttributesW(tmp_pref_file_.value().c_str(),
        FILE_ATTRIBUTE_NORMAL));
#endif

    launch_arguments_.AppendSwitchWithValue(switches::kUserDataDir,
                                            tmp_profile_.ToWStringHack());
  }

  bool LaunchAppWithProfile() {
    if (!file_util::PathExists(tmp_pref_file_))
      return false;
    UITest::SetUp();
    return true;
  }

  void TearDown() {
    UITest::TearDown();

    EXPECT_TRUE(DieFileDie(tmp_profile_, true));
  }

public:
  FilePath tmp_pref_file_;
  FilePath tmp_profile_;
};

#if defined(OS_WIN)
// This test verifies that the window position from the prefs file is restored
// when the app restores.  This doesn't really make sense on Linux, where
// the window manager might fight with you over positioning.  However, we
// might be able to make this work on buildbots.
// Also, not sure what should happen on the mac.  In any case, the code below
// (minus the Windows bits) compiles fine on my Linux box now.
// TODO(port): revisit this.
TEST_F(PreferenceServiceTest, DISABLED_PreservedWindowPlacementIsLoaded) {
  // The window should open with the reference profile
  ASSERT_TRUE(LaunchAppWithProfile());

  ASSERT_TRUE(file_util::PathExists(tmp_pref_file_));

  JSONFileValueSerializer deserializer(tmp_pref_file_);
  scoped_ptr<Value> root(deserializer.Deserialize(NULL));

  ASSERT_TRUE(root.get());
  ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY));

  DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get());

  // Retrieve the screen rect for the launched window
  scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  scoped_ptr<WindowProxy> window(browser->GetWindow());

  HWND hWnd;
  ASSERT_TRUE(window->GetHWND(&hWnd));

  WINDOWPLACEMENT window_placement;
  ASSERT_TRUE(GetWindowPlacement(hWnd, &window_placement));

  // Retrieve the expected rect values from "Preferences"
  int bottom = 0;
  std::wstring kBrowserWindowPlacement(prefs::kBrowserWindowPlacement);
  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + L".bottom",
      &bottom));
  EXPECT_EQ(bottom, window_placement.rcNormalPosition.bottom);

  int top = 0;
  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + L".top",
      &top));
  EXPECT_EQ(top, window_placement.rcNormalPosition.top);

  int left = 0;
  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + L".left",
      &left));
  EXPECT_EQ(left, window_placement.rcNormalPosition.left);

  int right = 0;
  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + L".right",
      &right));
  EXPECT_EQ(right, window_placement.rcNormalPosition.right);

  // Find if launched window is maximized
  bool is_window_maximized = (window_placement.showCmd == SW_MAXIMIZE);

  bool is_maximized = false;
  EXPECT_TRUE(root_dict->GetBoolean(kBrowserWindowPlacement + L".maximized",
      &is_maximized));
  EXPECT_EQ(is_maximized, is_window_maximized);
}
#endif
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2012 Sergey Lisitsyn
 * Written (W) 2012 Heiko Strathmann
 */

#include <shogun/evaluation/CrossValidationPrintOutput.h>
#include <shogun/machine/LinearMachine.h>
#include <shogun/machine/LinearMulticlassMachine.h>
#include <shogun/machine/KernelMachine.h>
#include <shogun/machine/KernelMulticlassMachine.h>
#include <shogun/kernel/CombinedKernel.h>
#include <shogun/classifier/mkl/MKL.h>

using namespace shogun;

void CCrossValidationPrintOutput::init_num_runs(index_t num_runs,
		const char* prefix)
{
	SG_PRINT("%scross validation number of runs %d\n", prefix, num_runs);
}

/** init number of folds */
void CCrossValidationPrintOutput::init_num_folds(index_t num_folds,
		const char* prefix)
{
	SG_PRINT("%scross validation number of folds %d\n", prefix, num_folds);
}

void CCrossValidationPrintOutput::update_run_index(index_t run_index,
		const char* prefix)
{
	SG_PRINT("%scross validation run %d\n", prefix, run_index);
}

void CCrossValidationPrintOutput::update_fold_index(index_t fold_index,
		const char* prefix)
{
	SG_PRINT("%sfold %d\n", prefix, fold_index);
}

void CCrossValidationPrintOutput::update_train_indices(
		SGVector<index_t> indices, const char* prefix)
{
	indices.display_vector("train_indices", prefix);
}

void CCrossValidationPrintOutput::update_test_indices(
		SGVector<index_t> indices, const char* prefix)
{
	indices.display_vector("test_indices", prefix);
}

void CCrossValidationPrintOutput::update_trained_machine(
		CMachine* machine, const char* prefix)
{
	if (dynamic_cast<CLinearMachine*>(machine))
	{
		CLinearMachine* linear_machine=(CLinearMachine*)machine;
		linear_machine->get_w().display_vector("learned_w", prefix);
		SG_PRINT("%slearned_bias=%f\n", prefix, linear_machine->get_bias());
	}

	if (dynamic_cast<CKernelMachine*>(machine))
	{
		CKernelMachine* kernel_machine=(CKernelMachine*)machine;
		kernel_machine->get_alphas().display_vector("learned_alphas", prefix);
		SG_PRINT("%slearned_bias=%f\n", prefix, kernel_machine->get_bias());
	}

	if (dynamic_cast<CLinearMulticlassMachine*>(machine)
			|| dynamic_cast<CKernelMulticlassMachine*>(machine))
	{
		/* append one tab to prefix */
		char* new_prefix=append_tab_to_string(prefix);

		CMulticlassMachine* mc_machine=(CMulticlassMachine*)machine;
		for (int i=0; i<mc_machine->get_num_machines(); i++)
		{
			CMachine* sub_machine=mc_machine->get_machine(i);
            //SG_PRINT("%smulti-class machine %d:\n", i, sub_machine);
			this->update_trained_machine(sub_machine, new_prefix);
			SG_UNREF(sub_machine);
		}

		/* clean up */
		SG_FREE(new_prefix);
	}

	if (dynamic_cast<CMKL*>(machine))
	{
		CMKL* mkl=(CMKL*)machine;
		CCombinedKernel* kernel=dynamic_cast<CCombinedKernel*>(
				mkl->get_kernel());
		kernel->get_subkernel_weights().display_vector("MKL sub-kernel weights",
				prefix);
		SG_UNREF(kernel);
	}
}

void CCrossValidationPrintOutput::update_test_result(CLabels* results,
		const char* prefix)
{
	results->get_confidences().display_vector("test_labels", prefix);
}

void CCrossValidationPrintOutput::update_test_true_result(CLabels* results,
		const char* prefix)
{
	results->get_confidences().display_vector("true_labels", prefix);
}

void CCrossValidationPrintOutput::update_evaluation_result(float64_t result,
		const char* prefix)
{
	SG_PRINT("%sevaluation result=%f\n", prefix, result);
}

char* CCrossValidationPrintOutput::append_tab_to_string(const char* string)
{
	/* allocate memory, concatenate and add termination character */
	index_t len=strlen(string);
	char* new_prefix=SG_MALLOC(char, len+2);
	memcpy(new_prefix, string, sizeof(char*)*len);
	new_prefix[len]='\t';
	new_prefix[len+1]='\0';

	return new_prefix;
}
<commit_msg>Added MKL multiclass handling in CV print output<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2012 Sergey Lisitsyn
 * Written (W) 2012 Heiko Strathmann
 */

#include <shogun/evaluation/CrossValidationPrintOutput.h>
#include <shogun/machine/LinearMachine.h>
#include <shogun/machine/LinearMulticlassMachine.h>
#include <shogun/machine/KernelMachine.h>
#include <shogun/machine/KernelMulticlassMachine.h>
#include <shogun/kernel/CombinedKernel.h>
#include <shogun/classifier/mkl/MKL.h>
#include <shogun/classifier/mkl/MKLMulticlass.h>

using namespace shogun;

void CCrossValidationPrintOutput::init_num_runs(index_t num_runs,
		const char* prefix)
{
	SG_PRINT("%scross validation number of runs %d\n", prefix, num_runs);
}

/** init number of folds */
void CCrossValidationPrintOutput::init_num_folds(index_t num_folds,
		const char* prefix)
{
	SG_PRINT("%scross validation number of folds %d\n", prefix, num_folds);
}

void CCrossValidationPrintOutput::update_run_index(index_t run_index,
		const char* prefix)
{
	SG_PRINT("%scross validation run %d\n", prefix, run_index);
}

void CCrossValidationPrintOutput::update_fold_index(index_t fold_index,
		const char* prefix)
{
	SG_PRINT("%sfold %d\n", prefix, fold_index);
}

void CCrossValidationPrintOutput::update_train_indices(
		SGVector<index_t> indices, const char* prefix)
{
	indices.display_vector("train_indices", prefix);
}

void CCrossValidationPrintOutput::update_test_indices(
		SGVector<index_t> indices, const char* prefix)
{
	indices.display_vector("test_indices", prefix);
}

void CCrossValidationPrintOutput::update_trained_machine(
		CMachine* machine, const char* prefix)
{
	if (dynamic_cast<CLinearMachine*>(machine))
	{
		CLinearMachine* linear_machine=(CLinearMachine*)machine;
		linear_machine->get_w().display_vector("learned_w", prefix);
		SG_PRINT("%slearned_bias=%f\n", prefix, linear_machine->get_bias());
	}

	if (dynamic_cast<CKernelMachine*>(machine))
	{
		CKernelMachine* kernel_machine=(CKernelMachine*)machine;
		kernel_machine->get_alphas().display_vector("learned_alphas", prefix);
		SG_PRINT("%slearned_bias=%f\n", prefix, kernel_machine->get_bias());
	}

	if (dynamic_cast<CLinearMulticlassMachine*>(machine)
			|| dynamic_cast<CKernelMulticlassMachine*>(machine))
	{
		/* append one tab to prefix */
		char* new_prefix=append_tab_to_string(prefix);

		CMulticlassMachine* mc_machine=(CMulticlassMachine*)machine;
		for (int i=0; i<mc_machine->get_num_machines(); i++)
		{
			CMachine* sub_machine=mc_machine->get_machine(i);
            //SG_PRINT("%smulti-class machine %d:\n", i, sub_machine);
			this->update_trained_machine(sub_machine, new_prefix);
			SG_UNREF(sub_machine);
		}

		/* clean up */
		SG_FREE(new_prefix);
	}

	if (dynamic_cast<CMKL*>(machine))
	{
		CMKL* mkl=(CMKL*)machine;
		CCombinedKernel* kernel=dynamic_cast<CCombinedKernel*>(
				mkl->get_kernel());
		kernel->get_subkernel_weights().display_vector("MKL sub-kernel weights",
				prefix);
		SG_UNREF(kernel);
	}

	if (dynamic_cast<CMKLMulticlass*>(machine))
	{
		CMKLMulticlass* mkl=(CMKLMulticlass*)machine;
		CCombinedKernel* kernel=dynamic_cast<CCombinedKernel*>(
				mkl->get_kernel());
		kernel->get_subkernel_weights().display_vector("MKL sub-kernel weights",
				prefix);
		SG_UNREF(kernel);
	}
}

void CCrossValidationPrintOutput::update_test_result(CLabels* results,
		const char* prefix)
{
	results->get_confidences().display_vector("test_labels", prefix);
}

void CCrossValidationPrintOutput::update_test_true_result(CLabels* results,
		const char* prefix)
{
	results->get_confidences().display_vector("true_labels", prefix);
}

void CCrossValidationPrintOutput::update_evaluation_result(float64_t result,
		const char* prefix)
{
	SG_PRINT("%sevaluation result=%f\n", prefix, result);
}

char* CCrossValidationPrintOutput::append_tab_to_string(const char* string)
{
	/* allocate memory, concatenate and add termination character */
	index_t len=strlen(string);
	char* new_prefix=SG_MALLOC(char, len+2);
	memcpy(new_prefix, string, sizeof(char*)*len);
	new_prefix[len]='\t';
	new_prefix[len+1]='\0';

	return new_prefix;
}
<|endoftext|>