<commit_before>/*!
  \copyright (c) RDO-Team, 2012
  \file      main.cpp
  \authors     (cerevra@gmail.com)
  \authors     (rdo@rk9.bmstu.ru)
  \date      05.11.2012
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#include <iostream>
#include <conio.h>
#include <QtSql\QtSql>
#include <QtCore\QCoreApplication>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator\runtime\test\sql\include\general_db.h"
// --------------------------------------------------------------------------------

int main(int argc, char *argv[])
{
	QCoreApplication app(argc, argv);
	generalDB db = generalDB::generalDB("localhost","postgres","postgres","rdo",5432);

	db.queryExec("DROP DATABASE IF EXISTS rdo;");
	db.queryExec("CREATE DATABASE rdo;");

	db.setDefParams();
	db.initDB();

	QSqlQuery query;
//------------------------
	QString create_rtp = "CREATE TABLE rtp"
						"("
						"	r_t_id               serial,"
						"	r_t_name             VARCHAR(40) NOT NULL,"
						"	r_t_perm             boolean NOT NULL,"
						"	PRIMARY KEY (r_t_id)"
						");";
	db.queryExec(create_rtp);

	QString create_list = "CREATE TABLE list_of_types_of_params"
						"("
						"	type_id       integer,"
						"	table_id      integer NOT NULL,"
						"	PRIMARY KEY (type_id)"
						");";
	db.queryExec(create_list);

	QString create_param = "CREATE TABLE param_of_type"
						"("
						"	param_id      serial,"
						"	param_name    VARCHAR(40) NOT NULL,"
						"	r_t_id        integer,"
						"	type_id       integer NOT NULL,"
						"	PRIMARY KEY (param_id,r_t_id),"
						"	FOREIGN KEY (r_t_id) REFERENCES rtp,"
						"	FOREIGN KEY (type_id) REFERENCES list_of_types_of_params"
						");";
	db.queryExec(create_param);
//------------------------

//------------------------
	QString create_seq = "CREATE SEQUENCE type_of_param_seq;";
	db.queryExec(create_seq);

	QString create_function = "CREATE FUNCTION copy_type_id() RETURNS TRIGGER AS $trig$"
							"	BEGIN"
							"		INSERT INTO list_of_types_of_params VALUES"
							"		(NEW.type_id, NEW.tableoid);"
							"		RETURN NULL;"
							"	END;"
							"	$trig$ LANGUAGE plpgsql;";
	db.queryExec(create_function);
//------------------------

//------------------------
	QString create_real = "CREATE TABLE real"
						"("
						"	type_id      integer NOT NULL DEFAULT nextval('type_of_param_seq'),"
						"	def_val      real,"
						"	min          real,"
						"	max          real,"
						"	PRIMARY KEY (type_id)"
						");";
	db.queryExec(create_real);

	QString create_realTr = "CREATE TRIGGER real_trig"
						"	AFTER INSERT ON real"
						"	FOR EACH ROW"
						"	EXECUTE PROCEDURE copy_type_id();";
	db.queryExec(create_realTr);
//------------------------

//------------------------
	QString create_enum = "CREATE TABLE enum"
						"("
						"	type_id      integer NOT NULL DEFAULT nextval('type_of_param_seq'),"
						"	def_val      VARCHAR(40),"
						"	PRIMARY KEY (type_id)"
						");";
	db.queryExec(create_enum);

	QString create_enumTr = "CREATE TRIGGER enum_trig"
						"	AFTER INSERT ON enum"
						"	FOR EACH ROW"
						"	EXECUTE PROCEDURE copy_type_id();";
	db.queryExec(create_enumTr);

	QString create_enumVv = "CREATE TABLE enum_valid_value"
						"("
						"	enum_id              integer,"
						"	vv_id                serial,"
						"	vv_str               VARCHAR(40) NOT NULL,"
						"	vv_int               integer NOT NULL,"
						"	PRIMARY KEY (enum_id, vv_id),"
						"	FOREIGN KEY (enum_id) REFERENCES enum"
						");";
	db.queryExec(create_enumVv);
//------------------------

//------------------------
	QString create_int = "CREATE TABLE int"
						"("
						"	type_id      integer NOT NULL DEFAULT nextval('type_of_param_seq'),"
						"	def_val      integer,"
						"	min          integer,"
						"	max          integer,"
						"	PRIMARY KEY (type_id)"
						");";
	db.queryExec(create_int);

	QString create_intTr = "CREATE TRIGGER int_trig"
						"	AFTER INSERT ON int"
						"	FOR EACH ROW"
						"	EXECUTE PROCEDURE copy_type_id();";
	db.queryExec(create_intTr);
//------------------------

	std::cout << "to be continued...\n";
	getch();
	return 0;
}
<commit_msg> - чистка кода<commit_after>/*!
  \copyright (c) RDO-Team, 2012
  \file      main.cpp
  \authors     (cerevra@gmail.com)
  \authors     (rdo@rk9.bmstu.ru)
  \date      05.11.2012
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#include <iostream>
#include <conio.h>
#include <QtSql\QtSql>
#include <QtCore\QCoreApplication>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator\runtime\test\sql\include\general_db.h"
// --------------------------------------------------------------------------------

void dropDB()
{
	generalDB db("localhost", "postgres", "postgres", "rdo", 5432);
	db.queryExec("DROP DATABASE IF EXISTS rdo;");
	db.queryExec("CREATE DATABASE rdo;");
}

int main(int argc, char *argv[])
{
	QCoreApplication app(argc, argv);

	dropDB();

	generalDB db;

	QSqlQuery query;
//------------------------
	QString create_rtp = "CREATE TABLE rtp"
						"("
						"	r_t_id               serial,"
						"	r_t_name             VARCHAR(40) NOT NULL,"
						"	r_t_perm             boolean NOT NULL,"
						"	PRIMARY KEY (r_t_id)"
						");";
	db.queryExec(create_rtp);

	QString create_list = "CREATE TABLE list_of_types_of_params"
						"("
						"	type_id       integer,"
						"	table_id      integer NOT NULL,"
						"	PRIMARY KEY (type_id)"
						");";
	db.queryExec(create_list);

	QString create_param = "CREATE TABLE param_of_type"
						"("
						"	param_id      serial,"
						"	param_name    VARCHAR(40) NOT NULL,"
						"	r_t_id        integer,"
						"	type_id       integer NOT NULL,"
						"	PRIMARY KEY (param_id,r_t_id),"
						"	FOREIGN KEY (r_t_id) REFERENCES rtp,"
						"	FOREIGN KEY (type_id) REFERENCES list_of_types_of_params"
						");";
	db.queryExec(create_param);
//------------------------

//------------------------
	QString create_seq = "CREATE SEQUENCE type_of_param_seq;";
	db.queryExec(create_seq);

	QString create_function = "CREATE FUNCTION copy_type_id() RETURNS TRIGGER AS $trig$"
							"	BEGIN"
							"		INSERT INTO list_of_types_of_params VALUES"
							"		(NEW.type_id, NEW.tableoid);"
							"		RETURN NULL;"
							"	END;"
							"	$trig$ LANGUAGE plpgsql;";
	db.queryExec(create_function);
//------------------------

//------------------------
	QString create_real = "CREATE TABLE real"
						"("
						"	type_id      integer NOT NULL DEFAULT nextval('type_of_param_seq'),"
						"	def_val      real,"
						"	min          real,"
						"	max          real,"
						"	PRIMARY KEY (type_id)"
						");";
	db.queryExec(create_real);

	QString create_realTr = "CREATE TRIGGER real_trig"
						"	AFTER INSERT ON real"
						"	FOR EACH ROW"
						"	EXECUTE PROCEDURE copy_type_id();";
	db.queryExec(create_realTr);
//------------------------

//------------------------
	QString create_enum = "CREATE TABLE enum"
						"("
						"	type_id      integer NOT NULL DEFAULT nextval('type_of_param_seq'),"
						"	def_val      VARCHAR(40),"
						"	PRIMARY KEY (type_id)"
						");";
	db.queryExec(create_enum);

	QString create_enumTr = "CREATE TRIGGER enum_trig"
						"	AFTER INSERT ON enum"
						"	FOR EACH ROW"
						"	EXECUTE PROCEDURE copy_type_id();";
	db.queryExec(create_enumTr);

	QString create_enumVv = "CREATE TABLE enum_valid_value"
						"("
						"	enum_id              integer,"
						"	vv_id                serial,"
						"	vv_str               VARCHAR(40) NOT NULL,"
						"	vv_int               integer NOT NULL,"
						"	PRIMARY KEY (enum_id, vv_id),"
						"	FOREIGN KEY (enum_id) REFERENCES enum"
						");";
	db.queryExec(create_enumVv);
//------------------------

//------------------------
	QString create_int = "CREATE TABLE int"
						"("
						"	type_id      integer NOT NULL DEFAULT nextval('type_of_param_seq'),"
						"	def_val      integer,"
						"	min          integer,"
						"	max          integer,"
						"	PRIMARY KEY (type_id)"
						");";
	db.queryExec(create_int);

	QString create_intTr = "CREATE TRIGGER int_trig"
						"	AFTER INSERT ON int"
						"	FOR EACH ROW"
						"	EXECUTE PROCEDURE copy_type_id();";
	db.queryExec(create_intTr);
//------------------------

	std::cout << "to be continued...\n";
	getch();
	return 0;
}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2009-2012
  \file      main.cpp
  \authors     (rdo@rk9.bmstu.ru)
  \authors     (lord.tiran@gmail.com)
  \authors     (robot.xet@gmail.com)
  \authors     (cerevra@gmail.com)
  \date      05.03.2013
  \brief     -  RDOValue
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#include <iostream>
#include <boost/bind.hpp>
#define BOOST_TEST_MODULE RDOValue_Test
#include <boost/test/included/unit_test.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/rdo_runtime.h"
#include "simulator/runtime/rdo_res_type.h"
// --------------------------------------------------------------------------------

OPEN_RDO_RUNTIME_NAMESPACE

RDOValue foo()
{
	LPRDOEnumType pRDOEnumType = rdo::Factory<RDOEnumType>::create();

	pRDOEnumType->add(_T("first_record"));
	pRDOEnumType->add(_T("second_record"));

	RDOValue tempObject = RDOValue(pRDOEnumType,_T("second_record"));
	return tempObject;
}

BOOST_AUTO_TEST_SUITE(RDOValue_Test)

BOOST_AUTO_TEST_CASE(RDOValue_String)
{
	RDOValue a = foo();
	int i = 1;
}

BOOST_AUTO_TEST_SUITE_END() // RDOValue_Test

CLOSE_RDO_RUNTIME_NAMESPACE
<commit_msg> - доработка теста<commit_after>/*!
  \copyright (c) RDO-Team, 2009-2012
  \file      main.cpp
  \authors     (rdo@rk9.bmstu.ru)
  \authors     (lord.tiran@gmail.com)
  \authors     (robot.xet@gmail.com)
  \authors     (cerevra@gmail.com)
  \date      05.03.2013
  \brief     -  RDOValue
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#define BOOST_TEST_MODULE RDOValue_Test
#include <boost/test/included/unit_test.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/rdo_runtime.h"
#include "simulator/runtime/rdo_res_type.h"
// --------------------------------------------------------------------------------

OPEN_RDO_RUNTIME_NAMESPACE

#define CREATE_VALUE\
	LPRDOEnumType pRDOEnumType = rdo::Factory<RDOEnumType>::create();\
	pRDOEnumType->add(_T("first_record"));\
	pRDOEnumType->add(_T("second_record"));\
	rdo::runtime::RDOValue tempObject = rdo::runtime::RDOValue(pRDOEnumType,_T("second_record"));

rdo::runtime::RDOValue foo()
{
	CREATE_VALUE;
	return tempObject;
}

BOOST_AUTO_TEST_SUITE(RDOValue_Test)

BOOST_AUTO_TEST_CASE(RDOValue)
{
	CREATE_VALUE;
	rdo::runtime::RDOValue a = foo();

	BOOST_CHECK(tempObject.getAsString() == a.getAsString());
	BOOST_CHECK(tempObject.getEnum()->getValues() == a.getEnum()->getValues());
}

BOOST_AUTO_TEST_SUITE_END() // RDOValue_Test

CLOSE_RDO_RUNTIME_NAMESPACE
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: animationaudionode.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-10 13:49:39 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

// must be first
#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <animationaudionode.hxx>
#include <delayevent.hxx>
#include <tools.hxx>
#include <nodetools.hxx>
#include <generateevent.hxx>

using namespace ::com::sun::star;

namespace presentation
{
    namespace internal
    {
        AnimationAudioNode::AnimationAudioNode( const uno::Reference< animations::XAnimationNode >& xNode,
                                                const BaseContainerNodeSharedPtr&                   rParent,
                                                const NodeContext&                                  rContext ) :
            BaseNode( xNode, rParent, rContext ),
            mxAudioNode( xNode, uno::UNO_QUERY_THROW ),
            mpPlayer()
        {
            ::rtl::OUString aSoundURL;
            mxAudioNode->getSource() >>= aSoundURL;

            OSL_ENSURE( aSoundURL.getLength(),
                        "AnimationAudioNode::AnimationAudioNode(): could not extract sound source URL/empty URL string" );

            ENSURE_AND_THROW( getContext().mxComponentContext.is(),
                              "AnimationAudioNode::AnimationAudioNode(): Invalid component context" );

            try
            {
                mpPlayer = SoundPlayer::create(
                    getContext().mrEventMultiplexer,
                    aSoundURL,
                    getContext().mxComponentContext );
            }
            catch( lang::NoSupportException& )
            {
                // catch possible exceptions from SoundPlayer,
                // since being not able to playback the sound
                // is not a hard error here (remainder of the
                // animations should still work).
            }
        }

        void AnimationAudioNode::dispose()
        {
            if (mpPlayer.get() != 0) {
                mpPlayer->stopPlayback();
                mpPlayer->dispose();
                mpPlayer.reset();
            }

            mxAudioNode.clear();

            BaseNode::dispose();
        }

        bool AnimationAudioNode::activate()
        {
            if( !BaseNode::activate() )
                return false;

            // not having a player is not a hard error here
            // (remainder of the animations should still
            // work). Below, we assume a duration of 0.0 if no
            // player is available
            if( !mpPlayer.get() )
                return false;

            return mpPlayer->startPlayback();
        }

        // TODO(F2): generate deactivation event, when sound
        // is over

        void AnimationAudioNode::deactivate()
        {
            // force-end sound
            if( mpPlayer.get() )
                mpPlayer->stopPlayback();

            // notify state change
            getContext().mrEventMultiplexer.notifyAudioStopped( getSelf() );

            BaseNode::deactivate();
        }

        /** Overridden, because the sound duration normally
            determines effect duration.
        */
        void AnimationAudioNode::scheduleDeactivationEvent() const
        {
            // TODO(F2): Handle end time attribute, too
            if( getXNode()->getDuration().hasValue() )
            {
                BaseNode::scheduleDeactivationEvent();
            }
            else
            {
                if( !mpPlayer.get() )
                {
                    // no duration and no inherent media time
                    // - assume duration '0'
                    getContext().mrEventQueue.addEvent(
                        makeEvent( ::boost::bind(&BaseNode::deactivate,
                                                 ::boost::cref( getSelf() ) ) ) );
                }
                else
                {
                    // no node duration. Take inherent media
                    // time, then
                    getContext().mrEventQueue.addEvent(
                        makeDelay( ::boost::bind(&BaseNode::deactivate,
                                                 ::boost::cref( getSelf() ) ),
                                   mpPlayer->getDuration() ) );

                }
            }
        }

        void AnimationAudioNode::notifyDeactivating( const AnimationNodeSharedPtr& rNotifier )
        {
            // NO-OP for all leaf nodes (which typically don't register nowhere)

            // TODO(F1): for end sync functionality, this might indeed be used some day
        }

        bool AnimationAudioNode::hasPendingAnimation() const
        {
            // force slide to use the animation framework
            // (otherwise, a single sound on the slide would
            // not be played).
            return true;
        }
    }
}
<commit_msg>INTEGRATION: CWS impress36 (1.2.10); FILE MERGED 2005/03/15 18:00:07 cl 1.2.10.2: RESYNC: (1.2-1.3); FILE MERGED 2005/03/02 11:52:10 cl 1.2.10.1: #i43679# added AnimationCommandNode for STOPAUDIO support<commit_after>/*************************************************************************
 *
 *  $RCSfile: animationaudionode.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-18 17:10:56 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

