<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: WColumnSelect.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 13:38:47 $
 *
 *  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 DBAUI_WIZ_COLUMNSELECT_HXX
#define DBAUI_WIZ_COLUMNSELECT_HXX

#ifndef DBAUI_WIZ_TABBPAGE_HXX
#include "WTabPage.hxx"
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif

namespace dbaui
{
    // ========================================================
    // Wizard Page: OWizColumnSelect
    // ========================================================

    class OWizColumnSelect : public OWizardPage
    {

        FixedLine               m_flColumns;
        MultiListBox            m_lbOrgColumnNames; // left side
        ImageButton             m_ibColumn_RH;
        ImageButton             m_ibColumns_RH;
        ImageButton             m_ibColumn_LH;
        ImageButton             m_ibColumns_LH;
        MultiListBox            m_lbNewColumnNames; // right side

        DECL_LINK( ButtonClickHdl, Button * );
        DECL_LINK( ListDoubleClickHdl, MultiListBox * );

        void clearListBox(MultiListBox& _rListBox);
        void fillColumns(       ListBox* pRight,
                                ::std::vector< ::rtl::OUString> &_rRightColumns);

        void createNewColumn(   ListBox* _pListbox,
                                OFieldDescription* _pSrcField,
                                ::std::vector< ::rtl::OUString>& _rRightColumns,
                                const ::rtl::OUString&  _sColumnName,
                                const ::rtl::OUString&  _sExtraChars,
                                sal_Int32               _nMaxNameLen,
                                const ::comphelper::TStringMixEqualFunctor& _aCase);

        void moveColumn(        ListBox* _pRight,
                                ListBox* _pLeft,
                                ::std::vector< ::rtl::OUString>& _rRightColumns,
                                const ::rtl::OUString&  _sColumnName,
                                const ::rtl::OUString&  _sExtraChars,
                                sal_Int32               _nMaxNameLen,
                                const ::comphelper::TStringMixEqualFunctor& _aCase);

        void enableButtons();

        USHORT adjustColumnPosition(ListBox* _pLeft,
                                    const ::rtl::OUString&  _sColumnName,
                                    ODatabaseExport::TColumnVector::size_type nCurrentPos,
                                    const ::comphelper::TStringMixEqualFunctor& _aCase);

    public:
        virtual void            Reset ( );
        virtual void            ActivatePage();
        virtual sal_Bool        LeavePage();
        virtual String          GetTitle() const ;

        OWizColumnSelect(Window* pParent);
        virtual ~OWizColumnSelect();
    };
}
#endif // DBAUI_WIZ_COLUMNSELECT_HXX

<commit_msg>INTEGRATION: CWS dba24d (1.8.158); FILE MERGED 2007/11/08 14:21:04 fs 1.8.158.1: #i81658# re-factoring of the Copy Table wizard<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: WColumnSelect.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2008-01-30 08:48:21 $
 *
 *  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 DBAUI_WIZ_COLUMNSELECT_HXX
#define DBAUI_WIZ_COLUMNSELECT_HXX

#include "WTabPage.hxx"
#include "WCopyTable.hxx"

#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#include <comphelper/stl_types.hxx>

namespace dbaui
{
    class OFieldDescription;

    // ========================================================
    // Wizard Page: OWizColumnSelect
    // ========================================================

    class OWizColumnSelect : public OWizardPage
    {

        FixedLine               m_flColumns;
        MultiListBox            m_lbOrgColumnNames; // left side
        ImageButton             m_ibColumn_RH;
        ImageButton             m_ibColumns_RH;
        ImageButton             m_ibColumn_LH;
        ImageButton             m_ibColumns_LH;
        MultiListBox            m_lbNewColumnNames; // right side

        DECL_LINK( ButtonClickHdl, Button * );
        DECL_LINK( ListDoubleClickHdl, MultiListBox * );

        void clearListBox(MultiListBox& _rListBox);
        void fillColumns(       ListBox* pRight,
                                ::std::vector< ::rtl::OUString> &_rRightColumns);

        void createNewColumn(   ListBox* _pListbox,
                                OFieldDescription* _pSrcField,
                                ::std::vector< ::rtl::OUString>& _rRightColumns,
                                const ::rtl::OUString&  _sColumnName,
                                const ::rtl::OUString&  _sExtraChars,
                                sal_Int32               _nMaxNameLen,
                                const ::comphelper::TStringMixEqualFunctor& _aCase);

        void moveColumn(        ListBox* _pRight,
                                ListBox* _pLeft,
                                ::std::vector< ::rtl::OUString>& _rRightColumns,
                                const ::rtl::OUString&  _sColumnName,
                                const ::rtl::OUString&  _sExtraChars,
                                sal_Int32               _nMaxNameLen,
                                const ::comphelper::TStringMixEqualFunctor& _aCase);

        void enableButtons();

        USHORT adjustColumnPosition(ListBox* _pLeft,
                                    const ::rtl::OUString&  _sColumnName,
                                    ODatabaseExport::TColumnVector::size_type nCurrentPos,
                                    const ::comphelper::TStringMixEqualFunctor& _aCase);

    public:
        virtual void            Reset ( );
        virtual void            ActivatePage();
        virtual sal_Bool        LeavePage();
        virtual String          GetTitle() const ;

        OWizColumnSelect(Window* pParent);
        virtual ~OWizColumnSelect();
    };
}
#endif // DBAUI_WIZ_COLUMNSELECT_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dbtreelistbox.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-10-22 12:06:14 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBAUI_DBTREELISTBOX_HXX
#define DBAUI_DBTREELISTBOX_HXX

#ifndef _SVTREEBOX_HXX
#include <svtools/svtreebx.hxx>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef DBAUI_SCROLLHELPER_HXX
#include "ScrollHelper.hxx"
#endif

namespace dbaui
{
    #define TABLE_TYPE  1
    #define VIEW_TYPE   2
    #define FOLDER_TYPE 3

    struct DBTreeEditedEntry
    {
        SvLBoxEntry*    pEntry;
        XubString       aNewText;
    };

    class IEntryFilter
    {
    public:
        virtual bool    includeEntry( SvLBoxEntry* _pEntry ) const = 0;
    };

    //========================================================================
    class IControlActionListener;
    class IController;
    class DBTreeListBox     :public SvTreeListBox
                            ,public dbaui::OModuleClient
    {
        OScrollHelper               m_aScrollHelper;
        Timer                       m_aTimer; // is needed for table updates
        Point                       m_aMousePos;
        SvLBoxEntry*                m_pSelectedEntry;
        SvLBoxEntry*                m_pDragedEntry;
        IControlActionListener*     m_pActionListener;
        IController*                m_pContextMenuActionListener;

        Link                        m_aPreExpandHandler;    // handler to be called before a node is expanded
        Link                        m_aCutHandler;          // called when someone press CTRL+X
        Link                        m_aCopyHandler;         // called when someone press CTRL+C
        Link                        m_aPasteHandler;        // called when someone press CTRL+V
        Link                        m_aDeleteHandler;       // called when someone press DELETE Key
        Link                        m_aEditingHandler;      // called before someone will edit an entry
        Link                        m_aEditedHandler;       // called after someone edited an entry
        Link                        m_aEnterKeyHdl;

        sal_Int32                   m_nSelectLock;
        sal_Bool                    m_bHandleEnterKey;

    protected:
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xORB;

    private:
        void init();
        DECL_LINK( OnTimeOut, void* );
        DECL_LINK( OnResetEntry, SvLBoxEntry* );
        DECL_LINK( DoubleClickHdl, SvTreeListBox* );
        DECL_LINK( ScrollUpHdl, SvTreeListBox* );
        DECL_LINK( ScrollDownHdl, SvTreeListBox* );

    public:
        DBTreeListBox( Window* pParent
            ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB
            ,WinBits nWinStyle=0
            ,sal_Bool _bHandleEnterKey = sal_False);
        DBTreeListBox( Window* pParent
            ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB
            ,const ResId& rResId
            ,sal_Bool _bHandleEnterKey = sal_False);
        ~DBTreeListBox();

        void                    setControlActionListener( IControlActionListener* _pListener ) { m_pActionListener = _pListener; }
        IControlActionListener* getControlActionListener( ) const { return m_pActionListener; }

        void            setContextMenuActionListener( IController* _pConextListener) { m_pContextMenuActionListener = _pConextListener; }
        IController*    getContextMenuActionListener( ) const { return m_pContextMenuActionListener; }

        inline void setORB(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB) { m_xORB = _xORB; }

        void    SetPreExpandHandler(const Link& _rHdl) { m_aPreExpandHandler = _rHdl; }
        Link    GetPreExpandHandler() const         { return m_aPreExpandHandler; }

        void    setCutHandler(const Link& _rHdl)    { m_aCutHandler = _rHdl; }
        Link    getCutHandler() const               { return m_aCutHandler; }

        void    setCopyHandler(const Link& _rHdl)   { m_aCopyHandler = _rHdl; }
        Link    getCopyHandler() const              { return m_aCopyHandler; }

        void    setPasteHandler(const Link& _rHdl)  { m_aPasteHandler = _rHdl; }
        Link    getPasteHandler() const             { return m_aPasteHandler; }

        void    setDeleteHandler(const Link& _rHdl) { m_aDeleteHandler = _rHdl; }
        Link    getDeleteHandler() const            { return m_aDeleteHandler; }

        void    setEditingHandler(const Link& _rHdl){ m_aEditingHandler = _rHdl; }
        Link    getEditingHandler() const           { return m_aEditingHandler; }

        void    setEditedHandler(const Link& _rHdl) { m_aEditedHandler = _rHdl; }
        Link    getEditedHandler() const            { return m_aEditedHandler; }

        inline SvLBoxEntry* GetSelectedEntry() const { return m_pSelectedEntry; }
        // modified the given entry so that the expand handler is called whenever the entry is expanded
        // (normally, the expand handler is called only once)
        void            EnableExpandHandler(SvLBoxEntry* _pEntry);

        SvLBoxEntry*    GetEntryPosByName( const String& aName, SvLBoxEntry* pStart = NULL, const IEntryFilter* _pFilter = NULL ) const;
        virtual void    RequestingChilds( SvLBoxEntry* pParent );
        virtual void    SelectHdl();
        virtual void    DeselectHdl();
        // Window
        virtual void    KeyInput( const KeyEvent& rKEvt );

        virtual void    InitEntry( SvLBoxEntry* pEntry, const XubString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp);

        virtual void    SelectEntry(SvLBoxEntry* _pEntry);
        // enable editing for tables/views and queries
        virtual BOOL    EditingEntry( SvLBoxEntry* pEntry, Selection& );
        virtual BOOL    EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText );

