<commit_before>#include <thread>
#include <vector>
#include <string>
#include <cassert>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
#include <vtkSmartPointer.h>
#include <vtkXMLImageDataReader.h>
#include <vtkImageData.h>
#include <vtkThreshold.h>
#include <vtkContourForests.h>
#include <vtkPersistenceCurve.h>
#include <vtkPersistenceDiagram.h>
#include <vtkTopologicalSimplification.h>

#include "imgui-1.49/imgui.h"
#include "imgui-1.49/imgui_impl_sdl_gl3.h"
#include "glt/gl_core_4_5.h"
#include "glt/arcball_camera.h"
#include "glt/debug.h"
#include "glt/buffer_allocator.h"

#include "transfer_function.h"
#include "volume.h"
#include "tree_widget.h"
#include "persistence_curve_widget.h"

static size_t WIN_WIDTH = 1280;
static size_t WIN_HEIGHT = 720;
static unsigned int debuglevel = 0;

void run_app(SDL_Window *win, const std::vector<std::string> &args);
void setup_window(SDL_Window *&win, SDL_GLContext &ctx);
void DefaultCommands(int argc, const char **argv) {
    for (int i = 1; i < argc; ++i) {
	std::string str(argv[i]);
	if (str.compare("-debug") == 0) {
	    debuglevel = std::stoi(argv[++i]);
	}
    }
}
int main(int argc, const char **argv) {
        DefaultCommands(argc, argv);
	SDL_Window *win = nullptr;
	SDL_GLContext ctx = nullptr;
	setup_window(win, ctx);
	run_app(win, std::vector<std::string>(argv, argv + argc));
	ImGui_ImplSdlGL3_Shutdown();
	SDL_GL_DeleteContext(ctx);
	SDL_DestroyWindow(win);
	SDL_Quit();
	return 0;
}
void run_app(SDL_Window *win, const std::vector<std::string> &args) {
	// Read the volume data using vtk
	vtkSmartPointer<vtkXMLImageDataReader> reader
		= vtkSmartPointer<vtkXMLImageDataReader>::New();
	reader->SetFileName(args[1].c_str());
	reader->Update();
	vtkImageData *vol = reader->GetOutput();
	assert(vol);

	glm::vec3 vol_render_size;
	for (size_t i = 0; i < 3; ++i) {
		vol_render_size[i] = vol->GetSpacing()[i] * vol->GetDimensions()[i];
	}
	std::shared_ptr<glt::BufferAllocator> allocator = std::make_shared<glt::BufferAllocator>(size_t(64e6));

	glm::mat4 proj_mat = glm::perspective(glm::radians(65.f),
			static_cast<float>(WIN_WIDTH) / WIN_HEIGHT, 0.1f, 2000.f);
	glt::ArcBallCamera camera(glm::lookAt(glm::vec3{0.0, 0.0, vol_render_size.z},
			glm::vec3{0.0, 0.0, 0}, glm::vec3{0, 1, 0}),
			2.0, 75.0, {WIN_WIDTH, WIN_HEIGHT});

	// Note the vec3 is padded to a vec4 size, so we need a bit more room
	auto viewing_buf = allocator->alloc(2 * sizeof(glm::mat4) + sizeof(glm::vec4), glt::BufAlignment::UNIFORM_BUFFER);
	glBindBuffer(GL_UNIFORM_BUFFER, viewing_buf.buffer);
	glBindBufferRange(GL_UNIFORM_BUFFER, 0, viewing_buf.buffer, viewing_buf.offset, viewing_buf.size);
	{
		char *buf = static_cast<char*>(viewing_buf.map(GL_UNIFORM_BUFFER,
					GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_WRITE_BIT));
		glm::mat4 *mats = reinterpret_cast<glm::mat4*>(buf);
		// While it says vec3 in the buffer with std140 layout they'll be padded to vec4's
		glm::vec4 *vecs = reinterpret_cast<glm::vec4*>(buf + 2 * sizeof(glm::mat4));
		mats[0] = proj_mat;
		mats[1] = camera.transform();
		vecs[0] = glm::vec4{camera.eye_pos(), 1};

		glBindBufferRange(GL_UNIFORM_BUFFER, 0, viewing_buf.buffer, viewing_buf.offset, viewing_buf.size);
		viewing_buf.unmap(GL_UNIFORM_BUFFER);
	}

	// TODO: Contour/Split/Merge tree widget, pick a branch or multiple branches
	// in this widget and select those segments in the volume rendering.
	// The volume rendering picking can be done by looking up the same voxel position
	// in a separate Segmentation ID texture and discarding voxels accordingly.
	// The tree widget can be done by translating the arcs/points from TTK to a
	// more abstract representation, take the min/max ImageFile value for each group
	// of points for a segmentation id and draw the graph with these points connecting to
	// each other and splitting. The points come in the same order as the arcs,
	// where arc 0 is segmentation id 0 and starts at point 0 and ends at point 1.
	// Can also check the point locations for the node/arc points to confirm this.
	PersistenceCurveWidget persistence_curve_widget(reader, debuglevel); // come on ... let me debug !

	vtkSmartPointer<vtkContourForests> contour_forest
		= vtkSmartPointer<vtkContourForests>::New();
	contour_forest->SetInputConnection(persistence_curve_widget.get_simplification()->GetOutputPort());
	contour_forest->SetUseInputOffsetScalarField(true);
	contour_forest->SetinputOffsetScalarFieldName_("OutputOffsetScalarField");
	contour_forest->SetArcResolution(20);
	contour_forest->SetSkeletonSmoothing(50);
	contour_forest->SetUseAllCores(true);
	contour_forest->SetThreadNumber(std::thread::hardware_concurrency());
	contour_forest->SetdebugLevel_(debuglevel);
	// Setup transfer function and volume
	TransferFunction tfcn;
	contour_forest->AddObserver(vtkCommand::EndEvent, &tfcn);

	TreeWidget tree_widget(contour_forest, persistence_curve_widget.get_simplification());
	Volume volume(dynamic_cast<vtkImageData*>(contour_forest->GetOutput(2)));
	tfcn.histogram = &volume.histogram;

	std::vector<unsigned int> prev_seg_selection, prev_seg_palettes;
	bool ui_hovered = false;
	bool quit = false;
	bool camera_updated = false;
	int volume_render_mode = 0;
	while (!quit) {
		SDL_Event e;
		while (SDL_PollEvent(&e)){
			ImGui_ImplSdlGL3_ProcessEvent(&e);

			if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)){
				quit = true;
				break;
			}
			if (!ui_hovered) {
				camera_updated |= camera.sdl_input(e, 1000.f / ImGui::GetIO().Framerate);
			}
			if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
				WIN_WIDTH = e.window.data1;
				WIN_HEIGHT = e.window.data2;
				camera.update_screen(WIN_WIDTH, WIN_HEIGHT);
				camera_updated = true;
			}
		}
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		if (camera_updated) {
			char *buf = static_cast<char*>(viewing_buf.map(GL_UNIFORM_BUFFER, GL_MAP_WRITE_BIT));
			glm::mat4 *mats = reinterpret_cast<glm::mat4*>(buf);
			glm::vec3 *eye_pos = reinterpret_cast<glm::vec3*>(buf + 2 * sizeof(glm::mat4));
			mats[1] = camera.transform();
			*eye_pos = camera.eye_pos();

			viewing_buf.unmap(GL_UNIFORM_BUFFER);
			camera_updated = false;
		}

		glViewport(0, 0, WIN_WIDTH, WIN_HEIGHT);
		tfcn.render();
		volume.render(allocator);

		// Draw UI
		ImGui_ImplSdlGL3_NewFrame(win);
		glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y);

		if (ImGui::Begin("TopoVol")) {
			ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
					1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		}
		ImGui::End();

		tfcn.draw_ui();
		tree_widget.draw_ui();
		persistence_curve_widget.set_tree_type(tree_widget.get_tree_type());
		persistence_curve_widget.draw_ui();

		const auto &tree_selection = tree_widget.get_selection();
		const auto &seg_palettes = tfcn.get_segmentation_palettes();
		if (prev_seg_selection != tree_selection || seg_palettes != prev_seg_palettes) {
			std::fill(volume.segmentation_selections.begin(), volume.segmentation_selections.end(),
					tree_selection.empty() ? 1 : 0);
			for (const auto &x : tree_selection) {
				volume.segmentation_selections[x] = 1;
			}
			volume.segmentation_palettes = seg_palettes;
			volume.segmentation_selection_changed = true;
			prev_seg_selection = tree_selection;
			prev_seg_palettes = seg_palettes;
		}

		ui_hovered = ImGui::IsMouseHoveringAnyWindow();
		ImGui::Render();

		SDL_GL_SwapWindow(win);
	}
}
void setup_window(SDL_Window *&win, SDL_GLContext &ctx) {
	if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
		throw std::runtime_error("Failed to initialize SDL");
	}

	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
#ifndef NDEBUG
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
#endif

	win = SDL_CreateWindow("Topology Guided Volume Exploration", SDL_WINDOWPOS_CENTERED,
			SDL_WINDOWPOS_CENTERED, WIN_WIDTH, WIN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
	if (!win){
		const std::string err = std::string("Failed to open SDL window: ") + SDL_GetError();
		throw std::runtime_error(err);
	}
	ctx = SDL_GL_CreateContext(win);
	if (!ctx){
		std::cout << "Failed to get OpenGL context: " << SDL_GetError() << "\n";
		const std::string err = std::string("Failed to open SDL window: ") + SDL_GetError();
		throw std::runtime_error(err);
	}
	if (ogl_LoadFunctions() == ogl_LOAD_FAILED){
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Failed to Load OpenGL Functions",
				"Could not load OpenGL functions for 4.4, OpenGL 4.4 or higher is required",
				NULL);
		SDL_GL_DeleteContext(ctx);
		SDL_DestroyWindow(win);
		SDL_Quit();
		throw std::runtime_error("OpenGL Load failed");
	}
	SDL_GL_SetSwapInterval(1);

#ifndef NDEBUG
	glt::register_debug_callback();
	glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER,
			0, GL_DEBUG_SEVERITY_NOTIFICATION, 16, "DEBUG LOG START");
#endif

	ImGui_ImplSdlGL3_Init(win);
	glEnable(GL_DEPTH_TEST);
	glClearColor(0.1, 0.1, 0.1, 1);
	glClearDepth(1.0);
}

<commit_msg>remove some old comments<commit_after>#include <thread>
#include <vector>
#include <string>
#include <cassert>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
#include <vtkSmartPointer.h>
#include <vtkXMLImageDataReader.h>
#include <vtkImageData.h>
#include <vtkThreshold.h>
#include <vtkContourForests.h>
#include <vtkPersistenceCurve.h>
#include <vtkPersistenceDiagram.h>
#include <vtkTopologicalSimplification.h>

#include "imgui-1.49/imgui.h"
#include "imgui-1.49/imgui_impl_sdl_gl3.h"
#include "glt/gl_core_4_5.h"
#include "glt/arcball_camera.h"
#include "glt/debug.h"
#include "glt/buffer_allocator.h"

#include "transfer_function.h"
#include "volume.h"
#include "tree_widget.h"
#include "persistence_curve_widget.h"

static size_t WIN_WIDTH = 1280;
static size_t WIN_HEIGHT = 720;
static unsigned int debuglevel = 0;

