<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016-2018 Morwenn
 *
 * 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 OR COPYRIGHT HOLDERS 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 <algorithm>
#include <functional>
#include <iterator>
#include <numeric>
#include <random>
#include <type_traits>
#include <utility>
#include <vector>
#include <catch2/catch.hpp>
#include <cpp-sort/sort.h>
#include <cpp-sort/sorter_facade.h>
#include <cpp-sort/sorter_traits.h>
#include <cpp-sort/utility/functional.h>

namespace
{
    struct tricky_function
    {
        template<typename T, typename U>
        auto operator()(T&& lhs, U&& rhs)
            noexcept(noexcept(std::forward<T>(lhs) > std::forward<U>(rhs)))
            -> decltype(std::forward<T>(lhs) > std::forward<U>(rhs))
        {
            // Compare values in reverse order
            return std::forward<T>(lhs) > std::forward<U>(rhs);
        }

        template<typename T>
        auto operator()(T&& value) const noexcept
            -> decltype(std::forward<T>(value))
        {
            return std::forward<T>(value);
        }
    };

    enum struct call
    {
        iterator,
        iterable
    };

    struct comparison_sorter_impl
    {
        template<
            typename Iterator,
            typename Compare = std::less<>,
            typename = std::enable_if_t<cppsort::is_projection_iterator_v<
                cppsort::utility::identity, Iterator, Compare
            >>
        >
        auto operator()(Iterator first, Iterator last, Compare compare={}) const
            -> call
        {
            cppsort::sort(first, last, compare);
            return call::iterator;
        }

        template<
            typename Iterable,
            typename Compare = std::less<>,
            typename = std::enable_if_t<cppsort::is_projection_v<
                cppsort::utility::identity, Iterable, Compare
            >>
        >
        auto operator()(Iterable& iterable, Compare compare={}) const
            -> call
        {
            cppsort::sort(iterable, compare);
            return call::iterable;
        }
    };

    struct projection_sorter_impl
    {
        template<
            typename Iterator,
            typename Projection=cppsort::utility::identity,
            typename = std::enable_if_t<cppsort::is_projection_iterator_v<
                Projection, Iterator
            >>
        >
        auto operator()(Iterator first, Iterator last, Projection projection={}) const
            -> call
        {
            // Use as_projection to make an actual projection-only sorter
            cppsort::sort(first, last, cppsort::utility::as_projection(projection));
            return call::iterator;
        }

        template<
            typename Iterable,
            typename Projection=cppsort::utility::identity,
            typename = std::enable_if_t<cppsort::is_projection_v<
                Projection, Iterable
            >>
        >
        auto operator()(Iterable& iterable, Projection projection={}) const
            -> call
        {
            // Use as_projection to make an actual projection-only sorter
            cppsort::sort(iterable, cppsort::utility::as_projection(projection));
            return call::iterable;
        }
    };

    struct comparison_sorter:
        cppsort::sorter_facade<comparison_sorter_impl>
    {};

    struct projection_sorter:
        cppsort::sorter_facade<projection_sorter_impl>
    {};
}