        virtual PopupMenu* CreateContextMenu( void );
        virtual void    ExcecuteContextMenuAction( USHORT nSelectedPopupEntry );

        sal_Int32       lockAutoSelect();
        sal_Int32       unlockAutoSelect();
        sal_Int32       locked() const { return m_nSelectLock; }

        void            SetEnterKeyHdl(const Link& rNewHdl) {m_aEnterKeyHdl = rNewHdl;}

        inline void     clearCurrentSelectionEntry() { m_pSelectedEntry = NULL; }

    protected:
        virtual void        MouseButtonDown( const MouseEvent& rMEvt );
        virtual void        Command( const CommandEvent& rCEvt );
        virtual void        RequestHelp( const HelpEvent& rHEvt );

        // DragSourceHelper overridables
        virtual void        StartDrag( sal_Int8 nAction, const Point& rPosPixel );
        // DropTargetHelper overridables
        virtual sal_Int8    AcceptDrop( const AcceptDropEvent& _rEvt );
        virtual sal_Int8    ExecuteDrop( const ExecuteDropEvent& _rEvt );

        virtual void        ModelHasRemoved( SvListEntry* pEntry );
        virtual void        ModelHasEntryInvalidated( SvListEntry* pEntry );

        void                implSelected(SvLBoxEntry* _pSelected);
    };
}

#endif // DBAUI_DBTREELISTBOX_HXX
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.176); FILE MERGED 2005/09/05 17:34:43 rt 1.4.176.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dbtreelistbox.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 15:48:15 $
 *
 *  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 DBAUI_DBTREELISTBOX_HXX
#define DBAUI_DBTREELISTBOX_HXX

#ifndef _SVTREEBOX_HXX
#include <svtools/svtreebx.hxx>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef DBAUI_SCROLLHELPER_HXX
#include "ScrollHelper.hxx"
#endif

namespace dbaui
{
    #define TABLE_TYPE  1
    #define VIEW_TYPE   2
    #define FOLDER_TYPE 3

    struct DBTreeEditedEntry
    {
        SvLBoxEntry*    pEntry;
        XubString       aNewText;
    };

    class IEntryFilter
    {
    public:
        virtual bool    includeEntry( SvLBoxEntry* _pEntry ) const = 0;
    };

    //========================================================================
    class IControlActionListener;
    class IController;
    class DBTreeListBox     :public SvTreeListBox
                            ,public dbaui::OModuleClient
    {
        OScrollHelper               m_aScrollHelper;
        Timer                       m_aTimer; // is needed for table updates
        Point                       m_aMousePos;
        SvLBoxEntry*                m_pSelectedEntry;
        SvLBoxEntry*                m_pDragedEntry;
        IControlActionListener*     m_pActionListener;
        IController*                m_pContextMenuActionListener;

        Link                        m_aPreExpandHandler;    // handler to be called before a node is expanded
        Link                        m_aCutHandler;          // called when someone press CTRL+X
        Link                        m_aCopyHandler;         // called when someone press CTRL+C
        Link                        m_aPasteHandler;        // called when someone press CTRL+V
        Link                        m_aDeleteHandler;       // called when someone press DELETE Key
        Link                        m_aEditingHandler;      // called before someone will edit an entry
        Link                        m_aEditedHandler;       // called after someone edited an entry
        Link                        m_aEnterKeyHdl;

        sal_Int32                   m_nSelectLock;
        sal_Bool                    m_bHandleEnterKey;

    protected:
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xORB;

    private:
        void init();
        DECL_LINK( OnTimeOut, void* );
        DECL_LINK( OnResetEntry, SvLBoxEntry* );
        DECL_LINK( DoubleClickHdl, SvTreeListBox* );
        DECL_LINK( ScrollUpHdl, SvTreeListBox* );
        DECL_LINK( ScrollDownHdl, SvTreeListBox* );

    public:
        DBTreeListBox( Window* pParent
            ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB
            ,WinBits nWinStyle=0
            ,sal_Bool _bHandleEnterKey = sal_False);
        DBTreeListBox( Window* pParent
            ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB
            ,const ResId& rResId
            ,sal_Bool _bHandleEnterKey = sal_False);
        ~DBTreeListBox();

        void                    setControlActionListener( IControlActionListener* _pListener ) { m_pActionListener = _pListener; }
        IControlActionListener* getControlActionListener( ) const { return m_pActionListener; }

        void            setContextMenuActionListener( IController* _pConextListener) { m_pContextMenuActionListener = _pConextListener; }
        IController*    getContextMenuActionListener( ) const { return m_pContextMenuActionListener; }

        inline void setORB(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB) { m_xORB = _xORB; }

        void    SetPreExpandHandler(const Link& _rHdl) { m_aPreExpandHandler = _rHdl; }
        Link    GetPreExpandHandler() const         { return m_aPreExpandHandler; }

        void    setCutHandler(const Link& _rHdl)    { m_aCutHandler = _rHdl; }
        Link    getCutHandler() const               { return m_aCutHandler; }

        void    setCopyHandler(const Link& _rHdl)   { m_aCopyHandler = _rHdl; }
        Link    getCopyHandler() const              { return m_aCopyHandler; }

        void    setPasteHandler(const Link& _rHdl)  { m_aPasteHandler = _rHdl; }
        Link    getPasteHandler() const             { return m_aPasteHandler; }

        void    setDeleteHandler(const Link& _rHdl) { m_aDeleteHandler = _rHdl; }
        Link    getDeleteHandler() const            { return m_aDeleteHandler; }

        void    setEditingHandler(const Link& _rHdl){ m_aEditingHandler = _rHdl; }
        Link    getEditingHandler() const           { return m_aEditingHandler; }

        void    setEditedHandler(const Link& _rHdl) { m_aEditedHandler = _rHdl; }
        Link    getEditedHandler() const            { return m_aEditedHandler; }

        inline SvLBoxEntry* GetSelectedEntry() const { return m_pSelectedEntry; }
        // modified the given entry so that the expand handler is called whenever the entry is expanded
        // (normally, the expand handler is called only once)
        void            EnableExpandHandler(SvLBoxEntry* _pEntry);

        SvLBoxEntry*    GetEntryPosByName( const String& aName, SvLBoxEntry* pStart = NULL, const IEntryFilter* _pFilter = NULL ) const;
        virtual void    RequestingChilds( SvLBoxEntry* pParent );
        virtual void    SelectHdl();
        virtual void    DeselectHdl();
        // Window
        virtual void    KeyInput( const KeyEvent& rKEvt );

        virtual void    InitEntry( SvLBoxEntry* pEntry, const XubString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp);

        virtual void    SelectEntry(SvLBoxEntry* _pEntry);
        // enable editing for tables/views and queries
        virtual BOOL    EditingEntry( SvLBoxEntry* pEntry, Selection& );
        virtual BOOL    EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText );

        virtual PopupMenu* CreateContextMenu( void );
        virtual void    ExcecuteContextMenuAction( USHORT nSelectedPopupEntry );

        sal_Int32       lockAutoSelect();
        sal_Int32       unlockAutoSelect();
        sal_Int32       locked() const { return m_nSelectLock; }

        void            SetEnterKeyHdl(const Link& rNewHdl) {m_aEnterKeyHdl = rNewHdl;}

        inline void     clearCurrentSelectionEntry() { m_pSelectedEntry = NULL; }

    protected:
        virtual void        MouseButtonDown( const MouseEvent& rMEvt );
        virtual void        Command( const CommandEvent& rCEvt );
        virtual void        RequestHelp( const HelpEvent& rHEvt );

        // DragSourceHelper overridables
        virtual void        StartDrag( sal_Int8 nAction, const Point& rPosPixel );
        // DropTargetHelper overridables
        virtual sal_Int8    AcceptDrop( const AcceptDropEvent& _rEvt );
        virtual sal_Int8    ExecuteDrop( const ExecuteDropEvent& _rEvt );

        virtual void        ModelHasRemoved( SvListEntry* pEntry );
        virtual void        ModelHasEntryInvalidated( SvListEntry* pEntry );

        void                implSelected(SvLBoxEntry* _pSelected);
    };
}

#endif // DBAUI_DBTREELISTBOX_HXX
<|endoftext|>


<commit_before>#ifndef ALX_FILE_HPP
#define ALX_FILE_HPP

#include <vector>
#include <array>
#include <algorithm>
#include "String.hpp"

#ifdef min
#undef min
#endif

namespace alx {

//TODO

/**
    Value-based wrapper around ALLEGRO_FILE.
 */
class File {
public:
    /**
        constructor from Allegro object.
        @param object allegro object.
        @param managed if true, the object will be deleted automatically when its last reference will be deleted.
     */
    File(ALLEGRO_FILE *object, bool managed = true) : m_object(object, managed ? al_fclose : [](ALLEGRO_FILE *){}) {
    }

    /**
        Opens a file.
        @param path path.
        @param mode mode.
     */
    File(const char *path, const char *mode) : m_object(al_fopen(path, mode), al_fclose) {
    }

