<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/

#include <osg/Texture2D>
#include <osg/CoordinateSystemNode>
#include <osg/TexEnv>
#include <osg/io_utils>

#include <osgUtil/CullVisitor>
#include <osgShadow/ShadowedScene>

using namespace osgShadow;

ShadowedScene::ShadowedScene(ShadowTechnique* st):
    _recievesShadowTraversalMask(0xffffffff),
    _castsShadowTraversalMask(0xffffffff)
{
    setNumChildrenRequiringUpdateTraversal(1);

    if (st) setShadowTechnique(st);
}

ShadowedScene::ShadowedScene(const ShadowedScene& copy, const osg::CopyOp& copyop):
    osg::Group(copy,copyop),
    _recievesShadowTraversalMask(copy._recievesShadowTraversalMask),
    _castsShadowTraversalMask(copy._castsShadowTraversalMask)
{
    setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);

    if (copy._shadowTechnique.valid())
    {
        setShadowTechnique( dynamic_cast<osgShadow::ShadowTechnique*>(copy._shadowTechnique->clone(copyop)) );
    }

}

ShadowedScene::~ShadowedScene()
{
    setShadowTechnique(0);
}

void ShadowedScene::traverse(osg::NodeVisitor& nv)
{
    if (_shadowTechnique.valid())
    {
        _shadowTechnique->traverse(nv);
    }
    else
    {
        osg::Group::traverse(nv);
    }
}

void ShadowedScene::setShadowTechnique(ShadowTechnique* technique)
{
    if (_shadowTechnique == technique) return;

    if (_shadowTechnique.valid())
    {
        _shadowTechnique->cleanSceneGraph();
        _shadowTechnique->_shadowedScene = 0;
    }

    _shadowTechnique = technique;

    if (_shadowTechnique.valid())
    {
        _shadowTechnique->_shadowedScene = this;
        _shadowTechnique->dirty();
    }
}

void ShadowedScene::dirty()
{
    if (_shadowTechnique.valid())
    {
        _shadowTechnique->dirty();
    }
}
<commit_msg>Checked in missing implementation of cleanSceneGraph.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/

#include <osg/Texture2D>
#include <osg/CoordinateSystemNode>
#include <osg/TexEnv>
#include <osg/io_utils>

#include <osgUtil/CullVisitor>
#include <osgShadow/ShadowedScene>

using namespace osgShadow;

ShadowedScene::ShadowedScene(ShadowTechnique* st):
    _recievesShadowTraversalMask(0xffffffff),
    _castsShadowTraversalMask(0xffffffff)
{
    setNumChildrenRequiringUpdateTraversal(1);

    if (st) setShadowTechnique(st);
}

ShadowedScene::ShadowedScene(const ShadowedScene& copy, const osg::CopyOp& copyop):
    osg::Group(copy,copyop),
    _recievesShadowTraversalMask(copy._recievesShadowTraversalMask),
    _castsShadowTraversalMask(copy._castsShadowTraversalMask)
{
    setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);

    if (copy._shadowTechnique.valid())
    {
        setShadowTechnique( dynamic_cast<osgShadow::ShadowTechnique*>(copy._shadowTechnique->clone(copyop)) );
    }

}

ShadowedScene::~ShadowedScene()
{
    setShadowTechnique(0);
}

void ShadowedScene::traverse(osg::NodeVisitor& nv)
{
    if (_shadowTechnique.valid())
    {
        _shadowTechnique->traverse(nv);
    }
    else
    {
        osg::Group::traverse(nv);
    }
}

void ShadowedScene::setShadowTechnique(ShadowTechnique* technique)
{
    if (_shadowTechnique == technique) return;

    if (_shadowTechnique.valid())
    {
        _shadowTechnique->cleanSceneGraph();
        _shadowTechnique->_shadowedScene = 0;
    }

    _shadowTechnique = technique;

    if (_shadowTechnique.valid())
    {
        _shadowTechnique->_shadowedScene = this;
        _shadowTechnique->dirty();
    }
}

void ShadowedScene::cleanSceneGraph()
{
    if (_shadowTechnique.valid())
    {
        _shadowTechnique->cleanSceneGraph();
    }
}

void ShadowedScene::dirty()
{
    if (_shadowTechnique.valid())
    {
        _shadowTechnique->dirty();
    }
}
<|endoftext|>


<commit_before>#include <Automaton.h>
#include "Atm_teensywave.h"

ATM_CLASSNAME & ATM_CLASSNAME::begin( int attached_pin, int steps, int delay )
{
      const static state_t state_table[] PROGMEM = {
      /*                ON_ENTER    ON_LOOP  ON_EXIT  EVT_COUNTER   EVT_TIMER  EVT_TOGGLE   ELSE */
      /* IDLE     */    ACT_IDLE, ATM_SLEEP,      -1,          -1,         -1,   START_SN,    -1,
      /* START_SN */   ACT_START,        -1,      -1,          -1,         -1,         -1,  SINE,
      /* SINE     */    ACT_SINE,        -1,      -1,    START_SN,       SINE,   START_SW,    -1,
      /* START_SW */   ACT_START,        -1,      -1,          -1,         -1,         -1,   SAW,
      /* SAW      */     ACT_SAW,        -1,      -1,    START_SW,        SAW,   START_SQ,    -1,
      /* START_SQ */ ACT_STARTSQ,        -1,      -1,          -1,         -1,         -1,  SQON,
      /* SQON     */    ACT_SQON,        -1,      -1,          -1,      SQOFF,         -1,    -1,
      /* SQOFF    */   ACT_SQOFF,        -1,      -1,          -1,       SQON,   START_SN,    -1,
	  };
      table( state_table, ELSE );
      pin = attached_pin;
      _steps = steps;
	  _delay = delay;
      set( timer, delay );
      set( phase, steps ); // 314 steps of 0.02 = 6.28 ( 2 * pi )
      _stepsize = (float) 6.28318 / _steps;
      pinMode( pin, OUTPUT );
	  analogWriteResolution( 12 );
      return *this;
}

int ATM_CLASSNAME::event( int id )
{
  switch ( id ) {
	case EVT_TIMER :
	  return expired( timer );
	case EVT_COUNTER :
	  return expired( phase );
	case EVT_TOGGLE :
	  return signalRead( SIG_TOGGLE );
   }
   return 0;
}

void ATM_CLASSNAME::action( int id )
{
  int val;
  switch ( id ) {
	case ACT_IDLE :
	  analogWrite( pin, 0 );
	  return;
	case ACT_START :
      set( timer, _delay );
	  set( phase, _steps );
	  return;
	case ACT_STARTSQ :
      set( timer, (int) ( _steps * _delay / 2 ) );
	  return;
	case ACT_SINE :
	  val = sin( phase.value * _stepsize ) * 2000.0 + 2050.0;
	  analogWrite( pin, val );
	  decrement( phase );
	  return;
	case ACT_SAW :
	  val = ( _steps - phase.value ) * 13;
	  analogWrite( pin, val );
	  decrement( phase );
	  return;
	case ACT_SQON :
	  analogWrite( pin, 4095 );
	  return;
	case ACT_SQOFF :
	  analogWrite( pin, 0 );
	  return;
   }
}
<commit_msg>Formatting<commit_after>#include <Automaton.h>
#include "Atm_teensywave.h"

ATM_CLASSNAME & ATM_CLASSNAME::begin( int attached_pin, int steps, int delay )
{
      const static state_t state_table[] PROGMEM = {
      /*                ON_ENTER    ON_LOOP  ON_EXIT  EVT_COUNTER   EVT_TIMER  EVT_TOGGLE   ELSE */
      /* IDLE     */    ACT_IDLE, ATM_SLEEP,      -1,          -1,         -1,   START_SN,    -1,
      /* START_SN */   ACT_START,        -1,      -1,          -1,         -1,         -1,  SINE,
      /* SINE     */    ACT_SINE,        -1,      -1,    START_SN,       SINE,   START_SW,    -1,
      /* START_SW */   ACT_START,        -1,      -1,          -1,         -1,         -1,   SAW,
      /* SAW      */     ACT_SAW,        -1,      -1,    START_SW,        SAW,   START_SQ,    -1,
      /* START_SQ */ ACT_STARTSQ,        -1,      -1,          -1,         -1,         -1,  SQON,
      /* SQON     */    ACT_SQON,        -1,      -1,          -1,      SQOFF,         -1,    -1,
      /* SQOFF    */   ACT_SQOFF,        -1,      -1,          -1,       SQON,   START_SN,    -1,
      };
      table( state_table, ELSE );
      pin = attached_pin;
      _steps = steps;
      _delay = delay;
      set( timer, delay );
      set( phase, steps ); // 314 steps of 0.02 = 6.28 ( 2 * pi )
      _stepsize = (float) 6.28318 / _steps;
      pinMode( pin, OUTPUT );
      analogWriteResolution( 12 );
      return *this;
}

int ATM_CLASSNAME::event( int id )
{
  switch ( id ) {
    case EVT_TIMER :
      return expired( timer );
    case EVT_COUNTER :
      return expired( phase );
    case EVT_TOGGLE :
      return signalRead( SIG_TOGGLE );
   }
   return 0;
}