void run_app(SDL_Window *win, const std::vector<std::string> &args);
void setup_window(SDL_Window *&win, SDL_GLContext &ctx);
void DefaultCommands(int argc, const char **argv) {
    for (int i = 1; i < argc; ++i) {
	std::string str(argv[i]);
	if (str.compare("-debug") == 0) {
	    debuglevel = std::stoi(argv[++i]);
	}
    }
}
int main(int argc, const char **argv) {
        DefaultCommands(argc, argv);
	SDL_Window *win = nullptr;
	SDL_GLContext ctx = nullptr;
	setup_window(win, ctx);
	run_app(win, std::vector<std::string>(argv, argv + argc));
	ImGui_ImplSdlGL3_Shutdown();
	SDL_GL_DeleteContext(ctx);
	SDL_DestroyWindow(win);
	SDL_Quit();
	return 0;
}
void run_app(SDL_Window *win, const std::vector<std::string> &args) {
	// Read the volume data using vtk
	vtkSmartPointer<vtkXMLImageDataReader> reader
		= vtkSmartPointer<vtkXMLImageDataReader>::New();
	reader->SetFileName(args[1].c_str());
	reader->Update();
	vtkImageData *vol = reader->GetOutput();
	assert(vol);

	glm::vec3 vol_render_size;
	for (size_t i = 0; i < 3; ++i) {
		vol_render_size[i] = vol->GetSpacing()[i] * vol->GetDimensions()[i];
	}
	std::shared_ptr<glt::BufferAllocator> allocator = std::make_shared<glt::BufferAllocator>(size_t(64e6));

	glm::mat4 proj_mat = glm::perspective(glm::radians(65.f),
			static_cast<float>(WIN_WIDTH) / WIN_HEIGHT, 0.1f, 2000.f);
	glt::ArcBallCamera camera(glm::lookAt(glm::vec3{0.0, 0.0, vol_render_size.z},
			glm::vec3{0.0, 0.0, 0}, glm::vec3{0, 1, 0}),
			2.0, 75.0, {WIN_WIDTH, WIN_HEIGHT});

	// Note the vec3 is padded to a vec4 size, so we need a bit more room
	auto viewing_buf = allocator->alloc(2 * sizeof(glm::mat4) + sizeof(glm::vec4), glt::BufAlignment::UNIFORM_BUFFER);
	glBindBuffer(GL_UNIFORM_BUFFER, viewing_buf.buffer);
	glBindBufferRange(GL_UNIFORM_BUFFER, 0, viewing_buf.buffer, viewing_buf.offset, viewing_buf.size);
	{
		char *buf = static_cast<char*>(viewing_buf.map(GL_UNIFORM_BUFFER,
					GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_WRITE_BIT));
		glm::mat4 *mats = reinterpret_cast<glm::mat4*>(buf);
		// While it says vec3 in the buffer with std140 layout they'll be padded to vec4's
		glm::vec4 *vecs = reinterpret_cast<glm::vec4*>(buf + 2 * sizeof(glm::mat4));
		mats[0] = proj_mat;
		mats[1] = camera.transform();
		vecs[0] = glm::vec4{camera.eye_pos(), 1};

		glBindBufferRange(GL_UNIFORM_BUFFER, 0, viewing_buf.buffer, viewing_buf.offset, viewing_buf.size);
		viewing_buf.unmap(GL_UNIFORM_BUFFER);
	}

	PersistenceCurveWidget persistence_curve_widget(reader, debuglevel);

	vtkSmartPointer<vtkContourForests> contour_forest
		= vtkSmartPointer<vtkContourForests>::New();
	contour_forest->SetInputConnection(persistence_curve_widget.get_simplification()->GetOutputPort());
	contour_forest->SetUseInputOffsetScalarField(true);
	contour_forest->SetinputOffsetScalarFieldName_("OutputOffsetScalarField");
	contour_forest->SetArcResolution(20);
	contour_forest->SetSkeletonSmoothing(50);
	contour_forest->SetUseAllCores(true);
	contour_forest->SetThreadNumber(std::thread::hardware_concurrency());
	contour_forest->SetdebugLevel_(debuglevel);
	// Setup transfer function and volume
	TransferFunction tfcn;
	contour_forest->AddObserver(vtkCommand::EndEvent, &tfcn);

	TreeWidget tree_widget(contour_forest, persistence_curve_widget.get_simplification());
	Volume volume(dynamic_cast<vtkImageData*>(contour_forest->GetOutput(2)));
	tfcn.histogram = &volume.histogram;

	std::vector<unsigned int> prev_seg_selection, prev_seg_palettes;
	bool ui_hovered = false;
	bool quit = false;
	bool camera_updated = false;
	int volume_render_mode = 0;
	while (!quit) {
		SDL_Event e;
		while (SDL_PollEvent(&e)){
			ImGui_ImplSdlGL3_ProcessEvent(&e);

			if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)){
				quit = true;
				break;
			}
			if (!ui_hovered) {
				camera_updated |= camera.sdl_input(e, 1000.f / ImGui::GetIO().Framerate);
			}
			if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
				WIN_WIDTH = e.window.data1;
				WIN_HEIGHT = e.window.data2;
				camera.update_screen(WIN_WIDTH, WIN_HEIGHT);
				camera_updated = true;
			}
		}
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		if (camera_updated) {
			char *buf = static_cast<char*>(viewing_buf.map(GL_UNIFORM_BUFFER, GL_MAP_WRITE_BIT));
			glm::mat4 *mats = reinterpret_cast<glm::mat4*>(buf);
			glm::vec3 *eye_pos = reinterpret_cast<glm::vec3*>(buf + 2 * sizeof(glm::mat4));
			mats[1] = camera.transform();
			*eye_pos = camera.eye_pos();

			viewing_buf.unmap(GL_UNIFORM_BUFFER);
			camera_updated = false;
		}

		glViewport(0, 0, WIN_WIDTH, WIN_HEIGHT);
		tfcn.render();
		volume.render(allocator);

		// Draw UI
		ImGui_ImplSdlGL3_NewFrame(win);
		glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y);

		if (ImGui::Begin("TopoVol")) {
			ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
					1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		}
		ImGui::End();

		tfcn.draw_ui();
		tree_widget.draw_ui();
		persistence_curve_widget.set_tree_type(tree_widget.get_tree_type());
		persistence_curve_widget.draw_ui();

		const auto &tree_selection = tree_widget.get_selection();
		const auto &seg_palettes = tfcn.get_segmentation_palettes();
		if (prev_seg_selection != tree_selection || seg_palettes != prev_seg_palettes) {
			std::fill(volume.segmentation_selections.begin(), volume.segmentation_selections.end(),
					tree_selection.empty() ? 1 : 0);
			for (const auto &x : tree_selection) {
				volume.segmentation_selections[x] = 1;
			}
			volume.segmentation_palettes = seg_palettes;
			volume.segmentation_selection_changed = true;
			prev_seg_selection = tree_selection;
			prev_seg_palettes = seg_palettes;
		}

		ui_hovered = ImGui::IsMouseHoveringAnyWindow();
		ImGui::Render();

		SDL_GL_SwapWindow(win);
	}
}
void setup_window(SDL_Window *&win, SDL_GLContext &ctx) {
	if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
		throw std::runtime_error("Failed to initialize SDL");
	}

	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
#ifndef NDEBUG
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
#endif

	win = SDL_CreateWindow("Topology Guided Volume Exploration", SDL_WINDOWPOS_CENTERED,
			SDL_WINDOWPOS_CENTERED, WIN_WIDTH, WIN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
	if (!win){
		const std::string err = std::string("Failed to open SDL window: ") + SDL_GetError();
		throw std::runtime_error(err);
	}
	ctx = SDL_GL_CreateContext(win);
	if (!ctx){
		std::cout << "Failed to get OpenGL context: " << SDL_GetError() << "\n";
		const std::string err = std::string("Failed to open SDL window: ") + SDL_GetError();
		throw std::runtime_error(err);
	}
	if (ogl_LoadFunctions() == ogl_LOAD_FAILED){
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Failed to Load OpenGL Functions",
				"Could not load OpenGL functions for 4.4, OpenGL 4.4 or higher is required",
				NULL);
		SDL_GL_DeleteContext(ctx);
		SDL_DestroyWindow(win);
		SDL_Quit();
		throw std::runtime_error("OpenGL Load failed");
	}
	SDL_GL_SetSwapInterval(1);

#ifndef NDEBUG
	glt::register_debug_callback();
	glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER,
			0, GL_DEBUG_SEVERITY_NOTIFICATION, 16, "DEBUG LOG START");
#endif

	ImGui_ImplSdlGL3_Init(win);
	glEnable(GL_DEPTH_TEST);
	glClearColor(0.1, 0.1, 0.1, 1);
	glClearDepth(1.0);
}

<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

//Forward declaration of the layers

#ifndef DLL_LAYER_FWD_HPP
#define DLL_LAYER_FWD_HPP

namespace dll {

template<typename Desc>
struct dyn_rbm;

template<typename Desc>
struct conv_rbm;

template<typename Desc>
struct conv_rbm_mp;

template<typename Desc>
struct mp_layer_3d;

template<typename Desc>
struct avgp_layer_3d;

template<typename Desc>
struct binarize_layer;

template<typename Desc>
struct normalize_layer;

template<typename Desc>
struct patches_layer;

template<typename Desc>
struct patches_layer_padh;

} //end of dll namespace

#endif
<commit_msg>New forward<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

//Forward declaration of the layers

#ifndef DLL_LAYER_FWD_HPP
#define DLL_LAYER_FWD_HPP

namespace dll {

template<typename Desc>
struct dyn_rbm;

template<typename Desc>
struct conv_rbm;

template<typename Desc>
struct conv_rbm_mp;

template<typename Desc>
struct mp_layer_3d;

template<typename Desc>
struct avgp_layer_3d;

template<typename Desc>
struct binarize_layer;

template<typename Desc>
struct normalize_layer;

template<typename Desc>
struct patches_layer;

template<typename Desc>
struct patches_layer_padh;

template<typename Desc>
struct dense_layer;

template<typename Desc>
struct conv_layer;

} //end of dll namespace

#endif
<|endoftext|>


<commit_before>/*
  File: pinGPIO.hpp

  Контакт general-purpose input/output (GPIO)

*/

template<int PORT, int DDR, int PIN, int BIT>
class PinGPIO
{

public:

  /*  Конструктор.
      @arg inOut - направление вывода (вход/выход).
        0 - вход.
        1 -выход.
  */
  PinGPIO(bool inOut);

  ~PinGPIO();

  /*  Устанавливает состояние пина.
      @arg level - уровень состояния выхода (включено/выключено).
  */
  void setPin(bool level);

  /*  Читает состояние пина.
      @return - уровень состояния входа (включено/выключено).
  */
  bool getPin();

private:

  /*  Инициализирует пин порта ввода вывода МК.
      @arg inOut - направление вывода (вход/выход).
        0 - вход.
        1 -выход.
      @return значение отличное от 0 - код ошибки.
  */
  int initPin(bool inOut);

};

template<int PORT, int DDR, int PIN, int BIT>
PinGPIO<PORT, DDR, PIN, BIT>::PinGPIO(bool inOut)
{
    initPin(inOut);
};

template<int PORT, int DDR, int PIN, int BIT>
PinGPIO<PORT, DDR, PIN, BIT>::~PinGPIO()
{

};

template<int PORT, int DDR, int PIN, int BIT>
int PinGPIO<PORT, DDR, PIN, BIT>::initPin(bool inOut)
{
  // TODO: режи высокого входного сопротивления при рабте порта на вход.

  uint8_t* ptR;
  ptR = (uint8_t*) DDR;

  if (inOut)
  {
    *ptR |= (1 << BIT);
  }
  else
  {
     *ptR &= ~ (1 << BIT);
  }

  return 0;
};

