<commit_before>#include "FAP.h"

#include "Util.h"

namespace Neolib {

	FastAPproximation::FastAPproximation() {

	}

	void FastAPproximation::addUnitPlayer1(FAPUnit fu) {
		player1.push_back(fu);
	}

	void FastAPproximation::addIfCombatUnitPlayer1(FAPUnit fu) {
		if (fu.groundDamage || fu.airDamage || fu.unitType == BWAPI::UnitTypes::Terran_Medic)
			addUnitPlayer1(fu);
	}

	void FastAPproximation::addUnitPlayer2(FAPUnit fu) {
		player2.push_back(fu);
	}

	void FastAPproximation::addIfCombatUnitPlayer2(FAPUnit fu) {
		if (fu.groundDamage || fu.airDamage || fu.unitType == BWAPI::UnitTypes::Terran_Medic)
			addUnitPlayer2(fu);
	}

	void FastAPproximation::simulate(int nFrames) {
		while (nFrames--) {
			if (!player1.size() || !player2.size())
				break;

			didSomething = false;

			isimulate();

			if (!didSomething)
				break;
		}
	}

	std::pair <int, int> FastAPproximation::getStatus() const {
		std::pair <int, int> res;

		for (auto & u : player1)
			if (u.health && u.maxHealth)
				res.first += (u.score * u.health) / u.maxHealth;

		for (auto & u : player2)
			if (u.health && u.maxHealth)
				res.second -= (u.score * u.health) / u.maxHealth;

		return res;
	}

	std::pair<std::vector<FastAPproximation::FAPUnit>*, std::vector<FastAPproximation::FAPUnit>*> FastAPproximation::getState() {
		return { &player1, &player2 };
	}

	void FastAPproximation::clearState() {
		player1.clear(), player2.clear();
	}

	void FastAPproximation::dealDamage(const FastAPproximation::FAPUnit &fu, int damage, BWAPI::DamageType damageType) const {
		if (fu.shields >= damage - fu.shieldArmor) {
			fu.shields -= damage - fu.shieldArmor;
			return;
		}
		else if(fu.shields) {
			damage -= (fu.shields + fu.shieldArmor);
			fu.shields = 0;
		}

		if (!damage)
			return;

#ifdef SSCAIT

		if (damageType == BWAPI::DamageTypes::Concussive) {
			if(fu.unitSize == BWAPI::UnitSizeTypes::Large)
				damage = damage / 2;
			else if(fu.unitSize == BWAPI::UnitSizeTypes::Medium)
				damage = (damage * 3) / 4;
		}
		else if (damageType == BWAPI::DamageTypes::Explosive) {
			if (fu.unitSize == BWAPI::UnitSizeTypes::Small)
				damage = damage / 2;
			else if (fu.unitSize == BWAPI::UnitSizeTypes::Medium)
				damage = (damage * 3) / 4;
		}

#else

		switch (damageType) {
			case BWAPI::DamageTypes::Concussive:
				switch (fu.unitSize) {
					case BWAPI::UnitSizeTypes::Large:
						damage = damage / 2;
						break;
					case BWAPI::UnitSizeTypes::Medium:
						damage = (damage * 3) / 4;
						break;
				}
				break;

			case BWAPI::DamageTypes::Explosive:
				switch (fu.unitSize) {
					case BWAPI::UnitSizeTypes::Small:
						damage = damage / 2;
						break;
					case BWAPI::UnitSizeTypes::Medium:
						damage = (damage * 3) / 4;
						break;
				}
				break;
		}

#endif

		fu.health -= MAX(1, damage - fu.armor);
	}

	int FastAPproximation::dist(const FastAPproximation::FAPUnit &u1, const FastAPproximation::FAPUnit &u2) const {
		return (int)sqrt((u1.x - u2.x)*(u1.x - u2.x) + (u1.y - u2.y)*(u1.y - u2.y));
	}

	void FastAPproximation::unitsim(const FastAPproximation::FAPUnit &fu, std::vector <FastAPproximation::FAPUnit> &enemyUnits) {
		if (fu.attackCooldownRemaining) {
			didSomething = true;
			return;
		}

		auto closestEnemy = enemyUnits.end();
		int closestDist;

		for (auto enemyIt = enemyUnits.begin(); enemyIt != enemyUnits.end(); ++ enemyIt) {
			if (enemyIt->flying) {
				if (fu.airDamage) {
					int d = dist(fu, *enemyIt);
					if ((closestEnemy == enemyUnits.end() || d < closestDist) && d >= fu.airMinRange) {
						closestDist = d;
						closestEnemy = enemyIt;
					}
				}
			}
			else {
				if (fu.groundDamage) {
					int d = dist(fu, *enemyIt);
					if ((closestEnemy == enemyUnits.end() || d < closestDist) && d >= fu.groundMinRange) {
						closestDist = d;
						closestEnemy = enemyIt;
					}
				}
			}
		}

		if (closestEnemy != enemyUnits.end() && closestDist <= fu.speed && !(fu.x == closestEnemy->x && fu.y == closestEnemy->y)) {
			fu.x = closestEnemy->x;
			fu.y = closestEnemy->y;
			closestDist = 0;

			didSomething = true;
		}

		if (closestEnemy != enemyUnits.end() && closestDist <= (closestEnemy->flying ? fu.groundMaxRange : fu.airMinRange)) {
			if (closestEnemy->flying)
				dealDamage(*closestEnemy, fu.airDamage, fu.airDamageType), fu.attackCooldownRemaining = fu.airCooldown;
			else
				dealDamage(*closestEnemy, fu.groundDamage, fu.groundDamageType), fu.attackCooldownRemaining = fu.groundCooldown;

			if (closestEnemy->health < 1) {
				*closestEnemy = enemyUnits.back();
				enemyUnits.pop_back();
			}

			didSomething = true;
			return;
		}
		else if(closestEnemy != enemyUnits.end() && closestDist > fu.speed) {
			int dx = closestEnemy->x - fu.x, dy = closestEnemy->y - fu.y;

			fu.x += (int)(dx*(fu.speed / sqrt(dx*dx + dy*dy)));
			fu.y += (int)(dy*(fu.speed / sqrt(dx*dx + dy*dy)));

			didSomething = true;
			return;
		}
	}

	void FastAPproximation::isimulate() {
		for (auto &fu : player1)
			unitsim(fu, player2);

		for (auto &fu : player2)
			unitsim(fu, player1);

		for (auto &fu : player1)
			if (fu.attackCooldownRemaining)
				--fu.attackCooldownRemaining;

		for (auto &fu : player2)
			if (fu.attackCooldownRemaining)
				--fu.attackCooldownRemaining;
	}

	FastAPproximation::FAPUnit::FAPUnit(BWAPI::Unit u): FAPUnit(EnemyData(u)) {

	}

	FastAPproximation::FAPUnit::FAPUnit(EnemyData ed) :
		x(ed.lastPosition.x),
		y(ed.lastPosition.y),

		speed(ed.lastPlayer->topSpeed(ed.lastType)),

		health(ed.expectedHealth()),
		maxHealth(ed.lastType.maxHitPoints()),

		shields(ed.expectedShields()),
		shieldArmor(ed.lastPlayer->getUpgradeLevel(BWAPI::UpgradeTypes::Protoss_Plasma_Shields)),
		maxShields(ed.lastType.maxShields()),
		armor(ed.lastPlayer->armor(ed.lastType)),
		flying(ed.lastType.isFlyer()),

		groundDamage(ed.lastPlayer->damage(ed.lastType.groundWeapon())),
		groundCooldown(ed.lastType.groundWeapon().damageFactor() && ed.lastType.maxGroundHits() ? ed.lastPlayer->weaponDamageCooldown(ed.lastType) / (ed.lastType.groundWeapon().damageFactor() * ed.lastType.maxGroundHits()) : 0),
		//groundInnerRadius(ed.lastType.groundWeapon().innerSplashRadius()),
		//groundOuterRadius(ed.lastType.groundWeapon().outerSplashRadius()),
		groundMaxRange(ed.lastPlayer->weaponMaxRange(ed.lastType.groundWeapon())),
		groundMinRange(ed.lastType.groundWeapon().minRange()),
		groundDamageType(ed.lastType.groundWeapon().damageType()),

		airDamage(ed.lastPlayer->damage(ed.lastType.airWeapon())),
		airCooldown(ed.lastType.airWeapon().damageFactor() && ed.lastType.maxAirHits() ? ed.lastType.airWeapon().damageCooldown() / (ed.lastType.airWeapon().damageFactor() * ed.lastType.maxAirHits()) : 0),
		//airInnerRadius(ed.lastType.airWeapon().innerSplashRadius()),
		//airOuterRadius(ed.lastType.airWeapon().outerSplashRadius()),
		airMaxRange(ed.lastPlayer->weaponMaxRange(ed.lastType.airWeapon())),
		airMinRange(ed.lastType.airWeapon().minRange()),
		airDamageType(ed.lastType.airWeapon().damageType()),

		unitType(ed.lastType),
		score(ed.lastType.destroyScore()) {

		static int nextId = 0;
		id = nextId++;

#ifdef SSCAIT

		if (ed.lastType == BWAPI::UnitTypes::Protoss_Carrier) {
			groundDamage = ed.lastPlayer->damage(BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon());
			groundDamageType = BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon().damageType();
			groundCooldown = 5;
			groundMaxRange = 32 * 8;

			airDamage = groundDamage;
			airDamageType = groundDamageType;
			airCooldown = groundCooldown;
			airMaxRange = groundMaxRange;
		}
		else if (ed.lastType == BWAPI::UnitTypes::Terran_Bunker) {
			groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Gauss_Rifle);
			groundCooldown = BWAPI::UnitTypes::Terran_Marine.groundWeapon().damageCooldown() / 4;
			groundMaxRange = ed.lastPlayer->weaponMaxRange(BWAPI::UnitTypes::Terran_Marine.groundWeapon()) + 32;

			airDamage = groundDamage;
			airCooldown = groundCooldown;
			airMaxRange = groundMaxRange;
		}
		else if (ed.lastType == BWAPI::UnitTypes::Protoss_Reaver) {
			groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Scarab);
		}

#else

		switch (ed.lastType) {
			case BWAPI::UnitTypes::Protoss_Carrier:
				groundDamage = ed.lastPlayer->damage(BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon());
				groundDamageType = BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon().damageType();
				groundCooldown = 5;
				groundMaxRange = 32 * 8;

				airDamage = groundDamage;
				airDamageType = groundDamageType;
				airCooldown = groundCooldown;
				airMaxRange = groundMaxRange;
				break;

			case BWAPI::UnitTypes::Terran_Bunker:
				groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Gauss_Rifle);
				groundCooldown = BWAPI::UnitTypes::Terran_Marine.groundWeapon().damageCooldown() / 4;
				groundMaxRange = ed.lastPlayer->weaponMaxRange(BWAPI::UnitTypes::Terran_Marine.groundWeapon()) + 32;

				airDamage = groundDamage;
				airCooldown = groundCooldown;
				airMaxRange = groundMaxRange;
				break;

			case BWAPI::UnitTypes::Protoss_Reaver:
				groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Scarab);
				break;

			default:
				break;
		}

#endif

		groundDamage *= 2;
		airDamage *= 2;

		shieldArmor *= 2;
		armor *= 2;

		health *= 2;
		shields *= 2;
	}

	FastAPproximation::FAPUnit &FastAPproximation::FAPUnit::operator=(const FAPUnit & other) {
		x = other.x, y = other.y;
		health = other.health, maxHealth = other.maxHealth;
		shields = other.shields, maxShields = other.maxShields;
		speed = other.speed, armor = other.armor, flying = other.flying, unitSize = other.unitSize;
		groundDamage = other.groundDamage, groundCooldown = other.groundCooldown, groundMaxRange = other.groundMaxRange, groundMinRange = other.groundMinRange, groundDamageType = other.groundDamageType;
		airDamage = other.airDamage, airCooldown = other.airCooldown, airMaxRange = other.airMaxRange, airMinRange = other.airMinRange, airDamageType = other.airDamageType;
		score = other.score;
		attackCooldownRemaining = other.attackCooldownRemaining;
		unitType = other.unitType;

		return *this;
	}

	bool FastAPproximation::FAPUnit::operator<(const FAPUnit & other) const {
		return id < other.id;
	}

}
<commit_msg>Bugfix: forgot to multiply old max values by 2<commit_after>#include "FAP.h"