void ATM_CLASSNAME::action( int id )
{
  int val;
  switch ( id ) {
    case ACT_IDLE :
      analogWrite( pin, 0 );
      return;
    case ACT_START :
      set( timer, _delay );
      set( phase, _steps );
      return;
    case ACT_STARTSQ :
      set( timer, (int) ( _steps * _delay / 2 ) );
      return;
    case ACT_SINE :
      val = sin( phase.value * _stepsize ) * 2000.0 + 2050.0;
      analogWrite( pin, val );
      decrement( phase );
      return;
    case ACT_SAW :
      val = ( _steps - phase.value ) * 13;
      analogWrite( pin, val );
      decrement( phase );
      return;
    case ACT_SQON :
      analogWrite( pin, 4095 );
      return;
    case ACT_SQOFF :
      analogWrite( pin, 0 );
      return;
   }
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "util/fixes.h"
#include <temple/dll.h>
#include "temple_functions.h"
#include "config/config.h"
#include "xp.h"
#include "obj.h"
#include "critter.h"
#include "party.h"
#include "d20_level.h"
#include "gamesystems/objects/objsystem.h"
#include "sound.h"
#include "combat.h"
#include "history.h"
#include "float_line.h"
#include "gamesystems/gamesystems.h"
#include "gamesystems/particlesystems.h"
#include "ui/ui_systems.h"
#include "ui/ui_legacysystems.h"

temple::GlobalPrimitive<float, 0x102CF708> experienceMultiplier;
temple::GlobalPrimitive<int, 0x10BCA850> numCrittersSlainByCR;
temple::GlobalPrimitive<int, 0x10BCA8BC> xpPile; // sum of all the XP given to party members before divinding by party size

static_assert(CRMIN == -2, "CRMIN for XP award definition should be at most -2!");
static_assert(CRMAX >= 20, "CRMAX for XP award definition should be at least 20!");
static_assert(XPTABLE_MAXLEVEL >= 20, "XPTABLE_MAXLEVEL for XP award definition should be at least 20!");

// static int XPAwardTable[XPTABLE_MAXLEVEL][CRMAX - CRMIN + 1] = {};

BOOL XPAward::XpGainProcess(objHndl handle, int xpGainRaw){

	if (!xpGainRaw || !handle)
		return FALSE;

	auto obj = objSystem->GetObject(handle);
	auto couldAlreadyLevelup = d20LevelSys.CanLevelup(handle);

	auto xpReduction = GetMulticlassXpReductionPercent(handle);
	auto xpGain = (int) ((1.0 - xpReduction / 100.0)*xpGainRaw);

	std::string text(fmt::format("{} {} {} {}", description.getDisplayName(handle), combatSys.GetCombatMesLine(145), xpGain, combatSys.GetCombatMesLine(146) )); // [obj] gains [xpGain] experience points
	if (xpReduction){
		text.append(fmt::format(" {}", combatSys.GetCombatMesLine(147)));
	}
	histSys.CreateFromFreeText( (text + "\n").c_str());

	auto xpNew = obj->GetInt32(obj_f_critter_experience) + xpGain;
	auto curLvl = critterSys.GetEffectiveLevel(handle);

	auto xpCap = d20LevelSys.GetXpRequireForLevel(curLvl + 2) - 1;
	if (curLvl >= (int)config.maxLevel)
		xpCap = d20LevelSys.GetXpRequireForLevel(config.maxLevel);

	if (!config.allowXpOverflow && xpNew > (int)xpCap)
		xpNew = xpCap;

	d20Sys.d20SendSignal(handle, DK_SIG_Experience_Awarded, xpNew, 0);
	obj->SetInt32(obj_f_critter_experience, xpNew);

	if (couldAlreadyLevelup || !d20LevelSys.CanLevelup(handle))
		return FALSE;

	floatSys.FloatCombatLine(handle, 148); // gains a level!
	histSys.CreateFromFreeText(fmt::format("{} {}\n", description.getDisplayName(handle), combatSys.GetCombatMesLine(148)).c_str()); // [obj] gains a level!
	gameSystems->GetParticleSys().CreateAtObj("LEVEL UP", handle);

	return TRUE;
}

int XPAward::GetMulticlassXpReductionPercent(objHndl handle){
	auto highestLvl = -1;
	auto reductionPct = 0;

	if (config.laxRules && config.disableMulticlassXpPenalty)
		return reductionPct;

	for (auto it: d20ClassSys.baseClassEnums){
		auto classEnum = (Stat)it;
		auto classLvl = objects.StatLevelGet(handle, classEnum);
		if (classLvl > highestLvl && !d20Sys.d20QueryWithData(handle, DK_QUE_FavoredClass, classEnum,0)){
			highestLvl = classLvl;
		}
	}

	for (auto it : d20ClassSys.baseClassEnums) {
		auto classEnum = (Stat)it;
		auto classLvl = objects.StatLevelGet(handle, classEnum);
		if (classLvl > 0 && classLvl < highestLvl - 1 && !d20Sys.d20QueryWithData(handle, DK_QUE_FavoredClass, classEnum,0)){
			reductionPct += 20;
		}
	}

	if (reductionPct >= 80)
		reductionPct = 80;

	return reductionPct;
}

XPAward::XPAward(){
	int table[XPTABLE_MAXLEVEL][CRMAX - CRMIN + 1];
	memset(table, 0, sizeof(table));

	// First set the table's "spine" - when CR = Level  then   XP = 300*level
	for (int level = 1; level <= XPTABLE_MAXLEVEL; level++) {
		assert(level >= 1);
		assert(level - CRMIN < CRCOUNT);
		if (!config.slowerLevelling || level < 3)
			table[level - 1][level - CRMIN] = level * 300;
		else
			table[level - 1][level - CRMIN] = (int)(level * 300 * (1 - min(0.66f, 0.66f * powf(level - 2.0f, 0.1f) / powf(16.0f, 0.1f))));
	}

	// Fill out the bottom left portion - CRs less than level - from highest to lowest
	for (int level = 1; level <= XPTABLE_MAXLEVEL; level++){
		for (int j = level - CRMIN - 1; j >= 2; j--){
			int i = level - 1;
			int cr = j + CRMIN;

			assert(i >= 0 && i < XPTABLE_MAXLEVEL);
			assert(j >= 0 && j < CRCOUNT);

			// 8 CRs below level grant nothing
			if (cr <= level - 8){
				table[i][j] = 0;
			}
			else if (cr == 0){
				table[i][2] = table[i][3] / 2; // CR 1/2
				table[i][1] = table[i][3] / 3; // CR 1/3
				table[i][0] = table[i][3] / 4; // CR 1/4
			}
			else if (cr == level - 1) {
				assert(i >= 1);
				if (config.slowerLevelling)
					table[i][j] = min(table[i - 1][j], (table[i][j + 1] * 6) / 11);
				else
					table[i][j] = min(table[i - 1][j], (table[i][j+1] * 2) /3);
			}
			else {
				assert(i >= 1);
				assert(j + 2 < CRCOUNT);
				if (config.slowerLevelling)
					table[i][j] = min(table[i - 1][j], ( table[i][j + 2] * 3) / 10);
				else
					table[i][j] = min(table[i - 1][j], table[i][j + 2] / 2);
			}
		}
	}

	// Fill out the top right portion
	for (int cr_off = 1; cr_off < CRMAX; cr_off++){

		for (int level = 1; level <= XPTABLE_MAXLEVEL && level + cr_off <= CRMAX; level++){
			int i = level - 1;
			int j = level - CRMIN + cr_off;

			assert(i >= 0 && i < XPTABLE_MAXLEVEL);
			assert(j >= 0 && j < CRCOUNT);

			if (cr_off >= 10){
				table[i][j] = table[level - 1][j - 1]; // repeat the last value
			}
			else if (cr_off == 1){
				assert(j >= 1);
				assert(i + 1 < XPTABLE_MAXLEVEL);
				table[i][j] = max((table[i][j - 1] * 3) / 2, table[i + 1][j]);
			}
			else {
				assert(i + 1 < XPTABLE_MAXLEVEL);
				assert(j >= 2);
				table[i][j] = max(table[i][j - 2] * 2, table[i + 1][j]);
			}
		}
	}

	memcpy(XPAwardTable, table, sizeof(table));
};

// XP Table Fix for higher levels
class XPTableForHighLevels : public TempleFix {
public:

	XPAward *xpawarddd;
	void GiveXPAwards();
	void apply() override;
} xpTableFix;

void XPTableForHighLevels::GiveXPAwards(){
	float fNumLivingPartyMembers = 0.0;

	//int XPAwardTable[XPTABLE_MAXLEVEL][CRMAX - CRMIN + 1] = {};

	for (uint32_t i = 0; i < party.GroupPCsLen(); i++){
		objHndl objHndPC = party.GroupPCsGetMemberN(i);
		if (!critterSys.IsDeadNullDestroyed(objHndPC)){
			fNumLivingPartyMembers += 1.0;
		}
	};
	for (uint32_t i = 0; i < party.GroupNPCFollowersLen(); i++){
		objHndl objHndNPCFollower = party.GroupNPCFollowersGetMemberN(i);
		if (!critterSys.IsDeadNullDestroyed(objHndNPCFollower)
			&& !d20Sys.d20Query(objHndNPCFollower, DK_QUE_ExperienceExempt)){
			fNumLivingPartyMembers += 1.0;
		}
	};
	if (fNumLivingPartyMembers < 0.99){
		return;
	};

	auto killCountByCR = numCrittersSlainByCR.ptr();
	bool bShouldUpdatePartyUI = false;
	int xpForxpPile = 0;

	for (uint32_t i = 0; i < party.GroupListGetLen(); i++){
		objHndl objHnd = party.GroupListGetMemberN(i);

		if (critterSys.IsDeadNullDestroyed(objHnd)){ continue; };
		if (d20Sys.d20Query(objHnd, DK_QUE_ExperienceExempt)) { continue; };
		if (party.ObjIsAIFollower(objHnd)) { continue; };

		int level = critterSys.GetEffectiveLevel(objHnd);
		if (level <= 0) { continue; };

		int xpGainRaw = 0; // raw means it's prior to applying multiclass penalties, which  is Someone Else's Problem :P

		for (int n = 0; n < CR_KILLED_TABLE_SIZE; n++){
			float nkill = (float)killCountByCR[n];
			float xp = (float)xpawarddd->XPAwardTable[level - 1][n];
			if (nkill){
				xpGainRaw += (int)(
					experienceMultiplier *
					nkill *	xp
					);
			}

		}
		xpForxpPile += xpGainRaw;
		xpGainRaw = int((float)(xpGainRaw) / fNumLivingPartyMembers);
		//if (templeFuncs.ObjXPGainProcess(objHnd, xpGainRaw)) {
		if (xpawarddd->XpGainProcess(objHnd, xpGainRaw)){
			auto obj = objSystem->GetObject(objHnd);
			if (obj->IsPC() || config.NPCsLevelLikePCs){
				bShouldUpdatePartyUI = true;
			}
		}
	}

	for (int n = 0; n < CR_KILLED_TABLE_SIZE; n++){
		killCountByCR[n] = 0;
	};
	*(xpPile.ptr()) = xpForxpPile;

	if (bShouldUpdatePartyUI){
		uiSystems->GetParty().Update();
		sound.PlaySound(100001); // LEVEL_UP.WAV
		sound.PlaySound(100001); // amp it up a bit
	}

	return;
}

void XPTableForHighLevels::apply() {
	logger->info("Applying XP Table Extension upto Level 20");
	replaceFunction<void(__cdecl)()>(0x100B5700, []() {
		xpTableFix.GiveXPAwards(); }
	);

	xpawarddd = new XPAward();

	if (config.allowXpOverflow)	{
		writeNoops(0x100B5608);
	}
}
<commit_msg>Added the ability to disable the XP penalty for particular character.<commit_after>#include "stdafx.h"
#include "util/fixes.h"
#include <temple/dll.h>
#include "temple_functions.h"
#include "config/config.h"
#include "xp.h"
#include "obj.h"
#include "critter.h"
#include "party.h"
#include "d20_level.h"
#include "gamesystems/objects/objsystem.h"
#include "sound.h"
#include "combat.h"
#include "history.h"
#include "float_line.h"
#include "gamesystems/gamesystems.h"
#include "gamesystems/particlesystems.h"
#include "ui/ui_systems.h"
#include "ui/ui_legacysystems.h"

temple::GlobalPrimitive<float, 0x102CF708> experienceMultiplier;
temple::GlobalPrimitive<int, 0x10BCA850> numCrittersSlainByCR;
temple::GlobalPrimitive<int, 0x10BCA8BC> xpPile; // sum of all the XP given to party members before divinding by party size

static_assert(CRMIN == -2, "CRMIN for XP award definition should be at most -2!");
static_assert(CRMAX >= 20, "CRMAX for XP award definition should be at least 20!");
static_assert(XPTABLE_MAXLEVEL >= 20, "XPTABLE_MAXLEVEL for XP award definition should be at least 20!");

// static int XPAwardTable[XPTABLE_MAXLEVEL][CRMAX - CRMIN + 1] = {};

BOOL XPAward::XpGainProcess(objHndl handle, int xpGainRaw){

	if (!xpGainRaw || !handle)
		return FALSE;

	auto obj = objSystem->GetObject(handle);
	auto couldAlreadyLevelup = d20LevelSys.CanLevelup(handle);

	auto xpReduction = GetMulticlassXpReductionPercent(handle);

	//Check if the multiclass xp penalty should be disabled for this character
	auto res = d20Sys.D20QueryPython(handle, "No MultiClass XP Penalty");
	if (res != 0) {
		xpReduction = 0;
	}
	auto xpGain = (int)((1.0 - xpReduction / 100.0)*xpGainRaw);

	std::string text(fmt::format("{} {} {} {}", description.getDisplayName(handle), combatSys.GetCombatMesLine(145), xpGain, combatSys.GetCombatMesLine(146) )); // [obj] gains [xpGain] experience points
	if (xpReduction){
		text.append(fmt::format(" {}", combatSys.GetCombatMesLine(147)));
	}
	histSys.CreateFromFreeText( (text + "\n").c_str());

	auto xpNew = obj->GetInt32(obj_f_critter_experience) + xpGain;
	auto curLvl = critterSys.GetEffectiveLevel(handle);

	auto xpCap = d20LevelSys.GetXpRequireForLevel(curLvl + 2) - 1;
	if (curLvl >= (int)config.maxLevel)
		xpCap = d20LevelSys.GetXpRequireForLevel(config.maxLevel);

	if (!config.allowXpOverflow && xpNew > (int)xpCap)
		xpNew = xpCap;

	d20Sys.d20SendSignal(handle, DK_SIG_Experience_Awarded, xpNew, 0);
	obj->SetInt32(obj_f_critter_experience, xpNew);

	if (couldAlreadyLevelup || !d20LevelSys.CanLevelup(handle))
		return FALSE;

	floatSys.FloatCombatLine(handle, 148); // gains a level!
	histSys.CreateFromFreeText(fmt::format("{} {}\n", description.getDisplayName(handle), combatSys.GetCombatMesLine(148)).c_str()); // [obj] gains a level!
	gameSystems->GetParticleSys().CreateAtObj("LEVEL UP", handle);

	return TRUE;
}

int XPAward::GetMulticlassXpReductionPercent(objHndl handle){
	auto highestLvl = -1;
	auto reductionPct = 0;

	if (config.laxRules && config.disableMulticlassXpPenalty)
		return reductionPct;

	for (auto it: d20ClassSys.baseClassEnums){
		auto classEnum = (Stat)it;
		auto classLvl = objects.StatLevelGet(handle, classEnum);
		if (classLvl > highestLvl && !d20Sys.d20QueryWithData(handle, DK_QUE_FavoredClass, classEnum,0)){
			highestLvl = classLvl;
		}
	}

	for (auto it : d20ClassSys.baseClassEnums) {
		auto classEnum = (Stat)it;
		auto classLvl = objects.StatLevelGet(handle, classEnum);
		if (classLvl > 0 && classLvl < highestLvl - 1 && !d20Sys.d20QueryWithData(handle, DK_QUE_FavoredClass, classEnum,0)){
			reductionPct += 20;
		}
	}

	if (reductionPct >= 80)
		reductionPct = 80;

	return reductionPct;
}

XPAward::XPAward(){
	int table[XPTABLE_MAXLEVEL][CRMAX - CRMIN + 1];
	memset(table, 0, sizeof(table));

	// First set the table's "spine" - when CR = Level  then   XP = 300*level
	for (int level = 1; level <= XPTABLE_MAXLEVEL; level++) {
		assert(level >= 1);
		assert(level - CRMIN < CRCOUNT);
		if (!config.slowerLevelling || level < 3)
			table[level - 1][level - CRMIN] = level * 300;
		else
			table[level - 1][level - CRMIN] = (int)(level * 300 * (1 - min(0.66f, 0.66f * powf(level - 2.0f, 0.1f) / powf(16.0f, 0.1f))));
	}

	// Fill out the bottom left portion - CRs less than level - from highest to lowest
	for (int level = 1; level <= XPTABLE_MAXLEVEL; level++){
		for (int j = level - CRMIN - 1; j >= 2; j--){
			int i = level - 1;
			int cr = j + CRMIN;

			assert(i >= 0 && i < XPTABLE_MAXLEVEL);
			assert(j >= 0 && j < CRCOUNT);

			// 8 CRs below level grant nothing
			if (cr <= level - 8){
				table[i][j] = 0;
			}
			else if (cr == 0){
				table[i][2] = table[i][3] / 2; // CR 1/2
				table[i][1] = table[i][3] / 3; // CR 1/3
				table[i][0] = table[i][3] / 4; // CR 1/4
			}
			else if (cr == level - 1) {
				assert(i >= 1);
				if (config.slowerLevelling)
					table[i][j] = min(table[i - 1][j], (table[i][j + 1] * 6) / 11);
				else
					table[i][j] = min(table[i - 1][j], (table[i][j+1] * 2) /3);
			}
			else {
				assert(i >= 1);
				assert(j + 2 < CRCOUNT);
				if (config.slowerLevelling)
					table[i][j] = min(table[i - 1][j], ( table[i][j + 2] * 3) / 10);
				else
					table[i][j] = min(table[i - 1][j], table[i][j + 2] / 2);
			}
		}
	}

	// Fill out the top right portion
	for (int cr_off = 1; cr_off < CRMAX; cr_off++){

		for (int level = 1; level <= XPTABLE_MAXLEVEL && level + cr_off <= CRMAX; level++){
			int i = level - 1;
			int j = level - CRMIN + cr_off;

			assert(i >= 0 && i < XPTABLE_MAXLEVEL);
			assert(j >= 0 && j < CRCOUNT);

			if (cr_off >= 10){
				table[i][j] = table[level - 1][j - 1]; // repeat the last value
			}
			else if (cr_off == 1){
				assert(j >= 1);
				assert(i + 1 < XPTABLE_MAXLEVEL);
				table[i][j] = max((table[i][j - 1] * 3) / 2, table[i + 1][j]);
			}
			else {
				assert(i + 1 < XPTABLE_MAXLEVEL);
				assert(j >= 2);
				table[i][j] = max(table[i][j - 2] * 2, table[i + 1][j]);
			}
		}
	}

	memcpy(XPAwardTable, table, sizeof(table));
};

// XP Table Fix for higher levels
class XPTableForHighLevels : public TempleFix {
public:

	XPAward *xpawarddd;
	void GiveXPAwards();
	void apply() override;
} xpTableFix;

void XPTableForHighLevels::GiveXPAwards(){
	float fNumLivingPartyMembers = 0.0;

	//int XPAwardTable[XPTABLE_MAXLEVEL][CRMAX - CRMIN + 1] = {};

	for (uint32_t i = 0; i < party.GroupPCsLen(); i++){
		objHndl objHndPC = party.GroupPCsGetMemberN(i);
		if (!critterSys.IsDeadNullDestroyed(objHndPC)){
			fNumLivingPartyMembers += 1.0;
		}
	};
	for (uint32_t i = 0; i < party.GroupNPCFollowersLen(); i++){
		objHndl objHndNPCFollower = party.GroupNPCFollowersGetMemberN(i);
		if (!critterSys.IsDeadNullDestroyed(objHndNPCFollower)
			&& !d20Sys.d20Query(objHndNPCFollower, DK_QUE_ExperienceExempt)){
			fNumLivingPartyMembers += 1.0;
		}
	};
	if (fNumLivingPartyMembers < 0.99){
		return;
	};

	auto killCountByCR = numCrittersSlainByCR.ptr();
	bool bShouldUpdatePartyUI = false;
	int xpForxpPile = 0;

	for (uint32_t i = 0; i < party.GroupListGetLen(); i++){
		objHndl objHnd = party.GroupListGetMemberN(i);

		if (critterSys.IsDeadNullDestroyed(objHnd)){ continue; };
		if (d20Sys.d20Query(objHnd, DK_QUE_ExperienceExempt)) { continue; };
		if (party.ObjIsAIFollower(objHnd)) { continue; };

		int level = critterSys.GetEffectiveLevel(objHnd);
		if (level <= 0) { continue; };

		int xpGainRaw = 0; // raw means it's prior to applying multiclass penalties, which  is Someone Else's Problem :P

		for (int n = 0; n < CR_KILLED_TABLE_SIZE; n++){
			float nkill = (float)killCountByCR[n];
			float xp = (float)xpawarddd->XPAwardTable[level - 1][n];
			if (nkill){
				xpGainRaw += (int)(
					experienceMultiplier *
					nkill *	xp
					);
			}

		}
		xpForxpPile += xpGainRaw;
		xpGainRaw = int((float)(xpGainRaw) / fNumLivingPartyMembers);
		//if (templeFuncs.ObjXPGainProcess(objHnd, xpGainRaw)) {
		if (xpawarddd->XpGainProcess(objHnd, xpGainRaw)){
			auto obj = objSystem->GetObject(objHnd);
			if (obj->IsPC() || config.NPCsLevelLikePCs){
				bShouldUpdatePartyUI = true;
			}
		}
	}

	for (int n = 0; n < CR_KILLED_TABLE_SIZE; n++){
		killCountByCR[n] = 0;
	};
	*(xpPile.ptr()) = xpForxpPile;

	if (bShouldUpdatePartyUI){
		uiSystems->GetParty().Update();
		sound.PlaySound(100001); // LEVEL_UP.WAV
		sound.PlaySound(100001); // amp it up a bit
	}

	return;
}

void XPTableForHighLevels::apply() {
	logger->info("Applying XP Table Extension upto Level 20");
	replaceFunction<void(__cdecl)()>(0x100B5700, []() {
		xpTableFix.GiveXPAwards(); }
	);

	xpawarddd = new XPAward();

	if (config.allowXpOverflow)	{
		writeNoops(0x100B5608);
	}
}
<|endoftext|>


<commit_before>/**
 * \file dcs/testbed/application_managers.hpp
 *
 * \brief Forward declarations for currently implemented application managers.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 *

 *
 * Copyright 2012 Marco Guazzone (marco.guazzone@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef DCS_TESTBED_APPLICATION_MANAGERS_HPP
#define DCS_TESTBED_APPLICATION_MANAGERS_HPP

#include <dcs/testbed/albano2013_fuzzyqe_application_manager.hpp>
//#include <dcs/testbed/albano2013v2_fuzzyqe_application_manager.hpp>
//#include <dcs/testbed/albano2013v3_fuzzyqe_application_manager.hpp>
//#include <dcs/testbed/albano2013v4_fuzzyqe_application_manager.hpp>
//#include <dcs/testbed/albano2013v5_fuzzyqe_application_manager.hpp>
#include <dcs/testbed/anglano2014_fc2q_application_manager.hpp>
#include <dcs/testbed/anglano2014_fc2q_mimo_application_manager.hpp>
#include <dcs/testbed/anglano2014_fc2q_mimo_v2_application_manager.hpp>
#include <dcs/testbed/anglano2014_fc2q_mimo_v3_application_manager.hpp>
#include <dcs/testbed/anglano2014_fc2q_mimo_v4_application_manager.hpp>
#include <dcs/testbed/anglano2016_fcms_application_manager.hpp>
#include <dcs/testbed/base_application_manager.hpp>
#include <dcs/testbed/dummy_application_manager.hpp>
#include <dcs/testbed/guazzone2015_anfis_ssmpc_application_manager.hpp>
#include <dcs/testbed/lama2015_appleware_application_manager.hpp>
#include <dcs/testbed/lq_application_manager.hpp>
#include <dcs/testbed/padala2009_autocontrol_application_manager.hpp>
#include <dcs/testbed/rao2013_dynaqos_application_manager.hpp>
#include <dcs/testbed/sysid_application_manager.hpp>
#include <dcs/testbed/wang2015_fmpc_application_manager.hpp>

#endif // DCS_TESTBED_APPLICATION_MANAGERS_HPP
<commit_msg>Commented unused application managers<commit_after>/**
 * \file dcs/testbed/application_managers.hpp
 *
 * \brief Forward declarations for currently implemented application managers.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 *

 *
 * Copyright 2012 Marco Guazzone (marco.guazzone@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef DCS_TESTBED_APPLICATION_MANAGERS_HPP
#define DCS_TESTBED_APPLICATION_MANAGERS_HPP

#include <dcs/testbed/albano2013_fuzzyqe_application_manager.hpp>
//#include <dcs/testbed/albano2013v2_fuzzyqe_application_manager.hpp>
//#include <dcs/testbed/albano2013v3_fuzzyqe_application_manager.hpp>
//#include <dcs/testbed/albano2013v4_fuzzyqe_application_manager.hpp>
//#include <dcs/testbed/albano2013v5_fuzzyqe_application_manager.hpp>
#include <dcs/testbed/anglano2014_fc2q_application_manager.hpp>
//#include <dcs/testbed/anglano2014_fc2q_mimo_application_manager.hpp>
//#include <dcs/testbed/anglano2014_fc2q_mimo_v2_application_manager.hpp>
//#include <dcs/testbed/anglano2014_fc2q_mimo_v3_application_manager.hpp>
//#include <dcs/testbed/anglano2014_fc2q_mimo_v4_application_manager.hpp>
#include <dcs/testbed/anglano2016_fcms_application_manager.hpp>
#include <dcs/testbed/base_application_manager.hpp>
#include <dcs/testbed/dummy_application_manager.hpp>
//#include <dcs/testbed/guazzone2015_anfis_ssmpc_application_manager.hpp>
#include <dcs/testbed/lama2015_appleware_application_manager.hpp>
#include <dcs/testbed/lq_application_manager.hpp>
#include <dcs/testbed/padala2009_autocontrol_application_manager.hpp>
#include <dcs/testbed/rao2013_dynaqos_application_manager.hpp>
#include <dcs/testbed/sysid_application_manager.hpp>
#include <dcs/testbed/wang2015_fmpc_application_manager.hpp>

#endif // DCS_TESTBED_APPLICATION_MANAGERS_HPP
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <math.h>
#include <boost/tokenizer.hpp>
#include <iostream>
#include <fstream>
#include <votca/csg/csgapplication.h>
#include <votca/csg/trajectorywriter.h>

using namespace std;
using namespace votca::csg;

class CsgMapApp
    : public CsgApplication
{
public:
    string ProgramName() { return "csg_map"; }
    void HelpText(ostream &out) {
      out << "Convert a reference atomistic trajectory or configuration into a coarse-grained one \n"
          << "based on a mapping xml-file. The mapping can be applied to either an entire trajectory \n"
          << "or a selected set of frames only (see options).\n"
	  << "Examples:\n"
	  << "* csg_map --top FA-topol.tpr --trj FA-traj.trr --out CG-traj.xtc --cg cg-map.xml\n"
	  << "* csg_map --top FA-topol.tpr --trj FA-conf.gro --out CG-conf.gro --cg cg-map.xml\n"
	  << "* csg_map --top FA-topol.tpr --trj FA-traj.xtc --out FA-history.dlph --no-map\n"
	  << "* csg_map --top FA-field.dlpf --trj FA-history.dlph --out CG-history.dlph --cg cg-map.xml\n"
	  << "* csg_map --top .dlpf --trj .dlph --out .dlph --cg cg-map.xml  convert HISTORY to HISTORY_CGV\n";
    }

    bool DoTrajectory() { return true;}
    bool DoMapping() { return true;}

    void Initialize() {
        CsgApplication::Initialize();
        AddProgramOptions()
	  ("out", boost::program_options::value<string>(),"  output file for coarse-grained trajectory")
	  ("vel", "  Write mapped velocities (if available)")
	  ("hybrid", "  Create hybrid trajectory containing both atomistic and coarse-grained");
    }

    bool EvaluateOptions() {
        CsgApplication::EvaluateOptions();
        CheckRequired("trj", "no trajectory file specified");
        CheckRequired("out", "need to specify output trajectory");
        return true;
    }

    void BeginEvaluate(Topology *top, Topology *top_ref);
void EvalConfiguration(Topology *top, Topology *top_ref) {
        if (!_do_hybrid) {
            // simply write the topology mapped by csgapplication class
            if (_do_vel) top->SetHasVel(true);
            _writer->Write(top);
        } else {
            // we want to combine atomistic and coarse-grained into one topology
            Topology *hybtol = new Topology();

            BeadContainer::iterator it_bead;
            ResidueContainer::iterator it_res;
            MoleculeContainer::iterator it_mol;
            InteractionContainer::iterator it_ia;

            hybtol->setBox(top->getBox());
            hybtol->setTime(top->getTime());
            hybtol->setStep(top->getStep());

            // copy all residues from both
            for (it_res = top_ref->Residues().begin(); it_res != top_ref->Residues().end(); ++it_res) {
                hybtol->CreateResidue((*it_res)->getName());
            }
            for (it_res = top->Residues().begin(); it_res != top->Residues().end(); ++it_res) {
                hybtol->CreateResidue((*it_res)->getName());
            }

            // copy all molecules and beads

            for(it_mol=top_ref->Molecules().begin();it_mol!=top_ref->Molecules().end(); ++it_mol) {
                Molecule *mi = hybtol->CreateMolecule((*it_mol)->getName());
                for (int i = 0; i < (*it_mol)->BeadCount(); i++) {
                    // copy atomistic beads of molecule
                    int beadid = (*it_mol)->getBead(i)->getId();

                    Bead *bi = (*it_mol)->getBead(i);
                    BeadType *type = hybtol->GetOrCreateBeadType(bi->getType()->getName());
                    Bead *bn = hybtol->CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr(), bi->getM(), bi->getQ());
                    bn->setOptions(bi->Options());
                    bn->setPos(bi->getPos());
                    if (bi->HasVel()) bn->setVel(bi->getVel());

                    mi->AddBead(hybtol->Beads()[beadid], (*it_mol)->getBeadName(i));

                }

                if (mi->getId() < top->MoleculeCount()) {
                    // copy cg beads of molecule
                    Molecule *cgmol = top->Molecules()[mi->getId()];
                    for (int i = 0; i < cgmol->BeadCount(); i++) {
                        Bead *bi = cgmol->getBead(i);
                        // todo: this is a bit dirty as a cg bead will always have the resid of its first parent
                        Bead *bparent = (*it_mol)->getBead(0);
                        BeadType *type = hybtol->GetOrCreateBeadType(bi->getType()->getName());
                        Bead *bn = hybtol->CreateBead(bi->getSymmetry(), bi->getName(), type, bparent->getResnr(), bi->getM(), bi->getQ());
                        bn->setOptions(bi->Options());
                        bn->setPos(bi->getPos());
                        if (bi->HasVel()) bn->setVel(bi->getVel());
                        int mid = bparent->getMolecule()->getId();
                        mi->AddBead(bi, bi->getName());
                    }
                }

            }
           hybtol->setBox(top_ref->getBox());

            _writer->Write(hybtol);
        }
    }

    void EndEvaluate() {
        _writer->Close();
        delete _writer;
    }

protected:
    TrajectoryWriter *_writer;
    bool _do_hybrid;
    bool _do_vel;

};

void CsgMapApp::BeginEvaluate(Topology *top, Topology *top_atom) {
    string out = OptionsMap()["out"].as<string > ();
    cout << "writing coarse-grained trajectory to " << out << endl;
    _writer = TrjWriterFactory().Create(out);
    if (_writer == NULL)
        throw runtime_error("output format not supported: " + out);

    _do_hybrid = false;
    if(OptionsMap().count("hybrid")){
        if (!_do_mapping)
            throw runtime_error("options hybrid and no-map not compatible");
        cout << "Doing hybrid mapping..." << endl;
        _do_hybrid = true;
    }

    _do_vel = false;
    if(OptionsMap().count("vel")){
        _do_vel = true;
    }

    _writer->Open(out);
};

int main(int argc, char **argv)
{
    CsgMapApp app;
    return app.Exec(argc, argv);
}

<commit_msg>csg_map: add --force option to map forces<commit_after>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <math.h>
#include <boost/tokenizer.hpp>
#include <iostream>
#include <fstream>
#include <votca/csg/csgapplication.h>
#include <votca/csg/trajectorywriter.h>

using namespace std;
using namespace votca::csg;

class CsgMapApp
    : public CsgApplication
{
public:
    string ProgramName() { return "csg_map"; }
    void HelpText(ostream &out) {
      out << "Convert a reference atomistic trajectory or configuration into a coarse-grained one \n"
          << "based on a mapping xml-file. The mapping can be applied to either an entire trajectory \n"
          << "or a selected set of frames only (see options).\n"
	  << "Examples:\n"
	  << "* csg_map --top FA-topol.tpr --trj FA-traj.trr --out CG-traj.xtc --cg cg-map.xml\n"
	  << "* csg_map --top FA-topol.tpr --trj FA-conf.gro --out CG-conf.gro --cg cg-map.xml\n"
	  << "* csg_map --top FA-topol.tpr --trj FA-traj.xtc --out FA-history.dlph --no-map\n"
	  << "* csg_map --top FA-field.dlpf --trj FA-history.dlph --out CG-history.dlph --cg cg-map.xml\n"
	  << "* csg_map --top .dlpf --trj .dlph --out .dlph --cg cg-map.xml  convert HISTORY to HISTORY_CGV\n";
    }

    bool DoTrajectory() { return true;}
    bool DoMapping() { return true;}

    void Initialize() {
        CsgApplication::Initialize();
        AddProgramOptions()
	  ("out", boost::program_options::value<string>(),"  output file for coarse-grained trajectory")
	  ("vel", "  Write mapped velocities (if available)")
	  ("force", "  Write mapped forces (if available)")
	  ("hybrid", "  Create hybrid trajectory containing both atomistic and coarse-grained");
    }

    bool EvaluateOptions() {
        CsgApplication::EvaluateOptions();
        CheckRequired("trj", "no trajectory file specified");
        CheckRequired("out", "need to specify output trajectory");
        return true;
    }

    void BeginEvaluate(Topology *top, Topology *top_ref);
void EvalConfiguration(Topology *top, Topology *top_ref) {
        if (!_do_hybrid) {
            // simply write the topology mapped by csgapplication class
            if (_do_vel) top->SetHasVel(true);
            if (_do_force) top->SetHasForce(true);
            _writer->Write(top);
        } else {
            // we want to combine atomistic and coarse-grained into one topology
            Topology *hybtol = new Topology();

            BeadContainer::iterator it_bead;
            ResidueContainer::iterator it_res;
            MoleculeContainer::iterator it_mol;
            InteractionContainer::iterator it_ia;

            hybtol->setBox(top->getBox());
            hybtol->setTime(top->getTime());
            hybtol->setStep(top->getStep());

            // copy all residues from both
            for (it_res = top_ref->Residues().begin(); it_res != top_ref->Residues().end(); ++it_res) {
                hybtol->CreateResidue((*it_res)->getName());
            }
            for (it_res = top->Residues().begin(); it_res != top->Residues().end(); ++it_res) {
                hybtol->CreateResidue((*it_res)->getName());
            }

            // copy all molecules and beads

            for(it_mol=top_ref->Molecules().begin();it_mol!=top_ref->Molecules().end(); ++it_mol) {
                Molecule *mi = hybtol->CreateMolecule((*it_mol)->getName());
                for (int i = 0; i < (*it_mol)->BeadCount(); i++) {
                    // copy atomistic beads of molecule
                    int beadid = (*it_mol)->getBead(i)->getId();

                    Bead *bi = (*it_mol)->getBead(i);
                    BeadType *type = hybtol->GetOrCreateBeadType(bi->getType()->getName());
                    Bead *bn = hybtol->CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr(), bi->getM(), bi->getQ());
                    bn->setOptions(bi->Options());
                    bn->setPos(bi->getPos());
                    if (bi->HasVel()) bn->setVel(bi->getVel());
                    if (bi->HasF()) bn->setF(bi->getF());

                    mi->AddBead(hybtol->Beads()[beadid], (*it_mol)->getBeadName(i));

                }

                if (mi->getId() < top->MoleculeCount()) {
                    // copy cg beads of molecule
                    Molecule *cgmol = top->Molecules()[mi->getId()];
                    for (int i = 0; i < cgmol->BeadCount(); i++) {
                        Bead *bi = cgmol->getBead(i);
                        // todo: this is a bit dirty as a cg bead will always have the resid of its first parent
                        Bead *bparent = (*it_mol)->getBead(0);
                        BeadType *type = hybtol->GetOrCreateBeadType(bi->getType()->getName());
                        Bead *bn = hybtol->CreateBead(bi->getSymmetry(), bi->getName(), type, bparent->getResnr(), bi->getM(), bi->getQ());
                        bn->setOptions(bi->Options());
                        bn->setPos(bi->getPos());
                        if (bi->HasVel()) bn->setVel(bi->getVel());
                        int mid = bparent->getMolecule()->getId();
                        mi->AddBead(bi, bi->getName());
                    }
                }

            }
           hybtol->setBox(top_ref->getBox());

            _writer->Write(hybtol);
        }
    }

    void EndEvaluate() {
        _writer->Close();
        delete _writer;
    }

protected:
    TrajectoryWriter *_writer;
    bool _do_hybrid;
    bool _do_vel;
    bool _do_force;

};

void CsgMapApp::BeginEvaluate(Topology *top, Topology *top_atom) {
    string out = OptionsMap()["out"].as<string > ();
    cout << "writing coarse-grained trajectory to " << out << endl;
    _writer = TrjWriterFactory().Create(out);
    if (_writer == NULL)
        throw runtime_error("output format not supported: " + out);

    _do_hybrid = false;
    if(OptionsMap().count("hybrid")){
        if (!_do_mapping)
            throw runtime_error("options hybrid and no-map not compatible");
        cout << "Doing hybrid mapping..." << endl;
        _do_hybrid = true;
    }

    _do_vel = false;
    if(OptionsMap().count("vel")){
        _do_vel = true;
    }

    _do_force = false;
    if(OptionsMap().count("force")){
        _do_force = true;
    }

    _writer->Open(out);
};

int main(int argc, char **argv)
{
    CsgMapApp app;
    return app.Exec(argc, argv);
}

<|endoftext|>


<commit_before>#include "plugin_base.h"

#include "default_term_ui.h"
#include "term_window.h"
#include "task.h"
#include "term_context.h"

#include "main_dlg.h"

class __wxGLTermApp : public wxApp {
public:
    virtual bool OnInit() {
        return true;
    }
};

class __wxGLTimer : public wxTimer {
public:
    __wxGLTimer(TaskPtr task, int miliseconds):
        m_Task(task)
        , m_Interval(miliseconds)
    {
    }

    virtual ~__wxGLTimer() = default;

public:
    virtual void Notify() {
        if (m_Task && !m_Task->IsCancelled()) {
            m_Task->Run();
        }
    }

private:
    TaskPtr m_Task;
    int m_Interval;
};

wxIMPLEMENT_APP_NO_MAIN(__wxGLTermApp);

class DefaultTermWindow : public virtual PluginBase, public virtual TermWindow {
public:
    DefaultTermWindow() :
        PluginBase("default_term_window", "default terminal window plugin", 0)
        , m_MainDlg(nullptr) {
    }

    virtual ~DefaultTermWindow() = default;

public:
    void Refresh() override {
        if (!m_MainDlg)
            return;
    }

    void Show() override {
        if (!m_MainDlg)
            m_MainDlg = new MainDialog(wxT("wxGLTerm"));

        m_MainDlg->Show(true);
    }

private:
    MainDialog * m_MainDlg;
};

class DefaultTermUI : public virtual PluginBase, public virtual TermUI {
public:
    DefaultTermUI() :
        PluginBase("default_term_ui", "default terminal ui plugin", 0)
    {
    }

    virtual ~DefaultTermUI() = default;

    TermWindowPtr CreateWindow() {
        return TermWindowPtr { new DefaultTermWindow() };
    }

    int32_t StartMainUILoop() {
        int argc = 0;

        return wxEntry(argc, (char **)nullptr);
    }

    bool ScheduleTask(TaskPtr task, int miliseconds, bool repeated) {
        auto timer = new __wxGLTimer(task, miliseconds);
        return timer->Start(miliseconds, !repeated);
    }
};

class __ShowContextWindowTask : public virtual PluginBase, public virtual Task {
public:
    __ShowContextWindowTask() :
        PluginBase("default_main_wnd_task", "default task show main window", 0)
        , m_Cancelled(false)
    {
    }

    virtual ~__ShowContextWindowTask() = default;

public:
    void Run() override {
        if (m_Cancelled)
            return;

        auto mainWnd = std::dynamic_pointer_cast<TermContext>(m_Context)->GetTermWindow();
        mainWnd->Show();
    }

    void Cancel() override {
        m_Cancelled = true;
    }

    bool IsCancelled() override {
        return m_Cancelled;
    }

private:
    bool m_Cancelled;
};

TermUIPtr CreateDefaultTermUI()
{
    if (!wxApp::GetInstance())
        wxCreateApp();
    return TermUIPtr{ new DefaultTermUI()};
}

TaskPtr CreateShowContextWindowTask() {
    return TaskPtr { new __ShowContextWindowTask() };
}
<commit_msg>fix compile warnings<commit_after>#include "plugin_base.h"

#include "default_term_ui.h"
#include "term_window.h"
#include "task.h"
#include "term_context.h"

#include "main_dlg.h"

class __wxGLTermApp : public wxApp {
public:
    virtual bool OnInit() {
        return true;
    }
};

class __wxGLTimer : public wxTimer {
public:
    __wxGLTimer(TaskPtr task, int miliseconds):
        m_Task(task)
        , m_Interval(miliseconds)
    {
        (void)m_Interval;
    }

    virtual ~__wxGLTimer() = default;

public:
    virtual void Notify() {
        if (m_Task && !m_Task->IsCancelled()) {
            m_Task->Run();
        }
    }

private:
    TaskPtr m_Task;
    int m_Interval;
};

wxIMPLEMENT_APP_NO_MAIN(__wxGLTermApp);

class DefaultTermWindow : public virtual PluginBase, public virtual TermWindow {
public:
    DefaultTermWindow() :
        PluginBase("default_term_window", "default terminal window plugin", 0)
        , m_MainDlg(nullptr) {
    }

    virtual ~DefaultTermWindow() = default;

public:
    void Refresh() override {
        if (!m_MainDlg)
            return;
    }

    void Show() override {
        if (!m_MainDlg)
            m_MainDlg = new MainDialog(wxT("wxGLTerm"));

        m_MainDlg->Show(true);
    }

private:
    MainDialog * m_MainDlg;
};

class DefaultTermUI : public virtual PluginBase, public virtual TermUI {
public:
    DefaultTermUI() :
        PluginBase("default_term_ui", "default terminal ui plugin", 0)
    {
    }

    virtual ~DefaultTermUI() = default;

    TermWindowPtr CreateWindow() {
        return TermWindowPtr { new DefaultTermWindow() };
    }

    int32_t StartMainUILoop() {
        int argc = 0;

        return wxEntry(argc, (char **)nullptr);
    }

    bool ScheduleTask(TaskPtr task, int miliseconds, bool repeated) {
        auto timer = new __wxGLTimer(task, miliseconds);
        return timer->Start(miliseconds, !repeated);
    }
};

class __ShowContextWindowTask : public virtual PluginBase, public virtual Task {
public:
    __ShowContextWindowTask() :
        PluginBase("default_main_wnd_task", "default task show main window", 0)
        , m_Cancelled(false)
    {
    }

    virtual ~__ShowContextWindowTask() = default;

public:
    void Run() override {
        if (m_Cancelled)
            return;

        auto mainWnd = std::dynamic_pointer_cast<TermContext>(m_Context)->GetTermWindow();
        mainWnd->Show();
    }

    void Cancel() override {
        m_Cancelled = true;
    }

    bool IsCancelled() override {
        return m_Cancelled;
    }

private:
    bool m_Cancelled;
};

TermUIPtr CreateDefaultTermUI()
{
    if (!wxApp::GetInstance())
        wxCreateApp();
    return TermUIPtr{ new DefaultTermUI()};
}

TaskPtr CreateShowContextWindowTask() {
    return TaskPtr { new __ShowContextWindowTask() };
}
<|endoftext|>


<commit_before>#ifndef ALEPH_BOUNDARY_MATRIX_HH__
#define ALEPH_BOUNDARY_MATRIX_HH__

#include <algorithm>
#include <fstream>
#include <istream>
#include <iterator>
#include <ostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

// FIXME: This is only a temporary workaround. Depending on the index
// type of the representation, conversions between signed and unsigned
// data types may occur here.
_Pragma( "GCC diagnostic push" )
_Pragma( "GCC diagnostic ignored \"-Wsign-conversion\"" )

namespace aleph
{

namespace topology
{

template <class Representation> class BoundaryMatrix
{
public:
  using Index = typename Representation::Index;

  void setNumColumns( Index numColumns )
  {
    _representation.setNumColumns( numColumns );
  }

  Index getNumColumns() const
  {
    return _representation.getNumColumns();
  }

  std::pair<Index, bool> getMaximumIndex( Index column ) const
  {
    return _representation.getMaximumIndex( column );
  };

  void addColumns( Index source, Index target )
  {
    _representation.addColumns( source, target );
  };

  template <class InputIterator> void setColumn( Index column,
                                                 InputIterator begin, InputIterator end )

  {
    _representation.setColumn( column, begin, end );
  }

  std::vector<Index> getColumn( Index column ) const
  {
    return _representation.getColumn( column );
  }

  void clearColumn( Index column )
  {
    _representation.clearColumn( column );
  }

  void setDimension( Index column, Index dimension )
  {
    _representation.setDimension( column, dimension );
  }

  Index getDimension( Index column ) const
  {
    return _representation.getDimension( column );
  }

  Index getDimension() const
  {
    return _representation.getDimension();
  }

  bool isDualized() const
  {
    return _isDualized;
  }

  // Comparison --------------------------------------------------------

  bool operator==( const BoundaryMatrix& other ) const
  {
    return    _representation == other._representation
           && _isDualized     == other._isDualized;
  }

  bool operator!=( const BoundaryMatrix& other ) const
  {
    return !this->operator==( other );
  }

  // Dualization -------------------------------------------------------

  BoundaryMatrix dualize() const
  {
    auto&& numColumns = this->getNumColumns();

    std::vector< std::vector<Index> > dualMatrix( numColumns );
    std::vector<Index> dualDimensions( numColumns );
    std::vector<std::size_t> dualColumnSizes( numColumns );

    // Determine the size of every column in the dualized matrix. This
    // keeps memory re-allocation at a minimum.

    for( Index j = 0; j < numColumns; j++ )
    {
      auto&& column = this->getColumn(j);

      for( auto&& i : column )
        ++dualColumnSizes[ numColumns - 1 - i ];
    }

    for( Index j = 0; j < numColumns; j++ )
      dualMatrix[j].reserve( dualColumnSizes[j] );

    // Calculate the actual anti-transpose of the matrix. Since the
    // vectors have been properly resized, this operation should be
    // relatively well-behaved.

    for( Index j = 0; j < numColumns; j++ )
    {
      auto&& column = this->getColumn( j );

      for( auto&& i : column )
        dualMatrix[ numColumns - 1 - i ].push_back( numColumns - 1 - j );
    }

    auto&& d = this->getDimension();

    for( Index j = 0; j < numColumns; j++ )
      dualDimensions[ numColumns - 1 - j ] = d - this->getDimension( j );

    BoundaryMatrix<Representation> M;
    M.setNumColumns( static_cast<Index>( dualMatrix.size() ) );

    for( Index j = 0; j < M.getNumColumns(); j++ )
    {
      // Do not assume that the column is properly sorted. A normal
      // std::reverse should be sufficient in most cases here but I
      // do not want to take any chances.
      std::sort( dualMatrix.at(j).begin(), dualMatrix.at(j).end() );

      M.setColumn( j,
                   dualMatrix.at(j).begin(), dualMatrix.at(j).end() );

      M.setDimension( j, dualDimensions.at(j) );
    }

    M._isDualized = !this->isDualized();
    return M;
  }

  // I/O operations ----------------------------------------------------

  static BoundaryMatrix load( std::istream& in )
  {
    std::string line;
    Index numColumns = Index(0);

    while( std::getline( in, line ) )
    {
      // Remove all spaces
      line.erase( std::remove_if( line.begin(), line.end(), ::isspace ),
                  line.end() );

      if( line.empty() == false && line.front() != '#' )
        ++numColumns;
    }

    in.clear();
    in.seekg( 0 );

    BoundaryMatrix<Representation> M;
    M.setNumColumns( numColumns );

    Index curColumn = Index(0);

    while( std::getline( in, line ) )
    {
      // Ignore empty lines and comment lines
      if( line.empty() || line.front() == '#' )
        continue;

      std::istringstream iss( line );

      std::vector<std::string> tokens;

      std::copy( std::istream_iterator<std::string>( iss ),
                 std::istream_iterator<std::string>(),
                 std::back_inserter( tokens ) );

      // Ignore this line if it does not contain any tokens
      if( tokens.empty() )
        continue;

      std::vector<Index> indices;
      indices.reserve( tokens.size() );

      std::transform( tokens.begin(), tokens.end(), std::back_inserter( indices ),
                      [] ( const std::string& token )
                      {
                        return static_cast<Index>( std::stoul( token ) );
                      } );

      if( indices.empty() )
        throw std::runtime_error( "Amount of indices in boundary must not be empty" );

      // Enforcing sorted column indices. His is required by any other
      // representation of the matrix class.
      std::sort( indices.begin() + 1, indices.end() );

      M.setColumn( curColumn,
                   indices.begin() + 1, indices.end() );

      if( M.getDimension( curColumn ) != indices.front() )
        throw std::runtime_error( "Inconsistency between actual number of indices and specified number of indices in boundary" );

      ++curColumn;
    }

    return M;
  }

  static BoundaryMatrix load( const std::string& filename )
  {
    std::ifstream in( filename );
    return BoundaryMatrix::load( in );
  }

private:
  Representation _representation;

  /**
    Flag indicating whether the matrix is dualized or not. By default
    no matrix is dualized. This flag is used by some of the reduction
    algorithms to determine how to calculate indices.
  */

  bool _isDualized = false;
};

