<commit_before>/*******************************************************************************

 Module:       FGAtmosphere.cpp
 Author:       Jon Berndt
               Implementation of 1959 Standard Atmosphere added by Tony Peden
 Date started: 11/24/98
 Purpose:      Models the atmosphere
 Called by:    FGSimExec

 ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program 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 General Public License for more
 details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
Models the atmosphere. The equation used below was determined by a third order
curve fit using Excel. The data is from the ICAO atmosphere model.

HISTORY
--------------------------------------------------------------------------------
11/24/98   JSB   Created
07/23/99   TP    Added implementation of 1959 Standard Atmosphere
                 Moved calculation of Mach number to FGTranslation
********************************************************************************
COMMENTS, REFERENCES,  and NOTES
********************************************************************************
[1]   Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
      1989, ISBN 0-07-001641-0

********************************************************************************
INCLUDES
*******************************************************************************/

#include "FGAtmosphere.h"
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGFCS.h"
#include "FGAircraft.h"
#include "FGTranslation.h"
#include "FGRotation.h"
#include "FGPosition.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"
#include "FGDefs.h"

/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/

FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
{
  Name = "FGAtmosphere";
  h = 0;
  Calculate(h);
  SLtemperature = temperature;
  SLpressure    = pressure;
  SLdensity     = density;
  SLsoundspeed  = sqrt(SHRATIO*Reng*temperature);
  useExternal=false;
}

FGAtmosphere::~FGAtmosphere()
{
}

bool FGAtmosphere::Run(void)
{
  if (!FGModel::Run()) {                 // if false then execute this Run()
    if (!useExternal) {
      h = State->Geth();
      Calculate(h);
    } else {
      density = exDensity;
      pressure = exPressure;
      temperature = exTemperature;
    }
    soundspeed = sqrt(SHRATIO*Reng*temperature);
    State->Seta(soundspeed);
  } else {                               // skip Run() execution this time
  }
  return false;
}

void FGAtmosphere::Calculate(float altitude)
{
  //see reference [1]

    float slope,reftemp,refpress,refdens;
    int i=0;
    float htab[]={0,36089,82020,154198,173882,259183,295272,344484}; //ft.
//      cout << "Atmosphere:  h=" << altitude << " rho= " << density << endl;
    if (altitude <= htab[0]) {
      altitude=0;
    } else if (altitude >= htab[7]){
      i = 7;
      altitude = htab[7];
    } else {
      while (htab[i+1] < altitude) {
        i++;
      }
    }

    switch(i) {
    case 0:     // sea level
      slope     = -0.0035662; // R/ft.
      reftemp   = 518.688;    // R
      refpress  = 2116.17;    // psf
      refdens   = 0.0023765;  // slugs/cubic ft.
      break;
    case 1:     // 36089 ft.
      slope     = 0;
      reftemp   = 389.988;
      refpress  = 474.1;
      refdens   = 0.0007078;
      break;
    case 2:     // 82020 ft.
      slope     = 0.00164594;
      reftemp   = 389.988;
      refpress  = 52.7838;
      refdens   = 7.8849E-5;
      break;
    case 3:     // 154198 ft.
      slope     = 0;
      reftemp   = 508.788;
      refpress  = 2.62274;
      refdens   = 3.01379E-6;
      break;
    case 4:     // 173882 ft.
      slope     = -0.00246891;
      reftemp   = 508.788;
      refpress  = 1.28428;
      refdens   = 1.47035e-06;
      break;
    case 5:     // 259183 ft.
      slope     = 0;
      reftemp   = 298.188;
      refpress  = 0.0222008;
      refdens   = 4.33396e-08;
      break;
    case 6:     // 295272 ft.
      slope     = 0.00219459;
      reftemp   = 298.188;
      refpress  = 0.00215742;
      refdens   = 4.21368e-09;
      break;
    case 7:     // 344484 ft.
      slope     = 0;
      reftemp   = 406.188;
      refpress  = 0.000153755;
      refdens   = 2.20384e-10;
      break;
    }

    if (slope == 0) {
      temperature = reftemp;
      pressure = refpress*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
      density = refdens*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
    } else {
      temperature = reftemp+slope*(altitude-htab[i]);
      pressure = refpress*pow(temperature/reftemp,-GRAVITY/(slope*Reng));
      density = refdens*pow(temperature/reftemp,-(GRAVITY/(slope*Reng)+1));
    }

   cout << "Atmosphere:  h=" << altitude << " rho= " << density << endl;

}

<commit_msg>Removed output statement<commit_after>/*******************************************************************************

 Module:       FGAtmosphere.cpp
 Author:       Jon Berndt
               Implementation of 1959 Standard Atmosphere added by Tony Peden
 Date started: 11/24/98
 Purpose:      Models the atmosphere
 Called by:    FGSimExec

 ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program 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 General Public License for more
 details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
Models the atmosphere. The equation used below was determined by a third order
curve fit using Excel. The data is from the ICAO atmosphere model.

HISTORY
--------------------------------------------------------------------------------
11/24/98   JSB   Created
07/23/99   TP    Added implementation of 1959 Standard Atmosphere
                 Moved calculation of Mach number to FGTranslation
********************************************************************************
COMMENTS, REFERENCES,  and NOTES
********************************************************************************
[1]   Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
      1989, ISBN 0-07-001641-0

********************************************************************************
INCLUDES
*******************************************************************************/

#include "FGAtmosphere.h"
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGFCS.h"
#include "FGAircraft.h"
#include "FGTranslation.h"
#include "FGRotation.h"
#include "FGPosition.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"
#include "FGDefs.h"

/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/

FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
{
  Name = "FGAtmosphere";
  h = 0;
  Calculate(h);
  SLtemperature = temperature;
  SLpressure    = pressure;
  SLdensity     = density;
  SLsoundspeed  = sqrt(SHRATIO*Reng*temperature);
  useExternal=false;
}

FGAtmosphere::~FGAtmosphere()
{
}

bool FGAtmosphere::Run(void)
{
  if (!FGModel::Run()) {                 // if false then execute this Run()
    if (!useExternal) {
      h = State->Geth();
      Calculate(h);
    } else {
      density = exDensity;
      pressure = exPressure;
      temperature = exTemperature;
    }
    soundspeed = sqrt(SHRATIO*Reng*temperature);
    State->Seta(soundspeed);
  } else {                               // skip Run() execution this time
  }
  return false;
}

void FGAtmosphere::Calculate(float altitude)
{
  //see reference [1]

    float slope,reftemp,refpress,refdens;
    int i=0;
    float htab[]={0,36089,82020,154198,173882,259183,295272,344484}; //ft.
//      cout << "Atmosphere:  h=" << altitude << " rho= " << density << endl;
    if (altitude <= htab[0]) {
      altitude=0;
    } else if (altitude >= htab[7]){
      i = 7;
      altitude = htab[7];
    } else {
      while (htab[i+1] < altitude) {
        i++;
      }
    }

    switch(i) {
    case 0:     // sea level
      slope     = -0.0035662; // R/ft.
      reftemp   = 518.688;    // R
      refpress  = 2116.17;    // psf
      refdens   = 0.0023765;  // slugs/cubic ft.
      break;
    case 1:     // 36089 ft.
      slope     = 0;
      reftemp   = 389.988;
      refpress  = 474.1;
      refdens   = 0.0007078;
      break;
    case 2:     // 82020 ft.
      slope     = 0.00164594;
      reftemp   = 389.988;
      refpress  = 52.7838;
      refdens   = 7.8849E-5;
      break;
    case 3:     // 154198 ft.
      slope     = 0;
      reftemp   = 508.788;
      refpress  = 2.62274;
      refdens   = 3.01379E-6;
      break;
    case 4:     // 173882 ft.
      slope     = -0.00246891;
      reftemp   = 508.788;
      refpress  = 1.28428;
      refdens   = 1.47035e-06;
      break;
    case 5:     // 259183 ft.
      slope     = 0;
      reftemp   = 298.188;
      refpress  = 0.0222008;
      refdens   = 4.33396e-08;
      break;
    case 6:     // 295272 ft.
      slope     = 0.00219459;
      reftemp   = 298.188;
      refpress  = 0.00215742;
      refdens   = 4.21368e-09;
      break;
    case 7:     // 344484 ft.
      slope     = 0;
      reftemp   = 406.188;
      refpress  = 0.000153755;
      refdens   = 2.20384e-10;
      break;
    }

    if (slope == 0) {
      temperature = reftemp;
      pressure = refpress*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
      density = refdens*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
    } else {
      temperature = reftemp+slope*(altitude-htab[i]);
      pressure = refpress*pow(temperature/reftemp,-GRAVITY/(slope*Reng));
      density = refdens*pow(temperature/reftemp,-(GRAVITY/(slope*Reng)+1));
    }

   //cout << "Atmosphere:  h=" << altitude << " rho= " << density << endl;

}

<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Condor ClassAd library
 * Copyright (C) 1990-2001, CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI, and Rajesh Raman.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of version 2.1 of the GNU Lesser General
 * Public License as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 *********************************************************************/

#include "common.h"
#include "exprTree.h"

using namespace std;

BEGIN_NAMESPACE( classad )

ExprList::
ExprList()
{
	nodeKind = EXPR_LIST_NODE;
}

ExprList::
~ExprList()
{
	Clear( );
}

void ExprList::
Clear ()
{
	vector<ExprTree*>::iterator itr;
	for( itr = exprList.begin( ); itr != exprList.end( ); itr++ ) {
		delete *itr;
	}
	exprList.clear( );
}

ExprList *ExprList::
Copy( ) const
{
	ExprList *newList = new ExprList;
	ExprTree *newTree;

	if (newList == 0) return 0;
	newList->parentScope = parentScope;

	vector<ExprTree*>::const_iterator itr;
	for( itr = exprList.begin( ); itr != exprList.end( ); itr++ ) {
		if( !( newTree = (*itr)->Copy( ) ) ) {
			delete newList;
			CondorErrno = ERR_MEM_ALLOC_FAILED;
			CondorErrMsg = "";
			return((ExprList*)NULL);
		}
		newList->exprList.push_back( newTree );
	}
	return newList;
}

void ExprList::
_SetParentScope( const ClassAd *parent )
{
	vector<ExprTree*>::iterator	itr;
	for( itr = exprList.begin( ); itr != exprList.end( ); itr++ ) {
		(*itr)->SetParentScope( parent );
	}
}

ExprList *ExprList::
MakeExprList( const vector<ExprTree*> &exprs )
{
	vector<ExprTree*>::const_iterator itr;
	ExprList *el = new ExprList;
	if( !el ) {
		CondorErrno = ERR_MEM_ALLOC_FAILED;
		CondorErrMsg = "";
		return( NULL );
	}
	for( itr=exprs.begin( ) ; itr!=exprs.end( ); itr++ ) {
		el->exprList.push_back( *itr );
	}
	return( el );
}

void ExprList::
GetComponents( vector<ExprTree*> &exprs ) const
{
	vector<ExprTree*>::const_iterator itr;
	exprs.clear( );
	for( itr=exprList.begin( ); itr!=exprList.end( ); itr++ ) {
		exprs.push_back( *itr );
	}
}

bool ExprList::
_Evaluate (EvalState &, Value &val) const
{
	val.SetListValue (this);
	return( true );
}

bool ExprList::
_Evaluate( EvalState &, Value &val, ExprTree *&sig ) const
{
	val.SetListValue( this );
	return( ( sig = Copy( ) ) );
}

bool ExprList::
_Flatten( EvalState &state, Value &, ExprTree *&tree, int* ) const
{
	vector<ExprTree*>::const_iterator	itr;
	ExprTree	*expr, *nexpr;
	Value		tempVal;
	ExprList	*newList;

	if( ( newList = new ExprList( ) ) == NULL ) return false;

	for( itr = exprList.begin( ); itr != exprList.end( ); itr++ ) {
		expr = *itr;
		// flatten the constituent expression
		if( !expr->Flatten( state, tempVal, nexpr ) ) {
			delete newList;
			tree = NULL;
			return false;
		}

		// if only a value was obtained, convert to an expression
		if( !nexpr ) {
			nexpr = Literal::MakeLiteral( tempVal );
			if( !nexpr ) {
				CondorErrno = ERR_MEM_ALLOC_FAILED;
				CondorErrMsg = "";
				delete newList;
				return false;
			}
		}
		// add the new expression to the flattened list
		newList->exprList.push_back( nexpr );
	}

	tree = newList;

	return true;
}

