<commit_before>#include <thread>
#include "TcpClient.h"
#include "platform/CCFileUtils.h"
#include "base/CCDirector.h"
#include "base/CCScheduler.h"
#include "2d/CCLabel.h"
#include "../../PacketType.h"
#include "GameScene.h"
#include "ObjectLayer.h"
#include "NetworkScene.h"
#include "RoomScene.h"

#ifdef _WIN32
#pragma comment(lib,"ws2_32.lib")
#define sleep(x) Sleep(x)
#endif

static TcpClient* s_TcpClient = nullptr;

TcpClient::TcpClient() : mRecvBuffer(BUF_SIZE), mSock(NULL), mLoginId(-1)
{
	///
	auto t = std::thread(CC_CALLBACK_0(TcpClient::networkThread, this));
	t.detach();
}

TcpClient::~TcpClient()
{
	if(mSock == NULL)
		return;

#ifndef _WIN32
	close(mSock);
#else
	closesocket(mSock);
	WSACleanup();
#endif
}

TcpClient* TcpClient::getInstance()
{
	if (nullptr == s_TcpClient)
	{
		s_TcpClient = new TcpClient();
	}
	return s_TcpClient;
}

void TcpClient::destroyInstance()
{
	CC_SAFE_DELETE(s_TcpClient);
}

///////////////////////////////////////////////////////////////////////////
/*
	 ,  Լ
*/
///////////////////////////////////////////////////////////////////////////
bool TcpClient::connect()
{
	if (mSock != NULL)
	{
		TcpClient::getInstance()->disconnect();
	}

#ifdef _WIN32
	WSADATA wsa;
	if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
		return false;
#endif

	mSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (mSock == INVALID_SOCKET)
		return false;

	std::string ipaddr = cocos2d::UserDefault::getInstance()->getStringForKey("ipaddr", std::string("localhost"));
	int port = cocos2d::UserDefault::getInstance()->getIntegerForKey("port", 9001);

	struct hostent* host;
	struct sockaddr_in hostAddr;

	if ((host = gethostbyname(ipaddr.c_str())) == 0)
		return false;

	memset(&hostAddr, 0, sizeof(hostAddr));
	hostAddr.sin_family = AF_INET;
	hostAddr.sin_addr.s_addr = inet_addr("10.73.42.129");
	hostAddr.sin_port = htons(port);

	if (SOCKET_ERROR == ::connect(mSock, (struct sockaddr*)&hostAddr, sizeof(hostAddr)))
	{
		CCLOG("CONNECT FAILED");
		return false;
	}

	/// nagle ˰
	int opt = 1;
	setsockopt(mSock, IPPROTO_TCP, TCP_NODELAY, (const char*)&opt, sizeof(int));

	return true;
}

void TcpClient::disconnect()
{
	if (mSock == NULL)
		return;

#ifndef _WIN32
	close(mSock);
#else
	closesocket(mSock);
	WSACleanup();
#endif
	mSock = NULL;
	mLoginId = -1;

	return;
}

///////////////////////////////////////////////////////////////////////////
/*
	 Ŷ , ޴ Լ
*/
///////////////////////////////////////////////////////////////////////////
bool TcpClient::send(const char* data, int length)
{
	int count = 0;
	while (count < length)
	{
		int n = ::send(mSock, data + count, length, 0);
		if (n == SOCKET_ERROR)
		{
			CCLOG("SEND ERROR");
			return false;
		}
		count += n;
		length -= n;
	}

	return true;
}

void TcpClient::networkThread()
{
	while ( true )
	{
		char inBuf[4096] = { 0, };

		int n = ::recv(mSock, inBuf, 4096, 0);

		if (n < 1)
		{
			sleep(0); ///< for cpu low-utilization
			continue;
		}

		if (!mRecvBuffer.Write(inBuf, n))
		{
			///  á.
			assert(false);
		}

		processPacket();
	}
}

///////////////////////////////////////////////////////////////////////////
/*
	 Ŷ ĽϿ óϴ Լ
*/
///////////////////////////////////////////////////////////////////////////
void TcpClient::processPacket()
{
	auto scheduler = cocos2d::Director::getInstance()->getScheduler();

	/// Ŷ Ľؼ ϼǴ Ŷ , ش ݹ ҷش.
	while (true)
	{
		PacketHeader header;

		if (false == mRecvBuffer.Peek((char*)&header, sizeof(PacketHeader)))
			break;

		if (header.mSize > mRecvBuffer.GetStoredSize())
			break;

		switch (header.mType)
		{
		case PKT_SC_LOGIN:
			{
				LoginResult recvData;
				bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
				assert(ret && recvData.mPlayerId != -1);

				mLoginId = recvData.mPlayerId;

				auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("NetworkScene");
				if (layer == nullptr)
					break;
				scheduler->performFunctionInCocosThread(CC_CALLBACK_0(NetworkScene::ConnectComplete, dynamic_cast<NetworkScene*>(layer)));
			}
			break;
		case PKT_SC_MAKE_ROOM:
			{
				MakeRoomResult recvData;
				bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
				assert(ret && recvData.mPlayerId == mLoginId);

				auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("NetworkScene");
				if (layer == nullptr)
					break;
				scheduler->performFunctionInCocosThread(CC_CALLBACK_0(NetworkScene::MakeRoomComplete, dynamic_cast<NetworkScene*>(layer), recvData.mRoomId));
			}
			break;
		case PKT_SC_INOUT_ROOM:
			{
				InOutRoomResult recvData;
				bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
				assert(ret && recvData.mPlayerId == mLoginId);

				if (recvData.mIsIn)
				{
					auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("NetworkScene");
					if (layer == nullptr)
						break;
					scheduler->performFunctionInCocosThread(CC_CALLBACK_0(NetworkScene::MakeRoomComplete, dynamic_cast<NetworkScene*>(layer), recvData.mRoomId));
				}
				else
				{
					// ÷̾ ó ʿ
// 					auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("RoomScene");
// 					if (layer == nullptr)
// 						break;
//					scheduler->performFunctionInCocosThread(CC_CALLBACK_0(NetworkScene::MakeRoomComplete, dynamic_cast<NetworkScene*>(layer), recvData.mRoomId));
				}
			}

		//case: //
		//{
		//		  StartGameResult recvData;
		//		  bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
		//		  assert(ret && recvData.mPlayerId != -1);

		//		  auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("RoomScene");
		//		  if (layer == nullptr)
		//			  break;
		//		  scheduler->performFunctionInCocosThread(CC_CALLBACK_0(RoomScene::gameStartComplete, dynamic_cast<RoomScene*>(layer)));

		//}

		case PKT_SC_CREATE_HERO:
			{
				CreateHeroResult recvData;
				bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
				assert(ret && recvData.mPlayerId != -1);

				auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("GameScene")->getChildByName("PhyshicsLayer")->getChildByName("ObjectLayer");
				// scheduler->performFunctionInCocosThread(CC_CALLBACK_0(ObjectLayer::createHeroStart, dynamic_cast<ObjectLayer*>(layer)));
				scheduler->performFunctionInCocosThread(CC_CALLBACK_0(ObjectLayer::UpdatePeer, dynamic_cast<ObjectLayer*>(layer), recvData.mUnitId, recvData.mPosX, recvData.mPosY));

			}
			break;

		default:
			assert(false);
		}

	}
}

///////////////////////////////////////////////////////////////////////////
/*
	 Ŷ Ľϴ Լ
*/
///////////////////////////////////////////////////////////////////////////
void TcpClient::loginRequest()
{
	if (mLoginId > 0)
		return;

	srand(time(NULL));

	LoginRequest sendData;
	sendData.mPlayerId = 1000 + rand() % 101;

	send((const char*)&sendData, sizeof(LoginRequest));
}

void TcpClient::makeRoomRequest()
{
	if (mLoginId < 0)
		return;

	MakeRoomRequest sendData;
	sendData.mPlayerId = mLoginId;

	send((const char*)&sendData, sizeof(MakeRoomRequest));
}

void TcpClient::joinRoomRequest()
{
	if (mLoginId < 0)
		return;

	InOutRoomRequest sendData;
	sendData.mPlayerId = mLoginId;
	sendData.mIsIn = true;

	send((const char*)&sendData, sizeof(InOutRoomRequest));
}

void TcpClient::outRoomRequest(int roomId)
{
	if (mLoginId < 0)
		return;

	InOutRoomRequest sendData;
	sendData.mPlayerId = mLoginId;
	sendData.mIsIn = false;
	sendData.mRoomId = roomId;

	send((const char*)&sendData, sizeof(InOutRoomRequest));
}

void TcpClient::createRequest(int unitID, float x, float y)
{
	if (mLoginId < 0)
		return;

	CreateHeroRequest sendData;
	sendData.mPlayerId = mLoginId;
	sendData.mUnitId = unitID;
	sendData.mPosX = x;
	sendData.mPosY = y;

	send((const char*)&sendData, sizeof(CreateHeroRequest));

}

void TcpClient::moveRequest(float x, float y)
{
	if (mLoginId < 0)
		return;

	MoveRequest sendData;
	sendData.mPlayerId = mLoginId;
	sendData.mPosX = x;
	sendData.mPosY = y;

	send((const char*)&sendData, sizeof(MoveRequest));
}

void TcpClient::chatRequest(const char* chat)
{
	if (mLoginId < 0)
		return;

	ChatBroadcastRequest sendData;

	sendData.mPlayerId = mLoginId;
	memcpy(sendData.mChat, chat, strlen(chat));

	send((const char*)&sendData, sizeof(ChatBroadcastRequest));
}

 void TcpClient::gameStartRequest()
 {
// 	if (mLoginId < 0)
// 		return;
//
// 	StartGameRequest sendData;
//
// 	sendData.mPlayerId = mLoginId;
//
// 	send((const char*)&sendData, sizeof(StartGameRequest));
//
//
 }

<commit_msg>자잘 클라 수정<commit_after>#include <thread>
#include "TcpClient.h"
#include "platform/CCFileUtils.h"
#include "base/CCDirector.h"
#include "base/CCScheduler.h"
#include "2d/CCLabel.h"
#include "../../PacketType.h"
#include "GameScene.h"
#include "ObjectLayer.h"
#include "NetworkScene.h"
#include "RoomScene.h"

#ifdef _WIN32
#pragma comment(lib,"ws2_32.lib")
#define sleep(x) Sleep(x)
#endif

static TcpClient* s_TcpClient = nullptr;

TcpClient::TcpClient() : mRecvBuffer(BUF_SIZE), mSock(NULL), mLoginId(-1)
{
	///
	auto t = std::thread(CC_CALLBACK_0(TcpClient::networkThread, this));
	t.detach();
}

TcpClient::~TcpClient()
{
	if(mSock == NULL)
		return;

#ifndef _WIN32
	close(mSock);
#else
	closesocket(mSock);
	WSACleanup();
#endif
}

TcpClient* TcpClient::getInstance()
{
	if (nullptr == s_TcpClient)
	{
		s_TcpClient = new TcpClient();
	}
	return s_TcpClient;
}

void TcpClient::destroyInstance()
{
	CC_SAFE_DELETE(s_TcpClient);
}

///////////////////////////////////////////////////////////////////////////
/*
	 ,  Լ
*/
///////////////////////////////////////////////////////////////////////////
bool TcpClient::connect()
{
	if (mSock != NULL)
	{
		TcpClient::getInstance()->disconnect();
	}

#ifdef _WIN32
	WSADATA wsa;
	if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
		return false;
#endif

	mSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (mSock == INVALID_SOCKET)
		return false;

	std::string ipaddr = cocos2d::UserDefault::getInstance()->getStringForKey("ipaddr", std::string("localhost"));
	int port = cocos2d::UserDefault::getInstance()->getIntegerForKey("port", 9001);

	struct hostent* host;
	struct sockaddr_in hostAddr;

	if ((host = gethostbyname(ipaddr.c_str())) == 0)
		return false;

	memset(&hostAddr, 0, sizeof(hostAddr));
	hostAddr.sin_family = AF_INET;
	hostAddr.sin_addr.s_addr = inet_addr("10.73.42.129");
	hostAddr.sin_port = htons(port);

	if (SOCKET_ERROR == ::connect(mSock, (struct sockaddr*)&hostAddr, sizeof(hostAddr)))
	{
		CCLOG("CONNECT FAILED");
		return false;
	}

	/// nagle ˰
	int opt = 1;
	setsockopt(mSock, IPPROTO_TCP, TCP_NODELAY, (const char*)&opt, sizeof(int));

	return true;
}