// ---------------------------------------------------------------------

template <class Representation> std::ostream& operator<< ( std::ostream& o, const BoundaryMatrix<Representation>& M )
{
  using Index = typename Representation::Index;

  auto numColumns = M.getNumColumns();

  for( Index j = Index(0); j < numColumns; ++j )
  {
    auto column = M.getColumn( j );

    if( !column.empty() )
    {
      for( auto&& c : column )
        o << c << " ";
    }
    else
      o << "-";

    o << "\n";
  }

  return o;
}

// ---------------------------------------------------------------------

} // namespace topology

} // namespace aleph

_Pragma( "GCC diagnostic pop" )

#endif
<commit_msg>Extended boundary matrix debug operator<commit_after>#ifndef ALEPH_BOUNDARY_MATRIX_HH__
#define ALEPH_BOUNDARY_MATRIX_HH__

#include <algorithm>
#include <fstream>
#include <istream>
#include <iterator>
#include <ostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

// FIXME: This is only a temporary workaround. Depending on the index
// type of the representation, conversions between signed and unsigned
// data types may occur here.
_Pragma( "GCC diagnostic push" )
_Pragma( "GCC diagnostic ignored \"-Wsign-conversion\"" )

namespace aleph
{

namespace topology
{

template <class Representation> class BoundaryMatrix
{
public:
  using Index = typename Representation::Index;

  void setNumColumns( Index numColumns )
  {
    _representation.setNumColumns( numColumns );
  }

  Index getNumColumns() const
  {
    return _representation.getNumColumns();
  }

  std::pair<Index, bool> getMaximumIndex( Index column ) const
  {
    return _representation.getMaximumIndex( column );
  };

  void addColumns( Index source, Index target )
  {
    _representation.addColumns( source, target );
  };

  template <class InputIterator> void setColumn( Index column,
                                                 InputIterator begin, InputIterator end )

  {
    _representation.setColumn( column, begin, end );
  }

  std::vector<Index> getColumn( Index column ) const
  {
    return _representation.getColumn( column );
  }

  void clearColumn( Index column )
  {
    _representation.clearColumn( column );
  }

  void setDimension( Index column, Index dimension )
  {
    _representation.setDimension( column, dimension );
  }

  Index getDimension( Index column ) const
  {
    return _representation.getDimension( column );
  }

  Index getDimension() const
  {
    return _representation.getDimension();
  }

  bool isDualized() const
  {
    return _isDualized;
  }

  // Comparison --------------------------------------------------------

  bool operator==( const BoundaryMatrix& other ) const
  {
    return    _representation == other._representation
           && _isDualized     == other._isDualized;
  }

  bool operator!=( const BoundaryMatrix& other ) const
  {
    return !this->operator==( other );
  }

  // Dualization -------------------------------------------------------

  BoundaryMatrix dualize() const
  {
    auto&& numColumns = this->getNumColumns();

    std::vector< std::vector<Index> > dualMatrix( numColumns );
    std::vector<Index> dualDimensions( numColumns );
    std::vector<std::size_t> dualColumnSizes( numColumns );

    // Determine the size of every column in the dualized matrix. This
    // keeps memory re-allocation at a minimum.

    for( Index j = 0; j < numColumns; j++ )
    {
      auto&& column = this->getColumn(j);

      for( auto&& i : column )
        ++dualColumnSizes[ numColumns - 1 - i ];
    }

    for( Index j = 0; j < numColumns; j++ )
      dualMatrix[j].reserve( dualColumnSizes[j] );

    // Calculate the actual anti-transpose of the matrix. Since the
    // vectors have been properly resized, this operation should be
    // relatively well-behaved.

    for( Index j = 0; j < numColumns; j++ )
    {
      auto&& column = this->getColumn( j );

      for( auto&& i : column )
        dualMatrix[ numColumns - 1 - i ].push_back( numColumns - 1 - j );
    }

    auto&& d = this->getDimension();

    for( Index j = 0; j < numColumns; j++ )
      dualDimensions[ numColumns - 1 - j ] = d - this->getDimension( j );

    BoundaryMatrix<Representation> M;
    M.setNumColumns( static_cast<Index>( dualMatrix.size() ) );

    for( Index j = 0; j < M.getNumColumns(); j++ )
    {
      // Do not assume that the column is properly sorted. A normal
      // std::reverse should be sufficient in most cases here but I
      // do not want to take any chances.
      std::sort( dualMatrix.at(j).begin(), dualMatrix.at(j).end() );

      M.setColumn( j,
                   dualMatrix.at(j).begin(), dualMatrix.at(j).end() );

      M.setDimension( j, dualDimensions.at(j) );
    }

    M._isDualized = !this->isDualized();
    return M;
  }

  // I/O operations ----------------------------------------------------

  static BoundaryMatrix load( std::istream& in )
  {
    std::string line;
    Index numColumns = Index(0);

    while( std::getline( in, line ) )
    {
      // Remove all spaces
      line.erase( std::remove_if( line.begin(), line.end(), ::isspace ),
                  line.end() );

      if( line.empty() == false && line.front() != '#' )
        ++numColumns;
    }

    in.clear();
    in.seekg( 0 );

    BoundaryMatrix<Representation> M;
    M.setNumColumns( numColumns );

    Index curColumn = Index(0);

    while( std::getline( in, line ) )
    {
      // Ignore empty lines and comment lines
      if( line.empty() || line.front() == '#' )
        continue;

      std::istringstream iss( line );

      std::vector<std::string> tokens;

      std::copy( std::istream_iterator<std::string>( iss ),
                 std::istream_iterator<std::string>(),
                 std::back_inserter( tokens ) );

      // Ignore this line if it does not contain any tokens
      if( tokens.empty() )
        continue;

      std::vector<Index> indices;
      indices.reserve( tokens.size() );

      std::transform( tokens.begin(), tokens.end(), std::back_inserter( indices ),
                      [] ( const std::string& token )
                      {
                        return static_cast<Index>( std::stoul( token ) );
                      } );

      if( indices.empty() )
        throw std::runtime_error( "Amount of indices in boundary must not be empty" );

      // Enforcing sorted column indices. His is required by any other
      // representation of the matrix class.
      std::sort( indices.begin() + 1, indices.end() );

      M.setColumn( curColumn,
                   indices.begin() + 1, indices.end() );

      if( M.getDimension( curColumn ) != indices.front() )
        throw std::runtime_error( "Inconsistency between actual number of indices and specified number of indices in boundary" );

      ++curColumn;
    }

    return M;
  }

  static BoundaryMatrix load( const std::string& filename )
  {
    std::ifstream in( filename );
    return BoundaryMatrix::load( in );
  }

private:
  Representation _representation;

  /**
    Flag indicating whether the matrix is dualized or not. By default
    no matrix is dualized. This flag is used by some of the reduction
    algorithms to determine how to calculate indices.
  */

  bool _isDualized = false;
};

// ---------------------------------------------------------------------

/**
  Permits sending a boundary matrix to an output stream. This is only
  meant as a debugging aid. Usually, there is no need to print any of
  these matrices since they are not visible to the client.

  @param o Output stream
  @param M Matrix
*/

template <class Representation> std::ostream& operator<< ( std::ostream& o, const BoundaryMatrix<Representation>& M )
{
  using Index = typename Representation::Index;

  auto numColumns = M.getNumColumns();

  o << std::string( 72, '-' ) << "\n\n";

  o << "Number of columns: " << numColumns << "\n";

  for( Index j = Index(0); j < numColumns; ++j )
    o << "Dimension [" << j << "]: " << M.getDimension(j) << "\n";

  o << "\n";

  for( Index j = Index(0); j < numColumns; ++j )
  {
    auto column = M.getColumn( j );

    if( !column.empty() )
    {
      for( auto&& c : column )
        o << c << " ";
    }
    else
      o << "-";

    o << "\n";
  }

  o << std::string( 72, '-' ) << "\n\n";
  return o;
}

// ---------------------------------------------------------------------

} // namespace topology

} // namespace aleph