template<int PORT, int DDR, int PIN, int BIT>
void PinGPIO<PORT, DDR, PIN, BIT>::setPin(bool level)
{
  uint8_t* ptR;
  ptR = (uint8_t*) PORT;

  if (level)
  {
    *ptR |= (1 << BIT);
  }
  else
  {
     *ptR &= ~ (1 << BIT);
  }

};

template<int PORT, int DDR, int PIN, int BIT>
bool PinGPIO<PORT, DDR, PIN, BIT>::getPin()
{
  uint8_t* ptR;
  ptR = (uint8_t*) PIN;

  return  *ptR & (1 << BIT);
};

<commit_msg>Added declaration pins for port D. ref #2<commit_after>/*
  File: pinGPIO.hpp

  Контакт general-purpose input/output (GPIO)

*/

template<int PORT, int DDR, int PIN, int BIT>
class PinGPIO
{

public:

  /*  Конструктор.
      @arg inOut - направление вывода (вход/выход).
        0 - вход.
        1 -выход.
  */
  PinGPIO(bool inOut);

  ~PinGPIO();

  /*  Устанавливает состояние пина.
      @arg level - уровень состояния выхода (включено/выключено).
  */
  void setPin(bool level);

  /*  Читает состояние пина.
      @return - уровень состояния входа (включено/выключено).
  */
  bool getPin();

private:

  /*  Инициализирует пин порта ввода вывода МК.
      @arg inOut - направление вывода (вход/выход).
        0 - вход.
        1 -выход.
      @return значение отличное от 0 - код ошибки.
  */
  int initPin(bool inOut);

};

template<int PORT, int DDR, int PIN, int BIT>
PinGPIO<PORT, DDR, PIN, BIT>::PinGPIO(bool inOut)
{
    initPin(inOut);
};

template<int PORT, int DDR, int PIN, int BIT>
PinGPIO<PORT, DDR, PIN, BIT>::~PinGPIO()
{

};

template<int PORT, int DDR, int PIN, int BIT>
int PinGPIO<PORT, DDR, PIN, BIT>::initPin(bool inOut)
{
  // TODO: режим высокого входного сопротивления при рабте порта на вход.

  uint8_t* ptR;
  ptR = (uint8_t*) DDR;

  if (inOut)
  {
    *ptR |= (1 << BIT);
  }
  else
  {
     *ptR &= ~ (1 << BIT);
  }

  return 0;
};

template<int PORT, int DDR, int PIN, int BIT>
void PinGPIO<PORT, DDR, PIN, BIT>::setPin(bool level)
{
  // TODO: ptR сделать членом класса.
  //       Инициализировать переменную в конструкторе объекта.
  uint8_t* ptR;
  ptR = (uint8_t*) PORT;

  if (level)
  {
    *ptR |= (1 << BIT);
  }
  else
  {
     *ptR &= ~ (1 << BIT);
  }

};

template<int PORT, int DDR, int PIN, int BIT>
bool PinGPIO<PORT, DDR, PIN, BIT>::getPin()
{
  uint8_t* ptR;
  ptR = (uint8_t*) PIN;

  return  *ptR & (1 << BIT);
};

typedef PinGPIO<0x2B, 0x2A, 0x29, 2> PinD2;
typedef PinGPIO<0x2B, 0x2A, 0x29, 3> PinD3;
typedef PinGPIO<0x2B, 0x2A, 0x29, 4> PinD4;
typedef PinGPIO<0x2B, 0x2A, 0x29, 5> PinD5;
typedef PinGPIO<0x2B, 0x2A, 0x29, 6> PinD6;
typedef PinGPIO<0x2B, 0x2A, 0x29, 7> PinD7;

<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
#include <berryIPreferences.h>
#include <berryIPreferencesService.h>
#include <berryIBerryPreferences.h>

// Qmitk
#include "CommandLineModulesView.h"
#include "CommandLineModulesPreferencesPage.h"

// Qt
#include <QMessageBox>
#include <QScrollArea>
#include <QFile>
#include <QFileDialog>
#include <QFileInfoList>
#include <QDir>
#include <QBuffer>
#include <QtUiTools/QUiLoader>
#include <QByteArray>
#include <QHBoxLayout>
#include <QAction>

// CTK
#include <ctkCmdLineModuleManager.h>
#include <ctkCmdLineModuleInstance.h>
#include <ctkCmdLineModuleDescription.h>
#include <ctkCmdLineModuleInstanceFactoryQtGui.h>
#include <ctkCmdLineModuleXmlValidator.h>
#include <ctkCmdLineModuleProcessFuture.h>

const std::string CommandLineModulesView::VIEW_ID = "org.mitk.gui.qt.cli";

CommandLineModulesView::CommandLineModulesView()
: m_Controls(NULL)
, m_Parent(NULL)
, m_ModuleManager(NULL)
, m_TemporaryDirectoryName("")
{
  m_ModulesDirectoryNames.clear();
  m_MapFilenameToReference.clear();
  m_MapTabToModuleInstance.clear();
  m_ModuleManager = new ctkCmdLineModuleManager(new ctkCmdLineModuleInstanceFactoryQtGui());
}

CommandLineModulesView::~CommandLineModulesView()
{
  if (m_ModuleManager != NULL)
  {
    delete m_ModuleManager;
  }
}

void CommandLineModulesView::SetFocus()
{
  this->m_Controls->m_ComboBox->setFocus();
}

void CommandLineModulesView::CreateQtPartControl( QWidget *parent )
{
  if (!m_Controls)
  {
    // We create CommandLineModulesViewControls, which derives from the Qt generated class.
    m_Controls = new CommandLineModulesViewControls(parent);

    // Loads the preferences like directory settings into member variables.
    this->RetrievePreferenceValues();

    // Connect signals to slots after we have set up GUI.
    connect(this->m_Controls->m_RunButton, SIGNAL(pressed()), this, SLOT(OnRunButtonPressed()));
    connect(this->m_Controls->m_StopButton, SIGNAL(pressed()), this, SLOT(OnStopButtonPressed()));
    connect(this->m_Controls->m_RestoreDefaults, SIGNAL(pressed()), this, SLOT(OnRestoreDefaultsButtonPressed()));
    connect(this->m_Controls->m_ComboBox, SIGNAL(actionChanged(QAction*)), this, SLOT(OnActionChanged(QAction*)));
    connect(&(this->m_FutureWatcher), SIGNAL(finished()), this, SLOT(OnFutureFinished()));
  }
}

void CommandLineModulesView::RetrievePreferenceValues()
{
  berry::IPreferencesService::Pointer prefService
      = berry::Platform::GetServiceRegistry()
      .GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);

  assert( prefService );

  std::string id = "/" + CommandLineModulesView::VIEW_ID;
  berry::IBerryPreferences::Pointer prefs
      = (prefService->GetSystemPreferences()->Node(id))
        .Cast<berry::IBerryPreferences>();

  assert( prefs );

  m_TemporaryDirectoryName = QString::fromStdString(prefs->Get(CommandLineModulesPreferencesPage::TEMPORARY_DIRECTORY_NODE_NAME, ""));
  QString pathString = QString::fromStdString(prefs->Get(CommandLineModulesPreferencesPage::MODULE_DIRECTORIES_NODE_NAME, ""));
  QStringList paths = pathString.split(";", QString::SkipEmptyParts);

  // OnPreferencesChanged can be called for each preference in a dialog box, so
  // when you hit "OK", it is called repeatedly, whereas we want to only call this once,
  // so I am checking if the list of directory names has changed.
  if (paths != this->m_ModulesDirectoryNames)
  {
    m_MapFilenameToReference = this->LoadModuleReferencesFromPaths(paths);
    QMenu *menu = this->CreateMenuFromReferences(m_MapFilenameToReference);
    this->m_Controls->m_ComboBox->setMenu(menu);
    this->m_ModulesDirectoryNames = paths;
  }
}

QHash<QString, ctkCmdLineModuleReference> CommandLineModulesView::LoadModuleReferencesFromPaths(QStringList &paths)
{
  QString path;
  QString executable;
  QFileInfo executableFileInfo;

  QHash<QString, ctkCmdLineModuleReference> result;

  foreach (path, paths)
  {
    if (!path.isNull() && !path.isEmpty() && !path.trimmed().isEmpty())
    {
      QDir directory = QDir(path);
      directory.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::Executable);

      QFileInfoList executablesInfoList = directory.entryInfoList();
      foreach (executableFileInfo, executablesInfoList)
      {
        executable = executableFileInfo.absoluteFilePath();
        ctkCmdLineModuleReference ref = m_ModuleManager->registerModule(executable, true);
        if (ref)
        {
          result[executable] = ref;
        }
      }
    }
  }
  return result;
}

QMenu* CommandLineModulesView::CreateMenuFromReferences(QHash<QString, ctkCmdLineModuleReference>& hashMap)
{
  QMenu *menu = new QMenu();
  ctkCmdLineModuleReference ref;

  QList<ctkCmdLineModuleReference> references = hashMap.values();
  foreach (ref, references)
  {
    menu->addAction(ref.description().title());
  }
  return menu;
}

void CommandLineModulesView::OnPreferencesChanged(const berry::IBerryPreferences* /*prefs*/)
{
  // Loads the preferences into member variables.
  this->RetrievePreferenceValues();
}

void CommandLineModulesView::AddModuleTab(const ctkCmdLineModuleReference& moduleRef)
{
  ctkCmdLineModuleInstance* moduleInstance = m_ModuleManager->createModuleInstance(moduleRef);
  if (!moduleInstance) return;

  QObject* guiHandle = moduleInstance->guiHandle();
  QWidget* widget = qobject_cast<QWidget*>(guiHandle);

  int tabIndex = m_Controls->m_TabWidget->addTab(widget, moduleRef.description().title());
  m_Controls->m_TabWidget->setCurrentIndex(tabIndex);
  m_MapTabToModuleInstance[tabIndex] = moduleInstance;

  m_Controls->m_HelpBrowser->clear();
  m_Controls->m_HelpBrowser->setPlainText(moduleRef.description().description());
  m_Controls->m_AboutBrowser->clear();
  m_Controls->m_AboutBrowser->setPlainText(moduleRef.description().acknowledgements());
}

void CommandLineModulesView::OnFutureFinished()
{
  qDebug() << "*** Future finished ***";
  qDebug() << "stdout:" << m_FutureWatcher.future().standardOutput();
  qDebug() << "stderr:" << m_FutureWatcher.future().standardError();
}

void CommandLineModulesView::OnActionChanged(QAction* action)
{
  ctkCmdLineModuleReference ref = this->GetReferenceByIdentifier(action->text());
  if (ref)
  {
    this->AddModuleTab(ref);
  }
}

ctkCmdLineModuleReference CommandLineModulesView::GetReferenceByIdentifier(QString identifier)
{
  ctkCmdLineModuleReference result;

  QList<ctkCmdLineModuleReference> references = m_MapFilenameToReference.values();
  ctkCmdLineModuleReference ref;
  foreach(ref, references)
  {
    if (ref.description().title() == identifier)
    {
      result = ref;
    }
  }
  return result;
}

void CommandLineModulesView::OnRunButtonPressed()
{
  qDebug() << "Creating module command line...";

  ctkCmdLineModuleInstance* moduleInstance = m_MapTabToModuleInstance[m_Controls->m_TabWidget->currentIndex()];
  if (!moduleInstance)
  {
    qWarning() << "Invalid module instance";
    return;
  }

  qDebug() << "Launching module command line...";

  ctkCmdLineModuleProcessFuture future = moduleInstance->run();

  qDebug() << "Launched module command line...";
}

void CommandLineModulesView::OnStopButtonPressed()
{
  qDebug() << "Stopping module command line...";

  qDebug() << "Stopped module command line...";
}