void TcpClient::disconnect()
{
	if (mSock == NULL)
		return;

#ifndef _WIN32
	close(mSock);
#else
	closesocket(mSock);
	WSACleanup();
#endif
	mSock = NULL;
	mLoginId = -1;

	return;
}

///////////////////////////////////////////////////////////////////////////
/*
	 Ŷ , ޴ Լ
*/
///////////////////////////////////////////////////////////////////////////
bool TcpClient::send(const char* data, int length)
{
	int count = 0;
	while (count < length)
	{
		int n = ::send(mSock, data + count, length, 0);
		if (n == SOCKET_ERROR)
		{
			CCLOG("SEND ERROR");
			return false;
		}
		count += n;
		length -= n;
	}

	return true;
}

void TcpClient::networkThread()
{
	while ( true )
	{
		char inBuf[4096] = { 0, };

		int n = ::recv(mSock, inBuf, 4096, 0);

		if (n < 1)
		{
			sleep(0); ///< for cpu low-utilization
			continue;
		}

		if (!mRecvBuffer.Write(inBuf, n))
		{
			///  á.
			assert(false);
		}

		processPacket();
	}
}

///////////////////////////////////////////////////////////////////////////
/*
	 Ŷ ĽϿ óϴ Լ
*/
///////////////////////////////////////////////////////////////////////////
void TcpClient::processPacket()
{
	auto scheduler = cocos2d::Director::getInstance()->getScheduler();

	/// Ŷ Ľؼ ϼǴ Ŷ , ش ݹ ҷش.
	while (true)
	{
		PacketHeader header;

		if (false == mRecvBuffer.Peek((char*)&header, sizeof(PacketHeader)))
			break;

		if (header.mSize > mRecvBuffer.GetStoredSize())
			break;

		switch (header.mType)
		{
		case PKT_SC_LOGIN:
			{
				LoginResult recvData;
				bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
				assert(ret && recvData.mPlayerId != -1);

				mLoginId = recvData.mPlayerId;

				auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("NetworkScene");
				if (layer == nullptr)
					break;
				scheduler->performFunctionInCocosThread(CC_CALLBACK_0(NetworkScene::ConnectComplete, dynamic_cast<NetworkScene*>(layer)));
			}
			break;
		case PKT_SC_MAKE_ROOM:
			{
				MakeRoomResult recvData;
				bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
				assert(ret && recvData.mPlayerId == mLoginId);

				auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("NetworkScene");
				if (layer == nullptr)
					break;
				scheduler->performFunctionInCocosThread(CC_CALLBACK_0(NetworkScene::MakeRoomComplete, dynamic_cast<NetworkScene*>(layer), recvData.mRoomId));
			}
			break;
		case PKT_SC_INOUT_ROOM:
			{
				InOutRoomResult recvData;
				bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
				assert(ret && recvData.mPlayerId == mLoginId);

				if (recvData.mIsIn)
				{
					auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("NetworkScene");
					if (layer == nullptr)
						break;
					scheduler->performFunctionInCocosThread(CC_CALLBACK_0(NetworkScene::JoinRoomComplete, dynamic_cast<NetworkScene*>(layer), recvData.mRoomId));
				}
				else
				{
					// ÷̾ ó ʿ
// 					auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("RoomScene");
// 					if (layer == nullptr)
// 						break;
//					scheduler->performFunctionInCocosThread(CC_CALLBACK_0(NetworkScene::MakeRoomComplete, dynamic_cast<NetworkScene*>(layer), recvData.mRoomId));
				}
			}
			break;

		//case: //
		//{
		//		  StartGameResult recvData;
		//		  bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
		//		  assert(ret && recvData.mPlayerId != -1);

		//		  auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("RoomScene");
		//		  if (layer == nullptr)
		//			  break;
		//		  scheduler->performFunctionInCocosThread(CC_CALLBACK_0(RoomScene::gameStartComplete, dynamic_cast<RoomScene*>(layer)));

		//}

		case PKT_SC_CREATE_HERO:
			{
				CreateHeroResult recvData;
				bool ret = mRecvBuffer.Read((char*)&recvData, recvData.mSize);
				assert(ret && recvData.mPlayerId != -1);

				auto layer = cocos2d::Director::getInstance()->getRunningScene()->getChildByName("GameScene")->getChildByName("PhyshicsLayer")->getChildByName("ObjectLayer");
				// scheduler->performFunctionInCocosThread(CC_CALLBACK_0(ObjectLayer::createHeroStart, dynamic_cast<ObjectLayer*>(layer)));
				scheduler->performFunctionInCocosThread(CC_CALLBACK_0(ObjectLayer::UpdatePeer, dynamic_cast<ObjectLayer*>(layer), recvData.mUnitId, recvData.mPosX, recvData.mPosY));

			}
			break;

		default:
			assert(false);
		}

	}
}

///////////////////////////////////////////////////////////////////////////
/*
	 Ŷ Ľϴ Լ
*/
///////////////////////////////////////////////////////////////////////////
void TcpClient::loginRequest()
{
	if (mLoginId > 0)
		return;

	srand(time(NULL));

	LoginRequest sendData;
	sendData.mPlayerId = 1000 + rand() % 101;

	send((const char*)&sendData, sizeof(LoginRequest));
}

void TcpClient::makeRoomRequest()
{
	if (mLoginId < 0)
		return;

	MakeRoomRequest sendData;
	sendData.mPlayerId = mLoginId;

	send((const char*)&sendData, sizeof(MakeRoomRequest));
}

void TcpClient::joinRoomRequest()
{
	if (mLoginId < 0)
		return;

	InOutRoomRequest sendData;
	sendData.mPlayerId = mLoginId;
	sendData.mIsIn = true;

	send((const char*)&sendData, sizeof(InOutRoomRequest));
}

void TcpClient::outRoomRequest(int roomId)
{
	if (mLoginId < 0)
		return;

	InOutRoomRequest sendData;
	sendData.mPlayerId = mLoginId;
	sendData.mIsIn = false;
	sendData.mRoomId = roomId;

	send((const char*)&sendData, sizeof(InOutRoomRequest));
}

void TcpClient::createRequest(int unitID, float x, float y)
{
	if (mLoginId < 0)
		return;

	CreateHeroRequest sendData;
	sendData.mPlayerId = mLoginId;
	sendData.mUnitId = unitID;
	sendData.mPosX = x;
	sendData.mPosY = y;

	send((const char*)&sendData, sizeof(CreateHeroRequest));

}

void TcpClient::moveRequest(float x, float y)
{
	if (mLoginId < 0)
		return;

	MoveRequest sendData;
	sendData.mPlayerId = mLoginId;
	sendData.mPosX = x;
	sendData.mPosY = y;

	send((const char*)&sendData, sizeof(MoveRequest));
}

void TcpClient::chatRequest(const char* chat)
{
	if (mLoginId < 0)
		return;

	ChatBroadcastRequest sendData;

	sendData.mPlayerId = mLoginId;
	memcpy(sendData.mChat, chat, strlen(chat));

	send((const char*)&sendData, sizeof(ChatBroadcastRequest));
}

 void TcpClient::gameStartRequest()
 {
// 	if (mLoginId < 0)
// 		return;
//
// 	StartGameRequest sendData;
//
// 	sendData.mPlayerId = mLoginId;
//
// 	send((const char*)&sendData, sizeof(StartGameRequest));
//
//
 }

<|endoftext|>


<commit_before>#include "MenuButton.h"
#include "InputHandler.h"

//constructor for MenuButton, calls SDLGameObject constructor first with LoaderParams
MenuButton::MenuButton(const LoaderParams* pParams)	: SDLGameObject(pParams)
{
	m_currentFrame = MOUSE_OUT;	//start at frame 0
}

void MenuButton::draw()
{
	SDLGameObject::draw();	//use the base class drawing
}

void MenuButton::update()
{
	//get the coordinates of the mouse pointer and save them in pMousePos
	Vector2D* pMousePos = TheInputHandler::Instance()->getMousePosition();

	//check if the mouse pointer is over the button
	if (pMousePos->getX() < (m_position.getX() + m_width) && pMousePos->getX > m_position.getX() && pMousePos->getY() < (m_position.getY() + m_height) && pMousePos->getY() > m_position.getY())
	{
		//confirms that Mouse pointer is over the button
		m_currentFrame = MOUSE_OVER;

		if (TheInputHandler::Instance()->getMouseButtonState(LEFT))
		{
			//confirms that the button was clicked
			m_currentFrame = CLICKED;
		}
	}
	else
	{
		//Mouse is not over the button
		m_currentFrame = MOUSE_OUT;
	}
}

void MenuButton::clean()
{
	SDLGameObject::clean();
}<commit_msg>Fixed C3867 error in MenuButton<commit_after>#include "MenuButton.h"
#include "InputHandler.h"

//constructor for MenuButton, calls SDLGameObject constructor first with LoaderParams
MenuButton::MenuButton(const LoaderParams* pParams)	: SDLGameObject(pParams)
{
	m_currentFrame = MOUSE_OUT;	//start at frame 0
}

void MenuButton::draw()
{
	SDLGameObject::draw();	//use the base class drawing
}

void MenuButton::update()
{
	//get the coordinates of the mouse pointer and save them in pMousePos
	Vector2D* pMousePos = TheInputHandler::Instance()->getMousePosition();

	//check if the mouse pointer is over the button
	if (pMousePos->getX() < (m_position.getX() + m_width) && pMousePos->getX() > m_position.getX() && pMousePos->getY() < (m_position.getY() + m_height) && pMousePos->getY() > m_position.getY())
	{
		//confirms that Mouse pointer is over the button
		m_currentFrame = MOUSE_OVER;

		if (TheInputHandler::Instance()->getMouseButtonState(LEFT))
		{
			//confirms that the button was clicked
			m_currentFrame = CLICKED;
		}
	}
	else
	{
		//Mouse is not over the button
		m_currentFrame = MOUSE_OUT;
	}
}

void MenuButton::clean()
{
	SDLGameObject::clean();
}<|endoftext|>


<commit_before>/* console.trace():
before we have:
selectFirstItem (qrc:/qml/ui/accordion/SomeLongName.qml:179)
selectFirstItemBoth (qrc:/qml/ui/accordion/OtherSomeLongName.qml:164)
onTriggered (qrc:/qml/ui/accordion/OtherSomeLongName23.qml:202)

After maybeChangeQmlFormatting() we have:
selectFirstItem  qrc:/qml/ui/accordion/ SomeLongName.qml:179
selectFirstItemBoth  qrc:/qml/ui/accordion/ OtherSomeLongName.qml:164
onTriggered  qrc:/qml/ui/accordion/ OtherSomeLongName23.qml:202
*/
void maybeChangeQmlFormatting(QString & str) {
	auto lines = str.split("\n");
	for(QString & line: lines) {
		if (line.endsWith(')') && line.contains(".qml:")) {
			line.chop(1);
			int index = line.indexOf(" (");
			if (-1!=index) {
				line[index+1] = ' ';
			}
			index = line.lastIndexOf('/');
			if (-1!=index) {
				line.insert(index + 1, ' ');
			}
		}
	}
	str = lines.join("\n");
}