TEST_CASE( "sorter_facade with sorters overloaded for iterables and mixed comparison/projection",
           "[sorter_facade][compare][projection][as_projection]" )
{
    // Test the intersection between mixed comparison/projection functions,
    // as_projection, as_comparison and some additional sorter_facade
    // overloads

    struct wrapper { int value; };

    // Collection to sort
    std::vector<int> collection(100);
    std::iota(std::begin(collection), std::end(collection), 0);
    std::mt19937 engine(Catch::rngSeed());
    std::shuffle(std::begin(collection), std::end(collection), engine);
    auto vec = collection;

    tricky_function func;
    comparison_sorter comp_sort;
    projection_sorter proj_sort;

    SECTION( "comparison_sorter" )
    {
        vec = collection;
        auto res1 = cppsort::sort(comp_sort, vec, func);
        CHECK( res1 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res2 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec), func);
        CHECK( res2 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res3 = cppsort::sort(comp_sort, vec, cppsort::utility::as_comparison(func));
        CHECK( res3 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res4 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec),
                                  cppsort::utility::as_comparison(func));
        CHECK( res4 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res5 = cppsort::sort(comp_sort, vec, cppsort::utility::as_projection(func));
        CHECK( res5 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res6 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec),
                                  cppsort::utility::as_projection(func));
        CHECK( res6 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res7 = cppsort::sort(comp_sort, vec, func,
                                  cppsort::utility::as_projection(func));
        CHECK( res7 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res8 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec), func,
                                  cppsort::utility::as_projection(func));
        CHECK( res8 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res9 = cppsort::sort(comp_sort, vec, cppsort::utility::as_comparison(func),
                                                  cppsort::utility::as_projection(func));
        CHECK( res9 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res10 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec),
                                   cppsort::utility::as_comparison(func),
                                   cppsort::utility::as_projection(func));
        CHECK( res10 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );
    }

    SECTION( "projection_sorter" )
    {
        vec = collection;
        auto res1 = cppsort::sort(proj_sort, vec, cppsort::utility::as_projection(func));
        CHECK( res1 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res2 = cppsort::sort(proj_sort, std::begin(vec), std::end(vec),
                                  cppsort::utility::as_projection(func));
        CHECK( res2 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res3 = cppsort::sort(proj_sort, vec, func);
        CHECK( res3 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res4 = cppsort::sort(proj_sort, std::begin(vec), std::end(vec), func);
        CHECK( res4 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );
    }
}
<commit_msg>Remove redundant lines in test suite<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016-2020 Morwenn
 *
 * 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 OR COPYRIGHT HOLDERS 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 <algorithm>
#include <functional>
#include <iterator>
#include <numeric>
#include <random>
#include <type_traits>
#include <utility>
#include <vector>
#include <catch2/catch.hpp>
#include <cpp-sort/sort.h>
#include <cpp-sort/sorter_facade.h>
#include <cpp-sort/sorter_traits.h>
#include <cpp-sort/utility/functional.h>

namespace
{
    struct tricky_function
    {
        template<typename T, typename U>
        auto operator()(T&& lhs, U&& rhs)
            noexcept(noexcept(std::forward<T>(lhs) > std::forward<U>(rhs)))
            -> decltype(std::forward<T>(lhs) > std::forward<U>(rhs))
        {
            // Compare values in reverse order
            return std::forward<T>(lhs) > std::forward<U>(rhs);
        }

        template<typename T>
        auto operator()(T&& value) const noexcept
            -> decltype(std::forward<T>(value))
        {
            return std::forward<T>(value);
        }
    };

    enum struct call
    {
        iterator,
        iterable
    };

    struct comparison_sorter_impl
    {
        template<
            typename Iterator,
            typename Compare = std::less<>,
            typename = std::enable_if_t<cppsort::is_projection_iterator_v<
                cppsort::utility::identity, Iterator, Compare
            >>
        >
        auto operator()(Iterator first, Iterator last, Compare compare={}) const
            -> call
        {
            cppsort::sort(first, last, compare);
            return call::iterator;
        }

        template<
            typename Iterable,
            typename Compare = std::less<>,
            typename = std::enable_if_t<cppsort::is_projection_v<
                cppsort::utility::identity, Iterable, Compare
            >>
        >
        auto operator()(Iterable& iterable, Compare compare={}) const
            -> call
        {
            cppsort::sort(iterable, compare);
            return call::iterable;
        }
    };

    struct projection_sorter_impl
    {
        template<
            typename Iterator,
            typename Projection=cppsort::utility::identity,
            typename = std::enable_if_t<cppsort::is_projection_iterator_v<
                Projection, Iterator
            >>
        >
        auto operator()(Iterator first, Iterator last, Projection projection={}) const
            -> call
        {
            // Use as_projection to make an actual projection-only sorter
            cppsort::sort(first, last, cppsort::utility::as_projection(projection));
            return call::iterator;
        }

        template<
            typename Iterable,
            typename Projection=cppsort::utility::identity,
            typename = std::enable_if_t<cppsort::is_projection_v<
                Projection, Iterable
            >>
        >
        auto operator()(Iterable& iterable, Projection projection={}) const
            -> call
        {
            // Use as_projection to make an actual projection-only sorter
            cppsort::sort(iterable, cppsort::utility::as_projection(projection));
            return call::iterable;
        }
    };

    struct comparison_sorter:
        cppsort::sorter_facade<comparison_sorter_impl>
    {};

    struct projection_sorter:
        cppsort::sorter_facade<projection_sorter_impl>
    {};
}

TEST_CASE( "sorter_facade with sorters overloaded for iterables and mixed comparison/projection",
           "[sorter_facade][compare][projection][as_projection]" )
{
    // Test the intersection between mixed comparison/projection functions,
    // as_projection, as_comparison and some additional sorter_facade
    // overloads

    // Collection to sort
    std::vector<int> collection(100);
    std::iota(std::begin(collection), std::end(collection), 0);
    std::mt19937 engine(Catch::rngSeed());
    std::shuffle(std::begin(collection), std::end(collection), engine);
    auto vec = collection;

    tricky_function func;
    comparison_sorter comp_sort;
    projection_sorter proj_sort;

    SECTION( "comparison_sorter" )
    {
        auto res1 = cppsort::sort(comp_sort, vec, func);
        CHECK( res1 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res2 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec), func);
        CHECK( res2 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res3 = cppsort::sort(comp_sort, vec, cppsort::utility::as_comparison(func));
        CHECK( res3 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res4 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec),
                                  cppsort::utility::as_comparison(func));
        CHECK( res4 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res5 = cppsort::sort(comp_sort, vec, cppsort::utility::as_projection(func));
        CHECK( res5 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res6 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec),
                                  cppsort::utility::as_projection(func));
        CHECK( res6 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res7 = cppsort::sort(comp_sort, vec, func,
                                  cppsort::utility::as_projection(func));
        CHECK( res7 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res8 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec), func,
                                  cppsort::utility::as_projection(func));
        CHECK( res8 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res9 = cppsort::sort(comp_sort, vec, cppsort::utility::as_comparison(func),
                                                  cppsort::utility::as_projection(func));
        CHECK( res9 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );

        vec = collection;
        auto res10 = cppsort::sort(comp_sort, std::begin(vec), std::end(vec),
                                   cppsort::utility::as_comparison(func),
                                   cppsort::utility::as_projection(func));
        CHECK( res10 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec), std::greater<>{}) );
    }

    SECTION( "projection_sorter" )
    {
        auto res1 = cppsort::sort(proj_sort, vec, cppsort::utility::as_projection(func));
        CHECK( res1 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res2 = cppsort::sort(proj_sort, std::begin(vec), std::end(vec),
                                  cppsort::utility::as_projection(func));
        CHECK( res2 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res3 = cppsort::sort(proj_sort, vec, func);
        CHECK( res3 == call::iterable );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );

        vec = collection;
        auto res4 = cppsort::sort(proj_sort, std::begin(vec), std::end(vec), func);
        CHECK( res4 == call::iterator );
        CHECK( std::is_sorted(std::begin(vec), std::end(vec)) );
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: framework.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: as $ $Date: 2001-05-21 06:12:47 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_HELPER_OINSTANCEPROVIDER_HXX_
#include <helper/oinstanceprovider.hxx>
#endif

#ifndef __FRAMEWORK_CLASSES_SERVICEMANAGER_HXX_
#include <classes/servicemanager.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_DEBUG_HXX_
#include <macros/debug.hxx>
#endif

#ifndef __FRAMEWORK_DEFINES_HXX_
#include <defines.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_FRAME_XDESKTOP_HPP_
#include <com/sun/star/frame/XDesktop.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAMELOADER_HPP_
#include <com/sun/star/frame/XFrameLoader.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XLOADEVENTLISTENER_HPP_
#include <com/sun/star/frame/XLoadEventListener.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
#include <com/sun/star/frame/XDispatchProvider.hpp>
#endif

#ifndef _COM_SUN_STAR_UTIL_URL_HPP_
#include <com/sun/star/util/URL.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAMES_HPP_
#include <com/sun/star/frame/XFrames.hpp>
#endif

#ifndef _COM_SUN_STAR_CONNECTION_XConnection_HPP_
#include <com/sun/star/connection/XConnection.hpp>
#endif

#ifndef _COM_SUN_STAR_BRIDGE_XBridgeFactory_HPP_
#include <com/sun/star/bridge/XBridgeFactory.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif

#ifndef _SVT_UNOIFACE_HXX
#include <svtools/unoiface.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
#endif

#ifndef _VOS_PROCESS_HXX_
#include <vos/process.hxx>
#endif

//_________________________________________________________________________________________________________________
//  namespace
//_________________________________________________________________________________________________________________

using namespace ::rtl                           ;
using namespace ::vos                           ;
using namespace ::comphelper                    ;
using namespace ::framework                     ;
using namespace ::com::sun::star::uno           ;
using namespace ::com::sun::star::lang          ;
using namespace ::com::sun::star::frame         ;
using namespace ::com::sun::star::awt           ;
using namespace ::com::sun::star::beans         ;
using namespace ::com::sun::star::util          ;
using namespace ::com::sun::star::connection    ;
using namespace ::com::sun::star::bridge        ;

//_________________________________________________________________________________________________________________
//  const
//_________________________________________________________________________________________________________________

#define APPLICATIONNAME                         "FrameWork"
#define COMMANDARGUMENT_PLUGIN                  DECLARE_ASCII("-plugin"                 )
#define NAME_PLUGINBRIDGE                       DECLARE_ASCII("mozilla plugin bridge"   )
#define PROTOCOL_PLUGINBRIDGE                   DECLARE_ASCII("urp"                     )

//_________________________________________________________________________________________________________________
//  declarations
//_________________________________________________________________________________________________________________

/*-************************************************************************************************************//**
    @short      normal application
    @descr      An instance of these class can be a normal node in frame tree only. The highest level to be allowed is 3!
                On 1 stand the desktop himself as the only one, on 2 are all tasks present ... and then comes frames only.
                A frame support influencing of his subtree, find of subframes, activate- and deactivate-mechanism as well as
                set/get of a frame window, component or controller.

    @implements XInterface
                XTypeProvider
                XServiceInfo
                XFramesSupplier
                XFrame
                XComponent
                XStatusIndicatorSupplier
                XDispatchProvider
                XDispatchProviderInterception
                XBrowseHistoryRegistry
                XLoadEventListener
                XEventListener
                XWindowListener
                XTopWindowListener
                [ XDebugging, if TEST_TREE is defined! ]
    @base       OMutexMember
                OWeakObject

    @devstatus  deprecated
*//*-*************************************************************************************************************/
class FrameWork : public Application
{
    //-------------------------------------------------------------------------------------------------------------
    //  public methods
    //-------------------------------------------------------------------------------------------------------------

    public:
        void Main();

    private:
        void impl_analyzeCommandArguments();

    private:
        sal_Bool    m_bUsePlugIn    ;

};  //  class FrameWork

//_________________________________________________________________________________________________________________
//  definitions
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//  global variables
//_________________________________________________________________________________________________________________

FrameWork   aFrameWork  ;

//_________________________________________________________________________________________________________________
//  definitions
//_________________________________________________________________________________________________________________

//*****************************************************************************************************************
//  private methods
//*****************************************************************************************************************
void FrameWork::impl_analyzeCommandArguments()
{
    // First reset all member variables which present states of incoming arguments!
    m_bUsePlugIn = sal_False;   // depends from "/plugin"

    // Then step over all given arguments and search for supported one.
    OStartupInfo    aInfo       ;
    OUString        sArgument   ;
    sal_uInt32      nCount      = aInfo.getCommandArgCount();
    for ( sal_uInt32 nArgument=0; nArgument<nCount; ++nArgument )
    {
        // If extraction of current argument successfull ...
        if ( aInfo.getCommandArg( nArgument, sArgument ) == osl_Process_E_None )
        {
            // ... search for matching with supported values.
            if ( sArgument == COMMANDARGUMENT_PLUGIN )
            {
                // We found "/plugin" => set internal equivalent.
                m_bUsePlugIn = sal_True;
            }
        }
    }
}

//_________________________________________________________________________________________________________________
//  main
//_________________________________________________________________________________________________________________

void FrameWork::Main()
{
    //-------------------------------------------------------------------------------------------------------------
    // a) Initialize ouer application

    // Analyze command arguments.
    impl_analyzeCommandArguments();

    // Create new global servicemanager.
    ServiceManager aManager;
    Reference< XMultiServiceFactory > xGlobalServiceManager = aManager.getGlobalUNOServiceManager();

    if ( xGlobalServiceManager.is() == sal_True )
    {
        // If it was successful - set in as static value in UNOTOOLS!
        setProcessServiceFactory( xGlobalServiceManager );

        //---------------------------------------------------------------------------------------------------------
        // b) Create root of ouer frame tree

        // Create top of frame hierarchy - the desktop.
        Reference< XDesktop > xDesktop( xGlobalServiceManager->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
        // Safe impossible cases
        // We need the desktop for working.
        LOG_ASSERT( !(xDesktop.is()==sal_False), "FrameWork::Main()\nCan't instanciate desktop!Servicename unknown?\n" )

        //---------------------------------------------------------------------------------------------------------
        // c) Initialize connection to possible PlugIn dll.

// OPipeConnection removed, connection to plugin now uses acceptor service
#if 0
        if ( m_bUsePlugIn == sal_True )
        {
            Reference< XConnection >    xConnection         = new OPipeConnection( xGlobalServiceManager );
            Reference< XBridgeFactory > xBridgeFactory      ( xGlobalServiceManager->createInstance( SERVICENAME_BRIDGEFACTORY  ), UNO_QUERY );
            if  (
                    ( xConnection.is()          == sal_True )   &&
                    ( xBridgeFactory.is()       == sal_True )
                )
            {
                Reference< XBridge > xBridge = xBridgeFactory->createBridge(    NAME_PLUGINBRIDGE                               ,
                                                                                PROTOCOL_PLUGINBRIDGE                           ,
                                                                                xConnection                                     ,
                                                                                new OInstanceProvider( xGlobalServiceManager )  );
            }
            else
            {
                // Error handling ... !?
                LOG_ASSERT( sal_False, "FrameWork::Main()\nNo connection to plugin. Initialization of bridge failed.\n" )
            }
        }
#endif
        //---------------------------------------------------------------------------------------------------------
        // d) Initialize new task with a HTML-URL in it.

        // Cast desktop to right interface to do this.
        Reference< XDispatchProvider > xDispatchProvider( xDesktop, UNO_QUERY );
        // Safe impossible cases.
        // Desktop MUST support these interface!
        LOG_ASSERT( !(xDispatchProvider.is()==sal_False), "FrameWork::Main()\nDesktop don't support XDispatchProvider interface.\n" )
        if ( xDispatchProvider.is() == sal_True )
        {
            // Build URL ...
            OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "file://e|/dokumentation/Documentation/projekte/services/inimanager/inimanager/index.html" ));
            URL aURL;
            aURL.Complete = sURL;
            // ... and dispatch it.
            Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aURL, FRAMETYPE_BLANK, 0 );
            xDispatch->dispatch( aURL, Sequence< PropertyValue >() );

            // Use special feature of desktop service and log current tree state in file.
//          LOG_TREE( xDesktop )

            // Build URL ...
            sURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "file://d|/menu.htm" ));
            aURL.Complete = sURL;
            // ... and dispatch it.
            xDispatch = xDispatchProvider->queryDispatch( aURL, FRAMETYPE_BLANK, 0 );
            xDispatch->dispatch( aURL, Sequence< PropertyValue >() );

            // Use special feature of desktop service and log current tree state in file.
//          LOG_TREE( xDesktop )
        }

        // Set running-mode for application.
        Execute();
    }
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.8.584); FILE MERGED 2005/09/05 13:05:58 rt 1.8.584.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: framework.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 01:05:34 $
 *
 *  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
 *
 ************************************************************************/

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_HELPER_OINSTANCEPROVIDER_HXX_
#include <helper/oinstanceprovider.hxx>
#endif