    /**
        Checks if the internal allegro object is null.
        @return true if null, false otherwise.
     */
    bool isNull() const {
        return m_object;
    }

    /**
        opens the file.
        @param path path.
        @param mode mode.
        @return true on success.
     */
    bool open(const char *path, const char *mode) {
        m_object = std::shared_ptr<ALLEGRO_FILE>(al_fopen(path, mode), al_fclose);
        return m_object;
    }

    /**
        closes the file.
     */
    void close() {
        al_fclose(m_object.get());
    }

    /**
        Flushes any pending writes.
        @return true on success.
     */
    bool flush() {
        al_fflush(m_object.get());
    }

    /**
        Returns the file position (the 'ftell' function).
        @return the file position.
     */
    int64_t getFilePosition() const {
        return al_ftell(m_object.get());
    }

    /**
        Sets the file position (the 'fseek' function).
        @param pos position.
        @param from the 'whence' parameter: ALLEGRO_SEEK_SET, ALLEGRO_SEEK_CUR, ALLEGRO_SEEK_END.
     */
    bool setFilePosition(int64_t pos, int from = ALLEGRO_SEEK_SET) {
        return al_fseek(m_object.get(), pos, from);
    }

    /**
        Checks if the EOF indicator has been set.
        @return true if set.
     */
    bool getEOF() const {
        return al_feof(m_object.get());
    }

    /**
        Checks if the error indicator has been set.
        @return true if set.
     */
    bool getError() const {
        return al_ferror(m_object.get());
    }

    /**
        Clears the error.
     */
    void clearError() {
        al_fclearerr(m_object.get());
    }

    /**
        Returns the size of the file.
        @return the size of the file.
     */
    int64_t getSize() const {
       return al_fsize(m_object.get());
    }

    /**
        Reads raw bytes into a buffer.
        @param dst destination buffer; it must have enough space to read the given data.
        @param size number of bytes to read.
        @return the number of bytes actually read.
     */
    size_t read(void *dst, size_t size) {
        return al_fread(m_object.get(), dst, size);
    }

    /**
        Reads raw bytes into a static array.
        It reads no more than the size that the array can hold.
        @param dst destination buffer.
        @param size number of bytes to read.
        @return the number of bytes actually read.
     */
    template <class T, size_t BUFFER_SIZE> size_t read(std::array<T, BUFFER_SIZE> &dst, size_t size) {
        return read(&dst[0], std::min(BUFFER_SIZE * sizeof(T), size));
    }

    /**
        Reads raw bytes into a dynamic array.
        It reads no more than the size that the array can hold.
        @param dst destination buffer.
        @param size number of bytes to read.
        @return the number of bytes actually read.
     */
    template <class T, class A> size_t read(std::vector<T, A> &dst, size_t size) {
        return read(&dst[0], std::min(dst.size() * sizeof(T), size));
    }

    /**
        Writes raw bytes to the file.
        @param src source buffer.
        @param size number of bytes to write.
        @return number of bytes actually written.
     */
    size_t write(const void *src, size_t size) {
        return al_fwrite(m_object.get(), src, size);
    }

    /**
        Writes raw bytes from a static array.
        It writes no more than the size that the array can hold.
        @param src source buffer.
        @param size number of bytes to write.
        @return the number of bytes actually written.
     */
    template <class T, size_t BUFFER_SIZE> size_t write(const std::array<T, BUFFER_SIZE> &src, size_t size) {
        return write(&src[0], std::min(BUFFER_SIZE * sizeof(T), size));
    }

    /**
        Writes raw bytes from a dynamic array.
        It writes no more than the size that the array can hold.
        @param src source buffer.
        @param size number of bytes to write.
        @return the number of bytes actually written.
     */
    template <class T, class A> size_t write(const std::vector<T, A> &src, size_t size) {
        return write(&src[0], std::min(src.size() * sizeof(T), size));
    }

    //TODO read/write specific types

private:
    //internal allegro object.
    std::shared_ptr<ALLEGRO_FILE> m_object;

    friend class Config;
};

} //namespace alx

#endif //ALX_FILE_HPP
<commit_msg>Minor changes.<commit_after>#ifndef ALX_FILE_HPP
#define ALX_FILE_HPP

#include <vector>
#include <array>
#include <algorithm>
#include "String.hpp"

#ifdef min
#undef min
#endif

namespace alx {

//TODO

/**
    Value-based wrapper around ALLEGRO_FILE.
 */
class File {
public:
    /**
        constructor from Allegro object.
        @param object allegro object.
        @param managed if true, the object will be deleted automatically when its last reference will be deleted.
     */
    File(ALLEGRO_FILE *object, bool managed = true) : m_object(object, managed ? al_fclose : [](ALLEGRO_FILE *){}) {
    }

    /**
        Opens a file.
        @param path path.
        @param mode mode.
     */
    File(const char *path, const char *mode) : m_object(al_fopen(path, mode), al_fclose) {
    }

    /**
        Checks if the internal allegro object is null.
        @return true if null, false otherwise.
     */
    bool isNull() const {
        return m_object;
    }

    /**
        opens the file.
        @param path path.
        @param mode mode.
        @return true on success.
     */
    bool open(const char *path, const char *mode) {
        m_object = std::shared_ptr<ALLEGRO_FILE>(al_fopen(path, mode), al_fclose);
        return m_object;
    }

    /**
        closes the file.
     */
    void close() {
        al_fclose(m_object.get());
    }

    /**
        Flushes any pending writes.
        @return true on success.
     */
    bool flush() {
        al_fflush(m_object.get());
    }

    /**
        Returns the file position (the 'ftell' function).
        @return the file position.
     */
    int64_t getFilePosition() const {
        return al_ftell(m_object.get());
    }

    /**
        Sets the file position (the 'fseek' function).
        @param pos position.
        @param from the 'whence' parameter: ALLEGRO_SEEK_SET, ALLEGRO_SEEK_CUR, ALLEGRO_SEEK_END.
     */
    bool setFilePosition(int64_t pos, int from = ALLEGRO_SEEK_SET) {
        return al_fseek(m_object.get(), pos, from);
    }

    /**
        Checks if the EOF indicator has been set.
        @return true if set.
     */
    bool isEOF() const {
        return al_feof(m_object.get());
    }

    /**
        Checks if the error indicator has been set.
        @return true if set.
     */
    bool isError() const {
        return al_ferror(m_object.get());
    }

    /**
        Clears the error.
     */
    void clearError() {
        al_fclearerr(m_object.get());
    }

    /**
        Returns the size of the file.
        @return the size of the file.
     */
    int64_t getSize() const {
       return al_fsize(m_object.get());
    }

    /**
        Reads raw bytes into a buffer.
        @param dst destination buffer; it must have enough space to read the given data.
        @param size number of bytes to read.
        @return the number of bytes actually read.
     */
    size_t read(void *dst, size_t size) {
        return al_fread(m_object.get(), dst, size);
    }

    /**
        Reads raw bytes into a static array.
        It reads no more than the size that the array can hold.
        @param dst destination buffer.
        @param size number of bytes to read.
        @return the number of bytes actually read.
     */
    template <class T, size_t BUFFER_SIZE> size_t read(std::array<T, BUFFER_SIZE> &dst, size_t size) {
        return read(&dst[0], std::min(BUFFER_SIZE * sizeof(T), size));
    }

    /**
        Reads raw bytes into a dynamic array.
        It reads no more than the size that the array can hold.
        @param dst destination buffer.
        @param size number of bytes to read.
        @return the number of bytes actually read.
     */
    template <class T, class A> size_t read(std::vector<T, A> &dst, size_t size) {
        return read(&dst[0], std::min(dst.size() * sizeof(T), size));
    }

    /**
        Writes raw bytes to the file.
        @param src source buffer.
        @param size number of bytes to write.
        @return number of bytes actually written.
     */
    size_t write(const void *src, size_t size) {
        return al_fwrite(m_object.get(), src, size);
    }

    /**
        Writes raw bytes from a static array.
        It writes no more than the size that the array can hold.
        @param src source buffer.
        @param size number of bytes to write.
        @return the number of bytes actually written.
     */
    template <class T, size_t BUFFER_SIZE> size_t write(const std::array<T, BUFFER_SIZE> &src, size_t size) {
        return write(&src[0], std::min(BUFFER_SIZE * sizeof(T), size));
    }

    /**
        Writes raw bytes from a dynamic array.
        It writes no more than the size that the array can hold.
        @param src source buffer.
        @param size number of bytes to write.
        @return the number of bytes actually written.
     */
    template <class T, class A> size_t write(const std::vector<T, A> &src, size_t size) {
        return write(&src[0], std::min(src.size() * sizeof(T), size));
    }

    //TODO read/write primitive values

private:
    //internal allegro object.
    std::shared_ptr<ALLEGRO_FILE> m_object;

    friend class Config;
};

} //namespace alx

#endif //ALX_FILE_HPP
<|endoftext|>


<commit_before>/*
Copyright (C) 2014-2017 Rodrigo Jose Hernandez Cordoba

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*! \file
\brief Implementation file for the Scene Node class.
\author Rodrigo Hernandez.
\copy 2014-2016 Rodrigo Hernandez
*/
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <cassert>
#include <algorithm>
#include "aeongames/Node.h"
#include "aeongames/Scene.h"
#include "aeongames/LogLevel.h"
#include "aeongames/ModelInstance.h"

namespace AeonGames
{

    const std::shared_ptr<Node> Node::mNullNode{};
    const size_t Node::kInvalidIndex = std::numeric_limits<size_t>::max(); // Use on VS2013

    Node::Node ( uint32_t aFlags ) :
        mName ( "Node" ),
        mParent{},
        mScene{},
        mLocalTransform(),
        mGlobalTransform(),
        mNodes(),
        mIndex ( kInvalidIndex ),
        mIterator ( 0 ),
        mFlags ( aFlags )
    {
    }

