<commit_before>#include "Platform.h"
#include <stdlib.h>
#include "CppUTest/TestHarness.h"
#undef malloc
#undef free
#undef calloc
#undef realloc

#include "CppUTest/TestRegistry.h"
#include <stdio.h>
#include <stdarg.h>
#include <setjmp.h>
#include <string.h>
#include <math.h>
#include <float.h>
#include <time.h>
#include "CppUTest/PlatformSpecificFunctions.h"

#include <windows.h>
#include <mmsystem.h>

#include <setjmp.h>

static jmp_buf test_exit_jmp_buf[10];
static int jmp_buf_index = 0;

int PlatformSpecificSetJmp(void (*function) (void* data), void* data)
{
	if (0 == setjmp(test_exit_jmp_buf[jmp_buf_index])) {
	    jmp_buf_index++;
		function(data);
	    jmp_buf_index--;
		return 1;
	}
	return 0;
}

void PlatformSpecificLongJmp()
{
	jmp_buf_index--;
	longjmp(test_exit_jmp_buf[jmp_buf_index], 1);
}

void PlatformSpecificRestoreJumpBuffer()
{
	jmp_buf_index--;
}

void PlatformSpecificRunTestInASeperateProcess(UtestShell* shell, TestPlugin* plugin, TestResult* result)
{
   printf("-p doesn't work on this platform as it is not implemented. Running inside the process\b");
   shell->runOneTest(plugin, *result);
}

TestOutput::WorkingEnvironment PlatformSpecificGetWorkingEnvironment()
{
	return TestOutput::vistualStudio;
}

///////////// Time in millis

static long TimeInMillisImplementation()
{
    return timeGetTime();
}

static long (*timeInMillisFp) () = TimeInMillisImplementation;

long GetPlatformSpecificTimeInMillis()
{
	return timeInMillisFp();
}

void SetPlatformSpecificTimeInMillisMethod(long (*platformSpecific) ())
{
	timeInMillisFp = (platformSpecific == 0) ? TimeInMillisImplementation : platformSpecific;
}

///////////// Time in String

static const char* TimeStringImplementation()
{
	time_t tm = time(NULL);
	static char dateTime[80];
	struct tm *tmp = localtime(&tm);
	strftime(dateTime, 80, "%Y-%m-%dT%H:%M:%S", tmp);
	return dateTime;
}

static const char* (*timeStringFp) () = TimeStringImplementation;

const char* GetPlatformSpecificTimeString()
{
	return timeStringFp();
}

void SetPlatformSpecificTimeStringMethod(const char* (*platformMethod) ())
{
	timeStringFp = (platformMethod == 0) ? TimeStringImplementation : platformMethod;
}

////// taken from gcc

int PlatformSpecificAtoI(const char*str)
{
   return atoi(str);
}

size_t PlatformSpecificStrLen(const char* str)
{
   return strlen(str);
}

char* PlatformSpecificStrNCpy(char* s1, const char* s2, size_t size)
{
   return strncpy(s1, s2, size);
}

int PlatformSpecificStrCmp(const char* s1, const char* s2)
{
   return strcmp(s1, s2);
}

int PlatformSpecificStrNCmp(const char* s1, const char* s2, size_t size)
{
   return strncmp(s1, s2, size);
}
char* PlatformSpecificStrStr(const char* s1, const char* s2)
{
   return (char*) strstr(s1, s2);
}

int PlatformSpecificVSNprintf(char *str, size_t size, const char* format, va_list args)
{
	char* buf = 0;
	size_t sizeGuess = size;

	int result = _vsnprintf( str, size, format, args);
	str[size-1] = 0;
	while (result == -1)
	{
		if (buf != 0)
			free(buf);
		sizeGuess += 10;
		buf = (char*)malloc(sizeGuess);
		result = _vsnprintf( buf, sizeGuess, format, args);
	}

	if (buf != 0)
		free(buf);
	return result;

}

PlatformSpecificFile PlatformSpecificFOpen(const char* filename, const char* flag)
{
   return fopen(filename, flag);
}

void PlatformSpecificFPuts(const char* str, PlatformSpecificFile file)
{
   fputs(str, (FILE*)file);
}

void PlatformSpecificFClose(PlatformSpecificFile file)
{
   fclose((FILE*)file);
}

void PlatformSpecificFlush()
{
  fflush(stdout);
}

int PlatformSpecificPutchar(int c)
{
  return putchar(c);
}

void* PlatformSpecificMalloc(size_t size)
{
   return malloc(size);
}

void* PlatformSpecificRealloc (void* memory, size_t size)
{
   return realloc(memory, size);
}

void PlatformSpecificFree(void* memory)
{
   free(memory);
}

void* PlatformSpecificMemCpy(void* s1, const void* s2, size_t size)
{
   return memcpy(s1, s2, size);
}

void* PlatformSpecificMemset(void* mem, int c, size_t size)
{
	return memset(mem, c, size);
}

double PlatformSpecificFabs(double d)
{
   return fabs(d);
}

int PlatformSpecificIsNan(double d)
{
	return _isnan(d);
}

int PlatformSpecificVSNprintf(char *str, unsigned int size, const char* format, void* args)
{
   return _vsnprintf( str, size, format, (va_list) args);
}

char PlatformSpecificToLower(char c)
{
	return tolower(c);
}

<commit_msg>VS problem. localtime_s appears to be OK.<commit_after>#include "Platform.h"
#include <stdlib.h>
#include "CppUTest/TestHarness.h"
#undef malloc
#undef free
#undef calloc
#undef realloc

#include "CppUTest/TestRegistry.h"
#include <stdio.h>
#include <stdarg.h>
#include <setjmp.h>
#include <string.h>
#include <math.h>
#include <float.h>
#include <time.h>
#include "CppUTest/PlatformSpecificFunctions.h"

#include <windows.h>
#include <mmsystem.h>

#include <setjmp.h>

static jmp_buf test_exit_jmp_buf[10];
static int jmp_buf_index = 0;

int PlatformSpecificSetJmp(void (*function) (void* data), void* data)
{
	if (0 == setjmp(test_exit_jmp_buf[jmp_buf_index])) {
	    jmp_buf_index++;
		function(data);
	    jmp_buf_index--;
		return 1;
	}
	return 0;
}

void PlatformSpecificLongJmp()
{
	jmp_buf_index--;
	longjmp(test_exit_jmp_buf[jmp_buf_index], 1);
}

void PlatformSpecificRestoreJumpBuffer()
{
	jmp_buf_index--;
}

void PlatformSpecificRunTestInASeperateProcess(UtestShell* shell, TestPlugin* plugin, TestResult* result)
{
   printf("-p doesn't work on this platform as it is not implemented. Running inside the process\b");
   shell->runOneTest(plugin, *result);
}

TestOutput::WorkingEnvironment PlatformSpecificGetWorkingEnvironment()
{
	return TestOutput::vistualStudio;
}

///////////// Time in millis

static long TimeInMillisImplementation()
{
    return timeGetTime();
}

static long (*timeInMillisFp) () = TimeInMillisImplementation;

long GetPlatformSpecificTimeInMillis()
{
	return timeInMillisFp();
}

void SetPlatformSpecificTimeInMillisMethod(long (*platformSpecific) ())
{
	timeInMillisFp = (platformSpecific == 0) ? TimeInMillisImplementation : platformSpecific;
}

///////////// Time in String

static const char* TimeStringImplementation()
{
	time_t the_time = time(NULL);
	struct tm the_local_time;
	static char dateTime[80];
	localtime_s(&the_local_time, &the_time);
	strftime(dateTime, 80, "%Y-%m-%dT%H:%M:%S", &the_local_time);
	return dateTime;
}

static const char* (*timeStringFp) () = TimeStringImplementation;

const char* GetPlatformSpecificTimeString()
{
	return timeStringFp();
}

void SetPlatformSpecificTimeStringMethod(const char* (*platformMethod) ())
{
	timeStringFp = (platformMethod == 0) ? TimeStringImplementation : platformMethod;
}

////// taken from gcc

int PlatformSpecificAtoI(const char*str)
{
   return atoi(str);
}

size_t PlatformSpecificStrLen(const char* str)
{
   return strlen(str);
}

char* PlatformSpecificStrNCpy(char* s1, const char* s2, size_t size)
{
   return strncpy(s1, s2, size);
}

int PlatformSpecificStrCmp(const char* s1, const char* s2)
{
   return strcmp(s1, s2);
}

int PlatformSpecificStrNCmp(const char* s1, const char* s2, size_t size)
{
   return strncmp(s1, s2, size);
}
char* PlatformSpecificStrStr(const char* s1, const char* s2)
{
   return (char*) strstr(s1, s2);
}

int PlatformSpecificVSNprintf(char *str, size_t size, const char* format, va_list args)
{
	char* buf = 0;
	size_t sizeGuess = size;

	int result = _vsnprintf( str, size, format, args);
	str[size-1] = 0;
	while (result == -1)
	{
		if (buf != 0)
			free(buf);
		sizeGuess += 10;
		buf = (char*)malloc(sizeGuess);
		result = _vsnprintf( buf, sizeGuess, format, args);
	}

	if (buf != 0)
		free(buf);
	return result;

}

PlatformSpecificFile PlatformSpecificFOpen(const char* filename, const char* flag)
{
   return fopen(filename, flag);
}

void PlatformSpecificFPuts(const char* str, PlatformSpecificFile file)
{
   fputs(str, (FILE*)file);
}

void PlatformSpecificFClose(PlatformSpecificFile file)
{
   fclose((FILE*)file);
}

void PlatformSpecificFlush()
{
  fflush(stdout);
}

int PlatformSpecificPutchar(int c)
{
  return putchar(c);
}

void* PlatformSpecificMalloc(size_t size)
{
   return malloc(size);
}

void* PlatformSpecificRealloc (void* memory, size_t size)
{
   return realloc(memory, size);
}

void PlatformSpecificFree(void* memory)
{
   free(memory);
}

void* PlatformSpecificMemCpy(void* s1, const void* s2, size_t size)
{
   return memcpy(s1, s2, size);
}

void* PlatformSpecificMemset(void* mem, int c, size_t size)
{
	return memset(mem, c, size);
}

double PlatformSpecificFabs(double d)
{
   return fabs(d);
}

int PlatformSpecificIsNan(double d)
{
	return _isnan(d);
}

int PlatformSpecificVSNprintf(char *str, unsigned int size, const char* format, void* args)
{
   return _vsnprintf( str, size, format, (va_list) args);
}

char PlatformSpecificToLower(char c)
{
	return tolower(c);
}

<|endoftext|>