// must be first
#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <animationaudionode.hxx>
#include <delayevent.hxx>
#include <tools.hxx>
#include <nodetools.hxx>
#include <generateevent.hxx>

using namespace ::com::sun::star;

namespace presentation
{
    namespace internal
    {
        AnimationAudioNode::AnimationAudioNode( const uno::Reference< animations::XAnimationNode >& xNode,
                                                const BaseContainerNodeSharedPtr&                   rParent,
                                                const NodeContext&                                  rContext ) :
            BaseNode( xNode, rParent, rContext ),
            mxAudioNode( xNode, uno::UNO_QUERY_THROW ),
            mpPlayer()
        {
            ::rtl::OUString aSoundURL;
            mxAudioNode->getSource() >>= aSoundURL;

            OSL_ENSURE( aSoundURL.getLength(),
                        "AnimationAudioNode::AnimationAudioNode(): could not extract sound source URL/empty URL string" );

            ENSURE_AND_THROW( getContext().mxComponentContext.is(),
                              "AnimationAudioNode::AnimationAudioNode(): Invalid component context" );

            try
            {
                mpPlayer = SoundPlayer::create(
                    getContext().mrEventMultiplexer,
                    aSoundURL,
                    getContext().mxComponentContext );
            }
            catch( lang::NoSupportException& )
            {
                // catch possible exceptions from SoundPlayer,
                // since being not able to playback the sound
                // is not a hard error here (remainder of the
                // animations should still work).
            }
        }