void CommandLineModulesView::OnRestoreDefaultsButtonPressed()
{

}
<commit_msg>CLI plugin: provide default and user-pref directories to scan<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
#include <berryIPreferences.h>
#include <berryIPreferencesService.h>
#include <berryIBerryPreferences.h>

// Qmitk
#include "CommandLineModulesView.h"
#include "CommandLineModulesPreferencesPage.h"

// Qt
#include <QMessageBox>
#include <QScrollArea>
#include <QFile>
#include <QFileDialog>
#include <QFileInfoList>
#include <QDir>
#include <QBuffer>
#include <QtUiTools/QUiLoader>
#include <QByteArray>
#include <QHBoxLayout>
#include <QAction>

// CTK
#include <ctkCmdLineModuleManager.h>
#include <ctkCmdLineModuleInstance.h>
#include <ctkCmdLineModuleDescription.h>
#include <ctkCmdLineModuleInstanceFactoryQtGui.h>
#include <ctkCmdLineModuleXmlValidator.h>
#include <ctkCmdLineModuleProcessFuture.h>
#include <ctkCmdLineModuleDefaultPathBuilder.h>

const std::string CommandLineModulesView::VIEW_ID = "org.mitk.gui.qt.cli";

CommandLineModulesView::CommandLineModulesView()
: m_Controls(NULL)
, m_Parent(NULL)
, m_ModuleManager(NULL)
, m_TemporaryDirectoryName("")
{
  m_ModulesDirectoryNames.clear();
  m_MapFilenameToReference.clear();
  m_MapTabToModuleInstance.clear();
  m_ModuleManager = new ctkCmdLineModuleManager(new ctkCmdLineModuleInstanceFactoryQtGui());
}

CommandLineModulesView::~CommandLineModulesView()
{
  if (m_ModuleManager != NULL)
  {
    delete m_ModuleManager;
  }
}

void CommandLineModulesView::SetFocus()
{
  this->m_Controls->m_ComboBox->setFocus();
}

void CommandLineModulesView::CreateQtPartControl( QWidget *parent )
{
  if (!m_Controls)
  {
    // We create CommandLineModulesViewControls, which derives from the Qt generated class.
    m_Controls = new CommandLineModulesViewControls(parent);

    // Loads the preferences like directory settings into member variables.
    this->RetrievePreferenceValues();

    // Connect signals to slots after we have set up GUI.
    connect(this->m_Controls->m_RunButton, SIGNAL(pressed()), this, SLOT(OnRunButtonPressed()));
    connect(this->m_Controls->m_StopButton, SIGNAL(pressed()), this, SLOT(OnStopButtonPressed()));
    connect(this->m_Controls->m_RestoreDefaults, SIGNAL(pressed()), this, SLOT(OnRestoreDefaultsButtonPressed()));
    connect(this->m_Controls->m_ComboBox, SIGNAL(actionChanged(QAction*)), this, SLOT(OnActionChanged(QAction*)));
    connect(&(this->m_FutureWatcher), SIGNAL(finished()), this, SLOT(OnFutureFinished()));
  }
}

void CommandLineModulesView::RetrievePreferenceValues()
{
  berry::IPreferencesService::Pointer prefService
      = berry::Platform::GetServiceRegistry()
      .GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);

  assert( prefService );

  std::string id = "/" + CommandLineModulesView::VIEW_ID;
  berry::IBerryPreferences::Pointer prefs
      = (prefService->GetSystemPreferences()->Node(id))
        .Cast<berry::IBerryPreferences>();

  assert( prefs );

  // Get some default application paths.
  ctkCmdLineModuleDefaultPathBuilder builder;
  QStringList defaultPaths = builder.build();

  // We get additional paths from preferences.
  m_TemporaryDirectoryName = QString::fromStdString(prefs->Get(CommandLineModulesPreferencesPage::TEMPORARY_DIRECTORY_NODE_NAME, ""));
  QString pathString = QString::fromStdString(prefs->Get(CommandLineModulesPreferencesPage::MODULE_DIRECTORIES_NODE_NAME, ""));
  QStringList additionalPaths = pathString.split(";", QString::SkipEmptyParts);

  // Combine the sets of paths.
  QStringList totalPaths;
  totalPaths << defaultPaths;
  totalPaths << additionalPaths;

  // OnPreferencesChanged can be called for each preference in a dialog box, so
  // when you hit "OK", it is called repeatedly, whereas we want to only call this once,
  // so I am checking if the list of directory names has changed.
  if (this->m_ModulesDirectoryNames != totalPaths)
  {
    m_MapFilenameToReference = this->LoadModuleReferencesFromPaths(totalPaths);
    QMenu *menu = this->CreateMenuFromReferences(m_MapFilenameToReference);
    this->m_Controls->m_ComboBox->setMenu(menu);
    this->m_ModulesDirectoryNames = totalPaths;
  }
}

QHash<QString, ctkCmdLineModuleReference> CommandLineModulesView::LoadModuleReferencesFromPaths(QStringList &paths)
{
  QString path;
  QString executable;
  QFileInfo executableFileInfo;

  QHash<QString, ctkCmdLineModuleReference> result;

  foreach (path, paths)
  {
    if (!path.isNull() && !path.isEmpty() && !path.trimmed().isEmpty())
    {
      QDir directory = QDir(path);
      directory.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::Executable);

      QFileInfoList executablesInfoList = directory.entryInfoList();
      foreach (executableFileInfo, executablesInfoList)
      {
        executable = executableFileInfo.absoluteFilePath();
        ctkCmdLineModuleReference ref = m_ModuleManager->registerModule(executable, true);
        if (ref)
        {
          result[executable] = ref;
        }
      }
    }
  }
  return result;
}

QMenu* CommandLineModulesView::CreateMenuFromReferences(QHash<QString, ctkCmdLineModuleReference>& hashMap)
{
  QMenu *menu = new QMenu();
  ctkCmdLineModuleReference ref;

  QList<ctkCmdLineModuleReference> references = hashMap.values();
  foreach (ref, references)
  {
    menu->addAction(ref.description().title());
  }
  return menu;
}

void CommandLineModulesView::OnPreferencesChanged(const berry::IBerryPreferences* /*prefs*/)
{
  // Loads the preferences into member variables.
  this->RetrievePreferenceValues();
}

void CommandLineModulesView::AddModuleTab(const ctkCmdLineModuleReference& moduleRef)
{
  ctkCmdLineModuleInstance* moduleInstance = m_ModuleManager->createModuleInstance(moduleRef);
  if (!moduleInstance) return;

  QObject* guiHandle = moduleInstance->guiHandle();
  QWidget* widget = qobject_cast<QWidget*>(guiHandle);

  int tabIndex = m_Controls->m_TabWidget->addTab(widget, moduleRef.description().title());
  m_Controls->m_TabWidget->setCurrentIndex(tabIndex);
  m_MapTabToModuleInstance[tabIndex] = moduleInstance;

  m_Controls->m_HelpBrowser->clear();
  m_Controls->m_HelpBrowser->setPlainText(moduleRef.description().description());
  m_Controls->m_AboutBrowser->clear();
  m_Controls->m_AboutBrowser->setPlainText(moduleRef.description().acknowledgements());
}

void CommandLineModulesView::OnFutureFinished()
{
  qDebug() << "*** Future finished ***";
  qDebug() << "stdout:" << m_FutureWatcher.future().standardOutput();
  qDebug() << "stderr:" << m_FutureWatcher.future().standardError();
}

void CommandLineModulesView::OnActionChanged(QAction* action)
{
  ctkCmdLineModuleReference ref = this->GetReferenceByIdentifier(action->text());
  if (ref)
  {
    this->AddModuleTab(ref);
  }
}

ctkCmdLineModuleReference CommandLineModulesView::GetReferenceByIdentifier(QString identifier)
{
  ctkCmdLineModuleReference result;

  QList<ctkCmdLineModuleReference> references = m_MapFilenameToReference.values();
  ctkCmdLineModuleReference ref;
  foreach(ref, references)
  {
    if (ref.description().title() == identifier)
    {
      result = ref;
    }
  }
  return result;
}

void CommandLineModulesView::OnRunButtonPressed()
{
  qDebug() << "Creating module command line...";

  ctkCmdLineModuleInstance* moduleInstance = m_MapTabToModuleInstance[m_Controls->m_TabWidget->currentIndex()];
  if (!moduleInstance)
  {
    qWarning() << "Invalid module instance";
    return;
  }

  qDebug() << "Launching module command line...";

  ctkCmdLineModuleProcessFuture future = moduleInstance->run();

  qDebug() << "Launched module command line...";
}

void CommandLineModulesView::OnStopButtonPressed()
{
  qDebug() << "Stopping module command line...";

  qDebug() << "Stopped module command line...";
}

void CommandLineModulesView::OnRestoreDefaultsButtonPressed()
{

}
<|endoftext|>


<commit_before>#include <Engine.hpp>

Engine::Engine(const int _argc, const char** _argv) :
        argc(_argc), argv(_argv) {
    // check if a game directory is specified on the command line
    if (argc > 1 and argv[1] != nullptr) {
        game = std::string(argv[1]);
    } else {
        game = "game";
    }

    LOGOG_INITIALIZE();

    // create custom format
    class FormatterCustom : public logog::FormatterGCC {
        virtual TOPIC_FLAGS GetTopicFlags(const logog::Topic& topic) {
            return (logog::FormatterGCC::GetTopicFlags(topic) &
                    ~(TOPIC_FILE_NAME_FLAG | TOPIC_LINE_NUMBER_FLAG));
        }
    };

    const std::string logFilename = data_dir + '/' + game + ".log";

    // remove existing log file
    remove(logFilename.c_str());

    logFile = new logog::LogFile(logFilename.c_str());
    logConsole = new logog::Cout;
    formatter = new FormatterCustom;
    // use custom format
    formatter->SetShowTimeOfDay(true);
    logFile->SetFormatter(*formatter);
    logConsole->SetFormatter(*formatter);

    // try to make sure we don't get extra crap in our console log
    std::cout.flush();

    INFO("Logging system initialized.");

    dumpSystemInfo();

    INFO("Initializing Engine with game data in '%s'", game.c_str());

    data_dir = game;

    // TODO: verify data_dir is accesible, abort if not
    // TODO: _chdir into data_dir for easier relative paths everywhere else

    readConfig();

    INFO("Creating %dx%d render target", renderWidth, renderHeight);
    screen.create(renderWidth, renderHeight);

    createWindow(config.fullscreen);

    std::unique_lock<std::mutex> spritesLock(spritesMutex);
    INFO("Creating entities");
    player = std::make_shared<Sprite>(data_dir + "/player.yaml");
    player->setPosition(renderWidth * 1 / 2, renderHeight * 3 / 4);
    sprites.push_back(player);
    INFO("Created player");
    enemy = std::make_shared<Sprite>(data_dir + "/enemy.yaml");
    enemy->setPosition(renderWidth * 1 / 2, renderHeight * 1 / 4);
    sprites.push_back(enemy);
    INFO("Created enemy");
    spritesLock.unlock();

    isReady = true;
    INFO("Initialization Complete");
}

Engine::~Engine() {
    INFO("Logging system shutting down.");

    delete logFile;
    delete logConsole;
    delete formatter;

    LOGOG_SHUTDOWN();
}

bool Engine::ready() {
    if (isReady) {
        INFO("Game of '%s' is ready", config.name.c_str());
    } else {

    }
    return isReady;
}