<commit_before>// Copyright (c) 2017 Andrey Valyaev
//
// This software may be modified and distributed under the terms
// of the MIT license.  See the LICENSE file for details.

#include "KeyIterTest.h"
#include <list>
#include <2out/ReprPrintable.h>
#include <2out/TestEqual.h>
#include <2out/TestNamed.h>
#include <kuznyechik/BlkRaw.h>
#include <kuznyechik/KeyDataString.h>
#include <kuznyechik/KeyIter.h>

using namespace std;
using namespace oout;
using namespace kuznyechik;

template<typename KI>
class ReprKeyIter final : public Representation {
public:
	explicit ReprKeyIter(const shared_ptr<const Key::Data> &key)
		: ReprKeyIter(make_unique<KI>(key))
	{
	}

	explicit ReprKeyIter(const shared_ptr<const KI> &key_iter)
		: key_iter(key_iter)
	{
	}

	string asString() const override {
		return ReprPrintable<BlkRaw>(key_iter->value()).asString();
	}
private:
	const shared_ptr<const KI> key_iter;
};

KeyIterTest::KeyIterTest()
	: key_data(
		make_unique<KeyDataString>(
			"8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef"
		)
	  ),
	  tests(
		make_unique<TestNamed>(
			__func__,
			make_shared<TestNamed>(
				"R3412_A14_K1",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter1>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x0011223344556677, 0x8899aabbccddeeff)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K2",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter2>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x0123456789abcdef, 0xfedcba9876543210)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K3",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter3>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x228d6aef8cc78c44, 0xdb31485315694343)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K4",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter4>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x15ebadc40a9ffd04, 0x3d4553d8e9cfec68)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K5",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter5>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0xd3e59246f429f1ac, 0x57646468c44a5e28)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K6",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter6>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0xb532e82834da581b, 0xbd079435165c6432)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K7",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter7>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x705727265a0098b1, 0x51e640757e8745de)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K8",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter8>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0xd72a91a22286f984, 0x5a7925017b9fdd3e)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K9",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter9>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0xa5f32f73cdb6e517, 0xbb44e25378c73123)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K10",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter10>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x755dbaa88e4a4043, 0x72e9dd7416bcf45b)
					)
				)
			)
		)
	)
{
}

unique_ptr<const Result> KeyIterTest::result() const
{
	return tests->result();
}
<commit_msg>#173: Pointers in ReprKeyIter<commit_after>// Copyright (c) 2017 Andrey Valyaev
//
// This software may be modified and distributed under the terms
// of the MIT license.  See the LICENSE file for details.

#include "KeyIterTest.h"
#include <list>
#include <2out/ReprPrintable.h>
#include <2out/TestEqual.h>
#include <2out/TestNamed.h>
#include <kuznyechik/BlkRaw.h>
#include <kuznyechik/KeyDataString.h>
#include <kuznyechik/KeyIter.h>

using namespace std;
using namespace oout;
using namespace kuznyechik;

template<typename KI>
class ReprKeyIter final : public Representation {
public:
	explicit ReprKeyIter(const shared_ptr<const Key::Data> &key)
		: ReprKeyIter(make_shared<KI>(key))
	{
	}

	explicit ReprKeyIter(const shared_ptr<const KI> &key_iter)
		: key_iter(key_iter)
	{
	}

	string asString() const override {
		return ReprPrintable<BlkRaw>(key_iter->value()).asString();
	}
private:
	const shared_ptr<const KI> key_iter;
};

KeyIterTest::KeyIterTest()
	: key_data(
		make_unique<KeyDataString>(
			"8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef"
		)
	  ),
	  tests(
		make_unique<TestNamed>(
			__func__,
			make_shared<TestNamed>(
				"R3412_A14_K1",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter1>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x0011223344556677, 0x8899aabbccddeeff)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K2",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter2>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x0123456789abcdef, 0xfedcba9876543210)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K3",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter3>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x228d6aef8cc78c44, 0xdb31485315694343)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K4",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter4>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x15ebadc40a9ffd04, 0x3d4553d8e9cfec68)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K5",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter5>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0xd3e59246f429f1ac, 0x57646468c44a5e28)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K6",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter6>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0xb532e82834da581b, 0xbd079435165c6432)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K7",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter7>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x705727265a0098b1, 0x51e640757e8745de)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K8",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter8>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0xd72a91a22286f984, 0x5a7925017b9fdd3e)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K9",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter9>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0xa5f32f73cdb6e517, 0xbb44e25378c73123)
					)
				)
			),
			make_shared<TestNamed>(
				"R3412_A14_K10",
				make_shared<TestEqual>(
					make_unique<ReprKeyIter<KeyIter10>>(key_data),
					make_unique<ReprPrintable<BlkRaw>>(
						BlkRaw(0x755dbaa88e4a4043, 0x72e9dd7416bcf45b)
					)
				)
			)
		)
	)
{
}

unique_ptr<const Result> KeyIterTest::result() const
{
	return tests->result();
}
<|endoftext|>


<commit_before>//
// Created by erik on 9/18/16.
//

#include "GameObject.h"
#include "Starship.h"
#include <cmath>
#include <algorithm>
#include "components/ProjectileWeapon.h"
#include "components/ShieldGenerator.h"
#include "components/Engine.h"
#include "components/FuelTank.h"
#include "components/LifeSupport.h"
#include "SubSystems.h"
#include <boost/property_tree/ptree.hpp>
#include <iostream>
#include "components/PowerPlant.h"

using namespace spatacs;
using namespace core;

ShipData::ShipData(std::uint64_t team, std::string name) : mTeam(team), mName( std::move(name) )
{

}

Starship::Starship()
{

}
Starship::Starship(std::uint64_t team, std::string name, const boost::property_tree::ptree& data) :
        ShipData( team, std::move(name) ),
        mSubSystems( std::make_unique<SubSystems>(data) )
{
}

Starship::~Starship() {

}

void Starship::onStep()
{
    mEnergyProduced = mSubSystems->produceEnergy();
    mEnergyUsed     = mSubSystems->distributeEnergy(0);

    for(auto& c : mSubSystems->mCompPtrs)
    {
        c->onStep(*this);
    }
}

const Engine& Starship::engine() const
{
    return *mSubSystems->mEngine;
}

Engine& Starship::getEngine()
{
    return *mSubSystems->mEngine;
}

std::size_t Starship::weapon_count() const
{
    return mSubSystems->mArmament.size();
}

const IWeapon& Starship::weapon( std::size_t id ) const
{
    return *mSubSystems->mArmament.at(id);
}

IWeapon& Starship::getWeapon( std::size_t id )
{
    return *mSubSystems->mArmament.at(id);
}

bool Starship::alive() const
{
    return mHitPoints > 0;
}

Starship::Starship(const Starship& other):
    GameObject( other ),
    ShipData( other ),
    mSubSystems( std::make_unique<SubSystems>( *other.mSubSystems ) )
{

}

Starship& Starship::operator=(const Starship& other)
{
    *this = Starship(other);
    return *this;
}

ShieldGenerator& Starship::getShield()
{
    return *mSubSystems->mShield;
}

const ShieldGenerator& Starship::shield() const
{
    return *mSubSystems->mShield;
}

Starship::Starship(Starship&& o):
    GameObject(o), ShipData(o),
    mSubSystems( std::move(o.mSubSystems) )
{

}

Starship& Starship::operator=( Starship&& o )
{
    GameObject::operator=( o );
    ShipData::operator=( o );
    mSubSystems = std::move(o.mSubSystems);
    return *this;
}

SystemStatus Starship::shield_strength() const
{
    return SystemStatus{ shield().shield(), shield().max_shield() };
}

SystemStatus Starship::hull_status() const {
    return SystemStatus{armour(), max_armour()};
}

void Starship::dealDamage(float dmg)
{
    auto dmg_target = rand() % mSubSystems->mCompPtrs.size();
    auto leftover = mSubSystems->mCompPtrs[dmg_target]->dealDamage( dmg );
    mHitPoints -= leftover;
}

length_t spatacs::core::distance(const Starship& s1, const Starship& s2)
{
    return length(s1.position() - s2.position());
}

uint64_t ShipData::team() const
{
    return mTeam;
}

const std::string& ShipData::name() const
{
    return mName;
}

double ShipData::max_hp() const
{
    return mMaxHitPoints;
}

double ShipData::producedEnergy() const
{
    return mEnergyProduced;
}

double ShipData::usedEnergy() const
{
    return mEnergyUsed;
}

double ShipData::hp() const
{
    return mHitPoints;
}

double ShipData::armour() const
{
    return mCurArmour;
}

double ShipData::max_armour() const
{
    return mMaxArmour;
}

void ShipData::setArmour(double new_value)
{
    mCurArmour = new_value;
}

const FuelTank& Starship::tank() const
{
    return *mSubSystems->mFuelTank;
}

FuelTank& Starship::getTank()
{
    return *mSubSystems->mFuelTank;
}

void ShipData::setHP(double hp)
{
    mHitPoints = hp;
}

length_t ShipData::radius() const
{
    return mRadius;
}

void ShipData::setRadius(length_t radius)
{
    mRadius = radius;
}
<commit_msg>bugfix<commit_after>//
// Created by erik on 9/18/16.
//

#include "GameObject.h"
#include "Starship.h"
#include <cmath>
#include <algorithm>
#include "components/ProjectileWeapon.h"
#include "components/ShieldGenerator.h"
#include "components/Engine.h"
#include "components/FuelTank.h"
#include "components/LifeSupport.h"
#include "SubSystems.h"
#include <boost/property_tree/ptree.hpp>
#include <iostream>
#include "components/PowerPlant.h"

using namespace spatacs;
using namespace core;

ShipData::ShipData(std::uint64_t team, std::string name) : mTeam(team), mName( std::move(name) )
{

}

Starship::Starship()
{

}
Starship::Starship(std::uint64_t team, std::string name, const boost::property_tree::ptree& data) :
        ShipData( team, std::move(name) ),
        mSubSystems( std::make_unique<SubSystems>(data) )
{
}

Starship::~Starship() {

}

void Starship::onStep()
{
    mEnergyProduced = mSubSystems->produceEnergy();
    mEnergyUsed     = mSubSystems->distributeEnergy(mEnergyProduced);

    for(auto& c : mSubSystems->mCompPtrs)
    {
        c->onStep(*this);
    }
}

const Engine& Starship::engine() const
{
    return *mSubSystems->mEngine;
}

Engine& Starship::getEngine()
{
    return *mSubSystems->mEngine;
}

std::size_t Starship::weapon_count() const
{
    return mSubSystems->mArmament.size();
}