        void AnimationAudioNode::dispose()
        {
            if (mpPlayer.get() != 0) {
                mpPlayer->stopPlayback();
                mpPlayer->dispose();
                mpPlayer.reset();
            }

            mxAudioNode.clear();

            BaseNode::dispose();
        }

        bool AnimationAudioNode::activate()
        {
            if( !BaseNode::activate() )
                return false;

            // not having a player is not a hard error here
            // (remainder of the animations should still
            // work). Below, we assume a duration of 0.0 if no
            // player is available
            if( !mpPlayer.get() )
                return false;

            AnimationEventHandlerSharedPtr aHandler( ::boost::dynamic_pointer_cast<AnimationEventHandler>( getSelf() ) );
            OSL_ENSURE( aHandler.get(), "AnimationAudioNode::activate(): could not cas self to AnimationEventHandler?" );
            getContext().mrEventMultiplexer.addCommandStopAudioHandler( aHandler );

            return mpPlayer->startPlayback();
        }

        // TODO(F2): generate deactivation event, when sound
        // is over

        void AnimationAudioNode::deactivate()
        {
            AnimationEventHandlerSharedPtr aHandler( ::boost::dynamic_pointer_cast<AnimationEventHandler>( getSelf() ) );
            OSL_ENSURE( aHandler.get(), "AnimationAudioNode::deactivate(): could not cas self to AnimationEventHandler?" );
            getContext().mrEventMultiplexer.removeCommandStopAudioHandler( aHandler );

            // force-end sound
            if( mpPlayer.get() )
                mpPlayer->stopPlayback();

            // notify state change
            getContext().mrEventMultiplexer.notifyAudioStopped( getSelf() );

            BaseNode::deactivate();
        }

        /** Overridden, because the sound duration normally
            determines effect duration.
        */
        void AnimationAudioNode::scheduleDeactivationEvent() const
        {
            // TODO(F2): Handle end time attribute, too
            if( getXNode()->getDuration().hasValue() )
            {
                BaseNode::scheduleDeactivationEvent();
            }
            else
            {
                if( !mpPlayer.get() )
                {
                    // no duration and no inherent media time
                    // - assume duration '0'
                    getContext().mrEventQueue.addEvent(
                        makeEvent( ::boost::bind(&BaseNode::deactivate,
                                                 ::boost::cref( getSelf() ) ) ) );
                }
                else
                {
                    // no node duration. Take inherent media
                    // time, then
                    getContext().mrEventQueue.addEvent(
                        makeDelay( ::boost::bind(&BaseNode::deactivate,
                                                 ::boost::cref( getSelf() ) ),
                                   mpPlayer->getDuration() ) );

                }
            }
        }

        void AnimationAudioNode::notifyDeactivating( const AnimationNodeSharedPtr& rNotifier )
        {
            // NO-OP for all leaf nodes (which typically don't register nowhere)

            // TODO(F1): for end sync functionality, this might indeed be used some day
        }

        bool AnimationAudioNode::hasPendingAnimation() const
        {
            // force slide to use the animation framework
            // (otherwise, a single sound on the slide would
            // not be played).
            return true;
        }

        bool AnimationAudioNode::handleAnimationEvent( const AnimationNodeSharedPtr& rNode )
        {
            // TODO: for now we support only STOPAUDIO events.
            deactivate();
            return true;
        }

    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: animationaudionode.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2006-07-26 07:29:16 $
 *
 *  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 INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX
#define INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX

#include "basecontainernode.hxx"
#include "soundplayer.hxx"
#include "com/sun/star/animations/XAnimationNode.hpp"
#include "com/sun/star/animations/XAudio.hpp"

namespace presentation {
namespace internal {

/** Audio node.

    This animation node contains an audio effect. Duration and
    start/stop behaviour is affected by the referenced audio
    file.
*/
class AnimationAudioNode : public BaseNode, public AnimationEventHandler
{
public:
    AnimationAudioNode(
        ::com::sun::star::uno::Reference<
        ::com::sun::star::animations::XAnimationNode> const& xNode,
        ::boost::shared_ptr<BaseContainerNode> const& pParent,
        NodeContext const& rContext );

protected:
    virtual void dispose();

private:
    virtual void activate_st();
    virtual void deactivate_st( NodeState eDestState, bool );
    virtual bool hasPendingAnimation() const;

    /// overriden, because we need to deal with STOPAUDIO commands
    virtual bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode );

private:
    ::com::sun::star::uno::Reference<
        ::com::sun::star::animations::XAudio >  mxAudioNode;
    ::rtl::OUString                             maSoundURL;
    mutable SoundPlayerSharedPtr                mpPlayer;

    void createPlayer() const;
    void resetPlayer() const;
};

} // namespace internal
} // namespace presentation

#endif /* INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX */
<commit_msg>INTEGRATION: CWS sb59 (1.6.8); FILE MERGED 2006/08/23 09:37:07 thb 1.6.8.1: #i68336# Corrected wrong deactivate_st override in AnimationAudioNode<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: animationaudionode.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 13:58:30 $
 *
 *  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 INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX
#define INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX

#include "basecontainernode.hxx"
#include "soundplayer.hxx"
#include "com/sun/star/animations/XAnimationNode.hpp"
#include "com/sun/star/animations/XAudio.hpp"

namespace presentation {
namespace internal {

/** Audio node.

    This animation node contains an audio effect. Duration and
    start/stop behaviour is affected by the referenced audio
    file.
*/
class AnimationAudioNode : public BaseNode, public AnimationEventHandler
{
public:
    AnimationAudioNode(
        ::com::sun::star::uno::Reference<
        ::com::sun::star::animations::XAnimationNode> const& xNode,
        ::boost::shared_ptr<BaseContainerNode> const& pParent,
        NodeContext const& rContext );

protected:
    virtual void dispose();

private:
    virtual void activate_st();
    virtual void deactivate_st( NodeState eDestState );
    virtual bool hasPendingAnimation() const;

    /// overriden, because we need to deal with STOPAUDIO commands
    virtual bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode );

private:
    ::com::sun::star::uno::Reference<
        ::com::sun::star::animations::XAudio >  mxAudioNode;
    ::rtl::OUString                             maSoundURL;
    mutable SoundPlayerSharedPtr                mpPlayer;

    void createPlayer() const;
    void resetPlayer() const;
};

} // namespace internal
} // namespace presentation

#endif /* INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX */
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 */