#ifndef __FRAMEWORK_CLASSES_SERVICEMANAGER_HXX_
#include <classes/servicemanager.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_DEBUG_HXX_
#include <macros/debug.hxx>
#endif

#ifndef __FRAMEWORK_DEFINES_HXX_
#include <defines.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_FRAME_XDESKTOP_HPP_
#include <com/sun/star/frame/XDesktop.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAMELOADER_HPP_
#include <com/sun/star/frame/XFrameLoader.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XLOADEVENTLISTENER_HPP_
#include <com/sun/star/frame/XLoadEventListener.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
#include <com/sun/star/frame/XDispatchProvider.hpp>
#endif

#ifndef _COM_SUN_STAR_UTIL_URL_HPP_
#include <com/sun/star/util/URL.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAMES_HPP_
#include <com/sun/star/frame/XFrames.hpp>
#endif

#ifndef _COM_SUN_STAR_CONNECTION_XConnection_HPP_
#include <com/sun/star/connection/XConnection.hpp>
#endif

#ifndef _COM_SUN_STAR_BRIDGE_XBridgeFactory_HPP_
#include <com/sun/star/bridge/XBridgeFactory.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif

#ifndef _SVT_UNOIFACE_HXX
#include <svtools/unoiface.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
#endif

#ifndef _VOS_PROCESS_HXX_
#include <vos/process.hxx>
#endif

//_________________________________________________________________________________________________________________
//  namespace
//_________________________________________________________________________________________________________________

using namespace ::rtl                           ;
using namespace ::vos                           ;
using namespace ::comphelper                    ;
using namespace ::framework                     ;
using namespace ::com::sun::star::uno           ;
using namespace ::com::sun::star::lang          ;
using namespace ::com::sun::star::frame         ;
using namespace ::com::sun::star::awt           ;
using namespace ::com::sun::star::beans         ;
using namespace ::com::sun::star::util          ;
using namespace ::com::sun::star::connection    ;
using namespace ::com::sun::star::bridge        ;

//_________________________________________________________________________________________________________________
//  const
//_________________________________________________________________________________________________________________

#define APPLICATIONNAME                         "FrameWork"
#define COMMANDARGUMENT_PLUGIN                  DECLARE_ASCII("-plugin"                 )
#define NAME_PLUGINBRIDGE                       DECLARE_ASCII("mozilla plugin bridge"   )
#define PROTOCOL_PLUGINBRIDGE                   DECLARE_ASCII("urp"                     )

//_________________________________________________________________________________________________________________
//  declarations
//_________________________________________________________________________________________________________________

/*-************************************************************************************************************//**
    @short      normal application
    @descr      An instance of these class can be a normal node in frame tree only. The highest level to be allowed is 3!
                On 1 stand the desktop himself as the only one, on 2 are all tasks present ... and then comes frames only.
                A frame support influencing of his subtree, find of subframes, activate- and deactivate-mechanism as well as
                set/get of a frame window, component or controller.

    @implements XInterface
                XTypeProvider
                XServiceInfo
                XFramesSupplier
                XFrame
                XComponent
                XStatusIndicatorSupplier
                XDispatchProvider
                XDispatchProviderInterception
                XBrowseHistoryRegistry
                XLoadEventListener
                XEventListener
                XWindowListener
                XTopWindowListener
                [ XDebugging, if TEST_TREE is defined! ]
    @base       OMutexMember
                OWeakObject

    @devstatus  deprecated
*//*-*************************************************************************************************************/
class FrameWork : public Application
{
    //-------------------------------------------------------------------------------------------------------------
    //  public methods
    //-------------------------------------------------------------------------------------------------------------

    public:
        void Main();

    private:
        void impl_analyzeCommandArguments();

    private:
        sal_Bool    m_bUsePlugIn    ;

};  //  class FrameWork

//_________________________________________________________________________________________________________________
//  definitions
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//  global variables
//_________________________________________________________________________________________________________________

FrameWork   aFrameWork  ;

//_________________________________________________________________________________________________________________
//  definitions
//_________________________________________________________________________________________________________________

//*****************************************************************************************************************
//  private methods
//*****************************************************************************************************************
void FrameWork::impl_analyzeCommandArguments()
{
    // First reset all member variables which present states of incoming arguments!
    m_bUsePlugIn = sal_False;   // depends from "/plugin"

    // Then step over all given arguments and search for supported one.
    OStartupInfo    aInfo       ;
    OUString        sArgument   ;
    sal_uInt32      nCount      = aInfo.getCommandArgCount();
    for ( sal_uInt32 nArgument=0; nArgument<nCount; ++nArgument )
    {
        // If extraction of current argument successfull ...
        if ( aInfo.getCommandArg( nArgument, sArgument ) == osl_Process_E_None )
        {
            // ... search for matching with supported values.
            if ( sArgument == COMMANDARGUMENT_PLUGIN )
            {
                // We found "/plugin" => set internal equivalent.
                m_bUsePlugIn = sal_True;
            }
        }
    }
}