#include "Util.h"

namespace Neolib {

	FastAPproximation::FastAPproximation() {

	}

	void FastAPproximation::addUnitPlayer1(FAPUnit fu) {
		player1.push_back(fu);
	}

	void FastAPproximation::addIfCombatUnitPlayer1(FAPUnit fu) {
		if (fu.groundDamage || fu.airDamage || fu.unitType == BWAPI::UnitTypes::Terran_Medic)
			addUnitPlayer1(fu);
	}

	void FastAPproximation::addUnitPlayer2(FAPUnit fu) {
		player2.push_back(fu);
	}

	void FastAPproximation::addIfCombatUnitPlayer2(FAPUnit fu) {
		if (fu.groundDamage || fu.airDamage || fu.unitType == BWAPI::UnitTypes::Terran_Medic)
			addUnitPlayer2(fu);
	}

	void FastAPproximation::simulate(int nFrames) {
		while (nFrames--) {
			if (!player1.size() || !player2.size())
				break;

			didSomething = false;

			isimulate();

			if (!didSomething)
				break;
		}
	}

	std::pair <int, int> FastAPproximation::getStatus() const {
		std::pair <int, int> res;

		for (auto & u : player1)
			if (u.health && u.maxHealth)
				res.first += (u.score * u.health) / u.maxHealth;

		for (auto & u : player2)
			if (u.health && u.maxHealth)
				res.second -= (u.score * u.health) / u.maxHealth;

		return res;
	}

	std::pair<std::vector<FastAPproximation::FAPUnit>*, std::vector<FastAPproximation::FAPUnit>*> FastAPproximation::getState() {
		return { &player1, &player2 };
	}

	void FastAPproximation::clearState() {
		player1.clear(), player2.clear();
	}

	void FastAPproximation::dealDamage(const FastAPproximation::FAPUnit &fu, int damage, BWAPI::DamageType damageType) const {
		if (fu.shields >= damage - fu.shieldArmor) {
			fu.shields -= damage - fu.shieldArmor;
			return;
		}
		else if(fu.shields) {
			damage -= (fu.shields + fu.shieldArmor);
			fu.shields = 0;
		}

		if (!damage)
			return;

#ifdef SSCAIT

		if (damageType == BWAPI::DamageTypes::Concussive) {
			if(fu.unitSize == BWAPI::UnitSizeTypes::Large)
				damage = damage / 2;
			else if(fu.unitSize == BWAPI::UnitSizeTypes::Medium)
				damage = (damage * 3) / 4;
		}
		else if (damageType == BWAPI::DamageTypes::Explosive) {
			if (fu.unitSize == BWAPI::UnitSizeTypes::Small)
				damage = damage / 2;
			else if (fu.unitSize == BWAPI::UnitSizeTypes::Medium)
				damage = (damage * 3) / 4;
		}

#else

		switch (damageType) {
			case BWAPI::DamageTypes::Concussive:
				switch (fu.unitSize) {
					case BWAPI::UnitSizeTypes::Large:
						damage = damage / 2;
						break;
					case BWAPI::UnitSizeTypes::Medium:
						damage = (damage * 3) / 4;
						break;
				}
				break;

			case BWAPI::DamageTypes::Explosive:
				switch (fu.unitSize) {
					case BWAPI::UnitSizeTypes::Small:
						damage = damage / 2;
						break;
					case BWAPI::UnitSizeTypes::Medium:
						damage = (damage * 3) / 4;
						break;
				}
				break;
		}

#endif

		fu.health -= MAX(1, damage - fu.armor);
	}

	int FastAPproximation::dist(const FastAPproximation::FAPUnit &u1, const FastAPproximation::FAPUnit &u2) const {
		return (int)sqrt((u1.x - u2.x)*(u1.x - u2.x) + (u1.y - u2.y)*(u1.y - u2.y));
	}

	void FastAPproximation::unitsim(const FastAPproximation::FAPUnit &fu, std::vector <FastAPproximation::FAPUnit> &enemyUnits) {
		if (fu.attackCooldownRemaining) {
			didSomething = true;
			return;
		}

		auto closestEnemy = enemyUnits.end();
		int closestDist;

		for (auto enemyIt = enemyUnits.begin(); enemyIt != enemyUnits.end(); ++ enemyIt) {
			if (enemyIt->flying) {
				if (fu.airDamage) {
					int d = dist(fu, *enemyIt);
					if ((closestEnemy == enemyUnits.end() || d < closestDist) && d >= fu.airMinRange) {
						closestDist = d;
						closestEnemy = enemyIt;
					}
				}
			}
			else {
				if (fu.groundDamage) {
					int d = dist(fu, *enemyIt);
					if ((closestEnemy == enemyUnits.end() || d < closestDist) && d >= fu.groundMinRange) {
						closestDist = d;
						closestEnemy = enemyIt;
					}
				}
			}
		}

		if (closestEnemy != enemyUnits.end() && closestDist <= fu.speed && !(fu.x == closestEnemy->x && fu.y == closestEnemy->y)) {
			fu.x = closestEnemy->x;
			fu.y = closestEnemy->y;
			closestDist = 0;

			didSomething = true;
		}

		if (closestEnemy != enemyUnits.end() && closestDist <= (closestEnemy->flying ? fu.groundMaxRange : fu.airMinRange)) {
			if (closestEnemy->flying)
				dealDamage(*closestEnemy, fu.airDamage, fu.airDamageType), fu.attackCooldownRemaining = fu.airCooldown;
			else
				dealDamage(*closestEnemy, fu.groundDamage, fu.groundDamageType), fu.attackCooldownRemaining = fu.groundCooldown;

			if (closestEnemy->health < 1) {
				*closestEnemy = enemyUnits.back();
				enemyUnits.pop_back();
			}

			didSomething = true;
			return;
		}
		else if(closestEnemy != enemyUnits.end() && closestDist > fu.speed) {
			int dx = closestEnemy->x - fu.x, dy = closestEnemy->y - fu.y;

			fu.x += (int)(dx*(fu.speed / sqrt(dx*dx + dy*dy)));
			fu.y += (int)(dy*(fu.speed / sqrt(dx*dx + dy*dy)));

			didSomething = true;
			return;
		}
	}

	void FastAPproximation::isimulate() {
		for (auto &fu : player1)
			unitsim(fu, player2);

		for (auto &fu : player2)
			unitsim(fu, player1);

		for (auto &fu : player1)
			if (fu.attackCooldownRemaining)
				--fu.attackCooldownRemaining;

		for (auto &fu : player2)
			if (fu.attackCooldownRemaining)
				--fu.attackCooldownRemaining;
	}

	FastAPproximation::FAPUnit::FAPUnit(BWAPI::Unit u): FAPUnit(EnemyData(u)) {

	}

	FastAPproximation::FAPUnit::FAPUnit(EnemyData ed) :
		x(ed.lastPosition.x),
		y(ed.lastPosition.y),

		speed(ed.lastPlayer->topSpeed(ed.lastType)),

		health(ed.expectedHealth()),
		maxHealth(ed.lastType.maxHitPoints()),

		shields(ed.expectedShields()),
		shieldArmor(ed.lastPlayer->getUpgradeLevel(BWAPI::UpgradeTypes::Protoss_Plasma_Shields)),
		maxShields(ed.lastType.maxShields()),
		armor(ed.lastPlayer->armor(ed.lastType)),
		flying(ed.lastType.isFlyer()),

		groundDamage(ed.lastPlayer->damage(ed.lastType.groundWeapon())),
		groundCooldown(ed.lastType.groundWeapon().damageFactor() && ed.lastType.maxGroundHits() ? ed.lastPlayer->weaponDamageCooldown(ed.lastType) / (ed.lastType.groundWeapon().damageFactor() * ed.lastType.maxGroundHits()) : 0),
		//groundInnerRadius(ed.lastType.groundWeapon().innerSplashRadius()),
		//groundOuterRadius(ed.lastType.groundWeapon().outerSplashRadius()),
		groundMaxRange(ed.lastPlayer->weaponMaxRange(ed.lastType.groundWeapon())),
		groundMinRange(ed.lastType.groundWeapon().minRange()),
		groundDamageType(ed.lastType.groundWeapon().damageType()),

		airDamage(ed.lastPlayer->damage(ed.lastType.airWeapon())),
		airCooldown(ed.lastType.airWeapon().damageFactor() && ed.lastType.maxAirHits() ? ed.lastType.airWeapon().damageCooldown() / (ed.lastType.airWeapon().damageFactor() * ed.lastType.maxAirHits()) : 0),
		//airInnerRadius(ed.lastType.airWeapon().innerSplashRadius()),
		//airOuterRadius(ed.lastType.airWeapon().outerSplashRadius()),
		airMaxRange(ed.lastPlayer->weaponMaxRange(ed.lastType.airWeapon())),
		airMinRange(ed.lastType.airWeapon().minRange()),
		airDamageType(ed.lastType.airWeapon().damageType()),

		unitType(ed.lastType),
		score(ed.lastType.destroyScore()) {

		static int nextId = 0;
		id = nextId++;

#ifdef SSCAIT

		if (ed.lastType == BWAPI::UnitTypes::Protoss_Carrier) {
			groundDamage = ed.lastPlayer->damage(BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon());
			groundDamageType = BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon().damageType();
			groundCooldown = 5;
			groundMaxRange = 32 * 8;

			airDamage = groundDamage;
			airDamageType = groundDamageType;
			airCooldown = groundCooldown;
			airMaxRange = groundMaxRange;
		}
		else if (ed.lastType == BWAPI::UnitTypes::Terran_Bunker) {
			groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Gauss_Rifle);
			groundCooldown = BWAPI::UnitTypes::Terran_Marine.groundWeapon().damageCooldown() / 4;
			groundMaxRange = ed.lastPlayer->weaponMaxRange(BWAPI::UnitTypes::Terran_Marine.groundWeapon()) + 32;

			airDamage = groundDamage;
			airCooldown = groundCooldown;
			airMaxRange = groundMaxRange;
		}
		else if (ed.lastType == BWAPI::UnitTypes::Protoss_Reaver) {
			groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Scarab);
		}

#else

		switch (ed.lastType) {
			case BWAPI::UnitTypes::Protoss_Carrier:
				groundDamage = ed.lastPlayer->damage(BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon());
				groundDamageType = BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon().damageType();
				groundCooldown = 5;
				groundMaxRange = 32 * 8;

				airDamage = groundDamage;
				airDamageType = groundDamageType;
				airCooldown = groundCooldown;
				airMaxRange = groundMaxRange;
				break;

			case BWAPI::UnitTypes::Terran_Bunker:
				groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Gauss_Rifle);
				groundCooldown = BWAPI::UnitTypes::Terran_Marine.groundWeapon().damageCooldown() / 4;
				groundMaxRange = ed.lastPlayer->weaponMaxRange(BWAPI::UnitTypes::Terran_Marine.groundWeapon()) + 32;

				airDamage = groundDamage;
				airCooldown = groundCooldown;
				airMaxRange = groundMaxRange;
				break;

			case BWAPI::UnitTypes::Protoss_Reaver:
				groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Scarab);
				break;

			default:
				break;
		}