#include "base/misc.hh"
#include "base/pollevent.hh"
#include "base/types.hh"
#include "sim/async.hh"
#include "sim/eventq.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/simulate.hh"
#include "sim/stat_control.hh"

/** Simulate for num_cycles additional cycles.  If num_cycles is -1
 * (the default), do not limit simulation; some other event must
 * terminate the loop.  Exported to Python via SWIG.
 * @return The SimLoopExitEvent that caused the loop to exit.
 */
SimLoopExitEvent *
simulate(Tick num_cycles)
{
    inform("Entering event queue @ %d.  Starting simulation...\n", curTick());

    if (num_cycles < 0)
        fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles);
    else if (curTick() + num_cycles < 0)  //Overflow
        num_cycles = MaxTick;
    else
        num_cycles = curTick() + num_cycles;

    Event *limit_event =
        new SimLoopExitEvent("simulate() limit reached", 0);
    mainEventQueue.schedule(limit_event, num_cycles);

    while (1) {
        // there should always be at least one event (the SimLoopExitEvent
        // we just scheduled) in the queue
        assert(!mainEventQueue.empty());
        assert(curTick() <= mainEventQueue.nextTick() &&
               "event scheduled in the past");

        // forward current cycle to the time of the first event on the
        // queue
        curTick(mainEventQueue.nextTick());
        Event *exit_event = mainEventQueue.serviceOne();
        if (exit_event != NULL) {
            // hit some kind of exit event; return to Python
            // event must be subclass of SimLoopExitEvent...
            SimLoopExitEvent *se_event;
            se_event = dynamic_cast<SimLoopExitEvent *>(exit_event);

            if (se_event == NULL)
                panic("Bogus exit event class!");

            // if we didn't hit limit_event, delete it
            if (se_event != limit_event) {
                assert(limit_event->scheduled());
                limit_event->squash();
                hack_once("be nice to actually delete the event here");
            }

            return se_event;
        }

        if (async_event) {
            async_event = false;
            if (async_statdump || async_statreset) {
                Stats::schedStatEvent(async_statdump, async_statreset);
                async_statdump = false;
                async_statreset = false;
            }

            if (async_exit) {
                async_exit = false;
                exitSimLoop("user interrupt received");
            }

            if (async_io || async_alarm) {
                async_io = false;
                async_alarm = false;
                pollQueue.service();
            }

            if (async_exception) {
                async_exception = false;
                return NULL;
            }
        }
    }

    // not reached... only exit is return on SimLoopExitEvent
}

<commit_msg>sim: fix overflow check in simulate because Tick is now unsigned<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 */

#include "base/misc.hh"
#include "base/pollevent.hh"
#include "base/types.hh"
#include "sim/async.hh"
#include "sim/eventq.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/simulate.hh"
#include "sim/stat_control.hh"

/** Simulate for num_cycles additional cycles.  If num_cycles is -1
 * (the default), do not limit simulation; some other event must
 * terminate the loop.  Exported to Python via SWIG.
 * @return The SimLoopExitEvent that caused the loop to exit.
 */
