<commit_before>// This file may be redistributed and modified under the terms of the
// GNU Lesser General Public License (See COPYING for details).
// Copyright (C) 2002 Michael Koch <konqueror@gmx.de>

#include "Bach.h"

namespace Atlas { namespace Codecs {

Bach::Bach(std::iostream& s, Atlas::Bridge* b)
    : m_socket(s)
    , m_bridge(b)
    , m_comma( false )
{
    m_state.push(PARSE_STREAM);
}

void Bach::parseStream(char next)
{
    cout << "parseStream" << endl;

    switch (next)
    {
    case '[':
        m_bridge->streamMessage(m_mapBegin);
        m_state.push(PARSE_MAP);
        break;

    default:
        cout << "parseStream: unexpected character : " << next << endl;
        // FIXME signal error here
        // unexpected character
        break;
    }
}

void Bach::parseMap(char next)
{
    cout << "parseMap" << endl;

    switch (next)
    {
    case '}':
        m_bridge->mapEnd();
        m_state.pop();
        break;

    case '{':
        m_state.push(PARSE_MAP);
        m_state.push(PARSE_MAP_BEGIN);
        m_state.push(PARSE_DATA);
        m_state.push(PARSE_NAME);
        break;

    case '[':
        m_state.push(PARSE_LIST);
        m_state.push(PARSE_LIST_BEGIN);
        m_state.push(PARSE_DATA);
        m_state.push(PARSE_NAME);
        break;

    case ',':
        break;

    default:
        if (((next>='a')&&(next<='z'))||
            ((next>='A')&&(next<='Z')))
        {
            m_socket.putback(next);
            m_state.push(PARSE_DATA);
            m_state.push(PARSE_NAME);
        }
        else
        {
            cout << "parseMap: unexpected character: " << next << endl;
            // FIXME signal error here
            // unexpected character
        }
        break;
    }
}

void Bach::parseList(char next)
{
    cout << "parseList" << endl;

    switch (next)
    {
    case ']':
        m_bridge->listEnd();
        m_state.pop();
        break;

    case '{':
        m_bridge->listItem(m_mapBegin);
        m_state.push(PARSE_MAP);
        m_state.push(PARSE_NAME);
        m_state.push(PARSE_DATA);
        break;

    case '[':
        m_bridge->listItem(m_listBegin);
        m_state.push(PARSE_LIST);
        m_state.push(PARSE_DATA);
        break;

    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '0':
    case '-':
        m_state.push(PARSE_FLOAT);
        m_socket.putback(next);
        break;

    default:
        cout << "parseMap: unexpected character: " << next << endl;
        // FIXME signal error here
        // unexpected character
        break;
    }
}

void Bach::parseMapBegin(char next)
{
    cout << "parseMapBegin" << endl;

    m_bridge->mapItem(decodeString(m_name), m_mapBegin);
    m_socket.putback(next);
    m_state.pop();
    m_name.erase();
}

void Bach::parseListBegin(char next)
{
    cout << "parseListBegin" << endl;

    m_bridge->mapItem(decodeString(m_name), m_listBegin);
    m_socket.putback(next);
    m_state.pop();
    m_name.erase();
}

void Bach::parseInt(char next)
{
    cout << "parseInt" << endl;
}

void Bach::parseFloat(char next)
{
    cout << "parseFloat" << endl;

    switch (next)
    {
    case '[':
    case ']':
    case '(':
    case ')':
    case ',':
        m_socket.putback(next);
        m_state.pop();
        if (m_state.top() == PARSE_MAP_BEGIN)
        {
            cout << "Float: " << m_data << endl;

            m_bridge->mapItem(decodeString(m_name), atof(m_data.c_str()));
            m_name.erase();
        }
        else if (m_state.top() == PARSE_LIST_BEGIN)
        {
            cout << "Float: " << m_data << endl;

            m_bridge->listItem(atof(m_data.c_str()));
        }
        else
        {
            cout << "Bach::parseFloat: Error: " << m_state.top() << endl;
            // FIXME some kind of sanity checking assertion here
        }
        m_data.erase();
	break;

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '.':
    case '-':
    case '+':
    case 'e':
    case 'E':
        m_data += next;
	break;

    default:
        cout << "parseFloat: unexpected character: " << next << endl;
        // FIXME signal error here
        // unexpected character
	break;
    }
}

void Bach::parseString(char next)
{
    cout << "parseString" << endl;

    switch (next)
    {
    case '\"':
        m_state.pop();
        if (m_state.top() == PARSE_MAP)
        {
            cout << "String: " << m_data << endl;

            m_bridge->mapItem(decodeString(m_name), decodeString(m_data));
            m_name.erase();
        }
        else if (m_state.top() == PARSE_LIST)
        {
            cout << "String: " << m_data << endl;

            m_bridge->listItem(decodeString(m_data));
        }
        else
        {
            // FIXME some kind of sanity checking assertion here
        }
        m_data.erase();
        break;

/*
    case '\\':
        // FIXME escape signs
        break;
*/

    default:
        m_data += next;
        break;
    }
}

void Bach::parseData(char next)
{
    cout << "parseData" << endl;

    switch (next)
    {
    case '-':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '0':
        m_socket.putback(next);
        m_state.pop();
        m_state.push(PARSE_FLOAT);
        break;

    case '{':
        m_state.pop();
        m_state.push(PARSE_MAP);
        m_state.push(PARSE_NAME);
        m_state.push(PARSE_DATA);
        break;

    case '[':
        m_state.pop();
        m_state.push(PARSE_LIST);
        m_state.push(PARSE_DATA);
        break;

    case '\"':
        m_state.pop();
        m_state.push(PARSE_STRING);
        break;

    case ',':
        break;

    default:
        cout << "parseData: unexpected character: " << next << endl;
        break;
    }
}

void Bach::parseName(char next)
{
    cout << "parseName" << endl;

    switch (next)
    {
    case ':':
        cout << "Name: " << m_name << endl;
        m_state.pop();
	break;

/*
    case '[':
    case ']':
    case '(':
    case ')':
    case ',':
        // FIXME signal error here
        // unexpected character
	break;
*/

    default:
        if (((next>='a')&&(next<='z'))||
            ((next>='A')&&(next<='Z'))||
            ((next>='0')&&(next<='9')))
        {
            m_name += next;
        }
        else
        {
            cout << "parseName: unexpected character: " << next << endl;
            // FIXME signal error here
            // unexpected character
        }
	break;
    }
}

void Bach::poll(bool can_read)
{
    if (!can_read) return;
    do
    {
	char next = (char) m_socket.get();

        cout << "Character: " << next << "   ";

        switch (m_state.top())
	{
        case PARSE_STREAM:     parseStream(next); break;
        case PARSE_MAP:        parseMap(next); break;
        case PARSE_LIST:       parseList(next); break;
        case PARSE_MAP_BEGIN:  parseMapBegin(next); break;
        case PARSE_LIST_BEGIN: parseListBegin(next); break;
        case PARSE_DATA:       parseData(next); break;
        case PARSE_INT:	       parseInt(next); break;
        case PARSE_FLOAT:      parseFloat(next); break;
        case PARSE_STRING:     parseString(next); break;
        case PARSE_NAME:       parseName(next); break;
	}
    }
    while (m_socket.rdbuf()->in_avail());
}

const std::string Bach::decodeString(std::string toDecode)
{
    unsigned int pos;

//    while((pos = toDecode.find( "\\\"" )) >= 0)
//          toDecode.replace(pos, 2, "\"");

//    while((pos = toDecode.find( "\\\\")) >= 0)
//          toDecode.replace(pos, 2, "\\");

    return toDecode;
}

const std::string Bach::encodeString(std::string toEncode)
{
    int pos;

    while ((pos = toEncode.find ( '\\' )) >= 0)
	toEncode.replace( pos, 1, "\\\\" );

    while ((pos = toEncode.find ( '\"' )) >= 0)
	toEncode.replace( pos, 1, "\\\"" );

    return toEncode;
}

void Bach::writeItem(std::string name, long data)
{
    if( m_comma )
	m_socket << ",";

    if( name != "" )
	m_socket << name << ":";

    m_socket << data;
}

void Bach::writeItem(std::string name, double data)
{
    if( m_comma )
	m_socket << ",";

    if( name != "" )
	m_socket << name << ":";

    m_socket << data;
}

void Bach::writeItem(std::string name, std::string data)
{
    if( m_comma )
	m_socket << ",";

    if( name != "" )
	m_socket << name << ":";

    m_socket << "\"" << encodeString( data ) << "\"";
}

void Bach::writeLine(std::string line, bool endline, bool endtag)
{
    if (m_comma && !endtag)
	m_socket << ",";

    m_socket << line;
}

void Bach::streamBegin()
{
    writeLine( "[" );
    m_comma = false;
}

void Bach::streamEnd()
{
    writeLine( "]", true, true );
}

void Bach::streamMessage(const Map&)
{
    writeLine( "{" );
    m_comma = false;
}

void Bach::mapItem(const std::string& name, const Map&)
{
    writeLine( name + ":{" );
    m_comma = false;
}

void Bach::mapItem(const std::string& name, const List&)
{
    writeLine( name + ":[" );
    m_comma = false;
}

void Bach::mapItem(const std::string& name, long data)
{
    writeItem( name, data );
    m_comma = true;
}

void Bach::mapItem(const std::string& name, double data)
{
    writeItem( name, data );
    m_comma = true;
}

void Bach::mapItem(const std::string& name, const std::string& data)
{
    writeItem( name, data );
    m_comma = true;
}

void Bach::mapEnd()
{
    writeLine( "}", true, true );
    m_comma = true;
}

void Bach::listItem(const Map&)
{
    writeLine( "{" );
    m_comma = false;
}

void Bach::listItem(const List&)
{
    writeLine( "[" );
    m_comma = false;
}

void Bach::listItem(long data)
{
    writeItem( "", data );
    m_comma = true;
}

void Bach::listItem(double data)
{
    writeItem( "", data );
    m_comma = true;
}

void Bach::listItem(const std::string& data)
{
    writeItem( "", data );
    m_comma = true;
}

void Bach::listEnd()
{
    writeLine( "]", true, true );
    m_comma = true;
}

} } //namespace Atlas::Codecs
<commit_msg>another step on the ladder to a working codec<commit_after>// This file may be redistributed and modified under the terms of the
// GNU Lesser General Public License (See COPYING for details).
// Copyright (C) 2002 Michael Koch <konqueror@gmx.de>