#endif

		groundDamage *= 2;
		airDamage *= 2;

		shieldArmor *= 2;
		armor *= 2;

		health *= 2;
		maxHealth *= 2;
		shields *= 2;
		maxShields *= 2;
	}

	FastAPproximation::FAPUnit &FastAPproximation::FAPUnit::operator=(const FAPUnit & other) {
		x = other.x, y = other.y;
		health = other.health, maxHealth = other.maxHealth;
		shields = other.shields, maxShields = other.maxShields;
		speed = other.speed, armor = other.armor, flying = other.flying, unitSize = other.unitSize;
		groundDamage = other.groundDamage, groundCooldown = other.groundCooldown, groundMaxRange = other.groundMaxRange, groundMinRange = other.groundMinRange, groundDamageType = other.groundDamageType;
		airDamage = other.airDamage, airCooldown = other.airCooldown, airMaxRange = other.airMaxRange, airMinRange = other.airMinRange, airDamageType = other.airDamageType;
		score = other.score;
		attackCooldownRemaining = other.attackCooldownRemaining;
		unitType = other.unitType;

		return *this;
	}

	bool FastAPproximation::FAPUnit::operator<(const FAPUnit & other) const {
		return id < other.id;
	}

}
<|endoftext|>


<commit_before>#include <nan.h>
#include "functions.h"

NAN_METHOD(nothing) {
  NanScope();
  NanReturnUndefined();
}

NAN_METHOD(aString) {
	NanScope();
	NanReturnValue(NanNew<v8::String>("This is a thing."));
}

NAN_METHOD(aBoolean) {
	NanScope();
	NanReturnValue(NanFalse());
}

NAN_METHOD(aNumber) {
	NanScope();
	NanReturnValue(NanNew<v8::Number>(1.75));
}

NAN_METHOD(anObject) {
	NanScope();
	v8::Local<v8::Object> obj = NanNew<v8::Object>();
	obj->Set(NanNew<v8::String>("key"), NanNew<v8::String>("value"));
	NanReturnValue(obj);
}

NAN_METHOD(anArray) {
	NanScope();
	v8::Local<v8::Array> arr = NanNew<v8::Array>(3);
	arr->Set(0, NanNew<v8::Number>(1));
	arr->Set(1, NanNew<v8::Number>(2));
	arr->Set(2, NanNew<v8::Number>(3));
	NanReturnValue(arr);
}

NAN_METHOD(callback) {
 	NanScope();

 	v8::Local<v8::Function> callbackHandle = args[0].As<v8::Function>();
	NanCallback *callback = new NanCallback(callbackHandle);

	callback->Call(0, NULL);

	delete callback;

  NanReturnUndefined();
}<commit_msg>Fix indentation<commit_after>#include <nan.h>
#include "functions.h"

NAN_METHOD(nothing) {
    NanScope();
    NanReturnUndefined();
}

NAN_METHOD(aString) {
    NanScope();
    NanReturnValue(NanNew<v8::String>("This is a thing."));
}

NAN_METHOD(aBoolean) {
    NanScope();
    NanReturnValue(NanFalse());
}

NAN_METHOD(aNumber) {
    NanScope();
    NanReturnValue(NanNew<v8::Number>(1.75));
}

NAN_METHOD(anObject) {
    NanScope();
    v8::Local<v8::Object> obj = NanNew<v8::Object>();
    obj->Set(NanNew<v8::String>("key"), NanNew<v8::String>("value"));
    NanReturnValue(obj);
}

NAN_METHOD(anArray) {
    NanScope();
    v8::Local<v8::Array> arr = NanNew<v8::Array>(3);
    arr->Set(0, NanNew<v8::Number>(1));
    arr->Set(1, NanNew<v8::Number>(2));
    arr->Set(2, NanNew<v8::Number>(3));
    NanReturnValue(arr);
}

NAN_METHOD(callback) {
    NanScope();

    v8::Local<v8::Function> callbackHandle = args[0].As<v8::Function>();
    NanCallback *callback = new NanCallback(callbackHandle);

    callback->Call(0, NULL);

    delete callback;

  NanReturnUndefined();
}
<|endoftext|>


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

#include "GafferBindings/ExecutableNodeBinding.h"

#include "GafferImage/ImageWriter.h"

#include "GafferImageBindings/ImageWriterBinding.h"

using namespace GafferImage;