// Iterator implementation
ExprListIterator::
ExprListIterator( )
{
	l = NULL;
}

ExprListIterator::
ExprListIterator( const ExprList* l )
{
	Initialize( l );
}

ExprListIterator::
~ExprListIterator( )
{
}

void ExprListIterator::
Initialize( const ExprList *el )
{
	// initialize eval state
	l = el;
	state.cache.clear( );
	state.curAd = (ClassAd*)l->parentScope;
	state.SetRootScope( );

	// initialize list iterator
	itr = l->exprList.begin( );
}

void ExprListIterator::
ToFirst( )
{
	if( l ) itr = l->exprList.begin( );
}

void ExprListIterator::
ToAfterLast( )
{
	if( l ) itr = l->exprList.end( );
}

bool ExprListIterator::
ToNth( int n )
{
	if( l && n >= 0 && l->exprList.size( ) > (unsigned)n ) {
		itr = l->exprList.begin( ) + n;
		return( true );
	}
	itr = l->exprList.begin( );
	return( false );
}

const ExprTree* ExprListIterator::
NextExpr( )
{
	if( l && itr != l->exprList.end( ) ) {
		itr++;
		return( itr==l->exprList.end() ? NULL : *itr );
	}
	return( NULL );
}

const ExprTree* ExprListIterator::
CurrentExpr( ) const
{
	return( l && itr != l->exprList.end( ) ? *itr : NULL );
}

const ExprTree* ExprListIterator::
PrevExpr( )
{
	if( l && itr != l->exprList.begin( ) ) {
		itr++;
		return( *itr );
	}
	return( NULL );
}

bool ExprListIterator::
GetValue( Value& val, const ExprTree *tree, EvalState *es )
{
	Value				cv;
	EvalState			*currentState;
    EvalCache::iterator	itr;

	if( !tree ) return false;

	// if called from user code, es == NULL so we use &state instead
	currentState = es ? es : &state;

	// lookup in cache
	itr = currentState->cache.find( tree );

	// if found, return cached value
	if( itr != currentState->cache.end( ) ) {
		val.CopyFrom( itr->second );
		return true;
	}

	// temporarily cache value as undef, so any circular refs in
    // Evaluate() will eval to undef rather than loop

	cv.SetUndefinedValue( );

	currentState->cache[ tree ] = cv;

	const ClassAd *tmpScope = es->curAd;
	es->curAd = (ClassAd*) tree->GetParentScope();
	tree->Evaluate( *currentState, val );
	es->curAd = (ClassAd*) tmpScope;

	// replace temporary cached value (above) with actual evaluation
	currentState->cache[ tree ] = val;

	return true;
}

bool ExprListIterator::
NextValue( Value& val, EvalState *es )
{
	return GetValue( val, NextExpr( ), es );
}

bool ExprListIterator::
CurrentValue( Value& val, EvalState *es )
{
	return GetValue( val, CurrentExpr( ), es );
}

bool ExprListIterator::
PrevValue( Value& val, EvalState *es )
{
	return GetValue( val, PrevExpr( ), es );
}

bool ExprListIterator::
GetValue( Value& val, ExprTree*& sig, const ExprTree *tree, EvalState *es )
{
	Value				cv;
	EvalState			*currentState;
    EvalCache::iterator	itr;

	if( !tree ) return false;

	// if called from user code, es == NULL so we use &state instead
	currentState = es ? es : &state;

	// lookup in cache
	itr = currentState->cache.find( tree );

	// if found, return cached value
	if( itr != currentState->cache.end( ) ) {
		val.CopyFrom( itr->second );
		return true;
	}

	// temporarily cache value as undef, so any circular refs in
    // Evaluate() will eval to undef rather than loop

	cv.SetUndefinedValue( );
	currentState->cache[ tree ] = cv;

	const ClassAd *tmpScope = es->curAd;
	es->curAd = (ClassAd*) tree->GetParentScope();
	tree->Evaluate( *currentState, val, sig );
	es->curAd = (ClassAd*) tmpScope;

	// replace temporary cached value (above) with actual evaluation
	currentState->cache[ tree ] = val;

	return true;
}

bool ExprListIterator::
NextValue( Value& val, ExprTree*& sig, EvalState *es )
{
	return GetValue( val, sig, NextExpr( ), es );
}

bool ExprListIterator::
CurrentValue( Value& val, ExprTree*& sig, EvalState *es )
{
	return GetValue( val, sig, CurrentExpr( ), es );
}

bool ExprListIterator::
PrevValue( Value& val, ExprTree*& sig, EvalState *es )
{
	return GetValue( val, sig, PrevExpr( ), es );
}

bool ExprListIterator::
IsAtFirst( ) const
{
	return( l && itr == l->exprList.begin( ) );
}

bool ExprListIterator::
IsAfterLast( ) const
{
	return( l && itr == l->exprList.end( ) );
}

END_NAMESPACE // classad
<commit_msg>Fixed NULL pointer de-reference.<commit_after>/*********************************************************************
 *
 * Condor ClassAd library
 * Copyright (C) 1990-2001, CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI, and Rajesh Raman.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of version 2.1 of the GNU Lesser General
 * Public License as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 *********************************************************************/

#include "common.h"
#include "exprTree.h"

using namespace std;

BEGIN_NAMESPACE( classad )

ExprList::
ExprList()
{
	nodeKind = EXPR_LIST_NODE;
}

ExprList::
~ExprList()
{
	Clear( );
}

void ExprList::
Clear ()
{
	vector<ExprTree*>::iterator itr;
	for( itr = exprList.begin( ); itr != exprList.end( ); itr++ ) {
		delete *itr;
	}
	exprList.clear( );
}

ExprList *ExprList::
Copy( ) const
{
	ExprList *newList = new ExprList;
	ExprTree *newTree;

	if (newList == 0) return 0;
	newList->parentScope = parentScope;

	vector<ExprTree*>::const_iterator itr;
	for( itr = exprList.begin( ); itr != exprList.end( ); itr++ ) {
		if( !( newTree = (*itr)->Copy( ) ) ) {
			delete newList;
			CondorErrno = ERR_MEM_ALLOC_FAILED;
			CondorErrMsg = "";
			return((ExprList*)NULL);
		}
		newList->exprList.push_back( newTree );
	}
	return newList;
}

void ExprList::
_SetParentScope( const ClassAd *parent )
{
	vector<ExprTree*>::iterator	itr;
	for( itr = exprList.begin( ); itr != exprList.end( ); itr++ ) {
		(*itr)->SetParentScope( parent );
	}
}

ExprList *ExprList::
MakeExprList( const vector<ExprTree*> &exprs )
{
	vector<ExprTree*>::const_iterator itr;
	ExprList *el = new ExprList;
	if( !el ) {
		CondorErrno = ERR_MEM_ALLOC_FAILED;
		CondorErrMsg = "";
		return( NULL );
	}
	for( itr=exprs.begin( ) ; itr!=exprs.end( ); itr++ ) {
		el->exprList.push_back( *itr );
	}
	return( el );
}

void ExprList::
GetComponents( vector<ExprTree*> &exprs ) const
{
	vector<ExprTree*>::const_iterator itr;
	exprs.clear( );
	for( itr=exprList.begin( ); itr!=exprList.end( ); itr++ ) {
		exprs.push_back( *itr );
	}
}

bool ExprList::
_Evaluate (EvalState &, Value &val) const
{
	val.SetListValue (this);
	return( true );
}

bool ExprList::
_Evaluate( EvalState &, Value &val, ExprTree *&sig ) const
{
	val.SetListValue( this );
	return( ( sig = Copy( ) ) );
}

bool ExprList::
_Flatten( EvalState &state, Value &, ExprTree *&tree, int* ) const
{
	vector<ExprTree*>::const_iterator	itr;
	ExprTree	*expr, *nexpr;
	Value		tempVal;
	ExprList	*newList;

	if( ( newList = new ExprList( ) ) == NULL ) return false;

	for( itr = exprList.begin( ); itr != exprList.end( ); itr++ ) {
		expr = *itr;
		// flatten the constituent expression
		if( !expr->Flatten( state, tempVal, nexpr ) ) {
			delete newList;
			tree = NULL;
			return false;
		}

		// if only a value was obtained, convert to an expression
		if( !nexpr ) {
			nexpr = Literal::MakeLiteral( tempVal );
			if( !nexpr ) {
				CondorErrno = ERR_MEM_ALLOC_FAILED;
				CondorErrMsg = "";
				delete newList;
				return false;
			}
		}
		// add the new expression to the flattened list
		newList->exprList.push_back( nexpr );
	}

	tree = newList;

	return true;
}

// Iterator implementation
ExprListIterator::
ExprListIterator( )
{
	l = NULL;
}

ExprListIterator::
ExprListIterator( const ExprList* l )
{
	Initialize( l );
}

ExprListIterator::
~ExprListIterator( )
{
}

void ExprListIterator::
Initialize( const ExprList *el )
{
	// initialize eval state
	l = el;
	state.cache.clear( );
	state.curAd = (ClassAd*)l->parentScope;
	state.SetRootScope( );

	// initialize list iterator
	itr = l->exprList.begin( );
}

void ExprListIterator::
ToFirst( )
{
	if( l ) itr = l->exprList.begin( );
}

void ExprListIterator::
ToAfterLast( )
{
	if( l ) itr = l->exprList.end( );
}

bool ExprListIterator::
ToNth( int n )
{
	if( l && n >= 0 && l->exprList.size( ) > (unsigned)n ) {
		itr = l->exprList.begin( ) + n;
		return( true );
	}
	itr = l->exprList.begin( );
	return( false );
}

const ExprTree* ExprListIterator::
NextExpr( )
{
	if( l && itr != l->exprList.end( ) ) {
		itr++;
		return( itr==l->exprList.end() ? NULL : *itr );
	}
	return( NULL );
}

const ExprTree* ExprListIterator::
CurrentExpr( ) const
{
	return( l && itr != l->exprList.end( ) ? *itr : NULL );
}

const ExprTree* ExprListIterator::
PrevExpr( )
{
	if( l && itr != l->exprList.begin( ) ) {
		itr++;
		return( *itr );
	}
	return( NULL );
}

bool ExprListIterator::
GetValue( Value& val, const ExprTree *tree, EvalState *es )
{
	Value				cv;
	EvalState			*currentState;
    EvalCache::iterator	itr;

	if( !tree ) return false;

	// if called from user code, es == NULL so we use &state instead
	currentState = es ? es : &state;

	// lookup in cache
	itr = currentState->cache.find( tree );

	// if found, return cached value
	if( itr != currentState->cache.end( ) ) {
		val.CopyFrom( itr->second );
		return true;
	}

	// temporarily cache value as undef, so any circular refs in
    // Evaluate() will eval to undef rather than loop

	cv.SetUndefinedValue( );

	currentState->cache[ tree ] = cv;

	const ClassAd *tmpScope = currentState->curAd;
	currentState->curAd = (ClassAd*) tree->GetParentScope();
	tree->Evaluate( *currentState, val );
	currentState->curAd = (ClassAd*) tmpScope;

	// replace temporary cached value (above) with actual evaluation
	currentState->cache[ tree ] = val;

	return true;
}

bool ExprListIterator::
NextValue( Value& val, EvalState *es )
{
	return GetValue( val, NextExpr( ), es );
}

bool ExprListIterator::
CurrentValue( Value& val, EvalState *es )
{
	return GetValue( val, CurrentExpr( ), es );
}