#include "Bach.h"

namespace Atlas { namespace Codecs {

Bach::Bach(std::iostream& s, Atlas::Bridge* b)
    : m_socket(s)
    , m_bridge(b)
    , m_comma( false )
{
    m_state.push(PARSE_INIT);
}

void Bach::parseInit(char next)
{
    cout << "parseInit" << endl;

    if (next=='{')
    {
        m_bridge->streamBegin();
        m_socket.putback(next);
        m_state.push(PARSE_STREAM);
    }
}

void Bach::parseStream(char next)
{
    cout << "parseStream" << endl;

    switch (next)
    {
    case '{':
        m_bridge->streamMessage(m_mapBegin);
        m_state.push(PARSE_MAP);
        break;

    case ',':
        break;

    case ']':
        m_bridge->streamEnd();
        break;

    default:
        cout << "parseStream: unexpected character : " << next << endl;
        // FIXME signal error here
        // unexpected character
        break;
    }
}

void Bach::parseMap(char next)
{
    cout << "parseMap" << endl;

    switch (next)
    {
    case '}':
        m_bridge->mapEnd();
        m_state.pop();
        break;

    case '{':
        m_state.push(PARSE_MAP);
        m_state.push(PARSE_MAP_BEGIN);
        m_state.push(PARSE_DATA);
        m_state.push(PARSE_NAME);
        break;

    case '[':
        m_state.push(PARSE_LIST);
        m_state.push(PARSE_LIST_BEGIN);
        m_state.push(PARSE_DATA);
        m_state.push(PARSE_NAME);
        break;

    case ',':
        break;

    default:
        if (((next>='a')&&(next<='z'))||
            ((next>='A')&&(next<='Z')))
        {
            m_socket.putback(next);
            m_state.push(PARSE_DATA);
            m_state.push(PARSE_NAME);
        }
        else
        {
            cout << "parseMap: unexpected character: " << next << endl;
            // FIXME signal error here
            // unexpected character
        }
        break;
    }
}

void Bach::parseList(char next)
{
    cout << "parseList" << endl;

    switch (next)
    {
    case ']':
        m_bridge->listEnd();
        m_state.pop();
        break;

    case '{':
        m_bridge->listItem(m_mapBegin);
        m_state.push(PARSE_MAP);
        m_state.push(PARSE_NAME);
        m_state.push(PARSE_DATA);
        break;

    case '[':
        m_bridge->listItem(m_listBegin);
        m_state.push(PARSE_LIST);
        m_state.push(PARSE_DATA);
        break;

    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '0':
    case '-':
        m_state.push(PARSE_FLOAT);
        m_socket.putback(next);
        break;

    default:
        cout << "parseMap: unexpected character: " << next << endl;
        // FIXME signal error here
        // unexpected character
        break;
    }
}

void Bach::parseMapBegin(char next)
{
    cout << "parseMapBegin" << endl;

    m_bridge->mapItem(decodeString(m_name), m_mapBegin);
    m_socket.putback(next);
    m_state.pop();
    m_name.erase();
}

void Bach::parseListBegin(char next)
{
    cout << "parseListBegin" << endl;

    m_bridge->mapItem(decodeString(m_name), m_listBegin);
    m_socket.putback(next);
    m_state.pop();
    m_name.erase();
}

void Bach::parseInt(char next)
{
    cout << "parseInt" << endl;
}

void Bach::parseFloat(char next)
{
    cout << "parseFloat" << endl;

    switch (next)
    {
    case '[':
    case ']':
    case '(':
    case ')':
    case ',':
        m_socket.putback(next);
        m_state.pop();
        if (m_state.top() == PARSE_MAP)
        {
            cout << "Float: " << m_data << endl;

            m_bridge->mapItem(decodeString(m_name), atof(m_data.c_str()));
            m_name.erase();
        }
        else if (m_state.top() == PARSE_LIST)
        {
            cout << "Float: " << m_data << endl;

            m_bridge->listItem(atof(m_data.c_str()));
        }
        else
        {
            cout << "Bach::parseFloat: Error: " << m_state.top() << endl;
            // FIXME some kind of sanity checking assertion here
        }
        m_data.erase();
	break;

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '.':
    case '-':
    case '+':
    case 'e':
    case 'E':
        m_data += next;
	break;

    default:
        cout << "parseFloat: unexpected character: " << next << endl;
        // FIXME signal error here
        // unexpected character
	break;
    }
}

void Bach::parseString(char next)
{
    cout << "parseString" << endl;

    switch (next)
    {
    case '\"':
        m_state.pop();
        if (m_state.top() == PARSE_MAP)
        {
            cout << "String: " << m_data << endl;

            m_bridge->mapItem(decodeString(m_name), decodeString(m_data));
            m_name.erase();
        }
        else if (m_state.top() == PARSE_LIST)
        {
            cout << "String: " << m_data << endl;

            m_bridge->listItem(decodeString(m_data));
        }
        else
        {
            // FIXME some kind of sanity checking assertion here
        }
        m_data.erase();
        break;

/*
    case '\\':
        // FIXME escape signs
        break;
*/

    default:
        m_data += next;
        break;
    }
}

void Bach::parseData(char next)
{
    cout << "parseData" << endl;

    switch (next)
    {
    case '-':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '0':
        m_socket.putback(next);
        m_state.pop();
        m_state.push(PARSE_FLOAT);
        break;

    case '{':
        m_state.pop();
        m_state.push(PARSE_MAP);
        m_state.push(PARSE_NAME);
        m_state.push(PARSE_DATA);
        break;

    case '[':
        m_state.pop();
        m_state.push(PARSE_LIST);
        m_state.push(PARSE_DATA);
        break;

    case '\"':
        m_state.pop();
        m_state.push(PARSE_STRING);
        break;

    case ',':
        break;

    default:
        cout << "parseData: unexpected character: " << next << endl;
        break;
    }
}

void Bach::parseName(char next)
{
    cout << "parseName" << endl;

    switch (next)
    {
    case ':':
        cout << "Name: " << m_name << endl;
        m_state.pop();
	break;

/*
    case '[':
    case ']':
    case '(':
    case ')':
    case ',':
        // FIXME signal error here
        // unexpected character
	break;
*/

    default:
        if (((next>='a')&&(next<='z'))||
            ((next>='A')&&(next<='Z'))||
            ((next>='0')&&(next<='9')))
        {
            m_name += next;
        }
        else
        {
            cout << "parseName: unexpected character: " << next << endl;
            // FIXME signal error here
            // unexpected character
        }
	break;
    }
}

void Bach::poll(bool can_read)
{
    if (!can_read) return;
    do
    {
	char next = (char) m_socket.get();

        cout << "Character: " << next << "   ";

        switch (m_state.top())
	{
        case PARSE_INIT:       parseInit(next); break;
        case PARSE_STREAM:     parseStream(next); break;
        case PARSE_MAP:        parseMap(next); break;
        case PARSE_LIST:       parseList(next); break;
        case PARSE_MAP_BEGIN:  parseMapBegin(next); break;
        case PARSE_LIST_BEGIN: parseListBegin(next); break;
        case PARSE_DATA:       parseData(next); break;
        case PARSE_INT:	       parseInt(next); break;
        case PARSE_FLOAT:      parseFloat(next); break;
        case PARSE_STRING:     parseString(next); break;
        case PARSE_NAME:       parseName(next); break;
	}
    }
    while (m_socket.rdbuf()->in_avail());
}

const std::string Bach::decodeString(std::string toDecode)
{
    unsigned int pos;

//    while((pos = toDecode.find( "\\\"" )) >= 0)
//          toDecode.replace(pos, 2, "\"");

//    while((pos = toDecode.find( "\\\\")) >= 0)
//          toDecode.replace(pos, 2, "\\");

    return toDecode;
}

const std::string Bach::encodeString(std::string toEncode)
{
    int pos;

    while ((pos = toEncode.find ( '\\' )) >= 0)
	toEncode.replace( pos, 1, "\\\\" );

    while ((pos = toEncode.find ( '\"' )) >= 0)
	toEncode.replace( pos, 1, "\\\"" );

    return toEncode;
}

void Bach::writeItem(std::string name, long data)
{
    if( m_comma )
	m_socket << ",";

    if( name != "" )
	m_socket << name << ":";

    m_socket << data;
}

void Bach::writeItem(std::string name, double data)
{
    if( m_comma )
	m_socket << ",";

    if( name != "" )
	m_socket << name << ":";

    m_socket << data;
}

void Bach::writeItem(std::string name, std::string data)
{
    if( m_comma )
	m_socket << ",";

    if( name != "" )
	m_socket << name << ":";

    m_socket << "\"" << encodeString( data ) << "\"";
}

void Bach::writeLine(std::string line, bool endline, bool endtag)
{
    if (m_comma && !endtag)
	m_socket << ",";

    m_socket << line;
}

void Bach::streamBegin()
{
    writeLine( "[" );
    m_comma = false;
}

void Bach::streamEnd()
{
    writeLine( "]", true, true );
}

void Bach::streamMessage(const Map&)
{
    writeLine( "{" );
    m_comma = false;
}

void Bach::mapItem(const std::string& name, const Map&)
{
    writeLine( name + ":{" );
    m_comma = false;
}

void Bach::mapItem(const std::string& name, const List&)
{
    writeLine( name + ":[" );
    m_comma = false;
}

void Bach::mapItem(const std::string& name, long data)
{
    writeItem( name, data );
    m_comma = true;
}

void Bach::mapItem(const std::string& name, double data)
{
    writeItem( name, data );
    m_comma = true;
}

void Bach::mapItem(const std::string& name, const std::string& data)
{
    writeItem( name, data );
    m_comma = true;
}

void Bach::mapEnd()
{
    writeLine( "}", true, true );
    m_comma = true;
}

void Bach::listItem(const Map&)
{
    writeLine( "{" );
    m_comma = false;
}

void Bach::listItem(const List&)
{
    writeLine( "[" );
    m_comma = false;
}

void Bach::listItem(long data)
{
    writeItem( "", data );
    m_comma = true;
}

void Bach::listItem(double data)
{
    writeItem( "", data );
    m_comma = true;
}

void Bach::listItem(const std::string& data)
{
    writeItem( "", data );
    m_comma = true;
}

void Bach::listEnd()
{
    writeLine( "]", true, true );
    m_comma = true;
}

} } //namespace Atlas::Codecs
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: statusbarmanager.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 11:05:37 $
 *
 *  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 __FRAMEWORK_UIELEMENT_STATUSBARMANAGER_HXX_