bool Engine::run() {
    INFO("Starting a game of '%s'", config.name.c_str());

    INFO("Initializing event loop");
    sf::Int32 updateHz = 60;
    sf::Int32 updateWaitTime = 1'000'000 / updateHz;
    sf::Clock gameClock;
    sf::Time elapsedTime;
    sf::Time lastUpdateTime;
    sf::Int64 totalUpdateTime = 0;
    sf::Int64 averageUpdateTime;
    sf::Int32 updateCount = 0;

    INFO("Creating Render thread");
    running = true;
    renderThread = std::make_unique<std::thread>(&Engine::renderLoop, this);

    INFO("Starting event loop");
    while (running) {
        elapsedTime = gameClock.restart();
        processEvents();
        update(elapsedTime);
        //compute
        lastUpdateTime = gameClock.getElapsedTime();
        totalUpdateTime += lastUpdateTime.asMilliseconds();
        averageUpdateTime = totalUpdateTime / ++updateCount;
        // log the average time per update every 1 seconds
        if (updateCount % (60 * 1) == 0) {
            DBUG("Average update time: %d ms", averageUpdateTime);
        }
        // update at approximately 60 Hz (16666us minus time taken by last update
        sf::sleep(sf::microseconds(updateWaitTime - lastUpdateTime.asMicroseconds()));
    }
    INFO("Stopped event loop");
    renderThread->join();
    INFO("Closing window");
    window.close();
    INFO("Game of '%s' ended successfully", config.name.c_str());
    return true;
}

void Engine::processEvents() {
    static sf::Event event;

    while (window.pollEvent(event)) {
        switch (event.type) {
            case sf::Event::Closed:
                INFO("Window closed");
                running = false;
                break;
            case sf::Event::Resized:
                handleResize(event.size);
                break;
            case sf::Event::KeyPressed:
                handleKeyPress(event);
                break;
            case sf::Event::KeyReleased:
                handleKeyRelease(event);
                break;
            default:
                break;
        }
    }
}

void Engine::update(const sf::Time& elapsed) {
    float x, y = 0;

    // get current state of controls
    float joy0_X = sf::Joystick::getAxisPosition(0, sf::Joystick::X);
    float joy0_y = sf::Joystick::getAxisPosition(0, sf::Joystick::Y);
    x = std::fabs(joy0_X) < config.deadZone ? 0 : joy0_X;
    y = std::fabs(joy0_y) < config.deadZone ? 0 : joy0_y;

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
        y += -config.keySpeed;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
        x += config.keySpeed;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
        y += config.keySpeed;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
        x += -config.keySpeed;
    }

    std::unique_lock<std::mutex> spritesLock(spritesMutex);

    player->moveBy(x, y);

    const int millis = elapsed.asMilliseconds();
    for (auto sprite : sprites) {
        sprite->update(millis);
    }

    spritesLock.unlock();
}

void Engine::renderLoop() {
    INFO("Initializing render loop");
    sf::Clock frameClock;
    sf::Int32 lastFrameTime;
    sf::Int32 averageFrameTime;
    sf::Int32 totalFrameTime = 0;
    sf::Int32 frameCount = 0;
    INFO("Starting render loop");
    while (running) {
        frameClock.restart();
        // blank the render target to black
        screen.clear(sf::Color::Black);
        // render all the normal sprites
        std::unique_lock<std::mutex> spritesLock(spritesMutex);
        for (const auto sprite : sprites) {
            screen.draw(*sprite);
        }
        spritesLock.unlock();
        // update the target
        screen.display();
        // lock and activate the window
        std::unique_lock<std::mutex> windowLock(windowMutex);
        if (window.setActive(true)) {
            // blank the window to gray
            window.clear(sf::Color(128, 128, 128));
            // copy render target to window
            window.draw(sf::Sprite(screen.getTexture()));
            // update the window
            window.display();
        } else {
            ("Failed to get window context for rendering.");
        }
        // release the lock
        windowLock.unlock();
        lastFrameTime = frameClock.getElapsedTime().asMilliseconds();
        totalFrameTime += lastFrameTime;
        averageFrameTime = totalFrameTime / ++frameCount;
        // log the time per frame every 60 frames (every second if at 60 Hz)
        if (frameCount % (60 * 1) == 0) {
            DBUG("Average frame time: %d ms", averageFrameTime);
        }
    }
    INFO("Stopped render loop");
}

void Engine::handleResize(const sf::Event::SizeEvent& newSize) {
    // save the new window size since this came from a resize event
    // not from a window creation event (initialization or fullscreen toggle)
    config.width = newSize.width;
    config.height = newSize.height;
    INFO("Window resized to: %dx%d", config.width, config.height);
    // do the calculation
    adjustAspect(sf::Vector2u(newSize.width, newSize.height));
}

void Engine::handleKeyPress(const sf::Event& event) {
    switch (event.key.code) {
        case sf::Keyboard::Escape:
            INFO("Key: Escape: exiting");
            running = false;
            break;
        case sf::Keyboard::Return:
            if (event.key.alt) {
                createWindow(!config.fullscreen);
            }
            break;
        default:
            break;
    }
}

void Engine::handleKeyRelease(const sf::Event& event) {
    switch (event.key.code) {
        default:
            break;
    }
}

void Engine::dumpSystemInfo() {
#ifndef NDEBUG
    INFO(argv[0]);
#endif
    // dump our own version and build info
    INFO("JAGE %d.%d.%d", JAGE_VERSION_MAJOR, JAGE_VERSION_MINOR, JAGE_VERSION_REVISION);
    INFO("Built %s %s", __DATE__, __TIME__);

    // and SFML's info
    INFO("SFML %d.%d.%d", SFML_VERSION_MAJOR, SFML_VERSION_MINOR, SFML_VERSION_PATCH);

// what compiler did we use?
#ifdef __MINGW32__
#ifdef __MINGW64__
    INFO("MinGW-w64 %s", __MINGW64_VERSION_STR);
#else
    INFO("MinGW %s", __MINGW64_VERSION_STR);
#endif
#endif

#ifdef __clang__
    INFO("CLang %s", __clang_version__);
#endif

#ifdef __GNUG__
    INFO("GCC %s", __VERSION__);
#endif

#ifdef MSC_VER
    INFO("Visual C++ %s", _MCS_VER);
#endif
}

void Engine::readConfig() {
    std::string configFilename = data_dir + "/config.yaml";
    INFO("Reading config from '%s'", configFilename.c_str());
    try {
        YAML::Node yamlConfig = YAML::LoadFile(configFilename);
        config.name = yamlConfig["name"].as<std::string>(game);
        config.width = yamlConfig["width"].as<uint32_t>(config.width);
        config.height = yamlConfig["height"].as<uint32_t>(config.height);
        config.fullscreen = yamlConfig["fullscreen"].as<bool>(config.fullscreen);
        config.useDesktopSize = yamlConfig["useDesktopSize"].as<bool>(config.useDesktopSize);
        config.vsync = yamlConfig["vsync"].as<bool>(config.vsync);
        config.deadZone = yamlConfig["deadzone"].as<float>(config.deadZone);
        config.keySpeed = yamlConfig["keySpeed"].as<float>(config.keySpeed);
    } catch (YAML::Exception e) {
        ERR("YAML Exception: %s", e.msg.c_str());
        ERR("Can't load '%s', using sane defaults", configFilename.c_str());
    }
    INFO("Current settings:");
    INFO("\tname = %s", config.name.c_str());
    INFO("\twidth = %d", config.width);
    INFO("\theight = %d", config.height);
    INFO("\tfullscreen = %s", (config.fullscreen ? "true" : "false"));
    INFO("\tuseDesktopSize = %s", (config.useDesktopSize ? "true" : "false"));
    INFO("\tvsync = %s", (config.vsync ? "true" : "false"));
    INFO("\tdeadZone = %f", config.deadZone);
    INFO("\tkeySpeed = %f", config.keySpeed);
}

void Engine::createWindow(const bool shouldFullscreen) {
    unsigned int flags = 0;

    std::unique_lock<std::mutex> windowLock(windowMutex);

    INFO("Reading config");
    sf::VideoMode mode;
    config.fullscreen = shouldFullscreen;
    if (config.fullscreen) {
        INFO("Going fullscreen");
        window.setMouseCursorVisible(false);
        if (config.useDesktopSize) {
            INFO("Setting fullscreen mode (using desktop size): %dx%d",
                 sf::VideoMode::getDesktopMode().width,
                 sf::VideoMode::getDesktopMode().height);
            mode = sf::VideoMode::getDesktopMode();
        } else {
            INFO("Setting fullscreen mode: %dx%d", config.width, config.height);
            mode = sf::VideoMode(config.width, config.height);
        }
        flags = sf::Style::Fullscreen;
    } else {
        INFO("Setting windowed mode: %dx%d", config.width, config.height);
        window.setMouseCursorVisible(true);
        mode = sf::VideoMode(config.width, config.height);
        flags = sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize;
    }
    INFO("Creating the main window");
    window.create(mode, game, flags);
    if (!window.isOpen()) {
        ERR("Could not create main window");
        exit(EXIT_FAILURE);
    }
    window.setActive(true);
    sf::ContextSettings settings = window.getSettings();
    INFO("Using OpenGL %d.%d", settings.majorVersion, settings.minorVersion);

    // initialize the view
    INFO("Setting window view");
    view = window.getDefaultView();
    view.setSize(renderWidth, renderHeight);
    view.setCenter(renderWidth / 2, renderHeight / 2);
    window.setView(view);
    if (config.vsync) {
        INFO("Enabling V-sync");
        window.setVerticalSyncEnabled(true);
    } else {
        window.setVerticalSyncEnabled(false);
    }

    window.setActive(false);
    windowLock.unlock();

    // scale the viewport to maintain good aspect
    adjustAspect(window.getSize());
}

void Engine::adjustAspect(const sf::Vector2u& newSize) {
    INFO("Adjusting aspect for window size %dx%d", newSize.x, newSize.y);
    // compute the current aspect
    float currentRatio = (float) newSize.x / (float) newSize.y;
    // used to offset and scale the viewport to maintain 16:9 aspect
    float widthScale = 1.0f;
    float widthOffset = 0.0f;
    float heightScale = 1.0f;
    float heightOffset = 0.0f;
    // used to compare and compute aspect ratios
    // for logging
    std::string isSixteenNine = "16:9";
    if (currentRatio > 16.0f / 9.0f) {
        // we are wider
        isSixteenNine = "wide";
        widthScale = newSize.y * (16.0f / 9.0f) / newSize.x;
        widthOffset = (1.0f - widthScale) / 2.0f;
    } else if (currentRatio < 16.0f / 9.0f) {
        // we are narrower
        isSixteenNine = "narrow";
        heightScale = newSize.x * (9.0f / 16.0f) / newSize.y;
        heightOffset = (1.0f - heightScale) / 2.0f;
    }
    std::unique_lock<std::mutex> windowLock(windowMutex);
    INFO("Setting %s viewport (wo:%f, ho:%f; ws:%f, hs: %f", isSixteenNine.c_str(),
         widthOffset, heightOffset, widthScale, heightScale);
    view.setViewport(sf::FloatRect(widthOffset, heightOffset, widthScale, heightScale));
    window.setView(view);
    windowLock.unlock();
}

<commit_msg>Rearrange timing stuff to better measure just the parts we care about.<commit_after>#include <Engine.hpp>