bool ExprListIterator::
PrevValue( Value& val, EvalState *es )
{
	return GetValue( val, PrevExpr( ), es );
}

bool ExprListIterator::
GetValue( Value& val, ExprTree*& sig, const ExprTree *tree, EvalState *es )
{
	Value				cv;
	EvalState			*currentState;
    EvalCache::iterator	itr;

	if( !tree ) return false;

	// if called from user code, es == NULL so we use &state instead
	currentState = es ? es : &state;

	// lookup in cache
	itr = currentState->cache.find( tree );

	// if found, return cached value
	if( itr != currentState->cache.end( ) ) {
		val.CopyFrom( itr->second );
		return true;
	}

	// temporarily cache value as undef, so any circular refs in
    // Evaluate() will eval to undef rather than loop

	cv.SetUndefinedValue( );
	currentState->cache[ tree ] = cv;

	const ClassAd *tmpScope = currentState->curAd;
	currentState->curAd = (ClassAd*) tree->GetParentScope();
	tree->Evaluate( *currentState, val, sig );
	currentState->curAd = (ClassAd*) tmpScope;

	// replace temporary cached value (above) with actual evaluation
	currentState->cache[ tree ] = val;

	return true;
}

bool ExprListIterator::
NextValue( Value& val, ExprTree*& sig, EvalState *es )
{
	return GetValue( val, sig, NextExpr( ), es );
}

bool ExprListIterator::
CurrentValue( Value& val, ExprTree*& sig, EvalState *es )
{
	return GetValue( val, sig, CurrentExpr( ), es );
}

bool ExprListIterator::
PrevValue( Value& val, ExprTree*& sig, EvalState *es )
{
	return GetValue( val, sig, PrevExpr( ), es );
}

bool ExprListIterator::
IsAtFirst( ) const
{
	return( l && itr == l->exprList.begin( ) );
}

bool ExprListIterator::
IsAfterLast( ) const
{
	return( l && itr == l->exprList.end( ) );
}

END_NAMESPACE // classad
<|endoftext|>


<commit_before>#include "PackAnimation.h"
#include "PackNodeFactory.h"
#include "PackAnchor.h"
#include "PackClipbox.h"
#include "Utility.h"
#include "typedef.h"

#include "AnimToLuaString.h"
#include "AnimFromLua.h"

#include "AnimToBin.h"
#include "AnimFromBin.h"

#include <ee/Sprite.h>
#include <ee/SymbolFile.h>
#include <ee/ImageSprite.h>
#include <ee/SymbolFile.h>

#include <sprite2/SymType.h>
#include <sprite2/RenderColor.h>
#include <sprite2/RenderShader.h>
#include <sprite2/RenderCamera.h>
#include <sprite2/RenderFilter.h>
#include <gum/trans_color.h>

namespace erespacker
{

PackAnimation::PackAnimation(int id)
	: IPackNode(id)
{
}

void PackAnimation::PackToLuaString(ebuilder::CodeGenerator& gen,
									const ee::TexturePacker& tp,
									float scale) const
{
	AnimToLuaString::Pack(this, gen);
}

void PackAnimation::UnpackFromLua(lua_State* L, const std::vector<ee::Image*>& images)
{
	AnimFromLua::Unpack(L, this);
}

int PackAnimation::SizeOfPackToBin() const
{
	return AnimToBin::Size(this);
}

void PackAnimation::PackToBin(uint8_t** ptr,
							  const ee::TexturePacker& tp,
							  float scale) const
{
	AnimToBin::Pack(this, ptr);
}

int PackAnimation::SizeOfUnpackFromBin() const
{
	return AnimFromBin::Size(this);
}

void PackAnimation::UnpackFromBin(uint8_t** ptr, const std::vector<ee::Image*>& images)
{
	AnimFromBin::Unpack(ptr, this);
}

bool PackAnimation::CreateFramePart(const ee::Sprite* spr, Frame& frame)
{
	const IPackNode* node = PackNodeFactory::Instance()->Create(spr);

	PackAnimation::Part part;
	std::string name = "";
	if (Utility::IsNameValid(spr->GetName())) {
		name = spr->GetName();
	}

	bool force_mat = false;
	bool new_comp = AddComponent(node, name, part.comp_idx, force_mat);
	PackAnimation::LoadSprTrans(spr, part.t, force_mat);

	frame.parts.push_back(part);

	return new_comp;
}

void PackAnimation::CreateClipboxFramePart(const PackClipbox* cb, Frame& frame)
{
	PackAnimation::Part part;

	bool force_mat;
	AddComponent(cb, "", part.comp_idx, force_mat);

	part.t.mat[0] = part.t.mat[3] = 1024;
	part.t.mat[1] = part.t.mat[2] = 0;
	part.t.mat[4] = static_cast<int>(cb->x * SCALE);
	part.t.mat[5] =-static_cast<int>(cb->y * SCALE);

	frame.parts.push_back(part);
}

void PackAnimation::Clear()
{
	export_name.clear();
	components.clear();
	actions.clear();
	frames.clear();
}

bool PackAnimation::AddComponent(const IPackNode* node, const std::string& name, int& comp_idx, bool& force_mat)
{
	bool new_comp = false;
	bool is_anchor = false;
	if (const PackAnchor* anchor = dynamic_cast<const PackAnchor*>(node)) {
		is_anchor = true;
		for (int i = 0, n = components.size(); i < n; ++i) {
			if (dynamic_cast<const PackAnchor*>(components[i].node) && components[i].name == name) {
				comp_idx = i;
				force_mat = true;
				return new_comp;
			}
		}
	} else {
		for (int i = 0, n = components.size(); i < n; ++i) {
			if (components[i].node == node && components[i].name == name) {
				comp_idx = i;
				force_mat = true;
				return new_comp;
			}
		}

		for (int i = 0, n = components.size(); i < n; ++i) {
			if (components[i].node->GetFilepath() == node->GetFilepath()
				&& components[i].name == name
				&& !name.empty())
			{
				int type = ee::SymbolFile::Instance()->Type(node->GetFilepath());
				switch (type)
				{
				case s2::SYM_IMAGE: case s2::SYM_COMPLEX: case s2::SYM_ANIMATION: case s2::SYM_TEXTBOX: case s2::SYM_MASK: case s2::SYM_PARTICLE3D:
					comp_idx = i;
					force_mat = true;
					return new_comp;
				}
			}
		}
	}

	Component comp;
	comp.node = node;
	comp.name = name;
	components.push_back(comp);
	comp_idx = components.size() - 1;

	new_comp = true;

	if (is_anchor) {
		force_mat = true;
	} else if (ee::SymbolFile::Instance()->Type(node->GetFilepath()) == s2::SYM_IMAGE) {
		force_mat = false;
	} else {
		force_mat = !name.empty();
	}

	return new_comp;
}

void PackAnimation::LoadSprTrans(const ee::Sprite* spr, SpriteTrans& trans, bool force_mat)
{
	LoadSprMat(spr, trans, force_mat);
	LoadSprColor(spr, trans);
	trans.blend = static_cast<int>(spr->GetShader().GetBlend());
	if (spr->GetShader().GetFilter()) {
		trans.filter = static_cast<int>(spr->GetShader().GetFilter()->GetMode());
	} else {
		trans.filter = s2::FM_NULL;
	}
	trans.camera = static_cast<int>(spr->GetCamera().mode);
}

void PackAnimation::LoadSprMat(const ee::Sprite* spr, SpriteTrans& trans, bool force)
{
	if (!force) {
		return;
	}

	float mat[6];

	// | 1  ky    | | sx       | |  c  s    | | 1       |
	// | kx  1    | |    sy    | | -s  c    | |    1    |
	// |        1 | |        1 | |        1 | | x  y  1 |
	//     skew        scale        rotate        move

	mat[1] = mat[2] = mat[4] = mat[5] = 0;
	mat[0] = mat[3] = 1;

	sm::vec2 center = spr->GetCenter();

	float sx = spr->GetScale().x,
		  sy = spr->GetScale().y;
	float c  = cos(-spr->GetAngle()),
		  s  = sin(-spr->GetAngle());
	float kx = -spr->GetShear().x,
		  ky = -spr->GetShear().y;
	mat[0] = sx*c - ky*sy*s;
	mat[1] = sx*s + ky*sy*c;
	mat[2] = kx*sx*c - sy*s;
	mat[3] = kx*sx*s + sy*c;
	mat[4] = center.x/* * m_scale*/;
	mat[5] = center.y/* * m_scale*/;

	for (size_t i = 0; i < 4; ++i) {
		trans.mat[i] = static_cast<int>(floor(mat[i] * 1024 + 0.5f));
	}
	for (size_t i = 4; i < 6; ++i) {
		trans.mat[i] = static_cast<int>(floor(mat[i] * 16 + 0.5f));
	}
	// flip y
	trans.mat[5] = -trans.mat[5];
}

void PackAnimation::LoadSprColor(const ee::Sprite* spr, SpriteTrans& trans)
{
	const s2::RenderColor& rc = spr->GetColor();

	trans.color    = gum::color2int(rc.mul, gum::ARGB);
	trans.additive = gum::color2int(rc.add, gum::ARGB);

	trans.rmap = rc.rmap.ToRGBA();
	trans.gmap = rc.gmap.ToRGBA();
	trans.bmap = rc.bmap.ToRGBA();
}

bool PackAnimation::IsMatrixIdentity(const int* mat)
{
	return mat[0] == 1024 && mat[3] == 1024
		&& mat[1] == 0 && mat[2] == 0 && mat[4] == 0 && mat[5] == 0;
}

}<commit_msg>Revert "[FIXED] pack img"<commit_after>#include "PackAnimation.h"
#include "PackNodeFactory.h"
#include "PackAnchor.h"
#include "PackClipbox.h"
#include "Utility.h"
#include "typedef.h"

#include "AnimToLuaString.h"
#include "AnimFromLua.h"

#include "AnimToBin.h"
#include "AnimFromBin.h"

#include <ee/Sprite.h>
#include <ee/SymbolFile.h>
#include <ee/ImageSprite.h>
#include <ee/SymbolFile.h>

#include <sprite2/SymType.h>
#include <sprite2/RenderColor.h>
#include <sprite2/RenderShader.h>
#include <sprite2/RenderCamera.h>
#include <sprite2/RenderFilter.h>
#include <gum/trans_color.h>