//_________________________________________________________________________________________________________________
//  main
//_________________________________________________________________________________________________________________

void FrameWork::Main()
{
    //-------------------------------------------------------------------------------------------------------------
    // a) Initialize ouer application

    // Analyze command arguments.
    impl_analyzeCommandArguments();

    // Create new global servicemanager.
    ServiceManager aManager;
    Reference< XMultiServiceFactory > xGlobalServiceManager = aManager.getGlobalUNOServiceManager();

    if ( xGlobalServiceManager.is() == sal_True )
    {
        // If it was successful - set in as static value in UNOTOOLS!
        setProcessServiceFactory( xGlobalServiceManager );

        //---------------------------------------------------------------------------------------------------------
        // b) Create root of ouer frame tree

        // Create top of frame hierarchy - the desktop.
        Reference< XDesktop > xDesktop( xGlobalServiceManager->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
        // Safe impossible cases
        // We need the desktop for working.
        LOG_ASSERT( !(xDesktop.is()==sal_False), "FrameWork::Main()\nCan't instanciate desktop!Servicename unknown?\n" )

        //---------------------------------------------------------------------------------------------------------
        // c) Initialize connection to possible PlugIn dll.

// OPipeConnection removed, connection to plugin now uses acceptor service
#if 0
        if ( m_bUsePlugIn == sal_True )
        {
            Reference< XConnection >    xConnection         = new OPipeConnection( xGlobalServiceManager );
            Reference< XBridgeFactory > xBridgeFactory      ( xGlobalServiceManager->createInstance( SERVICENAME_BRIDGEFACTORY  ), UNO_QUERY );
            if  (
                    ( xConnection.is()          == sal_True )   &&
                    ( xBridgeFactory.is()       == sal_True )
                )
            {
                Reference< XBridge > xBridge = xBridgeFactory->createBridge(    NAME_PLUGINBRIDGE                               ,
                                                                                PROTOCOL_PLUGINBRIDGE                           ,
                                                                                xConnection                                     ,
                                                                                new OInstanceProvider( xGlobalServiceManager )  );
            }
            else
            {
                // Error handling ... !?
                LOG_ASSERT( sal_False, "FrameWork::Main()\nNo connection to plugin. Initialization of bridge failed.\n" )
            }
        }
#endif
        //---------------------------------------------------------------------------------------------------------
        // d) Initialize new task with a HTML-URL in it.

        // Cast desktop to right interface to do this.
        Reference< XDispatchProvider > xDispatchProvider( xDesktop, UNO_QUERY );
        // Safe impossible cases.
        // Desktop MUST support these interface!
        LOG_ASSERT( !(xDispatchProvider.is()==sal_False), "FrameWork::Main()\nDesktop don't support XDispatchProvider interface.\n" )
        if ( xDispatchProvider.is() == sal_True )
        {
            // Build URL ...
            OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "file://e|/dokumentation/Documentation/projekte/services/inimanager/inimanager/index.html" ));
            URL aURL;
            aURL.Complete = sURL;
            // ... and dispatch it.
            Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aURL, FRAMETYPE_BLANK, 0 );
            xDispatch->dispatch( aURL, Sequence< PropertyValue >() );

            // Use special feature of desktop service and log current tree state in file.
//          LOG_TREE( xDesktop )

            // Build URL ...
            sURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "file://d|/menu.htm" ));
            aURL.Complete = sURL;
            // ... and dispatch it.
            xDispatch = xDispatchProvider->queryDispatch( aURL, FRAMETYPE_BLANK, 0 );
            xDispatch->dispatch( aURL, Sequence< PropertyValue >() );

            // Use special feature of desktop service and log current tree state in file.
//          LOG_TREE( xDesktop )
        }

        // Set running-mode for application.
        Execute();
    }
}
<|endoftext|>


<commit_before>//===- tools/seec-trace-print/OnlinePythonTutor.cpp -----------------------===//
//
//                                    SeeC
//
// This file is distributed under The MIT License (MIT). See LICENSE.TXT for
// details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
//===----------------------------------------------------------------------===//

#include "seec/Clang/MappedFunctionState.hpp"
#include "seec/Clang/MappedGlobalVariable.hpp"
#include "seec/Clang/MappedProcessState.hpp"
#include "seec/Clang/MappedProcessTrace.hpp"
#include "seec/Clang/MappedStateMovement.hpp"
#include "seec/Clang/MappedThreadState.hpp"
#include "seec/Util/Printing.hpp"

#include "clang/AST/Decl.h"

#include "llvm/Support/raw_ostream.h"

using namespace seec;
using namespace seec::cm;
using namespace seec::util;

llvm::StringRef GetSingularMainFileContents(ProcessTrace const &Trace)
{
  auto const &CompileInfoMap = Trace.getMapping().getCompileInfoMap();
  if (CompileInfoMap.size() != 1)
    return llvm::StringRef();

  auto const FI = CompileInfoMap.cbegin()->second->getMainFileInfo();
  if (!FI)
    return llvm::StringRef();

  return FI->getContents().getBuffer();
}

class OPTPrinter {
  llvm::raw_ostream &Out;

  IndentationGuide Indent;

  ProcessTrace const &Trace;

  ProcessState Process;

  OPTPrinter(llvm::raw_ostream &ToStream, ProcessTrace const &FromTrace)
  : Out(ToStream),
    Indent("  ", 1),
    Trace(FromTrace),
    Process(FromTrace)
  {}

  void printValue(Value const &V);

  void printGlobal(GlobalVariable const &GV, std::string &NameOut);

  void printGlobals();

  void printParameter(ParamState const &Param, std::string &NameOut);

  void printLocal(LocalState const &Local, std::string &NameOut);

  void printFunction(FunctionState const &Function);

  void printThread(ThreadState const &Thread);

  void printState();

  bool printAllStates();

public:
  static bool print(llvm::raw_ostream &Out, ProcessTrace const &Trace)
  {
    OPTPrinter Printer(Out, Trace);
    return Printer.printAllStates();
  }
};

void OPTPrinter::printValue(Value const &V)
{
  writeJSONStringLiteral(V.getValueAsStringFull(), Out);
}

void OPTPrinter::printGlobal(GlobalVariable const &GV, std::string &NameOut)
{
  NameOut = GV.getClangValueDecl()->getNameAsString();

  Out << Indent.getString();
  writeJSONStringLiteral(NameOut, Out);
  Out << ": ";

  if (auto const V = GV.getValue())
    printValue(*V);
  else
    Out << "\"<no value>\"";
}

void OPTPrinter::printGlobals()
{
  std::vector<std::string> OrderedNames;

  // globals: dict
  Out << Indent.getString() << "\"globals\": {\n";
  Indent.indent();

  bool PreviousPrinted = false;

  for (auto const &GV : Process.getGlobalVariables()) {
    if (!GV || (GV->isInSystemHeader() && !GV->isReferenced()))
      continue;

    if (PreviousPrinted)
      Out << ",\n";
    else
      PreviousPrinted = true;

    OrderedNames.emplace_back();
    printGlobal(*GV, OrderedNames.back());
  }

  Indent.unindent();
  Out << "\n" << Indent.getString() << "},\n";

  // ordered_globals: [string]
  Out << Indent.getString() << "\"ordered_globals\": [";
  for (std::size_t i = 0; i < OrderedNames.size(); ++i) {
    if (i != 0)
      Out << ", ";
    writeJSONStringLiteral(OrderedNames[i], Out);
  }
  Out << "],\n";
}

void OPTPrinter::printParameter(ParamState const &Param, std::string &NameOut)
{
  NameOut = Param.getDecl()->getNameAsString();

  Out << Indent.getString();
  writeJSONStringLiteral(NameOut, Out);
  Out << ": ";

  if (auto const V = Param.getValue())
    printValue(*V);
  else
    Out << "\"<no value>\"";
}

void OPTPrinter::printLocal(LocalState const &Local, std::string &NameOut)
{
  NameOut = Local.getDecl()->getNameAsString();

  Out << Indent.getString();
  writeJSONStringLiteral(NameOut, Out);
  Out << ": ";

  if (auto const V = Local.getValue())
    printValue(*V);
  else
    Out << "\"<no value>\"";
}