SimLoopExitEvent *
simulate(Tick num_cycles)
{
    inform("Entering event queue @ %d.  Starting simulation...\n", curTick());

    if (num_cycles < MaxTick - curTick())
        num_cycles = curTick() + num_cycles;
    else // counter would roll over or be set to MaxTick anyhow
        num_cycles = MaxTick;

    Event *limit_event =
        new SimLoopExitEvent("simulate() limit reached", 0);
    mainEventQueue.schedule(limit_event, num_cycles);

    while (1) {
        // there should always be at least one event (the SimLoopExitEvent
        // we just scheduled) in the queue
        assert(!mainEventQueue.empty());
        assert(curTick() <= mainEventQueue.nextTick() &&
               "event scheduled in the past");

        // forward current cycle to the time of the first event on the
        // queue
        curTick(mainEventQueue.nextTick());
        Event *exit_event = mainEventQueue.serviceOne();
        if (exit_event != NULL) {
            // hit some kind of exit event; return to Python
            // event must be subclass of SimLoopExitEvent...
            SimLoopExitEvent *se_event;
            se_event = dynamic_cast<SimLoopExitEvent *>(exit_event);

            if (se_event == NULL)
                panic("Bogus exit event class!");

            // if we didn't hit limit_event, delete it
            if (se_event != limit_event) {
                assert(limit_event->scheduled());
                limit_event->squash();
                hack_once("be nice to actually delete the event here");
            }

            return se_event;
        }

        if (async_event) {
            async_event = false;
            if (async_statdump || async_statreset) {
                Stats::schedStatEvent(async_statdump, async_statreset);
                async_statdump = false;
                async_statreset = false;
            }

            if (async_exit) {
                async_exit = false;
                exitSimLoop("user interrupt received");
            }

            if (async_io || async_alarm) {
                async_io = false;
                async_alarm = false;
                pollQueue.service();
            }

            if (async_exception) {
                async_exception = false;
                return NULL;
            }
        }
    }

    // not reached... only exit is return on SimLoopExitEvent
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2021 dresden elektronik ingenieurtechnik gmbh.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 *
 */

#include "device.h"
#include "device_compat.h"
#include "device_descriptions.h"
#include "device_ddf_init.h"
#include "database.h"

// TODO move external declaration in de_web_plugin_private.h into utils.h
QString generateUniqueId(quint64 extAddress, quint8 endpoint, quint16 clusterId);

static QString uniqueIdFromTemplate(const QStringList &templ, const quint64 extAddress)
{
    bool ok = false;
    quint8 endpoint = 0;
    quint16 clusterId = 0;

    // <mac>-<endpoint>
    // <mac>-<endpoint>-<cluster>
    if (templ.size() > 1 && templ.first() == QLatin1String("$address.ext"))
    {
        endpoint = templ.at(1).toUInt(&ok, 0);

        if (ok && templ.size() > 2)
        {
            clusterId = templ.at(2).toUInt(&ok, 0);
        }
    }

    if (ok)
    {
        return generateUniqueId(extAddress, endpoint, clusterId);
    }

    return {};
}

/*! Creates a ResourceItem if not exist, initialized with \p ddfItem content.
 */
static ResourceItem *DEV_InitDeviceDescriptionItem(const DeviceDescription::Item &ddfItem, Resource *rsub)
{
    Q_ASSERT(rsub);
    Q_ASSERT(ddfItem.isValid());

    auto *item = rsub->item(ddfItem.descriptor.suffix);
    const auto uniqueId = rsub->item(RAttrUniqueId)->toString();

    if (item)
    {
        DBG_Printf(DBG_INFO, "sub-device: %s, has item: %s\n", qPrintable(uniqueId), ddfItem.descriptor.suffix);
    }
    else
    {
        DBG_Printf(DBG_INFO, "sub-device: %s, create item: %s\n", qPrintable(uniqueId), ddfItem.descriptor.suffix);
        item = rsub->addItem(ddfItem.descriptor.type, ddfItem.descriptor.suffix);

        if (!item)
        {
            return nullptr;
        }

    }

    if (ddfItem.defaultValue.isValid() && !item->lastSet().isValid())
    {
        item->setValue(ddfItem.defaultValue);
    }

    Q_ASSERT(item);

    // check updates
    item->setIsPublic(ddfItem.isPublic);
    item->setAwake(ddfItem.awake);

    if (ddfItem.refreshInterval >= 0)
    {
        item->setRefreshInterval(ddfItem.refreshInterval);
    }

    if (item->parseParameters() != ddfItem.parseParameters)
    {
        item->setParseFunction(nullptr);
        item->setParseParameters(ddfItem.parseParameters);
    }

    if (item->readParameters() != ddfItem.readParameters)
    {
        item->setReadParameters(ddfItem.readParameters);
    }

    if (item->writeParameters() != ddfItem.writeParameters)
    {
        item->setWriteParameters(ddfItem.writeParameters);
    }

    return item;
}

/*! Creates and initialises sub-device Resources and ResourceItems if not already present.

    This function can replace database and joining device initialisation.
 */
bool DEV_InitDeviceFromDescription(Device *device, const DeviceDescription &description)
{
    Q_ASSERT(device);
    Q_ASSERT(description.isValid());

    size_t subCount = 0;

    for (const auto &sub : description.subDevices)
    {
        Q_ASSERT(sub.isValid());

        const auto uniqueId = uniqueIdFromTemplate(sub.uniqueId, device->item(RAttrExtAddress)->toNumber());
        Resource *rsub = DEV_GetSubDevice(device, nullptr, uniqueId);

        if (!rsub)
        {
            rsub = DEV_InitCompatNodeFromDescription(device, sub, uniqueId);
        }

        if (!rsub)
        {
            DBG_Printf(DBG_INFO, "sub-device: %s, failed to setup: %s\n", qPrintable(uniqueId), qPrintable(sub.type));
            return false;
        }

        subCount++;

        auto *mf = rsub->item(RAttrManufacturerName);
        if (mf && mf->toString().isEmpty())
        {
            mf->setValue(DeviceDescriptions::instance()->constantToString(description.manufacturer));
        }

        DB_StoreSubDevice(rsub);

        DB_StoreSubDeviceItem(rsub, rsub->item(RAttrManufacturerName));
        DB_StoreSubDeviceItem(rsub, rsub->item(RAttrModelId));

        for (const auto &ddfItem : sub.items)
        {
            auto *item = DEV_InitDeviceDescriptionItem(ddfItem, rsub);
            if (!item)
            {
                continue;
            }

            if (item->descriptor().suffix == RConfigCheckin)
            {
                StateChange stateChange(StateChange::StateWaitSync, SC_WriteZclAttribute, sub.uniqueId.at(1).toUInt());
                stateChange.addTargetValue(RConfigCheckin, ddfItem.defaultValue);
                stateChange.setChangeTimeoutMs(1000 * 60 * 60);
                rsub->addStateChange(stateChange);
            }
        }
    }

    if (description.sleeper >= 0)
    {
        device->item(RAttrSleeper)->setValue(description.sleeper == 1);
    }

    return subCount == description.subDevices.size();
}

<commit_msg>DEV: config/checkin disable state change (for now)<commit_after>/*
 * Copyright (c) 2021 dresden elektronik ingenieurtechnik gmbh.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 *
 */

#include "device.h"
#include "device_compat.h"
#include "device_descriptions.h"
#include "device_ddf_init.h"
#include "database.h"

// TODO move external declaration in de_web_plugin_private.h into utils.h
QString generateUniqueId(quint64 extAddress, quint8 endpoint, quint16 clusterId);

static QString uniqueIdFromTemplate(const QStringList &templ, const quint64 extAddress)
{
    bool ok = false;
    quint8 endpoint = 0;
    quint16 clusterId = 0;

    // <mac>-<endpoint>
    // <mac>-<endpoint>-<cluster>
    if (templ.size() > 1 && templ.first() == QLatin1String("$address.ext"))
    {
        endpoint = templ.at(1).toUInt(&ok, 0);

        if (ok && templ.size() > 2)
        {
            clusterId = templ.at(2).toUInt(&ok, 0);
        }
    }

    if (ok)
    {
        return generateUniqueId(extAddress, endpoint, clusterId);
    }

    return {};
}

/*! Creates a ResourceItem if not exist, initialized with \p ddfItem content.
 */
static ResourceItem *DEV_InitDeviceDescriptionItem(const DeviceDescription::Item &ddfItem, Resource *rsub)
{
    Q_ASSERT(rsub);
    Q_ASSERT(ddfItem.isValid());

    auto *item = rsub->item(ddfItem.descriptor.suffix);
    const auto uniqueId = rsub->item(RAttrUniqueId)->toString();

    if (item)
    {
        DBG_Printf(DBG_INFO, "sub-device: %s, has item: %s\n", qPrintable(uniqueId), ddfItem.descriptor.suffix);
    }
    else
    {
        DBG_Printf(DBG_INFO, "sub-device: %s, create item: %s\n", qPrintable(uniqueId), ddfItem.descriptor.suffix);
        item = rsub->addItem(ddfItem.descriptor.type, ddfItem.descriptor.suffix);

        if (!item)
        {
            return nullptr;
        }

    }

    if (ddfItem.defaultValue.isValid() && !item->lastSet().isValid())
    {
        item->setValue(ddfItem.defaultValue);
    }

    Q_ASSERT(item);

    // check updates
    item->setIsPublic(ddfItem.isPublic);
    item->setAwake(ddfItem.awake);

    if (ddfItem.refreshInterval >= 0)
    {
        item->setRefreshInterval(ddfItem.refreshInterval);
    }

    if (item->parseParameters() != ddfItem.parseParameters)
    {
        item->setParseFunction(nullptr);
        item->setParseParameters(ddfItem.parseParameters);
    }

    if (item->readParameters() != ddfItem.readParameters)
    {
        item->setReadParameters(ddfItem.readParameters);
    }

    if (item->writeParameters() != ddfItem.writeParameters)
    {
        item->setWriteParameters(ddfItem.writeParameters);
    }

    return item;
}

/*! Creates and initialises sub-device Resources and ResourceItems if not already present.

    This function can replace database and joining device initialisation.
 */
bool DEV_InitDeviceFromDescription(Device *device, const DeviceDescription &description)
{
    Q_ASSERT(device);
    Q_ASSERT(description.isValid());

    size_t subCount = 0;

    for (const auto &sub : description.subDevices)
    {
        Q_ASSERT(sub.isValid());

        const auto uniqueId = uniqueIdFromTemplate(sub.uniqueId, device->item(RAttrExtAddress)->toNumber());
        Resource *rsub = DEV_GetSubDevice(device, nullptr, uniqueId);

        if (!rsub)
        {
            rsub = DEV_InitCompatNodeFromDescription(device, sub, uniqueId);
        }

        if (!rsub)
        {
            DBG_Printf(DBG_INFO, "sub-device: %s, failed to setup: %s\n", qPrintable(uniqueId), qPrintable(sub.type));
            return false;
        }

        subCount++;

        auto *mf = rsub->item(RAttrManufacturerName);
        if (mf && mf->toString().isEmpty())
        {
            mf->setValue(DeviceDescriptions::instance()->constantToString(description.manufacturer));
        }

        DB_StoreSubDevice(rsub);

        DB_StoreSubDeviceItem(rsub, rsub->item(RAttrManufacturerName));
        DB_StoreSubDeviceItem(rsub, rsub->item(RAttrModelId));

        for (const auto &ddfItem : sub.items)
        {
            auto *item = DEV_InitDeviceDescriptionItem(ddfItem, rsub);
            if (!item)
            {
                continue;
            }

//            if (item->descriptor().suffix == RConfigCheckin)
//            {
//                StateChange stateChange(StateChange::StateWaitSync, SC_WriteZclAttribute, sub.uniqueId.at(1).toUInt());
//                stateChange.addTargetValue(RConfigCheckin, ddfItem.defaultValue);
//                stateChange.setChangeTimeoutMs(1000 * 60 * 60);
//                rsub->addStateChange(stateChange);
//            }
        }
    }

    if (description.sleeper >= 0)
    {
        device->item(RAttrSleeper)->setValue(description.sleeper == 1);
    }

    return subCount == description.subDevices.size();
}

<|endoftext|>


<commit_before>/*
Resembla
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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.
*/

#ifndef RESEMBLA_KEYWORD_MATCH_PREPROCESSOR_HPP
#define RESEMBLA_KEYWORD_MATCH_PREPROCESSOR_HPP

#include <string>
#include <vector>
#include <memory>

#include <json.hpp>

#include "../string_util.hpp"
#include "romaji_preprocessor.hpp"

#ifdef DEBUG
#include <iostream>
#endif

namespace resembla {

template<typename string_type, typename Indexer>
class KeywordMatchPreprocessor
{
public:
    struct output_type
    {
        string_type text;
        std::vector<string_type> keywords;
    };

    KeywordMatchPreprocessor(std::shared_ptr<Indexer> index_func): index_func(index_func)
    {
        // TODO: loadSynonyms(synonym_path);
    }

    output_type operator()(const string_type& raw_text, bool is_original = false) const
    {
        if(!is_original){
            return {(*index_func)(raw_text), {}};
        }

        const auto key = cast_string<string_type>("keyword");
        auto columns = split(raw_text, column_delimiter<typename string_type::value_type>());
        if(columns.size() > 1){
            for(auto f: split(columns[1], attribute_delimiter<typename string_type::value_type>())){
                auto kv = split(f, keyvalue_delimiter<typename string_type::value_type>());
                if(kv.size() == 2 && kv[0] == key){
#ifdef DEBUG
                    for(auto w: split(kv[1], value_delimiter<typename string_type::value_type>())){
                        std::cerr << "load keyword: text=" << cast_string<std::string>((*index_func)(columns[0])) <<
                            ", keyword=" << cast_string<std::string>((*index_func)(w)) << std::endl;
                    }
#endif
                    std::vector<string_type> keywords;
                    for(auto w: split(kv[1], value_delimiter<typename string_type::value_type>())){
                        keywords.push_back((*index_func)(w));
                    }
                    return {(*index_func)(columns[0]), keywords};
                }
            }
            return {(*index_func)(columns[0]), {}};
        }
        return {(*index_func)(raw_text), {}};
    }

protected:
    std::shared_ptr<Indexer> index_func;

// TODO: use synonym dictionary to improve keyword matching quality
//    std::vector<std::vector<string_type>> synonyms;
//    std::unordered_map<string_type, size_t> synonym_index;
};

// TODO: implement as template functions
void to_json(nlohmann::json& j,
        const typename KeywordMatchPreprocessor<string_type, RomajiPreprocessor>::output_type& o);
void from_json(const nlohmann::json& j,
        typename KeywordMatchPreprocessor<string_type, RomajiPreprocessor>::output_type& o);

}
#endif
<commit_msg>modify template class name<commit_after>/*
Resembla
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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.
*/

#ifndef RESEMBLA_KEYWORD_MATCH_PREPROCESSOR_HPP
#define RESEMBLA_KEYWORD_MATCH_PREPROCESSOR_HPP

#include <string>
#include <vector>
#include <memory>

#include <json.hpp>

#include "../string_util.hpp"
#include "romaji_preprocessor.hpp"

#ifdef DEBUG
#include <iostream>
#endif

namespace resembla {

template<typename string_type, typename StringPreprocessor>
class KeywordMatchPreprocessor
{
public:
    struct output_type
    {
        string_type text;
        std::vector<string_type> keywords;
    };

    KeywordMatchPreprocessor(std::shared_ptr<StringPreprocessor> preprocess): preprocess(preprocess)
    {
        // TODO: loadSynonyms(synonym_path);
    }

    output_type operator()(const string_type& raw_text, bool is_original = false) const
    {
        if(!is_original){
            return {(*preprocess)(raw_text), {}};
        }

        const auto key = cast_string<string_type>("keyword");
        auto columns = split(raw_text, column_delimiter<typename string_type::value_type>());
        if(columns.size() > 1){
            auto preprocessed_text = (*preprocess)(columns[0]);
            for(auto f: split(columns[1], attribute_delimiter<typename string_type::value_type>())){
                auto kv = split(f, keyvalue_delimiter<typename string_type::value_type>());
                if(kv.size() == 2 && kv[0] == key){
#ifdef DEBUG
                    for(auto w: split(kv[1], value_delimiter<typename string_type::value_type>())){
                        std::cerr << "load keyword: text=" << cast_string<std::string>((*preprocess)(columns[0])) <<
                            ", keyword=" << cast_string<std::string>((*preprocess)(w)) << std::endl;
                    }
#endif
                    std::vector<string_type> keywords;
                    for(auto w: split(kv[1], value_delimiter<typename string_type::value_type>())){
                        keywords.push_back((*preprocess)(w));
                    }
                    return {preprocessed_text, keywords};
                }
            }
            return {preprocessed_text, {}};
        }
        return {(*preprocess)(raw_text), {}};
    }

protected:
    std::shared_ptr<StringPreprocessor> preprocess;

// TODO: use synonym dictionary to improve keyword matching quality
//    std::vector<std::vector<string_type>> synonyms;
//    std::unordered_map<string_type, size_t> synonym_index;
};

// TODO: implement as template functions
void to_json(nlohmann::json& j,
        const typename KeywordMatchPreprocessor<string_type, RomajiPreprocessor>::output_type& o);
void from_json(const nlohmann::json& j,
        typename KeywordMatchPreprocessor<string_type, RomajiPreprocessor>::output_type& o);

}
#endif
<|endoftext|>


<commit_before>#include "columns_to_blocks.hpp"

namespace mlpack {
namespace math {

ColumnsToBlocks::ColumnsToBlocks(const size_t rows,
                                 const size_t cols,
                                 const size_t blockHeight,
                                 const size_t blockWidth) :
    blockHeight(blockHeight),
    blockWidth(blockWidth),
    bufSize(1),
    bufValue(-1),
    minRange(0),
    maxRange(255),
    scale(false),
    rows(rows),
    cols(cols)
{
}

bool ColumnsToBlocks::IsPerfectSquare(const size_t value) const
{
  if (value < 0)
  {
    return false;
  }

  const int root = std::round(std::sqrt(value));
  return value == root * root;
}

void ColumnsToBlocks::Transform(const arma::mat& maximalInputs,
                                arma::mat& output)
{
  if (!IsPerfectSquare(maximalInputs.n_rows))
  {
    throw std::runtime_error("maximalInputs.n_rows should be perfect square");
  }

  if (blockHeight == 0 || blockWidth == 0)
  {
    size_t const squareRows =
        static_cast<size_t>(std::sqrt(maximalInputs.n_rows));
    blockHeight = squareRows;
    blockWidth = squareRows;
  }

  if (blockHeight * blockWidth != maximalInputs.n_rows)
  {
    throw std::runtime_error("blockHeight * blockWidth should "
                             "equal to maximalInputs.n_rows");
  }

  const size_t rowOffset = blockHeight+bufSize;
  const size_t colOffset = blockWidth+bufSize;
  output.ones(bufSize + rows * rowOffset,
              bufSize + cols * colOffset);
  output *= bufValue;

  size_t k = 0;
  const size_t maxSize = std::min(rows * cols, (size_t) maximalInputs.n_cols);
  for (size_t i = 0; i != rows; ++i)
  {
    for (size_t j = 0; j != cols; ++j)
    {
      // Now, copy the elements of the row to the output submatrix.
      const size_t minRow = bufSize + i * rowOffset;
      const size_t minCol = bufSize + j * colOffset;
      const size_t maxRow = i * rowOffset + blockHeight;
      const size_t maxCol = j * colOffset + blockWidth;

      output.submat(minRow, minCol, maxRow, maxCol) =
          arma::reshape(maximalInputs.col(k++), blockHeight, blockWidth);

      if (k >= maxSize)
        break;
    }
  }

  if (scale)
  {
    const double max = output.max();
    const double min = output.min();
    if ((max - min) != 0)
    {
      output = (output - min) / (max - min) * (maxRange - minRange) + minRange;
    }
  }
}

} // namespace math
} // namespace mlpack
<commit_msg>The positivity check is unnecessary -- it's a size_t.<commit_after>#include "columns_to_blocks.hpp"

namespace mlpack {
namespace math {

ColumnsToBlocks::ColumnsToBlocks(const size_t rows,
                                 const size_t cols,
                                 const size_t blockHeight,
                                 const size_t blockWidth) :
    blockHeight(blockHeight),
    blockWidth(blockWidth),
    bufSize(1),
    bufValue(-1),
    minRange(0),
    maxRange(255),
    scale(false),
    rows(rows),
    cols(cols)
{
}

bool ColumnsToBlocks::IsPerfectSquare(const size_t value) const
{
  const size_t root = (size_t) std::round(std::sqrt(value));
  return (value == root * root);
}

void ColumnsToBlocks::Transform(const arma::mat& maximalInputs,
                                arma::mat& output)
{
  if (!IsPerfectSquare(maximalInputs.n_rows))
  {
    throw std::runtime_error("maximalInputs.n_rows should be perfect square");
  }

  if (blockHeight == 0 || blockWidth == 0)
  {
    size_t const squareRows =
        static_cast<size_t>(std::sqrt(maximalInputs.n_rows));
    blockHeight = squareRows;
    blockWidth = squareRows;
  }

  if (blockHeight * blockWidth != maximalInputs.n_rows)
  {
    throw std::runtime_error("blockHeight * blockWidth should "
                             "equal to maximalInputs.n_rows");
  }

  const size_t rowOffset = blockHeight+bufSize;
  const size_t colOffset = blockWidth+bufSize;
  output.ones(bufSize + rows * rowOffset,
              bufSize + cols * colOffset);
  output *= bufValue;

  size_t k = 0;
  const size_t maxSize = std::min(rows * cols, (size_t) maximalInputs.n_cols);
  for (size_t i = 0; i != rows; ++i)
  {
    for (size_t j = 0; j != cols; ++j)
    {
      // Now, copy the elements of the row to the output submatrix.
      const size_t minRow = bufSize + i * rowOffset;
      const size_t minCol = bufSize + j * colOffset;
      const size_t maxRow = i * rowOffset + blockHeight;
      const size_t maxCol = j * colOffset + blockWidth;

      output.submat(minRow, minCol, maxRow, maxCol) =
          arma::reshape(maximalInputs.col(k++), blockHeight, blockWidth);

      if (k >= maxSize)
        break;
    }
  }

  if (scale)
  {
    const double max = output.max();
    const double min = output.min();
    if ((max - min) != 0)
    {
      output = (output - min) / (max - min) * (maxRange - minRange) + minRange;
    }
  }
}

} // namespace math
} // namespace mlpack
<|endoftext|>


<commit_before>/**
 * @file trainer.hpp
 * @author Marcus Edel
 *
 * Definition and implementation of a trainer that trains the parameters of a
 * neural network according to a supervised dataset.
 */
#ifndef __MLPACK_METHODS_ANN_TRAINER_TRAINER_HPP
#define __MLPACK_METHODS_ANN_TRAINER_TRAINER_HPP

#include <mlpack/core.hpp>

#include <mlpack/methods/ann/network_traits.hpp>
#include <mlpack/methods/ann/layer/layer_traits.hpp>
#include <mlpack/methods/ann/layer/neuron_layer.hpp>

namespace mlpack {
namespace ann /** Artificial Neural Network. */ {

/**
 * Trainer that trains the parameters of a neural network according to a
 * supervised dataset.
 *
 * @tparam NetworkType The type of network which should be trained and
 * evaluated.
 * @tparam MaType Type of the error type (arma::mat or arma::sp_mat).
 * @tparam VecType Type of error type (arma::colvec, arma::mat or arma::sp_mat).
 */
template<
  typename NetworkType,
  typename MatType = arma::mat,
  typename VecType = arma::colvec
>
class Trainer
{
  public:
    /**
     * Construct the Trainer object, which will be used to train a neural
     * network according to a supervised dataset by backpropagating the errors.
     *
     * If batchSize is greater 1 the trainer will take a mean gradient step over
     * this many samples and will update the parameters only at the end of
     * each epoch (Default 1).
     *
     * @param net The network that should be trained.
     * @param maxEpochs The number of maximal trained iterations (0 means no
     * limit).
     * @param batchSize The batch size used to train the network.
     * @param tolerance Train the network until it converges against
     * the specified threshold.
     * @param shuffle If true, the order of the training set is shuffled;
     * otherwise, each data is visited in linear order.
     */
    Trainer(NetworkType& net,
            const size_t maxEpochs = 0,
            const size_t batchSize = 1,
            const double tolerance = 0.0001,
            const bool shuffle = true) :
        net(net),
        maxEpochs(maxEpochs),
        batchSize(batchSize),
        tolerance(tolerance),
        shuffle(shuffle)
    {
      // Nothing to do here.
    }

    /**
     * Train the network on the given datasets until the network converges. If
     * maxEpochs is greater than zero that many epochs are maximal trained.
     *
     * @param trainingData Data used to train the network.
     * @param trainingLabels Labels used to train the network.
     * @param validationData Data used to evaluate the network.
     * @tparam validationLabels Labels used to evaluate the network.
     */
    template<typename InputType, typename OutputType>
    void Train(InputType& trainingData,
               OutputType& trainingLabels,
               InputType& validationData,
               OutputType& validationLabels)
    {
      Index(trainingData);
      epoch = 0;

      while(true)
      {
        if (shuffle)
          index = arma::shuffle(index);

        Train(trainingData, trainingLabels);
        Evaluate(validationData, validationLabels);

        if (validationError <= tolerance)
          break;

        if (maxEpochs > 0 && ++epoch >= maxEpochs)
          break;
      }
    }

    //! Get the training error.
    double TrainingError() const { return trainingError; }

    //! Get the validation error.
    double ValidationError() const { return validationError; }

    //! Get whether or not the individual inputs are shuffled.
    bool Shuffle() const { return shuffle; }
    //! Modify whether or not the individual inputs are shuffled.
    bool& Shuffle() { return shuffle; }

    //! Get the batch size.
    size_t StepSize() const { return batchSize; }
    //! Modify the batch size.
    size_t& StepSize() { return batchSize; }

    //! Get the maximum number of iterations (0 indicates no limit).
    size_t MaxEpochs() const { return maxEpochs; }
    //! Modify the maximum number of iterations (0 indicates no limit).
    size_t& MaxEpochs() { return maxEpochs; }

    //! Get the tolerance for termination.
    double Tolerance() const { return tolerance; }
    //! Modify the tolerance for termination.
    double& Tolerance() { return tolerance; }

  private:
    /**
     * Train the network on the given dataset.
     *
     * @param data Data used to train the network.
     * @param target Labels used to train the network.
     */
    template<typename InputType, typename OutputType>
    void Train(InputType& data, OutputType& target)
    {
      // Reset the training error.
      trainingError = 0;

      for (size_t i = 0; i < data.n_cols; i++)
      {
        net.FeedForward(Element(data, index(i)),
            Element(target, index(i)), error);

        trainingError += net.Error();
        net.FeedBackward(error);

        if (((i + 1) % batchSize) == 0)
          net.ApplyGradients();
      }

      if ((data.n_cols % batchSize) != 0)
        net.ApplyGradients();

      trainingError /= data.n_cols;
    }

    /**
     * Evaluate the network on the given dataset.
     *
     * @param data Data used to train the network.
     * @param target Labels used to train the network.
     */
    template<typename InputType, typename OutputType>
    void Evaluate(InputType& data, OutputType& target)
    {
      // Reset the validation error.
      validationError = 0;

      for (size_t i = 0; i < data.n_cols; i++)
      {
         validationError += net.Evaluate(Element(data, i),
            Element(target, i), error);
      }

      validationError /= data.n_cols;
    }

    /*
     * Generate index sequence to iterate through the data.
     *
     * @param input The reference data.
     */
    template<typename eT>
    void Index(const arma::Mat<eT>& input)
    {
      // This generates [0 1 2 3 ... (input.n_cols - 1)]. The sequence
      // will be used to iterate through the training data.
      index = arma::linspace<arma::Col<size_t> >(0, input.n_cols - 1,
          input.n_cols);
    }

    /*
     * Generate index sequence to iterate through the data.
     *
     * @param input The reference data.
     */
    template<typename eT>
    void Index(const arma::Cube<eT>& input)
    {
      // This generates [0 1 2 3 ... (input.n_slices - 1)]. The sequence
      // will be used to iterate through the training data.
      index = arma::linspace<arma::Col<size_t> >(0, input.n_slices - 1,
          input.n_slices);
    }

    /*
     * Create a Col object which uses memory from an existing matrix object.
     * (This approach is currently not alias safe)
     *
     * @param data The reference data.
     * @param sliceNum Provide a Col object of the specified index.
     */
    template<typename eT>
    arma::Col<eT> Element(arma::Mat<eT>& input, const size_t colNum)
    {
      return arma::Col<eT>(input.colptr(colNum), input.n_rows, false, true);
    }

    /*
     * Provide the reference to the matrix representing a single slice.
     *
     * @param data The reference data.
     * @param sliceNum Provide a single slice of the specified index.
     */
    template<typename eT>
    const arma::Mat<eT>& Element(arma::Cube<eT>& input,
        const size_t sliceNum)
    {
      return *(input.mat_ptrs[sliceNum]);
    }

    //! The network which should be trained and evaluated.
    NetworkType& net;

    //! The current network error of a single input.
    typename std::conditional<NetworkTraits<NetworkType>::IsFNN,
        VecType, MatType>::type error;

    //! The current epoch if maxEpochs is set.
    size_t epoch;

    //! The maximal epochs that should be used.
    size_t maxEpochs;

    //! The size until a update is performed.
    size_t batchSize;

    //! The shuffel sequence index used to train the network.
    arma::Col<size_t> index;

    //! The overall traing error.
    double trainingError;

    //! The overall validation error.
    double validationError;

    //! The tolerance for termination.
    double tolerance;

    //! Controls whether or not the individual inputs are shuffled when
    //! iterating.
    bool shuffle;
}; // class Trainer

}; // namespace ann
}; // namespace mlpack

#endif
<commit_msg>Add function to get the number of cols/slices. Thanks Shangtong for pointing this out.<commit_after>/**
 * @file trainer.hpp
 * @author Marcus Edel
 *
 * Definition and implementation of a trainer that trains the parameters of a
 * neural network according to a supervised dataset.
 */
#ifndef __MLPACK_METHODS_ANN_TRAINER_TRAINER_HPP
#define __MLPACK_METHODS_ANN_TRAINER_TRAINER_HPP

#include <mlpack/core.hpp>

#include <mlpack/methods/ann/network_traits.hpp>
#include <mlpack/methods/ann/layer/layer_traits.hpp>
#include <mlpack/methods/ann/layer/neuron_layer.hpp>

namespace mlpack {
namespace ann /** Artificial Neural Network. */ {

/**
 * Trainer that trains the parameters of a neural network according to a
 * supervised dataset.
 *
 * @tparam NetworkType The type of network which should be trained and
 * evaluated.
 * @tparam MaType Type of the error type (arma::mat or arma::sp_mat).
 * @tparam VecType Type of error type (arma::colvec, arma::mat or arma::sp_mat).
 */
template<
  typename NetworkType,
  typename MatType = arma::mat,
  typename VecType = arma::colvec
>
class Trainer
{
  public:
    /**
     * Construct the Trainer object, which will be used to train a neural
     * network according to a supervised dataset by backpropagating the errors.
     *
     * If batchSize is greater 1 the trainer will take a mean gradient step over
     * this many samples and will update the parameters only at the end of
     * each epoch (Default 1).
     *
     * @param net The network that should be trained.
     * @param maxEpochs The number of maximal trained iterations (0 means no
     * limit).
     * @param batchSize The batch size used to train the network.
     * @param tolerance Train the network until it converges against
     * the specified threshold.
     * @param shuffle If true, the order of the training set is shuffled;
     * otherwise, each data is visited in linear order.
     */
    Trainer(NetworkType& net,
            const size_t maxEpochs = 0,
            const size_t batchSize = 1,
            const double tolerance = 0.0001,
            const bool shuffle = true) :
        net(net),
        maxEpochs(maxEpochs),
        batchSize(batchSize),
        tolerance(tolerance),
        shuffle(shuffle)
    {
      // Nothing to do here.
    }

    /**
     * Train the network on the given datasets until the network converges. If
     * maxEpochs is greater than zero that many epochs are maximal trained.
     *
     * @param trainingData Data used to train the network.
     * @param trainingLabels Labels used to train the network.
     * @param validationData Data used to evaluate the network.
     * @tparam validationLabels Labels used to evaluate the network.
     */
    template<typename InputType, typename OutputType>
    void Train(InputType& trainingData,
               OutputType& trainingLabels,
               InputType& validationData,
               OutputType& validationLabels)
    {
      // This generates [0 1 2 3 ... (ElementCount(trainingData) - 1)]. The
      // sequence will be used to iterate through the training data.
      index = arma::linspace<arma::Col<size_t> >(0,
          ElementCount(trainingData) - 1, ElementCount(trainingData));
      epoch = 0;

      while(true)
      {
        if (shuffle)
          index = arma::shuffle(index);

        Train(trainingData, trainingLabels);
        Evaluate(validationData, validationLabels);

        if (validationError <= tolerance)
          break;

        if (maxEpochs > 0 && ++epoch >= maxEpochs)
          break;
      }
    }

    //! Get the training error.
    double TrainingError() const { return trainingError; }

    //! Get the validation error.
    double ValidationError() const { return validationError; }

    //! Get whether or not the individual inputs are shuffled.
    bool Shuffle() const { return shuffle; }
    //! Modify whether or not the individual inputs are shuffled.
    bool& Shuffle() { return shuffle; }

    //! Get the batch size.
    size_t StepSize() const { return batchSize; }
    //! Modify the batch size.
    size_t& StepSize() { return batchSize; }

    //! Get the maximum number of iterations (0 indicates no limit).
    size_t MaxEpochs() const { return maxEpochs; }
    //! Modify the maximum number of iterations (0 indicates no limit).
    size_t& MaxEpochs() { return maxEpochs; }

    //! Get the tolerance for termination.
    double Tolerance() const { return tolerance; }
    //! Modify the tolerance for termination.
    double& Tolerance() { return tolerance; }

  private:
    /**
     * Train the network on the given dataset.
     *
     * @param data Data used to train the network.
     * @param target Labels used to train the network.
     */
    template<typename InputType, typename OutputType>
    void Train(InputType& data, OutputType& target)
    {
      // Reset the training error.
      trainingError = 0;

      for (size_t i = 0; i < index.n_elem; i++)
      {
        net.FeedForward(Element(data, index(i)),
            Element(target, index(i)), error);

        trainingError += net.Error();
        net.FeedBackward(error);

        if (((i + 1) % batchSize) == 0)
          net.ApplyGradients();
      }

      if ((index.n_elem % batchSize) != 0)
        net.ApplyGradients();

      trainingError /= index.n_elem;
    }

    /**
     * Evaluate the network on the given dataset.
     *
     * @param data Data used to train the network.
     * @param target Labels used to train the network.
     */
    template<typename InputType, typename OutputType>
    void Evaluate(InputType& data, OutputType& target)
    {
      // Reset the validation error.
      validationError = 0;

      for (size_t i = 0; i < ElementCount(data); i++)
      {
         validationError += net.Evaluate(Element(data, i),
            Element(target, i), error);
      }

      validationError /= ElementCount(data);
    }

    /*
     * Create a Col object which uses memory from an existing matrix object.
     * (This approach is currently not alias safe)
     *
     * @param data The reference data.
     * @param sliceNum Provide a Col object of the specified index.
     */
    template<typename eT>
    arma::Col<eT> Element(arma::Mat<eT>& input, const size_t colNum)
    {
      return arma::Col<eT>(input.colptr(colNum), input.n_rows, false, true);
    }

    /*
     * Provide the reference to the matrix representing a single slice.
     *
     * @param data The reference data.
     * @param sliceNum Provide a single slice of the specified index.
     */
    template<typename eT>
    const arma::Mat<eT>& Element(arma::Cube<eT>& input, const size_t sliceNum)
    {
      return *(input.mat_ptrs[sliceNum]);
    }

    /*
     * Get the number of elements.
     *
     * @param data The reference data.
     */
    template<typename eT>
    size_t ElementCount(const arma::Mat<eT>& data) const
    {
      return data.n_cols;
    }

    /*
     * Get the number of elements.
     *
     * @param data The reference data.
     */
    template<typename eT>
    size_t ElementCount(const arma::Cube<eT>& data) const
    {
      return data.n_slices;
    }

    //! The network which should be trained and evaluated.
    NetworkType& net;

    //! The current network error of a single input.
    typename std::conditional<NetworkTraits<NetworkType>::IsFNN,
        VecType, MatType>::type error;

    //! The current epoch if maxEpochs is set.
    size_t epoch;

    //! The maximal epochs that should be used.
    size_t maxEpochs;

    //! The size until a update is performed.
    size_t batchSize;

    //! The shuffel sequence index used to train the network.
    arma::Col<size_t> index;

    //! The overall traing error.
    double trainingError;

    //! The overall validation error.
    double validationError;

    //! The tolerance for termination.
    double tolerance;

    //! Controls whether or not the individual inputs are shuffled when
    //! iterating.
    bool shuffle;
}; // class Trainer

}; // namespace ann
}; // namespace mlpack

#endif
<|endoftext|>