Engine::Engine(const int _argc, const char** _argv) :
        argc(_argc), argv(_argv) {
    // check if a game directory is specified on the command line
    if (argc > 1 and argv[1] != nullptr) {
        game = std::string(argv[1]);
    } else {
        game = "game";
    }

    LOGOG_INITIALIZE();

    // create custom format
    class FormatterCustom : public logog::FormatterGCC {
        virtual TOPIC_FLAGS GetTopicFlags(const logog::Topic& topic) {
            return (logog::FormatterGCC::GetTopicFlags(topic) &
                    ~(TOPIC_FILE_NAME_FLAG | TOPIC_LINE_NUMBER_FLAG));
        }
    };

    const std::string logFilename = data_dir + '/' + game + ".log";

    // remove existing log file
    remove(logFilename.c_str());

    logFile = new logog::LogFile(logFilename.c_str());
    logConsole = new logog::Cout;
    formatter = new FormatterCustom;
    // use custom format
    formatter->SetShowTimeOfDay(true);
    logFile->SetFormatter(*formatter);
    logConsole->SetFormatter(*formatter);

    // try to make sure we don't get extra crap in our console log
    std::cout.flush();

    INFO("Logging system initialized.");

    dumpSystemInfo();

    INFO("Initializing Engine with game data in '%s'", game.c_str());

    data_dir = game;

    // TODO: verify data_dir is accesible, abort if not
    // TODO: _chdir into data_dir for easier relative paths everywhere else

    readConfig();

    INFO("Creating %dx%d render target", renderWidth, renderHeight);
    screen.create(renderWidth, renderHeight);

    createWindow(config.fullscreen);

    std::unique_lock<std::mutex> spritesLock(spritesMutex);
    INFO("Creating entities");
    player = std::make_shared<Sprite>(data_dir + "/player.yaml");
    player->setPosition(renderWidth * 1 / 2, renderHeight * 3 / 4);
    sprites.push_back(player);
    INFO("Created player");
    enemy = std::make_shared<Sprite>(data_dir + "/enemy.yaml");
    enemy->setPosition(renderWidth * 1 / 2, renderHeight * 1 / 4);
    sprites.push_back(enemy);
    INFO("Created enemy");
    spritesLock.unlock();

    isReady = true;
    INFO("Initialization Complete");
}

Engine::~Engine() {
    INFO("Logging system shutting down.");

    delete logFile;
    delete logConsole;
    delete formatter;

    LOGOG_SHUTDOWN();
}

bool Engine::ready() {
    if (isReady) {
        INFO("Game of '%s' is ready", config.name.c_str());
    } else {

    }
    return isReady;
}

bool Engine::run() {
    INFO("Starting a game of '%s'", config.name.c_str());

    INFO("Initializing event loop");
    sf::Int64 updateHz = 60;
    sf::Int64 updateWaitTime = 1'000'000 / updateHz;
    sf::Clock gameClock;
    sf::Time elapsedTime;
    sf::Time lastUpdateTime;
    float averageUpdateTime;
    sf::Int64 totalUpdateTime = 0;
    sf::Int64 updateCount = 0;

    INFO("Creating Render thread");
    running = true;
    renderThread = std::make_unique<std::thread>(&Engine::renderLoop, this);

    INFO("Starting event loop");
    while (running) {
        elapsedTime = gameClock.restart();

        //compute update time spent
        totalUpdateTime += lastUpdateTime.asMicroseconds();
        updateCount++;
        averageUpdateTime = static_cast<float>(totalUpdateTime) / updateCount;
        // log the average time per update every 0.5 seconds
        if (updateCount % (60 * 1 / 2) == 0) {
            DBUG("Average update time: %f ms", averageUpdateTime / 1000.0f);
        }

        processEvents();
        update(elapsedTime);

        // remember how long the above code took, for update time spent calculation
        lastUpdateTime = gameClock.getElapsedTime();

        // sleep long enough to update at approximately updateHz
        sf::Int64 timeToWait = updateWaitTime - lastUpdateTime.asMicroseconds();
        sf::sleep(sf::microseconds(timeToWait));
    }
    INFO("Stopped event loop");
    INFO("Average update time: %f ms", averageUpdateTime / 1000.0f);
    renderThread->join();
    INFO("Closing window");
    window.close();
    INFO("Game of '%s' ended successfully", config.name.c_str());
    return true;
}

void Engine::processEvents() {
    static sf::Event event;

    while (window.pollEvent(event)) {
        switch (event.type) {
            case sf::Event::Closed:
                INFO("Window closed");
                running = false;
                break;
            case sf::Event::Resized:
                handleResize(event.size);
                break;
            case sf::Event::KeyPressed:
                handleKeyPress(event);
                break;
            case sf::Event::KeyReleased:
                handleKeyRelease(event);
                break;
            default:
                break;
        }
    }
}

void Engine::update(const sf::Time& elapsed) {
    float x, y = 0;

    // get current state of controls
    float joy0_X = sf::Joystick::getAxisPosition(0, sf::Joystick::X);
    float joy0_y = sf::Joystick::getAxisPosition(0, sf::Joystick::Y);
    x = std::fabs(joy0_X) < config.deadZone ? 0 : joy0_X;
    y = std::fabs(joy0_y) < config.deadZone ? 0 : joy0_y;

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
        y += -config.keySpeed;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
        x += config.keySpeed;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
        y += config.keySpeed;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
        x += -config.keySpeed;
    }

    std::unique_lock<std::mutex> spritesLock(spritesMutex);

    player->moveBy(x, y);

    const int millis = elapsed.asMilliseconds();
    for (auto sprite : sprites) {
        sprite->update(millis);
    }

    spritesLock.unlock();
}

void Engine::renderLoop() {
    INFO("Initializing render loop");
    sf::Clock frameClock;
    sf::Time lastFrameTime;
    float averageFrameTime = 0.0f;
    sf::Int64 totalFrameTime = 0;
    sf::Int64 frameCount = 0;

    INFO("Starting render loop");
    while (running) {
        frameClock.restart();

        // compute FPS
        totalFrameTime += lastFrameTime.asMicroseconds();
        frameCount++;
        averageFrameTime = static_cast<float>(totalFrameTime) / frameCount;
        // log the time per frame every 30 frames (every half second if at 60 Hz)
        if (frameCount % (60 * 1 / 2) == 0) {
            DBUG("Average frame time: %f ms", averageFrameTime / 1000.0f);
        }

        // blank the render target to black
        screen.clear(sf::Color::Black);
        // render all the normal sprites
        std::unique_lock<std::mutex> spritesLock(spritesMutex);
        for (const auto sprite : sprites) {
            screen.draw(*sprite);
        }
        spritesLock.unlock();
        // update the target
        screen.display();

        // lock and activate the window
        std::unique_lock<std::mutex> windowLock(windowMutex);
        if (window.setActive(true)) {
            // blank the window to gray
            window.clear(sf::Color(128, 128, 128));
            // copy render target to window
            window.draw(sf::Sprite(screen.getTexture()));
            // update the window
            window.display();
        } else {
            ("Failed to get window context for rendering.");
        }
        // release the lock
        windowLock.unlock();

        // remember how long the whole loop took, for FPS calculation
        lastFrameTime = frameClock.getElapsedTime();
    }
    INFO("Stopped render loop");
    INFO("Average frame time: %f ms", averageFrameTime / 1000.0);
}

void Engine::handleResize(const sf::Event::SizeEvent& newSize) {
    // save the new window size since this came from a resize event
    // not from a window creation event (initialization or fullscreen toggle)
    config.width = newSize.width;
    config.height = newSize.height;
    INFO("Window resized to: %dx%d", config.width, config.height);
    // do the calculation
    adjustAspect(sf::Vector2u(newSize.width, newSize.height));
}

void Engine::handleKeyPress(const sf::Event& event) {
    switch (event.key.code) {
        case sf::Keyboard::Escape:
            INFO("Key: Escape: exiting");
            running = false;
            break;
        case sf::Keyboard::Return:
            if (event.key.alt) {
                createWindow(!config.fullscreen);
            }
            break;
        default:
            break;
    }
}

void Engine::handleKeyRelease(const sf::Event& event) {
    switch (event.key.code) {
        default:
            break;
    }
}

void Engine::dumpSystemInfo() {
#ifndef NDEBUG
    INFO(argv[0]);
#endif
    // dump our own version and build info
    INFO("JAGE %d.%d.%d", JAGE_VERSION_MAJOR, JAGE_VERSION_MINOR, JAGE_VERSION_REVISION);
    INFO("Built %s %s", __DATE__, __TIME__);

    // and SFML's info
    INFO("SFML %d.%d.%d", SFML_VERSION_MAJOR, SFML_VERSION_MINOR, SFML_VERSION_PATCH);

// what compiler did we use?
#ifdef __MINGW32__
#ifdef __MINGW64__
    INFO("MinGW-w64 %s", __MINGW64_VERSION_STR);
#else
    INFO("MinGW %s", __MINGW64_VERSION_STR);
#endif
#endif

#ifdef __clang__
    INFO("CLang %s", __clang_version__);
#endif

#ifdef __GNUG__
    INFO("GCC %s", __VERSION__);
#endif

#ifdef MSC_VER
    INFO("Visual C++ %s", _MCS_VER);
#endif
}

void Engine::readConfig() {
    std::string configFilename = data_dir + "/config.yaml";
    INFO("Reading config from '%s'", configFilename.c_str());
    try {
        YAML::Node yamlConfig = YAML::LoadFile(configFilename);
        config.name = yamlConfig["name"].as<std::string>(game);
        config.width = yamlConfig["width"].as<uint32_t>(config.width);
        config.height = yamlConfig["height"].as<uint32_t>(config.height);
        config.fullscreen = yamlConfig["fullscreen"].as<bool>(config.fullscreen);
        config.useDesktopSize = yamlConfig["useDesktopSize"].as<bool>(config.useDesktopSize);
        config.vsync = yamlConfig["vsync"].as<bool>(config.vsync);
        config.deadZone = yamlConfig["deadzone"].as<float>(config.deadZone);
        config.keySpeed = yamlConfig["keySpeed"].as<float>(config.keySpeed);
    } catch (YAML::Exception e) {
        ERR("YAML Exception: %s", e.msg.c_str());
        ERR("Can't load '%s', using sane defaults", configFilename.c_str());
    }
    INFO("Current settings:");
    INFO("\tname = %s", config.name.c_str());
    INFO("\twidth = %d", config.width);
    INFO("\theight = %d", config.height);
    INFO("\tfullscreen = %s", (config.fullscreen ? "true" : "false"));
    INFO("\tuseDesktopSize = %s", (config.useDesktopSize ? "true" : "false"));
    INFO("\tvsync = %s", (config.vsync ? "true" : "false"));
    INFO("\tdeadZone = %f", config.deadZone);
    INFO("\tkeySpeed = %f", config.keySpeed);
}

void Engine::createWindow(const bool shouldFullscreen) {
    unsigned int flags = 0;

    std::unique_lock<std::mutex> windowLock(windowMutex);

    INFO("Reading config");
    sf::VideoMode mode;
    config.fullscreen = shouldFullscreen;
    if (config.fullscreen) {
        INFO("Going fullscreen");
        window.setMouseCursorVisible(false);
        if (config.useDesktopSize) {
            INFO("Setting fullscreen mode (using desktop size): %dx%d",
                 sf::VideoMode::getDesktopMode().width,
                 sf::VideoMode::getDesktopMode().height);
            mode = sf::VideoMode::getDesktopMode();
        } else {
            INFO("Setting fullscreen mode: %dx%d", config.width, config.height);
            mode = sf::VideoMode(config.width, config.height);
        }
        flags = sf::Style::Fullscreen;
    } else {
        INFO("Setting windowed mode: %dx%d", config.width, config.height);
        window.setMouseCursorVisible(true);
        mode = sf::VideoMode(config.width, config.height);
        flags = sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize;
    }
    INFO("Creating the main window");
    window.create(mode, game, flags);
    if (!window.isOpen()) {
        ERR("Could not create main window");
        exit(EXIT_FAILURE);
    }
    window.setActive(true);
    sf::ContextSettings settings = window.getSettings();
    INFO("Using OpenGL %d.%d", settings.majorVersion, settings.minorVersion);

    // initialize the view
    INFO("Setting window view");
    view = window.getDefaultView();
    view.setSize(renderWidth, renderHeight);
    view.setCenter(renderWidth / 2, renderHeight / 2);
    window.setView(view);
    if (config.vsync) {
        INFO("Enabling V-sync");
        window.setVerticalSyncEnabled(true);
    } else {
        window.setVerticalSyncEnabled(false);
    }

    window.setActive(false);
    windowLock.unlock();

    // scale the viewport to maintain good aspect
    adjustAspect(window.getSize());
}