void OPTPrinter::printFunction(FunctionState const &Function)
{
  Out << Indent.getString() << "{\n";
  Indent.indent();

  // func_name
  Out << Indent.getString() << "\"func_name\": ";
  writeJSONStringLiteral(Function.getNameAsString(), Out);
  Out << ",\n";

  // frame_id = ?
  // unique_hash = ?

  // encoded_locals = dict
  std::vector<std::string> OrderedVarnames;

  Out << Indent.getString() << "\"encoded_locals\": {\n";
  Indent.indent();

  {
    bool PreviousPrinted = false;

    for (auto const &Param : Function.getParameters()) {
      if (PreviousPrinted)
        Out << ",\n";
      else
        PreviousPrinted = true;

      OrderedVarnames.emplace_back();
      printParameter(Param, OrderedVarnames.back());
    }

    for (auto const &Local : Function.getLocals()) {
      if (PreviousPrinted)
        Out << ",\n";
      else
        PreviousPrinted = true;

      OrderedVarnames.emplace_back();
      printLocal(Local, OrderedVarnames.back());
    }
  }

  Indent.unindent();
  Out << "\n" << Indent.getString() << "},\n";

  // ordered_varnames = [string]
  Out << Indent.getString() << "\"ordered_varnames\": [";
  for (std::size_t i = 0; i < OrderedVarnames.size(); ++i) {
    if (i != 0)
      Out << ", ";
    writeJSONStringLiteral(OrderedVarnames[i], Out);
  }
  Out << "],\n";

  // is_highlighted = ?

  // These are for Closures and Zombie Frames, so we don't need them.
  Out << Indent.getString() << "\"is_parent\" = false,\n";
  Out << Indent.getString() << "\"is_zombie\" = false,\n";
  Out << Indent.getString() << "\"parent_frame_id_list\": [],\n";

  Indent.unindent();
  Out << Indent.getString() << "}";
}

void OPTPrinter::printThread(ThreadState const &Thread)
{
  auto const &Stack = Thread.getCallStack();

  // func_name
  // stack_to_render
  if (!Stack.empty()) {
    // Write the active function's name.
    auto const &Active = Stack.back().get();
    Out << Indent.getString() << "\"func_name\": ";
    writeJSONStringLiteral(Active.getNameAsString(), Out);
    Out << ",\n";

    // Write the stack.
    Out << Indent.getString() << "\"stack_to_render\": [\n";
    Indent.indent();

    bool PreviousPrinted = false;
    for (auto const &Fn : Stack) {
      if (PreviousPrinted)
        Out << ",\n";
      else
        PreviousPrinted = true;

      printFunction(Fn);
    }

    Indent.unindent();
    Out << "\n" << Indent.getString() << "]\n";
  }
  else {
    Out << Indent.getString() << "\"func_name\": \"<none>\",\n";
    Out << Indent.getString() << "\"stack_to_render\": [],\n";
  }

  // line: int
  // event: string
}

void OPTPrinter::printState()
{
  Out << Indent.getString() << "{\n";
  Indent.indent();

  printGlobals();
  printThread(Process.getThread(0));

  // stdout
  if (auto const Stream = Process.getStreamStdout()) {
    Out << Indent.getString() << "\"stdout\": ";
    writeJSONStringLiteral(Stream->getWritten(), Out);
    Out << ",\n";
  }
  else {
    Out << Indent.getString() << "\"stdout\": \"\",\n";
  }

  // heap
  Out << Indent.getString() << "\"heap\": {}\n";

  Indent.unindent();
  Out << Indent.getString() << "}";
}

bool OPTPrinter::printAllStates()
{
  // OnlinePythonTutor output only supports single-threaded programs.
  if (Process.getThreadCount() != 1)
    return false;

  Out << Indent.getString() << "{\n";
  Indent.indent();

  // Write the source code.
  auto const SourceCode = GetSingularMainFileContents(Trace);
  if (SourceCode.empty())
    return false;

  Out << Indent.getString() << "\"code\": ";
  writeJSONStringLiteral(SourceCode, Out);
  Out << ",\n";

  Out << Indent.getString() << "\"trace\": [\n";
  Indent.indent();

  printState();

  while (moveForward(Process.getThread(0))) {
    Out << ",\n";
    printState();
  }

  Out << "\n";

  Indent.unindent();
  Out << Indent.getString() << "]\n";

  Indent.unindent();
  Out << Indent.getString() << "}\n";

  return true;
}

void PrintOnlinePythonTutor(ProcessTrace const &Trace)
{
  OPTPrinter::print(llvm::outs(), Trace);
}
<commit_msg>Add support for frame_id, unique_hash, is_highlighted, event, and line. Also correct some bugs with the output. Now successfully renders with OnlinePythonTutor.<commit_after>//===- tools/seec-trace-print/OnlinePythonTutor.cpp -----------------------===//
//
//                                    SeeC
//
// This file is distributed under The MIT License (MIT). See LICENSE.TXT for
// details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
//===----------------------------------------------------------------------===//

#include "seec/Clang/MappedFunctionState.hpp"
#include "seec/Clang/MappedGlobalVariable.hpp"
#include "seec/Clang/MappedProcessState.hpp"
#include "seec/Clang/MappedProcessTrace.hpp"
#include "seec/Clang/MappedStateMovement.hpp"
#include "seec/Clang/MappedThreadState.hpp"
#include "seec/Trace/FunctionState.hpp"
#include "seec/Trace/TraceReader.hpp"
#include "seec/Util/Printing.hpp"

#include "clang/AST/Decl.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/raw_ostream.h"

using namespace seec;
using namespace seec::cm;
using namespace seec::util;

llvm::StringRef GetSingularMainFileContents(ProcessTrace const &Trace)
{
  auto const &CompileInfoMap = Trace.getMapping().getCompileInfoMap();
  if (CompileInfoMap.size() != 1)
    return llvm::StringRef();

  auto const FI = CompileInfoMap.cbegin()->second->getMainFileInfo();
  if (!FI)
    return llvm::StringRef();

  return FI->getContents().getBuffer();
}

class OPTPrinter {
  llvm::raw_ostream &Out;

  IndentationGuide Indent;

  ProcessTrace const &Trace;

  ProcessState Process;

  llvm::DenseMap<seec::trace::offset_uint, uint32_t> FrameIDMap;

  unsigned PreviousLine;

  OPTPrinter(llvm::raw_ostream &ToStream, ProcessTrace const &FromTrace)
  : Out(ToStream),
    Indent("  ", 1),
    Trace(FromTrace),
    Process(FromTrace),
    FrameIDMap(),
    PreviousLine(1)
  {}

  uint32_t getFrameID(FunctionState const &Function);

  void printValue(Value const &V);

  void printGlobal(GlobalVariable const &GV, std::string &NameOut);

  void printGlobals();

  void printParameter(ParamState const &Param, std::string &NameOut);

  void printLocal(LocalState const &Local, std::string &NameOut);

  void printFunction(FunctionState const &Function, bool IsActive);

  void printThread(ThreadState const &Thread);

  bool printAndMoveState();

  bool printAllStates();

public:
  static bool print(llvm::raw_ostream &Out, ProcessTrace const &Trace)
  {
    OPTPrinter Printer(Out, Trace);
    return Printer.printAllStates();
  }
};

uint32_t OPTPrinter::getFrameID(FunctionState const &Function)
{
  auto const &Trace = Function.getUnmappedState().getTrace();
  auto const Result = FrameIDMap.insert(std::make_pair(Trace.getEventStart(),
                                                       FrameIDMap.size() + 1));
  return Result.first->second;
}

void OPTPrinter::printValue(Value const &V)
{
  writeJSONStringLiteral(V.getValueAsStringFull(), Out);
}

void OPTPrinter::printGlobal(GlobalVariable const &GV, std::string &NameOut)
{
  NameOut = GV.getClangValueDecl()->getNameAsString();

  Out << Indent.getString();
  writeJSONStringLiteral(NameOut, Out);
  Out << ": ";

  if (auto const V = GV.getValue())
    printValue(*V);
  else
    Out << "\"<no value>\"";
}