QString maybeToHtmlTable(const QString & str) {//changes text from maybeChangeQmlFormatting to html table
	auto lines = str.split("\n");
	for(QString & line: lines) {
		if (!line.contains("  ") || !line.contains(".qml:"))
			return str;
		line.chop(1);
	}
	QString ret = "
";
	for(QString & line: lines) {
		ret += "
";

		int index = line.indexOf("  ");
		Q_ASSERT(-1 != index);
		line.remove(index, 2);
		line.insert(index, "	");
		index = line.lastIndexOf('/');
		if (-1!=index) {
			line.insert(index + 1, ' ');
		}
		ret += line;
		ret += "
";
	}
	ret += "
";
	return ret;
}
<commit_msg>Update qmlFormtatting.cpp<commit_after>/* console.trace() produces output like this:
selectFirstItem (qrc:/qml/ui/accordion/SomeLongName.qml:179)
selectFirstItemBoth (qrc:/qml/ui/accordion/OtherSomeLongName.qml:164)
onTriggered (qrc:/qml/ui/accordion/OtherSomeLongName23.qml:202)

Which is inconvenient to copy file name with line number. After maybeChangeQmlFormatting() we have:
selectFirstItem  qrc:/qml/ui/accordion/ SomeLongName.qml:179
selectFirstItemBoth  qrc:/qml/ui/accordion/ OtherSomeLongName.qml:164
onTriggered  qrc:/qml/ui/accordion/ OtherSomeLongName23.qml:202
*/
void maybeChangeQmlFormatting(QString & str) {
	auto lines = str.split("\n");
	for(QString & line: lines) {
		if (line.endsWith(')') && line.contains(".qml:")) {
			line.chop(1);
			int index = line.indexOf(" (");
			if (-1!=index) {
				line[index+1] = ' ';
			}
			index = line.lastIndexOf('/');
			if (-1!=index) {
				line.insert(index + 1, ' ');
			}
		}
	}
	str = lines.join("\n");
}

QString maybeToHtmlTable(const QString & str) {//changes text from maybeChangeQmlFormatting to html table
	auto lines = str.split("\n");
	for(QString & line: lines) {
		if (!line.contains("  ") || !line.contains(".qml:"))
			return str;
		line.chop(1);
	}
	QString ret = "
";
	for(QString & line: lines) {
		ret += "
";

		int index = line.indexOf("  ");
		Q_ASSERT(-1 != index);
		line.remove(index, 2);
		line.insert(index, "	");
		index = line.lastIndexOf('/');
		if (-1!=index) {
			line.insert(index + 1, ' ');
		}
		ret += line;
		ret += "
";
	}
	ret += "
";
	return ret;
}
<|endoftext|>


<commit_before>#include "UEPyFMenuBuilder.h"

#include "Wrappers/UEPyESlateEnums.h"

static PyObject *py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder *self, PyObject * args)
{
	char *name;
	char *text;
	if (!PyArg_ParseTuple(args, "ss:begin_section", &name, &text))
		return nullptr;

	self->menu_builder.BeginSection(name, FText::FromString(UTF8_TO_TCHAR(text)));

	Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_end_section(ue_PyFMenuBuilder *self, PyObject * args)
{
	self->menu_builder.EndSection();

	Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_make_widget(ue_PyFMenuBuilder *self, PyObject * args)
{
    ue_PySWidget *ret = py_ue_new_swidget<ue_PySWidget>(self->menu_builder.MakeWidget(), &ue_PySWidgetType);
	return (PyObject *)ret;
}

static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyObject * args)
{
	char *label;
	char *tooltip;
	PyObject *py_callable;
	PyObject *py_obj = nullptr;
	int ui_action_type = EUserInterfaceActionType::Button;
	if (!PyArg_ParseTuple(args, "ssO|Oi:add_menu_entry", &label, &tooltip, &py_callable, &py_obj, &ui_action_type))
		return nullptr;

	if (!PyCalllable_Check_Extended(py_callable))
	{
		return PyErr_Format(PyExc_Exception, "argument is not callable");
	}

	FExecuteAction handler;
	TSharedRef<FPythonSlateDelegate> py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewStaticSlateDelegate(py_callable);

	if (py_obj)
	{
		Py_INCREF(py_obj);
		handler.BindSP(py_delegate, &FPythonSlateDelegate::ExecuteAction, py_obj);
	}
	else
	{
		handler.BindSP(py_delegate, &FPythonSlateDelegate::SimpleExecuteAction);
	}

	self->menu_builder.AddMenuEntry(FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), FSlateIcon(), FUIAction(handler), NAME_None,
		(EUserInterfaceActionType::Type)ui_action_type);

	Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder *self, PyObject * args)
{
	char *name = nullptr;

	if (!PyArg_ParseTuple(args, "|s:add_menu_separator", &name))
		return nullptr;

	FName f_name = NAME_None;

	if (name)
		f_name = FName(UTF8_TO_TCHAR(name));

	self->menu_builder.AddMenuSeparator(f_name);

	Py_RETURN_NONE;
}

#if WITH_EDITOR
static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self, PyObject * args)
{
	PyObject *py_assets;

	if (!PyArg_ParseTuple(args, "O:add_asset_actions", &py_assets))
		return nullptr;

	py_assets = PyObject_GetIter(py_assets);
	if (!py_assets)
	{
		return PyErr_Format(PyExc_Exception, "argument is not iterable");
	}

	TArray<UObject *> u_objects;
	while (PyObject *item = PyIter_Next(py_assets))
	{
		UObject *u_object = ue_py_check_type<UObject>(item);
		if (u_object)
		{
			u_objects.Add(u_object);
		}
	}
	Py_DECREF(py_assets);

	FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
	bool addedSomething = AssetToolsModule.Get().GetAssetActions(u_objects, self->menu_builder, true);
	if (addedSomething)
	{
		Py_RETURN_TRUE;
	}

	Py_RETURN_FALSE;
}
#endif

static PyObject *py_ue_fmenu_builder_add_search_widget(ue_PyFMenuBuilder *self, PyObject * args)
{
	self->menu_builder.AddSearchWidget();

	Py_RETURN_NONE;
}

static PyMethodDef ue_PyFMenuBuilder_methods[] = {
	{ "begin_section", (PyCFunction)py_ue_fmenu_builder_begin_section, METH_VARARGS, "" },
	{ "end_section", (PyCFunction)py_ue_fmenu_builder_end_section, METH_VARARGS, "" },
	{ "make_widget", (PyCFunction)py_ue_fmenu_builder_make_widget, METH_VARARGS, "" },
	{ "add_menu_entry", (PyCFunction)py_ue_fmenu_builder_add_menu_entry, METH_VARARGS, "" },
	{ "add_menu_separator", (PyCFunction)py_ue_fmenu_builder_add_menu_separator, METH_VARARGS, "" },
	{ "add_search_widget", (PyCFunction)py_ue_fmenu_builder_add_search_widget, METH_VARARGS, "" },
#if WITH_EDITOR
	{ "add_asset_actions", (PyCFunction)py_ue_fmenu_builder_add_asset_actions, METH_VARARGS, "" },
#endif
	{ NULL }  /* Sentinel */
};

static PyObject *ue_PyFMenuBuilder_str(ue_PyFMenuBuilder *self)
{
	return PyUnicode_FromFormat("<unreal_engine.FMenuBuilder '%p'}>",
		&self->menu_builder);
}

static void ue_py_fmenu_builder_dealloc(ue_PyFMenuBuilder *self)
{
#if PY_MAJOR_VERSION < 3
	self->ob_type->tp_free((PyObject*)self);
#else
	Py_TYPE(self)->tp_free((PyObject*)self);
#endif
}

static PyTypeObject ue_PyFMenuBuilderType = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"unreal_engine.FMenuBuilder", /* tp_name */
	sizeof(ue_PyFMenuBuilder), /* tp_basicsize */
	0,                         /* tp_itemsize */
	(destructor)ue_py_fmenu_builder_dealloc,       /* tp_dealloc */
	0,                         /* tp_print */
	0,                         /* tp_getattr */
	0,                         /* tp_setattr */
	0,                         /* tp_reserved */
	0,                         /* tp_repr */
	0,                         /* tp_as_number */
	0,                         /* tp_as_sequence */
	0,                         /* tp_as_mapping */
	0,                         /* tp_hash  */
	0,                         /* tp_call */
	(reprfunc)ue_PyFMenuBuilder_str,                         /* tp_str */
	0,                         /* tp_getattro */
	0,                         /* tp_setattro */
	0,                         /* tp_as_buffer */
	Py_TPFLAGS_DEFAULT,        /* tp_flags */
	"Unreal Engine FMenuBuilder",           /* tp_doc */
	0,                         /* tp_traverse */
	0,                         /* tp_clear */
	0,                         /* tp_richcompare */
	0,                         /* tp_weaklistoffset */
	0,                         /* tp_iter */
	0,                         /* tp_iternext */
	ue_PyFMenuBuilder_methods,             /* tp_methods */
};

static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder *self, PyObject *args, PyObject *kwargs)
{
	new(&self->menu_builder) FMenuBuilder(true, nullptr);
	return 0;
}

void ue_python_init_fmenu_builder(PyObject *ue_module)
{
	ue_PyFMenuBuilderType.tp_new = PyType_GenericNew;

	ue_PyFMenuBuilderType.tp_init = (initproc)ue_py_fmenu_builder_init;

	if (PyType_Ready(&ue_PyFMenuBuilderType) < 0)
		return;

	Py_INCREF(&ue_PyFMenuBuilderType);
	PyModule_AddObject(ue_module, "FMenuBuilder", (PyObject *)&ue_PyFMenuBuilderType);
}

PyObject *py_ue_new_fmenu_builder(FMenuBuilder menu_builder)
{
	ue_PyFMenuBuilder *ret = (ue_PyFMenuBuilder *)PyObject_New(ue_PyFMenuBuilder, &ue_PyFMenuBuilderType);
	new(&ret->menu_builder) FMenuBuilder(menu_builder);
	return (PyObject *)ret;
}
<commit_msg>Add extension to py_ue_fmenu_builder_add_menu_entry to support is checked delegate<commit_after>#include "UEPyFMenuBuilder.h"

#include "Wrappers/UEPyESlateEnums.h"

static PyObject *py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder *self, PyObject * args)
{
	char *name;
	char *text;
	if (!PyArg_ParseTuple(args, "ss:begin_section", &name, &text))
		return nullptr;

	self->menu_builder.BeginSection(name, FText::FromString(UTF8_TO_TCHAR(text)));

	Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_end_section(ue_PyFMenuBuilder *self, PyObject * args)
{
	self->menu_builder.EndSection();

	Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_make_widget(ue_PyFMenuBuilder *self, PyObject * args)
{
    ue_PySWidget *ret = py_ue_new_swidget<ue_PySWidget>(self->menu_builder.MakeWidget(), &ue_PySWidgetType);
	return (PyObject *)ret;
}

static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyObject * args)
{
	char *label;
	char *tooltip;
	PyObject *py_callableExecAction = nullptr;
    PyObject *py_callableIsActnChecked = nullptr;
	PyObject *py_obj = nullptr;
	int ui_action_type = EUserInterfaceActionType::Button;
	if (!PyArg_ParseTuple(args, "ssO|OiO:add_menu_entry", &label, &tooltip, &py_callableExecAction, &py_obj, &ui_action_type, &py_callableIsActnChecked))
		return nullptr;

	if (!PyCalllable_Check_Extended(py_callableExecAction))
	{
		return PyErr_Format(PyExc_Exception, "argument is not callable");
	}

    if (py_callableIsActnChecked && !PyCalllable_Check_Extended(py_callableIsActnChecked))
    {
        return PyErr_Format(PyExc_Exception, "IsActnChecked argument is not callable");
    }

	FExecuteAction execActionHandler;
	TSharedRef<FPythonSlateDelegate> py_delegateExecAction = FUnrealEnginePythonHouseKeeper::Get()->NewStaticSlateDelegate(py_callableExecAction);

	if (py_obj && py_obj != Py_None)
	{
		Py_INCREF(py_obj);
		execActionHandler.BindSP(py_delegateExecAction, &FPythonSlateDelegate::ExecuteAction, py_obj);
	}
	else
	{
		execActionHandler.BindSP(py_delegateExecAction, &FPythonSlateDelegate::SimpleExecuteAction);
	}

    FCanExecuteAction canExecActnHandler = FCanExecuteAction::CreateRaw(&FSlateApplication::Get(), &FSlateApplication::IsNormalExecution);

    FIsActionChecked isActnChkdHandler;
    if (py_callableIsActnChecked)
    {
        if (!PyCalllable_Check_Extended(py_callableIsActnChecked))
        {
            return PyErr_Format(PyExc_Exception, "IsActnChecked argument is not callable");
        }
        TSharedRef<FPythonSlateDelegate> py_delegateIsActnChecked = FUnrealEnginePythonHouseKeeper::Get()->NewStaticSlateDelegate(py_callableIsActnChecked);
        isActnChkdHandler.BindSP(py_delegateIsActnChecked, &FPythonSlateDelegate::GetterBool);
    }

    FUIAction action_MenuEntry
    (
        execActionHandler,
        canExecActnHandler,
        isActnChkdHandler
    );

	self->menu_builder.AddMenuEntry(FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), FSlateIcon(), action_MenuEntry, NAME_None,
		(EUserInterfaceActionType::Type)ui_action_type);

	Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder *self, PyObject * args)
{
	char *name = nullptr;

	if (!PyArg_ParseTuple(args, "|s:add_menu_separator", &name))
		return nullptr;

	FName f_name = NAME_None;

	if (name)
		f_name = FName(UTF8_TO_TCHAR(name));

	self->menu_builder.AddMenuSeparator(f_name);

	Py_RETURN_NONE;
}