namespace erespacker
{

PackAnimation::PackAnimation(int id)
	: IPackNode(id)
{
}

void PackAnimation::PackToLuaString(ebuilder::CodeGenerator& gen,
									const ee::TexturePacker& tp,
									float scale) const
{
	AnimToLuaString::Pack(this, gen);
}

void PackAnimation::UnpackFromLua(lua_State* L, const std::vector<ee::Image*>& images)
{
	AnimFromLua::Unpack(L, this);
}

int PackAnimation::SizeOfPackToBin() const
{
	return AnimToBin::Size(this);
}

void PackAnimation::PackToBin(uint8_t** ptr,
							  const ee::TexturePacker& tp,
							  float scale) const
{
	AnimToBin::Pack(this, ptr);
}

int PackAnimation::SizeOfUnpackFromBin() const
{
	return AnimFromBin::Size(this);
}

void PackAnimation::UnpackFromBin(uint8_t** ptr, const std::vector<ee::Image*>& images)
{
	AnimFromBin::Unpack(ptr, this);
}

bool PackAnimation::CreateFramePart(const ee::Sprite* spr, Frame& frame)
{
	const IPackNode* node = PackNodeFactory::Instance()->Create(spr);

	PackAnimation::Part part;
	std::string name = "";
	if (Utility::IsNameValid(spr->GetName())) {
		name = spr->GetName();
	}

	bool force_mat = false;
	bool new_comp = AddComponent(node, name, part.comp_idx, force_mat);
	PackAnimation::LoadSprTrans(spr, part.t, force_mat);

	frame.parts.push_back(part);

	return new_comp;
}

void PackAnimation::CreateClipboxFramePart(const PackClipbox* cb, Frame& frame)
{
	PackAnimation::Part part;

	bool force_mat;
	AddComponent(cb, "", part.comp_idx, force_mat);

	part.t.mat[0] = part.t.mat[3] = 1024;
	part.t.mat[1] = part.t.mat[2] = 0;
	part.t.mat[4] = static_cast<int>(cb->x * SCALE);
	part.t.mat[5] =-static_cast<int>(cb->y * SCALE);

	frame.parts.push_back(part);
}

void PackAnimation::Clear()
{
	export_name.clear();
	components.clear();
	actions.clear();
	frames.clear();
}

bool PackAnimation::AddComponent(const IPackNode* node, const std::string& name, int& comp_idx, bool& force_mat)
{
	bool new_comp = false;
	bool is_anchor = false;
	if (const PackAnchor* anchor = dynamic_cast<const PackAnchor*>(node)) {
		is_anchor = true;
		for (int i = 0, n = components.size(); i < n; ++i) {
			if (dynamic_cast<const PackAnchor*>(components[i].node) && components[i].name == name) {
				comp_idx = i;
				force_mat = true;
				return new_comp;
			}
		}
	} else {
		for (int i = 0, n = components.size(); i < n; ++i) {
			if (components[i].node == node && components[i].name == name) {
				comp_idx = i;
				force_mat = true;
				return new_comp;
			}
		}

		for (int i = 0, n = components.size(); i < n; ++i) {
			if (components[i].node->GetFilepath() == node->GetFilepath()
				&& components[i].name == name
				&& !name.empty())
			{
				int type = ee::SymbolFile::Instance()->Type(node->GetFilepath());
				switch (type)
				{
				case s2::SYM_IMAGE:
					comp_idx = i;
					force_mat = false;
					return new_comp;
				case s2::SYM_COMPLEX: case s2::SYM_ANIMATION: case s2::SYM_TEXTBOX: case s2::SYM_MASK: case s2::SYM_PARTICLE3D:
					comp_idx = i;
					force_mat = true;
					return new_comp;
				}
			}
		}
	}

	Component comp;
	comp.node = node;
	comp.name = name;
	components.push_back(comp);
	comp_idx = components.size() - 1;

	new_comp = true;

	if (is_anchor) {
		force_mat = true;
	} else if (ee::SymbolFile::Instance()->Type(node->GetFilepath()) == s2::SYM_IMAGE) {
		force_mat = false;
	} else {
		force_mat = !name.empty();
	}

	return new_comp;
}

void PackAnimation::LoadSprTrans(const ee::Sprite* spr, SpriteTrans& trans, bool force_mat)
{
	LoadSprMat(spr, trans, force_mat);
	LoadSprColor(spr, trans);
	trans.blend = static_cast<int>(spr->GetShader().GetBlend());
	if (spr->GetShader().GetFilter()) {
		trans.filter = static_cast<int>(spr->GetShader().GetFilter()->GetMode());
	} else {
		trans.filter = s2::FM_NULL;
	}
	trans.camera = static_cast<int>(spr->GetCamera().mode);
}

void PackAnimation::LoadSprMat(const ee::Sprite* spr, SpriteTrans& trans, bool force)
{
	if (!force && dynamic_cast<const ee::ImageSprite*>(spr)) {
		return;
	}

	float mat[6];

	// | 1  ky    | | sx       | |  c  s    | | 1       |
	// | kx  1    | |    sy    | | -s  c    | |    1    |
	// |        1 | |        1 | |        1 | | x  y  1 |
	//     skew        scale        rotate        move

	mat[1] = mat[2] = mat[4] = mat[5] = 0;
	mat[0] = mat[3] = 1;

	sm::vec2 center = spr->GetCenter();

	float sx = spr->GetScale().x,
		  sy = spr->GetScale().y;
	float c  = cos(-spr->GetAngle()),
		  s  = sin(-spr->GetAngle());
	float kx = -spr->GetShear().x,
		  ky = -spr->GetShear().y;
	mat[0] = sx*c - ky*sy*s;
	mat[1] = sx*s + ky*sy*c;
	mat[2] = kx*sx*c - sy*s;
	mat[3] = kx*sx*s + sy*c;
	mat[4] = center.x/* * m_scale*/;
	mat[5] = center.y/* * m_scale*/;

	for (size_t i = 0; i < 4; ++i) {
		trans.mat[i] = static_cast<int>(floor(mat[i] * 1024 + 0.5f));
	}
	for (size_t i = 4; i < 6; ++i) {
		trans.mat[i] = static_cast<int>(floor(mat[i] * 16 + 0.5f));
	}
	// flip y
	trans.mat[5] = -trans.mat[5];
}

void PackAnimation::LoadSprColor(const ee::Sprite* spr, SpriteTrans& trans)
{
	const s2::RenderColor& rc = spr->GetColor();

	trans.color    = gum::color2int(rc.mul, gum::ARGB);
	trans.additive = gum::color2int(rc.add, gum::ARGB);

	trans.rmap = rc.rmap.ToRGBA();
	trans.gmap = rc.gmap.ToRGBA();
	trans.bmap = rc.bmap.ToRGBA();
}

bool PackAnimation::IsMatrixIdentity(const int* mat)
{
	return mat[0] == 1024 && mat[3] == 1024
		&& mat[1] == 0 && mat[2] == 0 && mat[4] == 0 && mat[5] == 0;
}

}<|endoftext|>


<commit_before>#ifndef CONTAINERS_OBJECT_BUFFER_HPP_
#define CONTAINERS_OBJECT_BUFFER_HPP_

#include "errors.hpp"

template <class T>
class object_buffer_t {
public:
    // TODO: this object makes no guarantees that its parent still exists when it is destroyed
    //  is that ok?
    class destruction_sentinel_t {
    public:
        explicit destruction_sentinel_t(object_buffer_t<T> *_parent) : parent(_parent) { }

        ~destruction_sentinel_t() {
            if (parent->has()) {
                parent->reset();
            }
        }
    private:
        object_buffer_t<T> *parent;

        DISABLE_COPYING(destruction_sentinel_t);
    };

    object_buffer_t() : instantiated(false) { }
    ~object_buffer_t() {
        if (instantiated) { reset(); }
    }

#define OBJECT_BUFFER_CREATE_INTERNAL(...) do {                         \
        rassert(!instantiated);                                         \
        instantiated = true;                                            \
        return new (&object_data[0]) T(__VA_ARGS__);                    \
    } while (0)

    // 9 arguments ought to be enough for anybody
    T * create()
    { OBJECT_BUFFER_CREATE_INTERNAL(); }

    template <class arg1_t>
    T * create(const arg1_t &arg1)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1); }

    template <class arg1_t, class arg2_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2); }

    template <class arg1_t, class arg2_t, class arg3_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5, const arg6_t &arg6)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5, arg6); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5, const arg6_t &arg6, const arg7_t &arg7)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5, arg6, arg7); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t, class arg8_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5, const arg6_t &arg6, const arg7_t &arg7, const arg8_t &arg8)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t, class arg8_t, class arg9_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5, const arg6_t &arg6, const arg7_t &arg7, const arg8_t &arg8, const arg9_t &arg9)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); }

    T * get() {
        rassert(instantiated);
        return reinterpret_cast<T *>(&object_data[0]);
    }

    const T * get() const {
        rassert(instantiated);
        return reinterpret_cast<const T *>(&object_data[0]);
    }

    void reset() {
        rassert(instantiated);
        get()->~T();
        instantiated = false;
    }

    bool has() const {
        return instantiated;
    }

private:
    bool instantiated;
    uint8_t object_data[sizeof(T)];

    DISABLE_COPYING(object_buffer_t);
};

#endif  // CONTAINERS_OBJECT_BUFFER_HPP_
<commit_msg>Made the object_buffer_t have a higher probability of good alignment.<commit_after>#ifndef CONTAINERS_OBJECT_BUFFER_HPP_
#define CONTAINERS_OBJECT_BUFFER_HPP_

#include "errors.hpp"

template <class T>
class object_buffer_t {
public:
    class destruction_sentinel_t {
    public:
        explicit destruction_sentinel_t(object_buffer_t<T> *_parent) : parent(_parent) { }

        ~destruction_sentinel_t() {
            if (parent->has()) {
                parent->reset();
            }
        }
    private:
        object_buffer_t<T> *parent;

        DISABLE_COPYING(destruction_sentinel_t);
    };

    object_buffer_t() : instantiated(false) { }
    ~object_buffer_t() {
        if (instantiated) { reset(); }
    }

#define OBJECT_BUFFER_CREATE_INTERNAL(...) do {                         \
        rassert(!instantiated);                                         \
        instantiated = true;                                            \
        return new (&object_data[0]) T(__VA_ARGS__);                    \
    } while (0)

    // 9 arguments ought to be enough for anybody
    T * create()
    { OBJECT_BUFFER_CREATE_INTERNAL(); }

    template <class arg1_t>
    T * create(const arg1_t &arg1)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1); }

    template <class arg1_t, class arg2_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2); }

    template <class arg1_t, class arg2_t, class arg3_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5, const arg6_t &arg6)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5, arg6); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5, const arg6_t &arg6, const arg7_t &arg7)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5, arg6, arg7); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t, class arg8_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5, const arg6_t &arg6, const arg7_t &arg7, const arg8_t &arg8)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }

    template <class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t, class arg8_t, class arg9_t>
    T * create(const arg1_t &arg1, const arg2_t &arg2, const arg3_t &arg3, const arg4_t &arg4, const arg5_t &arg5, const arg6_t &arg6, const arg7_t &arg7, const arg8_t &arg8, const arg9_t &arg9)
    { OBJECT_BUFFER_CREATE_INTERNAL(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); }

    T * get() {
        rassert(instantiated);
        return reinterpret_cast<T *>(&object_data[0]);
    }

    const T * get() const {
        rassert(instantiated);
        return reinterpret_cast<const T *>(&object_data[0]);
    }

    void reset() {
        rassert(instantiated);
        get()->~T();
        instantiated = false;
    }

    bool has() const {
        return instantiated;
    }

private:
    // We're going more for a high probability of good alignment than
    // proof of good alignment.
    uint8_t object_data[sizeof(T)];
    bool instantiated;

    DISABLE_COPYING(object_buffer_t);
};

#endif  // CONTAINERS_OBJECT_BUFFER_HPP_
<|endoftext|>


<commit_before>#include "input_manager.hpp"

#include "input_mapping.hpp"

#include "../asset/asset_manager.hpp"
#include "../utils/template_utils.hpp"

#include <glm/glm.hpp>
#include <sf2/sf2.hpp>

#include <SDL2/SDL_gesture.h>

#ifdef EMSCRIPTEN
	#include <emscripten/html5.h>
#endif

namespace lux {
namespace input {

	using namespace unit_literals;

	class Input_manager::Gamepad {
		public:
			Gamepad(Input_source src_id, SDL_GameController*, Input_mapper& mapper);
			~Gamepad();

			void force_feedback(float force);

			auto button_pressed(Pad_button b)const noexcept -> bool;
			auto button_released(Pad_button b)const noexcept -> bool;

			auto button_down(Pad_button b)const noexcept -> bool;
			auto button_up(Pad_button b)const noexcept -> bool;
			auto trigger(Pad_button b)const noexcept -> float;

			void update(Time dt);

			auto axis(Pad_stick stick) -> glm::vec2;

			auto id()const noexcept {return _id;}

		private:
			Input_source _src_id;
			int _id;
			SDL_GameController* _sdl_controller;
			SDL_Haptic* _haptic;
			Input_mapper& _mapper;

			uint8_t   _button_state[pad_button_count] {};
			float     _button_value[pad_button_count] {};
			glm::vec2 _stick_state[pad_stick_count]   {};

			float _stick_dead_zone=0.2, _stick_max=32767;

			float _current_force = 0.f;
			Time _force_reset_timer {0.f};
	};

	namespace {
		inline auto from_sdl_keycode(SDL_Keycode key) {
			return static_cast<Key>(key);
		}