#define __FRAMEWORK_UIELEMENT_STATUSBARMANAGER_HXX_

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
#include <threadhelp/threadhelpbase.hxx>
#endif
#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif
#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/xinterface.hxx>
#endif
#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif
#ifndef __FRAMEWORK_STDTYPES_H_
#include <stdtypes.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XSTATUSLISTENER_HPP_
#include <com/sun/star/frame/XStatusListener.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XUICONTROLLERREGISTRATION_HPP_
#include <com/sun/star/frame/XUIControllerRegistration.hpp>
#endif
#ifndef _COM_SUN_STAR_UI_XUICONFIGURATION_HPP_
#include <com/sun/star/ui/XUIConfiguration.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
#include <com/sun/star/frame/XModuleManager.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#include <vcl/status.hxx>

namespace framework
{

class FrameworkStatusBar;
class StatusBarManager : public ::com::sun::star::frame::XFrameActionListener         ,
                         public ::com::sun::star::lang::XComponent                    ,
                         public ::com::sun::star::lang::XTypeProvider                 ,
                         public ::com::sun::star::ui::XUIConfigurationListener,
                         public ThreadHelpBase                                        ,
                         public ::cppu::OWeakObject
{
    friend class FrameworkStatusBar;

    public:
        StatusBarManager( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rServicveManager,
                          const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& rFrame,
                          const rtl::OUString& rResourceName,
                          StatusBar* pStatusBar );
        virtual ~StatusBarManager();

        //  XInterface, XTypeProvider, XServiceInfo
        FWK_DECLARE_XINTERFACE
        FWK_DECLARE_XTYPEPROVIDER

        StatusBar* GetStatusBar() const;

        // XFrameActionListener
        virtual void SAL_CALL frameAction( const com::sun::star::frame::FrameActionEvent& Action ) throw ( ::com::sun::star::uno::RuntimeException );

        // XEventListener
        virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& Source ) throw ( ::com::sun::star::uno::RuntimeException );

        // XUIConfigurationListener
        virtual void SAL_CALL elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);

        // XComponent
        void SAL_CALL dispose() throw ( ::com::sun::star::uno::RuntimeException );
        void SAL_CALL addEventListener( const com::sun::star::uno::Reference< XEventListener >& xListener ) throw( com::sun::star::uno::RuntimeException );
        void SAL_CALL removeEventListener( const com::sun::star::uno::Reference< XEventListener >& xListener ) throw( com::sun::star::uno::RuntimeException );

        void FillStatusBar( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& rStatusBarData );

    protected:
        void StateChanged( StateChangedType nType );
        void DataChanged( const DataChangedEvent& rDCEvt );
        void UserDraw( const UserDrawEvent& rUDEvt );
        void Command( const CommandEvent& rEvt );
        DECL_LINK( Click, StatusBar* );
        DECL_LINK( DoubleClick, StatusBar* );

        void RemoveControllers();
        rtl::OUString RetrieveLabelFromCommand( const rtl::OUString& aCmdURL );
        void CreateControllers();
        void UpdateControllers();
        void AddFrameActionListener();

    protected:
        typedef std::vector< ::com::sun::star::uno::Reference< com::sun::star::frame::XStatusListener > > StatusBarControllerVector;

        sal_Bool                                                                                m_bDisposed : 1,
                                                                                m_bModuleIdentified : 1,
                                                                                m_bFrameActionRegistered : 1,
                                                                                m_bUpdateControllers : 1;
        StatusBar*                                                                                m_pStatusBar;
        rtl::OUString                                                                                m_aModuleIdentifier;
        rtl::OUString                                                                                m_aResourceName;
        com::sun::star::uno::Reference< com::sun::star::frame::XFrame >                                 m_xFrame;
        com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >                        m_xUICommandLabels;
        StatusBarControllerVector                                                                       m_aControllerVector;
        ::cppu::OMultiTypeInterfaceContainerHelper                                                      m_aListenerContainer;   /// container for ALL Listener
        ::com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >                  m_xServiceManager;
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XUIControllerRegistration >  m_xStatusbarControllerRegistration;
};

}

#endif // __FRAMEWORK_UIELEMENT_STATUSBARMANAGER_HXX_
<commit_msg>INTEGRATION: CWS pages01_DEV300 (1.6.260); FILE MERGED 2007/12/10 08:18:57 fme 1.6.260.1: #i84413# SfxStatusBarControl::mouseButtonDown not called<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: statusbarmanager.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-07 14:32:01 $
 *
 *  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 __FRAMEWORK_UIELEMENT_STATUSBARMANAGER_HXX_
#define __FRAMEWORK_UIELEMENT_STATUSBARMANAGER_HXX_

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
#include <threadhelp/threadhelpbase.hxx>
#endif
#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif
#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/xinterface.hxx>
#endif
#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif
#ifndef __FRAMEWORK_STDTYPES_H_
#include <stdtypes.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XSTATUSLISTENER_HPP_
#include <com/sun/star/frame/XStatusListener.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XUICONTROLLERREGISTRATION_HPP_
#include <com/sun/star/frame/XUIControllerRegistration.hpp>
#endif
#ifndef _COM_SUN_STAR_UI_XUICONFIGURATION_HPP_
#include <com/sun/star/ui/XUIConfiguration.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
#include <com/sun/star/frame/XModuleManager.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#include <vcl/status.hxx>

namespace framework
{

class FrameworkStatusBar;
class StatusBarManager : public ::com::sun::star::frame::XFrameActionListener         ,
                         public ::com::sun::star::lang::XComponent                    ,
                         public ::com::sun::star::lang::XTypeProvider                 ,
                         public ::com::sun::star::ui::XUIConfigurationListener,
                         public ThreadHelpBase                                        ,
                         public ::cppu::OWeakObject
{
    friend class FrameworkStatusBar;

    public:
        StatusBarManager( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rServicveManager,
                          const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& rFrame,
                          const rtl::OUString& rResourceName,
                          StatusBar* pStatusBar );
        virtual ~StatusBarManager();

        //  XInterface, XTypeProvider, XServiceInfo
        FWK_DECLARE_XINTERFACE
        FWK_DECLARE_XTYPEPROVIDER

        StatusBar* GetStatusBar() const;

        // XFrameActionListener
        virtual void SAL_CALL frameAction( const com::sun::star::frame::FrameActionEvent& Action ) throw ( ::com::sun::star::uno::RuntimeException );

        // XEventListener
        virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& Source ) throw ( ::com::sun::star::uno::RuntimeException );

        // XUIConfigurationListener
        virtual void SAL_CALL elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);

        // XComponent
        void SAL_CALL dispose() throw ( ::com::sun::star::uno::RuntimeException );
        void SAL_CALL addEventListener( const com::sun::star::uno::Reference< XEventListener >& xListener ) throw( com::sun::star::uno::RuntimeException );
        void SAL_CALL removeEventListener( const com::sun::star::uno::Reference< XEventListener >& xListener ) throw( com::sun::star::uno::RuntimeException );

        void FillStatusBar( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& rStatusBarData );

    protected:
        void StateChanged( StateChangedType nType );
        void DataChanged( const DataChangedEvent& rDCEvt );
        void UserDraw( const UserDrawEvent& rUDEvt );
        void Command( const CommandEvent& rEvt );
        void MouseMove( const MouseEvent& rMEvt );
        void MouseButtonDown( const MouseEvent& rMEvt );
        void MouseButtonUp( const MouseEvent& rMEvt );
        DECL_LINK( Click, StatusBar* );
        DECL_LINK( DoubleClick, StatusBar* );

        void RemoveControllers();
        rtl::OUString RetrieveLabelFromCommand( const rtl::OUString& aCmdURL );
        void CreateControllers();
        void UpdateControllers();
        void AddFrameActionListener();

    protected:
        typedef std::vector< ::com::sun::star::uno::Reference< com::sun::star::frame::XStatusListener > > StatusBarControllerVector;

        sal_Bool                                                                                m_bDisposed : 1,
                                                                                m_bModuleIdentified : 1,
                                                                                m_bFrameActionRegistered : 1,
                                                                                m_bUpdateControllers : 1;
        StatusBar*                                                                                m_pStatusBar;
        rtl::OUString                                                                                m_aModuleIdentifier;
        rtl::OUString                                                                                m_aResourceName;
        com::sun::star::uno::Reference< com::sun::star::frame::XFrame >                                 m_xFrame;
        com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >                        m_xUICommandLabels;
        StatusBarControllerVector                                                                       m_aControllerVector;
        ::cppu::OMultiTypeInterfaceContainerHelper                                                      m_aListenerContainer;   /// container for ALL Listener
        ::com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >                  m_xServiceManager;
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XUIControllerRegistration >  m_xStatusbarControllerRegistration;
};

}