#if WITH_EDITOR
static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self, PyObject * args)
{
	PyObject *py_assets;

	if (!PyArg_ParseTuple(args, "O:add_asset_actions", &py_assets))
		return nullptr;

	py_assets = PyObject_GetIter(py_assets);
	if (!py_assets)
	{
		return PyErr_Format(PyExc_Exception, "argument is not iterable");
	}

	TArray<UObject *> u_objects;
	while (PyObject *item = PyIter_Next(py_assets))
	{
		UObject *u_object = ue_py_check_type<UObject>(item);
		if (u_object)
		{
			u_objects.Add(u_object);
		}
	}
	Py_DECREF(py_assets);

	FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
	bool addedSomething = AssetToolsModule.Get().GetAssetActions(u_objects, self->menu_builder, true);
	if (addedSomething)
	{
		Py_RETURN_TRUE;
	}

	Py_RETURN_FALSE;
}
#endif

static PyObject *py_ue_fmenu_builder_add_search_widget(ue_PyFMenuBuilder *self, PyObject * args)
{
	self->menu_builder.AddSearchWidget();

	Py_RETURN_NONE;
}

static PyMethodDef ue_PyFMenuBuilder_methods[] = {
	{ "begin_section", (PyCFunction)py_ue_fmenu_builder_begin_section, METH_VARARGS, "" },
	{ "end_section", (PyCFunction)py_ue_fmenu_builder_end_section, METH_VARARGS, "" },
	{ "make_widget", (PyCFunction)py_ue_fmenu_builder_make_widget, METH_VARARGS, "" },
	{ "add_menu_entry", (PyCFunction)py_ue_fmenu_builder_add_menu_entry, METH_VARARGS, "" },
	{ "add_menu_separator", (PyCFunction)py_ue_fmenu_builder_add_menu_separator, METH_VARARGS, "" },
	{ "add_search_widget", (PyCFunction)py_ue_fmenu_builder_add_search_widget, METH_VARARGS, "" },
#if WITH_EDITOR
	{ "add_asset_actions", (PyCFunction)py_ue_fmenu_builder_add_asset_actions, METH_VARARGS, "" },
#endif
	{ NULL }  /* Sentinel */
};

static PyObject *ue_PyFMenuBuilder_str(ue_PyFMenuBuilder *self)
{
	return PyUnicode_FromFormat("<unreal_engine.FMenuBuilder '%p'}>",
		&self->menu_builder);
}

static void ue_py_fmenu_builder_dealloc(ue_PyFMenuBuilder *self)
{
#if PY_MAJOR_VERSION < 3
	self->ob_type->tp_free((PyObject*)self);
#else
	Py_TYPE(self)->tp_free((PyObject*)self);
#endif
}

static PyTypeObject ue_PyFMenuBuilderType = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"unreal_engine.FMenuBuilder", /* tp_name */
	sizeof(ue_PyFMenuBuilder), /* tp_basicsize */
	0,                         /* tp_itemsize */
	(destructor)ue_py_fmenu_builder_dealloc,       /* tp_dealloc */
	0,                         /* tp_print */
	0,                         /* tp_getattr */
	0,                         /* tp_setattr */
	0,                         /* tp_reserved */
	0,                         /* tp_repr */
	0,                         /* tp_as_number */
	0,                         /* tp_as_sequence */
	0,                         /* tp_as_mapping */
	0,                         /* tp_hash  */
	0,                         /* tp_call */
	(reprfunc)ue_PyFMenuBuilder_str,                         /* tp_str */
	0,                         /* tp_getattro */
	0,                         /* tp_setattro */
	0,                         /* tp_as_buffer */
	Py_TPFLAGS_DEFAULT,        /* tp_flags */
	"Unreal Engine FMenuBuilder",           /* tp_doc */
	0,                         /* tp_traverse */
	0,                         /* tp_clear */
	0,                         /* tp_richcompare */
	0,                         /* tp_weaklistoffset */
	0,                         /* tp_iter */
	0,                         /* tp_iternext */
	ue_PyFMenuBuilder_methods,             /* tp_methods */
};

static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder *self, PyObject *args, PyObject *kwargs)
{
	new(&self->menu_builder) FMenuBuilder(true, nullptr);
	return 0;
}

void ue_python_init_fmenu_builder(PyObject *ue_module)
{
	ue_PyFMenuBuilderType.tp_new = PyType_GenericNew;

	ue_PyFMenuBuilderType.tp_init = (initproc)ue_py_fmenu_builder_init;

	if (PyType_Ready(&ue_PyFMenuBuilderType) < 0)
		return;

	Py_INCREF(&ue_PyFMenuBuilderType);
	PyModule_AddObject(ue_module, "FMenuBuilder", (PyObject *)&ue_PyFMenuBuilderType);
}