const IWeapon& Starship::weapon( std::size_t id ) const
{
    return *mSubSystems->mArmament.at(id);
}

IWeapon& Starship::getWeapon( std::size_t id )
{
    return *mSubSystems->mArmament.at(id);
}

bool Starship::alive() const
{
    return mHitPoints > 0;
}

Starship::Starship(const Starship& other):
    GameObject( other ),
    ShipData( other ),
    mSubSystems( std::make_unique<SubSystems>( *other.mSubSystems ) )
{

}

Starship& Starship::operator=(const Starship& other)
{
    *this = Starship(other);
    return *this;
}

ShieldGenerator& Starship::getShield()
{
    return *mSubSystems->mShield;
}

const ShieldGenerator& Starship::shield() const
{
    return *mSubSystems->mShield;
}

Starship::Starship(Starship&& o):
    GameObject(o), ShipData(o),
    mSubSystems( std::move(o.mSubSystems) )
{

}

Starship& Starship::operator=( Starship&& o )
{
    GameObject::operator=( o );
    ShipData::operator=( o );
    mSubSystems = std::move(o.mSubSystems);
    return *this;
}

SystemStatus Starship::shield_strength() const
{
    return SystemStatus{ shield().shield(), shield().max_shield() };
}

SystemStatus Starship::hull_status() const {
    return SystemStatus{armour(), max_armour()};
}

void Starship::dealDamage(float dmg)
{
    auto dmg_target = rand() % mSubSystems->mCompPtrs.size();
    auto leftover = mSubSystems->mCompPtrs[dmg_target]->dealDamage( dmg );
    mHitPoints -= leftover;
}

length_t spatacs::core::distance(const Starship& s1, const Starship& s2)
{
    return length(s1.position() - s2.position());
}

uint64_t ShipData::team() const
{
    return mTeam;
}

const std::string& ShipData::name() const
{
    return mName;
}

double ShipData::max_hp() const
{
    return mMaxHitPoints;
}

double ShipData::producedEnergy() const
{
    return mEnergyProduced;
}

double ShipData::usedEnergy() const
{
    return mEnergyUsed;
}

double ShipData::hp() const
{
    return mHitPoints;
}

double ShipData::armour() const
{
    return mCurArmour;
}

double ShipData::max_armour() const
{
    return mMaxArmour;
}

void ShipData::setArmour(double new_value)
{
    mCurArmour = new_value;
}

const FuelTank& Starship::tank() const
{
    return *mSubSystems->mFuelTank;
}

FuelTank& Starship::getTank()
{
    return *mSubSystems->mFuelTank;
}

void ShipData::setHP(double hp)
{
    mHitPoints = hp;
}

length_t ShipData::radius() const
{
    return mRadius;
}

void ShipData::setRadius(length_t radius)
{
    mRadius = radius;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
#define ANSI_FG_BLACK "\x1b[30m"
#define ANSI_FG_RED "\x1b[31m"
#define ANSI_FG_GREEN "\x1b[32m"
#define ANSI_FG_YELLOW "\x1b[33m"
#define ANSI_FG_BLUE "\x1b[34m"
#define ANSI_FG_MAGENTA "\x1b[35m"
#define ANSI_FG_CYAN "\x1b[36m"
#define ANSI_FG_WHITE "\x1b[37m"

#define ANSI_BG_RED "\x1b[41m"
#define ANSI_BG_GREEN "\x1b[42m"
#define ANSI_BG_YELLOW "\x1b[43m"
#define ANSI_BG_BLUE "\x1b[44m"
#define ANSI_BG_MAGENTA "\x1b[45m"
#define ANSI_BG_CYAN "\x1b[46m"
#define ANSI_BG_WHITE "\x1b[47m"
#define ANSI_RESET "\x1b[0m"

TestResult::TestResult() : compare(true){};

TestResult::TestResult(bool compare_, std::string name_)
    : compare(compare_), fileName(name_ + ".xml"){};

TestResult::TestResult(bool compare_, std::string name_, std::size_t n_,
                       std::size_t nev_, std::size_t nex_, std::size_t deg_,
                       double tol_, char mode_, char opt_, bool sequence)
    : compare(compare_) {
  std::ostringstream fileNameBuilder(std::ostringstream::ate);
  fileNameBuilder << name_ << "_" << n_ << "_" << nev_ << "_" << nex_ << "_"
                  << deg_ << "_" << tol_ << "_" << mode_ << "_" << opt_;

  if (sequence) fileNameBuilder << "_seq";

  fileNameBuilder << ".xml";
  fileName = fileNameBuilder.str();
};

std::string TestResult::name() { return this->fileName; }

void TestResult::done() {
  // either save or compare
  if (!compare)
    save();
  else {
    // load reference
    loadAndCompare();
  }
}
void TestResult::save() {
  std::ofstream ofs(this->name().c_str());
  boost::archive::xml_oarchive oa(ofs);

#ifdef __INTEL_COMPILER
  oa << BOOST_SERIALIZATION_NVP(this);
#else
  oa << BOOST_SERIALIZATION_NVP(*this);
#endif
}

void TestResult::loadAndCompare() {
  // construct object
  TestResult ref;
  std::ifstream ifs(this->name().c_str());

  try {
    boost::archive::xml_iarchive ia(ifs);
    ia >> BOOST_SERIALIZATION_NVP(ref);
  } catch (std::exception& e) {
    std::cout << e.what() << std::endl;

    std::cout << ANSI_FG_BLACK << ANSI_BG_YELLOW << "File not found, writing"
              << std::endl
              << ANSI_RESET << ANSI_RESET
              << "Consider creating the test profile for the whole sequence"
              << std::endl;

    save();
    return;
  }

  compareMembers(ref);
}

void TestResult::compareMembers(TestResult& ref) {
  std::size_t tests = 0;
  std::size_t fails = 0;

  if (iterationResults.size() > ref.iterationResults.size())
    std::cout << "Reference does not contain full sequence!" << std::endl
              << "Consider creating the test profile for the whole sequence"
              << std::endl;

  for (auto it = 0;
       it < std::min(iterationResults.size(), ref.iterationResults.size());
       ++it)
    iterationResults[it].compareMembers(ref.iterationResults[it], tests, fails);
  reportResult(tests, fails);
}

void TestResult::reportResult(std::size_t tests, std::size_t fails) {
  if (fails == 0)
    std::cout << ANSI_BG_GREEN;
  else
    std::cout << ANSI_BG_RED;
  std::cout << ANSI_FG_BLACK << "PASSED\t" << (tests - fails) << " / " << tests
            << ANSI_RESET << std::endl;
}
<commit_msg>Fixes error with boost serialization on GCC<commit_after>/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
#define ANSI_FG_BLACK "\x1b[30m"
#define ANSI_FG_RED "\x1b[31m"
#define ANSI_FG_GREEN "\x1b[32m"
#define ANSI_FG_YELLOW "\x1b[33m"
#define ANSI_FG_BLUE "\x1b[34m"
#define ANSI_FG_MAGENTA "\x1b[35m"
#define ANSI_FG_CYAN "\x1b[36m"
#define ANSI_FG_WHITE "\x1b[37m"

#define ANSI_BG_RED "\x1b[41m"
#define ANSI_BG_GREEN "\x1b[42m"
#define ANSI_BG_YELLOW "\x1b[43m"
#define ANSI_BG_BLUE "\x1b[44m"
#define ANSI_BG_MAGENTA "\x1b[45m"
#define ANSI_BG_CYAN "\x1b[46m"
#define ANSI_BG_WHITE "\x1b[47m"
#define ANSI_RESET "\x1b[0m"

TestResult::TestResult() : compare(true){};

TestResult::TestResult(bool compare_, std::string name_)
    : compare(compare_), fileName(name_ + ".xml"){};

TestResult::TestResult(bool compare_, std::string name_, std::size_t n_,
                       std::size_t nev_, std::size_t nex_, std::size_t deg_,
                       double tol_, char mode_, char opt_, bool sequence)
    : compare(compare_) {
  std::ostringstream fileNameBuilder(std::ostringstream::ate);
  fileNameBuilder << name_ << "_" << n_ << "_" << nev_ << "_" << nex_ << "_"
                  << deg_ << "_" << tol_ << "_" << mode_ << "_" << opt_;

  if (sequence) fileNameBuilder << "_seq";

  fileNameBuilder << ".xml";
  fileName = fileNameBuilder.str();
};

std::string TestResult::name() { return this->fileName; }

void TestResult::done() {
  // either save or compare
  if (!compare)
    save();
  else {
    // load reference
    loadAndCompare();
  }
}
void TestResult::save() {
  std::ofstream ofs(this->name().c_str());
  boost::archive::xml_oarchive oa(ofs);

#ifdef __INTEL_COMPILER
  oa << boost::serialization::make_nvp("TestResult", this);
#elif defined(__GNUC__) || defined(__GNUG__)
  oa << boost::serialization::make_nvp("TestResult", *this);
#else
  oa << boost::serialization::make_nvp("TestResult", *this);
#endif
}

void TestResult::loadAndCompare() {
  // construct object
  TestResult ref;
  std::ifstream ifs(this->name().c_str());

  try {
    boost::archive::xml_iarchive ia(ifs);
    ia >> BOOST_SERIALIZATION_NVP(ref);
  } catch (std::exception& e) {
    std::cout << e.what() << std::endl;

    std::cout << ANSI_FG_BLACK << ANSI_BG_YELLOW << "File not found, writing"
              << std::endl
              << ANSI_RESET << ANSI_RESET
              << "Consider creating the test profile for the whole sequence"
              << std::endl;

    save();
    return;
  }

  compareMembers(ref);
}

void TestResult::compareMembers(TestResult& ref) {
  std::size_t tests = 0;
  std::size_t fails = 0;

  if (iterationResults.size() > ref.iterationResults.size())
    std::cout << "Reference does not contain full sequence!" << std::endl
              << "Consider creating the test profile for the whole sequence"
              << std::endl;

  for (auto it = 0;
       it < std::min(iterationResults.size(), ref.iterationResults.size());
       ++it)
    iterationResults[it].compareMembers(ref.iterationResults[it], tests, fails);
  reportResult(tests, fails);
}

void TestResult::reportResult(std::size_t tests, std::size_t fails) {
  if (fails == 0)
    std::cout << ANSI_BG_GREEN;
  else
    std::cout << ANSI_BG_RED;
  std::cout << ANSI_FG_BLACK << "PASSED\t" << (tests - fails) << " / " << tests
            << ANSI_RESET << std::endl;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by Till Adam <adam@kde.org>                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/
#include <QDebug>

#include "akonadi.h"
#include "akonadiconnection.h"
#include "storagebackend.h"
#include "storage/datastore.h"
#include "storage/entity.h"

#include "list.h"
#include "response.h"

using namespace Akonadi;

List::List(): Handler()
{
}

List::~List()
{
}

bool List::handleLine(const QByteArray& line )
{
    // parse out the reference name and mailbox name
    int startOfCommand = line.indexOf( ' ' ) + 1;
    int startOfReference = line.indexOf( '"', startOfCommand ) + 1;
    int endOfReference = line.indexOf( '"', startOfReference );
    int startOfMailbox = line.indexOf( ' ', endOfReference ) + 1;
    QByteArray reference = line.mid( startOfReference, endOfReference - startOfReference );
    QByteArray mailbox = line.right( line.size() - startOfMailbox );
    //qDebug() << "reference:" << reference << "mailbox:" << mailbox << endl;
    if ( reference.isEmpty() )
        reference = connection()->selectedCollection();

    Response response;
    response.setUntagged();

    Resource resource;
    CollectionList collections = connection()->storageBackend()->listCollections( reference, mailbox );
    CollectionListIterator it(collections);
    while ( it.hasNext() ) {
        Collection c = it.next();
        QString list( "LIST ");
        list += "(";
        if ( c.isNoSelect() )
            list += "\\Noselect ";
        if ( c.isNoInferiors() )
            list += "\\Noinferiors ";
        list += ") ";
        list += "\"/\" \""; // FIXME delimiter
        list += c.identifier();
        list += "\" ";
        response.setString( list.toLatin1() );
        emit responseAvailable( response );
    }
    response.setSuccess();
    response.setTag( tag() );
    response.setString( "List completed" );
    emit responseAvailable( response );
    deleteLater();
    return true;
}

<commit_msg>Implement % and * for LIST.<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by Till Adam <adam@kde.org>                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/
#include <QDebug>

#include "akonadi.h"
#include "akonadiconnection.h"
#include "storagebackend.h"
#include "storage/datastore.h"
#include "storage/entity.h"

#include "list.h"
#include "response.h"

using namespace Akonadi;

List::List(): Handler()
{
}

List::~List()
{
}

bool List::handleLine(const QByteArray& line )
{
    // parse out the reference name and mailbox name
    int startOfCommand = line.indexOf( ' ' ) + 1;
    int startOfReference = line.indexOf( '"', startOfCommand ) + 1;
    int endOfReference = line.indexOf( '"', startOfReference );
    int startOfMailbox = line.indexOf( ' ', endOfReference ) + 1;
    QByteArray reference = line.mid( startOfReference, endOfReference - startOfReference );
    QByteArray mailbox = line.right( line.size() - startOfMailbox );
    //qDebug() << "reference:" << reference << "mailbox:" << mailbox << endl;
    if ( reference.isEmpty() )
        reference = connection()->selectedCollection();

    Response response;
    response.setUntagged();

    Resource resource;
    DataStore *db = connection()->storageBackend();
    CollectionList collections = db->listCollections( reference, mailbox );
    CollectionListIterator it(collections);
    while ( it.hasNext() ) {
        Collection c = it.next();
        QString list( "LIST ");
        list += "(";
        if ( c.isNoSelect() )
            list += "\\Noselect ";
        if ( c.isNoInferiors() )
            list += "\\Noinferiors ";
        list += ") ";
        list += "\"/\" \""; // FIXME delimiter
        list += c.identifier();
        list += "\" ";
        response.setString( list.toLatin1() );
        emit responseAvailable( response );
    }
    response.setSuccess();
    response.setTag( tag() );
    response.setString( "List completed" );
    emit responseAvailable( response );
    deleteLater();
    return true;
}

<|endoftext|>


<commit_before>
/*
    pbrt source code Copyright(c) 1998-2010 Matt Pharr and Greg Humphreys.

    This file is part of pbrt.

    pbrt is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.  Note that the text contents of
    the book "Physically Based Rendering" are *not* licensed under the
    GNU GPL.

    pbrt is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 */

// core/material.cpp*
#include "material.h"
#include "primitive.h"
#include "texture.h"
#include "spectrum.h"
#include "reflection.h"

// Material Method Definitions
Material::~Material() {
}

void Material::Bump(const Reference<Texture<float> > &d,
                    const DifferentialGeometry &dgGeom,
                    const DifferentialGeometry &dgs,
                    DifferentialGeometry *dgBump) {
    // Compute offset positions and evaluate displacement texture
    DifferentialGeometry dgEval = dgs;

    // Shift _dgEval_ _du_ in the $u$ direction
    float du = .5f * (fabsf(dgs.dudx) + fabsf(dgs.dudy));
    if (du == 0.f) du = .01f;
    dgEval.p = dgs.p + du * dgs.dpdu;
    dgEval.u = dgs.u + du;
    dgEval.nn = Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) +
                          du * dgs.dndu);
    float uDisplace = d->Evaluate(dgEval);
    if (isnan(uDisplace))
        uDisplace = d->Evaluate(dgEval);

    // Shift _dgEval_ _dv_ in the $v$ direction
    float dv = .5f * (fabsf(dgs.dvdx) + fabsf(dgs.dvdy));
    if (dv == 0.f) dv = .01f;
    dgEval.p = dgs.p + dv * dgs.dpdv;
    dgEval.u = dgs.u;
    dgEval.v = dgs.v + dv;
    dgEval.nn = Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) +
                          dv * dgs.dndv);
    float vDisplace = d->Evaluate(dgEval);
    float displace = d->Evaluate(dgs);

    // Compute bump-mapped differential geometry
    *dgBump = dgs;
    dgBump->dpdu = dgs.dpdu + (uDisplace - displace) / du * Vector(dgs.nn) +
                   displace * Vector(dgs.dndu);
    dgBump->dpdv = dgs.dpdv + (vDisplace - displace) / dv * Vector(dgs.nn) +
                   displace * Vector(dgs.dndv);
    dgBump->nn = Normal(Normalize(Cross(dgBump->dpdu, dgBump->dpdv)));
    if (dgs.shape->ReverseOrientation ^ dgs.shape->TransformSwapsHandedness)
        dgBump->nn *= -1.f;

    // Orient shading normal to match geometric normal
    dgBump->nn = Faceforward(dgBump->nn, dgGeom.nn);
}