void OPTPrinter::printGlobals()
{
  std::vector<std::string> OrderedNames;

  // globals: dict
  Out << Indent.getString() << "\"globals\": {\n";
  Indent.indent();

  bool PreviousPrinted = false;

  for (auto const &GV : Process.getGlobalVariables()) {
    if (!GV || (GV->isInSystemHeader() && !GV->isReferenced()))
      continue;

    if (PreviousPrinted)
      Out << ",\n";
    else
      PreviousPrinted = true;

    OrderedNames.emplace_back();
    printGlobal(*GV, OrderedNames.back());
  }

  Indent.unindent();
  Out << "\n" << Indent.getString() << "},\n";

  // ordered_globals: [string]
  Out << Indent.getString() << "\"ordered_globals\": [";
  for (std::size_t i = 0; i < OrderedNames.size(); ++i) {
    if (i != 0)
      Out << ", ";
    writeJSONStringLiteral(OrderedNames[i], Out);
  }
  Out << "],\n";
}

void OPTPrinter::printParameter(ParamState const &Param, std::string &NameOut)
{
  NameOut = Param.getDecl()->getNameAsString();

  Out << Indent.getString();
  writeJSONStringLiteral(NameOut, Out);
  Out << ": ";

  if (auto const V = Param.getValue())
    printValue(*V);
  else
    Out << "\"<no value>\"";
}

void OPTPrinter::printLocal(LocalState const &Local, std::string &NameOut)
{
  NameOut = Local.getDecl()->getNameAsString();

  Out << Indent.getString();
  writeJSONStringLiteral(NameOut, Out);
  Out << ": ";

  if (auto const V = Local.getValue())
    printValue(*V);
  else
    Out << "\"<no value>\"";
}

void OPTPrinter::printFunction(FunctionState const &Function, bool IsActive)
{
  Out << Indent.getString() << "{\n";
  Indent.indent();

  // func_name
  auto const FnName = Function.getNameAsString();
  Out << Indent.getString() << "\"func_name\": ";
  writeJSONStringLiteral(FnName, Out);
  Out << ",\n";

  // frame_id = unique key for this function call
  // unique_hash = func_name + frame_id
  auto const FrameID = getFrameID(Function);
  Out << Indent.getString() << "\"frame_id\": " << FrameID << ",\n";
  Out << Indent.getString() << "\"unique_hash\": ";
  writeJSONStringLiteral(FnName + std::to_string(FrameID), Out);
  Out << ",\n";

  // encoded_locals = dict
  std::vector<std::string> OrderedVarnames;

  Out << Indent.getString() << "\"encoded_locals\": {\n";
  Indent.indent();

  {
    bool PreviousPrinted = false;

    for (auto const &Param : Function.getParameters()) {
      if (PreviousPrinted)
        Out << ",\n";
      else
        PreviousPrinted = true;

      OrderedVarnames.emplace_back();
      printParameter(Param, OrderedVarnames.back());
    }

    for (auto const &Local : Function.getLocals()) {
      if (PreviousPrinted)
        Out << ",\n";
      else
        PreviousPrinted = true;

      OrderedVarnames.emplace_back();
      printLocal(Local, OrderedVarnames.back());
    }
  }

  Indent.unindent();
  Out << "\n" << Indent.getString() << "},\n";

  // ordered_varnames = [string]
  Out << Indent.getString() << "\"ordered_varnames\": [";
  for (std::size_t i = 0; i < OrderedVarnames.size(); ++i) {
    if (i != 0)
      Out << ", ";
    writeJSONStringLiteral(OrderedVarnames[i], Out);
  }
  Out << "],\n";

  // is_highlighted = ?
  Out << Indent.getString();
  if (IsActive)
    Out << "\"is_highlighted\": true,\n";
  else
    Out << "\"is_highlighted\": false,\n";

  // These are for Closures and Zombie Frames, so we don't need them.
  Out << Indent.getString() << "\"is_parent\": false,\n";
  Out << Indent.getString() << "\"is_zombie\": false,\n";
  Out << Indent.getString() << "\"parent_frame_id_list\": []\n";

  Indent.unindent();
  Out << Indent.getString() << "}";
}

void OPTPrinter::printThread(ThreadState const &Thread)
{
  auto const &Stack = Thread.getCallStack();

  // func_name
  // stack_to_render
  if (!Stack.empty()) {
    // Write the active function's name.
    auto const &Active = Stack.back().get();
    Out << Indent.getString() << "\"func_name\": ";
    writeJSONStringLiteral(Active.getNameAsString(), Out);
    Out << ",\n";

    // Write the stack.
    Out << Indent.getString() << "\"stack_to_render\": [\n";
    Indent.indent();

    bool PreviousPrinted = false;
    for (auto const &Fn : Stack) {
      if (PreviousPrinted)
        Out << ",\n";
      else
        PreviousPrinted = true;

      printFunction(Fn, &Fn.get() == &Active);
    }

    Indent.unindent();
    Out << "\n" << Indent.getString() << "],\n";
  }
  else {
    Out << Indent.getString() << "\"func_name\": \"<none>\",\n";
    Out << Indent.getString() << "\"stack_to_render\": [],\n";
  }

  // event: string
  Out << Indent.getString() << "\"event\": ";
  if (!Thread.isAtEnd())
    Out << "\"step_line\"";
  else
    Out << "\"return\"";
  Out << ",\n";
}

/// \brief Get the start line in the outermost file.
///
static unsigned getLineOutermost(clang::SourceLocation Start,
                                 clang::ASTContext const &AST)
{
  auto const &SourceManager = AST.getSourceManager();

  while (Start.isMacroID())
    Start = SourceManager.getExpansionLoc(Start);

  return SourceManager.getSpellingLineNumber(Start);
}

bool OPTPrinter::printAndMoveState()
{
  Out << Indent.getString() << "{\n";
  Indent.indent();

  printGlobals();
  printThread(Process.getThread(0));

  // stdout
  if (auto const Stream = Process.getStreamStdout()) {
    Out << Indent.getString() << "\"stdout\": ";
    writeJSONStringLiteral(Stream->getWritten(), Out);
    Out << ",\n";
  }
  else {
    Out << Indent.getString() << "\"stdout\": \"\",\n";
  }

  // TODO: heap
  Out << Indent.getString() << "\"heap\": {},\n";

  // Move now so that we can get the "next" line number.
  auto const Moved = moveForward(Process.getThread(0));

  // line: int
  auto const &Thread = Process.getThread(0);
  auto const &Stack = Thread.getCallStack();

  if (!Stack.empty()) {
    auto const &ActiveFn = Stack.back().get();
    auto const &AST = ActiveFn.getMappedAST()->getASTUnit().getASTContext();

    if (auto const ActiveStmt = ActiveFn.getActiveStmt())
      PreviousLine = getLineOutermost(ActiveStmt->getLocStart(), AST);
    else
      PreviousLine = getLineOutermost(ActiveFn.getFunctionDecl()->getLocStart(),
                                      AST);
  }

  Out << Indent.getString() << "\"line\": " << PreviousLine << "\n";

  Indent.unindent();
  Out << Indent.getString() << "}";

  return Moved;
}

bool OPTPrinter::printAllStates()
{
  // OnlinePythonTutor output only supports single-threaded programs.
  if (Process.getThreadCount() != 1)
    return false;

  Out << Indent.getString() << "{\n";
  Indent.indent();

  // Write the source code.
  auto const SourceCode = GetSingularMainFileContents(Trace);
  if (SourceCode.empty())
    return false;

  Out << Indent.getString() << "\"code\": ";
  writeJSONStringLiteral(SourceCode, Out);
  Out << ",\n";

  Out << Indent.getString() << "\"trace\": [\n";
  Indent.indent();

  while (printAndMoveState()) {
    Out << ",\n";
  }
  Out << "\n";

  Indent.unindent();
  Out << Indent.getString() << "]\n";

  Indent.unindent();
  Out << Indent.getString() << "}\n";

  return true;
}

void PrintOnlinePythonTutor(ProcessTrace const &Trace)
{
  OPTPrinter::print(llvm::outs(), Trace);
}
<|endoftext|>


<commit_before>
#include <SFML/Config.hpp>
#include <SFML/Graphics.hpp>
#include <sfeMovie/Movie.hpp>
#include <iostream>
#include <algorithm>