#endif // __FRAMEWORK_UIELEMENT_STATUSBARMANAGER_HXX_
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include "Fat32Disk.hpp"

int main(int argc, char *argv[])
{
    std::shared_ptr<Fat32Root> root;

    try
    {
        auto disk = Disk::create("disk.img", 10000);
        auto fat32Disk = std::make_shared<Fat32Disk>(disk);
        fat32Disk->format("Test Disk");

        /*auto disk = std::make_shared<Disk>("disk.img");
        auto fat32Disk = std::make_shared<Fat32Disk>(disk);*/

        const std::string fileName = "test.txt";
        const std::string hello = "hello world!! ";

        auto dir = fat32Disk->root();
        dir->add(fileName, FatAttrib::File);
        dir->add("testfolder", FatAttrib::Directory);

        root = dir;

        {
            auto file = dir->file(fileName);

            for (int i = 0; i < 50; i++)
                file.write(hello.c_str(), hello.length());

            file.seek(0);

            std::ofstream out(fileName, std::ios::out | std::ios::trunc | std::ios::binary);

            char buffer[512];
            int bytesRead = 0;

            while (bytesRead = file.read(buffer, 512))
            {
                out.write(buffer, bytesRead);
            }

            out.close();
        }

        auto entries = dir->entries();

        for (auto e : entries)
        {
            std::cout << e->getName();

            if (!(e->getAttributes() & (char)FatAttrib::Directory))
                std::cout << " - " << e->getSize() << " bytes";

            std::cout << std::endl;
        }
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }

    return 0;
}

<commit_msg>Remove junk from main<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include "Fat32Disk.hpp"

int main(int argc, char *argv[])
{
    try
    {
        auto disk = Disk::create("disk.img", 10000);
        auto fat32Disk = std::make_shared<Fat32Disk>(disk);
        fat32Disk->format("Test Disk");

        const std::string fileName = "test.txt";
        const std::string hello = "hello world!! ";

        auto dir = fat32Disk->root();
        dir->add(fileName, FatAttrib::File);
        dir->add("testfolder", FatAttrib::Directory);

        {
            auto file = dir->file(fileName);

            for (int i = 0; i < 50; i++)
                file.write(hello.c_str(), hello.length());

            file.seek(0);

            std::ofstream out(fileName, std::ios::out | std::ios::trunc | std::ios::binary);

            char buffer[512];
            int bytesRead = 0;

            while (bytesRead = file.read(buffer, 512))
            {
                out.write(buffer, bytesRead);
            }

            out.close();
        }

        auto entries = dir->entries();

        for (auto e : entries)
        {
            std::cout << e->getName();

            if (!(e->getAttributes() & (char)FatAttrib::Directory))
                std::cout << " - " << e->getSize() << " bytes";

            std::cout << std::endl;
        }
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }

    return 0;
}

<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#define ETL_COUNTERS
#define ETL_GPU_POOL

#include "dll/neural/conv/conv_layer.hpp"
#include "dll/neural/dense/dense_layer.hpp"
#include "dll/neural/bn/batch_normalization_layer.hpp"
#include "dll/pooling/mp_layer.hpp"
#include "dll/network.hpp"
#include "dll/datasets.hpp"

int main(int /*argc*/, char* /*argv*/ []) {
    // Load the dataset
    auto dataset = dll::make_mnist_dataset(dll::batch_size<256>{}, dll::scale_pre<255>{});

    // Build the network

    using network_t = dll::network_desc<
        dll::network_layers<
            dll::conv_layer<1, 28, 28, 16, 5, 5>,
            dll::mp_2d_layer<16, 24, 24, 2, 2>,
            dll::batch_normalization_4d_layer_desc<16, 12, 12>::layer_t,

            dll::conv_layer<16, 12, 12, 16, 5, 5>,
            dll::mp_2d_layer<16, 8, 8, 2, 2>,
            dll::batch_normalization_4d_layer_desc<16, 4, 4>::layer_t,

            dll::dense_layer<16 * 4 * 4, 256>,
            dll::batch_normalization_2d_layer_desc<256>::layer_t,

            dll::dense_layer<256, 10, dll::softmax>
        >
        , dll::updater<dll::updater_type::ADADELTA>  // ADADELTA
        , dll::batch_size<256>                       // The mini-batch size
        , dll::shuffle                               // Shuffle the dataset before each epoch
        //, dll::no_batch_display                    // Disable pretty print of each every batch
        //, dll::no_epoch_error                      // Disable computation of the error at each epoch
        , dll::early_training                        // Do not use validation error for early stopping (BN)
    >::network_t;

    auto net = std::make_unique<network_t>();

    // Display the network and dataset
    net->display_pretty();
    dataset.display_pretty();

    // Train the network
    net->train(dataset.train(), 10);

    // Test the network on test set
    net->evaluate(dataset.test());

    // Show where the time was spent
    dll::dump_timers_pretty();

    // Show ETL performance counters
    etl::dump_counters_pretty();

    return 0;
}
<commit_msg>Fix perf sample<commit_after>//=======================================================================
// Copyright (c) 2014-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#define ETL_COUNTERS
#define ETL_GPU_POOL

#include "dll/neural/conv/conv_layer.hpp"
#include "dll/neural/dense/dense_layer.hpp"
#include "dll/neural/bn/batch_normalization_layer.hpp"
#include "dll/pooling/mp_layer.hpp"
#include "dll/network.hpp"
#include "dll/datasets.hpp"

int main(int /*argc*/, char* /*argv*/ []) {
    // Load the dataset
    auto dataset = dll::make_mnist_dataset(dll::batch_size<256>{}, dll::scale_pre<255>{});

    // Build the network

    using network_t = dll::network_desc<
        dll::network_layers<
            dll::conv_layer<1, 28, 28, 16, 5, 5>,
            dll::mp_2d_layer<16, 24, 24, 2, 2>,
            dll::batch_normalization_4d_layer_desc<16, 12, 12>::layer_t,

            dll::conv_layer<16, 12, 12, 16, 5, 5>,
            dll::mp_2d_layer<16, 8, 8, 2, 2>,
            dll::batch_normalization_4d_layer_desc<16, 4, 4>::layer_t,

            dll::dense_layer<16 * 4 * 4, 256>,
            dll::batch_normalization_2d_layer_desc<256>::layer_t,

            dll::dense_layer<256, 10, dll::softmax>
        >
        , dll::updater<dll::updater_type::ADADELTA>  // ADADELTA
        , dll::batch_size<256>                       // The mini-batch size
        , dll::shuffle                               // Shuffle the dataset before each epoch
        , dll::no_batch_display                    // Disable pretty print of each every batch
        , dll::no_epoch_error                      // Disable computation of the error at each epoch
        , dll::early_training                        // Do not use validation error for early stopping (BN)
    >::network_t;

    auto net = std::make_unique<network_t>();

    // Display the network and dataset
    net->display_pretty();
    dataset.display_pretty();

    // Train the network
    net->train(dataset.train(), 10);

    // Test the network on test set
    net->evaluate(dataset.test());

    // Show where the time was spent
    dll::dump_timers_pretty();

    // Show ETL performance counters
    etl::dump_counters_pretty();

    return 0;
}
<|endoftext|>


<commit_before><?hh // strict
/**
 * @copyright   2010-2015, The Titon Project
 * @license     http://opensource.org/licenses/bsd-license.php
 * @link        http://titon.io
 */

namespace Titon\Context;

use Closure;
use ReflectionClass;
use ReflectionMethod;
use ReflectionFunction;
use ReflectionException;
use Titon\Context\Definition;
use Titon\Context\Definition\DefinitionFactory;
use Titon\Context\Exception\AlreadyRegisteredException;

/**
 * The depository serves as a dependency injector. After registering an object,
 * class, or callable with the depository, retrieving it will handle any necessary
 * dependency injection and reflection resolution before returning the object for
 * use.
 *
 * @package Titon\Context
 */
class Depository {

    /**
     * Hash of registered item definitions keyed by its alias or class name.
     *
     * @var \Titon\Context\ItemMap
     */
    protected ItemMap $items = Map {};

    /**
     * Hash of registered, and already constructed, singletons keyed by its
     * alias or class name.
     *
     * @var \Titon\Context\SingletonMap
     */
    protected SingletonMap $singletons = Map {};

    /**
     * Map of aliases to registered classes and keys.
     *
     * @var \Titon\Context\AliasMap
     */
    protected AliasMap $aliases = Map {};

    /**
     * Instantiate a new container object.
     */
    protected static ?Depository $instance;

    /**
     * Instantiate a new container object
     */
    public function __construct() {
        $this->singleton('Titon\Context\Depository', $this);
    }

    /**
     * Retrieve the Depository singleton
     *
     * @return Depository   Return the Depository instance
     */
    public static function getInstance(): Depository {
        if (is_null(self::$instance)) {
            self::$instance = new Depository();
        }

        return self::$instance;
    }