<commit_msg>Remove debugging code.<commit_after>
/*
    pbrt source code Copyright(c) 1998-2010 Matt Pharr and Greg Humphreys.

    This file is part of pbrt.

    pbrt is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.  Note that the text contents of
    the book "Physically Based Rendering" are *not* licensed under the
    GNU GPL.

    pbrt is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 */

// core/material.cpp*
#include "material.h"
#include "primitive.h"
#include "texture.h"
#include "spectrum.h"
#include "reflection.h"

// Material Method Definitions
Material::~Material() {
}

void Material::Bump(const Reference<Texture<float> > &d,
                    const DifferentialGeometry &dgGeom,
                    const DifferentialGeometry &dgs,
                    DifferentialGeometry *dgBump) {
    // Compute offset positions and evaluate displacement texture
    DifferentialGeometry dgEval = dgs;

    // Shift _dgEval_ _du_ in the $u$ direction
    float du = .5f * (fabsf(dgs.dudx) + fabsf(dgs.dudy));
    if (du == 0.f) du = .01f;
    dgEval.p = dgs.p + du * dgs.dpdu;
    dgEval.u = dgs.u + du;
    dgEval.nn = Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) +
                          du * dgs.dndu);
    float uDisplace = d->Evaluate(dgEval);

    // Shift _dgEval_ _dv_ in the $v$ direction
    float dv = .5f * (fabsf(dgs.dvdx) + fabsf(dgs.dvdy));
    if (dv == 0.f) dv = .01f;
    dgEval.p = dgs.p + dv * dgs.dpdv;
    dgEval.u = dgs.u;
    dgEval.v = dgs.v + dv;
    dgEval.nn = Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) +
                          dv * dgs.dndv);
    float vDisplace = d->Evaluate(dgEval);
    float displace = d->Evaluate(dgs);

    // Compute bump-mapped differential geometry
    *dgBump = dgs;
    dgBump->dpdu = dgs.dpdu + (uDisplace - displace) / du * Vector(dgs.nn) +
                   displace * Vector(dgs.dndu);
    dgBump->dpdv = dgs.dpdv + (vDisplace - displace) / dv * Vector(dgs.nn) +
                   displace * Vector(dgs.dndv);
    dgBump->nn = Normal(Normalize(Cross(dgBump->dpdu, dgBump->dpdv)));
    if (dgs.shape->ReverseOrientation ^ dgs.shape->TransformSwapsHandedness)
        dgBump->nn *= -1.f;

    // Orient shading normal to match geometric normal
    dgBump->nn = Faceforward(dgBump->nn, dgGeom.nn);
}

<|endoftext|>


<commit_before>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by Robert E. Smith, 2013.

    This file is part of MRtrix.

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

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "command.h"
#include "progressbar.h"

#include "image/buffer.h"
#include "image/buffer_sparse.h"
#include "image/loop.h"
#include "image/voxel.h"

#include "image/sparse/fixel_metric.h"
#include "image/sparse/voxel.h"

#include "math/SH.h"

using namespace MR;
using namespace App;

using Image::Sparse::FixelMetric;

const char* operations[] = {
  "sum",
  "count",
  NULL
};

void usage ()
{

  DESCRIPTION
  + "convert a fixel-based sparse-data image into a scalar image. Output either the sum of fixel values within a voxel, or the fixel count";

  ARGUMENTS
  + Argument ("fixel_in",  "the input sparse fixel image.").type_image_in ()
  + Argument ("operation", "the operation to apply, one of: " + join(operations, ", ") + ".").type_choice (operations)
  + Argument ("image_out", "the output scalar image.").type_image_out ();

}

void run ()
{
  Image::Header H_in (argument[0]);
  Image::BufferSparse<FixelMetric> fixel_data (H_in);
  Image::BufferSparse<FixelMetric>::voxel_type voxel (fixel_data);

  const size_t num_inputs = argument.size() - 2;
  const int op = argument[num_inputs];

  Image::Header H_out (H_in);
  if (op)
    H_out.datatype() = DataType::UInt8;
  else
    H_out.datatype() = DataType::Float32;

  Image::Buffer<float> out_data (argument[2], H_out);
  Image::Buffer<float>::voxel_type out (out_data);

  Image::LoopInOrder loop (voxel, "converting sparse fixel data to scalar image... ");
  for (loop.start (voxel, out); loop.ok(); loop.next (voxel, out)) {
    if (op) {
      out.value() = voxel.value().size();
    } else {
      float sum = 0;
      for (size_t fixel = 0; fixel != voxel.value().size(); ++fixel)
        sum += voxel.value()[fixel].value;
      out.value() = sum;
    }
  }
}