		inline auto to_sdl_pad_button(Pad_button b) {
			return static_cast<SDL_GameControllerButton>(b);
		}
		inline bool is_trigger(Pad_button b) {
			return b==Pad_button::left_trigger || b==Pad_button::right_trigger;
		}

		inline auto to_sdl_axis_x(Pad_stick s) {
			switch(s) {
				case Pad_stick::left:     return SDL_CONTROLLER_AXIS_LEFTX;
				case Pad_stick::right:    return SDL_CONTROLLER_AXIS_RIGHTX;
				default:                  return SDL_CONTROLLER_AXIS_INVALID;
			}
		}
		inline auto to_sdl_axis_y(Pad_stick s) {
			switch(s) {
				case Pad_stick::left:     return SDL_CONTROLLER_AXIS_LEFTY;
				case Pad_stick::right:    return SDL_CONTROLLER_AXIS_RIGHTY;
				default:                  return SDL_CONTROLLER_AXIS_INVALID;
			}
		}

	}

	Input_manager::Input_manager(util::Message_bus& bus,
	                             asset::Asset_manager& assets)
	    : _mailbox(bus),
	      _screen_to_world_coords(&util::identity<glm::vec2>),
	      _mapper(std::make_unique<Input_mapper>(bus, assets)) {

		SDL_JoystickEventState(SDL_ENABLE);
		SDL_GameControllerEventState(SDL_ENABLE);

		SDL_RecordGesture(-1);

		_mailbox.subscribe<Force_feedback, 4>(8, [&](auto& m) {
			auto handle = [&](Force_feedback fb) {
				if(m.src>0 && m.src-1<static_cast<int>(this->_gamepads.size())) {
					auto& pad = this->_gamepads.at(m.src-1);
					if(pad)
						pad->force_feedback(m.force);
				}

	#ifdef EMSCRIPTEN
				if(m.src==0 && m.force>0.5)
					emscripten_vibrate(200);
	#endif
			};

			if(m.src>=0)
				handle(m);

			else {
				for(auto i=0u; i<this->_gamepads.size()+1; i++) {
					m.src = i;
					handle(m);
				}
			}
		});
	}

	Input_manager::~Input_manager()noexcept {
	}

	void Input_manager::update(Time dt) {
		for(auto& gp : _gamepads)
			gp->update(dt);

		_mailbox.update_subscriptions();
	}

	void Input_manager::handle_event(SDL_Event& event) {
		switch(event.type) {
			case SDL_TEXTINPUT:
				_mailbox.send<Char_input>(event.text.text);
				break;

			case SDL_KEYDOWN:
				if(event.key.repeat==0)
					_mapper->on_key_pressed(from_sdl_keycode(event.key.keysym.sym));
				break;

			case SDL_KEYUP:
				if(event.key.repeat==0)
					_mapper->on_key_released(from_sdl_keycode(event.key.keysym.sym));
				break;

			case SDL_MOUSEMOTION: {
				auto idx        = 0;
				auto screen_pos = glm::vec2{event.motion.x, event.motion.y};
				auto world_pos  = _screen_to_world_coords(screen_pos);
				auto world_diff = world_pos - _pointer_world_pos[idx];

				_pointer_screen_pos[idx] = screen_pos;
				_pointer_world_pos[idx]  = world_pos;

				_mapper->on_mouse_pos_change(world_diff, world_pos);
				break;
			}

			case SDL_MOUSEBUTTONDOWN:
				_mapper->on_mouse_button_pressed(event.button.button);
				_pointer_active[0] = true;
				break;

			case SDL_MOUSEBUTTONUP:
				_mapper->on_mouse_button_released(event.button.button, event.button.clicks);
				_pointer_active[0] = false;
				break;

			case SDL_FINGERMOTION:
			case SDL_FINGERUP:
			case SDL_FINGERDOWN: {
				int idx = 0;
				for(;idx<_max_pointers; idx++) {
					if(_pointer_finger_id[idx] == event.tfinger.fingerId)
						break;
				}
				if(idx>=_max_pointers) {
					for(idx=0; idx<_max_pointers; idx++) {
						if(!_pointer_active[idx])
							break;
					}
				}

				if(idx<_max_pointers) {
					auto screen_pos = glm::vec2{event.tfinger.x, event.tfinger.y};
					if(screen_pos.x<=1.0f && screen_pos.y<=1.0f) {
						screen_pos *= glm::vec2{_viewport.z,_viewport.w};
						screen_pos += glm::vec2{_viewport.x,_viewport.y};
					}

					auto world_pos  = _screen_to_world_coords(screen_pos);
					auto world_diff = world_pos - _pointer_world_pos[idx];

					_pointer_finger_id[idx]  = event.tfinger.fingerId;
					_pointer_screen_pos[idx] = screen_pos;
					_pointer_world_pos[idx]  = world_pos;
					_pointer_active[idx]     = event.type!=SDL_FINGERUP;

					if(idx==0) { //< mouse emulation
						_mapper->on_mouse_pos_change(world_diff, world_pos);

						if(event.tfinger.type==SDL_FINGERDOWN)
							_mapper->on_mouse_button_pressed(1, event.tfinger.pressure);
						else if(event.tfinger.type==SDL_FINGERUP)
							_mapper->on_mouse_button_released(1, 1);
					}
				}
				break;
			}

			case SDL_MOUSEWHEEL:
				_mapper->on_mouse_wheel_change({event.wheel.x,event.wheel.y});
				break;

			case SDL_CONTROLLERDEVICEADDED:
				_add_gamepad(event.cdevice.which);
				break;

			case SDL_CONTROLLERDEVICEREMOVED:
				_remove_gamepad(event.cdevice.which);
				break;

			case SDL_CONTROLLERDEVICEREMAPPED:
				break; // ignored for now
		}
	}
	void Input_manager::_add_gamepad(int joystick_id) {
		if(joystick_id==-1)
			joystick_id = SDL_NumJoysticks()-1;

		if (SDL_IsGameController(joystick_id)) {
			SDL_GameController* controller = SDL_GameControllerOpen(joystick_id);
			if (controller) {
				_gamepads.emplace_back(std::make_unique<Gamepad>(
						_gamepads.size()+1,
						controller,
						*_mapper ));
				_mailbox.send<Source_added>(Input_source(_gamepads.size()));

			} else {
				std::cerr<<"Could not open gamecontroller "<<joystick_id<<": "<<SDL_GetError()<<std::endl;
			}
		}
	}

	void Input_manager::_remove_gamepad(int instance_id) {
		auto e = std::find_if(_gamepads.begin(), _gamepads.end(),
					   [instance_id](auto& c) {
			return c->id()==instance_id;
		});

		if(e!=_gamepads.end()) {
			auto idx = std::distance(_gamepads.begin(), e);
			_mailbox.send<Source_removed>(Input_source(idx));
			e->reset();
		}
	}

	void Input_manager::enable_context(Context_id id) {
		_mapper->enable_context(id);
	}

	// Gamepad impl
	Input_manager::Gamepad::Gamepad(Input_source src_id,
	                                SDL_GameController* c,
	                                Input_mapper& mapper)
	    : _src_id(src_id),
	      _id(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(c))),
	      _sdl_controller(c),
	      _mapper(mapper) {

		auto name = SDL_GameControllerName(_sdl_controller);

		_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(_sdl_controller));
		if(!_haptic)
			WARN("Warning: Controller '"<<name<<
					   "'' does not support haptics: "<< SDL_GetError());

		else {
			if( SDL_HapticRumbleInit(_haptic) < 0 ) {
				_haptic = nullptr;
				WARN("Warning: Unable to initialize rumble for '"<<name<<
						   "': "<<SDL_GetError());
			}
		}

		INFO("Detected gamepad '"<<name<<"'");
	}
	Input_manager::Gamepad::~Gamepad() {
		if(_haptic)
			SDL_HapticClose(_haptic);

		SDL_GameControllerClose(_sdl_controller);
	}

	void Input_manager::Gamepad::force_feedback(float force) {
		if(force > _current_force) {
			_force_reset_timer = 200_ms;
			_current_force = force;
		}

		if(_haptic)
			SDL_HapticRumblePlay(_haptic, glm::clamp(_current_force,0.f,1.f), 200);
	}

	auto Input_manager::Gamepad::button_pressed(Pad_button b)const noexcept -> bool {
		return _button_state[static_cast<int8_t>(b)]==1;
	}
	auto Input_manager::Gamepad::button_released(Pad_button b)const noexcept -> bool {
		return _button_state[static_cast<int8_t>(b)]==3;
	}

	auto Input_manager::Gamepad::trigger(Pad_button b)const noexcept -> float {
		auto state = [&](auto t) {
			return glm::abs(SDL_GameControllerGetAxis(_sdl_controller,t)) / _stick_max;
		};

		if(b==Pad_button::left_trigger)
			return state(SDL_CONTROLLER_AXIS_TRIGGERLEFT);

		else if(b==Pad_button::right_trigger)
			return state(SDL_CONTROLLER_AXIS_TRIGGERRIGHT);

		else
			return 0;
	}

	auto Input_manager::Gamepad::button_down(Pad_button button)const noexcept -> bool {
		if(!is_trigger(button))
			return SDL_GameControllerGetButton(_sdl_controller, to_sdl_pad_button(button))!=0;

		else
			return trigger(button) > _stick_dead_zone;
	}
	auto Input_manager::Gamepad::button_up(Pad_button b)const noexcept -> bool {
		return !button_down(b);
	}

	void Input_manager::Gamepad::update(Time dt) {
		if(_force_reset_timer>0_s) {
			_force_reset_timer-=dt;
			if(_force_reset_timer<0_s)
				_current_force = 0.f;
		}

		for(auto i : util::range(pad_button_count)) {
			auto button = static_cast<Pad_button>(i);
			bool down = button_down(button);

			switch(_button_state[i]) {
				case 0: // up
					_button_state[i] = down ? 1 : 0;
					break;
				case 1: // pressed
					_button_state[i] = down ? 2 : 3;
					if(is_trigger(button))
						_mapper.on_pad_button_pressed(_src_id, button,
						                              trigger(button));
					else
						_mapper.on_pad_button_pressed(_src_id, button, 1.f);

					break;
				case 2: // down
					_button_state[i] = down ? 2 : 3;
					{
						auto value = trigger(button);
						if(std::abs(_button_value[i]-value)>0.1) {
							_mapper.on_pad_button_changed(_src_id,button,value);
							_button_value[i] = value;
						}
					}

					break;
				case 3: // released
					_button_state[i] = down ? 1 : 0;
					_mapper.on_pad_button_released(_src_id, button);
					break;
			}
		}

		for(auto i : util::range(pad_stick_count)) {
			auto stick = static_cast<Pad_stick>(i);

			auto state = axis(stick);
			if(state!=_stick_state[i]) {
				_mapper.on_pad_stick_change(_src_id, stick, state-_stick_state[i], state);
				_stick_state[i] = state;
			}
		}
	}

	auto Input_manager::Gamepad::axis(Pad_stick s) -> glm::vec2 {
		glm::vec2 v {
			SDL_GameControllerGetAxis(_sdl_controller, to_sdl_axis_x(s)) / _stick_max,
			SDL_GameControllerGetAxis(_sdl_controller, to_sdl_axis_y(s)) / _stick_max,
		};

		auto dz = _stick_dead_zone;
		auto length = glm::length(v);

		if(length<dz)
			return glm::vec2{0,0};

		return v/length * ((length-dz)/(1-dz));
	}

}
}
<commit_msg>fixed mouse drag<commit_after>#include "input_manager.hpp"

#include "input_mapping.hpp"

#include "../asset/asset_manager.hpp"
#include "../utils/template_utils.hpp"

#include <glm/glm.hpp>
#include <sf2/sf2.hpp>

#include <SDL2/SDL_gesture.h>

#ifdef EMSCRIPTEN
	#include <emscripten/html5.h>
#endif

namespace lux {
namespace input {

	using namespace unit_literals;