    Node::~Node()
    {
        /* Make sure tree is left in a valid state */
        if ( auto parent = mParent.lock() )
        {
            if ( !parent->RemoveNode ( shared_from_this() ) )
            {
                std::cerr << "Remove Node Failed" << std::endl;
            }
        }
        else if ( auto scene = mScene.lock() )
        {
            if ( !scene->RemoveNode ( shared_from_this() ) )
            {
                std::cerr << "Remove Node Failed" << std::endl;
            }
        }
        for ( auto & mNode : mNodes )
        {
            mNode->mParent.reset();
            mNode->mScene.reset();
            mNode.reset();
        }
    }

    size_t Node::GetChildrenCount() const
    {
        return mNodes.size();
    }

    const std::shared_ptr<Node>& Node::GetChild ( size_t aIndex ) const
    {
        if ( aIndex < mNodes.size() )
        {
            return mNodes[aIndex];
        }
        return mNullNode;
    }

    const std::shared_ptr<Node> Node::GetParent() const
    {
        return mParent.lock();
    }

    size_t Node::GetIndex() const
    {
        return mIndex;
    }

    const std::shared_ptr<ModelInstance>& Node::GetModelInstance() const
    {
        return mModelInstance;
    }

    void Node::SetModelInstance ( const std::shared_ptr<ModelInstance>& aModelInstance )
    {
        mModelInstance = aModelInstance;
    }

    void Node::SetFlags ( uint32_t aFlagBits, bool aEnabled )
    {
        ( aEnabled ) ? mFlags |= aFlagBits : mFlags &= static_cast<uint32_t> ( ~aFlagBits );
    }

    void Node::SetFlag ( enum Flags aFlag, bool aEnabled )
    {
        mFlags[aFlag] = aEnabled;
    }

    bool Node::IsFlagEnabled ( enum Flags aFlag ) const
    {
        return mFlags[aFlag];
    }

    const Transform& Node::GetLocalTransform() const
    {
        return mLocalTransform;
    }

    const Transform& Node::GetGlobalTransform() const
    {
        return mGlobalTransform;
    }

    void Node::SetLocalTransform ( const Transform& aTransform )
    {
        mLocalTransform = aTransform;
        LoopTraverseDFSPreOrder (
            [] ( const std::shared_ptr<Node>& node )
        {
            if ( auto parent = node->mParent.lock() )
            {
                parent->mGlobalTransform * node->mLocalTransform;
            }
            else
            {
                node->mGlobalTransform = node->mLocalTransform;
            }
        } );
    }

    void Node::SetGlobalTransform ( const Transform& aTransform )
    {
        mGlobalTransform = aTransform;
        // Update the Local transform for this node only
        if ( auto parent = mParent.lock() )
        {
            mLocalTransform = mGlobalTransform * parent->mGlobalTransform.GetInverted();
        }
        else
        {
            mLocalTransform = mGlobalTransform;
        }
        // Then Update the Global transform for all children
        LoopTraverseDFSPreOrder (
            [this] ( const std::shared_ptr<Node>& node )
        {
            /*! @todo Although this->mLocalTransform has already been computed
                      think about removing the check and let it be recomputed,
                      it may be faster than the branch that needs to run
                      for each node and is false only once.*/
            if ( node.get() != this )
            {
                if ( auto parent = node->mParent.lock() )
                {
                    node->mGlobalTransform = parent->mGlobalTransform * node->mLocalTransform;
                }
            }
        } );
    }

    void Node::SetName ( const std::string& aName )
    {
        mName = aName;
    }

    const std::string& Node::GetName() const
    {
        return mName;
    }

    bool Node::InsertNode ( size_t aIndex, const std::shared_ptr<Node>& aNode )
    {
        // Never append null or this pointers.
        ///@todo std::find might be slower than removing and reinserting an existing node
        if ( ( aNode != nullptr ) && ( aNode.get() != this ) && ( std::find ( mNodes.begin(), mNodes.end(), aNode ) == mNodes.end() ) )
        {
            if ( auto parent = aNode->mParent.lock() )
            {
                if ( !parent->RemoveNode ( aNode ) )
                {
                    std::cout << LogLevel ( LogLevel::Level::Warning ) << "Parent for node " << aNode->GetName() << " did not have it as a child.";
                }
            }
            aNode->mParent = shared_from_this();
            aNode->mIndex = aIndex;
            mNodes.insert ( mNodes.begin() + aIndex, aNode );
            for ( auto i = mNodes.begin() + aIndex + 1; i != mNodes.end(); ++i )
            {
                ++ ( *i )->mIndex;
            }
            // Force a recalculation of the LOCAL transform
            // by setting the GLOBAL transform to itself.
            aNode->SetGlobalTransform ( aNode->mGlobalTransform );
            aNode->LoopTraverseDFSPreOrder (
                [this] ( const std::shared_ptr<Node>& node )
            {
                if ( auto scene = mScene.lock() )
                {
                    scene->mAllNodes.push_back ( node );
                }
                node->mScene = this->mScene;
            } );
            return true;
        }
        return false;
    }

    bool Node::AddNode ( const std::shared_ptr<Node>& aNode )
    {
        // Never append null or this pointers.
        if ( ( aNode != nullptr ) && ( aNode.get() != this ) && ( std::find ( mNodes.begin(), mNodes.end(), aNode ) == mNodes.end() ) )
        {
            if ( auto parent = aNode->mParent.lock() )
            {
                if ( !parent->RemoveNode ( aNode ) )
                {
                    std::cout << LogLevel ( LogLevel::Level::Warning ) << "Parent for node " << aNode->GetName() << " did not have it as a child.";
                }
            }
            aNode->mParent = shared_from_this();
            aNode->mIndex = mNodes.size();
            mNodes.push_back ( aNode );
            // Force a recalculation of the LOCAL transform
            // by setting the GLOBAL transform to itself.
            aNode->SetGlobalTransform ( aNode->mGlobalTransform );
            aNode->LoopTraverseDFSPreOrder (
                [this] ( const std::shared_ptr<Node>& node )
            {
                if ( auto scene = mScene.lock() )
                {
                    scene->mAllNodes.push_back ( node );
                }
                node->mScene = mScene;
            } );
            return true;
        }
        return false;
    }

    bool Node::RemoveNode ( const std::shared_ptr<Node>& aNode )
    {
        assert ( aNode != nullptr );
        assert ( aNode.get() != this );
        // If passed a null or this pointer find SHOULD not find it on release builds.
        /*  While only a single instance should be found and erase does the element shifting
            we're using remove here to do the shifting in order to stablish
            that the erase-remove idiom is what should be used in these situations.*/
        auto it = std::remove ( mNodes.begin(), mNodes.end(), aNode );
        if ( it != mNodes.end() )
        {
            mNodes.erase ( it );
            for ( auto i = mNodes.begin() + aNode->GetIndex(); i != mNodes.end(); ++i )
            {
                ( *i )->mIndex = i - mNodes.begin();
            }
            aNode->mParent.reset();
            aNode->mIndex = Node::kInvalidIndex;
            // Force recalculation of transforms.
            aNode->SetLocalTransform ( aNode->mGlobalTransform );
            // Remove node from Scene
            if ( auto scene = mScene.lock() )
            {
                auto it = scene->mAllNodes.end();
                aNode->LoopTraverseDFSPostOrder ( [&scene, &it, this] ( const std::shared_ptr<Node>& node )
                {
                    node->mScene.reset();
                    it = std::remove ( scene->mAllNodes.begin(), it, node );
                } );
                if ( it != scene->mAllNodes.end() )
                {
                    scene->mAllNodes.erase ( it, scene->mAllNodes.end() );
                }
            }
            return true;
        }
        return false;
    }

    void Node::LoopTraverseDFSPreOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        /** @todo (EC++ Item 3) This code is the same as the constant overload,
        but can't easily be implemented in terms of that because of aAction's node parameter
        need to also be const.
        */
        auto node = shared_from_this();
        aAction ( node );
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                aAction ( node );
                prev->mIterator++;
            }
            else
            {
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::LoopTraverseDFSPreOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aPreamble, std::function<void ( const std::shared_ptr<Node>& ) > aPostamble )
    {
        /** @todo (EC++ Item 3) This code is the same as the constant overload,
        but can't easily be implemented in terms of that because of aAction's node parameter
        need to also be const.
        */
        auto node = shared_from_this();
        aPreamble ( node );
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                aPreamble ( node );
                prev->mIterator++;
            }
            else
            {
                aPostamble ( node );
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::LoopTraverseDFSPreOrder ( std::function<void ( const std::shared_ptr<const Node>& ) > aAction ) const
    {
        auto node = shared_from_this();
        aAction ( node );
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                aAction ( node );
                prev->mIterator++;
            }
            else
            {
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::LoopTraverseDFSPostOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        /*
        This code implements a similar solution to this stackoverflow answer:
        http://stackoverflow.com/questions/5987867/traversing-a-n-ary-tree-without-using-recurrsion/5988138#5988138
        */
        auto node = shared_from_this();
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                prev->mIterator++;
            }
            else
            {
                aAction ( node );
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::LoopTraverseDFSPostOrder ( std::function<void ( const std::shared_ptr<const Node>& ) > aAction ) const
    {
        /*
        This code implements a similar solution to this stackoverflow answer:
        http://stackoverflow.com/questions/5987867/traversing-a-n-ary-tree-without-using-recurrsion/5988138#5988138
        */
        auto node = shared_from_this();
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                prev->mIterator++;
            }
            else
            {
                aAction ( node );
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::RecursiveTraverseDFSPostOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        for ( auto & mNode : mNodes )
        {
            mNode->RecursiveTraverseDFSPostOrder ( aAction );
        }
        aAction ( shared_from_this() );
    }

    void Node::RecursiveTraverseDFSPreOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        aAction ( shared_from_this() );
        for ( auto & mNode : mNodes )
        {
            mNode->RecursiveTraverseDFSPreOrder ( aAction );
        }
    }

    void Node::LoopTraverseAncestors ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        auto node = shared_from_this();
        while ( node != nullptr )
        {
            aAction ( node );
            node = node->mParent.lock();
        }
    }

    void Node::LoopTraverseAncestors ( std::function<void ( const std::shared_ptr<const Node>& ) > aAction ) const
    {
        auto node = shared_from_this();
        while ( node != nullptr )
        {
            aAction ( node );
            node = node->mParent.lock();
        }
    }

    void Node::RecursiveTraverseAncestors ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        aAction ( shared_from_this() );
        if ( auto parent = mParent.lock() )
        {
            parent->RecursiveTraverseAncestors ( aAction );
        }
    }

    void Node::Update ( const double delta )
    {
        if ( mModelInstance )
        {
            mModelInstance->StepAnimation ( delta );
        }
    }
}
<commit_msg>Fix for bad_weak_ptr coverity issue.<commit_after>/*
Copyright (C) 2014-2017 Rodrigo Jose Hernandez Cordoba

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*! \file
\brief Implementation file for the Scene Node class.
\author Rodrigo Hernandez.
\copy 2014-2016 Rodrigo Hernandez
*/
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <cassert>
#include <algorithm>
#include "aeongames/Node.h"
#include "aeongames/Scene.h"
#include "aeongames/LogLevel.h"
#include "aeongames/ModelInstance.h"