<commit_msg>fixel2voxel: added command to output all fixel values<commit_after>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by Robert E. Smith, 2013.

    This file is part of MRtrix.

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

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "command.h"
#include "progressbar.h"

#include "image/buffer.h"
#include "image/buffer_sparse.h"
#include "image/loop.h"
#include "image/voxel.h"

#include "image/sparse/fixel_metric.h"
#include "image/sparse/voxel.h"

#include "math/SH.h"

using namespace MR;
using namespace App;

using Image::Sparse::FixelMetric;

const char* operations[] = {
  "sum",
  "count",
  "split",
  NULL
};

void usage ()
{

  DESCRIPTION
  + "convert a fixel-based sparse-data image into a scalar image. "
    "Output either the sum of fixel values within a voxel, the fixel count, "
    "or a set of 3D scalar images, one per fixel value.";

  ARGUMENTS
  + Argument ("fixel_in",  "the input sparse fixel image.").type_image_in ()
  + Argument ("operation", "the operation to apply, one of: " + join(operations, ", ") + ".").type_choice (operations)
  + Argument ("image_out", "the output scalar image.").type_image_out ();

}

void run ()
{
  Image::Header H_in (argument[0]);
  Image::BufferSparse<FixelMetric> fixel_data (H_in);
  Image::BufferSparse<FixelMetric>::voxel_type voxel (fixel_data);

  const int op = argument[1];

  Image::Header H_out (H_in);
  if (op == 1)
    H_out.datatype() = DataType::UInt8;
  else {
    H_out.datatype() = DataType::Float32;
    if (op == 2) {
      H_out.set_ndim (4);
      uint32_t max_count = 0;
      Image::LoopInOrder loop (voxel, "determining largest fixel count... ");
      for (loop.start (voxel); loop.ok(); loop.next (voxel))
        max_count = std::max (max_count, voxel.value().size());
      if (max_count == 0)
        throw Exception ("fixel image is empty");
      H_out.dim(3) = max_count;
    }
  }

  Image::Buffer<float> out_data (argument[2], H_out);
  Image::Buffer<float>::voxel_type out (out_data);

  Image::LoopInOrder loop (voxel, "converting sparse fixel data to scalar image... ");
  for (loop.start (voxel, out); loop.ok(); loop.next (voxel, out)) {
    switch (op) {
      case 0: // sum
        {
          float sum = 0.0;
          for (size_t fixel = 0; fixel != voxel.value().size(); ++fixel)
            sum += voxel.value()[fixel].value;
          out.value() = sum;
        }
        break;
      case 1: // count
        out.value() = voxel.value().size();
        break;
      case 2: // split
        out[3] = 0;
        for (size_t fixel = 0; fixel != voxel.value().size(); ++fixel, ++out[3])
          out.value() = voxel.value()[fixel].value;

    }
  }
}

<|endoftext|>


<commit_before>#include "Course.h"

int Course::getEndTime(){
	return 1500;
}

int Course::getStartTime(){

}<commit_msg>Course.it2 - pass: start time<commit_after>#include "Course.h"

int Course::getEndTime(){
	return 1500;
}

int Course::getStartTime(){
	return 1115;
}<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2020 The QXmpp developers
 *
 * Authors:
 *  Manjeet Dahiya
 *  Jeremy Lainé
 *
 * Source:
 *  https://github.com/qxmpp-project/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 */

#include "QXmppRosterIq.h"

#include "QXmppConstants_p.h"
#include "QXmppUtils.h"

#include <QDomElement>
#include <QSharedData>
#include <QXmlStreamWriter>

class QXmppRosterIqPrivate : public QSharedData
{
public:
    QList<QXmppRosterIq::Item> items;
    // XEP-0237 Roster Versioning
    QString version;
    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    bool mixAnnotate = false;
};

QXmppRosterIq::QXmppRosterIq()
    : d(new QXmppRosterIqPrivate)
{
}

QXmppRosterIq::QXmppRosterIq(const QXmppRosterIq &) = default;

QXmppRosterIq::~QXmppRosterIq() = default;

QXmppRosterIq &QXmppRosterIq::operator=(const QXmppRosterIq &) = default;

///
/// Adds an item to the roster IQ.
///
/// \param item
///
void QXmppRosterIq::addItem(const Item &item)
{
    d->items.append(item);
}

///
/// Returns the roster IQ's items.
///
QList<QXmppRosterIq::Item> QXmppRosterIq::items() const
{
    return d->items;
}

///
/// Returns the roster version of IQ.
///
/// \return version as a QString
///
/// \since QXmpp 1.0
///
QString QXmppRosterIq::version() const
{
    return d->version;
}

///
/// Sets the roster version of IQ.
///
/// \param version as a QString
///
/// \since QXmpp 1.0
///
void QXmppRosterIq::setVersion(const QString &version)
{
    d->version = version;
}

///
/// Whether to annotate which items are MIX channels.
///
/// \since QXmpp 1.3
///
bool QXmppRosterIq::mixAnnotate() const
{
    return d->mixAnnotate;
}

///
/// Sets whether to include which roster items are MIX channels. This MUST only
/// be enabled in get requests.
///
/// \since QXmpp 1.3
///
void QXmppRosterIq::setMixAnnotate(bool mixAnnotate)
{
    d->mixAnnotate = mixAnnotate;
}

/// \cond
bool QXmppRosterIq::isRosterIq(const QDomElement &element)
{
    return (element.firstChildElement(QStringLiteral("query")).namespaceURI() == ns_roster);
}

void QXmppRosterIq::parseElementFromChild(const QDomElement &element)
{
    QDomElement queryElement = element.firstChildElement(QStringLiteral("query"));
    setVersion(queryElement.attribute(QStringLiteral("ver")));

    QDomElement itemElement = queryElement.firstChildElement(QStringLiteral("item"));
    while (!itemElement.isNull()) {
        QXmppRosterIq::Item item;
        item.parse(itemElement);
        d->items.append(item);
        itemElement = itemElement.nextSiblingElement(QStringLiteral("item"));
    }

    QDomElement annotateElement = queryElement.firstChildElement(QStringLiteral("annotate"));
    setMixAnnotate(!annotateElement.isNull() && annotateElement.namespaceURI() == ns_mix_roster);
}

void QXmppRosterIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
{
    writer->writeStartElement(QStringLiteral("query"));
    writer->writeDefaultNamespace(ns_roster);

    // XEP-0237 roster versioning - If the server does not advertise support for roster versioning, the client MUST NOT include the 'ver' attribute.
    if (!version().isEmpty())
        writer->writeAttribute(QStringLiteral("ver"), version());

    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    if (d->mixAnnotate) {
        writer->writeStartElement(QStringLiteral("annotate"));
        writer->writeAttribute(QStringLiteral("xmlns"), ns_mix_roster);
        writer->writeEndElement();
    }

    for (int i = 0; i < d->items.count(); ++i)
        d->items.at(i).toXml(writer);
    writer->writeEndElement();
}
/// \endcond

class QXmppRosterIq::ItemPrivate : public QSharedData
{
public:
    ItemPrivate();

    QString bareJid;
    Item::SubscriptionType type;
    QString name;
    // can be subscribe/unsubscribe (attribute "ask")
    QString subscriptionStatus;
    QSet<QString> groups;
    bool approved;
    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    bool isMixChannel = false;
    QString mixParticipantId;
};

QXmppRosterIq::ItemPrivate::ItemPrivate()
    : type(QXmppRosterIq::Item::NotSet),
      approved(false)
{
}

///
/// Constructs a new roster entry.
///
QXmppRosterIq::Item::Item()
    : d(new ItemPrivate)
{
}

QXmppRosterIq::Item::Item(const QXmppRosterIq::Item &other) = default;

QXmppRosterIq::Item::~Item() = default;

QXmppRosterIq::Item &QXmppRosterIq::Item::operator=(const Item &other) = default;

///
/// Returns the bareJid of the roster entry.
///
/// \return bareJid as a QString
///
QString QXmppRosterIq::Item::bareJid() const
{
    return d->bareJid;
}

/// Sets the bareJid of the roster entry.
///
/// \param bareJid as a QString
///
void QXmppRosterIq::Item::setBareJid(const QString &bareJid)
{
    d->bareJid = bareJid;
}

///
/// Returns the groups of the roster entry.
///
/// \return QSet<QString> list of all the groups
///
QSet<QString> QXmppRosterIq::Item::groups() const
{
    return d->groups;
}

///
/// Sets the groups of the roster entry.
///
/// \param groups list of all the groups as a QSet<QString>
///
void QXmppRosterIq::Item::setGroups(const QSet<QString> &groups)
{
    d->groups = groups;
}

///
/// Returns the name of the roster entry.
///
/// \return name as a QString
///
QString QXmppRosterIq::Item::name() const
{
    return d->name;
}

///
/// Sets the name of the roster entry.
///
/// \param name as a QString
///
void QXmppRosterIq::Item::setName(const QString &name)
{
    d->name = name;
}

///
/// Returns the subscription status of the roster entry. It is the "ask"
/// attribute in the Roster IQ stanza. Its value can be "subscribe" or "unsubscribe"
/// or empty.
///
/// \return subscription status as a QString
///
QString QXmppRosterIq::Item::subscriptionStatus() const
{
    return d->subscriptionStatus;
}

///
/// Sets the subscription status of the roster entry. It is the "ask"
/// attribute in the Roster IQ stanza. Its value can be "subscribe" or "unsubscribe"
/// or empty.
///
/// \param status as a QString
///
void QXmppRosterIq::Item::setSubscriptionStatus(const QString &status)
{
    d->subscriptionStatus = status;
}

///
/// Returns the subscription type of the roster entry.
///
QXmppRosterIq::Item::SubscriptionType
QXmppRosterIq::Item::subscriptionType() const
{
    return d->type;
}

///
/// Sets the subscription type of the roster entry.
///
/// \param type
///
void QXmppRosterIq::Item::setSubscriptionType(SubscriptionType type)
{
    d->type = type;
}

///
/// Returns whether the item has a pre-approved presence subscription.
///
/// \since QXmpp 1.3
///
bool QXmppRosterIq::Item::isApproved() const
{
    return d->approved;
}

///
/// Sets whether the item has a pre-approved presence subscription.
///
/// This cannot be used to initiate a pre-approved subscription. For this
/// purpose the client must send a <presence/> stanza of type
/// \c subscribed to the user.
///
/// \since QXmpp 1.3
///
void QXmppRosterIq::Item::setIsApproved(bool approved)
{
    d->approved = approved;
}