	class Input_manager::Gamepad {
		public:
			Gamepad(Input_source src_id, SDL_GameController*, Input_mapper& mapper);
			~Gamepad();

			void force_feedback(float force);

			auto button_pressed(Pad_button b)const noexcept -> bool;
			auto button_released(Pad_button b)const noexcept -> bool;

			auto button_down(Pad_button b)const noexcept -> bool;
			auto button_up(Pad_button b)const noexcept -> bool;
			auto trigger(Pad_button b)const noexcept -> float;

			void update(Time dt);

			auto axis(Pad_stick stick) -> glm::vec2;

			auto id()const noexcept {return _id;}

		private:
			Input_source _src_id;
			int _id;
			SDL_GameController* _sdl_controller;
			SDL_Haptic* _haptic;
			Input_mapper& _mapper;

			uint8_t   _button_state[pad_button_count] {};
			float     _button_value[pad_button_count] {};
			glm::vec2 _stick_state[pad_stick_count]   {};

			float _stick_dead_zone=0.2, _stick_max=32767;

			float _current_force = 0.f;
			Time _force_reset_timer {0.f};
	};

	namespace {
		inline auto from_sdl_keycode(SDL_Keycode key) {
			return static_cast<Key>(key);
		}

		inline auto to_sdl_pad_button(Pad_button b) {
			return static_cast<SDL_GameControllerButton>(b);
		}
		inline bool is_trigger(Pad_button b) {
			return b==Pad_button::left_trigger || b==Pad_button::right_trigger;
		}

		inline auto to_sdl_axis_x(Pad_stick s) {
			switch(s) {
				case Pad_stick::left:     return SDL_CONTROLLER_AXIS_LEFTX;
				case Pad_stick::right:    return SDL_CONTROLLER_AXIS_RIGHTX;
				default:                  return SDL_CONTROLLER_AXIS_INVALID;
			}
		}
		inline auto to_sdl_axis_y(Pad_stick s) {
			switch(s) {
				case Pad_stick::left:     return SDL_CONTROLLER_AXIS_LEFTY;
				case Pad_stick::right:    return SDL_CONTROLLER_AXIS_RIGHTY;
				default:                  return SDL_CONTROLLER_AXIS_INVALID;
			}
		}

	}

	Input_manager::Input_manager(util::Message_bus& bus,
	                             asset::Asset_manager& assets)
	    : _mailbox(bus),
	      _screen_to_world_coords(&util::identity<glm::vec2>),
	      _mapper(std::make_unique<Input_mapper>(bus, assets)) {

		SDL_JoystickEventState(SDL_ENABLE);
		SDL_GameControllerEventState(SDL_ENABLE);

		SDL_RecordGesture(-1);

		_mailbox.subscribe<Force_feedback, 4>(8, [&](auto& m) {
			auto handle = [&](Force_feedback fb) {
				if(m.src>0 && m.src-1<static_cast<int>(this->_gamepads.size())) {
					auto& pad = this->_gamepads.at(m.src-1);
					if(pad)
						pad->force_feedback(m.force);
				}

	#ifdef EMSCRIPTEN
				if(m.src==0 && m.force>0.5)
					emscripten_vibrate(200);
	#endif
			};

			if(m.src>=0)
				handle(m);

			else {
				for(auto i=0u; i<this->_gamepads.size()+1; i++) {
					m.src = i;
					handle(m);
				}
			}
		});
	}

	Input_manager::~Input_manager()noexcept {
	}

	void Input_manager::update(Time dt) {
		for(auto& gp : _gamepads)
			gp->update(dt);

		_mailbox.update_subscriptions();
	}

	void Input_manager::handle_event(SDL_Event& event) {
		switch(event.type) {
			case SDL_TEXTINPUT:
				_mailbox.send<Char_input>(event.text.text);
				break;

			case SDL_KEYDOWN:
				if(event.key.repeat==0)
					_mapper->on_key_pressed(from_sdl_keycode(event.key.keysym.sym));
				break;

			case SDL_KEYUP:
				if(event.key.repeat==0)
					_mapper->on_key_released(from_sdl_keycode(event.key.keysym.sym));
				break;

			case SDL_MOUSEMOTION: {
				auto idx        = 0;
				auto screen_pos = glm::vec2{event.motion.x, event.motion.y};
				auto world_pos  = _screen_to_world_coords(screen_pos);
				auto screen_diff = screen_pos - _pointer_screen_pos[idx];

				_pointer_screen_pos[idx] = screen_pos;
				_pointer_world_pos[idx]  = world_pos;

				_mapper->on_mouse_pos_change(screen_diff, screen_pos);
				break;
			}

			case SDL_MOUSEBUTTONDOWN:
				_mapper->on_mouse_button_pressed(event.button.button);
				_pointer_active[0] = true;
				break;

			case SDL_MOUSEBUTTONUP:
				_mapper->on_mouse_button_released(event.button.button, event.button.clicks);
				_pointer_active[0] = false;
				break;

			case SDL_FINGERMOTION:
			case SDL_FINGERUP:
			case SDL_FINGERDOWN: {
				int idx = 0;
				for(;idx<_max_pointers; idx++) {
					if(_pointer_finger_id[idx] == event.tfinger.fingerId)
						break;
				}
				if(idx>=_max_pointers) {
					for(idx=0; idx<_max_pointers; idx++) {
						if(!_pointer_active[idx])
							break;
					}
				}

				if(idx<_max_pointers) {
					auto screen_pos = glm::vec2{event.tfinger.x, event.tfinger.y};
					if(screen_pos.x<=1.0f && screen_pos.y<=1.0f) {
						screen_pos *= glm::vec2{_viewport.z,_viewport.w};
						screen_pos += glm::vec2{_viewport.x,_viewport.y};
					}

					auto world_pos  = _screen_to_world_coords(screen_pos);
					auto screen_diff = screen_pos - _pointer_screen_pos[idx];

					_pointer_finger_id[idx]  = event.tfinger.fingerId;
					_pointer_screen_pos[idx] = screen_pos;
					_pointer_world_pos[idx]  = world_pos;
					_pointer_active[idx]     = event.type!=SDL_FINGERUP;

					if(idx==0) { //< mouse emulation
						_mapper->on_mouse_pos_change(screen_diff, screen_pos);

						if(event.tfinger.type==SDL_FINGERDOWN)
							_mapper->on_mouse_button_pressed(1, event.tfinger.pressure);
						else if(event.tfinger.type==SDL_FINGERUP)
							_mapper->on_mouse_button_released(1, 1);
					}
				}
				break;
			}

			case SDL_MOUSEWHEEL:
				_mapper->on_mouse_wheel_change({event.wheel.x,event.wheel.y});
				break;

			case SDL_CONTROLLERDEVICEADDED:
				_add_gamepad(event.cdevice.which);
				break;

			case SDL_CONTROLLERDEVICEREMOVED:
				_remove_gamepad(event.cdevice.which);
				break;

			case SDL_CONTROLLERDEVICEREMAPPED:
				break; // ignored for now
		}
	}
	void Input_manager::_add_gamepad(int joystick_id) {
		if(joystick_id==-1)
			joystick_id = SDL_NumJoysticks()-1;

		if (SDL_IsGameController(joystick_id)) {
			SDL_GameController* controller = SDL_GameControllerOpen(joystick_id);
			if (controller) {
				_gamepads.emplace_back(std::make_unique<Gamepad>(
						_gamepads.size()+1,
						controller,
						*_mapper ));
				_mailbox.send<Source_added>(Input_source(_gamepads.size()));

			} else {
				std::cerr<<"Could not open gamecontroller "<<joystick_id<<": "<<SDL_GetError()<<std::endl;
			}
		}
	}

	void Input_manager::_remove_gamepad(int instance_id) {
		auto e = std::find_if(_gamepads.begin(), _gamepads.end(),
					   [instance_id](auto& c) {
			return c->id()==instance_id;
		});

		if(e!=_gamepads.end()) {
			auto idx = std::distance(_gamepads.begin(), e);
			_mailbox.send<Source_removed>(Input_source(idx));
			e->reset();
		}
	}

	void Input_manager::enable_context(Context_id id) {
		_mapper->enable_context(id);
	}

	// Gamepad impl
	Input_manager::Gamepad::Gamepad(Input_source src_id,
	                                SDL_GameController* c,
	                                Input_mapper& mapper)
	    : _src_id(src_id),
	      _id(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(c))),
	      _sdl_controller(c),
	      _mapper(mapper) {

		auto name = SDL_GameControllerName(_sdl_controller);

		_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(_sdl_controller));
		if(!_haptic)
			WARN("Warning: Controller '"<<name<<
					   "'' does not support haptics: "<< SDL_GetError());

		else {
			if( SDL_HapticRumbleInit(_haptic) < 0 ) {
				_haptic = nullptr;
				WARN("Warning: Unable to initialize rumble for '"<<name<<
						   "': "<<SDL_GetError());
			}
		}

		INFO("Detected gamepad '"<<name<<"'");
	}
	Input_manager::Gamepad::~Gamepad() {
		if(_haptic)
			SDL_HapticClose(_haptic);

		SDL_GameControllerClose(_sdl_controller);
	}

	void Input_manager::Gamepad::force_feedback(float force) {
		if(force > _current_force) {
			_force_reset_timer = 200_ms;
			_current_force = force;
		}

		if(_haptic)
			SDL_HapticRumblePlay(_haptic, glm::clamp(_current_force,0.f,1.f), 200);
	}

	auto Input_manager::Gamepad::button_pressed(Pad_button b)const noexcept -> bool {
		return _button_state[static_cast<int8_t>(b)]==1;
	}
	auto Input_manager::Gamepad::button_released(Pad_button b)const noexcept -> bool {
		return _button_state[static_cast<int8_t>(b)]==3;
	}

	auto Input_manager::Gamepad::trigger(Pad_button b)const noexcept -> float {
		auto state = [&](auto t) {
			return glm::abs(SDL_GameControllerGetAxis(_sdl_controller,t)) / _stick_max;
		};

		if(b==Pad_button::left_trigger)
			return state(SDL_CONTROLLER_AXIS_TRIGGERLEFT);

		else if(b==Pad_button::right_trigger)
			return state(SDL_CONTROLLER_AXIS_TRIGGERRIGHT);

		else
			return 0;
	}

	auto Input_manager::Gamepad::button_down(Pad_button button)const noexcept -> bool {
		if(!is_trigger(button))
			return SDL_GameControllerGetButton(_sdl_controller, to_sdl_pad_button(button))!=0;

		else
			return trigger(button) > _stick_dead_zone;
	}
	auto Input_manager::Gamepad::button_up(Pad_button b)const noexcept -> bool {
		return !button_down(b);
	}

	void Input_manager::Gamepad::update(Time dt) {
		if(_force_reset_timer>0_s) {
			_force_reset_timer-=dt;
			if(_force_reset_timer<0_s)
				_current_force = 0.f;
		}

		for(auto i : util::range(pad_button_count)) {
			auto button = static_cast<Pad_button>(i);
			bool down = button_down(button);

			switch(_button_state[i]) {
				case 0: // up
					_button_state[i] = down ? 1 : 0;
					break;
				case 1: // pressed
					_button_state[i] = down ? 2 : 3;
					if(is_trigger(button))
						_mapper.on_pad_button_pressed(_src_id, button,
						                              trigger(button));
					else
						_mapper.on_pad_button_pressed(_src_id, button, 1.f);

					break;
				case 2: // down
					_button_state[i] = down ? 2 : 3;
					{
						auto value = trigger(button);
						if(std::abs(_button_value[i]-value)>0.1) {
							_mapper.on_pad_button_changed(_src_id,button,value);
							_button_value[i] = value;
						}
					}

					break;
				case 3: // released
					_button_state[i] = down ? 1 : 0;
					_mapper.on_pad_button_released(_src_id, button);
					break;
			}
		}

		for(auto i : util::range(pad_stick_count)) {
			auto stick = static_cast<Pad_stick>(i);

			auto state = axis(stick);
			if(state!=_stick_state[i]) {
				_mapper.on_pad_stick_change(_src_id, stick, state-_stick_state[i], state);
				_stick_state[i] = state;
			}
		}
	}

	auto Input_manager::Gamepad::axis(Pad_stick s) -> glm::vec2 {
		glm::vec2 v {
			SDL_GameControllerGetAxis(_sdl_controller, to_sdl_axis_x(s)) / _stick_max,
			SDL_GameControllerGetAxis(_sdl_controller, to_sdl_axis_y(s)) / _stick_max,
		};

		auto dz = _stick_dead_zone;
		auto length = glm::length(v);

		if(length<dz)
			return glm::vec2{0,0};

		return v/length * ((length-dz)/(1-dz));
	}

}
}
<|endoftext|>