void GafferImageBindings::bindImageWriter()
{

	GafferBindings::ExecutableNodeClass<ImageWriter>()
		.def( "getCurrentFileFormat", &ImageWriter::getCurrentFileFormat )
	;

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

#include "Gaffer/Context.h"

#include "GafferBindings/ExecutableNodeBinding.h"

#include "GafferImage/ImageWriter.h"

#include "GafferImageBindings/ImageWriterBinding.h"

using namespace GafferImage;

void GafferImageBindings::bindImageWriter()
{

	GafferBindings::ExecutableNodeClass<ImageWriter>()
		.def( "currentFileFormat", &ImageWriter::currentFileFormat )
	;

}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2015 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/*
 *  ConvertNrrdToMatrix.cc: Converts Nrrd(s) to a SCIRun Matrix.  It may convert
 *                   it to a ColumnMatrix, DenseMatrix, or SparseMatrix
 *                   depending on which ports are connected.
 *
 *  Written by:
 *   Darby Van Uitert
 *   April 2004
 *
 */

#include <Modules/Legacy/Teem/Converters/ConvertNrrdToMatrix.h>
#include <Core/Datatypes/Legacy/Nrrd/NrrdData.h>
#include <Core/Algorithms/Base/AlgorithmVariableNames.h>
//#include <Core/Datatypes/Legacy/Base/PropertyManager.h>
#include <Core/Datatypes/DenseColumnMatrix.h>
#include <Core/Datatypes/SparseRowMatrix.h>
#include <Core/Datatypes/DenseMatrix.h>

using namespace SCIRun;
using namespace SCIRun::Modules::Teem;
using namespace SCIRun::Dataflow::Networks;
using namespace Core::Algorithms::Teem;
using namespace Core::Datatypes;

ALGORITHM_PARAMETER_DEF(Teem, MatrixType);
ALGORITHM_PARAMETER_DEF(Teem, SparseColumns);

const ModuleLookupInfo ConvertNrrdToMatrix::staticInfo_("ConvertNrrdToMatrix", "Converters", "Teem");

ConvertNrrdToMatrix::ConvertNrrdToMatrix() : Module(staticInfo_)
{
  INITIALIZE_PORT(Data);
  INITIALIZE_PORT(Rows);
  INITIALIZE_PORT(Columns);
  INITIALIZE_PORT(OutputMatrix);
}

void ConvertNrrdToMatrix::setStateDefaults()
{
  //TODO
}

void
ConvertNrrdToMatrix::execute()
{
  auto data = getOptionalInput(Data);
  auto rows = getOptionalInput(Rows);
  auto cols = getOptionalInput(Columns);

  if (needToExecute())
  {
    auto state = get_state();
    int colsForSparse = state->getValue(Parameters::SparseColumns).toInt();
    auto matrix = create_matrix_from_nrrds(data, rows, cols, colsForSparse);
    sendOutput(OutputMatrix, matrix);
  }
}

MatrixHandle
ConvertNrrdToMatrix::create_matrix_from_nrrds(boost::optional<NrrdDataHandle> dataHOpt,
boost::optional<NrrdDataHandle> rowsHOpt,
boost::optional<NrrdDataHandle> colsHOpt, int cols)
{
  // Determine if we have data, rows, columns to indicate whether it is
  // a dense or sparse matrix
  bool has_data = false, has_rows = false, has_cols = false;
  bool has_error = false;

  if (dataHOpt && *dataHOpt)
    has_data = true;
  if (rowsHOpt && *rowsHOpt)
    has_rows = true;
  if (colsHOpt && *colsHOpt)
    has_cols = true;

  MatrixHandle matrix;
  if (has_data && (!has_rows || !has_cols))
  {
    auto dataH = *dataHOpt;
    if (dataH->getNrrd()->dim == 1)
    {
      // column matrix
      switch(dataH->getNrrd()->type)
      {
      case nrrdTypeChar:
	      matrix = create_column_matrix<char>(dataH);
	      break;
      case nrrdTypeUChar:
	      matrix = create_column_matrix<unsigned char>(dataH);
	      break;
      case nrrdTypeShort:
	      matrix = create_column_matrix<short>(dataH);
	break;
      case nrrdTypeUShort:
	matrix = create_column_matrix<unsigned short>(dataH);
	break;
      case nrrdTypeInt:
	matrix = create_column_matrix<int>(dataH);
	break;
      case nrrdTypeUInt:
	matrix = create_column_matrix<unsigned int>(dataH);
	break;
      case nrrdTypeFloat:
	matrix = create_column_matrix<float>(dataH);
	break;
      case nrrdTypeDouble:
	matrix = create_column_matrix<double>(dataH);
	break;
      default:
	      error("Unknown nrrd type.");
	      has_error = true;
	      return nullptr;
      }
    } else if (dataH->getNrrd()->dim == 2) {
      // dense matrix
      switch(dataH->getNrrd()->type) {
      case nrrdTypeChar:
	matrix = create_dense_matrix<char>(dataH);
	break;
      case nrrdTypeUChar:
	matrix = create_dense_matrix<unsigned char>(dataH);
	break;
      case nrrdTypeShort:
	matrix = create_dense_matrix<short>(dataH);
	break;
      case nrrdTypeUShort:
	matrix = create_dense_matrix<unsigned short>(dataH);
	break;
      case nrrdTypeInt:
	matrix = create_dense_matrix<int>(dataH);
	break;
      case nrrdTypeUInt:
	matrix = create_dense_matrix<unsigned int>(dataH);
	break;
      case nrrdTypeFloat:
	matrix = create_dense_matrix<float>(dataH);
	break;
      case nrrdTypeDouble:
	matrix = create_dense_matrix<double>(dataH);
	break;
      default:
	error("Unknown nrrd type.");
	has_error = true;
	return nullptr;
      }
    } else {
      error("Can only convert data nrrds of 1 or 2D (Column or Dense Matrix).");
      has_error = true;
      return nullptr;
    }
  } else if (has_data && has_rows && has_cols) {
    // sparse matrix
    auto dataH = *dataHOpt;
    auto rowsH = *rowsHOpt;
    auto colsH = *colsHOpt;
    // rows and cols should be of type nrrdTypeInt
    if (rowsH->getNrrd()->type != nrrdTypeInt || colsH->getNrrd()->type != nrrdTypeInt) {
      error("Rows and Columns nrrds must both be of type nrrdTypeInt");
      has_error = true;
      return nullptr;
    }

    if (dataH->getNrrd()->dim != 1 || rowsH->getNrrd()->dim != 1 || colsH->getNrrd()->dim != 1) {
      error("All nrrds must be 1 dimension for a SparseRowMatrix.");
      has_error = true;
      return nullptr;
    }
    switch(dataH->getNrrd()->type) {
    case nrrdTypeChar:
      matrix = create_sparse_matrix<char>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeUChar:
      matrix = create_sparse_matrix<unsigned char>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeShort:
      matrix = create_sparse_matrix<short>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeUShort:
      matrix = create_sparse_matrix<unsigned short>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeInt:
      matrix = create_sparse_matrix<int>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeUInt:
      matrix = create_sparse_matrix<unsigned int>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeFloat:
      matrix = create_sparse_matrix<float>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeDouble:
      matrix = create_sparse_matrix<double>(dataH, rowsH, colsH, cols);
      break;
    default:
      error("Unknown nrrd type.");
      has_error = true;
      return nullptr;
    }
  } else {
    error("Must have data to convert to any type of Matrix.  Must have rows and columns for a SparseRowMatrix.");
    has_error = true;
    return nullptr;
  }

  return matrix;
}

template<class PTYPE>
MatrixHandle
ConvertNrrdToMatrix::create_column_matrix(NrrdDataHandle dataH)
{
  remark("Creating column matrix");
  unsigned int rows = dataH->getNrrd()->axis[0].size;

  DenseColumnMatrixHandle matrix(new DenseColumnMatrix(rows));

  PTYPE *val = (PTYPE*)dataH->getNrrd()->data;
  double *data = matrix->data();

  std::copy(val, val + dataH->getNrrd()->axis[0].size, data);

  return matrix;
}

template<class PTYPE>
MatrixHandle
ConvertNrrdToMatrix::create_dense_matrix(NrrdDataHandle dataH)
{
  remark("Creating dense matrix");
  unsigned int rows = dataH->getNrrd()->axis[1].size;
  unsigned int cols = dataH->getNrrd()->axis[0].size;

  DenseMatrixHandle matrix(new DenseMatrix(rows,cols));

  PTYPE *val = (PTYPE*)dataH->getNrrd()->data;
  double *data = matrix->data();

  for(unsigned int r=0; r<rows; r++) {
    for(unsigned int c=0; c<cols; c++) {
      *data = *val;
      ++data;
      ++val;
    }
  }
  return matrix;
}

template<class PTYPE>
MatrixHandle
ConvertNrrdToMatrix::create_sparse_matrix(NrrdDataHandle dataH, NrrdDataHandle rowsH,
				   NrrdDataHandle colsH, int cols)
{
  error("Nrrd to Sparse matrix not supported yet.");
  return nullptr;
  #ifdef SCIRUN4_CODE_TO_BE_CONVERTED_LATER
  // TO DO: NEED TO FIX SCIRUN INDEX_TYPE TO NRRDTYPE CASTING AND CONVERTING
  remark("Creating sparse row matrix");
  Nrrd *data_n = dataH->getNrrd();
  Nrrd *rows_n = rowsH->getNrrd();
  Nrrd *cols_n = colsH->getNrrd();

  // pointers to nnrds
  PTYPE *data_d = (PTYPE*)data_n->data;
  index_type *rows_d = (index_type*)rows_n->data;
  index_type *cols_d = (index_type*)cols_n->data;

  if (cols == -1) {
    // Auto selected...attempt to determine number of columns
    for (index_type i=0; i<static_cast<size_type>(cols_n->axis[0].size); i++)
    {
      if (cols_d[i] > cols) cols = cols_d[i];
    }
    cols += 1;
  }

  size_type rows = static_cast<size_type>(rows_n->axis[0].size-1);
  size_type offset = 0;
  if (rows_d[0] != 0)
  {
    warning("First entry of rows nrrd must be a 0. Inserting 0 in first position.");
    offset = 1;
    rows++;
  }

  size_type nnz = static_cast<size_type>(data_n->axis[0].size);

  // error checking...

  // cols_n and dn should be of size nnz
  if (static_cast<size_type>(cols_n->axis[0].size) != nnz)
  {
    error("The Data and Columns nrrds should be the same size.");
    has_error_ = true;
    return 0;
  }

  // rows values must be in increasing order
  for (size_type i=0; i<static_cast<size_type>(rows_n->axis[0].size-1); i++)
  {
    if (rows_d[i] > rows_d[i+1] || rows_d[i] < 0) {
      error("Rows nrrd must contain values in increasing order and positive.");
      has_error_ = true;
      return 0;
    }
  }

  // last rows value should be less than nnz
  if (rows_d[rows_n->axis[0].size-1] > nnz) {
    error("The last entry in the rows array must be less than the number of non zeros.");
    has_error_ = true;
    return 0;
  }

  for (size_type i=0; i<nnz; i++)
  {
    if (cols_d[i] < 0)
    {
      error("Columns nrrd must have positive values");
      has_error_ = true;
      return 0;
    }
  }

  // for each rows[N+1] - rows[N] sections of the cols array,
  // those values must be in increasing order
  for (index_type i=0; i<static_cast<size_type>(rows_n->axis[0].size-1); i++)
  {
    size_type span = rows_d[i+1] - rows_d[i];
    for(index_type j=i; j<(i+span-1); j++)
    {
      if (cols_d[j] > cols_d[j+1])
      {
        error("Columns nrrd ordered incorrectly.");
        has_error_ = true;
        return 0;
      }
    }
  }

  SparseRowMatrix::Data sparseData(rows_n->axis[0].size+offset, nnz);
  const SparseRowMatrix::Rows& rr = sparseData.rows();
  const SparseRowMatrix::Columns& cc = sparseData.columns();
  const SparseRowMatrix::Storage& d = sparseData.data();

  // copy rest of rows
  if (offset == 1)
  {
    rr[0] = 0;
  }
  for (index_type i=0; i<static_cast<size_type>(rows_n->axis[0].size); i++)
  {
    rr[i+offset] = rows_d[i];
  }

  // copy data and cols
  for(index_type i=0; i<nnz; i++)
  {
    cc[i] = cols_d[i];
    d[i] = data_d[i];
  }

  return new SparseRowMatrix(rows, cols, sparseData, nnz);
  #endif
}
<commit_msg>Reformat<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2015 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
   */

/*
 *  ConvertNrrdToMatrix.cc: Converts Nrrd(s) to a SCIRun Matrix.  It may convert
 *                   it to a ColumnMatrix, DenseMatrix, or SparseMatrix
 *                   depending on which ports are connected.
 *
 *  Written by:
 *   Darby Van Uitert
 *   April 2004
 *
 */

#include <Modules/Legacy/Teem/Converters/ConvertNrrdToMatrix.h>
#include <Core/Datatypes/Legacy/Nrrd/NrrdData.h>
#include <Core/Algorithms/Base/AlgorithmVariableNames.h>
#include <Core/Datatypes/DenseColumnMatrix.h>
#include <Core/Datatypes/SparseRowMatrix.h>
#include <Core/Datatypes/DenseMatrix.h>

using namespace SCIRun;
using namespace SCIRun::Modules::Teem;
using namespace SCIRun::Dataflow::Networks;
using namespace Core::Algorithms::Teem;
using namespace Core::Datatypes;

ALGORITHM_PARAMETER_DEF(Teem, MatrixType);
ALGORITHM_PARAMETER_DEF(Teem, SparseColumns);

const ModuleLookupInfo ConvertNrrdToMatrix::staticInfo_("ConvertNrrdToMatrix", "Converters", "Teem");

ConvertNrrdToMatrix::ConvertNrrdToMatrix() : Module(staticInfo_)
{
  INITIALIZE_PORT(Data);
  INITIALIZE_PORT(Rows);
  INITIALIZE_PORT(Columns);
  INITIALIZE_PORT(OutputMatrix);
}

void ConvertNrrdToMatrix::setStateDefaults()
{
  //TODO
}

void
ConvertNrrdToMatrix::execute()
{
  auto data = getOptionalInput(Data);
  auto rows = getOptionalInput(Rows);
  auto cols = getOptionalInput(Columns);

  if (needToExecute())
  {
    auto state = get_state();
    int colsForSparse = state->getValue(Parameters::SparseColumns).toInt();
    auto matrix = create_matrix_from_nrrds(data, rows, cols, colsForSparse);
    sendOutput(OutputMatrix, matrix);
  }
}

MatrixHandle
ConvertNrrdToMatrix::create_matrix_from_nrrds(boost::optional<NrrdDataHandle> dataHOpt,
boost::optional<NrrdDataHandle> rowsHOpt,
boost::optional<NrrdDataHandle> colsHOpt, int cols)
{
  // Determine if we have data, rows, columns to indicate whether it is
  // a dense or sparse matrix
  bool has_data = false, has_rows = false, has_cols = false;
  bool has_error = false;

  if (dataHOpt && *dataHOpt)
    has_data = true;
  if (rowsHOpt && *rowsHOpt)
    has_rows = true;
  if (colsHOpt && *colsHOpt)
    has_cols = true;

  MatrixHandle matrix;
  if (has_data && (!has_rows || !has_cols))
  {
    auto dataH = *dataHOpt;
    if (dataH->getNrrd()->dim == 1)
    {
      // column matrix
      switch (dataH->getNrrd()->type)
      {
      case nrrdTypeChar:
        matrix = create_column_matrix<char>(dataH);
        break;
      case nrrdTypeUChar:
        matrix = create_column_matrix<unsigned char>(dataH);
        break;
      case nrrdTypeShort:
        matrix = create_column_matrix<short>(dataH);
        break;
      case nrrdTypeUShort:
        matrix = create_column_matrix<unsigned short>(dataH);
        break;
      case nrrdTypeInt:
        matrix = create_column_matrix<int>(dataH);
        break;
      case nrrdTypeUInt:
        matrix = create_column_matrix<unsigned int>(dataH);
        break;
      case nrrdTypeFloat:
        matrix = create_column_matrix<float>(dataH);
        break;
      case nrrdTypeDouble:
        matrix = create_column_matrix<double>(dataH);
        break;
      default:
        error("Unknown nrrd type.");
        has_error = true;
        return nullptr;
      }
    }
    else if (dataH->getNrrd()->dim == 2) {
      // dense matrix
      switch (dataH->getNrrd()->type) {
      case nrrdTypeChar:
        matrix = create_dense_matrix<char>(dataH);
        break;
      case nrrdTypeUChar:
        matrix = create_dense_matrix<unsigned char>(dataH);
        break;
      case nrrdTypeShort:
        matrix = create_dense_matrix<short>(dataH);
        break;
      case nrrdTypeUShort:
        matrix = create_dense_matrix<unsigned short>(dataH);
        break;
      case nrrdTypeInt:
        matrix = create_dense_matrix<int>(dataH);
        break;
      case nrrdTypeUInt:
        matrix = create_dense_matrix<unsigned int>(dataH);
        break;
      case nrrdTypeFloat:
        matrix = create_dense_matrix<float>(dataH);
        break;
      case nrrdTypeDouble:
        matrix = create_dense_matrix<double>(dataH);
        break;
      default:
        error("Unknown nrrd type.");
        has_error = true;
        return nullptr;
      }
    }
    else {
      error("Can only convert data nrrds of 1 or 2D (Column or Dense Matrix).");
      has_error = true;
      return nullptr;
    }
  }
  else if (has_data && has_rows && has_cols) {
    // sparse matrix
    auto dataH = *dataHOpt;
    auto rowsH = *rowsHOpt;
    auto colsH = *colsHOpt;
    // rows and cols should be of type nrrdTypeInt
    if (rowsH->getNrrd()->type != nrrdTypeInt || colsH->getNrrd()->type != nrrdTypeInt) {
      error("Rows and Columns nrrds must both be of type nrrdTypeInt");
      has_error = true;
      return nullptr;
    }

    if (dataH->getNrrd()->dim != 1 || rowsH->getNrrd()->dim != 1 || colsH->getNrrd()->dim != 1) {
      error("All nrrds must be 1 dimension for a SparseRowMatrix.");
      has_error = true;
      return nullptr;
    }
    switch (dataH->getNrrd()->type) {
    case nrrdTypeChar:
      matrix = create_sparse_matrix<char>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeUChar:
      matrix = create_sparse_matrix<unsigned char>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeShort:
      matrix = create_sparse_matrix<short>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeUShort:
      matrix = create_sparse_matrix<unsigned short>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeInt:
      matrix = create_sparse_matrix<int>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeUInt:
      matrix = create_sparse_matrix<unsigned int>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeFloat:
      matrix = create_sparse_matrix<float>(dataH, rowsH, colsH, cols);
      break;
    case nrrdTypeDouble:
      matrix = create_sparse_matrix<double>(dataH, rowsH, colsH, cols);
      break;
    default:
      error("Unknown nrrd type.");
      has_error = true;
      return nullptr;
    }
  }
  else {
    error("Must have data to convert to any type of Matrix.  Must have rows and columns for a SparseRowMatrix.");
    has_error = true;
    return nullptr;
  }

  return matrix;
}

template<class PTYPE>
MatrixHandle
ConvertNrrdToMatrix::create_column_matrix(NrrdDataHandle dataH)
{
  remark("Creating column matrix");
  unsigned int rows = dataH->getNrrd()->axis[0].size;

  DenseColumnMatrixHandle matrix(new DenseColumnMatrix(rows));

  PTYPE *val = (PTYPE*)dataH->getNrrd()->data;
  double *data = matrix->data();

  std::copy(val, val + dataH->getNrrd()->axis[0].size, data);

  return matrix;
}

template<class PTYPE>
MatrixHandle
ConvertNrrdToMatrix::create_dense_matrix(NrrdDataHandle dataH)
{
  remark("Creating dense matrix");
  unsigned int rows = dataH->getNrrd()->axis[1].size;
  unsigned int cols = dataH->getNrrd()->axis[0].size;

  DenseMatrixHandle matrix(new DenseMatrix(rows, cols));

  PTYPE *val = (PTYPE*)dataH->getNrrd()->data;
  double *data = matrix->data();

  for (unsigned int r = 0; r < rows; r++) {
    for (unsigned int c = 0; c < cols; c++) {
      *data = *val;
      ++data;
      ++val;
    }
  }
  return matrix;
}

template<class PTYPE>
MatrixHandle
ConvertNrrdToMatrix::create_sparse_matrix(NrrdDataHandle dataH, NrrdDataHandle rowsH,
NrrdDataHandle colsH, int cols)
{
  error("Nrrd to Sparse matrix not supported yet.");
  return nullptr;
#ifdef SCIRUN4_CODE_TO_BE_CONVERTED_LATER
  // TO DO: NEED TO FIX SCIRUN INDEX_TYPE TO NRRDTYPE CASTING AND CONVERTING
  remark("Creating sparse row matrix");
  Nrrd *data_n = dataH->getNrrd();
  Nrrd *rows_n = rowsH->getNrrd();
  Nrrd *cols_n = colsH->getNrrd();

  // pointers to nnrds
  PTYPE *data_d = (PTYPE*)data_n->data;
  index_type *rows_d = (index_type*)rows_n->data;
  index_type *cols_d = (index_type*)cols_n->data;

  if (cols == -1) {
    // Auto selected...attempt to determine number of columns
    for (index_type i = 0; i < static_cast<size_type>(cols_n->axis[0].size); i++)
    {
      if (cols_d[i] > cols) cols = cols_d[i];
    }
    cols += 1;
  }

  size_type rows = static_cast<size_type>(rows_n->axis[0].size - 1);
  size_type offset = 0;
  if (rows_d[0] != 0)
  {
    warning("First entry of rows nrrd must be a 0. Inserting 0 in first position.");
    offset = 1;
    rows++;
  }

  size_type nnz = static_cast<size_type>(data_n->axis[0].size);

  // error checking...

  // cols_n and dn should be of size nnz
  if (static_cast<size_type>(cols_n->axis[0].size) != nnz)
  {
    error("The Data and Columns nrrds should be the same size.");
    has_error_ = true;
    return 0;
  }

  // rows values must be in increasing order
  for (size_type i = 0; i < static_cast<size_type>(rows_n->axis[0].size - 1); i++)
  {
    if (rows_d[i] > rows_d[i + 1] || rows_d[i] < 0) {
      error("Rows nrrd must contain values in increasing order and positive.");
      has_error_ = true;
      return 0;
    }
  }

  // last rows value should be less than nnz
  if (rows_d[rows_n->axis[0].size - 1] > nnz) {
    error("The last entry in the rows array must be less than the number of non zeros.");
    has_error_ = true;
    return 0;
  }

  for (size_type i = 0; i < nnz; i++)
  {
    if (cols_d[i] < 0)
    {
      error("Columns nrrd must have positive values");
      has_error_ = true;
      return 0;
    }
  }

  // for each rows[N+1] - rows[N] sections of the cols array,
  // those values must be in increasing order
  for (index_type i = 0; i < static_cast<size_type>(rows_n->axis[0].size - 1); i++)
  {
    size_type span = rows_d[i + 1] - rows_d[i];
    for (index_type j = i; j < (i + span - 1); j++)
    {
      if (cols_d[j] > cols_d[j + 1])
      {
        error("Columns nrrd ordered incorrectly.");
        has_error_ = true;
        return 0;
      }
    }
  }

  SparseRowMatrix::Data sparseData(rows_n->axis[0].size + offset, nnz);
  const SparseRowMatrix::Rows& rr = sparseData.rows();
  const SparseRowMatrix::Columns& cc = sparseData.columns();
  const SparseRowMatrix::Storage& d = sparseData.data();

  // copy rest of rows
  if (offset == 1)
  {
    rr[0] = 0;
  }
  for (index_type i = 0; i < static_cast<size_type>(rows_n->axis[0].size); i++)
  {
    rr[i + offset] = rows_d[i];
  }

  // copy data and cols
  for (index_type i = 0; i < nnz; i++)
  {
    cc[i] = cols_d[i];
    d[i] = data_d[i];
  }

  return new SparseRowMatrix(rows, cols, sparseData, nnz);
#endif
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * $ Id: $
 *
 */

// Base include file.  Must be first.
#include "XSLTResultTarget.hpp"

#include <cassert>

#if defined(XALAN_CLASSIC_IOSTREAMS)
#include <iostream.h>
#else
#include <ostream>
#endif

XALAN_CPP_NAMESPACE_BEGIN

XSLTResultTarget::XSLTResultTarget() :
	m_fileName(),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(const XalanDOMString&	fileName) :
	m_fileName(fileName),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(const XalanDOMChar*	fileName) :
	m_fileName(fileName),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(const char*	fileName) :
	m_fileName(fileName),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(StreamType*	theStream) :
	m_fileName(),
	m_byteStream(theStream),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
	assert(theStream != 0);
}

XSLTResultTarget::XSLTResultTarget(StreamType&	theStream) :
	m_fileName(),
	m_byteStream(&theStream),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(Writer*	characterStream) :
	m_fileName(),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(characterStream),
	m_formatterListener(0),
	m_stream(0)
{
	assert(characterStream != 0);
}

XSLTResultTarget::XSLTResultTarget(FormatterListener&		flistener) :
	m_fileName(),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(&flistener),
	m_stream(0)
{
}

XSLTResultTarget::~XSLTResultTarget()
{
}

XALAN_CPP_NAMESPACE_END
<commit_msg>Added missing constructor.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * $ Id: $
 *
 */

// Base include file.  Must be first.
#include "XSLTResultTarget.hpp"

#include <cassert>

#if defined(XALAN_CLASSIC_IOSTREAMS)
#include <iostream.h>
#else
#include <ostream>
#endif

XALAN_CPP_NAMESPACE_BEGIN

XSLTResultTarget::XSLTResultTarget() :
	m_fileName(),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(const XalanDOMString&	fileName) :
	m_fileName(fileName),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(const XalanDOMChar*	fileName) :
	m_fileName(fileName),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(const char*	fileName) :
	m_fileName(fileName),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(StreamType*	theStream) :
	m_fileName(),
	m_byteStream(theStream),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
	assert(theStream != 0);
}