    /**
     * Register a new class, callable, or object in the container
     *
     * @param string $key     The alias (container key) for the registered item
     * @param mixed $concrete   The class name, closure, object to register in
     *                          the container, or null to use the alias as the
     *                          class name
     * @param bool  $singleton  Whether or not the container should register the
     *                          concrete as a singleton or not (only if concrete
     *                          is class name or a closure)
     *
     * @return object|$definition   Either the concrete (if an object is registered)
     *                              or the definition of the registered item
     * @throws \Titon\Context\Exception\AlreadyRegisteredException
     */
    public function register(string $key, mixed $concrete = null, bool $singleton = false): mixed {
        if ($this->isRegistered($key)) {
            throw new AlreadyRegisteredException("Key $key has already been registered");
        }

        if (!$concrete) {
            $concrete = $key;
        }

        if (is_object($concrete) && !($concrete instanceof Closure)) {
            if ($key !== get_class($concrete)) {
                $this->aliases[$key] = get_class($concrete);
                $key = get_class($concrete);
            }

            $this->singletons[$key] = $concrete;

            return $concrete;
        }

        if (is_string($concrete) && $key !== $concrete && !is_callable($concrete)) {
            $this->aliases[$key] = $concrete;
            $key = $concrete;
        }

        // we need to build a definition
        $definition = DefinitionFactory::factory($key, $concrete, $this);

        $this->items[$key] = shape(
            'definition' => $definition,
            'singleton'  => $singleton
        );

        return $definition;
    }

    /**
     * Alias a string to map to a registered item in the container. This allows
     * you to call 'make' on an alias that maps to a more complex class name,
     * Closure, or singleton instance.
     *
     * @param $alias string The alias to register
     * @param $key string   The original class name or key registered
     *
     * @return $this Return the depository for fluent method chaining
     * @throws \Titon\Context\Exception\AlreadyRegisteredException
     */
    public function alias(string $alias, string $key): this {
        if ($this->aliases->contains($alias)) {
            throw new AlreadyRegisteredException("Alias $alias has already been mapped to {$this->aliases[$alias]}");
        }

        $this->aliases[$alias] = $key;

        return $this;
    }

    /**
     * Register a new singleton in the container.
     *
     * @param string $alias     The alias (container key) for the registered item
     * @param mixed $concrete   The class name, Closure, or object to register in
     *                          the container, or null to use the alias as the
     *                          class name
     *
     * @return object|$definition   Either the concrete (if an object is registered)
     *                              or the definition of the registered item
     */
    public function singleton(string $alias, mixed $concrete = null): mixed {
        return $this->register($alias, $concrete, true);
    }

    /**
     * Change an existing item to be used as a singleton or, if alias doesn't
     * exist, register passed in alias and existing concrete as singleton.
     *
     * @param string $alias     The key or alias to change to a singleton
     * @param mixed  $concrete  Class name, Closure, or object to register if
     *                          no item is currently registered as the alias.
     *                          If an item is already registered, the existing
     *                          item will be used and this concrete will be
     *                          ignored.
     *
     * @return mixed    Either the concrete (if an object is registered)
     *                  or the definition of the registered item
     */
    public function makeSingleton(string $alias, mixed $concrete = null): mixed {
        if ($this->aliases->contains($alias)) {
            return $this->makeSingleton($this->aliases[$alias]);
        }

        if ($this->items->contains($alias)) {
            $this->items[$alias]['singleton'] = true;

            return $this->items[$alias]['definition'];
        }

        if (!$this->singletons->contains($alias)) {
            return $this->singletons[$alias];
        }

        return $this->register($alias, $concrete, true);
    }

    /**
     * Retrieve (and build if necessary) the registered item from the container.
     *
     * @param string $alias                 Key or alias of a registered item or a class
     *                                      name, callable, or Closure to construct
     * @param array<mixed> ...$arguments    Additional arguments to pass into the item at
     *                                      construction
     *
     * @return mixed    The resolved registered item or return value
     */
    public function make(mixed $alias, ...$arguments): mixed {
        if (is_string($alias) && $this->isRegistered($alias)) {
            return $this->getRegisteredItem($alias, ...$arguments);
        }

        if (is_string($alias) && class_exists($alias)) {
            $definition = $this->buildClass($alias, ...$arguments);
        } else {
            $definition = $this->buildCallable($alias);
        }

        return $definition->create(...$arguments);
    }

    /**
     * Immediately build a closure and run it.
     *
     * @param \Closure $callable
     * @param ...$arguments
     * @return mixed    The resolved registered item or return value
     */
    protected function getRegisteredItem(string $alias, ...$arguments): mixed {
        if ($this->aliases->contains($alias)) {
            return $this->make($this->aliases[$alias], ...$arguments);
        }

        if ($this->singletons->contains($alias)) {
            $retval = $this->singletons[$alias];
        } else {
            $definition = $this->items[$alias]['definition'];
            $retval = $definition;

            if ($definition instanceof Definition) {
                $retval = $definition->create(...$arguments);
            }

            if ($this->items->contains($alias) && $this->items[$alias]['singleton'] === true) {
                $this->items->remove($alias);
                $this->singletons[$alias] = $retval;
            }
        }

        return $definition->create(...$arguments);
    }

    /**
     * Remove an alias or key from the depository's registry.
     *
     * @param string $key The key to remove
     *
     * @return $this Return the depository for fluent method chaining
     */
    public function remove(string $key): this {
        $this->singletons->remove($key);
        $this->items->remove($key);

        if ($this->aliases->contains($key)) {
            $this->singletons->remove($this->aliases[$key]);
            $this->items->remove($this->aliases[$key]);
            $this->aliases->remove($key);
        }

        return $this;
    }

    /**
     * Clear all registered items, singletons, and aliases in the Depository.
     *
     * @return $this    Return the depository for fluent method chaining
     */
    public function clear(): this {
        $this->aliases->clear();
        $this->singletons->clear();
        $this->items->clear();

        return $this;
    }

    /**
     * Return whether or not an alias has been registered in the container
     *
     * @param string $alias Registered key or class name
     *
     * @return bool
     */
    protected function buildClass(string $class, ...$arguments): Definition {
        $reflection = new ReflectionClass($class);
        if (!$reflection->isInstantiable()) {
            $message = "Target [$class] is not instantiable.";
            throw new ReflectionException($message);
        }

        if ($this->singletons->contains($alias)) {
            return true;
        }

        if (count($arguments) > 0) {
            foreach ($arguments as $arg) {
                $definition->with($arg);
            }
        } else {
            foreach ($constructor->getParameters() as $param) {
                $dependency = $param->getClass();

                if (is_null($dependency)) {
                    if ($param->isDefaultValueAvailable()) {
                        $definition->with($param->getDefaultValue());
                        continue;
                    }

                    throw new ReflectionException("Cannot to resolve dependency of $param for $class");
                }

                $definition->with($dependency->getName());
            }
        }

        return false;
    }

    /**
     * This method will use reflection to build a definition of the callable to
     * be registered by the depository.
     *
     * @param string $alias
     *
     * @return Definition   The definition built from the callable
     */
    protected function buildCallable(mixed $alias): Definition {
        if (is_string($alias) && strpos($alias, '::') !== false) {
            $callable = explode('::', $alias);
        } else {
            $callable = $alias;

            if (!is_string($alias)) {
                $alias = 'Callable';
            }
        }

        $definition = DefinitionFactory::factory($alias, $callable, $this);

        if (is_array($callable)) {
            $reflector = new ReflectionMethod($callable[0], $callable[1]);
        } else {
            $reflector = new ReflectionFunction($callable);
        }

        foreach ($reflector->getParameters() as $param) {
            $dependency = $param->getClass();

            if (is_null($dependency)) {
                if ($param->isDefaultValueAvailable()) {
                    $definition->with($param->getDefaultValue());
                    continue;
                }

                throw new ReflectionException("Cannot to resolve dependency of $param for $alias");
            }

            $definition->with($dependency->getName());
        }

        return $definition;
    }

    /**
     * Return whether or not an alias has been registered in the container.
     *
     * @param string $class         The class name to reflect and construct
     * @param mixed ...$parameters  Parameters required for constructing the object
     *
     * @return Definition
     * @throws ReflectionException
     */
    protected function buildClass(string $class): Definition {
        $reflection = new ReflectionClass($class);

        if (!$reflection->isInstantiable()) {
            throw new ReflectionException("Target [$class] is not instantiable");
        }

        $definition = DefinitionFactory::factory($class, $class, $this);
        $constructor = $reflection->getConstructor();

        if (is_null($constructor)) {
            return $definition;
        }

        foreach ($constructor->getParameters() as $param) {
            $dependency = $param->getClass();

            if (is_null($dependency)) {
                if ($param->isDefaultValueAvailable()) {
                    $definition->with($param->getDefaultValue());
                    continue;
                }

                throw new ReflectionException("Cannot to resolve dependency of $param for $class");
            }

            $definition->with($dependency->getName());
        }

        return $definition;
    }

    /**
     * Return whether or not an alias has been registered as a singleton in
     * the container.
     *
     * @param string $alias                 The key the item is stored under
     * @param array<mixed> ...$arguments    Arguments passed into creating the
     *                                      definition
     *
     * @return mixed
     */
    protected function getRegisteredItem(string $alias, ...$arguments): mixed {
        if ($this->aliases->contains($alias)) {
            return $this->make($this->aliases[$alias], ...$arguments);
        }

        if ($this->singletons->contains($alias)) {
            $retval = $this->singletons[$alias];
        } else {
            $definition = $this->items[$alias]['definition'];
            $retval = $definition;

            if ($definition instanceof Definition) {
                $retval = $definition->create(...$arguments);
            }

            if ($this->items->contains($alias) && $this->items[$alias]['singleton'] === true) {
                $this->items->remove($alias);
                $this->singletons[$alias] = $retval;
            }
        }

        return $retval;
    }

}
<commit_msg>fixed merge conflicts<commit_after><?hh // strict
/**
 * @copyright   2010-2015, The Titon Project
 * @license     http://opensource.org/licenses/bsd-license.php
 * @link        http://titon.io
 */