PyObject *py_ue_new_fmenu_builder(FMenuBuilder menu_builder)
{
	ue_PyFMenuBuilder *ret = (ue_PyFMenuBuilder *)PyObject_New(ue_PyFMenuBuilder, &ue_PyFMenuBuilderType);
	new(&ret->menu_builder) FMenuBuilder(menu_builder);
	return (PyObject *)ret;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2022 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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.
 */

#pragma once

#include "stock/AbstractStock.hxx"

class StockLoggerDomain {
	const AbstractStock &stock;

public:
	explicit StockLoggerDomain(const AbstractStock &_stock) noexcept
		:stock(_stock) {}

	StringView GetDomain() const {
		return stock.GetName();
	}
};
<commit_msg>stock/LoggerDomain: use std::string_view<commit_after>/*
 * Copyright 2007-2022 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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.
 */

#pragma once

#include "stock/AbstractStock.hxx"

class StockLoggerDomain {
	const AbstractStock &stock;

public:
	explicit StockLoggerDomain(const AbstractStock &_stock) noexcept
		:stock(_stock) {}

	std::string_view GetDomain() const noexcept {
		return stock.GetName();
	}
};
<|endoftext|>


<commit_before>/*!
 * Copyright (c) 2015 by Contributors
 */
#define _ISOC11_SOURCE
#include "./cpu_storage.h"
#include <dmlc/logging.h>
#include <cstdlib>

namespace mxnet {
namespace storage {

void* CpuStorage::Alloc(size_t size) {
  return CHECK_NOTNULL(aligned_alloc(alignment_, size));
}

void CpuStorage::Free(void* ptr) { free(ptr); }

}  // namespace storage
}  // namespace mxnet
<commit_msg>[storage] try change header<commit_after>/*!
 * Copyright (c) 2015 by Contributors
 */
#define _ISOC11_SOURCE
#include "./cpu_storage.h"
#include <dmlc/logging.h>
#include <stdlib.h>

namespace mxnet {
namespace storage {

void* CpuStorage::Alloc(size_t size) {
  return CHECK_NOTNULL(aligned_alloc(alignment_, size));
}

void CpuStorage::Free(void* ptr) { free(ptr); }

}  // namespace storage
}  // namespace mxnet
<|endoftext|>


<commit_before>#include <Ancona/Engine/Core/Systems/Drawable/AnimatedDrawable.hpp>

using namespace ild;

AnimatedDrawable::AnimatedDrawable(
        const PositionComponent & positionComponent,
        const std::string textureKey,
        const int priority,
        sf::Vector2f frameDimensions,
        int numFrames,
        float duration,
        int priorityOffset,
        sf::Vector2f positionOffset) :
    _frameDimensions(frameDimensions),
    _numFrames(numFrames),
    DURATION(duration),
    _timeUntilChange(duration),
    SpriteDrawable(
            positionComponent,
            textureKey,
            priority,
            priorityOffset,
            positionOffset)
{
    _sprite->setTextureRect(
            sf::IntRect(
                0,
                0,
                _frameDimensions.x,
                _frameDimensions.y));
    _sprite->setOrigin(
            _frameDimensions.x / 2,
            _frameDimensions.y / 2);
}

void AnimatedDrawable::Draw(sf::RenderWindow & window, float delta)
{
    _timeUntilChange -= delta;
    if(_timeUntilChange <= 0)
    {
        _timeUntilChange += DURATION;
        AdvanceFrame();
    }
    SpriteDrawable::Draw(window, delta);
}

void AnimatedDrawable::AdvanceFrame()
{
    _curFrame++;
    if(_curFrame == _numFrames)
    {
        _curFrame = 0;
    }
    _sprite->setTextureRect(
            sf::IntRect(
                _curFrame * _frameDimensions.x,
                0,
                _frameDimensions.x,
                _frameDimensions.y));
}
<commit_msg>ANC-14 Allow AnimationDrawable's texture to be on multiple rows.<commit_after>#include <Ancona/Engine/Core/Systems/Drawable/AnimatedDrawable.hpp>

using namespace ild;

AnimatedDrawable::AnimatedDrawable(
        const PositionComponent & positionComponent,
        const std::string textureKey,
        const int priority,
        sf::Vector2f frameDimensions,
        int numFrames,
        float duration,
        int priorityOffset,
        sf::Vector2f positionOffset) :
    _frameDimensions(frameDimensions),
    _numFrames(numFrames),
    DURATION(duration),
    _timeUntilChange(duration),
    SpriteDrawable(
            positionComponent,
            textureKey,
            priority,
            priorityOffset,
            positionOffset)
{
    _sprite->setTextureRect(
            sf::IntRect(
                0,
                0,
                _frameDimensions.x,
                _frameDimensions.y));
    _sprite->setOrigin(
            _frameDimensions.x / 2,
            _frameDimensions.y / 2);
}

void AnimatedDrawable::Draw(sf::RenderWindow & window, float delta)
{
    _timeUntilChange -= delta;
    if(_timeUntilChange <= 0)
    {
        _timeUntilChange += DURATION;
        AdvanceFrame();
    }
    SpriteDrawable::Draw(window, delta);
}

void AnimatedDrawable::AdvanceFrame()
{
    _curFrame++;
    if(_curFrame == _numFrames)
    {
        _curFrame = 0;
    }
    float newX = _sprite->getTextureRect().left + _frameDimensions.x;
    float newY = _sprite->getTextureRect().top;
    if(newX >= _sprite->getTexture()->getSize().x)
    {
        newX = 0;
        newY += _frameDimensions.y;
        if(newY >= _sprite->getTexture()->getSize().y)
        {
            newY = 0;
        }
    }
    _sprite->setTextureRect(
            sf::IntRect(
                newX,
                newY,
                _frameDimensions.x,
                _frameDimensions.y));
}
<|endoftext|>


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

// own
#include "Importer.h"
// ospcommon
#include "common/FileName.h"
// ospray api
#include "ospray/ospray.h"

namespace ospray {
  namespace vv_importer {

    /*! helper function to help build voxel ranges during parsing */
    template<typename T>
    inline void extendVoxelRange(ospcommon::vec2f &voxelRange, const T *voxel, size_t num)
    {
      for (size_t i=0;i<num;i++) {
        voxelRange.x = std::min(voxelRange.x,(float)voxel[i]);
        voxelRange.y = std::max(voxelRange.y,(float)voxel[i]);
      }
    }

    void importVolumeRAW(const FileName &fileName, Volume *volume)
    {
      std::string filename = fileName.str();
      // Look for the volume data file at the given path.
      FILE *file = NULL;
      FileName fn = fileName;
      bool gzipped = fn.ext() == "gz";
      if (gzipped) {
        std::string cmd = "/usr/bin/gunzip -c "+filename;
        file = popen(cmd.c_str(),"r");
      } else {
        file = fopen(filename.c_str(),"rb");
      }
      //FILE *file = fopen(filename.c_str(), "rb");
      exitOnCondition(!file, "unable to open file '" + filename + "'");

      // Offset into the volume data file if any.
      if (volume->fileOffset > 0)
        fseek(file, volume->fileOffset, SEEK_SET);

      // Volume dimensions.
      ospcommon::vec3i volumeDimensions = volume->dimensions;
      assert(volumeDimensions != vec3i(0) && volumeDimensions != vec3i(-1));

      // Voxel type string.
      const char *voxelType = volume->voxelType.c_str();
      // Voxel size in bytes.
      size_t voxelSize;

      if (strcmp(voxelType, "uchar") == 0)
        voxelSize = sizeof(unsigned char);
      else if (strcmp(voxelType, "float") == 0)
        voxelSize = sizeof(float);
      else if (strcmp(voxelType, "double") == 0)
        voxelSize = sizeof(double);
      else
        exitOnCondition(true, "unsupported voxel type");
      ospSetString(volume->handle,"voxelType",voxelType);

      // Check if a subvolume of the volume has been specified.
      // Subvolume params: subvolumeOffsets, subvolumeDimensions, subvolumeSteps.
      // The subvolume defaults to full dimensions (allowing for just subsampling,
      // for example).
      ospcommon::vec3i subvolumeOffsets = volume->subVolumeOffsets;
      exitOnCondition(reduce_min(subvolumeOffsets) < 0 ||
                      reduce_max(subvolumeOffsets - volumeDimensions) >= 0,
                      "invalid subvolume offsets");

      ospcommon::vec3i subvolumeDimensions = volumeDimensions - subvolumeOffsets;
      if (volume->subVolumeDimensions != vec3i(-1))
        subvolumeDimensions = volume->subVolumeDimensions;

      exitOnCondition(reduce_min(subvolumeDimensions) < 1 ||
                      reduce_max(subvolumeDimensions -
                                 (volumeDimensions - subvolumeOffsets)) > 0,
                      "invalid subvolume dimension(s) specified");

      ospcommon::vec3i subvolumeSteps = ospcommon::vec3i(1);
      if (volume->subVolumeSteps != vec3i(-1))
        subvolumeSteps = volume->subVolumeSteps;
      exitOnCondition(reduce_min(subvolumeSteps) < 1 ||
                      reduce_max(subvolumeSteps -
                                 (volumeDimensions - subvolumeOffsets)) >= 0,
                      "invalid subvolume steps");

      bool useSubvolume = false;

      // The dimensions of the volume to be imported; this will be changed if a
      // subvolume is specified.
      ospcommon::vec3i importVolumeDimensions = volumeDimensions;

      if (reduce_max(subvolumeOffsets) > 0 ||
          subvolumeDimensions != volumeDimensions ||
          reduce_max(subvolumeSteps) > 1) {

        useSubvolume = true;

        // The dimensions of the volume to be imported, considering the subvolume
        // specified.
        int xdim = subvolumeDimensions.x / subvolumeSteps.x +
          (subvolumeDimensions.x % subvolumeSteps.x != 0);
        int ydim = subvolumeDimensions.y / subvolumeSteps.y +
          (subvolumeDimensions.y % subvolumeSteps.y != 0);
        int zdim = subvolumeDimensions.z / subvolumeSteps.z +
          (subvolumeDimensions.z % subvolumeSteps.z != 0);
        importVolumeDimensions = ospcommon::vec3i(xdim, ydim, zdim);

        // Range check.
        exitOnCondition(reduce_min(importVolumeDimensions) <= 0,
                        "invalid import volume dimensions");

        // Update the provided dimensions of the volume for the subvolume specified.
        ospSetVec3i(volume->handle, "dimensions", (osp::vec3i&)importVolumeDimensions);
      }
      else
        ospSetVec3i(volume->handle, "dimensions", (osp::vec3i&)volumeDimensions);
      PRINT(volumeDimensions);

      if (!useSubvolume) {

        size_t numSlicesPerSetRegion = 4;

        // Voxel count.
        size_t voxelCount = volumeDimensions.x * volumeDimensions.y;

        // Allocate memory for a single slice through the volume.
        unsigned char *voxelData =
          new unsigned char[numSlicesPerSetRegion * voxelCount * voxelSize];

        // We copy data into the volume by the slice in case memory is limited.
        for (size_t z = 0 ; z < volumeDimensions.z ; z += numSlicesPerSetRegion) {

          // Copy voxel data into the buffer.
          size_t slicesToRead = std::min(numSlicesPerSetRegion,
                                         volumeDimensions.z - z);

          size_t voxelsRead = fread(voxelData,
                                    voxelSize,
                                    slicesToRead * voxelCount,
                                    file);

          // The end of the file may have been reached unexpectedly.
          exitOnCondition(voxelsRead != slicesToRead*voxelCount,
                          "end of volume file reached before read completed");

          if (strcmp(voxelType, "uchar") == 0) {
            extendVoxelRange(volume->voxelRange,
                             (unsigned char *)voxelData,
                             volumeDimensions.x*volumeDimensions.y);
          }
          else if (strcmp(voxelType, "float") == 0) {
            extendVoxelRange(volume->voxelRange,
                             (float *)voxelData,
                             volumeDimensions.x*volumeDimensions.y);
          }
          else if (strcmp(voxelType, "double") == 0) {
            extendVoxelRange(volume->voxelRange,
                             (double *)voxelData,
                             volumeDimensions.x*volumeDimensions.y);
          }
          else {
            exitOnCondition(true, "unsupported voxel type");
          }

          ospcommon::vec3i region_lo(0, 0, z);
          ospcommon::vec3i region_sz(volumeDimensions.x,
                                     volumeDimensions.y,
                                     slicesToRead);
          // Copy the voxels into the volume.
          ospSetRegion(volume->handle,
                       voxelData,
                       (osp::vec3i&)region_lo,
                       (osp::vec3i&)region_sz);
        }

        ospSet2f(volume->handle,"voxelRange",volume->voxelRange.x,volume->voxelRange.y);

        // Clean up.
        delete [] voxelData;

      } else {

        throw std::runtime_error("subvolumes not yet implemented for RAW files ...");

        //   // Allocate memory for a single row of voxel data.
        //   unsigned char *rowData = new unsigned char[volumeDimensions.x * voxelSize];

        //   // Allocate memory for a single row of voxel data for the subvolume.
        //   unsigned char *subvolumeRowData =
        //     new unsigned char[importVolumeDimensions.x * voxelSize];

        //   // Read the subvolume data from the full volume.
        //   for(long i3 = subvolumeOffsets.z;
        //       i3 < subvolumeOffsets.z + subvolumeDimensions.z;
        //       i3 += subvolumeSteps.z) {

        //     for(long i2 = subvolumeOffsets.y;
        //         i2 < subvolumeOffsets.y + subvolumeDimensions.y;
        //         i2+=subvolumeSteps.y) {

        //       // Seek to appropriate location in file.
        //       fseek(file,
        //             volume->offset +
        //             (i3 * volumeDimensions.y * volumeDimensions.x * voxelSize) +
        //             (i2 * volumeDimensions.x * voxelSize), SEEK_SET);

        //       // Read row from volume.
        //       size_t voxelsRead = fread(rowData, voxelSize, volumeDimensions.x, file);

        //       // The end of the file may have been reached unexpectedly.
        //       exitOnCondition(voxelsRead != volumeDimensions.x,
        //                       "end of volume file reached before read completed");

        //       // Resample row for the subvolume.
        //       for(long i1 = subvolumeOffsets.x;
        //           i1 < subvolumeOffsets.x+subvolumeDimensions.x;
        //           i1 += subvolumeSteps.x) {
        //         memcpy(&subvolumeRowData[(i1 - subvolumeOffsets.x) /
        //                                  subvolumeSteps.x * voxelSize],
        //                &rowData[i1 * voxelSize],
        //                voxelSize);
        //       }

        //       // Copy subvolume row into the volume.
        //       ospcommon::vec3i region_lo(0,
        //                                  (i2 - subvolumeOffsets.y) / subvolumeSteps.y,
        //                                  (i3 - subvolumeOffsets.z) / subvolumeSteps.z);
        //       ospcommon::vec3i region_sz(importVolumeDimensions.x, 1, 1);
        //       ospSetRegion(volume,
        //                    &subvolumeRowData[0],
        //                    (osp::vec3i&)region_lo,
        //                    (osp::vec3i&)region_sz);
        //     }
        //   }

        //   // Clean up.
        //   delete [] rowData;
        //   delete [] subvolumeRowData;
      }

      volume->bounds = ospcommon::empty;
      volume->bounds.extend(volume->gridOrigin);
      volume->bounds.extend(volume->gridOrigin+ vec3f(volume->dimensions) * volume->gridSpacing);

      if (gzipped)
        pclose(file);
      else
        fclose(file);
      // Return the volume.

    }

  } // ::ospray::vv
} // ::ospray
<commit_msg>Port chunked loading in to the new raw importer<commit_after>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

// own
#include "Importer.h"
// ospcommon
#include "common/FileName.h"
// ospray api
#include "ospray/ospray.h"

namespace ospray {
  namespace vv_importer {

    /*! helper function to help build voxel ranges during parsing */
    template<typename T>
    inline void extendVoxelRange(ospcommon::vec2f &voxelRange, const T *voxel, size_t num)
    {
      for (size_t i=0;i<num;i++) {
        voxelRange.x = std::min(voxelRange.x,(float)voxel[i]);
        voxelRange.y = std::max(voxelRange.y,(float)voxel[i]);
      }
    }
    //! Convenient wrapper that will do the template dispatch for you based on the voxelSize passed
    //! voxelSize = 1 -> unsigned char
    //! voxelSize = 2 -> uint16_t
    //! voxelSize = 4 -> float
    //! voxelSize = 8 -> double
    inline void extendVoxelRange(ospcommon::vec2f &voxelRange, const size_t voxelSize, const unsigned char *voxels,
        const size_t numVoxels)
    {
      switch (voxelSize) {
        case sizeof(unsigned char):
          extendVoxelRange(voxelRange, (unsigned char*)voxels, numVoxels);
          break;
        case sizeof(float):
          extendVoxelRange(voxelRange, (float*)voxels, numVoxels);
          break;
        case sizeof(double):
          extendVoxelRange(voxelRange, (double*)voxels, numVoxels);
          break;
        default:
          std::cerr << "ERROR: unsupported voxel type with size " << voxelSize << std::endl;
          exit(1);
      }
    }

    void importVolumeRAW(const FileName &fileName, Volume *volume)
    {
      std::string filename = fileName.str();
      // Look for the volume data file at the given path.
      FILE *file = NULL;
      FileName fn = fileName;
      bool gzipped = fn.ext() == "gz";
      if (gzipped) {
        std::string cmd = "/usr/bin/gunzip -c "+filename;
        file = popen(cmd.c_str(),"r");
      } else {
        file = fopen(filename.c_str(),"rb");
      }
      //FILE *file = fopen(filename.c_str(), "rb");
      exitOnCondition(!file, "unable to open file '" + filename + "'");

      // Offset into the volume data file if any.
      if (volume->fileOffset > 0)
        fseek(file, volume->fileOffset, SEEK_SET);

      // Volume dimensions.
      ospcommon::vec3i volumeDimensions = volume->dimensions;
      assert(volumeDimensions != vec3i(0) && volumeDimensions != vec3i(-1));

      // Voxel type string.
      const char *voxelType = volume->voxelType.c_str();
      // Voxel size in bytes.
      size_t voxelSize;

      if (strcmp(voxelType, "uchar") == 0)
        voxelSize = sizeof(unsigned char);
      else if (strcmp(voxelType, "float") == 0)
        voxelSize = sizeof(float);
      else if (strcmp(voxelType, "double") == 0)
        voxelSize = sizeof(double);
      else
        exitOnCondition(true, "unsupported voxel type");
      ospSetString(volume->handle,"voxelType",voxelType);

      // Check if a subvolume of the volume has been specified.
      // Subvolume params: subvolumeOffsets, subvolumeDimensions, subvolumeSteps.
      // The subvolume defaults to full dimensions (allowing for just subsampling,
      // for example).
      ospcommon::vec3i subvolumeOffsets = volume->subVolumeOffsets;
      exitOnCondition(reduce_min(subvolumeOffsets) < 0 ||
                      reduce_max(subvolumeOffsets - volumeDimensions) >= 0,
                      "invalid subvolume offsets");

      ospcommon::vec3i subvolumeDimensions = volumeDimensions - subvolumeOffsets;
      if (volume->subVolumeDimensions != vec3i(-1))
        subvolumeDimensions = volume->subVolumeDimensions;

      exitOnCondition(reduce_min(subvolumeDimensions) < 1 ||
                      reduce_max(subvolumeDimensions -
                                 (volumeDimensions - subvolumeOffsets)) > 0,
                      "invalid subvolume dimension(s) specified");

      ospcommon::vec3i subvolumeSteps = ospcommon::vec3i(1);
      if (volume->subVolumeSteps != vec3i(-1))
        subvolumeSteps = volume->subVolumeSteps;
      exitOnCondition(reduce_min(subvolumeSteps) < 1 ||
                      reduce_max(subvolumeSteps -
                                 (volumeDimensions - subvolumeOffsets)) >= 0,
                      "invalid subvolume steps");

      bool useSubvolume = false;

      // The dimensions of the volume to be imported; this will be changed if a
      // subvolume is specified.
      ospcommon::vec3i importVolumeDimensions = volumeDimensions;

      if (reduce_max(subvolumeOffsets) > 0 ||
          subvolumeDimensions != volumeDimensions ||
          reduce_max(subvolumeSteps) > 1) {

        useSubvolume = true;

        // The dimensions of the volume to be imported, considering the subvolume
        // specified.
        int xdim = subvolumeDimensions.x / subvolumeSteps.x +
          (subvolumeDimensions.x % subvolumeSteps.x != 0);
        int ydim = subvolumeDimensions.y / subvolumeSteps.y +
          (subvolumeDimensions.y % subvolumeSteps.y != 0);
        int zdim = subvolumeDimensions.z / subvolumeSteps.z +
          (subvolumeDimensions.z % subvolumeSteps.z != 0);
        importVolumeDimensions = ospcommon::vec3i(xdim, ydim, zdim);

        // Range check.
        exitOnCondition(reduce_min(importVolumeDimensions) <= 0,
                        "invalid import volume dimensions");

        // Update the provided dimensions of the volume for the subvolume specified.
        ospSetVec3i(volume->handle, "dimensions", (osp::vec3i&)importVolumeDimensions);
      }
      else
        ospSetVec3i(volume->handle, "dimensions", (osp::vec3i&)volumeDimensions);
      PRINT(volumeDimensions);

      // To avoid hitting memory limits or exceeding the 2GB limit in MPIDevice::ospSetRegion we
      // set the volume data in at 1.5GB chunks
      // TODO How to compute these chunks, they must be convex as well, e.g. we can't set
      // 2.5 scanlines of the data b/c of the params we give to setRegion are the start & size of the chunk.
      // For testing try with super tiny 1k chunks
      const int SET_REGION_CHUNK_SIZE = 1512e6;
      const int MAX_CHUNK_VOXELS = SET_REGION_CHUNK_SIZE / voxelSize;
      // For chunk dims we must step biggest along X until we hit chunkDim.x == volumeDimensions.x
      // then increase chunk size along Y until we hit chunkDim.y == volumeDimensions.y and then
      // we can increase chunk size along Z (assumes row order is XYZ which should be fine for any sane raw file)
      osp::vec3i chunkDimensions;
      chunkDimensions.x = MAX_CHUNK_VOXELS;
      chunkDimensions.y = 1;
      chunkDimensions.z = 1;
      if (chunkDimensions.x > volumeDimensions.x) {
        chunkDimensions.x = volumeDimensions.x;
        chunkDimensions.y = MAX_CHUNK_VOXELS / chunkDimensions.x;
        if (chunkDimensions.y > volumeDimensions.y) {
          chunkDimensions.y = volumeDimensions.y;
          chunkDimensions.z = std::min(volumeDimensions.z, MAX_CHUNK_VOXELS / (chunkDimensions.x * chunkDimensions.y));
        }
      }

      std::cout << "Reading volume in chunks of size {" << chunkDimensions.x << ", " << chunkDimensions.y
        << ", " << chunkDimensions.z << "}" << std::endl;

      if (!useSubvolume) {
        // Allocate memory for a single chunk
        const size_t chunkVoxels = chunkDimensions.x * chunkDimensions.y * chunkDimensions.z;
        unsigned char *voxelData = new unsigned char[chunkVoxels * voxelSize];
        osp::vec3i numChunks;
        numChunks.x = volumeDimensions.x / chunkDimensions.x;
        numChunks.y = volumeDimensions.y / chunkDimensions.y;
        numChunks.z = volumeDimensions.z / chunkDimensions.z;
        osp::vec3i remainderVoxels;
        remainderVoxels.x = volumeDimensions.x % chunkDimensions.x;
        remainderVoxels.y = volumeDimensions.y % chunkDimensions.y;
        remainderVoxels.z = volumeDimensions.z % chunkDimensions.z;
        std::cout << "Number of chunks on each axis = {" << numChunks.x << ", " << numChunks.y << ", "
          << numChunks.z << "}, remainderVoxels {" << remainderVoxels.x
          << ", " << remainderVoxels.y << ", " << remainderVoxels.z << "}, each chunk is "
          << chunkVoxels << " voxels " << std::endl;
        // Load and copy in each chunk of the volume data into the OSPRay volume
        for (int chunkz = 0; chunkz < numChunks.z; ++chunkz) {
          for (int chunky = 0; chunky < numChunks.y; ++chunky) {
            for (int chunkx = 0; chunkx < numChunks.x; ++chunkx) {
              size_t voxelsRead = fread(voxelData, voxelSize, chunkVoxels, file);
              // The end of the file may have been reached unexpectedly.
              exitOnCondition(voxelsRead != chunkVoxels, "end of volume file reached before read completed");

              extendVoxelRange(volume->voxelRange, voxelSize, voxelData, voxelsRead);
              ospcommon::vec3i region_lo(chunkx * chunkDimensions.x, chunky * chunkDimensions.y,
                  chunkz * chunkDimensions.z);

              ospSetRegion(volume->handle, voxelData, (osp::vec3i&)region_lo, chunkDimensions);
            }
            // Read any remainder voxels on the scanline
            if (remainderVoxels.x > 0) {
              // We should only have remainder along x if we couldn't fit a scanline in SET_REGION_CHUNK_SIZE
              assert(chunkDimensions.y == 1 && chunkDimensions.z == 1);
              size_t remainder = remainderVoxels.x;
              size_t voxelsRead = fread(voxelData, voxelSize, remainder, file);
              ospcommon::vec3i region_lo(numChunks.x * chunkDimensions.x, chunky * chunkDimensions.y,
                  chunkz * chunkDimensions.z);
              ospcommon::vec3i region_sz(remainderVoxels.x, chunkDimensions.y, chunkDimensions.z);

              extendVoxelRange(volume->voxelRange, voxelSize, voxelData, voxelsRead);
              ospSetRegion(volume->handle, voxelData, (osp::vec3i&)region_lo, (osp::vec3i&)region_sz);
            }
          }
          if (remainderVoxels.y > 0) {
            // We should only have remainder along y if we couldn't fit a slice in SET_REGION_CHUNK_SIZE
            assert(chunkDimensions.x == volumeDimensions.x && chunkDimensions.z == 1);
            size_t remainder = chunkDimensions.x * remainderVoxels.y;
            size_t voxelsRead = fread(voxelData, voxelSize, remainder, file);
            ospcommon::vec3i region_lo(0, numChunks.y * chunkDimensions.y,
                chunkz * chunkDimensions.z);
            ospcommon::vec3i region_sz(chunkDimensions.x, remainderVoxels.y, chunkDimensions.z);

            extendVoxelRange(volume->voxelRange, voxelSize, voxelData, voxelsRead);
            ospSetRegion(volume->handle, voxelData, (osp::vec3i&)region_lo, (osp::vec3i&)region_sz);
          }
        }
        if (remainderVoxels.z > 0) {
          // We should only have remainder along z if we couldn't fit the volume in SET_REGION_CHUNK_SIZE
          assert(chunkDimensions.x == volumeDimensions.x && chunkDimensions.y == volumeDimensions.y);
          size_t remainder = chunkDimensions.x * chunkDimensions.y * remainderVoxels.z;
          size_t voxelsRead = fread(voxelData, voxelSize, remainder, file);
          ospcommon::vec3i region_lo(0, 0, numChunks.z * chunkDimensions.z);
          ospcommon::vec3i region_sz(chunkDimensions.x, chunkDimensions.y, remainderVoxels.z);

          extendVoxelRange(volume->voxelRange, voxelSize, voxelData, voxelsRead);
          ospSetRegion(volume->handle, voxelData, (osp::vec3i&)region_lo, (osp::vec3i&)region_sz);
        }
        ospSet2f(volume->handle,"voxelRange",volume->voxelRange.x,volume->voxelRange.y);

        // Clean up.
        delete [] voxelData;
      } else {

        throw std::runtime_error("subvolumes not yet implemented for RAW files ...");

        //   // Allocate memory for a single row of voxel data.
        //   unsigned char *rowData = new unsigned char[volumeDimensions.x * voxelSize];

        //   // Allocate memory for a single row of voxel data for the subvolume.
        //   unsigned char *subvolumeRowData =
        //     new unsigned char[importVolumeDimensions.x * voxelSize];

        //   // Read the subvolume data from the full volume.
        //   for(long i3 = subvolumeOffsets.z;
        //       i3 < subvolumeOffsets.z + subvolumeDimensions.z;
        //       i3 += subvolumeSteps.z) {

        //     for(long i2 = subvolumeOffsets.y;
        //         i2 < subvolumeOffsets.y + subvolumeDimensions.y;
        //         i2+=subvolumeSteps.y) {

        //       // Seek to appropriate location in file.
        //       fseek(file,
        //             volume->offset +
        //             (i3 * volumeDimensions.y * volumeDimensions.x * voxelSize) +
        //             (i2 * volumeDimensions.x * voxelSize), SEEK_SET);

        //       // Read row from volume.
        //       size_t voxelsRead = fread(rowData, voxelSize, volumeDimensions.x, file);

        //       // The end of the file may have been reached unexpectedly.
        //       exitOnCondition(voxelsRead != volumeDimensions.x,
        //                       "end of volume file reached before read completed");

        //       // Resample row for the subvolume.
        //       for(long i1 = subvolumeOffsets.x;
        //           i1 < subvolumeOffsets.x+subvolumeDimensions.x;
        //           i1 += subvolumeSteps.x) {
        //         memcpy(&subvolumeRowData[(i1 - subvolumeOffsets.x) /
        //                                  subvolumeSteps.x * voxelSize],
        //                &rowData[i1 * voxelSize],
        //                voxelSize);
        //       }

        //       // Copy subvolume row into the volume.
        //       ospcommon::vec3i region_lo(0,
        //                                  (i2 - subvolumeOffsets.y) / subvolumeSteps.y,
        //                                  (i3 - subvolumeOffsets.z) / subvolumeSteps.z);
        //       ospcommon::vec3i region_sz(importVolumeDimensions.x, 1, 1);
        //       ospSetRegion(volume,
        //                    &subvolumeRowData[0],
        //                    (osp::vec3i&)region_lo,
        //                    (osp::vec3i&)region_sz);
        //     }
        //   }

        //   // Clean up.
        //   delete [] rowData;
        //   delete [] subvolumeRowData;
      }

      volume->bounds = ospcommon::empty;
      volume->bounds.extend(volume->gridOrigin);
      volume->bounds.extend(volume->gridOrigin+ vec3f(volume->dimensions) * volume->gridSpacing);

      if (gzipped)
        pclose(file);
      else
        fclose(file);
      // Return the volume.

    }

  } // ::ospray::vv
} // ::ospray
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkLevenbergMarquardtOptimizerTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2000 National Library of Medicine
  All rights reserved.

  See COPYRIGHT.txt for copyright details.

=========================================================================*/

#include <itkLevenbergMarquardtOptimizer.h>
#include <vnl/vnl_vector.h>
#include <vnl/vnl_matrix.h>
#include <itkPoint.h>

typedef vnl_matrix<double> MatrixType;
typedef vnl_vector<double> VectorType;

/**
 *
 *   This example solves the equation:
 *
 *     (a-3) x^2  + (b-2) y^2
 *
 *   for the (a,b) parameters
 *
 *   the solution is the vector | 3 2 |
 *
 *   (x,y) values are sampled over a rectangular domain
 *   whose size is defined by XRange and YRange
 *
 */
class CostFunction : public itk::LightObject
{
public:
  typedef CostFunction Self;
  typedef itk::LightObject  Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  itkNewMacro( Self );

  enum { XRange = 1,
         YRange = 1 };   // size of the domain to sample the cost function

  enum { SpaceDimension =  2 };
  enum { RangeDimension =  ( 2*XRange+1 ) * ( 2*YRange+1 ) };

  typedef itk::Point<double,SpaceDimension>    ParametersType;
  typedef VectorType                           MeasureType;
  typedef MatrixType                           DerivativeType;

  CostFunction()
  {
    m_Measure.resize(RangeDimension);
    m_Derivative.resize(RangeDimension,SpaceDimension);
  }

  const ParametersType  & GetParameters(void) const
  {
    return m_Parameters;
  }

  const MeasureType & GetValue( const ParametersType & parameters )
  {

    m_Parameters = parameters;

    std::cout << "GetValue( ";
    double a = m_Parameters[0];
    double b = m_Parameters[1];

    std::cout << a << " , ";
    std::cout << b << ") = ";

    // Compute points of the function over a square domain
    unsigned valueindex = 0;
    for( int y = -YRange; y<=YRange; y++ )
    {
      const double yp = y*y*b;
      for( int x = -XRange; x<=XRange; x++ )
      {
        m_Measure[valueindex] = a * x*x + yp - (3.0 * x*x + 2 * y*y );
        std::cout << m_Measure[valueindex] << "  ";
        valueindex++;
      }
    }

    std::cout << std::endl;

    return m_Measure;
 }

  const DerivativeType &  GetDerivative(
                 const ParametersType & parameters ) const
  {

    return m_Derivative;
  }

private:

  mutable ParametersType    m_Parameters;
  mutable MeasureType       m_Measure;
  mutable DerivativeType    m_Derivative;

};

int main()
{
  std::cout << "Levenberg Marquardt optimizer test \n \n";

  typedef  itk::LevenbergMarquardtOptimizer< \
                                CostFunction >  OptimizerType;

  typedef  OptimizerType::InternalOptimizerType  vnlOptimizerType;

  // Declaration of a itkOptimizer
  OptimizerType::Pointer  itkOptimizer = OptimizerType::New();

  // Declaration of the CostFunction adaptor
  CostFunction costFunction;

  itkOptimizer->SetCostFunction( &costFunction );

  const double F_Tolerance      = 1e-3;  // Function value tolerance
  const double G_Tolerance      = 1e-4;  // Gradient magnitude tolerance
  const double X_Tolerance      = 1e-8;  // Search space tolerance
  const double Epsilon_Function = 1e-10; // Step
  const int    Max_Iterations   =   100; // Maximum number of iterations

  vnlOptimizerType & vnlOptimizer = itkOptimizer->GetOptimizer();

  vnlOptimizer.set_f_tolerance( F_Tolerance );
  vnlOptimizer.set_g_tolerance( G_Tolerance );
  vnlOptimizer.set_x_tolerance( X_Tolerance );
  vnlOptimizer.set_epsilon_function( Epsilon_Function );
  vnlOptimizer.set_max_function_evals( Max_Iterations );

  vnlOptimizer.set_check_derivatives( 3 );

  // We start not so far from  | 3 2 |
  typedef CostFunction::ParametersType ParametersType;
  ParametersType initialValue;
  initialValue = 20,10;

  itkOptimizer->SetInitialPosition( initialValue );

  itkOptimizer->StartOptimization();

  std::cout << "End condition   = " << vnlOptimizer.get_failure_code() << std::endl;
  std::cout << "Number of iters = " << vnlOptimizer.get_num_iterations() << std::endl;
  std::cout << "Number of evals = " << vnlOptimizer.get_num_evaluations() << std::endl;
  std::cout << std::endl;

  ParametersType finalPosition;
  finalPosition = costFunction.GetParameters();
  std::cout << "Solution        = (";
  std::cout << finalPosition[0] << "," ;
  std::cout << finalPosition[1] << ")" << std::endl;

  return 0;

}

<commit_msg>ENH: Added test for numerical precision<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkLevenbergMarquardtOptimizerTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2000 National Library of Medicine
  All rights reserved.

  See COPYRIGHT.txt for copyright details.

=========================================================================*/

#include <itkLevenbergMarquardtOptimizer.h>
#include <vnl/vnl_vector.h>
#include <vnl/vnl_matrix.h>
#include <itkPoint.h>

typedef vnl_matrix<double> MatrixType;
typedef vnl_vector<double> VectorType;

/**
 *
 *   This example solves the equation:
 *
 *     (a-3) x^2  + (b-2) y^2
 *
 *   for the (a,b) parameters
 *
 *   the solution is the vector | 3 2 |
 *
 *   (x,y) values are sampled over a rectangular domain
 *   whose size is defined by XRange and YRange
 *
 */
class CostFunction : public itk::LightObject
{
public:
  typedef CostFunction Self;
  typedef itk::LightObject  Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  itkNewMacro( Self );

  enum { XRange = 1,
         YRange = 1 };   // size of the domain to sample the cost function

  enum { SpaceDimension =  2 };
  enum { RangeDimension =  ( 2*XRange+1 ) * ( 2*YRange+1 ) };

  typedef itk::Point<double,SpaceDimension>    ParametersType;
  typedef VectorType                           MeasureType;
  typedef MatrixType                           DerivativeType;

  CostFunction()
  {
    m_Measure.resize(RangeDimension);
    m_Derivative.resize(RangeDimension,SpaceDimension);
  }

  const ParametersType  & GetParameters(void) const
  {
    return m_Parameters;
  }

  const MeasureType & GetValue( const ParametersType & parameters )
  {

    m_Parameters = parameters;

    std::cout << "GetValue( ";
    double a = m_Parameters[0];
    double b = m_Parameters[1];

    std::cout << a << " , ";
    std::cout << b << ") = ";

    // Compute points of the function over a square domain
    unsigned valueindex = 0;
    for( int y = -YRange; y<=YRange; y++ )
    {
      const double yp = y*y*b;
      for( int x = -XRange; x<=XRange; x++ )
      {
        m_Measure[valueindex] = a * x*x + yp - (3.0 * x*x + 2 * y*y );
        std::cout << m_Measure[valueindex] << "  ";
        valueindex++;
      }
    }

    std::cout << std::endl;

    return m_Measure;
 }

  const DerivativeType &  GetDerivative(
                 const ParametersType & parameters ) const
  {

    return m_Derivative;
  }

private:

  mutable ParametersType    m_Parameters;
  mutable MeasureType       m_Measure;
  mutable DerivativeType    m_Derivative;

};

int main()
{
  std::cout << "Levenberg Marquardt optimizer test \n \n";

  typedef  itk::LevenbergMarquardtOptimizer< \
                                CostFunction >  OptimizerType;

  typedef  OptimizerType::InternalOptimizerType  vnlOptimizerType;

  // Declaration of a itkOptimizer
  OptimizerType::Pointer  itkOptimizer = OptimizerType::New();

  // Declaration of the CostFunction adaptor
  CostFunction costFunction;

  itkOptimizer->SetCostFunction( &costFunction );

  const double F_Tolerance      = 1e-3;  // Function value tolerance
  const double G_Tolerance      = 1e-4;  // Gradient magnitude tolerance
  const double X_Tolerance      = 1e-8;  // Search space tolerance
  const double Epsilon_Function = 1e-10; // Step
  const int    Max_Iterations   =   100; // Maximum number of iterations

  vnlOptimizerType & vnlOptimizer = itkOptimizer->GetOptimizer();

  vnlOptimizer.set_f_tolerance( F_Tolerance );
  vnlOptimizer.set_g_tolerance( G_Tolerance );
  vnlOptimizer.set_x_tolerance( X_Tolerance );
  vnlOptimizer.set_epsilon_function( Epsilon_Function );
  vnlOptimizer.set_max_function_evals( Max_Iterations );

  vnlOptimizer.set_check_derivatives( 3 );

  // We start not so far from  | 3 2 |
  typedef CostFunction::ParametersType ParametersType;
  ParametersType initialValue;
  initialValue = 20,10;

  itkOptimizer->SetInitialPosition( initialValue );

  itkOptimizer->StartOptimization();

  std::cout << "End condition   = " << vnlOptimizer.get_failure_code() << std::endl;
  std::cout << "Number of iters = " << vnlOptimizer.get_num_iterations() << std::endl;
  std::cout << "Number of evals = " << vnlOptimizer.get_num_evaluations() << std::endl;
  std::cout << std::endl;

  ParametersType finalPosition;
  finalPosition = costFunction.GetParameters();
  std::cout << "Solution        = (";
  std::cout << finalPosition[0] << "," ;
  std::cout << finalPosition[1] << ")" << std::endl;

  //
  // check results to see if it is within range
  //
  bool pass = true;
  double trueParameters[2] = { 3, 2 };
  for( unsigned int j = 0; j < 2; j++ )
    {
    if( vnl_math_abs( finalPosition[j] - trueParameters[j] ) > 0.01 )
      pass = false;
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>/*************************************************************************
 *   Copyright (C) 2011-2013 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Teapotnet.                                     *
 *                                                                       *
 *   Teapotnet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Teapotnet 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Teapotnet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tpn/resource.h"
#include "tpn/config.h"
#include "tpn/binaryserializer.h"

namespace tpn
{

// TODO
int Resource::CreatePlaylist(const Set<Resource> &resources, Stream *output, String host)
{
	if(host.empty()) host = String("localhost:") + Config::Get("interface_port");

	int count = 0;
	output->writeLine("#EXTM3U");
	for(Set<Resource>::iterator it = resources.begin(); it != resources.end(); ++it)
	{
		const Resource &resource = *it;
		if(resource.isDirectory() || resource.digest().empty()) continue;
		if(!Mime::IsAudio(resource.name()) && !Mime::IsVideo(resource.name())) continue;
		String link = "http://" + host + "/" + resource.digest().toString();
		output->writeLine("#EXTINF:-1," + resource.name().beforeLast('.'));
		output->writeLine(link);
		++count;
	}

	return count;
}

Resource::Resource(void) :
	mIndexBlock(NULL),
	mIndexRecord(NULL)
{

}

Resource::Resource(const Resource &resource) :
	mIndexBlock(NULL),
	mIndexRecord(NULL)
{
	*this = resource;
}

Resource::Resource(const BinaryString &digest) :
	mIndexBlock(NULL),
	mIndexRecord(NULL)
{
	fetch(digest);
}

Resource::~Resource(void)
{
	delete mIndexBlock;
	delete mIndexRecord;
}

void Resource::fetch(const BinaryString &digest)
{
	delete mIndexBlock;
	delete mIndexRecord;
	mIndexRecord = NULL;
	mIndexBlock = NULL;

	try {
		mIndexBlock = new Block(digest);
		mIndexRecord = new IndexRecord;

		BinarySerializer serializer(mIndexBlock);
		AssertIO(serializer.input(*mIndexRecord));
	}
	catch(...)
	{
		delete mIndexBlock;
		delete mIndexRecord;
		mIndexRecord = NULL;
		mIndexBlock = NULL;
		throw;
	}

}

BinaryString Resource::digest(void) const
{
	if(!mIndexBlock) return BinaryString();
	return mIndexBlock->digest();
}

int Resource::blocksCount(void) const
{
	if(!mIndexRecord) return 0;
	return int(mIndexRecord->blockDigests.size());
}

int Resource::blockIndex(int64_t position) const
{
	if(!mIndexBlock || position < 0 || position >= mIndexRecord->size)
		throw OutOfBounds("Resource position out of bounds");

	// TODO: block size in record ?
	return int(position/Block::Size);
}

BinaryString Resource::blockDigest(int index) const
{
	if(!mIndexBlock || index < 0 || index >= mIndexRecord->blockDigests.size())
		throw OutOfBounds("Block index out of bounds");
	return mIndexRecord->blockDigests.at(index);
}

void Resource::serialize(Serializer &s) const
{
	// TODO
}

bool Resource::deserialize(Serializer &s)
{
	// TODO
	return true;
}

bool Resource::isInlineSerializable(void) const
{
	return false;
}

Resource &Resource::operator = (const Resource &resource)
{
	delete mIndexBlock;
	delete mIndexRecord;
	mIndexBlock = new Block(resource.mIndexBlock);
	mIndexRecord = new IndexRecord(resource.mIndexRecord);
}

bool operator <  (const Resource &r1, const Resource &r2)
{
	if(r1.isDirectory() && !r2.isDirectory()) return true;
	if(!r1.isDirectory() && r2.isDirectory()) return false;
	return r1.url().toLower() < r2.url().toLower();
}

bool operator >  (const Resource &r1, const Resource &r2)
{
	if(r1.isDirectory() && !r2.isDirectory()) return false;
	if(!r1.isDirectory() && r2.isDirectory()) return true;
	return r1.url().toLower() > r2.url().toLower();
}

bool operator == (const Resource &r1, const Resource &r2)
{
	if(r1.url() != r2.url()) return false;
	return r1.digest() == r2.digest() && r1.isDirectory() == r2.isDirectory();
}

bool operator != (const Resource &r1, const Resource &r2)
{
	return !(r1 == r2);
}

Resource::Reader::Reader(Resource *resource) :
	mResource(resource),
	mReadPosition(0)
	mCurrentBlock(NULL),
	mNextBlock(NULL)
{
	Assert(mResource);
	seekRead(0);	// Initialize positions
}

Resource::Reader::~Reader(void)
{
	delete mCurrentBlock;
	delete mNextBlock;
}

size_t Resource::Reader::readData(char *buffer, size_t size)
{
	if(!mCurrentBlock) return 0;	// EOF

	size_t ret;
	if((ret = mCurrentBlock->readData(buffer, size)))
	{
		mReadPosition+= ret;
		return ret;
	}

	delete mCurrentBlock;
	++mCurrentBlockIndex;
	mCurrentBlock = mNextBlock;
	mNextBlock = createBlock(mCurrentBlockIndex + 1);
	return readData(buffer, size);
}

void Resource::Reader::writeData(const char *data, size_t size)
{
	throw Unsupported("Writing to Resource::Reader");
}

void Resource::Reader::seekRead(int64_t position)
{
	delete mCurrentBlock;
	delete mNextBlock;

	mCurrentBlockIndex = mResource->blockIndex(position);
	mCurrentBlock	= createBlock(mCurrentBlockIndex);
	mNextBlock	= createBlock(mCurrentBlockIndex + 1);
	mReadPosition	= position;
}

void Resource::Reader::seekWrite(int64_t position)
{
	throw Unsupported("Writing to Resource::Reader");
}

int64_t Resource::Reader::tellRead(void) const
{
	return mReadPosition;
}

int64_t Resource::Reader::tellWrite(void) const
{
	return 0;
}

Block *Resource::Reader::createBlock(int index)
{
	if(index < 0 || index >= mResource->blocksCount()) return NULL;
	return new Block(mResource->blockDigest(index));
}

}
<commit_msg>Added resource serialization<commit_after>/*************************************************************************
 *   Copyright (C) 2011-2013 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Teapotnet.                                     *
 *                                                                       *
 *   Teapotnet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Teapotnet 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Teapotnet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tpn/resource.h"
#include "tpn/config.h"
#include "tpn/binaryserializer.h"

namespace tpn
{

// TODO
int Resource::CreatePlaylist(const Set<Resource> &resources, Stream *output, String host)
{
	if(host.empty()) host = String("localhost:") + Config::Get("interface_port");

	int count = 0;
	output->writeLine("#EXTM3U");
	for(Set<Resource>::iterator it = resources.begin(); it != resources.end(); ++it)
	{
		const Resource &resource = *it;
		if(resource.isDirectory() || resource.digest().empty()) continue;
		if(!Mime::IsAudio(resource.name()) && !Mime::IsVideo(resource.name())) continue;
		String link = "http://" + host + "/" + resource.digest().toString();
		output->writeLine("#EXTINF:-1," + resource.name().beforeLast('.'));
		output->writeLine(link);
		++count;
	}

	return count;
}

Resource::Resource(void) :
	mIndexBlock(NULL),
	mIndexRecord(NULL)
{

}

Resource::Resource(const Resource &resource) :
	mIndexBlock(NULL),
	mIndexRecord(NULL)
{
	*this = resource;
}

Resource::Resource(const BinaryString &digest) :
	mIndexBlock(NULL),
	mIndexRecord(NULL)
{
	fetch(digest);
}

Resource::~Resource(void)
{
	delete mIndexBlock;
	delete mIndexRecord;
}

void Resource::fetch(const BinaryString &digest)
{
	delete mIndexBlock;
	delete mIndexRecord;
	mIndexRecord = NULL;
	mIndexBlock = NULL;

	try {
		mIndexBlock = new Block(digest);
		mIndexRecord = new IndexRecord;

		BinarySerializer serializer(mIndexBlock);
		AssertIO(serializer.input(*mIndexRecord));
	}
	catch(...)
	{
		delete mIndexBlock;
		delete mIndexRecord;
		mIndexRecord = NULL;
		mIndexBlock = NULL;
		throw;
	}

}

BinaryString Resource::digest(void) const
{
	if(!mIndexBlock) return BinaryString();
	return mIndexBlock->digest();
}

int Resource::blocksCount(void) const
{
	if(!mIndexRecord) return 0;
	return int(mIndexRecord->blockDigests.size());
}

int Resource::blockIndex(int64_t position) const
{
	if(!mIndexBlock || position < 0 || position >= mIndexRecord->size)
		throw OutOfBounds("Resource position out of bounds");

	// TODO: block size in record ?
	return int(position/Block::Size);
}

BinaryString Resource::blockDigest(int index) const
{
	if(!mIndexBlock || index < 0 || index >= mIndexRecord->blockDigests.size())
		throw OutOfBounds("Block index out of bounds");
	return mIndexRecord->blockDigests.at(index);
}

void Resource::serialize(Serializer &s) const
{
	if(!mIndexRecord) throw Unsupported("Serializing empty resource");

	ConstSerializableWrapper<int64_t> sizeWrapper(mIndexRecord->size);
	BinaryString digest(mIndexBlock->digest());

	Serializer::ConstObjectMapping mapping;
	mapping["name"] = &mIndexRecord->name;
        mapping["type"] = &mIndexRecord->type;
	mapping["size"] = &sizeWrapper;
	mapping["digest"] = &digest;

	s.outputObject(mapping);
}

bool Resource::deserialize(Serializer &s)
{
	throw Unsupported("Deserializing resource");
	return false;
}

bool Resource::isInlineSerializable(void) const
{
	return false;
}

Resource &Resource::operator = (const Resource &resource)
{
	delete mIndexBlock;
	delete mIndexRecord;
	mIndexBlock = new Block(resource.mIndexBlock);
	mIndexRecord = new IndexRecord(resource.mIndexRecord);
}

bool operator <  (const Resource &r1, const Resource &r2)
{
	if(r1.isDirectory() && !r2.isDirectory()) return true;
	if(!r1.isDirectory() && r2.isDirectory()) return false;
	return r1.url().toLower() < r2.url().toLower();
}

bool operator >  (const Resource &r1, const Resource &r2)
{
	if(r1.isDirectory() && !r2.isDirectory()) return false;
	if(!r1.isDirectory() && r2.isDirectory()) return true;
	return r1.url().toLower() > r2.url().toLower();
}

bool operator == (const Resource &r1, const Resource &r2)
{
	if(r1.url() != r2.url()) return false;
	return r1.digest() == r2.digest() && r1.isDirectory() == r2.isDirectory();
}

bool operator != (const Resource &r1, const Resource &r2)
{
	return !(r1 == r2);
}

Resource::Reader::Reader(Resource *resource) :
	mResource(resource),
	mReadPosition(0)
	mCurrentBlock(NULL),
	mNextBlock(NULL)
{
	Assert(mResource);
	seekRead(0);	// Initialize positions
}

Resource::Reader::~Reader(void)
{
	delete mCurrentBlock;
	delete mNextBlock;
}

size_t Resource::Reader::readData(char *buffer, size_t size)
{
	if(!mCurrentBlock) return 0;	// EOF

	size_t ret;
	if((ret = mCurrentBlock->readData(buffer, size)))
	{
		mReadPosition+= ret;
		return ret;
	}

	delete mCurrentBlock;
	++mCurrentBlockIndex;
	mCurrentBlock = mNextBlock;
	mNextBlock = createBlock(mCurrentBlockIndex + 1);
	return readData(buffer, size);
}

void Resource::Reader::writeData(const char *data, size_t size)
{
	throw Unsupported("Writing to Resource::Reader");
}

void Resource::Reader::seekRead(int64_t position)
{
	delete mCurrentBlock;
	delete mNextBlock;

	mCurrentBlockIndex = mResource->blockIndex(position);
	mCurrentBlock	= createBlock(mCurrentBlockIndex);
	mNextBlock	= createBlock(mCurrentBlockIndex + 1);
	mReadPosition	= position;
}

void Resource::Reader::seekWrite(int64_t position)
{
	throw Unsupported("Writing to Resource::Reader");
}

int64_t Resource::Reader::tellRead(void) const
{
	return mReadPosition;
}

int64_t Resource::Reader::tellWrite(void) const
{
	return 0;
}

Block *Resource::Reader::createBlock(int index)
{
	if(index < 0 || index >= mResource->blocksCount()) return NULL;
	return new Block(mResource->blockDigest(index));
}

}
<|endoftext|>