XSLTResultTarget::XSLTResultTarget(StreamType&	theStream) :
	m_fileName(),
	m_byteStream(&theStream),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(0)
{
}

XSLTResultTarget::XSLTResultTarget(Writer*	characterStream) :
	m_fileName(),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(characterStream),
	m_formatterListener(0),
	m_stream(0)
{
	assert(characterStream != 0);
}

XSLTResultTarget::XSLTResultTarget(FILE*	stream) :
	m_fileName(),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(0),
	m_stream(stream)
{
	assert(stream != 0);
}

XSLTResultTarget::XSLTResultTarget(FormatterListener&	flistener) :
	m_fileName(),
	m_byteStream(0),
	m_encoding(),
	m_characterStream(0),
	m_formatterListener(&flistener),
	m_stream(0)
{
}

XSLTResultTarget::~XSLTResultTarget()
{
}

XALAN_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>// =====================================================================================
// LightSystemService.cpp : Service class providing abstract light
// settings
//
//    Copyright (c) 2017 Stephan Jänecke <stephan.jaenecke@haw-hamburg.de>
// =====================================================================================

#include "LightSystemService.h"

void LightSystemService::setWarningLevel(Level warningLevel) {
	// Send light color and frequency to Controller
	Color COLOR;
	Frequency FREQUENCY;

    switch (warningLevel) {
    case OPERATING:
    	COLOR = GREEN;
    	FREQUENCY = ALWAYS_ON;
    	break;
    case NOT_OPERATING:
    	COLOR = GREEN;
    	FREQUENCY = ALWAYS_OFF;
    	break;
    case WARNING:
    	COLOR = YELLOW;
    	FREQUENCY = SLOW_BLINKING; // FIXME: Specify frequency
    	break;
    case CLEAR_WARNING:
    	COLOR = YELLOW;
    	FREQUENCY = SLOW_BLINKING;
    	break;
    case CLEAR_ERROR:
    	COLOR = RED;
    	FREQUENCY = ALWAYS_OFF;
    	break;
    case ERROR_OCCURED:
    	COLOR = RED;
    	FREQUENCY = FAST_BLINKING;
    	break;
    case ERROR_ACKNOWLEDGED:
    	COLOR = RED;
    	FREQUENCY = ALWAYS_ON;
    	break;
    case ERROR_GONE_UNACKNOWLEDGED:
    	COLOR = RED;
    	FREQUENCY = SLOW_BLINKING;
    	break;
    case CLEAR_ALL:
    	COLOR = ALL;
    	FREQUENCY = ALWAYS_OFF;
    	break;
    default:
    	// TODO: Specify default case
    }

    //controller->setLights(COLOR, FREQUENCY); // FIXME: Replace by pulse message send
    //res = MsgSendPulse ( coid, priority, code, value ) ;
}

<commit_msg>Add refactoring of LightSystemService to task list<commit_after>// =====================================================================================
// LightSystemService.cpp : Service class providing abstract light
// settings
//
//    Copyright (c) 2017 Stephan Jänecke <stephan.jaenecke@haw-hamburg.de>
// =====================================================================================

#include "LightSystemService.h"

void LightSystemService::setWarningLevel(Level warningLevel) {
	// Send light color and frequency to Controller
	Color COLOR;
	Frequency FREQUENCY;

        /* TODO: Replace switch case by array of structs. The structs
         * contain color and frequency.  */
    switch (warningLevel) {
    case OPERATING:
    	COLOR = GREEN;
    	FREQUENCY = ALWAYS_ON;
    	break;
    case NOT_OPERATING:
    	COLOR = GREEN;
    	FREQUENCY = ALWAYS_OFF;
    	break;
    case WARNING:
    	COLOR = YELLOW;
    	FREQUENCY = SLOW_BLINKING; // FIXME: Specify frequency
    	break;
    case CLEAR_WARNING:
    	COLOR = YELLOW;
    	FREQUENCY = SLOW_BLINKING;
    	break;
    case CLEAR_ERROR:
    	COLOR = RED;
    	FREQUENCY = ALWAYS_OFF;
    	break;
    case ERROR_OCCURED:
    	COLOR = RED;
    	FREQUENCY = FAST_BLINKING;
    	break;
    case ERROR_ACKNOWLEDGED:
    	COLOR = RED;
    	FREQUENCY = ALWAYS_ON;
    	break;
    case ERROR_GONE_UNACKNOWLEDGED:
    	COLOR = RED;
    	FREQUENCY = SLOW_BLINKING;
    	break;
    case CLEAR_ALL:
    	COLOR = ALL;
    	FREQUENCY = ALWAYS_OFF;
    	break;
    default:
    	// TODO: Specify default case
    }

    //controller->setLights(COLOR, FREQUENCY); // FIXME: Replace by pulse message send
    //res = MsgSendPulse ( coid, priority, code, value ) ;
}

<|endoftext|>


<commit_before>#define SOL_CHECK_ARGUMENTS

#include <catch.hpp>
#include <sol.hpp>
#include <iostream>
#include "test_stack_guard.hpp"