/*
 * Here is a little use sample for sfeMovie.
 * It'll open and display the movie specified by MOVIE_FILE above.
 *
 * This sample implements basic controls as follow:
 *  - Escape key to exit
 *  - Space key to play/pause the movie playback
 *  - S key to stop and go back to the beginning of the movie
 *  - R key to restart playing from the beginning of the movie
 *  - F key to toggle between windowed and fullscreen mode
 */

void my_pause()
{
#ifdef SFML_SYSTEM_WINDOWS
	system("PAUSE");
#endif
}

std::string StatusToString(sfe::Status status)
{
	switch (status) {
		case sfe::Stopped: return "Stopped"; break;
		case sfe::Paused: return "Paused"; break;
		case sfe::Playing: return "Playing"; break;
		default: return "unknown status"; break;
	}
}

void drawControls(sf::RenderWindow& window, const sfe::Movie& movie)
{
	const int kHorizontalMargin = 10;
	const int kVerticalMargin = 10;
	const int kTimelineBackgroundHeight = 20;
	const int kTimelineInnerMargin = 4;

	sf::RectangleShape background(sf::Vector2f(window.getSize().x - 2 * kHorizontalMargin, kTimelineBackgroundHeight));
	background.setPosition(kHorizontalMargin, window.getSize().y - kTimelineBackgroundHeight - kVerticalMargin);
	background.setFillColor(sf::Color(0, 0, 0, 255/2));

	sf::RectangleShape border(sf::Vector2f(background.getSize().x - 2 * kTimelineInnerMargin, background.getSize().y - 2 * kTimelineInnerMargin));
	border.setPosition(background.getPosition().x + kTimelineInnerMargin, background.getPosition().y + kTimelineInnerMargin);
	border.setFillColor(sf::Color::Transparent);
	border.setOutlineColor(sf::Color::White);
	border.setOutlineThickness(1.0);

	float fprogress = movie.getPlayingOffset().asSeconds() / movie.getDuration().asSeconds();
	sf::RectangleShape progress(sf::Vector2f(1, border.getSize().y - 2 * border.getOutlineThickness()));
	progress.setPosition(border.getPosition().x + border.getOutlineThickness() + fprogress * (border.getSize().x - 2 * border.getOutlineThickness()), border.getPosition().y + border.getOutlineThickness());
	progress.setFillColor(sf::Color::White);

	window.draw(background);
	window.draw(border);
	window.draw(progress);
}

int main(int argc, const char *argv[])
{
	if (argc < 2)
	{
		std::cout << "Usage: " << std::string(argv[0]) << " movie_path" << std::endl;
		my_pause();
		return 1;
	}

	std::string mediaFile = std::string(argv[1]);
	std::cout << "Going to open movie file \"" << mediaFile << "\"" << std::endl;

	sfe::Movie movie;
	if (!movie.openFromFile(mediaFile)) {
		my_pause();
		return 1;
	}

	bool fullscreen = false;
	sf::VideoMode mode = sf::VideoMode::getDesktopMode();
	int width = std::min((int)mode.width, movie.getSize().x);
	int height = std::min((int)mode.height, movie.getSize().y);

	// Create window
	sf::RenderWindow window(sf::VideoMode(width, height), "sfeMovie Player", sf::Style::Close);
	movie.fit(0, 0, width, height);

	// Scale movie to the window drawing area and enable VSync
	window.setFramerateLimit(60);
	movie.play();

	while (window.isOpen())
	{
		sf::Event ev;
		while (window.pollEvent(ev))
		{
			// Window closure
			if (ev.type == sf::Event::Closed ||
				(ev.type == sf::Event::KeyPressed &&
				 ev.key.code == sf::Keyboard::Escape))
			{
				window.close();
			}

			if (ev.type == sf::Event::KeyPressed) {
				if (ev.key.code == sf::Keyboard::Space) {
					if (movie.getStatus() == sfe::Playing) {
						movie.pause();
					} else {
						movie.play();
					}
				} else if (ev.key.code == sf::Keyboard::F) {
					fullscreen = !fullscreen;
					window.create(sf::VideoMode(width, height), "sfeMovie Player", fullscreen ? sf::Style::Fullscreen : sf::Style::Close);
					movie.fit(0, 0, window.getSize().x, window.getSize().y);
				} else if (ev.key.code == sf::Keyboard::P) {
					std::cout << "Status: " << StatusToString(movie.getStatus()) << std::endl;
					std::cout << "Position: " << movie.getPlayingOffset().asSeconds() << "s" << std::endl;
					std::cout << "Duration: " << movie.getDuration().asSeconds() << "s" << std::endl;
					std::cout << "Size: " << movie.getSize().x << "x" << movie.getSize().y << std::endl;
					std::cout << "Framerate: " << movie.getFramerate() << " FPS (average)" << std::endl;
					std::cout << "Volume: " << movie.getVolume() << std::endl;
					std::cout << "Sample rate: " << movie.getSampleRate() << std::endl;
					std::cout << "Channel count: " << movie.getChannelCount() << std::endl;
				}
			} else if (ev.type == sf::Event::MouseWheelMoved) {
				float volume = movie.getVolume() + 10 * ev.mouseWheel.delta;
				volume = std::min(volume, 100.f);
				volume = std::max(volume, 0.f);
				movie.setVolume(volume);
			}
		}

		movie.update();

		// Render movie
		window.clear();
		window.draw(movie);
		drawControls(window, movie);
		window.display();
	}

	return 0;
}

<commit_msg>#49 Display stream info in sfeMovie sample<commit_after>
#include <SFML/Config.hpp>
#include <SFML/Graphics.hpp>
#include <sfeMovie/Movie.hpp>
#include <iostream>
#include <algorithm>

/*
 * Here is a little use sample for sfeMovie.
 * It'll open and display the movie specified by MOVIE_FILE above.
 *
 * This sample implements basic controls as follow:
 *  - Escape key to exit
 *  - Space key to play/pause the movie playback
 *  - S key to stop and go back to the beginning of the movie
 *  - R key to restart playing from the beginning of the movie
 *  - F key to toggle between windowed and fullscreen mode
 */

void my_pause()
{
#ifdef SFML_SYSTEM_WINDOWS
	system("PAUSE");
#endif
}

std::string StatusToString(sfe::Status status)
{
	switch (status) {
		case sfe::Stopped: return "Stopped"; break;
		case sfe::Paused: return "Paused"; break;
		case sfe::Playing: return "Playing"; break;
		default: return "unknown status"; break;
	}
}

std::string MediaTypeToString(sfe::MediaType type)
{
	switch (type) {
		case sfe::MEDIA_TYPE_AUDIO:		return "audio";
		case sfe::MEDIA_TYPE_SUBTITLE:	return "subtitle";
		case sfe::MEDIA_TYPE_VIDEO:		return "video";
		case sfe::MEDIA_TYPE_UNKNOWN:	return "unknown";
		default:						return "(null)";
	}
}

void drawControls(sf::RenderWindow& window, const sfe::Movie& movie)
{
	const int kHorizontalMargin = 10;
	const int kVerticalMargin = 10;
	const int kTimelineBackgroundHeight = 20;
	const int kTimelineInnerMargin = 4;

	sf::RectangleShape background(sf::Vector2f(window.getSize().x - 2 * kHorizontalMargin, kTimelineBackgroundHeight));
	background.setPosition(kHorizontalMargin, window.getSize().y - kTimelineBackgroundHeight - kVerticalMargin);
	background.setFillColor(sf::Color(0, 0, 0, 255/2));

	sf::RectangleShape border(sf::Vector2f(background.getSize().x - 2 * kTimelineInnerMargin, background.getSize().y - 2 * kTimelineInnerMargin));
	border.setPosition(background.getPosition().x + kTimelineInnerMargin, background.getPosition().y + kTimelineInnerMargin);
	border.setFillColor(sf::Color::Transparent);
	border.setOutlineColor(sf::Color::White);
	border.setOutlineThickness(1.0);

	float fprogress = movie.getPlayingOffset().asSeconds() / movie.getDuration().asSeconds();
	sf::RectangleShape progress(sf::Vector2f(1, border.getSize().y - 2 * border.getOutlineThickness()));
	progress.setPosition(border.getPosition().x + border.getOutlineThickness() + fprogress * (border.getSize().x - 2 * border.getOutlineThickness()), border.getPosition().y + border.getOutlineThickness());
	progress.setFillColor(sf::Color::White);

	window.draw(background);
	window.draw(border);
	window.draw(progress);
}