<commit_before>/*
 * main.cpp
 *
 *  Created on: Feb 25, 2017
 *      Author: fpregernik
 */

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <csignal>
#include <thread>
#include <chrono>
using namespace std;

#include "inc/cxxopts.hpp"
#include "radar_simulator.hpp"

RadarSimulator rsim;

std::chrono::seconds sleepDuration(1);

void signalHandler(int signum) {
    cout << "INTR=" << signum << endl;
    rsim.disable();
    cout << "DISABLE_SIM" << endl;

    exit(signum);
}

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

    // register signal SIGINT and signal handler
    signal(SIGINT, signalHandler);

    // ensure simulator is not running
    rsim.disable();

    // setup CLI option handling
    cxxopts::Options options(argv[0], " - example command line options");
    options.add_option("", "ct", "clear-target", "Clear target map", cxxopts::value<bool>(), "");
    options.add_option("", "cc", "clear-clutter", "Clear clutter map", cxxopts::value<bool>(), "");
    options.add_option("", "ltf", "load-target-file", "Load target file", cxxopts::value<string>(), "FILE");
    options.add_option("", "lcf", "load-clutter-file", "Load target file", cxxopts::value<string>(), "FILE");
    options.add_option("", "r", "run", "Start simulation", cxxopts::value<bool>(), "");
    options.add_option("", "c", "cal", "Calibrate", cxxopts::value<bool>(), "");
    options.add_option("", "h", "help", "Print help", cxxopts::value<bool>(), "");

    try {
        options.parse(argc, argv);
    } catch (const cxxopts::OptionException& e) {
        cout << "error parsing options: " << e.what() << endl;
        exit(1);
    }

    if (options.count("help")) {
        cout << options.help( { "" }) << endl;
        exit(0);
    }

    if (options.count("ct")) {
        rsim.clearTargetMap();
        cout << "CLR_MT_MAP" << endl;
    }

    if (options.count("ct")) {
        rsim.clearClutterMap();
        cout << "CLR_CL_MAP" << endl;
    }

    if (options.count("ltf")) {
        auto& ff = options["ltf"].as<string>();

        ifstream mtFile(ff, ios_base::in | ios_base::binary);
        if (!mtFile || !mtFile.is_open()) {
            cerr << "ERR=Unable to open file " << ff << endl;
            exit(2);
        }
        rsim.initTargetMap(mtFile);

        cout << "INIT_MT_FILE" << endl;
    }

    if (options.count("lcf")) {
        auto& ff = options["lcf"].as<string>();

        ifstream clFile(ff, ios_base::in | ios_base::binary);
        if (!clFile || !clFile.is_open()) {
            cerr << "ERR=Unable to open file " << ff << endl;
            exit(3);
        }
        rsim.initClutterMap(clFile);

        cout << "INIT_CL_FILE" << endl;
    }

    // get status
    auto status = rsim.getStatus();

    if (options.count("r")) {

        rsim.enable();
        cout << "ENABLE_SIM" << endl;

        auto startTime = chrono::steady_clock::now();
        auto lastStatTime = startTime;
        chrono::milliseconds timeSinceEpoch = chrono::duration_cast < chrono::milliseconds > (startTime.time_since_epoch());

        cout << "SIM_EN=" << status.enabled << endl;
        cout << "SIM_CAL=" << status.calibrated << endl;
        cout << "SIM_ARP_US=" << dec << status.arpUs << endl;
        cout << "SIM_ACP_CNT=" << dec << status.acpCnt << endl;
        cout << "SIM_TRIG_US=" << dec << status.trigUs << endl;
        cout << "SIM_MT_FIFO_CNT=" << dec << status.targetFifoCnt << endl;
        cout << "SIM_CL_FIFO_CNT=" << dec << status.clutterFifoCnt << endl;
        cout << "SIM_ACP_IDX=" << dec << status.simAcpIdx << "/" << timeSinceEpoch.count() << endl;
        cout << "SIM_CURR_ACP=" << dec << status.currAcpIdx << "/" << timeSinceEpoch.count() << endl;

        // notify caller of progress
        while (!rsim.isScenarioFinished()) {

            status = rsim.getStatus();

            auto secSinceFullStat = chrono::duration_cast < chrono::seconds > (chrono::steady_clock::now() - lastStatTime);
            if (secSinceFullStat.count() > 5 /* [s] */) {
                lastStatTime = chrono::steady_clock::now();
                cout << "SIM_EN=" << status.enabled << endl;
                cout << "SIM_CAL=" << status.calibrated << endl;
                cout << "SIM_ARP_US=" << dec << status.arpUs << endl;
                cout << "SIM_ACP_CNT=" << dec << status.acpCnt << endl;
                cout << "SIM_TRIG_US=" << dec << status.trigUs << endl;
                cout << "SIM_MT_FIFO_CNT=" << dec << status.targetFifoCnt << endl;
                cout << "SIM_CL_FIFO_CNT=" << dec << status.clutterFifoCnt << endl;
            }

            chrono::milliseconds timeSinceEpoch = chrono::duration_cast < chrono::milliseconds > (chrono::steady_clock::now().time_since_epoch());
            cout << "SIM_ACP_IDX=" << dec << status.simAcpIdx << "/" << timeSinceEpoch.count() << endl;
            cout << "SIM_CURR_ACP=" << dec << status.currAcpIdx << "/" << timeSinceEpoch.count() << endl;

            // check if we can load more moving target data
            if (options.count("ltf")) {
                auto& ff = options["ltf"].as<string>();
                ifstream mtFile(ff, ios_base::in | ios_base::binary);
                if (!mtFile || !mtFile.is_open()) {
                    cerr << "Unable to open file: " << ff << endl;
                    exit(2);
                }
                rsim.loadNextTargetMaps(mtFile);
            }

            this_thread::sleep_for(sleepDuration);
        }

        // disable simulator
        rsim.disable();
        cout << "END_SIM" << endl;

    } else if (options.count("c")) {

        // perform calibration
        cout << "CAL_BEGIN" << endl;

        do {

            status = rsim.getStatus();

            cout << "SIM_ARP_US=" << dec << status.arpUs << endl;
            cout << "SIM_ACP_CNT=" << dec << status.acpCnt << endl;
            cout << "SIM_TRIG_US=" << dec << status.trigUs << endl;
            cout << "SIM_CAL=" << status.calibrated << endl;

            this_thread::sleep_for(sleepDuration);

        } while (status.calibrated != 1);

        cout << "CAL_COMPLETE" << endl;

    }

    return 0;
}

<commit_msg>Remove unused code<commit_after>/*
 * main.cpp
 *
 *  Created on: Feb 25, 2017
 *      Author: fpregernik
 */

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <csignal>
#include <thread>
#include <chrono>
using namespace std;

#include "inc/cxxopts.hpp"
#include "radar_simulator.hpp"

RadarSimulator rsim;

std::chrono::seconds sleepDuration(1);

void signalHandler(int signum) {
    cout << "INTR=" << signum << endl;
    rsim.disable();
    cout << "DISABLE_SIM" << endl;

    exit(signum);
}

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

    // register signal SIGINT and signal handler
    signal(SIGINT, signalHandler);

    // ensure simulator is not running
    rsim.disable();

    // setup CLI option handling
    cxxopts::Options options(argv[0], " - example command line options");
    options.add_option("", "ct", "clear-target", "Clear target map", cxxopts::value<bool>(), "");
    options.add_option("", "cc", "clear-clutter", "Clear clutter map", cxxopts::value<bool>(), "");
    options.add_option("", "ltf", "load-target-file", "Load target file", cxxopts::value<string>(), "FILE");
    options.add_option("", "lcf", "load-clutter-file", "Load target file", cxxopts::value<string>(), "FILE");
    options.add_option("", "r", "run", "Start simulation", cxxopts::value<bool>(), "");
    options.add_option("", "c", "cal", "Calibrate", cxxopts::value<bool>(), "");
    options.add_option("", "h", "help", "Print help", cxxopts::value<bool>(), "");

    try {
        options.parse(argc, argv);
    } catch (const cxxopts::OptionException& e) {
        cout << "error parsing options: " << e.what() << endl;
        exit(1);
    }

    if (options.count("help")) {
        cout << options.help( { "" }) << endl;
        exit(0);
    }

    if (options.count("ct")) {
        rsim.clearTargetMap();
        cout << "CLR_MT_MAP" << endl;
    }

    if (options.count("ct")) {
        rsim.clearClutterMap();
        cout << "CLR_CL_MAP" << endl;
    }

    if (options.count("ltf")) {
        auto& ff = options["ltf"].as<string>();

        ifstream mtFile(ff, ios_base::in | ios_base::binary);
        if (!mtFile || !mtFile.is_open()) {
            cerr << "ERR=Unable to open file " << ff << endl;
            exit(2);
        }
        rsim.initTargetMap(mtFile);

        cout << "INIT_MT_FILE" << endl;
    }

    if (options.count("lcf")) {
        auto& ff = options["lcf"].as<string>();

        ifstream clFile(ff, ios_base::in | ios_base::binary);
        if (!clFile || !clFile.is_open()) {
            cerr << "ERR=Unable to open file " << ff << endl;
            exit(3);
        }
        rsim.initClutterMap(clFile);

        cout << "INIT_CL_FILE" << endl;
    }

    // get status
    auto status = rsim.getStatus();

    if (options.count("r")) {

        rsim.enable();
        cout << "ENABLE_SIM" << endl;

        auto startTime = chrono::steady_clock::now();
        auto lastStatTime = startTime;
        chrono::milliseconds timeSinceEpoch = chrono::duration_cast < chrono::milliseconds > (startTime.time_since_epoch());

        cout << "SIM_EN=" << status.enabled << endl;
        cout << "SIM_CAL=" << status.calibrated << endl;
        cout << "SIM_ARP_US=" << dec << status.arpUs << endl;
        cout << "SIM_ACP_CNT=" << dec << status.acpCnt << endl;
        cout << "SIM_TRIG_US=" << dec << status.trigUs << endl;
        cout << "SIM_MT_FIFO_CNT=" << dec << status.targetFifoCnt << endl;
        cout << "SIM_CL_FIFO_CNT=" << dec << status.clutterFifoCnt << endl;
        cout << "SIM_ACP_IDX=" << dec << status.simAcpIdx << "/" << timeSinceEpoch.count() << endl;
        cout << "SIM_CURR_ACP=" << dec << status.currAcpIdx << "/" << timeSinceEpoch.count() << endl;

        // notify caller of progress
        while (!rsim.isScenarioFinished()) {

            status = rsim.getStatus();

            auto secSinceFullStat = chrono::duration_cast < chrono::seconds > (chrono::steady_clock::now() - lastStatTime);
            if (secSinceFullStat.count() > 5 /* [s] */) {
                lastStatTime = chrono::steady_clock::now();
                cout << "SIM_EN=" << status.enabled << endl;
                cout << "SIM_CAL=" << status.calibrated << endl;
                cout << "SIM_ARP_US=" << dec << status.arpUs << endl;
                cout << "SIM_ACP_CNT=" << dec << status.acpCnt << endl;
                cout << "SIM_TRIG_US=" << dec << status.trigUs << endl;
                cout << "SIM_MT_FIFO_CNT=" << dec << status.targetFifoCnt << endl;
                cout << "SIM_CL_FIFO_CNT=" << dec << status.clutterFifoCnt << endl;
            }

            chrono::milliseconds timeSinceEpoch = chrono::duration_cast < chrono::milliseconds > (chrono::steady_clock::now().time_since_epoch());
            cout << "SIM_ACP_IDX=" << dec << status.simAcpIdx << "/" << timeSinceEpoch.count() << endl;

            // NOT IMPLEMENTED
            // cout << "SIM_CURR_ACP=" << dec << status.currAcpIdx << "/" << timeSinceEpoch.count() << endl;

            // check if we can load more moving target data
            if (options.count("ltf")) {
                auto& ff = options["ltf"].as<string>();
                ifstream mtFile(ff, ios_base::in | ios_base::binary);
                if (!mtFile || !mtFile.is_open()) {
                    cerr << "Unable to open file: " << ff << endl;
                    exit(2);
                }
                rsim.loadNextTargetMaps(mtFile);
            }

            this_thread::sleep_for(sleepDuration);
        }

        // disable simulator
        rsim.disable();
        cout << "END_SIM" << endl;

    } else if (options.count("c")) {

        // perform calibration
        cout << "CAL_BEGIN" << endl;

        do {

            status = rsim.getStatus();

            cout << "SIM_ARP_US=" << dec << status.arpUs << endl;
            cout << "SIM_ACP_CNT=" << dec << status.acpCnt << endl;
            cout << "SIM_TRIG_US=" << dec << status.trigUs << endl;
            cout << "SIM_CAL=" << status.calibrated << endl;

            this_thread::sleep_for(sleepDuration);

        } while (status.calibrated != 1);

        cout << "CAL_COMPLETE" << endl;

    }

    return 0;
}