TEST_CASE("environments/get", "Envronments can be taken out of things like Lua functions properly") {
	sol::state lua;
	sol::stack_guard luasg(lua);
	lua.open_libraries(sol::lib::base);

	lua.script("f = function() return test end");
	sol::function f = lua["f"];

	sol::environment env_f(lua, sol::create);
	env_f["test"] = 31;
	sol::set_environment(env_f, f);

	int result = f();
	REQUIRE(result == 31);

	lua.script("g = function() test = 5 end");
	sol::function g = lua["g"];
	sol::environment env_g(lua, sol::create);
	env_g.set_on(g);

	g();

	int test = env_g["test"];
	REQUIRE(test == 5);

	sol::object global_test = lua["test"];
	REQUIRE(!global_test.valid());

	lua.script("h = function() end");

	lua.set_function("check_f_env",
		[&lua, &env_f](sol::object target) {
		sol::stack_guard sg(lua);
		sol::environment target_env(sol::env_key, target);
		int test_env_f = env_f["test"];
		int test_target_env = target_env["test"];
		REQUIRE(test_env_f == test_target_env);
		REQUIRE(test_env_f == 31);
		REQUIRE(env_f == target_env);
	}
	);
	lua.set_function("check_g_env",
		[&lua, &env_g](sol::function target) {
		sol::stack_guard sg(lua);
		sol::environment target_env = sol::get_environment(target);
		int test_env_g = env_g["test"];
		int test_target_env = target_env["test"];
		REQUIRE(test_env_g == test_target_env);
		REQUIRE(test_env_g == 5);
		REQUIRE(env_g == target_env);
	}
	);
	lua.set_function("check_h_env",
		[&lua](sol::function target) {
		sol::stack_guard sg(lua);
		sol::environment target_env = sol::get_environment(target);
	}
	);

	REQUIRE_NOTHROW([&lua]() {
		lua.script("check_f_env(f)");
		lua.script("check_g_env(g)");
		lua.script("check_h_env(h)");
	}());
}

TEST_CASE("environments/shadowing", "Environments can properly shadow and fallback on variables") {

	sol::state lua;
	lua["b"] = 2142;

	SECTION("no fallback") {
		sol::environment plain_env(lua, sol::create);
		lua.script("a = 24", plain_env);
		sol::optional<int> maybe_env_a = plain_env["a"];
		sol::optional<int> maybe_global_a = lua["a"];
		sol::optional<int> maybe_env_b = plain_env["b"];
		sol::optional<int> maybe_global_b = lua["b"];

		REQUIRE(maybe_env_a != sol::nullopt);
		REQUIRE(maybe_env_a.value() == 24);
		REQUIRE(maybe_env_b == sol::nullopt);

		REQUIRE(maybe_global_a == sol::nullopt);
		REQUIRE(maybe_global_b != sol::nullopt);
		REQUIRE(maybe_global_b.value() == 2142);
	}
	SECTION("fallback") {
		sol::environment env_with_fallback(lua, sol::create, lua.globals());
		lua.script("a = 56", env_with_fallback, sol::default_on_error);
		sol::optional<int> maybe_env_a = env_with_fallback["a"];
		sol::optional<int> maybe_global_a = lua["a"];
		sol::optional<int> maybe_env_b = env_with_fallback["b"];
		sol::optional<int> maybe_global_b = lua["b"];

		REQUIRE(maybe_env_a != sol::nullopt);
		REQUIRE(maybe_env_a.value() == 56);
		REQUIRE(maybe_env_b != sol::nullopt);
		REQUIRE(maybe_env_b.value() == 2142);

		REQUIRE(maybe_global_a == sol::nullopt);
		REQUIRE(maybe_global_b != sol::nullopt);
		REQUIRE(maybe_global_b.value() == 2142);
	}
	SECTION("from name") {
		sol::environment env_with_fallback(lua, sol::create, lua.globals());
		lua["env"] = env_with_fallback;
		sol::environment env = lua["env"];
		lua.script("a = 56", env, sol::default_on_error);
		sol::optional<int> maybe_env_a = env["a"];
		sol::optional<int> maybe_global_a = lua["a"];
		sol::optional<int> maybe_env_b = env["b"];
		sol::optional<int> maybe_global_b = lua["b"];

		REQUIRE(maybe_env_a != sol::nullopt);
		REQUIRE(maybe_env_a.value() == 56);
		REQUIRE(maybe_env_b != sol::nullopt);
		REQUIRE(maybe_env_b.value() == 2142);

		REQUIRE(maybe_global_a == sol::nullopt);
		REQUIRE(maybe_global_b != sol::nullopt);
		REQUIRE(maybe_global_b.value() == 2142);
	}
	SECTION("name with newtable") {
		lua["blank_env"] = sol::new_table(0, 1);
		sol::environment plain_env = lua["blank_env"];
		lua.script("a = 24", plain_env);
		sol::optional<int> maybe_env_a = plain_env["a"];
		sol::optional<int> maybe_global_a = lua["a"];
		sol::optional<int> maybe_env_b = plain_env["b"];
		sol::optional<int> maybe_global_b = lua["b"];

		REQUIRE(maybe_env_a != sol::nullopt);
		REQUIRE(maybe_env_a.value() == 24);
		REQUIRE(maybe_env_b == sol::nullopt);

		REQUIRE(maybe_global_a == sol::nullopt);
		REQUIRE(maybe_global_b != sol::nullopt);
		REQUIRE(maybe_global_b.value() == 2142);
	}
}

TEST_CASE("environments/functions", "see if environments on functions are working properly") {

	SECTION("basic") {
		sol::state lua;

		lua.script("a = function() return 5 end");

		sol::function a = lua["a"];

		int result0 = a();
		REQUIRE(result0 == 5);

		sol::environment env(lua, sol::create);
		sol::set_environment(env, a);

		int result1 = a();
		REQUIRE(result1 == 5);
	}
	SECTION("return environment value") {
		sol::state lua;

		lua.script("a = function() return test end");

		sol::function a = lua["a"];
		sol::environment env(lua, sol::create);
		env["test"] = 5;
		env.set_on(a);

		// the function returns the value from the environment table
		int result = a();
		REQUIRE(result == 5);
	}

	SECTION("set environment value") {
		sol::state lua;
		lua.script("a = function() test = 5 end");

		sol::function a = lua["a"];
		sol::environment env(lua, sol::create);
		sol::set_environment(env, a);

		a();

		// the value can be retrieved from the env table
		int result = env["test"];
		REQUIRE(result == 5);

		// the global environment is not polluted
		auto gtest = lua["test"];
		REQUIRE(!gtest.valid());
	}
}

TEST_CASE("environments/this_environment", "test various situations of pulling out an environment") {
	static std::string code = "return (f(10))";

	sol::state lua;

	lua["f"] = [](sol::this_environment te, int x) {
		if (te) {
			sol::environment& env = te;
			return x + static_cast<int>(env["x"]);
		}
		return x;
	};

	sol::environment e(lua, sol::create, lua.globals());
	lua["x"] = 5;
	e["x"] = 20;
	SECTION("from Lua script") {
		int value = lua.script(code, e);
		REQUIRE(value == 30);
	}
	SECTION("from C++") {
		sol::function f = lua["f"];
		e.set_on(f);
		int value = f(10);
		REQUIRE(value == 30);
	}
	SECTION("from C++, with no env") {
		sol::function f = lua["f"];
		int value = f(10);
		REQUIRE(value == 15);
	}
}
<commit_msg>Sigh. I hate you, LuaJIT.<commit_after>#define SOL_CHECK_ARGUMENTS

#include <catch.hpp>
#include <sol.hpp>
#include <iostream>
#include "test_stack_guard.hpp"

TEST_CASE("environments/get", "Envronments can be taken out of things like Lua functions properly") {
	sol::state lua;
	sol::stack_guard luasg(lua);
	lua.open_libraries(sol::lib::base);

	lua.script("f = function() return test end");
	sol::function f = lua["f"];

	sol::environment env_f(lua, sol::create);
	env_f["test"] = 31;
	sol::set_environment(env_f, f);

	int result = f();
	REQUIRE(result == 31);

	lua.script("g = function() test = 5 end");
	sol::function g = lua["g"];
	sol::environment env_g(lua, sol::create);
	env_g.set_on(g);

	g();

	int test = env_g["test"];
	REQUIRE(test == 5);

	sol::object global_test = lua["test"];
	REQUIRE(!global_test.valid());

	lua.script("h = function() end");

	lua.set_function("check_f_env",
		[&lua, &env_f](sol::object target) {
		sol::stack_guard sg(lua);
		sol::environment target_env(sol::env_key, target);
		int test_env_f = env_f["test"];
		int test_target_env = target_env["test"];
		REQUIRE(test_env_f == test_target_env);
		REQUIRE(test_env_f == 31);
		REQUIRE(env_f == target_env);
	}
	);
	lua.set_function("check_g_env",
		[&lua, &env_g](sol::function target) {
		sol::stack_guard sg(lua);
		sol::environment target_env = sol::get_environment(target);
		int test_env_g = env_g["test"];
		int test_target_env = target_env["test"];
		REQUIRE(test_env_g == test_target_env);
		REQUIRE(test_env_g == 5);
		REQUIRE(env_g == target_env);
	}
	);
	lua.set_function("check_h_env",
		[&lua](sol::function target) {
		sol::stack_guard sg(lua);
		sol::environment target_env = sol::get_environment(target);
	}
	);

	REQUIRE_NOTHROW([&lua]() {
		lua.script("check_f_env(f)");
		lua.script("check_g_env(g)");
		lua.script("check_h_env(h)");
	}());
}

TEST_CASE("environments/shadowing", "Environments can properly shadow and fallback on variables") {

	sol::state lua;
	lua["b"] = 2142;

	SECTION("no fallback") {
		sol::environment plain_env(lua, sol::create);
		lua.script("a = 24", plain_env);
		sol::optional<int> maybe_env_a = plain_env["a"];
		sol::optional<int> maybe_global_a = lua["a"];
		sol::optional<int> maybe_env_b = plain_env["b"];
		sol::optional<int> maybe_global_b = lua["b"];

		REQUIRE(maybe_env_a != sol::nullopt);
		REQUIRE(maybe_env_a.value() == 24);
		REQUIRE(maybe_env_b == sol::nullopt);

		REQUIRE(maybe_global_a == sol::nullopt);
		REQUIRE(maybe_global_b != sol::nullopt);
		REQUIRE(maybe_global_b.value() == 2142);
	}
	SECTION("fallback") {
		sol::environment env_with_fallback(lua, sol::create, lua.globals());
		lua.script("a = 56", env_with_fallback, sol::default_on_error);
		sol::optional<int> maybe_env_a = env_with_fallback["a"];
		sol::optional<int> maybe_global_a = lua["a"];
		sol::optional<int> maybe_env_b = env_with_fallback["b"];
		sol::optional<int> maybe_global_b = lua["b"];

		REQUIRE(maybe_env_a != sol::nullopt);
		REQUIRE(maybe_env_a.value() == 56);
		REQUIRE(maybe_env_b != sol::nullopt);
		REQUIRE(maybe_env_b.value() == 2142);

		REQUIRE(maybe_global_a == sol::nullopt);
		REQUIRE(maybe_global_b != sol::nullopt);
		REQUIRE(maybe_global_b.value() == 2142);
	}
	SECTION("from name") {
		sol::environment env_with_fallback(lua, sol::create, lua.globals());
		lua["env"] = env_with_fallback;
		sol::environment env = lua["env"];
		lua.script("a = 56", env, sol::default_on_error);
		sol::optional<int> maybe_env_a = env["a"];
		sol::optional<int> maybe_global_a = lua["a"];
		sol::optional<int> maybe_env_b = env["b"];
		sol::optional<int> maybe_global_b = lua["b"];

		REQUIRE(maybe_env_a != sol::nullopt);
		REQUIRE(maybe_env_a.value() == 56);
		REQUIRE(maybe_env_b != sol::nullopt);
		REQUIRE(maybe_env_b.value() == 2142);

		REQUIRE(maybe_global_a == sol::nullopt);
		REQUIRE(maybe_global_b != sol::nullopt);
		REQUIRE(maybe_global_b.value() == 2142);
	}
	SECTION("name with newtable") {
		lua["blank_env"] = sol::new_table(0, 1);
		sol::environment plain_env = lua["blank_env"];
		lua.script("a = 24", plain_env);
		sol::optional<int> maybe_env_a = plain_env["a"];
		sol::optional<int> maybe_global_a = lua["a"];
		sol::optional<int> maybe_env_b = plain_env["b"];
		sol::optional<int> maybe_global_b = lua["b"];

		REQUIRE(maybe_env_a != sol::nullopt);
		REQUIRE(maybe_env_a.value() == 24);
		REQUIRE(maybe_env_b == sol::nullopt);

		REQUIRE(maybe_global_a == sol::nullopt);
		REQUIRE(maybe_global_b != sol::nullopt);
		REQUIRE(maybe_global_b.value() == 2142);
	}
}