namespace Titon\Context;

use Closure;
use ReflectionClass;
use ReflectionMethod;
use ReflectionFunction;
use ReflectionException;
use Titon\Context\Definition;
use Titon\Context\Definition\DefinitionFactory;
use Titon\Context\Exception\AlreadyRegisteredException;

/**
 * The depository serves as a dependency injector. After registering an object,
 * class, or callable with the depository, retrieving it will handle any necessary
 * dependency injection and reflection resolution before returning the object for
 * use.
 *
 * @package Titon\Context
 */
class Depository {

    /**
     * Hash of registered item definitions keyed by its alias or class name.
     *
     * @var \Titon\Context\ItemMap
     */
    protected ItemMap $items = Map {};

    /**
     * Hash of registered, and already constructed, singletons keyed by its
     * alias or class name.
     *
     * @var \Titon\Context\SingletonMap
     */
    protected SingletonMap $singletons = Map {};

    /**
     * Map of aliases to registered classes and keys.
     *
     * @var \Titon\Context\AliasMap
     */
    protected AliasMap $aliases = Map {};

    /**
     * Instantiate a new container object.
     */
    protected static ?Depository $instance;

    /**
     * Instantiate a new container object
     */
    public function __construct() {
        $this->singleton('Titon\Context\Depository', $this);
    }

    /**
     * Retrieve the Depository singleton
     *
     * @return Depository   Return the Depository instance
     */
    public static function getInstance(): Depository {
        if (is_null(self::$instance)) {
            self::$instance = new Depository();
        }

        return self::$instance;
    }

    /**
     * Register a new class, callable, or object in the container
     *
     * @param string $key     The alias (container key) for the registered item
     * @param mixed $concrete   The class name, closure, object to register in
     *                          the container, or null to use the alias as the
     *                          class name
     * @param bool  $singleton  Whether or not the container should register the
     *                          concrete as a singleton or not (only if concrete
     *                          is class name or a closure)
     *
     * @return object|$definition   Either the concrete (if an object is registered)
     *                              or the definition of the registered item
     */
    public function register(string $key, mixed $concrete = null, bool $singleton = false): mixed {
        if ($this->isRegistered($key)) {
            throw new AlreadyRegisteredException("Key $key has already been registered");
        }

        if (!$concrete) {
            $concrete = $key;
        }

        if (is_object($concrete) && !($concrete instanceof Closure)) {
            if ($key !== get_class($concrete)) {
                $this->aliases[$key] = get_class($concrete);
                $key = get_class($concrete);
            }

            $this->singletons[$key] = $concrete;

            return $concrete;
        }

        if (is_string($concrete) && $key !== $concrete && !is_callable($concrete)) {
            $this->aliases[$key] = $concrete;
            $key = $concrete;
        }

        // we need to build a definition
        $definition = DefinitionFactory::factory($key, $concrete, $this);

        $this->items[$key] = shape(
            'definition' => $definition,
            'singleton'  => $singleton
        );

        return $definition;
    }

    /**
     * Alias a string to map to a registered item in the container. This allows
     * you to call 'make' on an alias that maps to a more complex class name,
     * Closure, or singleton instance.
     *
     * @param $alias string The alias to register
     * @param $key string   The original class name or key registered
     *
     * @return $this Return the depository for fluent method chaining
     */
    public function alias(string $alias, string $key): this {
        if ($this->aliases->contains($alias)) {
            throw new AlreadyRegisteredException("Alias $alias has already been mapped to {$this->aliases[$alias]}");
        }

        $this->aliases[$alias] = $key;

        return $this;
    }

    /**
     * Register a new singleton in the container.
     *
     * @param string $alias     The alias (container key) for the registered item
     * @param mixed $concrete   The class name, Closure, or object to register in
     *                          the container, or null to use the alias as the
     *                          class name
     *
     * @return object|$definition   Either the concrete (if an object is registered)
     *                              or the definition of the registered item
     */
    public function singleton(string $alias, mixed $concrete = null): mixed {
        return $this->register($alias, $concrete, true);
    }

    /**
     * Change an existing item to be used as a singleton or, if alias doesn't
     * exist, register passed in alias and existing concrete as singleton.
     *
     * @param string $alias     The key or alias to change to a singleton
     * @param mixed  $concrete  Class name, Closure, or object to register if
     *                          no item is currently registered as the alias.
     *                          If an item is already registered, the existing
     *                          item will be used and this concrete will be
     *                          ignored.
     *
     * @return mixed    Either the concrete (if an object is registered)
     *                  or the definition of the registered item
     */
    public function makeSingleton(string $alias, mixed $concrete = null): mixed {
        if ($this->aliases->contains($alias)) {
            return $this->makeSingleton($this->aliases[$alias]);
        }

        if ($this->items->contains($alias)) {
            $this->items[$alias]['singleton'] = true;

            return $this->items[$alias]['definition'];
        }

        if (!$this->singletons->contains($alias)) {
            return $this->singletons[$alias];
        }

        return $this->register($alias, $concrete, true);
    }

    /**
     * Retrieve (and build if necessary) the registered item from the container.
     *
     * @param string $alias                 Key or alias of a registered item or a class
     *                                      name, callable, or Closure to construct
     * @param array<mixed> ...$arguments    Additional arguments to pass into the item at
     *                                      construction
     *
     * @return mixed    The resolved registered item or return value
     */
    public function make(mixed $alias, ...$arguments): mixed {
        if (is_string($alias) && $this->isRegistered($alias)) {
            return $this->getRegisteredItem($alias, ...$arguments);
        }

        if (is_string($alias) && class_exists($alias)) {
            $definition = $this->buildClass($alias, ...$arguments);
        } else {
            $definition = $this->buildCallable($alias);
        }

        return $definition->create(...$arguments);
    }

    /**
     * Retrieve the created definition or stored instance from the depository
     * by key
     *
     * @param string $alias                 The key the item is stored under
     * @param array<mixed> ...$arguments    Arguments passed into creating the
     *                                      definition
     *
     * @return mixed
     */
    protected function getRegisteredItem(string $alias, ...$arguments): mixed {
        if ($this->aliases->contains($alias)) {
            return $this->make($this->aliases[$alias], ...$arguments);
        }

        if ($this->singletons->contains($alias)) {
            $retval = $this->singletons[$alias];
        } else {
            $definition = $this->items[$alias]['definition'];
            $retval = $definition;

            if ($definition instanceof Definition) {
                $retval = $definition->create(...$arguments);
            }

            if ($this->items->contains($alias) && $this->items[$alias]['singleton'] === true) {
                $this->items->remove($alias);
                $this->singletons[$alias] = $retval;
            }
        }

        return $retval;
    }

    /**
     * Remove an alias or key from the depository's registry.
     *
     * @param string $key The key to remove
     *
     * @return $this Return the depository for fluent method chaining
     */
    public function remove(string $key): this {
        $this->singletons->remove($key);
        $this->items->remove($key);

        if ($this->aliases->contains($key)) {
            $this->singletons->remove($this->aliases[$key]);
            $this->items->remove($this->aliases[$key]);
            $this->aliases->remove($key);
        }

        return $this;
    }

    /**
     * Clear all registered items, singletons, and aliases in the Depository.
     *
     * @return $this    Return the depository for fluent method chaining
     */
    public function clear(): this {
        $this->aliases->clear();
        $this->singletons->clear();
        $this->items->clear();

        return $this;
    }

    /**
     * This method will use reflection to build the class and inject any
     * necessary arguments for construction.
     *
     * @param string $class         The class name to reflect and construct
     * @param mixed ...$parameters  Parameters required for constructing the object
     *
     * @return Definition|mixed
     * @throws ReflectionException
     */
    protected function buildClass(string $class, ...$arguments): Definition {
        $reflection = new ReflectionClass($class);
        if (!$reflection->isInstantiable()) {
            $message = "Target [$class] is not instantiable.";
            throw new ReflectionException($message);
        }

        $definition = DefinitionFactory::factory($class, $class, $this);
        $constructor = $reflection->getConstructor();

        if (is_null($constructor)) {
            return $definition;
        }

        if (count($arguments) > 0) {
            foreach ($arguments as $arg) {
                $definition->with($arg);
            }
        } else {
            foreach ($constructor->getParameters() as $param) {
                $dependency = $param->getClass();

                if (is_null($dependency)) {
                    if ($param->isDefaultValueAvailable()) {
                        $definition->with($param->getDefaultValue());
                        continue;
                    }

                    throw new ReflectionException("Cannot to resolve dependency of $param for $class");
                }

                $definition->with($dependency->getName());
            }
        }

        return $definition;
    }