void Engine::adjustAspect(const sf::Vector2u& newSize) {
    INFO("Adjusting aspect for window size %dx%d", newSize.x, newSize.y);
    // compute the current aspect
    float currentRatio = (float) newSize.x / (float) newSize.y;
    // used to offset and scale the viewport to maintain 16:9 aspect
    float widthScale = 1.0f;
    float widthOffset = 0.0f;
    float heightScale = 1.0f;
    float heightOffset = 0.0f;
    // used to compare and compute aspect ratios
    // for logging
    std::string isSixteenNine = "16:9";
    if (currentRatio > 16.0f / 9.0f) {
        // we are wider
        isSixteenNine = "wide";
        widthScale = newSize.y * (16.0f / 9.0f) / newSize.x;
        widthOffset = (1.0f - widthScale) / 2.0f;
    } else if (currentRatio < 16.0f / 9.0f) {
        // we are narrower
        isSixteenNine = "narrow";
        heightScale = newSize.x * (9.0f / 16.0f) / newSize.y;
        heightOffset = (1.0f - heightScale) / 2.0f;
    }
    std::unique_lock<std::mutex> windowLock(windowMutex);
    INFO("Setting %s viewport (wo:%f, ho:%f; ws:%f, hs: %f", isSixteenNine.c_str(),
         widthOffset, heightOffset, widthScale, heightScale);
    view.setViewport(sf::FloatRect(widthOffset, heightOffset, widthScale, heightScale));
    window.setView(view);
    windowLock.unlock();
}

<|endoftext|>