namespace AeonGames
{

    const std::shared_ptr<Node> Node::mNullNode{};
    const size_t Node::kInvalidIndex = std::numeric_limits<size_t>::max(); // Use on VS2013

    Node::Node ( uint32_t aFlags ) :
        mName ( "Node" ),
        mParent{},
        mScene{},
        mLocalTransform(),
        mGlobalTransform(),
        mNodes(),
        mIndex ( kInvalidIndex ),
        mIterator ( 0 ),
        mFlags ( aFlags )
    {
    }

    Node::~Node()
    {
        /* Make sure tree is left in a valid state */
        if ( auto parent = mParent.lock() )
        {
            try
            {
                if ( !parent->RemoveNode ( shared_from_this() ) )
                {
                    std::cerr << "Remove Node Failed" << std::endl;
                }
            }
            catch ( std::bad_weak_ptr e )
            {
                std::cerr << "Remove Node Failed " << e.what() << std::endl;
            }
        }
        else if ( auto scene = mScene.lock() )
        {
            try
            {
                if ( !scene->RemoveNode ( shared_from_this() ) )
                {
                    std::cerr << "Remove Node Failed" << std::endl;
                }
            }
            catch ( std::bad_weak_ptr e )
            {
                std::cerr << "Remove Node Failed " << e.what() << std::endl;
            }
        }
        for ( auto & mNode : mNodes )
        {
            mNode->mParent.reset();
            mNode->mScene.reset();
            mNode.reset();
        }
    }

    size_t Node::GetChildrenCount() const
    {
        return mNodes.size();
    }

    const std::shared_ptr<Node>& Node::GetChild ( size_t aIndex ) const
    {
        if ( aIndex < mNodes.size() )
        {
            return mNodes[aIndex];
        }
        return mNullNode;
    }

    const std::shared_ptr<Node> Node::GetParent() const
    {
        return mParent.lock();
    }

    size_t Node::GetIndex() const
    {
        return mIndex;
    }

    const std::shared_ptr<ModelInstance>& Node::GetModelInstance() const
    {
        return mModelInstance;
    }

    void Node::SetModelInstance ( const std::shared_ptr<ModelInstance>& aModelInstance )
    {
        mModelInstance = aModelInstance;
    }

    void Node::SetFlags ( uint32_t aFlagBits, bool aEnabled )
    {
        ( aEnabled ) ? mFlags |= aFlagBits : mFlags &= static_cast<uint32_t> ( ~aFlagBits );
    }

    void Node::SetFlag ( enum Flags aFlag, bool aEnabled )
    {
        mFlags[aFlag] = aEnabled;
    }

    bool Node::IsFlagEnabled ( enum Flags aFlag ) const
    {
        return mFlags[aFlag];
    }

    const Transform& Node::GetLocalTransform() const
    {
        return mLocalTransform;
    }

    const Transform& Node::GetGlobalTransform() const
    {
        return mGlobalTransform;
    }

    void Node::SetLocalTransform ( const Transform& aTransform )
    {
        mLocalTransform = aTransform;
        LoopTraverseDFSPreOrder (
            [] ( const std::shared_ptr<Node>& node )
        {
            if ( auto parent = node->mParent.lock() )
            {
                parent->mGlobalTransform * node->mLocalTransform;
            }
            else
            {
                node->mGlobalTransform = node->mLocalTransform;
            }
        } );
    }

    void Node::SetGlobalTransform ( const Transform& aTransform )
    {
        mGlobalTransform = aTransform;
        // Update the Local transform for this node only
        if ( auto parent = mParent.lock() )
        {
            mLocalTransform = mGlobalTransform * parent->mGlobalTransform.GetInverted();
        }
        else
        {
            mLocalTransform = mGlobalTransform;
        }
        // Then Update the Global transform for all children
        LoopTraverseDFSPreOrder (
            [this] ( const std::shared_ptr<Node>& node )
        {
            /*! @todo Although this->mLocalTransform has already been computed
                      think about removing the check and let it be recomputed,
                      it may be faster than the branch that needs to run
                      for each node and is false only once.*/
            if ( node.get() != this )
            {
                if ( auto parent = node->mParent.lock() )
                {
                    node->mGlobalTransform = parent->mGlobalTransform * node->mLocalTransform;
                }
            }
        } );
    }

    void Node::SetName ( const std::string& aName )
    {
        mName = aName;
    }

    const std::string& Node::GetName() const
    {
        return mName;
    }

    bool Node::InsertNode ( size_t aIndex, const std::shared_ptr<Node>& aNode )
    {
        // Never append null or this pointers.
        ///@todo std::find might be slower than removing and reinserting an existing node
        if ( ( aNode != nullptr ) && ( aNode.get() != this ) && ( std::find ( mNodes.begin(), mNodes.end(), aNode ) == mNodes.end() ) )
        {
            if ( auto parent = aNode->mParent.lock() )
            {
                if ( !parent->RemoveNode ( aNode ) )
                {
                    std::cout << LogLevel ( LogLevel::Level::Warning ) << "Parent for node " << aNode->GetName() << " did not have it as a child.";
                }
            }
            aNode->mParent = shared_from_this();
            aNode->mIndex = aIndex;
            mNodes.insert ( mNodes.begin() + aIndex, aNode );
            for ( auto i = mNodes.begin() + aIndex + 1; i != mNodes.end(); ++i )
            {
                ++ ( *i )->mIndex;
            }
            // Force a recalculation of the LOCAL transform
            // by setting the GLOBAL transform to itself.
            aNode->SetGlobalTransform ( aNode->mGlobalTransform );
            aNode->LoopTraverseDFSPreOrder (
                [this] ( const std::shared_ptr<Node>& node )
            {
                if ( auto scene = mScene.lock() )
                {
                    scene->mAllNodes.push_back ( node );
                }
                node->mScene = this->mScene;
            } );
            return true;
        }
        return false;
    }

    bool Node::AddNode ( const std::shared_ptr<Node>& aNode )
    {
        // Never append null or this pointers.
        if ( ( aNode != nullptr ) && ( aNode.get() != this ) && ( std::find ( mNodes.begin(), mNodes.end(), aNode ) == mNodes.end() ) )
        {
            if ( auto parent = aNode->mParent.lock() )
            {
                if ( !parent->RemoveNode ( aNode ) )
                {
                    std::cout << LogLevel ( LogLevel::Level::Warning ) << "Parent for node " << aNode->GetName() << " did not have it as a child.";
                }
            }
            aNode->mParent = shared_from_this();
            aNode->mIndex = mNodes.size();
            mNodes.push_back ( aNode );
            // Force a recalculation of the LOCAL transform
            // by setting the GLOBAL transform to itself.
            aNode->SetGlobalTransform ( aNode->mGlobalTransform );
            aNode->LoopTraverseDFSPreOrder (
                [this] ( const std::shared_ptr<Node>& node )
            {
                if ( auto scene = mScene.lock() )
                {
                    scene->mAllNodes.push_back ( node );
                }
                node->mScene = mScene;
            } );
            return true;
        }
        return false;
    }

    bool Node::RemoveNode ( const std::shared_ptr<Node>& aNode )
    {
        assert ( aNode != nullptr );
        assert ( aNode.get() != this );
        // If passed a null or this pointer find SHOULD not find it on release builds.
        /*  While only a single instance should be found and erase does the element shifting
            we're using remove here to do the shifting in order to stablish
            that the erase-remove idiom is what should be used in these situations.*/
        auto it = std::remove ( mNodes.begin(), mNodes.end(), aNode );
        if ( it != mNodes.end() )
        {
            mNodes.erase ( it );
            for ( auto i = mNodes.begin() + aNode->GetIndex(); i != mNodes.end(); ++i )
            {
                ( *i )->mIndex = i - mNodes.begin();
            }
            aNode->mParent.reset();
            aNode->mIndex = Node::kInvalidIndex;
            // Force recalculation of transforms.
            aNode->SetLocalTransform ( aNode->mGlobalTransform );
            // Remove node from Scene
            if ( auto scene = mScene.lock() )
            {
                auto it = scene->mAllNodes.end();
                aNode->LoopTraverseDFSPostOrder ( [&scene, &it, this] ( const std::shared_ptr<Node>& node )
                {
                    node->mScene.reset();
                    it = std::remove ( scene->mAllNodes.begin(), it, node );
                } );
                if ( it != scene->mAllNodes.end() )
                {
                    scene->mAllNodes.erase ( it, scene->mAllNodes.end() );
                }
            }
            return true;
        }
        return false;
    }

    void Node::LoopTraverseDFSPreOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        /** @todo (EC++ Item 3) This code is the same as the constant overload,
        but can't easily be implemented in terms of that because of aAction's node parameter
        need to also be const.
        */
        auto node = shared_from_this();
        aAction ( node );
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                aAction ( node );
                prev->mIterator++;
            }
            else
            {
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::LoopTraverseDFSPreOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aPreamble, std::function<void ( const std::shared_ptr<Node>& ) > aPostamble )
    {
        /** @todo (EC++ Item 3) This code is the same as the constant overload,
        but can't easily be implemented in terms of that because of aAction's node parameter
        need to also be const.
        */
        auto node = shared_from_this();
        aPreamble ( node );
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                aPreamble ( node );
                prev->mIterator++;
            }
            else
            {
                aPostamble ( node );
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::LoopTraverseDFSPreOrder ( std::function<void ( const std::shared_ptr<const Node>& ) > aAction ) const
    {
        auto node = shared_from_this();
        aAction ( node );
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                aAction ( node );
                prev->mIterator++;
            }
            else
            {
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::LoopTraverseDFSPostOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        /*
        This code implements a similar solution to this stackoverflow answer:
        http://stackoverflow.com/questions/5987867/traversing-a-n-ary-tree-without-using-recurrsion/5988138#5988138
        */
        auto node = shared_from_this();
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                prev->mIterator++;
            }
            else
            {
                aAction ( node );
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::LoopTraverseDFSPostOrder ( std::function<void ( const std::shared_ptr<const Node>& ) > aAction ) const
    {
        /*
        This code implements a similar solution to this stackoverflow answer:
        http://stackoverflow.com/questions/5987867/traversing-a-n-ary-tree-without-using-recurrsion/5988138#5988138
        */
        auto node = shared_from_this();
        auto parent = mParent.lock();
        while ( node != parent )
        {
            if ( node->mIterator < node->mNodes.size() )
            {
                auto prev = node;
                node = node->mNodes[node->mIterator];
                prev->mIterator++;
            }
            else
            {
                aAction ( node );
                node->mIterator = 0; // Reset counter for next traversal.
                node = node->mParent.lock();
            }
        }
    }

    void Node::RecursiveTraverseDFSPostOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        for ( auto & mNode : mNodes )
        {
            mNode->RecursiveTraverseDFSPostOrder ( aAction );
        }
        aAction ( shared_from_this() );
    }

    void Node::RecursiveTraverseDFSPreOrder ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        aAction ( shared_from_this() );
        for ( auto & mNode : mNodes )
        {
            mNode->RecursiveTraverseDFSPreOrder ( aAction );
        }
    }

    void Node::LoopTraverseAncestors ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        auto node = shared_from_this();
        while ( node != nullptr )
        {
            aAction ( node );
            node = node->mParent.lock();
        }
    }

    void Node::LoopTraverseAncestors ( std::function<void ( const std::shared_ptr<const Node>& ) > aAction ) const
    {
        auto node = shared_from_this();
        while ( node != nullptr )
        {
            aAction ( node );
            node = node->mParent.lock();
        }
    }

    void Node::RecursiveTraverseAncestors ( std::function<void ( const std::shared_ptr<Node>& ) > aAction )
    {
        aAction ( shared_from_this() );
        if ( auto parent = mParent.lock() )
        {
            parent->RecursiveTraverseAncestors ( aAction );
        }
    }

    void Node::Update ( const double delta )
    {
        if ( mModelInstance )
        {
            mModelInstance->StepAnimation ( delta );
        }
    }
}
<|endoftext|>


<commit_before>#ifndef EXPR_HXX_SPN8H6I7
#define EXPR_HXX_SPN8H6I7

#include "ppr.hxx"
#include "id.hxx"
#include "ptr.hxx"

namespace miniml
{

/// Type of expression.
enum class ExprType
{
  ID,   ///< Identifier
  APP,  ///< Application
  LAM,  ///< Lambda term
  INT,  ///< Integer literal
};

/// Abstract base class for expressions.
class Expr
{
public:
  virtual ~Expr() {}

  /// Get the type of the expression.
  /// \see ExprType
  virtual ExprType type() const = 0;

  /// Pretty print an expression.
  /// \param[in] prec The outermost precedence for inserting brackets.
  /// \related Ppr
  virtual Ptr<Ppr> ppr(unsigned prec = 0) const = 0;
};

/// Identifier expression.
class IdExpr final: public Expr
{
public:
  /// \param[in] id The identifier this expression represents.
  IdExpr(const Ptr<Id> id): m_id(id) {}

  /// \return ExprType::ID
  ExprType type() const { return ExprType::ID; }

  /// \param prec Ignored, since variables are always atomic.
  Ptr<Ppr> ppr(unsigned prec = 0) const;

  const Ptr<const Id> id() const { return m_id; }

private:
  Ptr<Id> m_id;   ///< Identifier value.
};

/// Integer literals.
class IntExpr final: public Expr
{
public:
  /// \param[in] val The value of this literal.
  IntExpr(long val): m_val(val) {}

  /// \return ExprType::INT
  ExprType type() const { return ExprType::INT; }

  /// \param prec Ignored, since literals are always atomic.
  Ptr<Ppr> ppr(unsigned prec = 0) const;

  /// \return The value of this literal.
  long val() const { return m_val; }

private:
  long m_val;
};

/// Application expression.
class AppExpr final: public Expr
{
public:
  AppExpr(const Ptr<Expr> left, const Ptr<Expr> right):
    m_left(left), m_right(right)
  {}

  /// \return ExprType::APP
  ExprType type() const { return ExprType::APP; }

  Ptr<Ppr> ppr(unsigned prec = 0) const;

  /// \return The left part (operator).
  const Ptr<const Expr> left() const { return m_left; }
  /// \return The right part (operand).
  const Ptr<const Expr> right() const { return m_right; }

private:
  Ptr<Expr> m_left;   ///< Operator.
  Ptr<Expr> m_right;  ///< Operand.
};

/// Lambda term (function) expression.
class LamExpr final: public Expr
{
public:
  LamExpr(const Ptr<Id> var, const Ptr<Expr> body):
    m_var(var), m_body(body)
  {}

  /// \return ExprType::LAM
  ExprType type() const { return ExprType::LAM; }

  Ptr<Ppr> ppr(unsigned prec = 0) const;

  /// \return The bound variable.
  const Ptr<const Id> var() const { return m_var; }
  /// \return The body of the term.
  const Ptr<const Expr> body() const { return m_body; }

private:
  Ptr<Id> m_var;      ///< Bound variable.
  Ptr<Expr> m_body;   ///< Body.
};

}

#endif /* end of include guard: EXPR_HXX_SPN8H6I7 */
<commit_msg>Doc for IdExpr::id<commit_after>#ifndef EXPR_HXX_SPN8H6I7
#define EXPR_HXX_SPN8H6I7

#include "ppr.hxx"
#include "id.hxx"
#include "ptr.hxx"

namespace miniml
{

/// Type of expression.
enum class ExprType
{
  ID,   ///< Identifier
  APP,  ///< Application
  LAM,  ///< Lambda term
  INT,  ///< Integer literal
};

/// Abstract base class for expressions.
class Expr
{
public:
  virtual ~Expr() {}

  /// Get the type of the expression.
  /// \see ExprType
  virtual ExprType type() const = 0;

  /// Pretty print an expression.
  /// \param[in] prec The outermost precedence for inserting brackets.
  /// \related Ppr
  virtual Ptr<Ppr> ppr(unsigned prec = 0) const = 0;
};

/// Identifier expression.
class IdExpr final: public Expr
{
public:
  /// \param[in] id The identifier this expression represents.
  IdExpr(const Ptr<Id> id): m_id(id) {}

  /// \return ExprType::ID
  ExprType type() const { return ExprType::ID; }

  /// \param prec Ignored, since variables are always atomic.
  Ptr<Ppr> ppr(unsigned prec = 0) const;

  /// \return The identifier value.
  const Ptr<const Id> id() const { return m_id; }

private:
  Ptr<Id> m_id;   ///< Identifier value.
};

/// Integer literals.
class IntExpr final: public Expr
{
public:
  /// \param[in] val The value of this literal.
  IntExpr(long val): m_val(val) {}

  /// \return ExprType::INT
  ExprType type() const { return ExprType::INT; }

  /// \param prec Ignored, since literals are always atomic.
  Ptr<Ppr> ppr(unsigned prec = 0) const;

  /// \return The value of this literal.
  long val() const { return m_val; }

private:
  long m_val;
};

/// Application expression.
class AppExpr final: public Expr
{
public:
  AppExpr(const Ptr<Expr> left, const Ptr<Expr> right):
    m_left(left), m_right(right)
  {}

  /// \return ExprType::APP
  ExprType type() const { return ExprType::APP; }

  Ptr<Ppr> ppr(unsigned prec = 0) const;

  /// \return The left part (operator).
  const Ptr<const Expr> left() const { return m_left; }
  /// \return The right part (operand).
  const Ptr<const Expr> right() const { return m_right; }

private:
  Ptr<Expr> m_left;   ///< Operator.
  Ptr<Expr> m_right;  ///< Operand.
};

/// Lambda term (function) expression.
class LamExpr final: public Expr
{
public:
  LamExpr(const Ptr<Id> var, const Ptr<Expr> body):
    m_var(var), m_body(body)
  {}

  /// \return ExprType::LAM
  ExprType type() const { return ExprType::LAM; }

  Ptr<Ppr> ppr(unsigned prec = 0) const;