    /**
     * This method will use reflection to build a definition of the callable to
     * be registered by the depository.
     *
     * @param string $alias
     *
     * @return Definition   The definition built from the callable
     */
    protected function buildCallable(mixed $alias): Definition {
        if (is_string($alias) && strpos($alias, '::') !== false) {
            $callable = explode('::', $alias);
        } else {
            $callable = $alias;

            if (!is_string($alias)) {
                $alias = 'Callable';
            }
        }

        $definition = DefinitionFactory::factory($alias, $callable, $this);

        if (is_array($callable)) {
            $reflector = new ReflectionMethod($callable[0], $callable[1]);
        } else {
            $reflector = new ReflectionFunction($callable);
        }

        foreach ($reflector->getParameters() as $param) {
            $dependency = $param->getClass();

            if (is_null($dependency)) {
                if ($param->isDefaultValueAvailable()) {
                    $definition->with($param->getDefaultValue());
                    continue;
                }

                throw new ReflectionException("Cannot to resolve dependency of $param for $alias");
            }

            $definition->with($dependency->getName());
        }

        return $definition;
    }

    /**
     * Return whether or not an alias has been registered in the container.
     *
     * @param string $alias Registered key or class name
     *
     * @return bool
     */
    public function isRegistered(string $alias): bool {
        if ($this->aliases->contains($alias)) {
            return true;
        }

        if ($this->singletons->contains($alias)) {
            return true;
        }

        if ($this->items->contains($alias)) {
            return true;
        }

        return false;
    }

    /**
     * Return whether or not an alias has been registered as a singleton in
     * the container.
     *
     * @param string $alias Registered key or class name
     *
     * @return bool
     */
    public function isSingleton(string $alias): bool {
        if ($this->aliases->contains($alias)) {
            return $this->isSingleton($this->aliases[$alias]);
        }

        if ($this->singletons->contains($alias) || ($this->items->contains($alias) && $this->items[$alias]['singleton'] === true)) {
            return true;
        }

        return false;
    }
}<|endoftext|>


<commit_before>// This code is based on Sabberstone project.
// Copyright (c) 2017-2018 SabberStone Team, darkfriend77 & rnilva
// Hearthstone++ is hearthstone simulator using C++ with reinforcement learning.
// Copyright (c) 2018 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

#include <hspp/Actions/Draw.hpp>
#include <hspp/Actions/Generic.hpp>
#include <hspp/Cards/Cards.hpp>
#include <hspp/Games/Game.hpp>
#include <hspp/Games/GameManager.hpp>

#include <effolkronium/random.hpp>

#include <algorithm>

using Random = effolkronium::random_static;