<commit_before>/*
   Filename: Events.cpp
   Purpose:  Mutli-targeting inner process message passing

   Part of Engine2D

   Copyright (C) 2014 Vbitz

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "Events.hpp"

#include <vector>
#include <unordered_map>
#include <queue>

#include "Logger.hpp"
#include "Platform.hpp"

namespace Engine {
    namespace Events {

        class EventTarget {
        public:
            void Run(std::function<bool(Json::Value)> filter, Json::Value e) {
                if (filter(_filter)) {
                    _run(e);
                }
            }

            virtual bool IsScript() { return true; }

        protected:
            Json::Value _filter = Json::nullValue;

            void setFilter(Json::Value filter) {
                _filter = filter;
            }

            virtual bool _run(Json::Value e) { return false; }
        };

        class CPPEventTarget : public EventTarget {
        public:
            CPPEventTarget(EventTargetFunc func, Json::Value* filter)
                : _func(func) {
                    setFilter(filter);
                }

            bool IsScript() override { return false; }

        protected:
            bool _run(Json::Value e) {
                this->_func(e);
                return true;
            }

        private:
            EventTargetFunc _func;
        };

        class JSEventTarget : public EventTarget {
        public:
            JSEventTarget(v8::Handle<v8::Function> func, Json::Value* filter){
                _func.Reset(v8::Isolate::GetCurrent(), func);
                    setFilter(filter);
                }

        protected:
            bool _run(Json::Value e) {
                v8::HandleScope scp(v8::Isolate::GetCurrent());
                v8::Local<v8::Context> ctx = v8::Isolate::GetCurrent()->GetCurrentContext();
                if (ctx.IsEmpty() || ctx->Global().IsEmpty()) return;
                v8::Context::Scope ctx_scope(ctx);

                v8::TryCatch tryCatch;

                v8::Handle<v8::Value> args[1];

                v8::Handle<v8::Object> obj = ScriptingManager::GetObjectFromJson(e);

                args[0] = obj;

                v8::Local<v8::Function> func = v8::Local<v8::Function>::New(v8::Isolate::GetCurrent(), _func);

                func->Call(ctx->Global(), 1, args);

                if (!tryCatch.StackTrace().IsEmpty()) {
                    ScriptingManager::ReportException(v8::Isolate::GetCurrent(), &tryCatch);
                    return false;
                } else {
                    return true;
                }
            }

        private:
            v8::Persistent<v8::Function> _func;
        };

        struct Event {
            std::string Label;
            EventTarget* Target = NULL;
            bool Active = false;

            Event() : Label(""), Active(false) {}
            Event(std::string Label, EventTarget* target) : Label(Label), Target(target), Active(true) { }
        };

        struct EventClassSecurity {
            bool NoScript = false;

            std::string ToString() {
                std::stringstream ss;
                ss << "NoScript=" << this->NoScript;
                return ss.str();
            }
        };

        struct EventClass {
            bool Valid = false;
            std::string TargetName;
            EventClassSecurity Security;
            std::unordered_map<std::string, Event> Events;
            std::queue<Json::Value> DeferedMessages;
        };

        Platform::Mutex* _eventMutex;
        std::unordered_map<std::string, EventClass> _events;

        int lastEventID = 0;

        void _debug(Json::Value args) {
            Logger::begin("Events", Logger::LogLevel_Log) << " == EVENT DEBUG ==" << Logger::end();

            for (auto iter = _events.begin();
                 iter != _events.end();
                 iter++) {
                Logger::begin("Events", Logger::LogLevel_Log)
                    << "    ==========================="
                    << Logger::end();
                Logger::begin("Events", Logger::LogLevel_Log)
                    << "    Event Class: " << iter->first
                    << Logger::end();
                Logger::begin("Events", Logger::LogLevel_Log)
                    << "    Event Security: " << iter->second.Security.ToString()
                    << Logger::end();
                Logger::begin("Events", Logger::LogLevel_Log)
                    << "    Event Members: "
                    << Logger::end();

                for (auto iter2 = iter->second.Events.begin();
                     iter2 != iter->second.Events.end();
                     iter2++) {
                    Logger::begin("Events", Logger::LogLevel_Log)
                    << "        " << (iter2->second.Target->IsScript() ? "Script" : "C++   ") << " | " << iter2->first
                        << Logger::end();
                }
            }
        }

        void Init() {
            _eventMutex = Platform::CreateMutex();
            Events::On("eventDebug", "Events::_debug", _debug);
        }

        void Emit(std::string evnt, std::function<bool(Json::Value)> filter, Json::Value args) {
            std::vector<Event> deleteTargets;

            EventClass& cls = _events[evnt];
            if (!cls.Valid) { _eventMutex->Exit(); return; }
            for (auto iter = cls.Events.begin(); iter != cls.Events.end(); iter++) {
                if (iter->second.Target == NULL) { throw "Invalid Target"; }
                if (iter->second.Active) {
                    if (!(cls.Security.NoScript && iter->second.Target->IsScript())) {
                        iter->second.Target->Run(filter, args);
                    }
                } else {
                    deleteTargets.push_back(iter->second);
                }
            }
            for (auto iter = deleteTargets.begin(); iter != deleteTargets.end(); iter++) {
                delete cls.Events[iter->Label].Target;
                cls.Events.erase(iter->Label);
            }
        }

        void Emit(std::string evnt, Json::Value args) {
            Emit(evnt, [](Json::Value e) { return true; }, args);
        }

        void Emit(std::string evnt) {
            Emit(evnt, [](Json::Value e) { return true; }, Json::nullValue);
        }

        void On(std::string evnt, std::string name, Json::Value e, EventTargetFunc target) {
            std::string evnt_copy = std::string(evnt.c_str());
            std::string name_copy = std::string(name.c_str());

            Event newEvent = Event(name_copy, new CPPEventTarget(target, new Json::Value(e)));
            EventClass& cls = _events[evnt_copy];
            if (!cls.Valid) {
                cls.Valid = true;
                cls.TargetName = evnt_copy;
            }
            cls.Events[name_copy] = newEvent;
        }

        void On(std::string evnt, std::string name, Json::Value e, v8::Handle<v8::
            Function> target) {
            std::string evnt_copy = std::string(evnt.c_str());
            std::string name_copy = std::string(name.c_str());

            Event newEvent = Event(name_copy, new JSEventTarget(target, new Json::Value(e)));
            EventClass& cls = _events[evnt_copy];
            if (!cls.Valid) {
                cls.Valid = true;
                cls.TargetName = evnt_copy;
            }
            cls.Events[name_copy] = newEvent;
        }

        void On(std::string evnt, std::string name, EventTargetFunc target) {
            On(evnt, name, Json::nullValue, target);
        }

        void On(std::string evnt, std::string name, v8::Handle<v8::Function> target) {
            On(evnt, name, Json::nullValue, target);
        }

        void Clear(std::string eventID) {
            for (auto iter = _events.begin(); iter != _events.end(); iter++) {
                for (auto iter2 = iter->second.Events.begin();
                     iter2 != iter->second.Events.end(); iter2++) {
                    if (iter2->first == eventID) {
                        iter2->second.Active = false;
                    }
                }
            }
        }

        // Only called from the main thread
        void PollDeferedMessages() {
            _eventMutex->Enter();

            for (auto iter = _events.begin(); iter != _events.end(); iter++) {
                while (iter->second.DeferedMessages.size() > 0) {
                    for (auto iter2 = iter->second.Events.begin(); iter2 != iter->second.Events.end(); iter2++) {
                        if (iter2->second.Target == NULL) { throw "Invalid Target"; }
                        if (iter2->second.Active) {
                            if (!(iter->second.Security.NoScript && iter2->second.Target->IsScript())) {
                                iter2->second.Target->Run(
                                    [](Json::Value e) { return true; },
                                    iter->second.DeferedMessages.front());
                            }
                        }
                    }
                    iter->second.DeferedMessages.pop();
                }
            }

            _eventMutex->Exit();
        }

        // Called from any worker thread
        void EmitThread(std::string threadID, std::string evnt, Json::Value e) {
            _eventMutex->Enter();

            if (_events.count(evnt) > 0) {
                _events[evnt].DeferedMessages.push(e);
            }

            _eventMutex->Exit();
        }
    }
}<commit_msg>Tweaked JSEventTarget::_run for performance<commit_after>/*
   Filename: Events.cpp
   Purpose:  Mutli-targeting inner process message passing

   Part of Engine2D

   Copyright (C) 2014 Vbitz

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "Events.hpp"

#include <vector>
#include <unordered_map>
#include <queue>

#include "Logger.hpp"
#include "Platform.hpp"

namespace Engine {
    namespace Events {

        class EventTarget {
        public:
            void Run(std::function<bool(Json::Value)> filter, Json::Value e) {
                if (filter(_filter)) {
                    _run(e);
                }
            }

            virtual bool IsScript() { return true; }

        protected:
            Json::Value _filter = Json::nullValue;

            void setFilter(Json::Value filter) {
                _filter = filter;
            }

            virtual bool _run(Json::Value e) { return false; }
        };

        class CPPEventTarget : public EventTarget {
        public:
            CPPEventTarget(EventTargetFunc func, Json::Value* filter)
                : _func(func) {
                    setFilter(filter);
                }

            bool IsScript() override { return false; }

        protected:
            bool _run(Json::Value e) {
                this->_func(e);
                return true;
            }

        private:
            EventTargetFunc _func;
        };

        class JSEventTarget : public EventTarget {
        public:
            JSEventTarget(v8::Handle<v8::Function> func, Json::Value* filter){
                _func.Reset(v8::Isolate::GetCurrent(), func);
                    setFilter(filter);
                }

        protected:
            bool _run(Json::Value e) {
                v8::Isolate* currentIsolate = v8::Isolate::GetCurrent();
                v8::Local<v8::Context> ctx = currentIsolate->GetCurrentContext();
                if (ctx.IsEmpty() || ctx->Global().IsEmpty()) return;

                v8::TryCatch tryCatch;

                v8::Local<v8::Object> obj;

                if ((e.isObject() || e.isArray()) &&
                    e.getMemberNames().size() == 0) {
                    obj = v8::Object::New();
                } else {
                    obj = ScriptingManager::GetObjectFromJson(e);
                }

                v8::Local<v8::Value> args[1] = {obj};

                v8::Local<v8::Function> func = v8::Local<v8::Function>::New(currentIsolate, _func);

                func->Call(ctx->Global(), 1, args);

                if (!tryCatch.StackTrace().IsEmpty()) {
                    ScriptingManager::ReportException(currentIsolate, &tryCatch);
                    return false;
                } else {
                    return true;
                }
            }

        private:
            v8::Persistent<v8::Function> _func;
        };

        struct Event {
            std::string Label;
            EventTarget* Target = NULL;
            bool Active = false;

            Event() : Label(""), Active(false) {}
            Event(std::string Label, EventTarget* target) : Label(Label), Target(target), Active(true) { }
        };

        struct EventClassSecurity {
            bool NoScript = false;

            std::string ToString() {
                std::stringstream ss;
                ss << "NoScript=" << this->NoScript;
                return ss.str();
            }
        };

        struct EventClass {
            bool Valid = false;
            std::string TargetName;
            EventClassSecurity Security;
            std::unordered_map<std::string, Event> Events;
            std::queue<Json::Value> DeferedMessages;
        };

        Platform::Mutex* _eventMutex;
        std::unordered_map<std::string, EventClass> _events;

        int lastEventID = 0;

        void _debug(Json::Value args) {
            Logger::begin("Events", Logger::LogLevel_Log) << " == EVENT DEBUG ==" << Logger::end();

            for (auto iter = _events.begin();
                 iter != _events.end();
                 iter++) {
                Logger::begin("Events", Logger::LogLevel_Log)
                    << "    ==========================="
                    << Logger::end();
                Logger::begin("Events", Logger::LogLevel_Log)
                    << "    Event Class: " << iter->first
                    << Logger::end();
                Logger::begin("Events", Logger::LogLevel_Log)
                    << "    Event Security: " << iter->second.Security.ToString()
                    << Logger::end();
                Logger::begin("Events", Logger::LogLevel_Log)
                    << "    Event Members: "
                    << Logger::end();

                for (auto iter2 = iter->second.Events.begin();
                     iter2 != iter->second.Events.end();
                     iter2++) {
                    Logger::begin("Events", Logger::LogLevel_Log)
                    << "        " << (iter2->second.Target->IsScript() ? "Script" : "C++   ") << " | " << iter2->first
                        << Logger::end();
                }
            }
        }

        void Init() {
            _eventMutex = Platform::CreateMutex();
            Events::On("eventDebug", "Events::_debug", _debug);
        }

        void Emit(std::string evnt, std::function<bool(Json::Value)> filter, Json::Value args) {
            std::vector<Event> deleteTargets;

            EventClass& cls = _events[evnt];
            if (!cls.Valid) { _eventMutex->Exit(); return; }
            for (auto iter = cls.Events.begin(); iter != cls.Events.end(); iter++) {
                if (iter->second.Target == NULL) { throw "Invalid Target"; }
                if (iter->second.Active) {
                    if (!(cls.Security.NoScript && iter->second.Target->IsScript())) {
                        iter->second.Target->Run(filter, args);
                    }
                } else {
                    deleteTargets.push_back(iter->second);
                }
            }
            for (auto iter = deleteTargets.begin(); iter != deleteTargets.end(); iter++) {
                delete cls.Events[iter->Label].Target;
                cls.Events.erase(iter->Label);
            }
        }

        void Emit(std::string evnt, Json::Value args) {
            Emit(evnt, [](Json::Value e) { return true; }, args);
        }

        void Emit(std::string evnt) {
            Emit(evnt, [](Json::Value e) { return true; }, Json::nullValue);
        }

        void On(std::string evnt, std::string name, Json::Value e, EventTargetFunc target) {
            std::string evnt_copy = std::string(evnt.c_str());
            std::string name_copy = std::string(name.c_str());

            Event newEvent = Event(name_copy, new CPPEventTarget(target, new Json::Value(e)));
            EventClass& cls = _events[evnt_copy];
            if (!cls.Valid) {
                cls.Valid = true;
                cls.TargetName = evnt_copy;
            }
            cls.Events[name_copy] = newEvent;
        }

        void On(std::string evnt, std::string name, Json::Value e, v8::Handle<v8::
            Function> target) {
            std::string evnt_copy = std::string(evnt.c_str());
            std::string name_copy = std::string(name.c_str());

            Event newEvent = Event(name_copy, new JSEventTarget(target, new Json::Value(e)));
            EventClass& cls = _events[evnt_copy];
            if (!cls.Valid) {
                cls.Valid = true;
                cls.TargetName = evnt_copy;
            }
            cls.Events[name_copy] = newEvent;
        }

        void On(std::string evnt, std::string name, EventTargetFunc target) {
            On(evnt, name, Json::nullValue, target);
        }

        void On(std::string evnt, std::string name, v8::Handle<v8::Function> target) {
            On(evnt, name, Json::nullValue, target);
        }

        void Clear(std::string eventID) {
            for (auto iter = _events.begin(); iter != _events.end(); iter++) {
                for (auto iter2 = iter->second.Events.begin();
                     iter2 != iter->second.Events.end(); iter2++) {
                    if (iter2->first == eventID) {
                        iter2->second.Active = false;
                    }
                }
            }
        }

        // Only called from the main thread
        void PollDeferedMessages() {
            _eventMutex->Enter();

            for (auto iter = _events.begin(); iter != _events.end(); iter++) {
                while (iter->second.DeferedMessages.size() > 0) {
                    for (auto iter2 = iter->second.Events.begin(); iter2 != iter->second.Events.end(); iter2++) {
                        if (iter2->second.Target == NULL) { throw "Invalid Target"; }
                        if (iter2->second.Active) {
                            if (!(iter->second.Security.NoScript && iter2->second.Target->IsScript())) {
                                iter2->second.Target->Run(
                                    [](Json::Value e) { return true; },
                                    iter->second.DeferedMessages.front());
                            }
                        }
                    }
                    iter->second.DeferedMessages.pop();
                }
            }

            _eventMutex->Exit();
        }

        // Called from any worker thread
        void EmitThread(std::string threadID, std::string evnt, Json::Value e) {
            _eventMutex->Enter();

            if (_events.count(evnt) > 0) {
                _events[evnt].DeferedMessages.push(e);
            }

            _eventMutex->Exit();
        }
    }
}<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_IO_HPP_INCLUDED
#define TORRENT_IO_HPP_INCLUDED

namespace libtorrent
{
	namespace detail
	{
		template <class T> struct type {};

		// reads an integer from a byte stream
		// in big endian byte order and converts
		// it to native endianess
		template <class T, class InIt>
		inline T read_impl(InIt& start, type<T>)
		{
			T ret = 0;
			for (int i = 0; i < (int)sizeof(T); ++i)
			{
				ret <<= 8;
				ret |= static_cast<unsigned char>(*start);
				++start;
			}
			return ret;
		}

		template <class T, class OutIt>
		inline void write_impl(T val, OutIt& start)
		{
			for (int i = (int)sizeof(T)-1; i >= 0; --i)
			{
				*start = static_cast<unsigned char>((val >> (i * 8)) & 0xff);
				++start;
			}
		}

		// -- adaptors

		template <class InIt>
		boost::int64_t read_int64(InIt& start)
		{ return read_impl(start, type<boost::int64_t>()); }

		template <class InIt>
		boost::uint64_t read_uint64(InIt& start)
		{ return read_impl(start, type<boost::uint64_t>()); }

		template <class InIt>
		boost::uint32_t read_uint32(InIt& start)
		{ return read_impl(start, type<boost::uint32_t>()); }

		template <class InIt>
		boost::int32_t read_int32(InIt& start)
		{ return read_impl(start, type<boost::int32_t>()); }

		template <class InIt>
		boost::int16_t read_int16(InIt& start)
		{ return read_impl(start, type<boost::int16_t>()); }

		template <class InIt>
		boost::uint16_t read_uint16(InIt& start)
		{ return read_impl(start, type<boost::uint16_t>()); }

		template <class InIt>
		boost::int8_t read_int8(InIt& start)
		{ return read_impl(start, type<boost::int8_t>()); }

		template <class InIt>
		boost::uint8_t read_uint8(InIt& start)
		{ return read_impl(start, type<boost::uint8_t>()); }

		template <class OutIt>
		void write_uint64(boost::uint64_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_int64(boost::int64_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_uint32(boost::uint32_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_int32(boost::int32_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_uint16(boost::uint16_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_int16(boost::int16_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_uint8(boost::uint8_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_int8(boost::int8_t val, OutIt& start)
		{ write_impl(val, start); }

	}
}

#endif // TORRENT_IO_HPP_INCLUDED
<commit_msg>*** empty log message ***<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_IO_HPP_INCLUDED
#define TORRENT_IO_HPP_INCLUDED

#include <boost/cstdint.hpp>

namespace libtorrent
{
	namespace detail
	{
		template <class T> struct type {};

		// reads an integer from a byte stream
		// in big endian byte order and converts
		// it to native endianess
		template <class T, class InIt>
		inline T read_impl(InIt& start, type<T>)
		{
			T ret = 0;
			for (int i = 0; i < (int)sizeof(T); ++i)
			{
				ret <<= 8;
				ret |= static_cast<unsigned char>(*start);
				++start;
			}
			return ret;
		}

		template <class T, class OutIt>
		inline void write_impl(T val, OutIt& start)
		{
			for (int i = (int)sizeof(T)-1; i >= 0; --i)
			{
				*start = static_cast<unsigned char>((val >> (i * 8)) & 0xff);
				++start;
			}
		}

		// -- adaptors

		template <class InIt>
		boost::int64_t read_int64(InIt& start)
		{ return read_impl(start, type<boost::int64_t>()); }

		template <class InIt>
		boost::uint64_t read_uint64(InIt& start)
		{ return read_impl(start, type<boost::uint64_t>()); }

		template <class InIt>
		boost::uint32_t read_uint32(InIt& start)
		{ return read_impl(start, type<boost::uint32_t>()); }

		template <class InIt>
		boost::int32_t read_int32(InIt& start)
		{ return read_impl(start, type<boost::int32_t>()); }

		template <class InIt>
		boost::int16_t read_int16(InIt& start)
		{ return read_impl(start, type<boost::int16_t>()); }

		template <class InIt>
		boost::uint16_t read_uint16(InIt& start)
		{ return read_impl(start, type<boost::uint16_t>()); }

		template <class InIt>
		boost::int8_t read_int8(InIt& start)
		{ return read_impl(start, type<boost::int8_t>()); }

		template <class InIt>
		boost::uint8_t read_uint8(InIt& start)
		{ return read_impl(start, type<boost::uint8_t>()); }

		template <class OutIt>
		void write_uint64(boost::uint64_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_int64(boost::int64_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_uint32(boost::uint32_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_int32(boost::int32_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_uint16(boost::uint16_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_int16(boost::int16_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_uint8(boost::uint8_t val, OutIt& start)
		{ write_impl(val, start); }

		template <class OutIt>
		void write_int8(boost::int8_t val, OutIt& start)
		{ write_impl(val, start); }

	}
}

#endif // TORRENT_IO_HPP_INCLUDED
<|endoftext|>