void printMovieInfo(const sfe::Movie& movie)
{
	std::cout << "Status: " << StatusToString(movie.getStatus()) << std::endl;
	std::cout << "Position: " << movie.getPlayingOffset().asSeconds() << "s" << std::endl;
	std::cout << "Duration: " << movie.getDuration().asSeconds() << "s" << std::endl;
	std::cout << "Size: " << movie.getSize().x << "x" << movie.getSize().y << std::endl;
	std::cout << "Framerate: " << movie.getFramerate() << " FPS (average)" << std::endl;
	std::cout << "Volume: " << movie.getVolume() << std::endl;
	std::cout << "Sample rate: " << movie.getSampleRate() << std::endl;
	std::cout << "Channel count: " << movie.getChannelCount() << std::endl;

	const std::vector<sfe::StreamDescriptor>& streams = movie.getStreams();
	std::cout << streams.size() << " streams found in the media" << std::endl;

	for (std::vector<sfe::StreamDescriptor>::const_iterator it = streams.begin(); it != streams.end(); ++it) {
		std::cout << " #" << it->index << " : " << MediaTypeToString(it->type);

		if (!it->language.empty())
			std::cout << " (language: " << it->language << ")";
		std::cout << std::endl;
	}
}

int main(int argc, const char *argv[])
{
	if (argc < 2)
	{
		std::cout << "Usage: " << std::string(argv[0]) << " movie_path" << std::endl;
		my_pause();
		return 1;
	}

	std::string mediaFile = std::string(argv[1]);
	std::cout << "Going to open movie file \"" << mediaFile << "\"" << std::endl;

	sfe::Movie movie;
	if (!movie.openFromFile(mediaFile)) {
		my_pause();
		return 1;
	}

	bool fullscreen = false;
	sf::VideoMode mode = sf::VideoMode::getDesktopMode();
	int width = std::min((int)mode.width, movie.getSize().x);
	int height = std::min((int)mode.height, movie.getSize().y);

	// Create window
	sf::RenderWindow window(sf::VideoMode(width, height), "sfeMovie Player", sf::Style::Close);
	movie.fit(0, 0, width, height);

	// Scale movie to the window drawing area and enable VSync
	window.setFramerateLimit(60);
	movie.play();

	while (window.isOpen())
	{
		sf::Event ev;
		while (window.pollEvent(ev))
		{
			// Window closure
			if (ev.type == sf::Event::Closed ||
				(ev.type == sf::Event::KeyPressed &&
				 ev.key.code == sf::Keyboard::Escape))
			{
				window.close();
			}

			if (ev.type == sf::Event::KeyPressed) {
				if (ev.key.code == sf::Keyboard::Space) {
					if (movie.getStatus() == sfe::Playing) {
						movie.pause();
					} else {
						movie.play();
					}
				} else if (ev.key.code == sf::Keyboard::F) {
					fullscreen = !fullscreen;
					window.create(sf::VideoMode(width, height), "sfeMovie Player", fullscreen ? sf::Style::Fullscreen : sf::Style::Close);
					movie.fit(0, 0, window.getSize().x, window.getSize().y);
				} else if (ev.key.code == sf::Keyboard::P) {
					printMovieInfo(movie);
				}
			} else if (ev.type == sf::Event::MouseWheelMoved) {
				float volume = movie.getVolume() + 10 * ev.mouseWheel.delta;
				volume = std::min(volume, 100.f);
				volume = std::max(volume, 0.f);
				movie.setVolume(volume);
			}
		}

		movie.update();

		// Render movie
		window.clear();
		window.draw(movie);
		drawControls(window, movie);
		window.display();
	}

	return 0;
}

<|endoftext|>


<commit_before>#include "CommandRegistry.h"

void megamol::frontend_resources::CommandRegistry::add_command(const megamol::frontend_resources::Command& c) {
    const bool command_is_new = command_index.find(c.name) == command_index.end();
    const bool key_code_unused = key_to_command.find(c.key) == key_to_command.end();
    if (command_is_new && key_code_unused) {
        push_command(c);
    } else {
        Command c2;
        if (!command_is_new) {
            c2.name = increment_name(c.name);
        }
        if (key_code_unused) {
            c2.key = c.key;
        }
        c2.param = c.param;
        push_command(c2);
    }
}

void megamol::frontend_resources::CommandRegistry::remove_command(const megamol::core::param::AbstractParam* param) {
    auto it = std::find_if(commands.begin(), commands.end(), [param] (const Command& c){return c.param == param;});
    if (it != commands.end()) {
        command_index.erase(it->name);
        if (it->key.key != Key::KEY_UNKNOWN) key_to_command.erase(it->key);
        commands.erase(it);
    }
}

void megamol::frontend_resources::CommandRegistry::update_hotkey(const std::string& command_name, KeyCode key) {
    if (!is_new(command_name)) {
        auto& c = commands[command_index[command_name]];
        const auto old_key = c.key;
        c.key = key;
        key_to_command.erase(old_key);
    }
}

std::string megamol::frontend_resources::CommandRegistry::increment_name(const std::string& oldname) {
    std::string new_name;
    std::string prefix;
    std::regex r("^(.*?)_\\d+$");
    std::cmatch m;
    if (std::regex_match(oldname.c_str(), m, r)) {
        // already have a suffix
        prefix = m[0];
    } else {
        prefix = oldname;
    }
    int cnt = 0;
    bool isnew = false;
    do {
        cnt++;
        new_name = prefix + "_" + std::to_string(cnt);
        isnew = is_new(new_name);
    } while (!isnew);
    return new_name;
}

void megamol::frontend_resources::CommandRegistry::push_command(const Command& c) {
    commands.push_back(c);
    if (c.key.key != Key::KEY_UNKNOWN) key_to_command[c.key] = static_cast<int>(commands.size() - 1);
    command_index[c.name] = static_cast<int>(commands.size() - 1);
}
<commit_msg>small fix to update_hotkey<commit_after>#include "CommandRegistry.h"

void megamol::frontend_resources::CommandRegistry::add_command(const megamol::frontend_resources::Command& c) {
    const bool command_is_new = command_index.find(c.name) == command_index.end();
    const bool key_code_unused = key_to_command.find(c.key) == key_to_command.end();
    if (command_is_new && key_code_unused) {
        push_command(c);
    } else {
        Command c2;
        if (!command_is_new) {
            c2.name = increment_name(c.name);
        }
        if (key_code_unused) {
            c2.key = c.key;
        }
        c2.param = c.param;
        push_command(c2);
    }
}

void megamol::frontend_resources::CommandRegistry::remove_command(const megamol::core::param::AbstractParam* param) {
    auto it = std::find_if(commands.begin(), commands.end(), [param] (const Command& c){return c.param == param;});
    if (it != commands.end()) {
        command_index.erase(it->name);
        if (it->key.key != Key::KEY_UNKNOWN) key_to_command.erase(it->key);
        commands.erase(it);
    }
}

void megamol::frontend_resources::CommandRegistry::update_hotkey(const std::string& command_name, KeyCode key) {
    if (!is_new(command_name)) {
        auto& c = commands[command_index[command_name]];
        const auto old_key = c.key;
        c.key = key;
        key_to_command.erase(old_key);
        key_to_command[key] = command_index[command_name];
    }
}

std::string megamol::frontend_resources::CommandRegistry::increment_name(const std::string& oldname) {
    std::string new_name;
    std::string prefix;
    std::regex r("^(.*?)_\\d+$");
    std::cmatch m;
    if (std::regex_match(oldname.c_str(), m, r)) {
        // already have a suffix
        prefix = m[0];
    } else {
        prefix = oldname;
    }
    int cnt = 0;
    bool isnew = false;
    do {
        cnt++;
        new_name = prefix + "_" + std::to_string(cnt);
        isnew = is_new(new_name);
    } while (!isnew);
    return new_name;
}

void megamol::frontend_resources::CommandRegistry::push_command(const Command& c) {
    commands.push_back(c);
    if (c.key.key != Key::KEY_UNKNOWN) key_to_command[c.key] = static_cast<int>(commands.size() - 1);
    command_index[c.name] = static_cast<int>(commands.size() - 1);
}
<|endoftext|>