TEST_CASE("environments/functions", "see if environments on functions are working properly") {

	SECTION("basic") {
		sol::state lua;

		lua.script("a = function() return 5 end");

		sol::function a = lua["a"];

		int result0 = a();
		REQUIRE(result0 == 5);

		sol::environment env(lua, sol::create);
		sol::set_environment(env, a);

		int result1 = a();
		REQUIRE(result1 == 5);
	}
	SECTION("return environment value") {
		sol::state lua;

		lua.script("a = function() return test end");

		sol::function a = lua["a"];
		sol::environment env(lua, sol::create);
		env["test"] = 5;
		env.set_on(a);

		// the function returns the value from the environment table
		int result = a();
		REQUIRE(result == 5);
	}

	SECTION("set environment value") {
		sol::state lua;
		lua.script("a = function() test = 5 end");

		sol::function a = lua["a"];
		sol::environment env(lua, sol::create);
		sol::set_environment(env, a);

		a();

		// the value can be retrieved from the env table
		int result = env["test"];
		REQUIRE(result == 5);

		// the global environment is not polluted
		auto gtest = lua["test"];
		REQUIRE(!gtest.valid());
	}
}

TEST_CASE("environments/this_environment", "test various situations of pulling out an environment") {
	static std::string code = "return (f(10))";

	sol::state lua;

	lua["f"] = [](sol::this_environment te, int x, sol::this_state ts) {
		if (te) {
			sol::environment& env = te;
			return x + static_cast<int>(env["x"]);
		}
		sol::state_view lua = ts;
		return x + static_cast<int>(lua["x"]);
	};

	sol::environment e(lua, sol::create, lua.globals());
	lua["x"] = 5;
	e["x"] = 20;
	SECTION("from Lua script") {
		int value = lua.script(code, e);
		REQUIRE(value == 30);
	}
	SECTION("from C++") {
		sol::function f = lua["f"];
		e.set_on(f);
		int value = f(10);
		REQUIRE(value == 30);
	}
	SECTION("from C++, with no env") {
		sol::function f = lua["f"];
		int value = f(10);
		REQUIRE(value == 15);
	}
}
<|endoftext|>


<commit_before>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "Test.h"
#include "SkData.h"
#include "SkDataSet.h"
#include "SkDataTable.h"
#include "SkStream.h"
#include "SkOrderedReadBuffer.h"
#include "SkOrderedWriteBuffer.h"

template <typename T> class SkTUnref {
public:
    SkTUnref(T* ref) : fRef(ref) {}
    ~SkTUnref() { fRef->unref(); }

    operator T*() { return fRef; }
    operator const T*() { return fRef; }

private:
    T*  fRef;
};

static void test_is_equal(skiatest::Reporter* reporter,
                          const SkDataTable* a, const SkDataTable* b) {
    REPORTER_ASSERT(reporter, a->count() == b->count());
    for (int i = 0; i < a->count(); ++i) {
        size_t sizea, sizeb;
        const void* mema = a->at(i, &sizea);
        const void* memb = b->at(i, &sizeb);
        REPORTER_ASSERT(reporter, sizea == sizeb);
        REPORTER_ASSERT(reporter, !memcmp(mema, memb, sizea));
    }
}

static void test_datatable_flatten(skiatest::Reporter* reporter,
                                   SkDataTable* table) {
    SkOrderedWriteBuffer wb(1024);
    wb.writeFlattenable(table);

    size_t wsize = wb.size();
    SkAutoMalloc storage(wsize);
    wb.writeToMemory(storage.get());

    SkOrderedReadBuffer rb(storage.get(), wsize);
    SkAutoTUnref<SkDataTable> newTable((SkDataTable*)rb.readFlattenable());

    SkDebugf("%d entries, %d flatten-size\n", table->count(), wsize);
    test_is_equal(reporter, table, newTable);
}

static void test_datatable_is_empty(skiatest::Reporter* reporter,
                                    SkDataTable* table) {
    REPORTER_ASSERT(reporter, table->isEmpty());
    REPORTER_ASSERT(reporter, 0 == table->count());
    test_datatable_flatten(reporter, table);
}

static void test_emptytable(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkDataTable> table0(SkDataTable::NewEmpty());
    SkAutoTUnref<SkDataTable> table1(SkDataTable::NewCopyArrays(NULL, NULL, 0));
    SkAutoTUnref<SkDataTable> table2(SkDataTable::NewCopyArray(NULL, 0, 0));
    SkAutoTUnref<SkDataTable> table3(SkDataTable::NewArrayProc(NULL, 0, 0,
                                                               NULL, NULL));

    test_datatable_is_empty(reporter, table0);
    test_datatable_is_empty(reporter, table1);
    test_datatable_is_empty(reporter, table2);
    test_datatable_is_empty(reporter, table3);

    test_is_equal(reporter, table0, table1);
    test_is_equal(reporter, table0, table2);
    test_is_equal(reporter, table0, table3);
}

static void test_simpletable(skiatest::Reporter* reporter) {
    const int idata[] = { 1, 4, 9, 16, 25, 63 };
    int icount = SK_ARRAY_COUNT(idata);
    SkAutoTUnref<SkDataTable> itable(SkDataTable::NewCopyArray(idata,
                                                               sizeof(idata[0]),
                                                               icount));
    REPORTER_ASSERT(reporter, itable->count() == icount);
    for (int i = 0; i < icount; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, sizeof(int) == itable->atSize(i));
        REPORTER_ASSERT(reporter, *itable->atT<int>(i, &size) == idata[i]);
        REPORTER_ASSERT(reporter, sizeof(int) == size);
    }
    test_datatable_flatten(reporter, itable);
}

static void test_vartable(skiatest::Reporter* reporter) {
    const char* str[] = {
        "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
    };
    int count = SK_ARRAY_COUNT(str);
    size_t sizes[SK_ARRAY_COUNT(str)];
    for (int i = 0; i < count; ++i) {
        sizes[i] = strlen(str[i]) + 1;
    }

    SkAutoTUnref<SkDataTable> table(SkDataTable::NewCopyArrays(
                                        (const void*const*)str, sizes, count));

    REPORTER_ASSERT(reporter, table->count() == count);
    for (int i = 0; i < count; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, table->atSize(i) == sizes[i]);
        REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
                                          str[i]));
        REPORTER_ASSERT(reporter, size == sizes[i]);

        const char* s = table->atStr(i);
        REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
    }
    test_datatable_flatten(reporter, table);
}

static void test_tablebuilder(skiatest::Reporter* reporter) {
    const char* str[] = {
        "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
    };
    int count = SK_ARRAY_COUNT(str);

    SkDataTableBuilder builder(16);

    for (int i = 0; i < count; ++i) {
        builder.append(str[i], strlen(str[i]) + 1);
    }
    SkAutoTUnref<SkDataTable> table(builder.detachDataTable());

    REPORTER_ASSERT(reporter, table->count() == count);
    for (int i = 0; i < count; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, table->atSize(i) == strlen(str[i]) + 1);
        REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
                                          str[i]));
        REPORTER_ASSERT(reporter, size == strlen(str[i]) + 1);

        const char* s = table->atStr(i);
        REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
    }
    test_datatable_flatten(reporter, table);
}

static void test_globaltable(skiatest::Reporter* reporter) {
    static const int gData[] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
    };
    int count = SK_ARRAY_COUNT(gData);

    SkAutoTUnref<SkDataTable> table(SkDataTable::NewArrayProc(gData,
                                          sizeof(gData[0]), count, NULL, NULL));

    REPORTER_ASSERT(reporter, table->count() == count);
    for (int i = 0; i < count; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, table->atSize(i) == sizeof(int));
        REPORTER_ASSERT(reporter, *table->atT<const char>(i, &size) == i);
        REPORTER_ASSERT(reporter, sizeof(int) == size);
    }
    test_datatable_flatten(reporter, table);
}

static void TestDataTable(skiatest::Reporter* reporter) {
    test_emptytable(reporter);
    test_simpletable(reporter);
    test_vartable(reporter);
    test_tablebuilder(reporter);
    test_globaltable(reporter);
}

static void unrefAll(const SkDataSet::Pair pairs[], int count) {
    for (int i = 0; i < count; ++i) {
        pairs[i].fValue->unref();
    }
}

// asserts that inner is a subset of outer
static void test_dataset_subset(skiatest::Reporter* reporter,
                                const SkDataSet& outer, const SkDataSet& inner) {
    SkDataSet::Iter iter(inner);
    for (; !iter.done(); iter.next()) {
        SkData* outerData = outer.find(iter.key());
        REPORTER_ASSERT(reporter, outerData);
        REPORTER_ASSERT(reporter, outerData->equals(iter.value()));
    }
}

static void test_datasets_equal(skiatest::Reporter* reporter,
                                const SkDataSet& ds0, const SkDataSet& ds1) {
    REPORTER_ASSERT(reporter, ds0.count() == ds1.count());

    test_dataset_subset(reporter, ds0, ds1);
    test_dataset_subset(reporter, ds1, ds0);
}

static void test_dataset(skiatest::Reporter* reporter, const SkDataSet& ds,
                         int count) {
    REPORTER_ASSERT(reporter, ds.count() == count);

    SkDataSet::Iter iter(ds);
    int index = 0;
    for (; !iter.done(); iter.next()) {
//        const char* name = iter.key();
//        SkData* data = iter.value();
//        SkDebugf("[%d] %s:%s\n", index, name, (const char*)data->bytes());
        index += 1;
    }
    REPORTER_ASSERT(reporter, index == count);

    SkDynamicMemoryWStream ostream;
    ds.writeToStream(&ostream);
    SkMemoryStream istream;
    istream.setData(ostream.copyToData())->unref();
    SkDataSet copy(&istream);

    test_datasets_equal(reporter, ds, copy);
}

static void test_dataset(skiatest::Reporter* reporter) {
    SkDataSet set0(NULL, 0);
    SkDataSet set1("hello", SkTUnref<SkData>(SkData::NewWithCString("world")));

    const SkDataSet::Pair pairs[] = {
        { "one", SkData::NewWithCString("1") },
        { "two", SkData::NewWithCString("2") },
        { "three", SkData::NewWithCString("3") },
    };
    SkDataSet set3(pairs, 3);
    unrefAll(pairs, 3);

    test_dataset(reporter, set0, 0);
    test_dataset(reporter, set1, 1);
    test_dataset(reporter, set3, 3);
}

static void* gGlobal;

static void delete_int_proc(const void* ptr, size_t len, void* context) {
    int* data = (int*)ptr;
    SkASSERT(context == gGlobal);
    delete[] data;
}

static void assert_len(skiatest::Reporter* reporter, SkData* ref, size_t len) {
    REPORTER_ASSERT(reporter, ref->size() == len);
}

static void assert_data(skiatest::Reporter* reporter, SkData* ref,
                        const void* data, size_t len) {
    REPORTER_ASSERT(reporter, ref->size() == len);
    REPORTER_ASSERT(reporter, !memcmp(ref->data(), data, len));
}

static void test_cstring(skiatest::Reporter* reporter) {
    const char str[] = "Hello world";
    size_t     len = strlen(str);

    SkAutoTUnref<SkData> r0(SkData::NewWithCopy(str, len + 1));
    SkAutoTUnref<SkData> r1(SkData::NewWithCString(str));

    REPORTER_ASSERT(reporter, r0->equals(r1));

    SkAutoTUnref<SkData> r2(SkData::NewWithCString(NULL));
    REPORTER_ASSERT(reporter, 1 == r2->size());
    REPORTER_ASSERT(reporter, 0 == *r2->bytes());
}