QString QXmppRosterIq::Item::getSubscriptionTypeStr() const
{
    switch (d->type) {
    case NotSet:
        return "";
    case None:
        return "none";
    case Both:
        return "both";
    case From:
        return "from";
    case To:
        return "to";
    case Remove:
        return "remove";
    default: {
        qWarning("QXmppRosterIq::Item::getTypeStr(): invalid type");
        return "";
    }
    }
}

void QXmppRosterIq::Item::setSubscriptionTypeFromStr(const QString &type)
{
    if (type.isEmpty() && !type.isNull())  // TODO CHECK
        setSubscriptionType(NotSet);
    else if (type == QStringLiteral("none"))
        setSubscriptionType(None);
    else if (type == QStringLiteral("both"))
        setSubscriptionType(Both);
    else if (type == QStringLiteral("from"))
        setSubscriptionType(From);
    else if (type == QStringLiteral("to"))
        setSubscriptionType(To);
    else if (type == QStringLiteral("remove"))
        setSubscriptionType(Remove);
    else
        qWarning("QXmppRosterIq::Item::setTypeFromStr(): invalid type");
}

///
/// Returns whether this is a MIX channel.
///
/// \since QXmpp 1.3
///
bool QXmppRosterIq::Item::isMixChannel() const
{
    return d->isMixChannel;
}

///
/// Sets whether this is a MIX channel.
///
/// \since QXmpp 1.3
///
void QXmppRosterIq::Item::setIsMixChannel(bool isMixChannel)
{
    d->isMixChannel = isMixChannel;
}

///
/// Returns the participant id for this MIX channel.
///
/// \since QXmpp 1.3
///
QString QXmppRosterIq::Item::mixParticipantId() const
{
    return d->mixParticipantId;
}

///
/// Sets the participant id for this MIX channel.
///
/// \since QXmpp 1.3
///
void QXmppRosterIq::Item::setMixParticipantId(const QString &participantId)
{
    d->mixParticipantId = participantId;
}

/// \cond
void QXmppRosterIq::Item::parse(const QDomElement &element)
{
    d->name = element.attribute(QStringLiteral("name"));
    d->bareJid = element.attribute(QStringLiteral("jid"));
    setSubscriptionTypeFromStr(element.attribute(QStringLiteral("subscription")));
    setSubscriptionStatus(element.attribute(QStringLiteral("ask")));

    // pre-approved
    const QString approved = element.attribute(QStringLiteral("approved"));
    d->approved = (approved == QStringLiteral("1") || approved == QStringLiteral("true"));

    // groups
    QDomElement groupElement = element.firstChildElement(QStringLiteral("group"));
    while (!groupElement.isNull()) {
        d->groups << groupElement.text();
        groupElement = groupElement.nextSiblingElement(QStringLiteral("group"));
    }

    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    QDomElement channelElement = element.firstChildElement(QStringLiteral("channel"));
    if (!channelElement.isNull() && channelElement.namespaceURI() == ns_mix_roster) {
        d->isMixChannel = true;
        d->mixParticipantId = channelElement.attribute(QStringLiteral("participant-id"));
    }
}

void QXmppRosterIq::Item::toXml(QXmlStreamWriter *writer) const
{
    writer->writeStartElement(QStringLiteral("item"));
    helperToXmlAddAttribute(writer, QStringLiteral("jid"), d->bareJid);
    helperToXmlAddAttribute(writer, QStringLiteral("name"), d->name);
    helperToXmlAddAttribute(writer, QStringLiteral("subscription"), getSubscriptionTypeStr());
    helperToXmlAddAttribute(writer, QStringLiteral("ask"), subscriptionStatus());
    if (d->approved)
        writer->writeAttribute(QStringLiteral("approved"), QStringLiteral("true"));

    QSet<QString>::const_iterator i = d->groups.constBegin();
    while (i != d->groups.constEnd()) {
        helperToXmlAddTextElement(writer, QStringLiteral("group"), *i);
        ++i;
    }

    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    if (d->isMixChannel) {
        writer->writeStartElement(QStringLiteral("channel"));
        writer->writeAttribute(QStringLiteral("xmlns"), ns_mix_roster);
        helperToXmlAddAttribute(writer, QStringLiteral("participant-id"), d->mixParticipantId);
        writer->writeEndElement();
    }

    writer->writeEndElement();
}
/// \endcond
<commit_msg>Set QXmppRosterIq subscription type correctly<commit_after>/*
 * Copyright (C) 2008-2020 The QXmpp developers
 *
 * Authors:
 *  Manjeet Dahiya
 *  Jeremy Lainé
 *
 * Source:
 *  https://github.com/qxmpp-project/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 */

#include "QXmppRosterIq.h"

#include "QXmppConstants_p.h"
#include "QXmppUtils.h"

#include <QDomElement>
#include <QSharedData>
#include <QXmlStreamWriter>

class QXmppRosterIqPrivate : public QSharedData
{
public:
    QList<QXmppRosterIq::Item> items;
    // XEP-0237 Roster Versioning
    QString version;
    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    bool mixAnnotate = false;
};

QXmppRosterIq::QXmppRosterIq()
    : d(new QXmppRosterIqPrivate)
{
}

QXmppRosterIq::QXmppRosterIq(const QXmppRosterIq &) = default;

QXmppRosterIq::~QXmppRosterIq() = default;

QXmppRosterIq &QXmppRosterIq::operator=(const QXmppRosterIq &) = default;

///
/// Adds an item to the roster IQ.
///
/// \param item
///
void QXmppRosterIq::addItem(const Item &item)
{
    d->items.append(item);
}

///
/// Returns the roster IQ's items.
///
QList<QXmppRosterIq::Item> QXmppRosterIq::items() const
{
    return d->items;
}

///
/// Returns the roster version of IQ.
///
/// \return version as a QString
///
/// \since QXmpp 1.0
///
QString QXmppRosterIq::version() const
{
    return d->version;
}

///
/// Sets the roster version of IQ.
///
/// \param version as a QString
///
/// \since QXmpp 1.0
///
void QXmppRosterIq::setVersion(const QString &version)
{
    d->version = version;
}

///
/// Whether to annotate which items are MIX channels.
///
/// \since QXmpp 1.3
///
bool QXmppRosterIq::mixAnnotate() const
{
    return d->mixAnnotate;
}

///
/// Sets whether to include which roster items are MIX channels. This MUST only
/// be enabled in get requests.
///
/// \since QXmpp 1.3
///
void QXmppRosterIq::setMixAnnotate(bool mixAnnotate)
{
    d->mixAnnotate = mixAnnotate;
}

/// \cond
bool QXmppRosterIq::isRosterIq(const QDomElement &element)
{
    return (element.firstChildElement(QStringLiteral("query")).namespaceURI() == ns_roster);
}

void QXmppRosterIq::parseElementFromChild(const QDomElement &element)
{
    QDomElement queryElement = element.firstChildElement(QStringLiteral("query"));
    setVersion(queryElement.attribute(QStringLiteral("ver")));

    QDomElement itemElement = queryElement.firstChildElement(QStringLiteral("item"));
    while (!itemElement.isNull()) {
        QXmppRosterIq::Item item;
        item.parse(itemElement);
        d->items.append(item);
        itemElement = itemElement.nextSiblingElement(QStringLiteral("item"));
    }

    QDomElement annotateElement = queryElement.firstChildElement(QStringLiteral("annotate"));
    setMixAnnotate(!annotateElement.isNull() && annotateElement.namespaceURI() == ns_mix_roster);
}

void QXmppRosterIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
{
    writer->writeStartElement(QStringLiteral("query"));
    writer->writeDefaultNamespace(ns_roster);

    // XEP-0237 roster versioning - If the server does not advertise support for roster versioning, the client MUST NOT include the 'ver' attribute.
    if (!version().isEmpty())
        writer->writeAttribute(QStringLiteral("ver"), version());

    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    if (d->mixAnnotate) {
        writer->writeStartElement(QStringLiteral("annotate"));
        writer->writeAttribute(QStringLiteral("xmlns"), ns_mix_roster);
        writer->writeEndElement();
    }

    for (int i = 0; i < d->items.count(); ++i)
        d->items.at(i).toXml(writer);
    writer->writeEndElement();
}
/// \endcond

class QXmppRosterIq::ItemPrivate : public QSharedData
{
public:
    ItemPrivate();

    QString bareJid;
    Item::SubscriptionType type;
    QString name;
    // can be subscribe/unsubscribe (attribute "ask")
    QString subscriptionStatus;
    QSet<QString> groups;
    bool approved;
    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    bool isMixChannel = false;
    QString mixParticipantId;
};

QXmppRosterIq::ItemPrivate::ItemPrivate()
    : type(QXmppRosterIq::Item::NotSet),
      approved(false)
{
}

///
/// Constructs a new roster entry.
///
QXmppRosterIq::Item::Item()
    : d(new ItemPrivate)
{
}

QXmppRosterIq::Item::Item(const QXmppRosterIq::Item &other) = default;

QXmppRosterIq::Item::~Item() = default;

QXmppRosterIq::Item &QXmppRosterIq::Item::operator=(const Item &other) = default;

///
/// Returns the bareJid of the roster entry.
///
/// \return bareJid as a QString
///
QString QXmppRosterIq::Item::bareJid() const
{
    return d->bareJid;
}

/// Sets the bareJid of the roster entry.
///
/// \param bareJid as a QString
///
void QXmppRosterIq::Item::setBareJid(const QString &bareJid)
{
    d->bareJid = bareJid;
}

///
/// Returns the groups of the roster entry.
///
/// \return QSet<QString> list of all the groups
///
QSet<QString> QXmppRosterIq::Item::groups() const
{
    return d->groups;
}

///
/// Sets the groups of the roster entry.
///
/// \param groups list of all the groups as a QSet<QString>
///
void QXmppRosterIq::Item::setGroups(const QSet<QString> &groups)
{
    d->groups = groups;
}

///
/// Returns the name of the roster entry.
///
/// \return name as a QString
///
QString QXmppRosterIq::Item::name() const
{
    return d->name;
}

///
/// Sets the name of the roster entry.
///
/// \param name as a QString
///
void QXmppRosterIq::Item::setName(const QString &name)
{
    d->name = name;
}

///
/// Returns the subscription status of the roster entry. It is the "ask"
/// attribute in the Roster IQ stanza. Its value can be "subscribe" or "unsubscribe"
/// or empty.
///
/// \return subscription status as a QString
///
QString QXmppRosterIq::Item::subscriptionStatus() const
{
    return d->subscriptionStatus;
}