_Pragma( "GCC diagnostic pop" )

#endif
<|endoftext|>


<commit_before>/* Tests
 * Copyright (C) 2006 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
//#define TEST_VERBOSE
#include <rapicorn-core/rapicorntests.h>
#include <rapicorn/rapicorn.hh>
#include <rapicorn/testitems.hh>

/* --- RapicornTester --- */
namespace Rapicorn {
struct RapicornTester {
  static bool
  loops_pending()
  {
    return EventLoop::iterate_loops (false, false);
  }
  static void
  loops_dispatch (bool may_block)
  {
    EventLoop::iterate_loops (may_block, true);
  }
};
} // Rapicorn

/* --- tests --- */
namespace {
using namespace Rapicorn;

static bool test_item_fatal_asserts = true;

static void
assertion_ok (const String &assertion)
{
  TPRINT ("%s\n", assertion.c_str());
}

static void
assertions_passed ()
{
  TOK();
}

static void
test_cxx_gui ()
{
  TSTART ("C++GUI Test");
  Window window = Factory::create_window ("Root");
  TOK();
  Item &titem = Factory::create_item ("TestItem");
  TOK();
  window.root().add (titem);
  TOK();
  /* perform all ops neccessary before showing */
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  uint old_seen_test = TestItem::seen_test_items();
  TOK();
  window.show();
  TOK();
  /* perform all ops neccessary immediately after showing */
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  TOK();
  printerr ("(auto-sleep)");
  sleep (1); // FIXME: work around lack of show_now()
  TOK();
  /* perform all unhandled ops for display (expose etc.) */
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  TOK();
  /* checks and cleanups */
  uint seen_test = TestItem::seen_test_items();
  TASSERT (seen_test > old_seen_test); // may fail due to missing exposes (locked screens) needs PNG etc. backends
  window.close();
  TOK();
  /* perform pending jobs after closing */
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  TOK();
  TDONE();
}

static void
test_test_item ()
{
  TSTART ("alignment-test");
  Window window = Factory::create_window ("alignment-test");
  TOK();
  Root &root = window.root();
  TestItem *titem = root.interface<TestItem*>();
  TASSERT (titem != NULL);
  titem->sig_assertion_ok += slot (assertion_ok);
  titem->sig_assertions_passed += slot (assertions_passed);
  titem->fatal_asserts (test_item_fatal_asserts);
  TOK();
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  uint old_seen_test = TestItem::seen_test_items();
  window.show();
  TOK();
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  TOK();
  printerr ("(auto-sleep)");
  sleep (1); // FIXME: work around lack of show_now()
  TOK();
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  printerr ("(auto-sleep)");
  sleep (1); // FIXME: work around lack of show_now()
  TOK();
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  TOK();
  uint seen_test = TestItem::seen_test_items();
  TASSERT (seen_test > old_seen_test);
  TDONE();
}

extern "C" int
main (int   argc,
      char *argv[])
{
  rapicorn_init_test (&argc, &argv);

  for (int i = 0; i < argc; i++)
    if (String (argv[i]) == "--non-fatal")
      test_item_fatal_asserts = false;

  /* initialize rapicorn */
  Application::init_with_x11 (&argc, &argv, "TestItemTest");

  /* parse GUI description */
  Application::auto_load ("testitems", "testitems.xml", argv[0]);

  /* create/run tests */
  test_cxx_gui ();
  test_test_item ();

  return 0;
}

} // Anon
<commit_msg>rapicorn/tests/testitems.cc: use root.enable_auto_close(), removed workarounds.<commit_after>/* Tests
 * Copyright (C) 2006 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
//#define TEST_VERBOSE
#include <rapicorn-core/rapicorntests.h>
#include <rapicorn/rapicorn.hh>
#include <rapicorn/testitems.hh>

/* --- RapicornTester --- */
namespace Rapicorn {
struct RapicornTester {
  static bool
  loops_pending()
  {
    return EventLoop::iterate_loops (false, false);
  }
  static void
  loops_dispatch (bool may_block)
  {
    EventLoop::iterate_loops (may_block, true);
  }
};
} // Rapicorn