<|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: Os2Transferable.hxx,v $
 * $Revision: 1.4 $
 *
 * 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 _DTRANS_OS2_TRANSFERABLE_HXX_
#define _DTRANS_OS2_TRANSFERABLE_HXX_

#include <com/sun/star/datatransfer/XTransferable.hpp>

#ifndef _COM_SUN_STAR_LANG_XEVENTLISTENER_HDL_
#include <com/sun/star/lang/XEventListener.hpp>
#endif
#include <cppuhelper/implbase1.hxx>
#include <osl/thread.h>

#include <errno.h>

#include <uclip.h>

#define CHAR_POINTER(THE_OUSTRING) ::rtl::OUStringToOString (THE_OUSTRING, RTL_TEXTENCODING_UTF8).pData->buffer

#if OSL_DEBUG_LEVEL>1
extern "C" int debug_printf(const char *f, ...);
#else
#define debug_printf( ...) { 1; }
#endif

#define CPPUTYPE_SEQSALINT8       getCppuType( (const Sequence< sal_Int8 >*) 0 )
#define CPPUTYPE_DEFAULT          CPPUTYPE_SEQSALINT8

#ifdef OOO_VENDOR
using namespace com::sun::star::uno;
HBITMAP OOoBmpToOS2Handle( Any &aAnyB);
int OS2HandleToOOoBmp( HBITMAP hbm, Sequence< sal_Int8 >* winDIBStream);
#else
#define OOoBmpToOS2Handle(a)    0
#define OS2HandleToOOoBmp(a,b)  0
#endif

namespace os2 {

    class Os2Transferable : public ::cppu::WeakImplHelper1 <
        ::com::sun::star::datatransfer::XTransferable >
    {
        HAB         hAB;
        ::rtl::OUString clipText;
        ::com::sun::star::datatransfer::DataFlavor aFlavor;
        ::osl::Mutex m_aMutex;
        ::com::sun::star::uno::Reference< XInterface >          m_xCreator;

    public:
        Os2Transferable( const ::com::sun::star::uno::Reference< XInterface >& xCreator);
        virtual ~Os2Transferable();

        /*
         * XTransferable
         */

        virtual ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor )
            throw(::com::sun::star::datatransfer::UnsupportedFlavorException,
                  ::com::sun::star::io::IOException,
                  ::com::sun::star::uno::RuntimeException
                  );

        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors(  )
            throw(::com::sun::star::uno::RuntimeException);

        virtual sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor )
            throw(::com::sun::star::uno::RuntimeException);
    };

} // namespace

#endif

<commit_msg>INTEGRATION: CWS os2port03 (1.3.8); FILE MERGED 2008/07/17 05:27:53 obr 1.3.8.2: RESYNC: (1.3-1.4); FILE MERGED 2008/01/14 16:27:33 ydario 1.3.8.1: remove old os2 directory Issue number:i85203 Submitted by:ydario<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: Os2Transferable.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 _DTRANS_OS2_TRANSFERABLE_HXX_
#define _DTRANS_OS2_TRANSFERABLE_HXX_

#include <com/sun/star/datatransfer/XTransferable.hpp>

#ifndef _COM_SUN_STAR_LANG_XEVENTLISTENER_HDL_
#include <com/sun/star/lang/XEventListener.hpp>
#endif
#include <cppuhelper/implbase1.hxx>
#include <osl/thread.h>

#include <errno.h>

#include <uclip.h>

#define CHAR_POINTER(THE_OUSTRING) ::rtl::OUStringToOString (THE_OUSTRING, RTL_TEXTENCODING_UTF8).pData->buffer

#if OSL_DEBUG_LEVEL>1
//extern "C" int debug_printf(const char *f, ...);
#define debug_printf( ...) { 1; }
#else
#define debug_printf( ...) { 1; }
#endif

#define CPPUTYPE_SEQSALINT8       getCppuType( (const Sequence< sal_Int8 >*) 0 )
#define CPPUTYPE_DEFAULT          CPPUTYPE_SEQSALINT8

#ifdef OOO_VENDOR
using namespace com::sun::star::uno;
HBITMAP OOoBmpToOS2Handle( Any &aAnyB);
int OS2HandleToOOoBmp( HBITMAP hbm, Sequence< sal_Int8 >* winDIBStream);
#else
#define OOoBmpToOS2Handle(a)    0
#define OS2HandleToOOoBmp(a,b)  0
#endif

namespace os2 {

    class Os2Transferable : public ::cppu::WeakImplHelper1 <
        ::com::sun::star::datatransfer::XTransferable >
    {
        HAB         hAB;
        ::rtl::OUString clipText;
        ::com::sun::star::datatransfer::DataFlavor aFlavor;
        ::osl::Mutex m_aMutex;
        ::com::sun::star::uno::Reference< XInterface >          m_xCreator;

    public:
        Os2Transferable( const ::com::sun::star::uno::Reference< XInterface >& xCreator);
        virtual ~Os2Transferable();

        /*
         * XTransferable
         */

        virtual ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor )
            throw(::com::sun::star::datatransfer::UnsupportedFlavorException,
                  ::com::sun::star::io::IOException,
                  ::com::sun::star::uno::RuntimeException
                  );

        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors(  )
            throw(::com::sun::star::uno::RuntimeException);

        virtual sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor )
            throw(::com::sun::star::uno::RuntimeException);
    };

} // namespace

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DataFmtTransl.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 06:04:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _DATAFMTTRANSL_HXX_
#define _DATAFMTTRANSL_HXX_

//-----------------------------------------------
// includes
//-----------------------------------------------

#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_
#include <cppuhelper/servicefactory.hxx>
#endif

#ifndef _COM_SUN_STAR_DATATRANSFER_XDATAFORMATTRANSLATOR_HPP_
#include <com/sun/star/datatransfer/XDataFormatTranslator.hpp>
#endif

#ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_
#include <com/sun/star/datatransfer/XTransferable.hpp>
#endif

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

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

#if defined _MSC_VER
#pragma warning(push,1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif

//-----------------------------------------------
// declaration
//-----------------------------------------------

class CFormatEtc;

class CDataFormatTranslator
{
public:
    CDataFormatTranslator( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&  aServiceManager );

    CFormatEtc getFormatEtcFromDataFlavor( const com::sun::star::datatransfer::DataFlavor& aDataFlavor ) const;
    com::sun::star::datatransfer::DataFlavor getDataFlavorFromFormatEtc(
        const FORMATETC& aFormatEtc, LCID lcid = GetThreadLocale( ) ) const;

    CFormatEtc    SAL_CALL getFormatEtcForClipformat( CLIPFORMAT cf ) const;
    CFormatEtc    SAL_CALL getFormatEtcForClipformatName( const rtl::OUString& aClipFmtName ) const;
    rtl::OUString SAL_CALL getClipboardFormatName( CLIPFORMAT aClipformat ) const;

    sal_Bool SAL_CALL isHTMLFormat( CLIPFORMAT cf ) const;
    sal_Bool SAL_CALL isTextHtmlFormat( CLIPFORMAT cf ) const;
    sal_Bool SAL_CALL isOemOrAnsiTextFormat( CLIPFORMAT cf ) const;
    sal_Bool SAL_CALL isUnicodeTextFormat( CLIPFORMAT cf ) const;
    sal_Bool SAL_CALL isTextFormat( CLIPFORMAT cf ) const;

private:
    rtl::OUString SAL_CALL getTextCharsetFromLCID( LCID lcid, CLIPFORMAT aClipformat ) const;

private:
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >  m_SrvMgr;
    com::sun::star::uno::Reference< com::sun::star::datatransfer::XDataFormatTranslator >   m_XDataFormatTranslator;
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.9.76); FILE MERGED 2008/04/01 15:13:35 thb 1.9.76.3: #i85898# Stripping all external header guards 2008/04/01 12:28:33 thb 1.9.76.2: #i85898# Stripping all external header guards 2008/03/31 13:09:02 rt 1.9.76.1: #i87441# Change license header to LPGL v3.<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: DataFmtTransl.hxx,v $
 * $Revision: 1.10 $
 *
 * 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 _DATAFMTTRANSL_HXX_
#define _DATAFMTTRANSL_HXX_

//-----------------------------------------------
// includes
//-----------------------------------------------

#include <cppuhelper/servicefactory.hxx>
#include <com/sun/star/datatransfer/XDataFormatTranslator.hpp>
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <sal/types.h>
#include <rtl/ustring.hxx>

#if defined _MSC_VER
#pragma warning(push,1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif

//-----------------------------------------------
// declaration
//-----------------------------------------------

class CFormatEtc;

class CDataFormatTranslator
{
public:
    CDataFormatTranslator( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&  aServiceManager );

    CFormatEtc getFormatEtcFromDataFlavor( const com::sun::star::datatransfer::DataFlavor& aDataFlavor ) const;
    com::sun::star::datatransfer::DataFlavor getDataFlavorFromFormatEtc(
        const FORMATETC& aFormatEtc, LCID lcid = GetThreadLocale( ) ) const;

    CFormatEtc    SAL_CALL getFormatEtcForClipformat( CLIPFORMAT cf ) const;
    CFormatEtc    SAL_CALL getFormatEtcForClipformatName( const rtl::OUString& aClipFmtName ) const;
    rtl::OUString SAL_CALL getClipboardFormatName( CLIPFORMAT aClipformat ) const;

    sal_Bool SAL_CALL isHTMLFormat( CLIPFORMAT cf ) const;
    sal_Bool SAL_CALL isTextHtmlFormat( CLIPFORMAT cf ) const;
    sal_Bool SAL_CALL isOemOrAnsiTextFormat( CLIPFORMAT cf ) const;
    sal_Bool SAL_CALL isUnicodeTextFormat( CLIPFORMAT cf ) const;
    sal_Bool SAL_CALL isTextFormat( CLIPFORMAT cf ) const;

private:
    rtl::OUString SAL_CALL getTextCharsetFromLCID( LCID lcid, CLIPFORMAT aClipformat ) const;

private:
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >  m_SrvMgr;
    com::sun::star::uno::Reference< com::sun::star::datatransfer::XDataFormatTranslator >   m_XDataFormatTranslator;
};

#endif
<|endoftext|>