///
/// Sets the subscription status of the roster entry. It is the "ask"
/// attribute in the Roster IQ stanza. Its value can be "subscribe" or "unsubscribe"
/// or empty.
///
/// \param status as a QString
///
void QXmppRosterIq::Item::setSubscriptionStatus(const QString &status)
{
    d->subscriptionStatus = status;
}

///
/// Returns the subscription type of the roster entry.
///
QXmppRosterIq::Item::SubscriptionType
QXmppRosterIq::Item::subscriptionType() const
{
    return d->type;
}

///
/// Sets the subscription type of the roster entry.
///
/// \param type
///
void QXmppRosterIq::Item::setSubscriptionType(SubscriptionType type)
{
    d->type = type;
}

///
/// Returns whether the item has a pre-approved presence subscription.
///
/// \since QXmpp 1.3
///
bool QXmppRosterIq::Item::isApproved() const
{
    return d->approved;
}

///
/// Sets whether the item has a pre-approved presence subscription.
///
/// This cannot be used to initiate a pre-approved subscription. For this
/// purpose the client must send a <presence/> stanza of type
/// \c subscribed to the user.
///
/// \since QXmpp 1.3
///
void QXmppRosterIq::Item::setIsApproved(bool approved)
{
    d->approved = approved;
}

QString QXmppRosterIq::Item::getSubscriptionTypeStr() const
{
    switch (d->type) {
    case NotSet:
        return "";
    case None:
        return "none";
    case Both:
        return "both";
    case From:
        return "from";
    case To:
        return "to";
    case Remove:
        return "remove";
    default: {
        qWarning("QXmppRosterIq::Item::getTypeStr(): invalid type");
        return "";
    }
    }
}

void QXmppRosterIq::Item::setSubscriptionTypeFromStr(const QString &type)
{
    if (type.isEmpty())
        setSubscriptionType(NotSet);
    else if (type == QStringLiteral("none"))
        setSubscriptionType(None);
    else if (type == QStringLiteral("both"))
        setSubscriptionType(Both);
    else if (type == QStringLiteral("from"))
        setSubscriptionType(From);
    else if (type == QStringLiteral("to"))
        setSubscriptionType(To);
    else if (type == QStringLiteral("remove"))
        setSubscriptionType(Remove);
    else
        qWarning("QXmppRosterIq::Item::setTypeFromStr(): invalid type");
}

///
/// Returns whether this is a MIX channel.
///
/// \since QXmpp 1.3
///
bool QXmppRosterIq::Item::isMixChannel() const
{
    return d->isMixChannel;
}

///
/// Sets whether this is a MIX channel.
///
/// \since QXmpp 1.3
///
void QXmppRosterIq::Item::setIsMixChannel(bool isMixChannel)
{
    d->isMixChannel = isMixChannel;
}

///
/// Returns the participant id for this MIX channel.
///
/// \since QXmpp 1.3
///
QString QXmppRosterIq::Item::mixParticipantId() const
{
    return d->mixParticipantId;
}

///
/// Sets the participant id for this MIX channel.
///
/// \since QXmpp 1.3
///
void QXmppRosterIq::Item::setMixParticipantId(const QString &participantId)
{
    d->mixParticipantId = participantId;
}

/// \cond
void QXmppRosterIq::Item::parse(const QDomElement &element)
{
    d->name = element.attribute(QStringLiteral("name"));
    d->bareJid = element.attribute(QStringLiteral("jid"));
    setSubscriptionTypeFromStr(element.attribute(QStringLiteral("subscription")));
    setSubscriptionStatus(element.attribute(QStringLiteral("ask")));

    // pre-approved
    const QString approved = element.attribute(QStringLiteral("approved"));
    d->approved = (approved == QStringLiteral("1") || approved == QStringLiteral("true"));

    // groups
    QDomElement groupElement = element.firstChildElement(QStringLiteral("group"));
    while (!groupElement.isNull()) {
        d->groups << groupElement.text();
        groupElement = groupElement.nextSiblingElement(QStringLiteral("group"));
    }

    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    QDomElement channelElement = element.firstChildElement(QStringLiteral("channel"));
    if (!channelElement.isNull() && channelElement.namespaceURI() == ns_mix_roster) {
        d->isMixChannel = true;
        d->mixParticipantId = channelElement.attribute(QStringLiteral("participant-id"));
    }
}

void QXmppRosterIq::Item::toXml(QXmlStreamWriter *writer) const
{
    writer->writeStartElement(QStringLiteral("item"));
    helperToXmlAddAttribute(writer, QStringLiteral("jid"), d->bareJid);
    helperToXmlAddAttribute(writer, QStringLiteral("name"), d->name);
    helperToXmlAddAttribute(writer, QStringLiteral("subscription"), getSubscriptionTypeStr());
    helperToXmlAddAttribute(writer, QStringLiteral("ask"), subscriptionStatus());
    if (d->approved)
        writer->writeAttribute(QStringLiteral("approved"), QStringLiteral("true"));

    QSet<QString>::const_iterator i = d->groups.constBegin();
    while (i != d->groups.constEnd()) {
        helperToXmlAddTextElement(writer, QStringLiteral("group"), *i);
        ++i;
    }

    // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
    if (d->isMixChannel) {
        writer->writeStartElement(QStringLiteral("channel"));
        writer->writeAttribute(QStringLiteral("xmlns"), ns_mix_roster);
        helperToXmlAddAttribute(writer, QStringLiteral("participant-id"), d->mixParticipantId);
        writer->writeEndElement();
    }

    writer->writeEndElement();
}
/// \endcond
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012, 2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 *          Andreas Hansson
 */

#ifndef __BASE_ADDR_RANGE_MAP_HH__
#define __BASE_ADDR_RANGE_MAP_HH__

#include <map>
#include <utility>

#include "base/addr_range.hh"

/**
 * The AddrRangeMap uses an STL map to implement an interval tree for
 * address decoding. The value stored is a template type and can be
 * e.g. a port identifier, or a pointer.
 */
template <typename V>
class AddrRangeMap
{
  private:
    typedef std::map<AddrRange, V> RangeMap;

  public:
    typedef typename RangeMap::iterator iterator;
    typedef typename RangeMap::const_iterator const_iterator;

    /**
     * Find entry that contains the given address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry which range is a superset of the input
     * address range. Returns end() if none found.
     *
     * @param r An input address range
     * @return An iterator that contains the input address range
     */
    const_iterator
    contains(const AddrRange &r) const
    {
        return find(r, [r](const AddrRange r1) { return r.isSubset(r1); });
    }

    /**
     * Find entry that contains the given address
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry which range is a superset of the input
     * address. Returns end() if none found.
     *
     * @param r An input address
     * @return An iterator that contains the input address
     */
    const_iterator
    contains(Addr r) const
    {
        return contains(RangeSize(r, 1));
    }

    /**
     * Find entry that intersects with the given address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the first entry which range intersects with the
     * input address.
     *
     * @param r An input address
     * @return An iterator that intersects with the input address range
     */
    const_iterator
    intersects(const AddrRange &r) const
    {
        return find(r, [r](const AddrRange r1) { return r.intersects(r1); });
    }

    const_iterator
    insert(const AddrRange &r, const V& d)
    {
        if (intersects(r) != end())
            return tree.end();

        return tree.insert(std::make_pair(r, d)).first;
    }

    void
    erase(iterator p)
    {
        tree.erase(p);
    }

    void
    erase(iterator p, iterator q)
    {
        tree.erase(p,q);
    }

    void
    clear()
    {
        tree.erase(tree.begin(), tree.end());
    }

    const_iterator
    begin() const
    {
        return tree.begin();
    }

    iterator
    begin()
    {
        return tree.begin();
    }

    const_iterator
    end() const
    {
        return tree.end();
    }

    iterator
    end()
    {
        return tree.end();
    }

    std::size_t
    size() const
    {
        return tree.size();
    }

    bool
    empty() const
    {
        return tree.empty();
    }

  private:
    /**
     * Find entry that satisfies a condition on an address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry that satisfies the input conidition on
     * the input address range. Returns end() if none found.
     *
     * @param r An input address range
     * @param f A condition on an address range
     * @return An iterator that contains the input address range
     */
    const_iterator
    find(const AddrRange &r, std::function<bool(const AddrRange)> cond) const
    {
        const_iterator next = tree.upper_bound(r);
        if (next != end() && cond(next->first)) {
            return next;
        }
        if (next == begin())
            return end();
        next--;

        const_iterator i;
        do {
            i = next;
            if (cond(i->first)) {
                return i;
            }
            // Keep looking if the next range merges with the current one.
        } while (next != begin() &&
                 (--next)->first.mergesWith(i->first));

        return end();
    }

    RangeMap tree;
};

#endif //__BASE_ADDR_RANGE_MAP_HH__
<commit_msg>base: Build caching into the AddrRangeMap class<commit_after>/*
 * Copyright (c) 2012, 2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 *          Andreas Hansson
 */

#ifndef __BASE_ADDR_RANGE_MAP_HH__
#define __BASE_ADDR_RANGE_MAP_HH__

#include <map>
#include <utility>

#include "base/addr_range.hh"

/**
 * The AddrRangeMap uses an STL map to implement an interval tree for
 * address decoding. The value stored is a template type and can be
 * e.g. a port identifier, or a pointer.
 */
template <typename V, int max_cache_size=0>
class AddrRangeMap
{
  private:
    typedef std::map<AddrRange, V> RangeMap;

  public:
    typedef typename RangeMap::iterator iterator;
    typedef typename RangeMap::const_iterator const_iterator;

    /**
     * Find entry that contains the given address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry which range is a superset of the input
     * address range. Returns end() if none found.
     *
     * @param r An input address range
     * @return An iterator that contains the input address range
     */
    const_iterator
    contains(const AddrRange &r) const
    {
        return find(r, [r](const AddrRange r1) { return r.isSubset(r1); });
    }

    /**
     * Find entry that contains the given address
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry which range is a superset of the input
     * address. Returns end() if none found.
     *
     * @param r An input address
     * @return An iterator that contains the input address
     */
    const_iterator
    contains(Addr r) const
    {
        return contains(RangeSize(r, 1));
    }

    /**
     * Find entry that intersects with the given address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the first entry which range intersects with the
     * input address.
     *
     * @param r An input address
     * @return An iterator that intersects with the input address range
     */
    const_iterator
    intersects(const AddrRange &r) const
    {
        return find(r, [r](const AddrRange r1) { return r.intersects(r1); });
    }

    const_iterator
    insert(const AddrRange &r, const V& d)
    {
        if (intersects(r) != end())
            return tree.end();

        return tree.insert(std::make_pair(r, d)).first;
    }

    void
    erase(iterator p)
    {
        cache.remove(p);
        tree.erase(p);
    }