static void TestData(skiatest::Reporter* reporter) {
    const char* str = "We the people, in order to form a more perfect union.";
    const int N = 10;

    SkAutoTUnref<SkData> r0(SkData::NewEmpty());
    SkAutoTUnref<SkData> r1(SkData::NewWithCopy(str, strlen(str)));
    SkAutoTUnref<SkData> r2(SkData::NewWithProc(new int[N], N*sizeof(int),
                                           delete_int_proc, gGlobal));
    SkAutoTUnref<SkData> r3(SkData::NewSubset(r1, 7, 6));

    assert_len(reporter, r0, 0);
    assert_len(reporter, r1, strlen(str));
    assert_len(reporter, r2, N * sizeof(int));
    assert_len(reporter, r3, 6);

    assert_data(reporter, r1, str, strlen(str));
    assert_data(reporter, r3, "people", 6);

    SkData* tmp = SkData::NewSubset(r1, strlen(str), 10);
    assert_len(reporter, tmp, 0);
    tmp->unref();
    tmp = SkData::NewSubset(r1, 0, 0);
    assert_len(reporter, tmp, 0);
    tmp->unref();

    test_cstring(reporter);
    test_dataset(reporter);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("Data", DataTestClass, TestData)
DEFINE_TESTCLASS("DataTable", DataTableTestClass, TestDataTable)
<commit_msg>remove printf<commit_after>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "Test.h"
#include "SkData.h"
#include "SkDataSet.h"
#include "SkDataTable.h"
#include "SkStream.h"
#include "SkOrderedReadBuffer.h"
#include "SkOrderedWriteBuffer.h"

template <typename T> class SkTUnref {
public:
    SkTUnref(T* ref) : fRef(ref) {}
    ~SkTUnref() { fRef->unref(); }

    operator T*() { return fRef; }
    operator const T*() { return fRef; }

private:
    T*  fRef;
};

static void test_is_equal(skiatest::Reporter* reporter,
                          const SkDataTable* a, const SkDataTable* b) {
    REPORTER_ASSERT(reporter, a->count() == b->count());
    for (int i = 0; i < a->count(); ++i) {
        size_t sizea, sizeb;
        const void* mema = a->at(i, &sizea);
        const void* memb = b->at(i, &sizeb);
        REPORTER_ASSERT(reporter, sizea == sizeb);
        REPORTER_ASSERT(reporter, !memcmp(mema, memb, sizea));
    }
}

static void test_datatable_flatten(skiatest::Reporter* reporter,
                                   SkDataTable* table) {
    SkOrderedWriteBuffer wb(1024);
    wb.writeFlattenable(table);

    size_t wsize = wb.size();
    SkAutoMalloc storage(wsize);
    wb.writeToMemory(storage.get());

    SkOrderedReadBuffer rb(storage.get(), wsize);
    SkAutoTUnref<SkDataTable> newTable((SkDataTable*)rb.readFlattenable());

    test_is_equal(reporter, table, newTable);
}

static void test_datatable_is_empty(skiatest::Reporter* reporter,
                                    SkDataTable* table) {
    REPORTER_ASSERT(reporter, table->isEmpty());
    REPORTER_ASSERT(reporter, 0 == table->count());
    test_datatable_flatten(reporter, table);
}

static void test_emptytable(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkDataTable> table0(SkDataTable::NewEmpty());
    SkAutoTUnref<SkDataTable> table1(SkDataTable::NewCopyArrays(NULL, NULL, 0));
    SkAutoTUnref<SkDataTable> table2(SkDataTable::NewCopyArray(NULL, 0, 0));
    SkAutoTUnref<SkDataTable> table3(SkDataTable::NewArrayProc(NULL, 0, 0,
                                                               NULL, NULL));

    test_datatable_is_empty(reporter, table0);
    test_datatable_is_empty(reporter, table1);
    test_datatable_is_empty(reporter, table2);
    test_datatable_is_empty(reporter, table3);

    test_is_equal(reporter, table0, table1);
    test_is_equal(reporter, table0, table2);
    test_is_equal(reporter, table0, table3);
}

static void test_simpletable(skiatest::Reporter* reporter) {
    const int idata[] = { 1, 4, 9, 16, 25, 63 };
    int icount = SK_ARRAY_COUNT(idata);
    SkAutoTUnref<SkDataTable> itable(SkDataTable::NewCopyArray(idata,
                                                               sizeof(idata[0]),
                                                               icount));
    REPORTER_ASSERT(reporter, itable->count() == icount);
    for (int i = 0; i < icount; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, sizeof(int) == itable->atSize(i));
        REPORTER_ASSERT(reporter, *itable->atT<int>(i, &size) == idata[i]);
        REPORTER_ASSERT(reporter, sizeof(int) == size);
    }
    test_datatable_flatten(reporter, itable);
}

static void test_vartable(skiatest::Reporter* reporter) {
    const char* str[] = {
        "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
    };
    int count = SK_ARRAY_COUNT(str);
    size_t sizes[SK_ARRAY_COUNT(str)];
    for (int i = 0; i < count; ++i) {
        sizes[i] = strlen(str[i]) + 1;
    }

    SkAutoTUnref<SkDataTable> table(SkDataTable::NewCopyArrays(
                                        (const void*const*)str, sizes, count));

    REPORTER_ASSERT(reporter, table->count() == count);
    for (int i = 0; i < count; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, table->atSize(i) == sizes[i]);
        REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
                                          str[i]));
        REPORTER_ASSERT(reporter, size == sizes[i]);

        const char* s = table->atStr(i);
        REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
    }
    test_datatable_flatten(reporter, table);
}

static void test_tablebuilder(skiatest::Reporter* reporter) {
    const char* str[] = {
        "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
    };
    int count = SK_ARRAY_COUNT(str);

    SkDataTableBuilder builder(16);

    for (int i = 0; i < count; ++i) {
        builder.append(str[i], strlen(str[i]) + 1);
    }
    SkAutoTUnref<SkDataTable> table(builder.detachDataTable());

    REPORTER_ASSERT(reporter, table->count() == count);
    for (int i = 0; i < count; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, table->atSize(i) == strlen(str[i]) + 1);
        REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
                                          str[i]));
        REPORTER_ASSERT(reporter, size == strlen(str[i]) + 1);

        const char* s = table->atStr(i);
        REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
    }
    test_datatable_flatten(reporter, table);
}

static void test_globaltable(skiatest::Reporter* reporter) {
    static const int gData[] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
    };
    int count = SK_ARRAY_COUNT(gData);

    SkAutoTUnref<SkDataTable> table(SkDataTable::NewArrayProc(gData,
                                          sizeof(gData[0]), count, NULL, NULL));

    REPORTER_ASSERT(reporter, table->count() == count);
    for (int i = 0; i < count; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, table->atSize(i) == sizeof(int));
        REPORTER_ASSERT(reporter, *table->atT<const char>(i, &size) == i);
        REPORTER_ASSERT(reporter, sizeof(int) == size);
    }
    test_datatable_flatten(reporter, table);
}

static void TestDataTable(skiatest::Reporter* reporter) {
    test_emptytable(reporter);
    test_simpletable(reporter);
    test_vartable(reporter);
    test_tablebuilder(reporter);
    test_globaltable(reporter);
}

static void unrefAll(const SkDataSet::Pair pairs[], int count) {
    for (int i = 0; i < count; ++i) {
        pairs[i].fValue->unref();
    }
}

// asserts that inner is a subset of outer
static void test_dataset_subset(skiatest::Reporter* reporter,
                                const SkDataSet& outer, const SkDataSet& inner) {
    SkDataSet::Iter iter(inner);
    for (; !iter.done(); iter.next()) {
        SkData* outerData = outer.find(iter.key());
        REPORTER_ASSERT(reporter, outerData);
        REPORTER_ASSERT(reporter, outerData->equals(iter.value()));
    }
}

static void test_datasets_equal(skiatest::Reporter* reporter,
                                const SkDataSet& ds0, const SkDataSet& ds1) {
    REPORTER_ASSERT(reporter, ds0.count() == ds1.count());

    test_dataset_subset(reporter, ds0, ds1);
    test_dataset_subset(reporter, ds1, ds0);
}

static void test_dataset(skiatest::Reporter* reporter, const SkDataSet& ds,
                         int count) {
    REPORTER_ASSERT(reporter, ds.count() == count);

    SkDataSet::Iter iter(ds);
    int index = 0;
    for (; !iter.done(); iter.next()) {
//        const char* name = iter.key();
//        SkData* data = iter.value();
//        SkDebugf("[%d] %s:%s\n", index, name, (const char*)data->bytes());
        index += 1;
    }
    REPORTER_ASSERT(reporter, index == count);

    SkDynamicMemoryWStream ostream;
    ds.writeToStream(&ostream);
    SkMemoryStream istream;
    istream.setData(ostream.copyToData())->unref();
    SkDataSet copy(&istream);

    test_datasets_equal(reporter, ds, copy);
}

static void test_dataset(skiatest::Reporter* reporter) {
    SkDataSet set0(NULL, 0);
    SkDataSet set1("hello", SkTUnref<SkData>(SkData::NewWithCString("world")));

    const SkDataSet::Pair pairs[] = {
        { "one", SkData::NewWithCString("1") },
        { "two", SkData::NewWithCString("2") },
        { "three", SkData::NewWithCString("3") },
    };
    SkDataSet set3(pairs, 3);
    unrefAll(pairs, 3);

    test_dataset(reporter, set0, 0);
    test_dataset(reporter, set1, 1);
    test_dataset(reporter, set3, 3);
}

static void* gGlobal;

static void delete_int_proc(const void* ptr, size_t len, void* context) {
    int* data = (int*)ptr;
    SkASSERT(context == gGlobal);
    delete[] data;
}

static void assert_len(skiatest::Reporter* reporter, SkData* ref, size_t len) {
    REPORTER_ASSERT(reporter, ref->size() == len);
}

static void assert_data(skiatest::Reporter* reporter, SkData* ref,
                        const void* data, size_t len) {
    REPORTER_ASSERT(reporter, ref->size() == len);
    REPORTER_ASSERT(reporter, !memcmp(ref->data(), data, len));
}

static void test_cstring(skiatest::Reporter* reporter) {
    const char str[] = "Hello world";
    size_t     len = strlen(str);

    SkAutoTUnref<SkData> r0(SkData::NewWithCopy(str, len + 1));
    SkAutoTUnref<SkData> r1(SkData::NewWithCString(str));

    REPORTER_ASSERT(reporter, r0->equals(r1));

    SkAutoTUnref<SkData> r2(SkData::NewWithCString(NULL));
    REPORTER_ASSERT(reporter, 1 == r2->size());
    REPORTER_ASSERT(reporter, 0 == *r2->bytes());
}

static void TestData(skiatest::Reporter* reporter) {
    const char* str = "We the people, in order to form a more perfect union.";
    const int N = 10;

    SkAutoTUnref<SkData> r0(SkData::NewEmpty());
    SkAutoTUnref<SkData> r1(SkData::NewWithCopy(str, strlen(str)));
    SkAutoTUnref<SkData> r2(SkData::NewWithProc(new int[N], N*sizeof(int),
                                           delete_int_proc, gGlobal));
    SkAutoTUnref<SkData> r3(SkData::NewSubset(r1, 7, 6));

    assert_len(reporter, r0, 0);
    assert_len(reporter, r1, strlen(str));
    assert_len(reporter, r2, N * sizeof(int));
    assert_len(reporter, r3, 6);

    assert_data(reporter, r1, str, strlen(str));
    assert_data(reporter, r3, "people", 6);

    SkData* tmp = SkData::NewSubset(r1, strlen(str), 10);
    assert_len(reporter, tmp, 0);
    tmp->unref();
    tmp = SkData::NewSubset(r1, 0, 0);
    assert_len(reporter, tmp, 0);
    tmp->unref();

    test_cstring(reporter);
    test_dataset(reporter);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("Data", DataTestClass, TestData)
DEFINE_TESTCLASS("DataTable", DataTableTestClass, TestDataTable)
<|endoftext|>