/* --- tests --- */
namespace {
using namespace Rapicorn;

static bool test_item_fatal_asserts = true;

static void
assertion_ok (const String &assertion)
{
  TPRINT ("%s\n", assertion.c_str());
}

static void
assertions_passed ()
{
  TOK();
}

static void
test_cxx_gui ()
{
  TSTART ("C++GUI Test");
  Window window = Factory::create_window ("Root");
  TOK();
  Item &titem = Factory::create_item ("TestItem");
  TOK();
  window.root().add (titem);
  TOK();
  /* close window (and exit main loop) after first expose */
  window.root().enable_auto_close();
  TOK();
  /* verify and assert at least one TestItem rendering */
  uint old_seen_test = TestItem::seen_test_items();
  TOK();
  /* show onscreen and handle events like expose */
  window.show();
  Application::execute_loops();
  TOK();
  /* assert TestItem rendering */
  uint seen_test = TestItem::seen_test_items();
  TASSERT (seen_test > old_seen_test); // may fail due to missing exposes (locked screens) needs PNG etc. backends
  TDONE();
}

static void
test_test_item ()
{
  TSTART ("alignment-test");
  Window window = Factory::create_window ("alignment-test");
  TOK();
  Root &root = window.root();
  TestItem *titem = root.interface<TestItem*>();
  TASSERT (titem != NULL);
  titem->sig_assertion_ok += slot (assertion_ok);
  titem->sig_assertions_passed += slot (assertions_passed);
  titem->fatal_asserts (test_item_fatal_asserts);
  TOK();
  while (RapicornTester::loops_pending())
    RapicornTester::loops_dispatch (false);
  /* close window (and exit main loop) after first expose */
  root.enable_auto_close();
  /* verify and assert at least one TestItem rendering */
  uint old_seen_test = TestItem::seen_test_items();
  window.show();
  Application::execute_loops();
  uint seen_test = TestItem::seen_test_items();
  TASSERT (seen_test > old_seen_test);
  /* test item rendering also executed various assertions */
  TDONE();
  return;
}

extern "C" int
main (int   argc,
      char *argv[])
{
  rapicorn_init_test (&argc, &argv);

  for (int i = 0; i < argc; i++)
    if (String (argv[i]) == "--non-fatal")
      test_item_fatal_asserts = false;

  /* initialize rapicorn */
  Application::init_with_x11 (&argc, &argv, "TestItemTest");

  /* parse GUI description */
  Application::auto_load ("testitems", "testitems.xml", argv[0]);

  /* create/run tests */
  test_cxx_gui ();
  test_test_item ();

  return 0;
}

} // Anon
<|endoftext|>