  /// \return The bound variable.
  const Ptr<const Id> var() const { return m_var; }
  /// \return The body of the term.
  const Ptr<const Expr> body() const { return m_body; }

private:
  Ptr<Id> m_var;      ///< Bound variable.
  Ptr<Expr> m_body;   ///< Body.
};

}

#endif /* end of include guard: EXPR_HXX_SPN8H6I7 */
<|endoftext|>


<commit_before>/**
 * Filename: MinMaxSearch.cpp
 *   Author: Igor Makhtes
 *     Date: Dec 12, 2014
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2014
 *
 * 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 <ai-homework2/MinMaxSearch.h>

MinMaxSearch::MinMaxSearch(IGoGameHeuristic* heuristic)
    : heuristic_(heuristic) {
}

const string MinMaxSearch::search(const GoGame& game, int maxSteps, int maxDepth) const {
    string winner = "X";

    GoGame currentGame = game;

    cout << currentGame.getBoard().toString() << endl;

    bool maxPlayer = true;

    while (!currentGame.isFinished() && maxSteps-- != 0) {
        Board::CellPoint bestMove = minimax(currentGame, maxPlayer, maxDepth).first;
        currentGame.makeMove(bestMove.point);
        maxPlayer = !maxPlayer;
        cout << currentGame.getBoard().toString() << endl;
    }

    return currentGame.getWinner();
}

pair<Board::CellPoint, double> MinMaxSearch::minimax(
        const GoGame& game, bool maxPlayer, int depth) const {

    if (depth == 0) {
        double estimate = heuristic_->estimate(game);
        return make_pair(
                Board::CellPoint(0, 0, Board::CellEmpty),
                estimate);
    }

    if (game.isFinished()) {
        double estimation = heuristic_->estimate(game);
        return make_pair(
                Board::CellPoint(0, 0, Board::CellEmpty),
                estimation);
    }

    set<Board::CellPoint> allMoves = game.getAvailableMoves();

    double bestValue;
    Board::CellPoint bestMove(0, 0, Board::CellEmpty);

    if (maxPlayer)
        bestValue = -std::numeric_limits<double>::max();
    else
        bestValue = std::numeric_limits<double>::max();

    for(set<Board::CellPoint>::iterator move = allMoves.begin();
            move != allMoves.end(); ++move) {

        GoGame nextGame = game.simulateMove(move->point);
        cout << nextGame.getBoard().toString() << endl;
        double childValue = minimax(nextGame, !maxPlayer, depth - 1).second;

        if (maxPlayer) {
            if (childValue > bestValue) {
                bestValue = childValue;
                bestMove = *move;
            }
        }
        else
            if (childValue < bestValue) {
                bestValue = childValue;
                bestMove = *move;
            }
    }

    return make_pair(bestMove, bestValue);
}
<commit_msg>redundant prints removed<commit_after>/**
 * Filename: MinMaxSearch.cpp
 *   Author: Igor Makhtes
 *     Date: Dec 12, 2014
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2014
 *
 * 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 <ai-homework2/MinMaxSearch.h>

MinMaxSearch::MinMaxSearch(IGoGameHeuristic* heuristic)
    : heuristic_(heuristic) {
}

const string MinMaxSearch::search(const GoGame& game, int maxSteps, int maxDepth) const {
    string winner = "X";

    GoGame currentGame = game;

    cout << currentGame.getBoard().toString() << endl;

    bool maxPlayer = true;

    while (!currentGame.isFinished() && maxSteps-- != 0) {
        Board::CellPoint bestMove = minimax(currentGame, maxPlayer, maxDepth).first;
        currentGame.makeMove(bestMove.point);
        maxPlayer = !maxPlayer;
        cout << currentGame.getBoard().toString() << endl;
    }

    return currentGame.getWinner();
}

pair<Board::CellPoint, double> MinMaxSearch::minimax(
        const GoGame& game, bool maxPlayer, int depth) const {

    if (depth == 0) {
        double estimate = heuristic_->estimate(game);
        return make_pair(
                Board::CellPoint(0, 0, Board::CellEmpty),
                estimate);
    }

    if (game.isFinished()) {
        double estimation = heuristic_->estimate(game);
        return make_pair(
                Board::CellPoint(0, 0, Board::CellEmpty),
                estimation);
    }

    set<Board::CellPoint> allMoves = game.getAvailableMoves();

    double bestValue;
    Board::CellPoint bestMove(0, 0, Board::CellEmpty);

    if (maxPlayer)
        bestValue = -std::numeric_limits<double>::max();
    else
        bestValue = std::numeric_limits<double>::max();

    for(set<Board::CellPoint>::iterator move = allMoves.begin();
            move != allMoves.end(); ++move) {

        GoGame nextGame = game.simulateMove(move->point);

        double childValue = minimax(nextGame, !maxPlayer, depth - 1).second;

        if (maxPlayer) {
            if (childValue > bestValue) {
                bestValue = childValue;
                bestMove = *move;
            }
        }
        else
            if (childValue < bestValue) {
                bestValue = childValue;
                bestMove = *move;
            }
    }

    return make_pair(bestMove, bestValue);
}
<|endoftext|>


<commit_before>// Filename: p3dMultifileReader.cxx
// Created by:  drose (15Jun09)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#include "p3dMultifileReader.h"
#include "p3dPackage.h"
#include "mkdir_complete.h"

#include <time.h>

#ifdef _WIN32
#include <sys/utime.h>
#include <direct.h>
#define stat _stat
#define utime _utime
#define utimbuf _utimbuf

#else
#include <utime.h>

#endif

// This sequence of bytes begins each Multifile to identify it as a
// Multifile.
const char P3DMultifileReader::_header[] = "pmf\0\n\r";
const size_t P3DMultifileReader::_header_size = 6;

const int P3DMultifileReader::_current_major_ver = 1;
const int P3DMultifileReader::_current_minor_ver = 1;

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::Constructor
//       Access: Public
//  Description:
////////////////////////////////////////////////////////////////////
P3DMultifileReader::
P3DMultifileReader() {
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::extract_all
//       Access: Public
//  Description: Reads the named multifile, and extracts all the
//               expected extractable components within it to the
//               indicated directory.  Returns true on success, false
//               on failure.
//
//               The parameters package, start_progress, and
//               progress_size are provided to make the appropriate
//               status updates on the package's progress callbacks
//               during this operation.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
extract_all(const string &pathname, const string &to_dir,
            P3DPackage *package, double start_progress, double progress_size) {
  if (!read_header(pathname)) {
    return false;
  }

  // Now walk through all of the files, and extract only the ones we
  // expect to encounter.
  size_t num_processed = 0;
  size_t num_expected = _subfiles.size();
  if (package != NULL) {
    num_expected = package->_extracts.size();
  }

  Subfiles::iterator si;
  for (si = _subfiles.begin(); si != _subfiles.end(); ++si) {
    const Subfile &s = (*si);
    if (package != NULL && !package->is_extractable(s._filename)) {
      continue;
    }

    string output_pathname = to_dir + "/" + s._filename;
    if (!mkfile_complete(output_pathname, nout)) {
      return false;
    }

    ofstream out(output_pathname.c_str(), ios::out | ios::binary);
    if (!out) {
      nout << "Unable to write to " << output_pathname << "\n";
      return false;
    }

    if (!extract_subfile(out, s)) {
      return false;
    }

    // Set the timestamp according to the multifile.
    out.close();
    utimbuf utb;
    utb.actime = time(NULL);
    utb.modtime = s._timestamp;
    utime(output_pathname.c_str(), &utb);

    ++num_processed;
    if (package != NULL) {
      double progress = (double)num_processed / (double)num_expected;
      package->report_progress(start_progress + progress * progress_size);
    }
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::extract_one
//       Access: Public
//  Description: Reads the named multifile, and extracts only the
//               named component to the indicated stream.  Returns
//               true on success, false on failure.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
extract_one(const string &pathname, ostream &out, const string &filename) {
  if (!read_header(pathname)) {
    return false;
  }

  // Look for the named component.
  Subfiles::iterator si;
  for (si = _subfiles.begin(); si != _subfiles.end(); ++si) {
    const Subfile &s = (*si);
    if (s._filename == filename) {
      return extract_subfile(out, s);
    }
  }

  nout << "Could not extract " << filename << ": not found.\n";
  return false;
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::read_header
//       Access: Private
//  Description: Opens the named multifile and reads the header
//               information and index, returning true on success,
//               false on failure.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
read_header(const string &pathname) {
  _subfiles.clear();

  _in.open(pathname.c_str(), ios::in | ios::binary);
  if (!_in) {
    nout << "Couldn't open " << pathname << "\n";
    return false;
  }

  char this_header[_header_size];
  _in.seekg(0);
  _in.read(this_header, _header_size);
  if (_in.fail() || _in.gcount() != (unsigned)_header_size) {
    nout
      << "Unable to read Multifile header " << pathname << ".\n";
    return false;
  }

  // Here's a special case: if the multifile begins with a hash
  // character, then we skip at least 6 characters, and continue
  // reading and discarding lines of ASCII text, until we come across
  // a nonempty line that does not begin with a hash character.  This
  // allows a P3D application (which is a multifile) to be run
  // directly on the command line on Unix-based systems.
  if (this_header[0] == '#') {
    int ch = '#';
    while (ch != EOF && ch == '#') {
      // Skip to the end of the line.
      while (ch != EOF && ch != '\n') {
        ch = _in.get();
      }
      // Skip to the first non-whitespace character of the line.
      while (ch != EOF && (isspace(ch) || ch == '\r')) {
        ch = _in.get();
      }
    }

    // Now fill up the header.
    this_header[0] = ch;
    _in.read(this_header + 1, _header_size - 1);
  }

  if (memcmp(this_header, _header, _header_size) != 0) {
    nout << "Failed header check: " << pathname << "\n";
    return false;
  }

  unsigned int major = read_uint16();
  unsigned int minor = read_uint16();
  if (major != _current_major_ver || minor != _current_minor_ver) {
    nout << "Incompatible multifile version: " << pathname << "\n";
    return false;
  }

  unsigned int scale = read_uint32();
  if (scale != 1) {
    nout << "Unsupported scale factor in " << pathname << "\n";
    return false;
  }

  // We don't care about the overall timestamp.
  read_uint32();

  if (!read_index()) {
    nout << "Error reading multifile index\n";
    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::read_index
//       Access: Private
//  Description: Assuming the file stream is positioned at the first
//               record, reads all of the records into the _subfiles
//               list.  Returns true on success, false on failure.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
read_index() {
  unsigned int next_entry = read_uint32();
  if (!_in) {
    return false;
  }
  while (next_entry != 0) {
    Subfile s;
    s._start = read_uint32();
    s._length = read_uint32();
    unsigned int flags = read_uint16();
    if ((flags & 0x18) != 0) {
      // Skip over the uncompressed length.
      read_uint32();
    }

    s._timestamp = read_uint32();
    size_t name_length = read_uint16();
    char *buffer = new char[name_length];
    _in.read(buffer, name_length);

    // The filenames are xored with 0xff just for fun.
    for (size_t ni = 0; ni < name_length; ++ni) {
      buffer[ni] ^= 0xff;
    }

    s._filename = string(buffer, name_length);
    delete[] buffer;

    if (flags == 0) {
      // We can only support subfiles with no particular flags set.
      _subfiles.push_back(s);
    }

    _in.seekg(next_entry);
    next_entry = read_uint32();
    if (!_in) {
      return false;
    }
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::extract_subfile
//       Access: Private
//  Description: Extracts the indicated subfile and writes it to the
//               indicated stream.  Returns true on success, false on
//               failure.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
extract_subfile(ostream &out, const Subfile &s) {
  _in.seekg(s._start);

  static const size_t buffer_size = 1024;
  char buffer[buffer_size];

  size_t remaining_data = s._length;
  _in.read(buffer, min(buffer_size, remaining_data));
  size_t count = _in.gcount();
  while (count != 0) {
    remaining_data -= count;
    out.write(buffer, count);
    _in.read(buffer, min(buffer_size, remaining_data));
    count = _in.gcount();
  }

  if (remaining_data != 0) {
    nout << "Unable to extract " << s._filename << "\n";
    return false;
  }

  return true;
}

<commit_msg>consistent code with panda<commit_after>// Filename: p3dMultifileReader.cxx
// Created by:  drose (15Jun09)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#include "p3dMultifileReader.h"
#include "p3dPackage.h"
#include "mkdir_complete.h"

#include <time.h>

#ifdef _WIN32
#include <sys/utime.h>
#include <direct.h>
#define stat _stat
#define utime _utime
#define utimbuf _utimbuf

#else
#include <utime.h>

#endif

// This sequence of bytes begins each Multifile to identify it as a
// Multifile.
const char P3DMultifileReader::_header[] = "pmf\0\n\r";
const size_t P3DMultifileReader::_header_size = 6;

const int P3DMultifileReader::_current_major_ver = 1;
const int P3DMultifileReader::_current_minor_ver = 1;

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::Constructor
//       Access: Public
//  Description:
////////////////////////////////////////////////////////////////////
P3DMultifileReader::
P3DMultifileReader() {
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::extract_all
//       Access: Public
//  Description: Reads the named multifile, and extracts all the
//               expected extractable components within it to the
//               indicated directory.  Returns true on success, false
//               on failure.
//
//               The parameters package, start_progress, and
//               progress_size are provided to make the appropriate
//               status updates on the package's progress callbacks
//               during this operation.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
extract_all(const string &pathname, const string &to_dir,
            P3DPackage *package, double start_progress, double progress_size) {
  if (!read_header(pathname)) {
    return false;
  }

  // Now walk through all of the files, and extract only the ones we
  // expect to encounter.
  size_t num_processed = 0;
  size_t num_expected = _subfiles.size();
  if (package != NULL) {
    num_expected = package->_extracts.size();
  }

  Subfiles::iterator si;
  for (si = _subfiles.begin(); si != _subfiles.end(); ++si) {
    const Subfile &s = (*si);
    if (package != NULL && !package->is_extractable(s._filename)) {
      continue;
    }

    string output_pathname = to_dir + "/" + s._filename;
    if (!mkfile_complete(output_pathname, nout)) {
      return false;
    }

    ofstream out(output_pathname.c_str(), ios::out | ios::binary);
    if (!out) {
      nout << "Unable to write to " << output_pathname << "\n";
      return false;
    }

    if (!extract_subfile(out, s)) {
      return false;
    }

    // Set the timestamp according to the multifile.
    out.close();
    utimbuf utb;
    utb.actime = time(NULL);
    utb.modtime = s._timestamp;
    utime(output_pathname.c_str(), &utb);

    ++num_processed;
    if (package != NULL) {
      double progress = (double)num_processed / (double)num_expected;
      package->report_progress(start_progress + progress * progress_size);
    }
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::extract_one
//       Access: Public
//  Description: Reads the named multifile, and extracts only the
//               named component to the indicated stream.  Returns
//               true on success, false on failure.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
extract_one(const string &pathname, ostream &out, const string &filename) {
  if (!read_header(pathname)) {
    return false;
  }

  // Look for the named component.
  Subfiles::iterator si;
  for (si = _subfiles.begin(); si != _subfiles.end(); ++si) {
    const Subfile &s = (*si);
    if (s._filename == filename) {
      return extract_subfile(out, s);
    }
  }

  nout << "Could not extract " << filename << ": not found.\n";
  return false;
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::read_header
//       Access: Private
//  Description: Opens the named multifile and reads the header
//               information and index, returning true on success,
//               false on failure.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
read_header(const string &pathname) {
  _subfiles.clear();

  _in.open(pathname.c_str(), ios::in | ios::binary);
  if (!_in) {
    nout << "Couldn't open " << pathname << "\n";
    return false;
  }

  char this_header[_header_size];
  _in.seekg(0);

  // Here's a special case: if the multifile begins with a hash
  // character, then we continue reading and discarding lines of ASCII
  // text, until we come across a nonempty line that does not begin
  // with a hash character.  This allows a P3D application (which is a
  // multifile) to be run directly on the command line on Unix-based
  // systems.
  int ch = _in.get();

  if (ch == '#') {
    while (ch != EOF && ch == '#') {
      // Skip to the end of the line.
      while (ch != EOF && ch != '\n') {
        ch = _in.get();
      }
      // Skip to the first non-whitespace character of the line.
      while (ch != EOF && (isspace(ch) || ch == '\r')) {
        ch = _in.get();
      }
    }
  }

  // Now read the actual Multifile header.
  this_header[0] = ch;
  _in.read(this_header + 1, _header_size - 1);
  if (_in.fail() || _in.gcount() != (unsigned)(_header_size - 1)) {
    nout << "Unable to read Multifile header: " << pathname << "\n";
    return false;
  }

  if (memcmp(this_header, _header, _header_size) != 0) {
    nout << "Failed header check: " << pathname << "\n";
    return false;
  }

  unsigned int major = read_uint16();
  unsigned int minor = read_uint16();
  if (major != _current_major_ver || minor != _current_minor_ver) {
    nout << "Incompatible multifile version: " << pathname << "\n";
    return false;
  }

  unsigned int scale = read_uint32();
  if (scale != 1) {
    nout << "Unsupported scale factor in " << pathname << "\n";
    return false;
  }

  // We don't care about the overall timestamp.
  read_uint32();

  if (!read_index()) {
    nout << "Error reading multifile index\n";
    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::read_index
//       Access: Private
//  Description: Assuming the file stream is positioned at the first
//               record, reads all of the records into the _subfiles
//               list.  Returns true on success, false on failure.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
read_index() {
  unsigned int next_entry = read_uint32();
  if (!_in) {
    return false;
  }
  while (next_entry != 0) {
    Subfile s;
    s._start = read_uint32();
    s._length = read_uint32();
    unsigned int flags = read_uint16();
    if ((flags & 0x18) != 0) {
      // Skip over the uncompressed length.
      read_uint32();
    }

    s._timestamp = read_uint32();
    size_t name_length = read_uint16();
    char *buffer = new char[name_length];
    _in.read(buffer, name_length);

    // The filenames are xored with 0xff just for fun.
    for (size_t ni = 0; ni < name_length; ++ni) {
      buffer[ni] ^= 0xff;
    }

    s._filename = string(buffer, name_length);
    delete[] buffer;

    if (flags == 0) {
      // We can only support subfiles with no particular flags set.
      _subfiles.push_back(s);
    }

    _in.seekg(next_entry);
    next_entry = read_uint32();
    if (!_in) {
      return false;
    }
  }

  return true;
}

////////////////////////////////////////////////////////////////////
//     Function: P3DMultifileReader::extract_subfile
//       Access: Private
//  Description: Extracts the indicated subfile and writes it to the
//               indicated stream.  Returns true on success, false on
//               failure.
////////////////////////////////////////////////////////////////////
bool P3DMultifileReader::
extract_subfile(ostream &out, const Subfile &s) {
  _in.seekg(s._start);

  static const size_t buffer_size = 1024;
  char buffer[buffer_size];

  size_t remaining_data = s._length;
  _in.read(buffer, min(buffer_size, remaining_data));
  size_t count = _in.gcount();
  while (count != 0) {
    remaining_data -= count;
    out.write(buffer, count);
    _in.read(buffer, min(buffer_size, remaining_data));
    count = _in.gcount();
  }

  if (remaining_data != 0) {
    nout << "Unable to extract " << s._filename << "\n";
    return false;
  }

  return true;
}

<|endoftext|>