<commit_before>// Copyright (c) 2014-2015 Dims dev-team
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "core.h"

#include <boost/statechart/state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>

#include "common/authenticationProvider.h"
#include "common/setResponseVisitor.h"
#include "common/analyseTransaction.h"
#include "common/commonRequests.h"

#include "monitor/admitTrackerAction.h"
#include "monitor/monitorController.h"
#include "monitor/admitTransactionsBundle.h"
#include "monitor/filters.h"
#include "monitor/reputationTracer.h"
#include "monitor/monitorRequests.h"
#include "monitor/rankingDatabase.h"

namespace monitor
{
struct CPaidRegistration;
struct CFreeRegistration;
struct CPaidRegistrationEmptyNetwork;
//milisec
unsigned int const WaitTime = 20000;

bool analyseTransaction( CTransaction & _transaction, uint256 const & _hash, CKeyID const & _trackerId )
{
	if ( !common::findKeyInInputs( _transaction, _trackerId ) )
		return false;

	CTxOut txOut;
	unsigned id;

	common::findOutputInTransaction(
				_transaction
				, common::CAuthenticationProvider::getInstance()->getMyKey().GetID()
				, txOut
				, id );

	return txOut.nValue >= CMonitorController::getInstance()->getPrice();
}

struct CWaitForInfo : boost::statechart::state< CWaitForInfo, CAdmitTrackerAction >
{
	CWaitForInfo( my_context ctx )
		: my_base( ctx )
	{
		LogPrintf("admit tracker action: %p wait for info \n", &context< CAdmitTrackerAction >() );
		context< CAdmitTrackerAction >().dropRequests();
		context< CAdmitTrackerAction >().addRequest( new common::CTimeEventRequest< common::CMonitorTypes >( WaitTime, new CMediumClassFilter( common::CMediumKinds::Time ) ) );

	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		// todo create alredy registered logic _messageResult.m_pubKey

		context< CAdmitTrackerAction >().dropRequests();

		context< CAdmitTrackerAction >().addRequest(
					new common::CAckRequest< common::CMonitorTypes >(
						context< CAdmitTrackerAction >().getActionKey()
						, _messageResult.m_message.m_header.m_id
						, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		context< CAdmitTrackerAction >().addRequest( new CRegistrationTerms(
														  CMonitorController::getInstance()->getPrice()
														 , CMonitorController::getInstance()->getPeriod()
														 , context< CAdmitTrackerAction >().getActionKey()
														 , _messageResult.m_message.m_header.m_id
														 , new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		return discard_event();
	}

	boost::statechart::result react( common::CAckEvent const & _ackEvent )
	{
		if ( CMonitorController::getInstance()->getPrice() )
		{
			if ( CReputationTracker::getInstance()->getTrackers().empty() )
				return transit< CPaidRegistrationEmptyNetwork >();
		}
		else
			return transit< CFreeRegistration >();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CAdmitTrackerAction >().dropRequests();
		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CAckEvent >,
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >
	> reactions;
};

struct CFreeRegistration : boost::statechart::state< CFreeRegistration, CAdmitTrackerAction >
{
	CFreeRegistration( my_context ctx )
		: my_base( ctx )
	{

		LogPrintf("admit tracker action: %p free registration \n", &context< CAdmitTrackerAction >() );

		context< CAdmitTrackerAction >().dropRequests();
		context< CAdmitTrackerAction >().addRequest( new common::CTimeEventRequest< common::CMonitorTypes >( WaitTime, new CMediumClassFilter( common::CMediumKinds::Time ) ) );
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		common::CAdmitProof admitMessage;

		common::convertPayload( orginalMessage, admitMessage );

		CReputationTracker::getInstance()->addTracker( CTrackerData( _messageResult.m_pubKey, 0, CMonitorController::getInstance()->getPeriod(), GetTime() ) );

		context< CAdmitTrackerAction >().addRequest(
					new common::CAckRequest< common::CMonitorTypes >(
						context< CAdmitTrackerAction >().getActionKey()
						, _messageResult.m_message.m_header.m_id
						, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		context< CAdmitTrackerAction >().addRequest(
					new common::CResultRequest< common::CMonitorTypes >(
						  context< CAdmitTrackerAction >().getActionKey()
						, _messageResult.m_message.m_header.m_id
						, 1
						, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		return discard_event();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CAdmitTrackerAction >().dropRequests();
		return discard_event();
	}

	boost::statechart::result react( common::CAckEvent const & _ackEvent )
	{
		context< CAdmitTrackerAction >().dropRequests();
		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CAckEvent >,
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >
	> reactions;

};

struct CPaidRegistrationEmptyNetwork : boost::statechart::state< CPaidRegistration, CAdmitTrackerAction >
{
	CPaidRegistrationEmptyNetwork( my_context ctx )
		: my_base( ctx )
	{
		context< CAdmitTrackerAction >().dropRequests();
		context< CAdmitTrackerAction >().addRequest(
					new common::CTimeEventRequest< common::CMonitorTypes >(
						WaitTime
						, new CMediumClassFilter( common::CMediumKinds::Time ) ) );
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		if ( _messageResult.m_message.m_header.m_payloadKind== common::CPayloadKind::AdmitAsk )
		{
			context< CAdmitTrackerAction >().addRequest(
						new common::CAckRequest< common::CMonitorTypes >(
							context< CAdmitTrackerAction >().getActionKey()
							, _messageResult.m_message.m_header.m_id
							, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

			context< CAdmitTrackerAction >().addRequest(
						new common::CResultRequest< common::CMonitorTypes >(
							context< CAdmitTrackerAction >().getActionKey()
							, _messageResult.m_message.m_header.m_id
							, 1
							, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );
		}
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CAdmitTrackerAction >().setExit();
		return discard_event();
	}

	boost::statechart::result react( common::CAckEvent const & _ackEvent )
	{
		return transit< CFreeRegistration >();
		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CAckEvent >,
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >
	> reactions;
};

struct CPaidRegistration : boost::statechart::state< CPaidRegistration, CAdmitTrackerAction >
{
	CPaidRegistration( my_context ctx )
		: my_base( ctx )
		, m_checkPeriod( 3000 )
	{
		LogPrintf("admit tracker action: %p paid registration \n", &context< CAdmitTrackerAction >() );
		context< CAdmitTrackerAction >().dropRequests();
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		common::CAdmitProof admitMessage;

		common::convertPayload( orginalMessage, admitMessage );

		CPaymentTracking::getInstance()->addTransactionToSearch( admitMessage.m_proofTransactionHash );

		m_proofHash = admitMessage.m_proofTransactionHash;

		context< CAdmitTrackerAction >().dropRequests();
		context< CAdmitTrackerAction >().addRequest( new common::CTimeEventRequest< common::CMonitorTypes >( m_checkPeriod, new CMediumClassFilter( common::CMediumKinds::Time ) ) );

		m_messageId = _messageResult.m_message.m_header.m_id;

		return discard_event();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		CTransaction transaction;

		if ( CPaymentTracking::getInstance()->transactionPresent( m_proofHash, transaction ) )
			return discard_event();

		CPubKey pubKey;
		CReputationTracker::getInstance()->getNodeToKey(
					  context< CAdmitTrackerAction >().getNodePtr()
					, pubKey );

		if ( analyseTransaction( transaction, m_proofHash, pubKey.GetID() ) )
		{
			CReputationTracker::getInstance()->addTracker( CTrackerData( pubKey, 0, CMonitorController::getInstance()->getPeriod(), GetTime() ) );
			context< CAdmitTrackerAction >().dropRequests();
			context< CAdmitTrackerAction >().addRequest(
						new common::CResultRequest< common::CMonitorTypes >(
							  context< CAdmitTrackerAction >().getActionKey()
							, m_messageId
							, 1
							, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

			CPubKey pubKey;

			CReputationTracker::getInstance()->getNodeToKey( context< CAdmitTrackerAction >().getNodePtr(), pubKey );

			CTrackerData trackerData( pubKey, 0, GetTime(), CMonitorController::getInstance()->getPeriod() );

			CRankingDatabase::getInstance()->writeTrackerData( trackerData );

			CReputationTracker::getInstance()->addTracker( trackerData );
		}
		else
		{
			context< CAdmitTrackerAction >().dropRequests();

			context< CAdmitTrackerAction >().addRequest(
						new common::CResultRequest< common::CMonitorTypes >(
							  context< CAdmitTrackerAction >().getActionKey()
							, m_messageId
							, 0
							, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		}
		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >
	> reactions;

	uint256 m_proofHash;

	uint256 m_messageId;

	int64_t const m_checkPeriod;
};

CAdmitTrackerAction::CAdmitTrackerAction( uint256 const & _actionKey, uintptr_t _nodePtr )
	: common::CAction< common::CMonitorTypes >( _actionKey )
	, m_nodePtr( _nodePtr )
{
	initiate();
}

void
CAdmitTrackerAction::accept( common::CSetResponseVisitor< common::CMonitorTypes > & _visitor )
{
	_visitor.visit( *this );
}

}
<commit_msg>registration  small  fix<commit_after>// Copyright (c) 2014-2015 Dims dev-team
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "core.h"

#include <boost/statechart/state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>

#include "common/authenticationProvider.h"
#include "common/setResponseVisitor.h"
#include "common/analyseTransaction.h"
#include "common/commonRequests.h"

#include "monitor/admitTrackerAction.h"
#include "monitor/monitorController.h"
#include "monitor/admitTransactionsBundle.h"
#include "monitor/filters.h"
#include "monitor/reputationTracer.h"
#include "monitor/monitorRequests.h"
#include "monitor/rankingDatabase.h"

namespace monitor
{
struct CPaidRegistration;
struct CFreeRegistration;
struct CPaidRegistrationEmptyNetwork;
//milisec
unsigned int const WaitTime = 20000;

bool analyseTransaction( CTransaction & _transaction, uint256 const & _hash, CKeyID const & _trackerId )
{
	if ( !common::findKeyInInputs( _transaction, _trackerId ) )
		return false;

	CTxOut txOut;
	unsigned id;

	common::findOutputInTransaction(
				_transaction
				, common::CAuthenticationProvider::getInstance()->getMyKey().GetID()
				, txOut
				, id );

	return txOut.nValue >= CMonitorController::getInstance()->getPrice();
}

struct CWaitForInfo : boost::statechart::state< CWaitForInfo, CAdmitTrackerAction >
{
	CWaitForInfo( my_context ctx )
		: my_base( ctx )
	{
		LogPrintf("admit tracker action: %p wait for info \n", &context< CAdmitTrackerAction >() );
		context< CAdmitTrackerAction >().dropRequests();
		context< CAdmitTrackerAction >().addRequest( new common::CTimeEventRequest< common::CMonitorTypes >( WaitTime, new CMediumClassFilter( common::CMediumKinds::Time ) ) );

	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		// todo create alredy registered logic _messageResult.m_pubKey

		context< CAdmitTrackerAction >().dropRequests();

		context< CAdmitTrackerAction >().addRequest(
					new common::CAckRequest< common::CMonitorTypes >(
						context< CAdmitTrackerAction >().getActionKey()
						, _messageResult.m_message.m_header.m_id
						, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		context< CAdmitTrackerAction >().addRequest( new CRegistrationTerms(
														  CMonitorController::getInstance()->getPrice()
														 , CMonitorController::getInstance()->getPeriod()
														 , context< CAdmitTrackerAction >().getActionKey()
														 , _messageResult.m_message.m_header.m_id
														 , new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		return discard_event();
	}

	boost::statechart::result react( common::CAckEvent const & _ackEvent )
	{
		if ( CMonitorController::getInstance()->getPrice() )
		{
			if ( CReputationTracker::getInstance()->getTrackers().empty() )
				return transit< CPaidRegistrationEmptyNetwork >();
		}
		else
			return transit< CFreeRegistration >();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CAdmitTrackerAction >().dropRequests();
		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CAckEvent >,
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >
	> reactions;
};

struct CFreeRegistration : boost::statechart::state< CFreeRegistration, CAdmitTrackerAction >
{
	CFreeRegistration( my_context ctx )
		: my_base( ctx )
	{

		LogPrintf("admit tracker action: %p free registration \n", &context< CAdmitTrackerAction >() );

		context< CAdmitTrackerAction >().dropRequests();
		context< CAdmitTrackerAction >().addRequest( new common::CTimeEventRequest< common::CMonitorTypes >( WaitTime, new CMediumClassFilter( common::CMediumKinds::Time ) ) );
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		common::CAdmitProof admitMessage;

		common::convertPayload( orginalMessage, admitMessage );

		CReputationTracker::getInstance()->addTracker( CTrackerData( _messageResult.m_pubKey, 0, CMonitorController::getInstance()->getPeriod(), GetTime() ) );

		context< CAdmitTrackerAction >().addRequest(
					new common::CAckRequest< common::CMonitorTypes >(
						context< CAdmitTrackerAction >().getActionKey()
						, _messageResult.m_message.m_header.m_id
						, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		context< CAdmitTrackerAction >().addRequest(
					new common::CResultRequest< common::CMonitorTypes >(
						  context< CAdmitTrackerAction >().getActionKey()
						, _messageResult.m_message.m_header.m_id
						, 1
						, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		return discard_event();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CAdmitTrackerAction >().dropRequests();
		return discard_event();
	}

	boost::statechart::result react( common::CAckEvent const & _ackEvent )
	{
		context< CAdmitTrackerAction >().dropRequests();
		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CAckEvent >,
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >
	> reactions;

};

struct CPaidRegistrationEmptyNetwork : boost::statechart::state< CPaidRegistrationEmptyNetwork, CAdmitTrackerAction >
{
	CPaidRegistrationEmptyNetwork( my_context ctx )
		: my_base( ctx )
	{
		context< CAdmitTrackerAction >().dropRequests();
		context< CAdmitTrackerAction >().addRequest(
					new common::CTimeEventRequest< common::CMonitorTypes >(
						WaitTime
						, new CMediumClassFilter( common::CMediumKinds::Time ) ) );
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		if ( _messageResult.m_message.m_header.m_payloadKind== common::CPayloadKind::AdmitAsk )
		{
			context< CAdmitTrackerAction >().addRequest(
						new common::CAckRequest< common::CMonitorTypes >(
							context< CAdmitTrackerAction >().getActionKey()
							, _messageResult.m_message.m_header.m_id
							, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

			context< CAdmitTrackerAction >().addRequest(
						new common::CResultRequest< common::CMonitorTypes >(
							context< CAdmitTrackerAction >().getActionKey()
							, _messageResult.m_message.m_header.m_id
							, 1
							, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );
		}
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CAdmitTrackerAction >().setExit();
		return discard_event();
	}

	boost::statechart::result react( common::CAckEvent const & _ackEvent )
	{
		return transit< CFreeRegistration >();
		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CAckEvent >,
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >
	> reactions;
};

struct CPaidRegistration : boost::statechart::state< CPaidRegistration, CAdmitTrackerAction >
{
	CPaidRegistration( my_context ctx )
		: my_base( ctx )
		, m_checkPeriod( 3000 )
	{
		LogPrintf("admit tracker action: %p paid registration \n", &context< CAdmitTrackerAction >() );
		context< CAdmitTrackerAction >().dropRequests();
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		common::CAdmitProof admitMessage;

		common::convertPayload( orginalMessage, admitMessage );

		CPaymentTracking::getInstance()->addTransactionToSearch( admitMessage.m_proofTransactionHash );

		m_proofHash = admitMessage.m_proofTransactionHash;

		context< CAdmitTrackerAction >().dropRequests();
		context< CAdmitTrackerAction >().addRequest( new common::CTimeEventRequest< common::CMonitorTypes >( m_checkPeriod, new CMediumClassFilter( common::CMediumKinds::Time ) ) );

		m_messageId = _messageResult.m_message.m_header.m_id;

		return discard_event();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		CTransaction transaction;

		if ( CPaymentTracking::getInstance()->transactionPresent( m_proofHash, transaction ) )
			return discard_event();

		CPubKey pubKey;
		CReputationTracker::getInstance()->getNodeToKey(
					  context< CAdmitTrackerAction >().getNodePtr()
					, pubKey );

		if ( analyseTransaction( transaction, m_proofHash, pubKey.GetID() ) )
		{
			CReputationTracker::getInstance()->addTracker( CTrackerData( pubKey, 0, CMonitorController::getInstance()->getPeriod(), GetTime() ) );
			context< CAdmitTrackerAction >().dropRequests();
			context< CAdmitTrackerAction >().addRequest(
						new common::CResultRequest< common::CMonitorTypes >(
							  context< CAdmitTrackerAction >().getActionKey()
							, m_messageId
							, 1
							, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

			CPubKey pubKey;

			CReputationTracker::getInstance()->getNodeToKey( context< CAdmitTrackerAction >().getNodePtr(), pubKey );

			CTrackerData trackerData( pubKey, 0, GetTime(), CMonitorController::getInstance()->getPeriod() );

			CRankingDatabase::getInstance()->writeTrackerData( trackerData );

			CReputationTracker::getInstance()->addTracker( trackerData );
		}
		else
		{
			context< CAdmitTrackerAction >().dropRequests();

			context< CAdmitTrackerAction >().addRequest(
						new common::CResultRequest< common::CMonitorTypes >(
							  context< CAdmitTrackerAction >().getActionKey()
							, m_messageId
							, 0
							, new CSpecificMediumFilter( context< CAdmitTrackerAction >().getNodePtr() ) ) );

		}
		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >
	> reactions;

	uint256 m_proofHash;

	uint256 m_messageId;

	int64_t const m_checkPeriod;
};

CAdmitTrackerAction::CAdmitTrackerAction( uint256 const & _actionKey, uintptr_t _nodePtr )
	: common::CAction< common::CMonitorTypes >( _actionKey )
	, m_nodePtr( _nodePtr )
{
	initiate();
}

void
CAdmitTrackerAction::accept( common::CSetResponseVisitor< common::CMonitorTypes > & _visitor )
{
	_visitor.visit( *this );
}

}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptProblem.cpp,v $
   $Revision: 1.49 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/07/06 17:16:23 $
   End CVS Header */

/**
 *  File name: COptProblem.cpp
 *
 *  Programmer: Yongqun He
 *  Contact email: yohe@vt.edu
 *  Purpose: This is the source file of the COptProblem class.
 *           It specifies the optimization problem with its own members and
 *           functions. It's used by COptAlgorithm class and COptimization class
 */
#include <float.h>

#include "copasi.h"
#include "COptTask.h"
#include "COptProblem.h"
#include "COptItem.h"

#include "function/CFunctionDB.h"

#include "CopasiDataModel/CCopasiDataModel.h"

#include "steadystate/CSteadyStateTask.h"
#include "trajectory/CTrajectoryTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "trajectory/CTrajectoryProblem.h"

#include "model/CModel.h"
#include "model/CCompartment.h"

#include "report/CCopasiObjectReference.h"
#include "report/CKeyFactory.h"

#include "utilities/CProcessReport.h"

//  Default constructor
COptProblem::COptProblem(const CCopasiContainer * pParent):
    CCopasiProblem(CCopasiTask::optimization, pParent),
    mpSteadyState(NULL),
    mpTrajectory(NULL),
    mpFunction(NULL),
    mOptItemList()
{
  addGroup("OptimizationItemList");
  addGroup("OptimizationConstraintList");

  addParameter("Steady-State", CCopasiParameter::KEY, (std::string) "");
  addParameter("Time-Course", CCopasiParameter::KEY, (std::string) "");
  addParameter("ObjectiveFunction", CCopasiParameter::KEY, (std::string) "");
  addParameter("Maximize", CCopasiParameter::BOOL, (bool) false);

  initObjects();
}

// copy constructor
COptProblem::COptProblem(const COptProblem& src,
                         const CCopasiContainer * pParent):
    CCopasiProblem(src, pParent),
    mpSteadyState(src.mpSteadyState),
    mpTrajectory(src.mpTrajectory),
    mpFunction(NULL),
    mOptItemList()
{
  if (src.mpFunction)
    {
      createObjectiveFunction();
      mpFunction->setInfix(src.mpFunction->getInfix());
      setValue("ObjectiveFunction", mpFunction->getKey());
    }

  initObjects();
}

// Destructor
COptProblem::~COptProblem()
{
  std::vector<COptItem *>::iterator it = mOptItemList.begin();
  std::vector<COptItem *>::iterator end = mOptItemList.end();

  for (; it != end; ++it)
    pdelete(*it);

  if (mpFunction && CCopasiDataModel::Global && CCopasiDataModel::Global->getFunctionList())
    CCopasiDataModel::Global->getFunctionList()->loadedFunctions().remove(mpFunction->getObjectName());

  pdelete(mpFunction);
}

bool COptProblem::setModel(CModel * pModel)
{
  mpModel = pModel;
  return true;
}

bool COptProblem::setCallBack(CProcessReport * pCallBack)
{
  CCopasiProblem::setCallBack(pCallBack);

  if (pCallBack)
    {
      mhSolutionValue =
        mpCallBack->addItem("Best Value",
                            CCopasiParameter::DOUBLE,
                            & mSolutionValue);
      mhCounter =
        mpCallBack->addItem("Simulation Counter",
                            CCopasiParameter::UINT,
                            & mCounter);
    }

  return true;
}

void COptProblem::initObjects()
{
  addObjectReference("Best Value", mSolutionValue, CCopasiObject::ValueDbl);
  addObjectReference("Simulation Counter", mCounter, CCopasiObject::ValueDbl);
}

bool COptProblem::initialize()
{
  if (!mpModel) return false;
  mpModel->compileIfNecessary();

  mpReport = NULL;
  mCounter = 0;

  std::vector< CCopasiContainer * > ContainerList;
  ContainerList.push_back(mpModel);

  COptTask * pTask = dynamic_cast<COptTask *>(getObjectParent());
  if (pTask)
    {
      ContainerList.push_back(pTask);
      mpReport = &pTask->getReport();
      if (!mpReport->getStream()) mpReport = NULL;
    }

  mpSteadyState =
    dynamic_cast<CSteadyStateTask *>(GlobalKeys.get(* getValue("Steady-State").pKEY));
  mpTrajectory =
    dynamic_cast<CTrajectoryTask *>(GlobalKeys.get(* getValue("Time-Course").pKEY));

  if (!mpSteadyState && !mpTrajectory) return false;

  if (mpSteadyState) mpSteadyState->initialize();
  if (mpTrajectory) mpTrajectory->initialize();

  unsigned C_INT32 i;
  unsigned C_INT32 Size = mOptItemList.size();
  mUpdateMethods.resize(Size);
  mSolutionVariables.resize(Size);

  std::vector< COptItem * >::iterator it = mOptItemList.begin();
  std::vector< COptItem * >::iterator end = mOptItemList.end();

  for (i = 0; it != end; ++it, i++)
    {
      if (!(*it)->compile(ContainerList)) return false;
      mUpdateMethods[i] = (*it)->getUpdateMethod();
    }

  if (!mpFunction)
    mpFunction =
      dynamic_cast<CExpression *>(GlobalKeys.get(* getValue("ObjectiveFunction").pKEY));

  if (!mpFunction) return false;

  return mpFunction->compile(ContainerList);
}

bool COptProblem::checkParametricConstraints()
{
  std::vector< COptItem * >::const_iterator it = mOptItemList.begin();
  std::vector< COptItem * >::const_iterator end = mOptItemList.end();

  for (; it != end; ++it)
    if ((*it)->checkConstraint()) return false;

  return true;
}

bool COptProblem::checkFunctionalConstraints()
{
  return true; // :TODO:
}

/**
 * calculate() decides whether the problem is a steady state problem or a
 * trajectory problem based on whether the pointer to that type of problem
 * is null or not.  It then calls the process() method for that type of
 * problem.  Currently process takes ofstream& as a parameter but it will
 * change so that process() takes no parameters.
 */
bool COptProblem::calculate()
{
  try
    {
      if (mpSteadyState != NULL)
        {
          ((CSteadyStateProblem *) mpSteadyState->getProblem())->
          setInitialState(mpSteadyState->getProblem()->getModel()->getInitialState());
          mpSteadyState->process();
        }

      if (mpTrajectory != NULL)
        {
          ((CTrajectoryProblem *) mpTrajectory->getProblem())->
          setInitialState(mpTrajectory->getProblem()->getModel()->getInitialState());
          mpTrajectory->process();
        }

      mCalculateValue = mpFunction->calcValue();
    }

  catch (...)
    {
      mCalculateValue = DBL_MAX;
    }

  mCounter += 1;

  if (mpCallBack) return mpCallBack->progress(mhCounter);

  return true;
}

const C_FLOAT64 & COptProblem::getCalculateValue() const
{return mCalculateValue;}

void COptProblem::setSolutionVariables(const CVector< C_FLOAT64 > & variables)
{mSolutionVariables = variables;}

const CVector< C_FLOAT64 > & COptProblem::getSolutionVariables() const
  {return mSolutionVariables;}

bool COptProblem::setSolutionValue(const C_FLOAT64 & value)
{
  mSolutionValue = value;
  if (mpCallBack) return mpCallBack->progress(mhSolutionValue);

  return true;
}

const C_FLOAT64 & COptProblem::getSolutionValue() const
{return mSolutionValue;}

// set the type of problem : Steady State OR Trajectory
void COptProblem::setProblemType(ProblemType type)
{
  // :TODO:
  if (type == SteadyState)
    mpSteadyState = new CSteadyStateTask(/*this*/NULL);
  if (type == Trajectory)
    mpTrajectory = new CTrajectoryTask(/*this*/NULL);
}

COptItem & COptProblem::getOptItem(const unsigned C_INT32 & index)
{
  assert (index < mOptItemList.size());
  return *mOptItemList[index];
}

const unsigned C_INT32 COptProblem::getOptItemSize() const
  {return getValue("OptimizationItemList").pGROUP->size();}

COptItem & COptProblem::addOptItem(const CCopasiObjectName & objectCN)
{
  unsigned C_INT32 index = getOptItemSize();

  CCopasiParameterGroup * pOptimizationItemList = (CCopasiParameterGroup *) getParameter("OptimizationItemList");

  pOptimizationItemList->addGroup("OptimizationItem");

  CCopasiParameterGroup * pOptItem =
    (CCopasiParameterGroup *) pOptimizationItemList->getParameter(index);

  assert(pOptItem != NULL);

  COptItem * pTmp = new COptItem(*pOptItem);

  //pTmp->setLowerBound(

  if (!pTmp->initialize(objectCN)) fatalError();

  mOptItemList.push_back(pTmp);

  return *pTmp;
}

bool COptProblem::removeOptItem(const unsigned C_INT32 & index)
{
  if (!(index < mOptItemList.size())) return false;

  pdelete(mOptItemList[index]);
  mOptItemList.erase(mOptItemList.begin() + index);

  return ((CCopasiParameterGroup *) getParameter("OptimizationItemList"))->removeParameter(index);
}

bool COptProblem::swapOptItem(const unsigned C_INT32 & iFrom,
                              const unsigned C_INT32 & iTo)
{
  if (!(iFrom < mOptItemList.size()) ||
      !(iTo < mOptItemList.size()))
    return false;

  COptItem * pTmp = mOptItemList[iFrom];
  mOptItemList[iFrom] = mOptItemList[iTo];
  mOptItemList[iTo] = pTmp;

  return ((CCopasiParameterGroup *) getParameter("OptimizationItemList"))->swap(iFrom, iTo);
}

const std::vector< COptItem * > & COptProblem::getOptItemList() const
{return mOptItemList;}

const std::vector< UpdateMethod * > & COptProblem::getCalculateVariableUpdateMethods() const
  {return mUpdateMethods;}

bool COptProblem::setObjectiveFunction(const std::string & infix)
{
  if (!mpFunction) createObjectiveFunction();

  return mpFunction->setInfix(infix);
}

const std::string COptProblem::getObjectiveFunction()
{
  if (!mpFunction) createObjectiveFunction();

  return mpFunction->getInfix();
}

bool COptProblem::createObjectiveFunction()
{
  mpFunction =
    dynamic_cast<CExpression *>(GlobalKeys.get(* getValue("ObjectiveFunction").pKEY));

  CCopasiVectorN<CEvaluationTree> & FunctionList =
    CCopasiDataModel::Global->getFunctionList()->loadedFunctions();

  if (!mpFunction)
    {
      std::ostringstream Name;
      Name << "Objective Function";

      int i = 0;

      while (FunctionList.getIndex(Name.str()) != C_INVALID_INDEX)
        {
          i++;
          Name.str("");
          Name << "Objective Function " << i;
        }

      mpFunction = new CExpression(Name.str(), this);
      FunctionList.add(mpFunction, false);

      setValue("ObjectiveFunction", mpFunction->getKey());
    }
  else
    {
      mpFunction->setObjectParent(this);

      if (FunctionList.getIndex(mpFunction->getObjectName()) == C_INVALID_INDEX)
        FunctionList.add(mpFunction, false);
    }

  return true;
}
<commit_msg>The solution value is initialized to infinity.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptProblem.cpp,v $
   $Revision: 1.50 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/07/06 20:12:18 $
   End CVS Header */

/**
 *  File name: COptProblem.cpp
 *
 *  Programmer: Yongqun He
 *  Contact email: yohe@vt.edu
 *  Purpose: This is the source file of the COptProblem class.
 *           It specifies the optimization problem with its own members and
 *           functions. It's used by COptAlgorithm class and COptimization class
 */
#include <float.h>

#include "copasi.h"
#include "COptTask.h"
#include "COptProblem.h"
#include "COptItem.h"

#include "function/CFunctionDB.h"

#include "CopasiDataModel/CCopasiDataModel.h"

#include "steadystate/CSteadyStateTask.h"
#include "trajectory/CTrajectoryTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "trajectory/CTrajectoryProblem.h"

#include "model/CModel.h"
#include "model/CCompartment.h"

#include "report/CCopasiObjectReference.h"
#include "report/CKeyFactory.h"

#include "utilities/CProcessReport.h"

//  Default constructor
COptProblem::COptProblem(const CCopasiContainer * pParent):
    CCopasiProblem(CCopasiTask::optimization, pParent),
    mpSteadyState(NULL),
    mpTrajectory(NULL),
    mpFunction(NULL),
    mOptItemList()
{
  addGroup("OptimizationItemList");
  addGroup("OptimizationConstraintList");

  addParameter("Steady-State", CCopasiParameter::KEY, (std::string) "");
  addParameter("Time-Course", CCopasiParameter::KEY, (std::string) "");
  addParameter("ObjectiveFunction", CCopasiParameter::KEY, (std::string) "");
  addParameter("Maximize", CCopasiParameter::BOOL, (bool) false);

  initObjects();
}

// copy constructor
COptProblem::COptProblem(const COptProblem& src,
                         const CCopasiContainer * pParent):
    CCopasiProblem(src, pParent),
    mpSteadyState(src.mpSteadyState),
    mpTrajectory(src.mpTrajectory),
    mpFunction(NULL),
    mOptItemList()
{
  if (src.mpFunction)
    {
      createObjectiveFunction();
      mpFunction->setInfix(src.mpFunction->getInfix());
      setValue("ObjectiveFunction", mpFunction->getKey());
    }

  initObjects();
}

// Destructor
COptProblem::~COptProblem()
{
  std::vector<COptItem *>::iterator it = mOptItemList.begin();
  std::vector<COptItem *>::iterator end = mOptItemList.end();

  for (; it != end; ++it)
    pdelete(*it);

  if (mpFunction && CCopasiDataModel::Global && CCopasiDataModel::Global->getFunctionList())
    CCopasiDataModel::Global->getFunctionList()->loadedFunctions().remove(mpFunction->getObjectName());

  pdelete(mpFunction);
}

bool COptProblem::setModel(CModel * pModel)
{
  mpModel = pModel;
  return true;
}

bool COptProblem::setCallBack(CProcessReport * pCallBack)
{
  CCopasiProblem::setCallBack(pCallBack);

  if (pCallBack)
    {
      mhSolutionValue =
        mpCallBack->addItem("Best Value",
                            CCopasiParameter::DOUBLE,
                            & mSolutionValue);
      mhCounter =
        mpCallBack->addItem("Simulation Counter",
                            CCopasiParameter::UINT,
                            & mCounter);
    }

  return true;
}

void COptProblem::initObjects()
{
  addObjectReference("Simulation Counter", mCounter, CCopasiObject::ValueDbl);
  addObjectReference("Best Value", mSolutionValue, CCopasiObject::ValueDbl);
  addVectorReference("Best Parameters", mSolutionVariables, CCopasiObject::ValueDbl);
}

#ifdef WIN32
// warning C4056: overflow in floating-point constant arithmetic
// warning C4756: overflow in constant arithmetic
# pragma warning (disable: 4056 4756)
#endif

bool COptProblem::initialize()
{
  if (!mpModel) return false;
  mpModel->compileIfNecessary();

  mpReport = NULL;
  mCounter = 0;
  mSolutionValue = DBL_MAX * 2;

  std::vector< CCopasiContainer * > ContainerList;
  ContainerList.push_back(mpModel);

  COptTask * pTask = dynamic_cast<COptTask *>(getObjectParent());
  if (pTask)
    {
      ContainerList.push_back(pTask);
      mpReport = &pTask->getReport();
      if (!mpReport->getStream()) mpReport = NULL;
    }

  mpSteadyState =
    dynamic_cast<CSteadyStateTask *>(GlobalKeys.get(* getValue("Steady-State").pKEY));
  mpTrajectory =
    dynamic_cast<CTrajectoryTask *>(GlobalKeys.get(* getValue("Time-Course").pKEY));

  if (!mpSteadyState && !mpTrajectory) return false;

  if (mpSteadyState) mpSteadyState->initialize();
  if (mpTrajectory) mpTrajectory->initialize();

  unsigned C_INT32 i;
  unsigned C_INT32 Size = mOptItemList.size();
  mUpdateMethods.resize(Size);
  mSolutionVariables.resize(Size);

  std::vector< COptItem * >::iterator it = mOptItemList.begin();
  std::vector< COptItem * >::iterator end = mOptItemList.end();

  for (i = 0; it != end; ++it, i++)
    {
      if (!(*it)->compile(ContainerList)) return false;
      mUpdateMethods[i] = (*it)->getUpdateMethod();
    }

  if (!mpFunction)
    mpFunction =
      dynamic_cast<CExpression *>(GlobalKeys.get(* getValue("ObjectiveFunction").pKEY));

  if (!mpFunction) return false;

  return mpFunction->compile(ContainerList);
}

#ifdef WIN32
# pragma warning (default: 4056 4756)
#endif

bool COptProblem::checkParametricConstraints()
{
  std::vector< COptItem * >::const_iterator it = mOptItemList.begin();
  std::vector< COptItem * >::const_iterator end = mOptItemList.end();

  for (; it != end; ++it)
    if ((*it)->checkConstraint()) return false;

  return true;
}

bool COptProblem::checkFunctionalConstraints()
{
  return true; // :TODO:
}

/**
 * calculate() decides whether the problem is a steady state problem or a
 * trajectory problem based on whether the pointer to that type of problem
 * is null or not.  It then calls the process() method for that type of
 * problem.  Currently process takes ofstream& as a parameter but it will
 * change so that process() takes no parameters.
 */
bool COptProblem::calculate()
{
  try
    {
      if (mpSteadyState != NULL)
        {
          ((CSteadyStateProblem *) mpSteadyState->getProblem())->
          setInitialState(mpSteadyState->getProblem()->getModel()->getInitialState());
          mpSteadyState->process();
        }

      if (mpTrajectory != NULL)
        {
          ((CTrajectoryProblem *) mpTrajectory->getProblem())->
          setInitialState(mpTrajectory->getProblem()->getModel()->getInitialState());
          mpTrajectory->process();
        }

      mCalculateValue = mpFunction->calcValue();
    }

  catch (...)
    {
      mCalculateValue = DBL_MAX;
    }

  mCounter += 1;

  if (mpCallBack) return mpCallBack->progress(mhCounter);

  return true;
}

const C_FLOAT64 & COptProblem::getCalculateValue() const
{return mCalculateValue;}

void COptProblem::setSolutionVariables(const CVector< C_FLOAT64 > & variables)
{mSolutionVariables = variables;}

const CVector< C_FLOAT64 > & COptProblem::getSolutionVariables() const
  {return mSolutionVariables;}

bool COptProblem::setSolutionValue(const C_FLOAT64 & value)
{
  mSolutionValue = value;
  if (mpCallBack) return mpCallBack->progress(mhSolutionValue);

  return true;
}

const C_FLOAT64 & COptProblem::getSolutionValue() const
{return mSolutionValue;}

// set the type of problem : Steady State OR Trajectory
void COptProblem::setProblemType(ProblemType type)
{
  // :TODO:
  if (type == SteadyState)
    mpSteadyState = new CSteadyStateTask(/*this*/NULL);
  if (type == Trajectory)
    mpTrajectory = new CTrajectoryTask(/*this*/NULL);
}

COptItem & COptProblem::getOptItem(const unsigned C_INT32 & index)
{
  assert (index < mOptItemList.size());
  return *mOptItemList[index];
}

const unsigned C_INT32 COptProblem::getOptItemSize() const
  {return getValue("OptimizationItemList").pGROUP->size();}

COptItem & COptProblem::addOptItem(const CCopasiObjectName & objectCN)
{
  unsigned C_INT32 index = getOptItemSize();

  CCopasiParameterGroup * pOptimizationItemList = (CCopasiParameterGroup *) getParameter("OptimizationItemList");

  pOptimizationItemList->addGroup("OptimizationItem");

  CCopasiParameterGroup * pOptItem =
    (CCopasiParameterGroup *) pOptimizationItemList->getParameter(index);

  assert(pOptItem != NULL);

  COptItem * pTmp = new COptItem(*pOptItem);

  //pTmp->setLowerBound(

  if (!pTmp->initialize(objectCN)) fatalError();

  mOptItemList.push_back(pTmp);

  return *pTmp;
}

bool COptProblem::removeOptItem(const unsigned C_INT32 & index)
{
  if (!(index < mOptItemList.size())) return false;

  pdelete(mOptItemList[index]);
  mOptItemList.erase(mOptItemList.begin() + index);

  return ((CCopasiParameterGroup *) getParameter("OptimizationItemList"))->removeParameter(index);
}

bool COptProblem::swapOptItem(const unsigned C_INT32 & iFrom,
                              const unsigned C_INT32 & iTo)
{
  if (!(iFrom < mOptItemList.size()) ||
      !(iTo < mOptItemList.size()))
    return false;

  COptItem * pTmp = mOptItemList[iFrom];
  mOptItemList[iFrom] = mOptItemList[iTo];
  mOptItemList[iTo] = pTmp;

  return ((CCopasiParameterGroup *) getParameter("OptimizationItemList"))->swap(iFrom, iTo);
}

const std::vector< COptItem * > & COptProblem::getOptItemList() const
{return mOptItemList;}

const std::vector< UpdateMethod * > & COptProblem::getCalculateVariableUpdateMethods() const
  {return mUpdateMethods;}

bool COptProblem::setObjectiveFunction(const std::string & infix)
{
  if (!mpFunction) createObjectiveFunction();

  return mpFunction->setInfix(infix);
}

const std::string COptProblem::getObjectiveFunction()
{
  if (!mpFunction) createObjectiveFunction();

  return mpFunction->getInfix();
}

bool COptProblem::createObjectiveFunction()
{
  mpFunction =
    dynamic_cast<CExpression *>(GlobalKeys.get(* getValue("ObjectiveFunction").pKEY));

  CCopasiVectorN<CEvaluationTree> & FunctionList =
    CCopasiDataModel::Global->getFunctionList()->loadedFunctions();

  if (!mpFunction)
    {
      std::ostringstream Name;
      Name << "Objective Function";

      int i = 0;

      while (FunctionList.getIndex(Name.str()) != C_INVALID_INDEX)
        {
          i++;
          Name.str("");
          Name << "Objective Function " << i;
        }

      mpFunction = new CExpression(Name.str(), this);
      FunctionList.add(mpFunction, false);

      setValue("ObjectiveFunction", mpFunction->getKey());
    }
  else
    {
      mpFunction->setObjectParent(this);

      if (FunctionList.getIndex(mpFunction->getObjectName()) == C_INVALID_INDEX)
        FunctionList.add(mpFunction, false);
    }

  return true;
}
<|endoftext|>


<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file sigma_point_additive_prediction_policy.hpp
 * \date July 2015
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__FILTER__GAUSSIAN__SIGMA_POINT_ADDITIVE_PREDICTION_POLICY_HPP
#define FL__FILTER__GAUSSIAN__SIGMA_POINT_ADDITIVE_PREDICTION_POLICY_HPP

#include <Eigen/Dense>

#include <fl/util/meta.hpp>
#include <fl/util/traits.hpp>
#include <fl/filter/gaussian/transform/point_set.hpp>
#include <fl/filter/gaussian/quadrature/sigma_point_quadrature.hpp>

namespace fl
{

// Forward declarations
template <typename...> class SigmaPointPredictPolicy;

template <
    typename SigmaPointQuadrature,
    typename AdditiveStateTransitionFunction
>
class SigmaPointPredictPolicy<
          SigmaPointQuadrature,
          Additive<AdditiveStateTransitionFunction>>
{
public:
    typedef typename AdditiveStateTransitionFunction::State State;
    typedef typename AdditiveStateTransitionFunction::Input Input;

    enum : signed int
    {
        NumberOfPoints = SigmaPointQuadrature
                            ::number_of_points(SizeOf<State>::Value)
    };

    typedef PointSet<State, NumberOfPoints> StatePointSet;

    template <
        typename Belief
    >
    void operator()(const AdditiveStateTransitionFunction&
                              additive_state_transition_function,
                    const SigmaPointQuadrature& quadrature,
                    const Belief& prior_belief,
                    const Input& u,
                    Belief& predicted_belief)
    {
        auto&& f = [=](const State& x)
        {
            return additive_state_transition_function.expected_state(x, u);
        };

        quadrature.integrate_to_points(f, prior_belief, Y, Z);

        /*
         * Obtain the centered points matrix of the prediction. The columns of
         * this matrix are the predicted points with zero mean. That is, the
         * sum of the columns in P is zero.
         *
         * P = [X_r[1]-mu_r  X_r[2]-mu_r  ... X_r[n]-mu_r]
         *
         * with weighted mean
         *
         * mu_r = Sum w_mean[i] X_r[i]
         */
        auto&& X_c = Z.centered_points();

        /*
         * Obtain the weights of point as a vector
         *
         * W = [w_cov[1]  w_cov[2]  ... w_cov[n]]
         *
         * Note that the covariance weights are used.
         */
        auto&& W = Z.covariance_weights_vector();

        /*
         * Compute and set the moments
         *
         * The first moment is simply the weighted mean of points.
         * The second centered moment is determined by
         *
         * C = Sum W[i,i] * (X_r[i]-mu_r)(X_r[i]-mu_r)^T
         *   = P * W * P^T
         *
         * given that W is the diagonal matrix
         */
        predicted_belief.mean(Z.mean());
        predicted_belief.covariance(
            X_c * W.asDiagonal() * X_c.transpose()
            + additive_state_transition_function.noise_covariance());
    }

protected:
    StatePointSet Y;
    StatePointSet Z;
};

}

#endif
<commit_msg>Implements Descriptor<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file sigma_point_additive_prediction_policy.hpp
 * \date July 2015
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__FILTER__GAUSSIAN__SIGMA_POINT_ADDITIVE_PREDICTION_POLICY_HPP
#define FL__FILTER__GAUSSIAN__SIGMA_POINT_ADDITIVE_PREDICTION_POLICY_HPP

#include <Eigen/Dense>

#include <fl/util/meta.hpp>
#include <fl/util/traits.hpp>
#include <fl/util/descriptor.hpp>
#include <fl/filter/gaussian/transform/point_set.hpp>
#include <fl/filter/gaussian/quadrature/sigma_point_quadrature.hpp>

namespace fl
{

// Forward declarations
template <typename...> class SigmaPointPredictPolicy;

template <
    typename SigmaPointQuadrature,
    typename AdditiveStateTransitionFunction
>
class SigmaPointPredictPolicy<
          SigmaPointQuadrature,
          Additive<AdditiveStateTransitionFunction>>
    : public Descriptor
{
public:
    typedef typename AdditiveStateTransitionFunction::State State;
    typedef typename AdditiveStateTransitionFunction::Input Input;

    enum : signed int
    {
        NumberOfPoints = SigmaPointQuadrature
                            ::number_of_points(SizeOf<State>::Value)
    };

    typedef PointSet<State, NumberOfPoints> StatePointSet;

    template <
        typename Belief
    >
    void operator()(const AdditiveStateTransitionFunction&
                              additive_state_transition_function,
                    const SigmaPointQuadrature& quadrature,
                    const Belief& prior_belief,
                    const Input& u,
                    Belief& predicted_belief)
    {
        auto&& f = [=](const State& x)
        {
            return additive_state_transition_function.expected_state(x, u);
        };

        quadrature.integrate_to_points(f, prior_belief, Y, Z);

        /*
         * Obtain the centered points matrix of the prediction. The columns of
         * this matrix are the predicted points with zero mean. That is, the
         * sum of the columns in P is zero.
         *
         * P = [X_r[1]-mu_r  X_r[2]-mu_r  ... X_r[n]-mu_r]
         *
         * with weighted mean
         *
         * mu_r = Sum w_mean[i] X_r[i]
         */
        auto&& X_c = Z.centered_points();

        /*
         * Obtain the weights of point as a vector
         *
         * W = [w_cov[1]  w_cov[2]  ... w_cov[n]]
         *
         * Note that the covariance weights are used.
         */
        auto&& W = Z.covariance_weights_vector();

        /*
         * Compute and set the moments
         *
         * The first moment is simply the weighted mean of points.
         * The second centered moment is determined by
         *
         * C = Sum W[i,i] * (X_r[i]-mu_r)(X_r[i]-mu_r)^T
         *   = P * W * P^T
         *
         * given that W is the diagonal matrix
         */
        predicted_belief.mean(Z.mean());
        predicted_belief.covariance(
            X_c * W.asDiagonal() * X_c.transpose()
            + additive_state_transition_function.noise_covariance());
    }

    virtual std::string name() const
    {
        return "SigmaPointPredictPolicy<"
                + list_arguments(
                       "SigmaPointQuadrature",
                       "Additive<AdditiveStateTransitionFunction>")
                + ">";
    }

    virtual std::string description() const
    {
        return "Sigma Point based filter prediction policy for state transition"
               " model with additive noise";
    }

protected:
    StatePointSet Y;
    StatePointSet Z;
};

}

#endif
<|endoftext|>


<commit_before>//
// Created by monty on 23/11/15.
//

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#include <string>
#include "GLES2Lesson.h"
#include "NdkGlue.h"

//Counter Clockwise
const float GLES2Lesson::cubeVertices[]{
//    4________5
//    /|       /|
//   / |      / |
// 0/__|___1_/  |
//  | 7|____|___|6
//  |  /    |  /
//  | /     | /
// 3|/______|/2
//x, y, z, r, g, b, u, v
        -1.0f, 1.0f, 1.0f, 0.0f, 1.0f,    //0
        1.0f, 1.0f, 1.0f, 1.0f, 1.0f,     //1
        1.0f, -1.0f, 1.0f, 1.0f, 0.0f,   //2
        -1.0f, -1.0f, 1.0f, 0.0f, 0.0f,   //3
        -1.0f, 1.0f, -1.0f, 0.0f, 0.0f,   //4
        1.0f, 1.0f, -1.0f, 1.0f, 0.0f,    //5
        1.0f, -1.0f, -1.0f, 1.0f, 1.0f,   //6
        -1.0f, -1.0f, -1.0f, 0.0f, 1.0f,   //7

        -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,    //0
        1.0f, 1.0f, 1.0f, 0.0f, 1.0f,     //1
        1.0f, -1.0f, 1.0f, 0.0f, 0.0f,   //2
        -1.0f, -1.0f, 1.0f, 1.0f, 0.0f,   //3
        -1.0f, 1.0f, -1.0f, 0.0f, 1.0f,   //4
        1.0f, 1.0f, -1.0f, 1.0f, 1.0f,    //5
        1.0f, -1.0f, -1.0f, 1.0f, 0.0f,   //6
        -1.0f, -1.0f, -1.0f, 0.0f, 0.0f   //7
};

const unsigned short GLES2Lesson::cubeIndices[]{
        0, 1, 2,
        0, 2, 3,

        5, 4, 7,
        5, 7, 6,

        4, 5, 1,
        0, 4, 1,

        6, 7, 2,
        2, 7, 3,

        9, 13, 14,
        9, 14, 10,

        12, 8, 15,
        8, 11, 15
};

GLuint CreateSimpleTexture2D() {
    // Texture object handle
    GLuint textureId = 0;

    // 2x2 Image, 3 bytes per pixel (R, G, B)
    GLubyte pixels[4 * 3] =
            {
                    255, 0, 0, // Red
                    0, 255, 0, // Green
                    0, 0, 255, // Blue
                    255, 255, 0  // Yellow
            };

    // Use tightly packed data
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    // Generate a texture object
    glGenTextures(1, &textureId);

    // Bind the texture object
    glBindTexture(GL_TEXTURE_2D, textureId);

    // Load the texture
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

    // Set the filtering mode
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    return textureId;

}

extern void printGLString(const char *name, GLenum s) {
    const char *v = (const char *) glGetString(s);
    LOGI("GL %s = %s\n", name, v);
}

extern void checkGlError(const char *op) {
    for (GLint error = glGetError(); error; error = glGetError()) {
        LOGI("after %s() glError (0x%x)\n", op, error);
    }
}

GLuint GLES2Lesson::loadShader(GLenum shaderType, const char *pSource) {
    GLuint shader = glCreateShader(shaderType);
    if (shader) {
        glShaderSource(shader, 1, &pSource, NULL);
        glCompileShader(shader);
        GLint compiled = 0;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        if (!compiled) {
            GLint infoLen = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen) {
                char *buf = (char *) malloc(infoLen);
                if (buf) {
                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
                    LOGE("Could not compile shader %d:\n%s\n", shaderType, buf);
                    free(buf);
                }
                glDeleteShader(shader);
                shader = 0;
            }
        }
    }
    return shader;
}

GLuint GLES2Lesson::createProgram(const char *pVertexSource, const char *pFragmentSource) {
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
    if (!vertexShader) {
        return 0;
    }

    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
    if (!pixelShader) {
        return 0;
    }

    GLuint program = glCreateProgram();
    if (program) {
        glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        glLinkProgram(program);
        GLint linkStatus = GL_FALSE;
        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
        if (linkStatus != GL_TRUE) {
            GLint bufLength = 0;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
            if (bufLength) {
                char *buf = (char *) malloc(bufLength);
                if (buf) {
                    glGetProgramInfoLog(program, bufLength, NULL, buf);
                    LOGE("Could not link program:\n%s\n", buf);
                    free(buf);
                }
            }
            glDeleteProgram(program);
            program = 0;
        }
    }
    return program;
}

void GLES2Lesson::printVerboseDriverInformation() {
    printGLString("Version", GL_VERSION);
    printGLString("Vendor", GL_VENDOR);
    printGLString("Renderer", GL_RENDERER);
    printGLString("Extensions", GL_EXTENSIONS);
}

GLES2Lesson::GLES2Lesson() {
//start off as identity - late we will init it with proper values.
    cubeTransformMatrix = glm::mat4(1.0f);
    projectionMatrix = glm::mat4(1.0f);

    vertexAttributePosition = 0;
    modelMatrixAttributePosition = 0;
    projectionMatrixAttributePosition = 0;
    gProgram = 0;
    cubeRotationAngleYZ = 0.0f;
    cubeRotationAngleXZ = 0.0f;
}

GLES2Lesson::~GLES2Lesson() {
    deleteVBOs();
}

bool GLES2Lesson::init(float w, float h, const std::string &vertexShader,
                       const std::string &fragmentShader) {

    printVerboseDriverInformation();

    gProgram = createProgram(vertexShader.c_str(), fragmentShader.c_str());

    if (!gProgram) {
        LOGE("Could not create program.");
        return false;
    }

    fetchShaderLocations();

    glViewport(0, 0, w, h);
    checkGlError("glViewport");

    projectionMatrix = glm::perspective(45.0f, w / h, 0.1f, 100.0f);

    createVBOs();
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glFrontFace(GL_CW);
    glDepthMask(true);
    return true;
}

void GLES2Lesson::resetTransformMatrices() {
    glm::mat4 identity = glm::mat4(1.0f);
    glm::vec3 translate = glm::vec3(0.0f, 0.0f, -6.0f);
    glm::vec3 xAxis = glm::vec3(1.0f, 0.0f, 0.0f);
    glm::vec3 yAxis = glm::vec3(0.0f, 1.0f, 0.0f);
    glm::mat4 translated = glm::translate(identity, translate);
    glm::mat4 rotatedAroundXAxis = glm::rotate(translated, cubeRotationAngleYZ, xAxis);
    glm::mat4 rotatedAroundYAxis = glm::rotate(rotatedAroundXAxis, cubeRotationAngleXZ, yAxis);
    cubeTransformMatrix = rotatedAroundYAxis;
}

void GLES2Lesson::fetchShaderLocations() {

    vertexAttributePosition = glGetAttribLocation(gProgram, "aPosition");
    modelMatrixAttributePosition = glGetUniformLocation(gProgram, "uModel");
    projectionMatrixAttributePosition = glGetUniformLocation(gProgram, "uProjection");
    samplerUniformPosition = glGetUniformLocation(gProgram, "sTexture");
    textureCoordinatesAttributePosition = glGetAttribLocation(gProgram, "aTexCoord");
}

void GLES2Lesson::drawGeometry(const int vertexVbo, const int indexVbo, int vertexCount,
                               const glm::mat4 &transform) {

    glBindBuffer(GL_ARRAY_BUFFER, vertexVbo);
    glEnableVertexAttribArray(vertexAttributePosition);
    glEnableVertexAttribArray(textureCoordinatesAttributePosition);

    glUniform1i(samplerUniformPosition, 0);

    glUniformMatrix4fv(modelMatrixAttributePosition, 1, false, &transform[0][0]);
    glVertexAttribPointer(vertexAttributePosition, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
    glVertexAttribPointer(textureCoordinatesAttributePosition, 2, GL_FLOAT, GL_TRUE,
                          sizeof(float) * 5, (void *) (sizeof(float) * 3));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
    glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, 0);

    glDisableVertexAttribArray(vertexAttributePosition);
    glDisableVertexAttribArray(textureCoordinatesAttributePosition);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void GLES2Lesson::deleteVBOs() {
    glDeleteBuffers(1, &vboCubeVertexDataIndex);
    glDeleteBuffers(1, &vboCubeVertexIndicesIndex);
}

void GLES2Lesson::createVBOs() {
    glGenBuffers(1, &vboCubeVertexDataIndex);
    glBindBuffer(GL_ARRAY_BUFFER, vboCubeVertexDataIndex);
    glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float) * 5, cubeVertices, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    textureId = CreateSimpleTexture2D();

    glGenBuffers(1, &vboCubeVertexIndicesIndex);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboCubeVertexIndicesIndex);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLushort), cubeIndices, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void GLES2Lesson::clearBuffers() {
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClearDepthf(1.0f);
    checkGlError("glClearColor");
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    checkGlError("glClear");
}

void GLES2Lesson::setPerspective() {
    glUniformMatrix4fv(projectionMatrixAttributePosition, 1, false, &projectionMatrix[0][0]);
}

void GLES2Lesson::prepareShaderProgram() {
    glUseProgram(gProgram);
    checkGlError("glUseProgram");
}

void GLES2Lesson::render() {
    clearBuffers();
    prepareShaderProgram();
    setPerspective();
    resetTransformMatrices();

    drawGeometry(vboCubeVertexDataIndex,
                 vboCubeVertexIndicesIndex,
                 36,
                 cubeTransformMatrix
    );
}

void GLES2Lesson::setTexture(void **bitmapData, int size) {
//    glBindBuffer( GL_ARRAY_BUFFER, vboCubeVertexDataIndex );
//    glBindTexture( GL_TEXTURE_2D, 0 );
//    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
//    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
//    glBufferData( GL_ARRAY_BUFFER, size, bitmapData, GL_STATIC_DRAW );
//    glBindBuffer( GL_ARRAY_BUFFER, 0 );
}

void GLES2Lesson::tick() {
    cubeRotationAngleYZ += 0.5f;
    cubeRotationAngleXZ += 1.0f;
}

void GLES2Lesson::shutdown() {
    LOGI("Shutdown!\n");
}<commit_msg>Kinda fix the Texture Coordinates for Lesson 06<commit_after>//
// Created by monty on 23/11/15.
//

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#include <string>
#include "GLES2Lesson.h"
#include "NdkGlue.h"

//Counter Clockwise
const float GLES2Lesson::cubeVertices[]{
//    4________5
//    /|       /|
//   / |      / |
// 0/__|___1_/  |
//  | 7|____|___|6
//  |  /    |  /
//  | /     | /
// 3|/______|/2
//x, y, z, r, g, b, u, v
        -1.0f, 1.0f, 1.0f, 0.0f, 1.0f,    //0
        1.0f, 1.0f, 1.0f, 1.0f, 1.0f,     //1
        1.0f, -1.0f, 1.0f, 1.0f, 0.0f,   //2
        -1.0f, -1.0f, 1.0f, 0.0f, 0.0f,   //3
        -1.0f, 1.0f, -1.0f, 0.0f, 0.0f,   //4
        1.0f, 1.0f, -1.0f, 1.0f, 0.0f,    //5
        1.0f, -1.0f, -1.0f, 1.0f, 1.0f,   //6
        -1.0f, -1.0f, -1.0f, 0.0f, 1.0f,   //7

        -1.0f, 1.0f, 1.0f, 0.0f, 1.0f,    //0
        1.0f, 1.0f, 1.0f, 1.0f, 1.0f,     //1
        1.0f, -1.0f, 1.0f, 1.0f, 0.0f,   //2
        -1.0f, -1.0f, 1.0f, 0.0f, 0.0f,   //3
        -1.0f, 1.0f, -1.0f, 1.0f, 1.0f,   //4
        1.0f, 1.0f, -1.0f, 0.0f, 1.0f,    //5
        1.0f, -1.0f, -1.0f, 0.0f, 0.0f,   //6
        -1.0f, -1.0f, -1.0f, 1.0f, 0.0f   //7
};

const unsigned short GLES2Lesson::cubeIndices[]{
        0, 1, 2,
        0, 2, 3,

        5, 4, 7,
        5, 7, 6,

        4, 5, 1,
        0, 4, 1,

        6, 7, 2,
        2, 7, 3,

        9, 13, 14,
        9, 14, 10,

        12, 8, 15,
        8, 11, 15
};

GLuint CreateSimpleTexture2D() {
    // Texture object handle
    GLuint textureId = 0;

    // 2x2 Image, 3 bytes per pixel (R, G, B)
    GLubyte pixels[4 * 3] =
            {
                    255, 0, 0, // Red
                    0, 255, 0, // Green
                    0, 0, 255, // Blue
                    255, 255, 0  // Yellow
            };

    // Use tightly packed data
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    // Generate a texture object
    glGenTextures(1, &textureId);

    // Bind the texture object
    glBindTexture(GL_TEXTURE_2D, textureId);

    // Load the texture
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

    // Set the filtering mode
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    return textureId;

}

extern void printGLString(const char *name, GLenum s) {
    const char *v = (const char *) glGetString(s);
    LOGI("GL %s = %s\n", name, v);
}

extern void checkGlError(const char *op) {
    for (GLint error = glGetError(); error; error = glGetError()) {
        LOGI("after %s() glError (0x%x)\n", op, error);
    }
}

GLuint GLES2Lesson::loadShader(GLenum shaderType, const char *pSource) {
    GLuint shader = glCreateShader(shaderType);
    if (shader) {
        glShaderSource(shader, 1, &pSource, NULL);
        glCompileShader(shader);
        GLint compiled = 0;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        if (!compiled) {
            GLint infoLen = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen) {
                char *buf = (char *) malloc(infoLen);
                if (buf) {
                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
                    LOGE("Could not compile shader %d:\n%s\n", shaderType, buf);
                    free(buf);
                }
                glDeleteShader(shader);
                shader = 0;
            }
        }
    }
    return shader;
}

GLuint GLES2Lesson::createProgram(const char *pVertexSource, const char *pFragmentSource) {
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
    if (!vertexShader) {
        return 0;
    }

    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
    if (!pixelShader) {
        return 0;
    }

    GLuint program = glCreateProgram();
    if (program) {
        glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        glLinkProgram(program);
        GLint linkStatus = GL_FALSE;
        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
        if (linkStatus != GL_TRUE) {
            GLint bufLength = 0;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
            if (bufLength) {
                char *buf = (char *) malloc(bufLength);
                if (buf) {
                    glGetProgramInfoLog(program, bufLength, NULL, buf);
                    LOGE("Could not link program:\n%s\n", buf);
                    free(buf);
                }
            }
            glDeleteProgram(program);
            program = 0;
        }
    }
    return program;
}

void GLES2Lesson::printVerboseDriverInformation() {
    printGLString("Version", GL_VERSION);
    printGLString("Vendor", GL_VENDOR);
    printGLString("Renderer", GL_RENDERER);
    printGLString("Extensions", GL_EXTENSIONS);
}

GLES2Lesson::GLES2Lesson() {
//start off as identity - late we will init it with proper values.
    cubeTransformMatrix = glm::mat4(1.0f);
    projectionMatrix = glm::mat4(1.0f);

    vertexAttributePosition = 0;
    modelMatrixAttributePosition = 0;
    projectionMatrixAttributePosition = 0;
    gProgram = 0;
    cubeRotationAngleYZ = 0.0f;
    cubeRotationAngleXZ = 0.0f;
}

GLES2Lesson::~GLES2Lesson() {
    deleteVBOs();
}

bool GLES2Lesson::init(float w, float h, const std::string &vertexShader,
                       const std::string &fragmentShader) {

    printVerboseDriverInformation();

    gProgram = createProgram(vertexShader.c_str(), fragmentShader.c_str());

    if (!gProgram) {
        LOGE("Could not create program.");
        return false;
    }

    fetchShaderLocations();

    glViewport(0, 0, w, h);
    checkGlError("glViewport");

    projectionMatrix = glm::perspective(45.0f, w / h, 0.1f, 100.0f);

    createVBOs();
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glFrontFace(GL_CW);
    glDepthMask(true);
    return true;
}

void GLES2Lesson::resetTransformMatrices() {
    glm::mat4 identity = glm::mat4(1.0f);
    glm::vec3 translate = glm::vec3(0.0f, 0.0f, -6.0f);
    glm::vec3 xAxis = glm::vec3(1.0f, 0.0f, 0.0f);
    glm::vec3 yAxis = glm::vec3(0.0f, 1.0f, 0.0f);
    glm::mat4 translated = glm::translate(identity, translate);
    glm::mat4 rotatedAroundXAxis = glm::rotate(translated, cubeRotationAngleYZ, xAxis);
    glm::mat4 rotatedAroundYAxis = glm::rotate(rotatedAroundXAxis, cubeRotationAngleXZ, yAxis);
    cubeTransformMatrix = rotatedAroundYAxis;
}

void GLES2Lesson::fetchShaderLocations() {

    vertexAttributePosition = glGetAttribLocation(gProgram, "aPosition");
    modelMatrixAttributePosition = glGetUniformLocation(gProgram, "uModel");
    projectionMatrixAttributePosition = glGetUniformLocation(gProgram, "uProjection");
    samplerUniformPosition = glGetUniformLocation(gProgram, "sTexture");
    textureCoordinatesAttributePosition = glGetAttribLocation(gProgram, "aTexCoord");
}

void GLES2Lesson::drawGeometry(const int vertexVbo, const int indexVbo, int vertexCount,
                               const glm::mat4 &transform) {

    glBindBuffer(GL_ARRAY_BUFFER, vertexVbo);
    glEnableVertexAttribArray(vertexAttributePosition);
    glEnableVertexAttribArray(textureCoordinatesAttributePosition);

    glUniform1i(samplerUniformPosition, 0);

    glUniformMatrix4fv(modelMatrixAttributePosition, 1, false, &transform[0][0]);
    glVertexAttribPointer(vertexAttributePosition, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
    glVertexAttribPointer(textureCoordinatesAttributePosition, 2, GL_FLOAT, GL_TRUE,
                          sizeof(float) * 5, (void *) (sizeof(float) * 3));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
    glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, 0);

    glDisableVertexAttribArray(vertexAttributePosition);
    glDisableVertexAttribArray(textureCoordinatesAttributePosition);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void GLES2Lesson::deleteVBOs() {
    glDeleteBuffers(1, &vboCubeVertexDataIndex);
    glDeleteBuffers(1, &vboCubeVertexIndicesIndex);
}

void GLES2Lesson::createVBOs() {
    glGenBuffers(1, &vboCubeVertexDataIndex);
    glBindBuffer(GL_ARRAY_BUFFER, vboCubeVertexDataIndex);
    glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float) * 5, cubeVertices, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    textureId = CreateSimpleTexture2D();

    glGenBuffers(1, &vboCubeVertexIndicesIndex);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboCubeVertexIndicesIndex);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLushort), cubeIndices, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void GLES2Lesson::clearBuffers() {
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClearDepthf(1.0f);
    checkGlError("glClearColor");
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    checkGlError("glClear");
}

void GLES2Lesson::setPerspective() {
    glUniformMatrix4fv(projectionMatrixAttributePosition, 1, false, &projectionMatrix[0][0]);
}

void GLES2Lesson::prepareShaderProgram() {
    glUseProgram(gProgram);
    checkGlError("glUseProgram");
}

void GLES2Lesson::render() {
    clearBuffers();
    prepareShaderProgram();
    setPerspective();
    resetTransformMatrices();

    drawGeometry(vboCubeVertexDataIndex,
                 vboCubeVertexIndicesIndex,
                 36,
                 cubeTransformMatrix
    );
}

void GLES2Lesson::setTexture(void **bitmapData, int size) {
//    glBindBuffer( GL_ARRAY_BUFFER, vboCubeVertexDataIndex );
//    glBindTexture( GL_TEXTURE_2D, 0 );
//    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
//    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
//    glBufferData( GL_ARRAY_BUFFER, size, bitmapData, GL_STATIC_DRAW );
//    glBindBuffer( GL_ARRAY_BUFFER, 0 );
}

void GLES2Lesson::tick() {
    cubeRotationAngleYZ += 0.5f;
    cubeRotationAngleXZ += 1.0f;
}

void GLES2Lesson::shutdown() {
    LOGI("Shutdown!\n");
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: color.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _TOOLS_COLOR_HXX
#define _TOOLS_COLOR_HXX

#include "tools/toolsdllapi.h"

class SvStream;
class ResId;
#include <tools/solar.h>

#ifndef _BGFX_COLOR_BCOLOR_HXX
#include <basegfx/color/bcolor.hxx>
#endif

// --------------------
// - ColorCount-Types -
// --------------------

#define COLCOUNT_MONOCHROM          ((ULONG)2)
#define COLCOUNT_16                 ((ULONG)16)
#define COLCOUNT_256                ((ULONG)256)
#define COLCOUNT_HICOLOR1           (((ULONG)0x00007FFF)+1)
#define COLCOUNT_HICOLOR2           (((ULONG)0x0000FFFF)+1)
#define COLCOUNT_TRUECOLOR          (((ULONG)0x00FFFFFF)+1)

// ---------------
// - Color-Types -
// ---------------

typedef UINT32 ColorData;
#define RGB_COLORDATA( r,g,b )      ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16))
#define TRGB_COLORDATA( t,r,g,b )   ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16)|(((UINT32)((UINT8)(t)))<<24))
#define COLORDATA_RED( n )          ((UINT8)((n)>>16))
#define COLORDATA_GREEN( n )        ((UINT8)(((UINT16)(n)) >> 8))
#define COLORDATA_BLUE( n )         ((UINT8)(n))
#define COLORDATA_TRANSPARENCY( n ) ((UINT8)((n)>>24))
#define COLORDATA_RGB( n )          ((ColorData)((n) & 0x00FFFFFF))

#define COL_BLACK                   RGB_COLORDATA( 0x00, 0x00, 0x00 )
#define COL_BLUE                    RGB_COLORDATA( 0x00, 0x00, 0x80 )
#define COL_GREEN                   RGB_COLORDATA( 0x00, 0x80, 0x00 )
#define COL_CYAN                    RGB_COLORDATA( 0x00, 0x80, 0x80 )
#define COL_RED                     RGB_COLORDATA( 0x80, 0x00, 0x00 )
#define COL_MAGENTA                 RGB_COLORDATA( 0x80, 0x00, 0x80 )
#define COL_BROWN                   RGB_COLORDATA( 0x80, 0x80, 0x00 )
#define COL_GRAY                    RGB_COLORDATA( 0x80, 0x80, 0x80 )
#define COL_LIGHTGRAY               RGB_COLORDATA( 0xC0, 0xC0, 0xC0 )
#define COL_LIGHTBLUE               RGB_COLORDATA( 0x00, 0x00, 0xFF )
#define COL_LIGHTGREEN              RGB_COLORDATA( 0x00, 0xFF, 0x00 )
#define COL_LIGHTCYAN               RGB_COLORDATA( 0x00, 0xFF, 0xFF )
#define COL_LIGHTRED                RGB_COLORDATA( 0xFF, 0x00, 0x00 )
#define COL_LIGHTMAGENTA            RGB_COLORDATA( 0xFF, 0x00, 0xFF )
#define COL_YELLOW                  RGB_COLORDATA( 0xFF, 0xFF, 0x00 )
#define COL_WHITE                   RGB_COLORDATA( 0xFF, 0xFF, 0xFF )
#define COL_TRANSPARENT             TRGB_COLORDATA( 0xFF, 0xFF, 0xFF, 0xFF )
#define COL_AUTO                    (UINT32)0xFFFFFFFF
#define COL_AUTHOR1_DARK            RGB_COLORDATA(198, 146, 0)
#define COL_AUTHOR1_NORMAL          RGB_COLORDATA(255, 255, 158)
#define COL_AUTHOR1_LIGHT           RGB_COLORDATA(255, 255, 195)
#define COL_AUTHOR2_DARK            RGB_COLORDATA(6,  70, 162)
#define COL_AUTHOR2_NORMAL          RGB_COLORDATA(216, 232, 255)
#define COL_AUTHOR2_LIGHT           RGB_COLORDATA(233, 242, 255)
#define COL_AUTHOR3_DARK            RGB_COLORDATA(87, 157,  28)
#define COL_AUTHOR3_NORMAL          RGB_COLORDATA(218, 248, 193)
#define COL_AUTHOR3_LIGHT           RGB_COLORDATA(226, 250, 207)
#define COL_AUTHOR4_DARK            RGB_COLORDATA(105,  43, 157)
#define COL_AUTHOR4_NORMAL          RGB_COLORDATA(228, 210, 245)
#define COL_AUTHOR4_LIGHT           RGB_COLORDATA(239, 228, 248)
#define COL_AUTHOR5_DARK            RGB_COLORDATA(197,   0,  11)
#define COL_AUTHOR5_NORMAL          RGB_COLORDATA(254, 205, 208)
#define COL_AUTHOR5_LIGHT           RGB_COLORDATA(255, 227, 229)
#define COL_AUTHOR6_DARK            RGB_COLORDATA(0, 128, 128)
#define COL_AUTHOR6_NORMAL          RGB_COLORDATA(210, 246, 246)
#define COL_AUTHOR6_LIGHT           RGB_COLORDATA(230, 250, 250)
#define COL_AUTHOR7_DARK            RGB_COLORDATA(140, 132,  0)
#define COL_AUTHOR7_NORMAL          RGB_COLORDATA(237, 252, 163)
#define COL_AUTHOR7_LIGHT           RGB_COLORDATA(242, 254, 181)
#define COL_AUTHOR8_DARK            RGB_COLORDATA(53,  85, 107)
#define COL_AUTHOR8_NORMAL          RGB_COLORDATA(211, 222, 232)
#define COL_AUTHOR8_LIGHT           RGB_COLORDATA(226, 234, 241)
#define COL_AUTHOR9_DARK            RGB_COLORDATA(209, 118,   0)
#define COL_AUTHOR9_NORMAL          RGB_COLORDATA(255, 226, 185)
#define COL_AUTHOR9_LIGHT           RGB_COLORDATA(255, 231, 199)

#define COLOR_CHANNEL_MERGE( _def_cDst, _def_cSrc, _def_cSrcTrans ) \
    ((BYTE)((((long)(_def_cDst)-(_def_cSrc))*(_def_cSrcTrans)+(((_def_cSrc)<<8L)|(_def_cDst)))>>8L))

// ---------
// - Color -
// ---------

class TOOLS_DLLPUBLIC Color
{
protected:
    ColorData           mnColor;

public:
                        Color() { mnColor = COL_BLACK; }
                        Color( ColorData nColor ) { mnColor = nColor; }
                        Color( UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
                            { mnColor = RGB_COLORDATA( nRed, nGreen, nBlue ); }
                        Color( UINT8 nTransparency, UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
                            { mnColor = TRGB_COLORDATA( nTransparency, nRed, nGreen, nBlue ); }
                        Color( const ResId& rResId );
                         // This ctor is defined in svtools, not tools!

                        // constructor to create a tools-Color from ::basegfx::BColor
                        explicit Color(const ::basegfx::BColor& rBColor)
                        {
                            mnColor = RGB_COLORDATA(
                                UINT8((rBColor.getRed() * 255.0) + 0.5),
                                UINT8((rBColor.getGreen() * 255.0) + 0.5),
                                UINT8((rBColor.getBlue() * 255.0) + 0.5));
                        }

    void                SetRed( UINT8 nRed );
    UINT8               GetRed() const { return COLORDATA_RED( mnColor ); }
    void                SetGreen( UINT8 nGreen );
    UINT8               GetGreen() const { return COLORDATA_GREEN( mnColor ); }
    void                SetBlue( UINT8 nBlue );
    UINT8               GetBlue() const { return COLORDATA_BLUE( mnColor ); }
    void                SetTransparency( UINT8 nTransparency );
    UINT8               GetTransparency() const { return COLORDATA_TRANSPARENCY( mnColor ); }

    void                SetColor( ColorData nColor ) { mnColor = nColor; }
    ColorData           GetColor() const { return mnColor; }
    ColorData           GetRGBColor() const { return COLORDATA_RGB( mnColor ); }

    UINT8               GetColorError( const Color& rCompareColor ) const;

    UINT8               GetLuminance() const;
    void                IncreaseLuminance( UINT8 cLumInc );
    void                DecreaseLuminance( UINT8 cLumDec );

    void                IncreaseContrast( UINT8 cContInc );
    void                DecreaseContrast( UINT8 cContDec );

    void                Invert();

    void                Merge( const Color& rMergeColor, BYTE cTransparency );

    BOOL                IsRGBEqual( const Color& rColor ) const;

    // comparison with luminance thresholds
    BOOL                IsDark()    const;
    BOOL                IsBright()  const;

    // color space conversion tools
    // the range for h/s/b is:
    // Hue: 0-360 degree
    // Saturation: 0-100 %
    // Brightness: 0-100 %
    static ColorData    HSBtoRGB( USHORT nHue, USHORT nSat, USHORT nBri );
    void                RGBtoHSB( USHORT& nHue, USHORT& nSat, USHORT& nBri ) const;

    BOOL                operator==( const Color& rColor ) const
                            { return (mnColor == rColor.mnColor); }
    BOOL                operator!=( const Color& rColor ) const
                            { return !(Color::operator==( rColor )); }

    SvStream&           Read( SvStream& rIStm, BOOL bNewFormat = TRUE );
    SvStream&           Write( SvStream& rOStm, BOOL bNewFormat = TRUE );

    TOOLS_DLLPUBLIC friend SvStream&    operator>>( SvStream& rIStream, Color& rColor );
    TOOLS_DLLPUBLIC friend SvStream&    operator<<( SvStream& rOStream, const Color& rColor );

    // get ::basegfx::BColor from this color
    ::basegfx::BColor getBColor() const { return ::basegfx::BColor(GetRed() / 255.0, GetGreen() / 255.0, GetBlue() / 255.0); }
};

inline void Color::SetRed( UINT8 nRed )
{
    mnColor &= 0xFF00FFFF;
    mnColor |= ((UINT32)nRed)<<16;
}

inline void Color::SetGreen( UINT8 nGreen )
{
    mnColor &= 0xFFFF00FF;
    mnColor |= ((UINT16)nGreen)<<8;
}

inline void Color::SetBlue( UINT8 nBlue )
{
    mnColor &= 0xFFFFFF00;
    mnColor |= nBlue;
}

inline void Color::SetTransparency( UINT8 nTransparency )
{
    mnColor &= 0x00FFFFFF;
    mnColor |= ((UINT32)nTransparency)<<24;
}

inline BOOL Color::IsRGBEqual( const Color& rColor ) const
{
    return (COLORDATA_RGB( mnColor ) == COLORDATA_RGB( rColor.mnColor ));
}

inline UINT8 Color::GetLuminance() const
{
    return( (UINT8) ( ( COLORDATA_BLUE( mnColor ) * 28UL +
                        COLORDATA_GREEN( mnColor ) * 151UL +
                        COLORDATA_RED( mnColor ) * 77UL ) >> 8UL ) );
}

inline void Color::Merge( const Color& rMergeColor, BYTE cTransparency )
{
    SetRed( COLOR_CHANNEL_MERGE( COLORDATA_RED( mnColor ), COLORDATA_RED( rMergeColor.mnColor ), cTransparency ) );
    SetGreen( COLOR_CHANNEL_MERGE( COLORDATA_GREEN( mnColor ), COLORDATA_GREEN( rMergeColor.mnColor ), cTransparency ) );
    SetBlue( COLOR_CHANNEL_MERGE( COLORDATA_BLUE( mnColor ), COLORDATA_BLUE( rMergeColor.mnColor ), cTransparency ) );
}

#endif // _TOOLS_COLOR_HXX
<commit_msg>calctabcolor: COL_AUTO should be of type ColorData, not of UINT32.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: color.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _TOOLS_COLOR_HXX
#define _TOOLS_COLOR_HXX

#include "tools/toolsdllapi.h"

class SvStream;
class ResId;
#include <tools/solar.h>

#ifndef _BGFX_COLOR_BCOLOR_HXX
#include <basegfx/color/bcolor.hxx>
#endif

// --------------------
// - ColorCount-Types -
// --------------------

#define COLCOUNT_MONOCHROM          ((ULONG)2)
#define COLCOUNT_16                 ((ULONG)16)
#define COLCOUNT_256                ((ULONG)256)
#define COLCOUNT_HICOLOR1           (((ULONG)0x00007FFF)+1)
#define COLCOUNT_HICOLOR2           (((ULONG)0x0000FFFF)+1)
#define COLCOUNT_TRUECOLOR          (((ULONG)0x00FFFFFF)+1)

// ---------------
// - Color-Types -
// ---------------

typedef UINT32 ColorData;
#define RGB_COLORDATA( r,g,b )      ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16))
#define TRGB_COLORDATA( t,r,g,b )   ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16)|(((UINT32)((UINT8)(t)))<<24))
#define COLORDATA_RED( n )          ((UINT8)((n)>>16))
#define COLORDATA_GREEN( n )        ((UINT8)(((UINT16)(n)) >> 8))
#define COLORDATA_BLUE( n )         ((UINT8)(n))
#define COLORDATA_TRANSPARENCY( n ) ((UINT8)((n)>>24))
#define COLORDATA_RGB( n )          ((ColorData)((n) & 0x00FFFFFF))

#define COL_BLACK                   RGB_COLORDATA( 0x00, 0x00, 0x00 )
#define COL_BLUE                    RGB_COLORDATA( 0x00, 0x00, 0x80 )
#define COL_GREEN                   RGB_COLORDATA( 0x00, 0x80, 0x00 )
#define COL_CYAN                    RGB_COLORDATA( 0x00, 0x80, 0x80 )
#define COL_RED                     RGB_COLORDATA( 0x80, 0x00, 0x00 )
#define COL_MAGENTA                 RGB_COLORDATA( 0x80, 0x00, 0x80 )
#define COL_BROWN                   RGB_COLORDATA( 0x80, 0x80, 0x00 )
#define COL_GRAY                    RGB_COLORDATA( 0x80, 0x80, 0x80 )
#define COL_LIGHTGRAY               RGB_COLORDATA( 0xC0, 0xC0, 0xC0 )
#define COL_LIGHTBLUE               RGB_COLORDATA( 0x00, 0x00, 0xFF )
#define COL_LIGHTGREEN              RGB_COLORDATA( 0x00, 0xFF, 0x00 )
#define COL_LIGHTCYAN               RGB_COLORDATA( 0x00, 0xFF, 0xFF )
#define COL_LIGHTRED                RGB_COLORDATA( 0xFF, 0x00, 0x00 )
#define COL_LIGHTMAGENTA            RGB_COLORDATA( 0xFF, 0x00, 0xFF )
#define COL_YELLOW                  RGB_COLORDATA( 0xFF, 0xFF, 0x00 )
#define COL_WHITE                   RGB_COLORDATA( 0xFF, 0xFF, 0xFF )
#define COL_TRANSPARENT             TRGB_COLORDATA( 0xFF, 0xFF, 0xFF, 0xFF )
#define COL_AUTO                    (ColorData)0xFFFFFFFF
#define COL_AUTHOR1_DARK            RGB_COLORDATA(198, 146, 0)
#define COL_AUTHOR1_NORMAL          RGB_COLORDATA(255, 255, 158)
#define COL_AUTHOR1_LIGHT           RGB_COLORDATA(255, 255, 195)
#define COL_AUTHOR2_DARK            RGB_COLORDATA(6,  70, 162)
#define COL_AUTHOR2_NORMAL          RGB_COLORDATA(216, 232, 255)
#define COL_AUTHOR2_LIGHT           RGB_COLORDATA(233, 242, 255)
#define COL_AUTHOR3_DARK            RGB_COLORDATA(87, 157,  28)
#define COL_AUTHOR3_NORMAL          RGB_COLORDATA(218, 248, 193)
#define COL_AUTHOR3_LIGHT           RGB_COLORDATA(226, 250, 207)
#define COL_AUTHOR4_DARK            RGB_COLORDATA(105,  43, 157)
#define COL_AUTHOR4_NORMAL          RGB_COLORDATA(228, 210, 245)
#define COL_AUTHOR4_LIGHT           RGB_COLORDATA(239, 228, 248)
#define COL_AUTHOR5_DARK            RGB_COLORDATA(197,   0,  11)
#define COL_AUTHOR5_NORMAL          RGB_COLORDATA(254, 205, 208)
#define COL_AUTHOR5_LIGHT           RGB_COLORDATA(255, 227, 229)
#define COL_AUTHOR6_DARK            RGB_COLORDATA(0, 128, 128)
#define COL_AUTHOR6_NORMAL          RGB_COLORDATA(210, 246, 246)
#define COL_AUTHOR6_LIGHT           RGB_COLORDATA(230, 250, 250)
#define COL_AUTHOR7_DARK            RGB_COLORDATA(140, 132,  0)
#define COL_AUTHOR7_NORMAL          RGB_COLORDATA(237, 252, 163)
#define COL_AUTHOR7_LIGHT           RGB_COLORDATA(242, 254, 181)
#define COL_AUTHOR8_DARK            RGB_COLORDATA(53,  85, 107)
#define COL_AUTHOR8_NORMAL          RGB_COLORDATA(211, 222, 232)
#define COL_AUTHOR8_LIGHT           RGB_COLORDATA(226, 234, 241)
#define COL_AUTHOR9_DARK            RGB_COLORDATA(209, 118,   0)
#define COL_AUTHOR9_NORMAL          RGB_COLORDATA(255, 226, 185)
#define COL_AUTHOR9_LIGHT           RGB_COLORDATA(255, 231, 199)

#define COLOR_CHANNEL_MERGE( _def_cDst, _def_cSrc, _def_cSrcTrans ) \
    ((BYTE)((((long)(_def_cDst)-(_def_cSrc))*(_def_cSrcTrans)+(((_def_cSrc)<<8L)|(_def_cDst)))>>8L))

// ---------
// - Color -
// ---------

class TOOLS_DLLPUBLIC Color
{
protected:
    ColorData           mnColor;

public:
                        Color() { mnColor = COL_BLACK; }
                        Color( ColorData nColor ) { mnColor = nColor; }
                        Color( UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
                            { mnColor = RGB_COLORDATA( nRed, nGreen, nBlue ); }
                        Color( UINT8 nTransparency, UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
                            { mnColor = TRGB_COLORDATA( nTransparency, nRed, nGreen, nBlue ); }
                        Color( const ResId& rResId );
                         // This ctor is defined in svtools, not tools!

                        // constructor to create a tools-Color from ::basegfx::BColor
                        explicit Color(const ::basegfx::BColor& rBColor)
                        {
                            mnColor = RGB_COLORDATA(
                                UINT8((rBColor.getRed() * 255.0) + 0.5),
                                UINT8((rBColor.getGreen() * 255.0) + 0.5),
                                UINT8((rBColor.getBlue() * 255.0) + 0.5));
                        }

    void                SetRed( UINT8 nRed );
    UINT8               GetRed() const { return COLORDATA_RED( mnColor ); }
    void                SetGreen( UINT8 nGreen );
    UINT8               GetGreen() const { return COLORDATA_GREEN( mnColor ); }
    void                SetBlue( UINT8 nBlue );
    UINT8               GetBlue() const { return COLORDATA_BLUE( mnColor ); }
    void                SetTransparency( UINT8 nTransparency );
    UINT8               GetTransparency() const { return COLORDATA_TRANSPARENCY( mnColor ); }

    void                SetColor( ColorData nColor ) { mnColor = nColor; }
    ColorData           GetColor() const { return mnColor; }
    ColorData           GetRGBColor() const { return COLORDATA_RGB( mnColor ); }

    UINT8               GetColorError( const Color& rCompareColor ) const;

    UINT8               GetLuminance() const;
    void                IncreaseLuminance( UINT8 cLumInc );
    void                DecreaseLuminance( UINT8 cLumDec );

    void                IncreaseContrast( UINT8 cContInc );
    void                DecreaseContrast( UINT8 cContDec );

    void                Invert();

    void                Merge( const Color& rMergeColor, BYTE cTransparency );

    BOOL                IsRGBEqual( const Color& rColor ) const;

    // comparison with luminance thresholds
    BOOL                IsDark()    const;
    BOOL                IsBright()  const;

    // color space conversion tools
    // the range for h/s/b is:
    // Hue: 0-360 degree
    // Saturation: 0-100 %
    // Brightness: 0-100 %
    static ColorData    HSBtoRGB( USHORT nHue, USHORT nSat, USHORT nBri );
    void                RGBtoHSB( USHORT& nHue, USHORT& nSat, USHORT& nBri ) const;

    BOOL                operator==( const Color& rColor ) const
                            { return (mnColor == rColor.mnColor); }
    BOOL                operator!=( const Color& rColor ) const
                            { return !(Color::operator==( rColor )); }

    SvStream&           Read( SvStream& rIStm, BOOL bNewFormat = TRUE );
    SvStream&           Write( SvStream& rOStm, BOOL bNewFormat = TRUE );

    TOOLS_DLLPUBLIC friend SvStream&    operator>>( SvStream& rIStream, Color& rColor );
    TOOLS_DLLPUBLIC friend SvStream&    operator<<( SvStream& rOStream, const Color& rColor );

    // get ::basegfx::BColor from this color
    ::basegfx::BColor getBColor() const { return ::basegfx::BColor(GetRed() / 255.0, GetGreen() / 255.0, GetBlue() / 255.0); }
};

inline void Color::SetRed( UINT8 nRed )
{
    mnColor &= 0xFF00FFFF;
    mnColor |= ((UINT32)nRed)<<16;
}

inline void Color::SetGreen( UINT8 nGreen )
{
    mnColor &= 0xFFFF00FF;
    mnColor |= ((UINT16)nGreen)<<8;
}

inline void Color::SetBlue( UINT8 nBlue )
{
    mnColor &= 0xFFFFFF00;
    mnColor |= nBlue;
}

inline void Color::SetTransparency( UINT8 nTransparency )
{
    mnColor &= 0x00FFFFFF;
    mnColor |= ((UINT32)nTransparency)<<24;
}

inline BOOL Color::IsRGBEqual( const Color& rColor ) const
{
    return (COLORDATA_RGB( mnColor ) == COLORDATA_RGB( rColor.mnColor ));
}

inline UINT8 Color::GetLuminance() const
{
    return( (UINT8) ( ( COLORDATA_BLUE( mnColor ) * 28UL +
                        COLORDATA_GREEN( mnColor ) * 151UL +
                        COLORDATA_RED( mnColor ) * 77UL ) >> 8UL ) );
}

inline void Color::Merge( const Color& rMergeColor, BYTE cTransparency )
{
    SetRed( COLOR_CHANNEL_MERGE( COLORDATA_RED( mnColor ), COLORDATA_RED( rMergeColor.mnColor ), cTransparency ) );
    SetGreen( COLOR_CHANNEL_MERGE( COLORDATA_GREEN( mnColor ), COLORDATA_GREEN( rMergeColor.mnColor ), cTransparency ) );
    SetBlue( COLOR_CHANNEL_MERGE( COLORDATA_BLUE( mnColor ), COLORDATA_BLUE( rMergeColor.mnColor ), cTransparency ) );
}

#endif // _TOOLS_COLOR_HXX
<|endoftext|>