<commit_before>//
//  basic_iostream.hpp
//  fibio
//
//  Created by Chen Xu on 14-3-8.
//  Copyright (c) 2014 0d0a.com. All rights reserved.
//

#ifndef fibio_basic_iostream_hpp
#define fibio_basic_iostream_hpp

#include <streambuf>
#include <iostream>
#include <chrono>
#include <vector>
#include <fibio/fibers/fiber.hpp>
#include <fibio/io/io.hpp>

namespace fibio { namespace stream {
    enum duplex_mode {
        full_duplex,
        half_duplex,
    };

    template<typename StreamDescriptor>
    class basic_fibio_streambuf : public std::streambuf {
    public:
        basic_fibio_streambuf()
        : sd_(fibio::fibers::this_fiber::detail::get_io_service())
        { init_buffers(); }

        basic_fibio_streambuf(basic_fibio_streambuf &&other)
        : sd_(std::move(other.sd_))
        , get_buffer_(std::move(other.get_buffer_))
        , put_buffer_(std::move(other.put_buffer_))
        , connect_timeout_(other.connect_timeout_)
        , read_timeout_(other.read_timeout_)
        , write_timeout_(other.write_timeout_)
        , unbuffered_(other.unbuffered_)
        , duplex_mode_(other.duplex_mode_)
        {}