    void
    erase(iterator p, iterator q)
    {
        for (auto it = p; it != q; it++) {
            cache.remove(p);
        }
        tree.erase(p,q);
    }

    void
    clear()
    {
        cache.erase(cache.begin(), cache.end());
        tree.erase(tree.begin(), tree.end());
    }

    const_iterator
    begin() const
    {
        return tree.begin();
    }

    iterator
    begin()
    {
        return tree.begin();
    }

    const_iterator
    end() const
    {
        return tree.end();
    }

    iterator
    end()
    {
        return tree.end();
    }

    std::size_t
    size() const
    {
        return tree.size();
    }

    bool
    empty() const
    {
        return tree.empty();
    }

  private:
    /**
     * Add an address range map entry to the cache.
     *
     * @param it Iterator to the entry in the address range map
     */
    void
    addNewEntryToCache(const_iterator it) const
    {
        if (max_cache_size != 0) {
            // If there's a cache, add this element to it.
            if (cache.size() >= max_cache_size) {
                // If the cache is full, move the last element to the
                // front and overwrite it with the new value. This
                // avoids creating or destroying elements of the list.
                auto last = cache.end();
                last--;
                *last = it;
                if (max_cache_size > 1)
                    cache.splice(cache.begin(), cache, last);
            } else {
                cache.push_front(it);
            }
        }
    }

    /**
     * Find entry that satisfies a condition on an address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry that satisfies the input conidition on
     * the input address range. Returns end() if none found.
     *
     * @param r An input address range
     * @param f A condition on an address range
     * @return An iterator that contains the input address range
     */
    const_iterator
    find(const AddrRange &r, std::function<bool(const AddrRange)> cond) const
    {
        // Check the cache first
        for (auto c = cache.begin(); c != cache.end(); c++) {
            auto it = *c;
            if (cond(it->first)) {
                // If this entry matches, promote it to the front
                // of the cache and return it.
                cache.splice(cache.begin(), cache, c);
                return it;
            }
        }

        const_iterator next = tree.upper_bound(r);
        if (next != end() && cond(next->first)) {
            addNewEntryToCache(next);
            return next;
        }
        if (next == begin())
            return end();
        next--;

        const_iterator i;
        do {
            i = next;
            if (cond(i->first)) {
                addNewEntryToCache(i);
                return i;
            }
            // Keep looking if the next range merges with the current one.
        } while (next != begin() &&
                 (--next)->first.mergesWith(i->first));

        return end();
    }

    RangeMap tree;

    /**
     * A list of iterator that correspond to the max_cache_size most
     * recently used entries in the address range map. This mainly
     * used to optimize lookups. The elements in the list should
     * always be valid iterators of the tree.
     */
    mutable std::list<const_iterator> cache;
};

#endif //__BASE_ADDR_RANGE_MAP_HH__
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////
//
// DAGON - An Adventure Game Engine
// Copyright (c) 2011-2014 Senscape s.r.l.
// All rights reserved.
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was
// not distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.
//
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////

#include "Config.h"
#include "Image.h"
#include "Texture.h"

#include <cstring>
#include <fstream>

namespace dagon {

static const unsigned char PNG_HEADER[8] = {137, 80, 78, 71, 13, 10, 26, 10};

////////////////////////////////////////////////////////////
// Implementation - Constructor
////////////////////////////////////////////////////////////

Image::Image() :
config(Config::instance())
{
  _hasTexture = false;
  _rect = ZeroRect;
  this->setType(kObjectImage);
}

Image::Image(const std::string &fromFileName) :
config(Config::instance())
{
  this->setTexture(fromFileName);
  if (_attachedTexture->isBitmapLoaded()) {
    _rect.origin = ZeroPoint;
    _rect.size = MakeSize(_attachedTexture->width(),
                          _attachedTexture->height());
    _calculateCoordinates();
    _attachedTexture->unloadBitmap();
  }
  this->setType(kObjectImage);
}

////////////////////////////////////////////////////////////
// Implementation - Checks
////////////////////////////////////////////////////////////

bool Image::hasTexture() {
  return _hasTexture;
}

////////////////////////////////////////////////////////////
// Implementation - Gets
////////////////////////////////////////////////////////////

float* Image::arrayOfCoordinates() {
  return _arrayOfCoordinates;
}

Point Image::position() {
  return _rect.origin;
}

Size Image::size() {
  return _rect.size;
}

Texture* Image::texture() {
  _attachedTexture->load();
  return _attachedTexture;
}

////////////////////////////////////////////////////////////
// Implementation - Sets
////////////////////////////////////////////////////////////

void Image::setPosition(float x, float y) {
  _rect.origin = MakePoint(x, y);
  _calculateCoordinates();
}

void Image::setSize(float width, float height) {
  _rect.size = MakeSize(width, height);
  _calculateCoordinates();
}

void Image::setTexture(const std::string &fromFileName) {
  // TODO: Important! We should determine first if the texture already exists
  // to avoid repeating resources. Eventually, this would be done via the
  // resource manager.
  // FIXME: These textures are immediately loaded which isn't very efficient.

  _attachedTexture = new Texture;
  _attachedTexture->setResource(config.path(kPathResources, fromFileName,
                                            kObjectImage).c_str());
  std::ifstream bitmapFile(_attachedTexture->resource(), std::ios::in |
                                                         std::ios::binary);
  if (!bitmapFile.good()) {
    _attachedTexture->loadBitmap();
  }
  else {
    char header[8];
    bitmapFile.read(header, 8);
    if (std::memcmp(header, PNG_HEADER, 8) == 0) {
      char buf[4]; // Width and height are stored as 32 bit words.
      bitmapFile.seekg(16); // Skip header (8 bytes) and IHDR chunk header (8 bytes).

      bitmapFile.read(buf, 4); // Read width (big endian integer).
      int width = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];

      bitmapFile.read(buf, 4); // Read height (big endian integer).
      int height = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];

      if (width <= 0 || height <= 0) { // In this case we should let STBI handle this file.
        _attachedTexture->loadBitmap();
      }
      else {
        _rect.origin = ZeroPoint;
        _rect.size = MakeSize(width, height);
        _calculateCoordinates();
      }
    }
    else {
      _attachedTexture->loadBitmap();
    }
  }

  _hasTexture = true;
}

////////////////////////////////////////////////////////////
// Implementation - State changes
////////////////////////////////////////////////////////////

void Image::move(float offsetX, float offsetY) {
  MoveRect(_rect, offsetX, offsetY);
  _calculateCoordinates();
}

void Image::scale(float factor) {
  ScaleRect(_rect, factor);
  _calculateCoordinates();
}

////////////////////////////////////////////////////////////
// Implementation - Private methods
////////////////////////////////////////////////////////////

void Image::_calculateCoordinates() {
  _arrayOfCoordinates[0] = MinX(_rect);
  _arrayOfCoordinates[1] = MinY(_rect);
  _arrayOfCoordinates[2] = MaxX(_rect);
  _arrayOfCoordinates[3] = MinY(_rect);
  _arrayOfCoordinates[4] = MaxX(_rect);
  _arrayOfCoordinates[5] = MaxY(_rect);
  _arrayOfCoordinates[6] = MinX(_rect);
  _arrayOfCoordinates[7] = MaxY(_rect);
}

}
<commit_msg>Go back to letting STBI handle all image loading (#184)<commit_after>////////////////////////////////////////////////////////////
//
// DAGON - An Adventure Game Engine
// Copyright (c) 2011-2014 Senscape s.r.l.
// All rights reserved.
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was
// not distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.
//
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////

#include "Config.h"
#include "Image.h"
#include "Texture.h"

namespace dagon {

////////////////////////////////////////////////////////////
// Implementation - Constructor
////////////////////////////////////////////////////////////

Image::Image() :
config(Config::instance())
{
  _hasTexture = false;
  _rect = ZeroRect;
  this->setType(kObjectImage);
}

Image::Image(const std::string &fromFileName) :
config(Config::instance())
{
  this->setTexture(fromFileName);
  this->setType(kObjectImage);
}

////////////////////////////////////////////////////////////
// Implementation - Checks
////////////////////////////////////////////////////////////

bool Image::hasTexture() {
  return _hasTexture;
}

////////////////////////////////////////////////////////////
// Implementation - Gets
////////////////////////////////////////////////////////////

float* Image::arrayOfCoordinates() {
  return _arrayOfCoordinates;
}

Point Image::position() {
  return _rect.origin;
}

Size Image::size() {
  return _rect.size;
}

Texture* Image::texture() {
  _attachedTexture->load();
  return _attachedTexture;
}

////////////////////////////////////////////////////////////
// Implementation - Sets
////////////////////////////////////////////////////////////

void Image::setPosition(float x, float y) {
  _rect.origin = MakePoint(x, y);
  _calculateCoordinates();
}

void Image::setSize(float width, float height) {
  _rect.size = MakeSize(width, height);
  _calculateCoordinates();
}

void Image::setTexture(const std::string &fromFileName) {
  // TODO: Important! We should determine first if the texture already exists
  // to avoid repeating resources. Eventually, this would be done via the
  // resource manager.
  // FIXME: These textures are immediately loaded which isn't very efficient.

  _attachedTexture = new Texture;
  _attachedTexture->setResource(config.path(kPathResources, fromFileName,
                                            kObjectImage).c_str());
  _attachedTexture->loadBitmap();
  if (_attachedTexture->isBitmapLoaded()) {
    _rect.origin = ZeroPoint;
    _rect.size = MakeSize(_attachedTexture->width(),
                          _attachedTexture->height());
    _calculateCoordinates();
    _attachedTexture->unloadBitmap();
  }

  _hasTexture = true;
}

////////////////////////////////////////////////////////////
// Implementation - State changes
////////////////////////////////////////////////////////////

void Image::move(float offsetX, float offsetY) {
  MoveRect(_rect, offsetX, offsetY);
  _calculateCoordinates();
}

void Image::scale(float factor) {
  ScaleRect(_rect, factor);
  _calculateCoordinates();
}

////////////////////////////////////////////////////////////
// Implementation - Private methods
////////////////////////////////////////////////////////////

void Image::_calculateCoordinates() {
  _arrayOfCoordinates[0] = MinX(_rect);
  _arrayOfCoordinates[1] = MinY(_rect);
  _arrayOfCoordinates[2] = MaxX(_rect);
  _arrayOfCoordinates[3] = MinY(_rect);
  _arrayOfCoordinates[4] = MaxX(_rect);
  _arrayOfCoordinates[5] = MaxY(_rect);
  _arrayOfCoordinates[6] = MinX(_rect);
  _arrayOfCoordinates[7] = MaxY(_rect);
}

}
<|endoftext|>