namespace Hearthstonepp
{
Game::Game(GameConfig& gameConfig) : m_gameConfig(gameConfig)
{
    // Add hero and hero power
    GetPlayer1().AddHeroAndPower(
        Cards::GetInstance().GetHeroCard(gameConfig.player1Class),
        Cards::GetInstance().GetDefaultHeroPower(gameConfig.player1Class));
    GetPlayer2().AddHeroAndPower(
        Cards::GetInstance().GetHeroCard(gameConfig.player2Class),
        Cards::GetInstance().GetDefaultHeroPower(gameConfig.player2Class));

    // Set opponent player
    GetPlayer1().SetOpponent(&GetPlayer2());
    GetPlayer2().SetOpponent(&GetPlayer1());
}

Player& Game::GetPlayer1()
{
    return m_players[0];
}

Player& Game::GetPlayer2()
{
    return m_players[1];
}

Player& Game::GetCurrentPlayer()
{
    return *m_currentPlayer;
}

Player& Game::GetOpponentPlayer()
{
    return m_currentPlayer->GetOpponent();
}

std::size_t Game::GetNextID()
{
    return m_entityID++;
}

std::size_t Game::GetNextOOP()
{
    return m_oopIndex++;
}

void Game::BeginFirst()
{
    // Set next step
    nextStep = Step::BEGIN_SHUFFLE;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::BeginShuffle()
{
    // Shuffle cards in deck
    if (m_gameConfig.doShuffle)
    {
        GetPlayer1().GetDeck().Shuffle();
        GetPlayer2().GetDeck().Shuffle();
    }

    // Set next step
    nextStep = Step::BEGIN_DRAW;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::BeginDraw()
{
    for (auto& p : m_players)
    {
        // Draw 3 cards
        Generic::Draw(p);
        Generic::Draw(p);
        Generic::Draw(p);

        if (&p != m_firstPlayer)
        {
            // Draw 4th card for second player
            Generic::Draw(p);

            // Give "The Coin" card to second player
            Card coin = Cards::GetInstance().FindCardByID("GAME_005");
            p.GetHand().AddCard(*Entity::GetFromCard(p, std::move(coin)));
        }
    }

    // Set next step
    nextStep =
        m_gameConfig.skipMulligan ? Step::MAIN_BEGIN : Step::BEGIN_MULLIGAN;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::BeginMulligan()
{
    // Start mulligan state
    GetPlayer1().mulliganState = Mulligan::INPUT;
    GetPlayer2().mulliganState = Mulligan::INPUT;
}

void Game::MainBegin()
{
    // Set next step
    nextStep = Step::MAIN_READY;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainReady()
{
    // Reset the number of attacked
    for (auto& p : m_players)
    {
        // Hero
        p.GetHero()->numAttacked = 0;
        // Field
        for (auto& m : p.GetField().GetAllMinions())
        {
            m->numAttacked = 0;
        }
    }

    // Reset exhaust for current player
    auto& curPlayer = GetCurrentPlayer();
    // Hero
    curPlayer.GetHero()->SetGameTag(GameTag::EXHAUSTED, 0);
    // Weapon
    if (curPlayer.GetHero()->weapon != nullptr)
    {
        curPlayer.GetHero()->weapon->SetGameTag(GameTag::EXHAUSTED, 0);
    }
    // Hero power
    curPlayer.GetHero()->heroPower->SetGameTag(GameTag::EXHAUSTED, 0);
    // Field
    for (auto& m : curPlayer.GetField().GetAllMinions())
    {
        m->SetGameTag(GameTag::EXHAUSTED, 0);
    }

    // Set next step
    nextStep = Step::MAIN_START_TRIGGERS;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainStartTriggers()
{
    // Set next step
    nextStep = Step::MAIN_RESOURCE;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainResource()
{
    auto& curPlayer = GetCurrentPlayer();

    // Add mana crystal to current player
    Generic::ChangeManaCrystal(curPlayer, 1, false);

    // Reset current mana
    curPlayer.currentMana = curPlayer.maximumMana;

    // Set next step
    nextStep = Step::MAIN_DRAW;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainDraw()
{
    // Draw a card for current player
    Generic::Draw(GetCurrentPlayer());

    // Set next step
    nextStep = Step::MAIN_START;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainStart()
{
    // Set next step
    nextStep = Step::MAIN_ACTION;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainEnd()
{
    // Set next step
    nextStep = Step::MAIN_CLEANUP;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainCleanUp()
{
    auto& curPlayer = GetCurrentPlayer();

    // Unfreeze all characters they control that are Frozen, don't have
    // summoning sickness (or do have Charge) and have not attacked that turn
    // Hero
    if (curPlayer.GetHero()->GetGameTag(GameTag::FROZEN) == 1 &&
        curPlayer.GetHero()->numAttacked == 0)
    {
        curPlayer.GetHero()->SetGameTag(GameTag::FROZEN, 0);
    }
    // Field
    for (auto& m : curPlayer.GetField().GetAllMinions())
    {
        if (m->GetGameTag(GameTag::FROZEN) == 1 && m->numAttacked == 0 &&
            m->GetGameTag(GameTag::EXHAUSTED) == 0)
        {
            m->SetGameTag(GameTag::FROZEN, 0);
        }
    }

    // Set next step
    nextStep = Step::MAIN_NEXT;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainNext()
{
    // Set player for next turn
    m_currentPlayer = &m_currentPlayer->GetOpponent();

    // Count next turn
    m_turn++;

    // Set next step
    nextStep = Step::MAIN_READY;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::FinalWrapUp()
{
    // Set game states according by result
    for (auto& p : m_players)
    {
        if (p.playState == +PlayState::LOSING ||
            p.playState == +PlayState::CONCEDED)
        {
            p.playState = PlayState::LOST;
            p.GetOpponent().playState = PlayState::WON;
        }
    }

    // Set next step
    nextStep = Step::FINAL_GAMEOVER;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::FinalGameOver()
{
    // Set game state to complete
    state = State::COMPLETE;
}

void Game::StartGame()
{
    // Set game to player
    for (auto& p : m_players)
    {
        p.SetGame(this);
    }

    // Reverse card order in deck
    if (!m_gameConfig.doShuffle)
    {
        std::reverse(m_gameConfig.player1Deck.begin(),
                     m_gameConfig.player1Deck.end());
        std::reverse(m_gameConfig.player2Deck.begin(),
                     m_gameConfig.player2Deck.end());
    }

    // Set up decks
    for (auto& card : m_gameConfig.player1Deck)
    {
        if (card.cardType == +CardType::INVALID)
        {
            continue;
        }

        Entity* entity = Entity::GetFromCard(GetPlayer1(), std::move(card));
        GetPlayer1().GetDeck().AddCard(*entity);
    }
    for (auto& card : m_gameConfig.player2Deck)
    {
        if (card.cardType == +CardType::INVALID)
        {
            continue;
        }

        Entity* entity = Entity::GetFromCard(GetPlayer2(), std::move(card));
        GetPlayer2().GetDeck().AddCard(*entity);
    }

    // Fill cards to deck
    if (m_gameConfig.doFillDecks)
    {
        for (auto& p : m_players)
        {
            for (auto& cardID : m_gameConfig.fillCardIDs)
            {
                Card card = Cards::GetInstance().FindCardByID(cardID);
                Entity* entity = Entity::GetFromCard(p, std::move(card));
                p.GetDeck().AddCard(*entity);
            }
        }
    }

    // Set game states
    state = State::RUNNING;
    for (auto& p : m_players)
    {
        p.playState = PlayState::PLAYING;
    }

    // Determine first player
    switch (m_gameConfig.startPlayer)
    {
        case PlayerType::RANDOM:
        {
            auto val = Random::get(0, 1);
            m_firstPlayer = &m_players[val];
            break;
        }
        case PlayerType::PLAYER1:
            m_firstPlayer = &m_players[0];
            break;
        case PlayerType::PLAYER2:
            m_firstPlayer = &m_players[1];
            break;
    }
    m_currentPlayer = m_firstPlayer;

    // Set first turn
    m_turn = 1;

    // Set next step
    nextStep = Step::BEGIN_FIRST;
    GameManager::ProcessNextStep(*this, nextStep);
}
}  // namespace Hearthstonepp<commit_msg>[ci skip] fix: Change location of code that set game to player (nullptr)<commit_after>// This code is based on Sabberstone project.
// Copyright (c) 2017-2018 SabberStone Team, darkfriend77 & rnilva
// Hearthstone++ is hearthstone simulator using C++ with reinforcement learning.
// Copyright (c) 2018 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

#include <hspp/Actions/Draw.hpp>
#include <hspp/Actions/Generic.hpp>
#include <hspp/Cards/Cards.hpp>
#include <hspp/Games/Game.hpp>
#include <hspp/Games/GameManager.hpp>

#include <effolkronium/random.hpp>

#include <algorithm>

using Random = effolkronium::random_static;

namespace Hearthstonepp
{
Game::Game(GameConfig& gameConfig) : m_gameConfig(gameConfig)
{
    // Set game to player
    for (auto& p : m_players)
    {
        p.SetGame(this);
    }

    // Add hero and hero power
    GetPlayer1().AddHeroAndPower(
        Cards::GetInstance().GetHeroCard(gameConfig.player1Class),
        Cards::GetInstance().GetDefaultHeroPower(gameConfig.player1Class));
    GetPlayer2().AddHeroAndPower(
        Cards::GetInstance().GetHeroCard(gameConfig.player2Class),
        Cards::GetInstance().GetDefaultHeroPower(gameConfig.player2Class));

    // Set opponent player
    GetPlayer1().SetOpponent(&GetPlayer2());
    GetPlayer2().SetOpponent(&GetPlayer1());
}

Player& Game::GetPlayer1()
{
    return m_players[0];
}

Player& Game::GetPlayer2()
{
    return m_players[1];
}

Player& Game::GetCurrentPlayer()
{
    return *m_currentPlayer;
}

Player& Game::GetOpponentPlayer()
{
    return m_currentPlayer->GetOpponent();
}

std::size_t Game::GetNextID()
{
    return m_entityID++;
}

std::size_t Game::GetNextOOP()
{
    return m_oopIndex++;
}

void Game::BeginFirst()
{
    // Set next step
    nextStep = Step::BEGIN_SHUFFLE;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::BeginShuffle()
{
    // Shuffle cards in deck
    if (m_gameConfig.doShuffle)
    {
        GetPlayer1().GetDeck().Shuffle();
        GetPlayer2().GetDeck().Shuffle();
    }

    // Set next step
    nextStep = Step::BEGIN_DRAW;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::BeginDraw()
{
    for (auto& p : m_players)
    {
        // Draw 3 cards
        Generic::Draw(p);
        Generic::Draw(p);
        Generic::Draw(p);

        if (&p != m_firstPlayer)
        {
            // Draw 4th card for second player
            Generic::Draw(p);

            // Give "The Coin" card to second player
            Card coin = Cards::GetInstance().FindCardByID("GAME_005");
            p.GetHand().AddCard(*Entity::GetFromCard(p, std::move(coin)));
        }
    }

    // Set next step
    nextStep =
        m_gameConfig.skipMulligan ? Step::MAIN_BEGIN : Step::BEGIN_MULLIGAN;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::BeginMulligan()
{
    // Start mulligan state
    GetPlayer1().mulliganState = Mulligan::INPUT;
    GetPlayer2().mulliganState = Mulligan::INPUT;
}

void Game::MainBegin()
{
    // Set next step
    nextStep = Step::MAIN_READY;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainReady()
{
    // Reset the number of attacked
    for (auto& p : m_players)
    {
        // Hero
        p.GetHero()->numAttacked = 0;
        // Field
        for (auto& m : p.GetField().GetAllMinions())
        {
            m->numAttacked = 0;
        }
    }

    // Reset exhaust for current player
    auto& curPlayer = GetCurrentPlayer();
    // Hero
    curPlayer.GetHero()->SetGameTag(GameTag::EXHAUSTED, 0);
    // Weapon
    if (curPlayer.GetHero()->weapon != nullptr)
    {
        curPlayer.GetHero()->weapon->SetGameTag(GameTag::EXHAUSTED, 0);
    }
    // Hero power
    curPlayer.GetHero()->heroPower->SetGameTag(GameTag::EXHAUSTED, 0);
    // Field
    for (auto& m : curPlayer.GetField().GetAllMinions())
    {
        m->SetGameTag(GameTag::EXHAUSTED, 0);
    }

    // Set next step
    nextStep = Step::MAIN_START_TRIGGERS;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainStartTriggers()
{
    // Set next step
    nextStep = Step::MAIN_RESOURCE;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainResource()
{
    auto& curPlayer = GetCurrentPlayer();

    // Add mana crystal to current player
    Generic::ChangeManaCrystal(curPlayer, 1, false);

    // Reset current mana
    curPlayer.currentMana = curPlayer.maximumMana;

    // Set next step
    nextStep = Step::MAIN_DRAW;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainDraw()
{
    // Draw a card for current player
    Generic::Draw(GetCurrentPlayer());

    // Set next step
    nextStep = Step::MAIN_START;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainStart()
{
    // Set next step
    nextStep = Step::MAIN_ACTION;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainEnd()
{
    // Set next step
    nextStep = Step::MAIN_CLEANUP;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainCleanUp()
{
    auto& curPlayer = GetCurrentPlayer();

    // Unfreeze all characters they control that are Frozen, don't have
    // summoning sickness (or do have Charge) and have not attacked that turn
    // Hero
    if (curPlayer.GetHero()->GetGameTag(GameTag::FROZEN) == 1 &&
        curPlayer.GetHero()->numAttacked == 0)
    {
        curPlayer.GetHero()->SetGameTag(GameTag::FROZEN, 0);
    }
    // Field
    for (auto& m : curPlayer.GetField().GetAllMinions())
    {
        if (m->GetGameTag(GameTag::FROZEN) == 1 && m->numAttacked == 0 &&
            m->GetGameTag(GameTag::EXHAUSTED) == 0)
        {
            m->SetGameTag(GameTag::FROZEN, 0);
        }
    }

    // Set next step
    nextStep = Step::MAIN_NEXT;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::MainNext()
{
    // Set player for next turn
    m_currentPlayer = &m_currentPlayer->GetOpponent();

    // Count next turn
    m_turn++;

    // Set next step
    nextStep = Step::MAIN_READY;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::FinalWrapUp()
{
    // Set game states according by result
    for (auto& p : m_players)
    {
        if (p.playState == +PlayState::LOSING ||
            p.playState == +PlayState::CONCEDED)
        {
            p.playState = PlayState::LOST;
            p.GetOpponent().playState = PlayState::WON;
        }
    }

    // Set next step
    nextStep = Step::FINAL_GAMEOVER;
    GameManager::ProcessNextStep(*this, nextStep);
}

void Game::FinalGameOver()
{
    // Set game state to complete
    state = State::COMPLETE;
}

void Game::StartGame()
{
    // Reverse card order in deck
    if (!m_gameConfig.doShuffle)
    {
        std::reverse(m_gameConfig.player1Deck.begin(),
                     m_gameConfig.player1Deck.end());
        std::reverse(m_gameConfig.player2Deck.begin(),
                     m_gameConfig.player2Deck.end());
    }

    // Set up decks
    for (auto& card : m_gameConfig.player1Deck)
    {
        if (card.cardType == +CardType::INVALID)
        {
            continue;
        }

        Entity* entity = Entity::GetFromCard(GetPlayer1(), std::move(card));
        GetPlayer1().GetDeck().AddCard(*entity);
    }
    for (auto& card : m_gameConfig.player2Deck)
    {
        if (card.cardType == +CardType::INVALID)
        {
            continue;
        }

        Entity* entity = Entity::GetFromCard(GetPlayer2(), std::move(card));
        GetPlayer2().GetDeck().AddCard(*entity);
    }

    // Fill cards to deck
    if (m_gameConfig.doFillDecks)
    {
        for (auto& p : m_players)
        {
            for (auto& cardID : m_gameConfig.fillCardIDs)
            {
                Card card = Cards::GetInstance().FindCardByID(cardID);
                Entity* entity = Entity::GetFromCard(p, std::move(card));
                p.GetDeck().AddCard(*entity);
            }
        }
    }

    // Set game states
    state = State::RUNNING;
    for (auto& p : m_players)
    {
        p.playState = PlayState::PLAYING;
    }

    // Determine first player
    switch (m_gameConfig.startPlayer)
    {
        case PlayerType::RANDOM:
        {
            auto val = Random::get(0, 1);
            m_firstPlayer = &m_players[val];
            break;
        }
        case PlayerType::PLAYER1:
            m_firstPlayer = &m_players[0];
            break;
        case PlayerType::PLAYER2:
            m_firstPlayer = &m_players[1];
            break;
    }
    m_currentPlayer = m_firstPlayer;

    // Set first turn
    m_turn = 1;

    // Set next step
    nextStep = Step::BEGIN_FIRST;
    GameManager::ProcessNextStep(*this, nextStep);
}
}  // namespace Hearthstonepp<|endoftext|>