        basic_fibio_streambuf(StreamDescriptor &&sd)
        : sd_(std::move(sd))
        { init_buffers(); }

        basic_fibio_streambuf(asio::io_service &iosvc)
        : sd_(iosvc)
        { init_buffers(); }

        /// Destructor flushes buffered data.
        ~basic_fibio_streambuf() {
            if (pptr() != pbase())
                overflow(traits_type::eof());
        }

        template <typename... T>
        std::error_code open(T... x) {
            return fibio::io::open(sd_, x...);
        }

        template <typename... T>
        std::error_code connect(T... x) {
            sd_.close();
            typename StreamDescriptor::protocol_type::resolver::query q(x...);
            typename StreamDescriptor::protocol_type::endpoint ep=fibio::io::resolve(q);
            typedef typename StreamDescriptor::protocol_type::endpoint endpoint_t;
            return fibio::io::connect(sd_, ep, endpoint_t(), connect_timeout_);
        }

        void swap(basic_fibio_streambuf &other) {
            StreamDescriptor temp(sd_.get_io_service());
            temp=std::move(other.sd_);
            other.sd_=std::move(sd_);
            sd_=std::move(temp);
            //std::swap(sd_, other.sd_);
            std::swap(get_buffer_, other.get_buffer_);
            std::swap(put_buffer_, other.put_buffer_);
            std::swap(connect_timeout_, other.connect_timeout_);
            std::swap(read_timeout_, other.read_timeout_);
            std::swap(write_timeout_, other.write_timeout_);
            std::swap(unbuffered_, other.unbuffered_);
        }

        inline bool is_open() const
        { return sd_.is_open(); }

        inline void close() {
            if(sd_.is_open()) {
                std::error_code ec;
                sd_.close(ec);
            }
        }

        typename StreamDescriptor::native_handle_type release()
        { return sd_.release(); }

        inline StreamDescriptor &stream_descriptor()
        { return sd_; }

        template<typename Rep, typename Period>
        void set_connect_timeout(const std::chrono::duration<Rep, Period>& timeout_duration)
        { connect_timeout_=std::chrono::duration_cast<std::chrono::microseconds>(timeout_duration).count(); }

        template<typename Rep, typename Period>
        void set_read_timeout(const std::chrono::duration<Rep, Period>& timeout_duration)
        { read_timeout_=std::chrono::duration_cast<std::chrono::microseconds>(timeout_duration).count(); }

        template<typename Rep, typename Period>
        void set_write_timeout(const std::chrono::duration<Rep, Period>& timeout_duration)
        { write_timeout_=std::chrono::duration_cast<std::chrono::microseconds>(timeout_duration).count(); }

        void set_duplex_mode(duplex_mode dm) {
            duplex_mode_=dm;
        }

        duplex_mode get_duplex_mode() const {
            return duplex_mode_;
        }

    protected:
        pos_type seekoff(off_type off,
                         std::ios_base::seekdir dir,
                         std::ios_base::openmode which) override
        {
            // Only seeking in input buffer from current pos is allowed
            if (which!=std::ios_base::in || dir!=std::ios_base::cur) return pos_type(off_type(-1));
            char_type* newg=gptr()+off;
            // Cannot seek back into put back area
            if (newg <eback()+putback_max) return false;
            // Cannot seek beyond end of get area
            if (newg >=egptr()) return false;
            setg(eback(), newg, egptr());
            return pos_type(off_type(0));
        }

        virtual std::streamsize showmanyc() override {
            if ( gptr() == egptr() ) {
                underflow();
            }
            return egptr()-gptr();
        }

        int_type underflow() override {
            if (duplex_mode_==half_duplex) sync();
            if (gptr() == egptr()) {
                std::error_code ec;
                size_t bytes_transferred=io::read_some(sd_,
                                                        &get_buffer_[0]+ putback_max,
                                                        buffer_size-putback_max,
                                                        read_timeout_,
                                                        ec);
                if (ec || bytes_transferred==0) {
                    return traits_type::eof();
                }
                setg(&get_buffer_[0],
                     &get_buffer_[0] + putback_max,
                     &get_buffer_[0] + putback_max + bytes_transferred);
                return traits_type::to_int_type(*gptr());
            } else {
                return traits_type::eof();
            }
        }

        int_type overflow(int_type c) override {
            std::error_code ec;
            if (unbuffered_) {
                if (traits_type::eq_int_type(c, traits_type::eof())) {
                    // Nothing to do.
                    return traits_type::not_eof(c);
                } else {
                    char c_=c;
                    fibio::io::write_some(sd_, &c_, 1, write_timeout_, ec);
                    if (ec)
                        return traits_type::eof();
                    return c;
                }
            } else {
                char *ptr=pbase();
                size_t size=pptr() - pbase();
                while (size > 0)
                {
                    size_t bytes_transferred=fibio::io::write_some(sd_,
                                                                   ptr,
                                                                   size,
                                                                   write_timeout_,
                                                                   ec);
                    ptr+=bytes_transferred;
                    size-=bytes_transferred;
                    if (ec)
                        return traits_type::eof();
                }
                setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());

                // If the new character is eof then our work here is done.
                if (traits_type::eq_int_type(c, traits_type::eof()))
                    return traits_type::not_eof(c);

                // Add the new character to the output buffer.
                *pptr() = traits_type::to_char_type(c);
                pbump(1);
                return c;
            }
        }

        int sync() override
        {
            return overflow(traits_type::eof());
        }

        std::streambuf* setbuf(char_type* s, std::streamsize n) override
        {
            if (pptr() == pbase() && s == 0 && n == 0)
            {
                unbuffered_ = true;
                setp(0, 0);
                return this;
            }

            return 0;
        }

    private:
        void init_buffers() {
            get_buffer_.resize(buffer_size+putback_max);
            put_buffer_.resize(buffer_size);
            setg(&get_buffer_[0],
                 &get_buffer_[0] + putback_max,
                 &get_buffer_[0] + putback_max);
            if (unbuffered_)
                setp(0, 0);
            else
                setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
        }

        enum { putback_max = 8 };
        // A practical MTU size
        enum { buffer_size = 1500 };

        StreamDescriptor sd_;
        std::vector<char> get_buffer_;
        std::vector<char> put_buffer_;
        int connect_timeout_=0;
        int read_timeout_=0;
        int write_timeout_=0;
        bool unbuffered_=false;
        duplex_mode duplex_mode_=half_duplex;
    };
}}  // End of namespace fibio::stream

namespace std {
    template<typename StreamDescriptor>
    void swap(fibio::stream::basic_fibio_streambuf<StreamDescriptor> &lhs, fibio::stream::basic_fibio_streambuf<StreamDescriptor> &rhs) {
        lhs.swap(rhs);
    }
}

#endif
<commit_msg>forget to swap duplex_mode_<commit_after>//
//  basic_iostream.hpp
//  fibio
//
//  Created by Chen Xu on 14-3-8.
//  Copyright (c) 2014 0d0a.com. All rights reserved.
//

#ifndef fibio_basic_iostream_hpp
#define fibio_basic_iostream_hpp

#include <streambuf>
#include <iostream>
#include <chrono>
#include <vector>
#include <fibio/fibers/fiber.hpp>
#include <fibio/io/io.hpp>

namespace fibio { namespace stream {
    enum duplex_mode {
        full_duplex,
        half_duplex,
    };

    template<typename StreamDescriptor>
    class basic_fibio_streambuf : public std::streambuf {
    public:
        basic_fibio_streambuf()
        : sd_(fibio::fibers::this_fiber::detail::get_io_service())
        { init_buffers(); }

        basic_fibio_streambuf(basic_fibio_streambuf &&other)
        : sd_(std::move(other.sd_))
        , get_buffer_(std::move(other.get_buffer_))
        , put_buffer_(std::move(other.put_buffer_))
        , connect_timeout_(other.connect_timeout_)
        , read_timeout_(other.read_timeout_)
        , write_timeout_(other.write_timeout_)
        , unbuffered_(other.unbuffered_)
        , duplex_mode_(other.duplex_mode_)
        {}

        basic_fibio_streambuf(StreamDescriptor &&sd)
        : sd_(std::move(sd))
        { init_buffers(); }

        basic_fibio_streambuf(asio::io_service &iosvc)
        : sd_(iosvc)
        { init_buffers(); }

        /// Destructor flushes buffered data.
        ~basic_fibio_streambuf() {
            if (pptr() != pbase())
                overflow(traits_type::eof());
        }

        template <typename... T>
        std::error_code open(T... x) {
            return fibio::io::open(sd_, x...);
        }

        template <typename... T>
        std::error_code connect(T... x) {
            sd_.close();
            typename StreamDescriptor::protocol_type::resolver::query q(x...);
            typename StreamDescriptor::protocol_type::endpoint ep=fibio::io::resolve(q);
            typedef typename StreamDescriptor::protocol_type::endpoint endpoint_t;
            return fibio::io::connect(sd_, ep, endpoint_t(), connect_timeout_);
        }

        void swap(basic_fibio_streambuf &other) {
            StreamDescriptor temp(sd_.get_io_service());
            temp=std::move(other.sd_);
            other.sd_=std::move(sd_);
            sd_=std::move(temp);
            //std::swap(sd_, other.sd_);
            std::swap(get_buffer_, other.get_buffer_);
            std::swap(put_buffer_, other.put_buffer_);
            std::swap(connect_timeout_, other.connect_timeout_);
            std::swap(read_timeout_, other.read_timeout_);
            std::swap(write_timeout_, other.write_timeout_);
            std::swap(unbuffered_, other.unbuffered_);
            std::swap(duplex_mode_, other.duplex_mode_);
        }

        inline bool is_open() const
        { return sd_.is_open(); }

        inline void close() {
            if(sd_.is_open()) {
                std::error_code ec;
                sd_.close(ec);
            }
        }

        typename StreamDescriptor::native_handle_type release()
        { return sd_.release(); }

        inline StreamDescriptor &stream_descriptor()
        { return sd_; }

        template<typename Rep, typename Period>
        void set_connect_timeout(const std::chrono::duration<Rep, Period>& timeout_duration)
        { connect_timeout_=std::chrono::duration_cast<std::chrono::microseconds>(timeout_duration).count(); }

        template<typename Rep, typename Period>
        void set_read_timeout(const std::chrono::duration<Rep, Period>& timeout_duration)
        { read_timeout_=std::chrono::duration_cast<std::chrono::microseconds>(timeout_duration).count(); }

        template<typename Rep, typename Period>
        void set_write_timeout(const std::chrono::duration<Rep, Period>& timeout_duration)
        { write_timeout_=std::chrono::duration_cast<std::chrono::microseconds>(timeout_duration).count(); }

        void set_duplex_mode(duplex_mode dm) {
            duplex_mode_=dm;
        }

        duplex_mode get_duplex_mode() const {
            return duplex_mode_;
        }

    protected:
        pos_type seekoff(off_type off,
                         std::ios_base::seekdir dir,
                         std::ios_base::openmode which) override
        {
            // Only seeking in input buffer from current pos is allowed
            if (which!=std::ios_base::in || dir!=std::ios_base::cur) return pos_type(off_type(-1));
            char_type* newg=gptr()+off;
            // Cannot seek back into put back area
            if (newg <eback()+putback_max) return false;
            // Cannot seek beyond end of get area
            if (newg >=egptr()) return false;
            setg(eback(), newg, egptr());
            return pos_type(off_type(0));
        }

        virtual std::streamsize showmanyc() override {
            if ( gptr() == egptr() ) {
                underflow();
            }
            return egptr()-gptr();
        }

        int_type underflow() override {
            if (duplex_mode_==half_duplex) sync();
            if (gptr() == egptr()) {
                std::error_code ec;
                size_t bytes_transferred=io::read_some(sd_,
                                                        &get_buffer_[0]+ putback_max,
                                                        buffer_size-putback_max,
                                                        read_timeout_,
                                                        ec);
                if (ec || bytes_transferred==0) {
                    return traits_type::eof();
                }
                setg(&get_buffer_[0],
                     &get_buffer_[0] + putback_max,
                     &get_buffer_[0] + putback_max + bytes_transferred);
                return traits_type::to_int_type(*gptr());
            } else {
                return traits_type::eof();
            }
        }

        int_type overflow(int_type c) override {
            std::error_code ec;
            if (unbuffered_) {
                if (traits_type::eq_int_type(c, traits_type::eof())) {
                    // Nothing to do.
                    return traits_type::not_eof(c);
                } else {
                    char c_=c;
                    fibio::io::write_some(sd_, &c_, 1, write_timeout_, ec);
                    if (ec)
                        return traits_type::eof();
                    return c;
                }
            } else {
                char *ptr=pbase();
                size_t size=pptr() - pbase();
                while (size > 0)
                {
                    size_t bytes_transferred=fibio::io::write_some(sd_,
                                                                   ptr,
                                                                   size,
                                                                   write_timeout_,
                                                                   ec);
                    ptr+=bytes_transferred;
                    size-=bytes_transferred;
                    if (ec)
                        return traits_type::eof();
                }
                setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());

                // If the new character is eof then our work here is done.
                if (traits_type::eq_int_type(c, traits_type::eof()))
                    return traits_type::not_eof(c);

                // Add the new character to the output buffer.
                *pptr() = traits_type::to_char_type(c);
                pbump(1);
                return c;
            }
        }

        int sync() override
        {
            return overflow(traits_type::eof());
        }

        std::streambuf* setbuf(char_type* s, std::streamsize n) override
        {
            if (pptr() == pbase() && s == 0 && n == 0)
            {
                unbuffered_ = true;
                setp(0, 0);
                return this;
            }

            return 0;
        }

    private:
        void init_buffers() {
            get_buffer_.resize(buffer_size+putback_max);
            put_buffer_.resize(buffer_size);
            setg(&get_buffer_[0],
                 &get_buffer_[0] + putback_max,
                 &get_buffer_[0] + putback_max);
            if (unbuffered_)
                setp(0, 0);
            else
                setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
        }

        enum { putback_max = 8 };
        // A practical MTU size
        enum { buffer_size = 1500 };

        StreamDescriptor sd_;
        std::vector<char> get_buffer_;
        std::vector<char> put_buffer_;
        int connect_timeout_=0;
        int read_timeout_=0;
        int write_timeout_=0;
        bool unbuffered_=false;
        duplex_mode duplex_mode_=half_duplex;
    };
}}  // End of namespace fibio::stream

namespace std {
    template<typename StreamDescriptor>
    void swap(fibio::stream::basic_fibio_streambuf<StreamDescriptor> &lhs, fibio::stream::basic_fibio_streambuf<StreamDescriptor> &rhs) {
        lhs.swap(rhs);
    }
}

#endif
<|endoftext|>