<commit_before>#include <cassert>
#include <cmath>
#include <cstdint>
#include <string>

#include "SDL.h"

#include "Game.h"

#include "GameData.h"
#include "Options.h"
#include "OptionsParser.h"
#include "PlayerInterface.h"
#include "../Assets/CityDataFile.h"
#include "../Assets/TextAssets.h"
#include "../Interface/Panel.h"
#include "../Media/FontManager.h"
#include "../Media/MusicFile.h"
#include "../Media/MusicName.h"
#include "../Media/PPMFile.h"
#include "../Media/TextureManager.h"
#include "../Rendering/Renderer.h"
#include "../Rendering/Surface.h"
#include "../Utilities/Debug.h"
#include "../Utilities/File.h"
#include "../Utilities/Platform.h"
#include "../Utilities/String.h"

#include "components/vfs/manager.hpp"

Game::Game()
{
	DebugMention("Initializing (Platform: " + std::string(SDL_GetPlatform()) + ").");

	// Get the current working directory. This is most relevant for platforms
	// like macOS, where the base path might be in the app's own "Resources" folder.
	this->basePath = Platform::getBasePath();

	// Get the path to the options folder. This is platform-dependent and points inside
	// the "preferences directory" so it's always writable. Append "options.txt" to access
	// the file itself.
	this->optionsPath = Platform::getOptionsPath();

	// Parse the desired options.txt.
	this->options = [this]()
	{
		// We want any local copy of "options/options.txt" to override the one
		// in the preferences directory for development purposes. At some point,
		// options.txt should be hardcoded in the executable and generated in the
		// preferences directory if it doesn't exist either there or locally.
		const std::string desiredOptionsPath = [this]()
		{
			const std::string localOptionsPath(this->basePath + "options/" + OptionsParser::FILENAME);
			const std::string prefsOptionsPath(this->optionsPath + OptionsParser::FILENAME);

			// Look for the local "options/options.txt" first.
			if (File::exists(localOptionsPath))
			{
				DebugMention("Using local \"options/" + OptionsParser::FILENAME +
					"\" (intended for development purposes).");
				return localOptionsPath;
			}
			else
			{
				// Create "<PrefsOptionsPath>/options.txt" if it doesn't exist.
				if (!File::exists(prefsOptionsPath))
				{
					// @todo: generate new options.txt via hardcoded text in executable? Maybe a bad idea.
					/*DebugMention("Created " + OptionsParser::FILENAME + " in \"" +
						prefsOptionsPath + "\".");*/
					DebugNotImplemented();
				}

				return prefsOptionsPath;
			}
		}();

		return OptionsParser::parse(desiredOptionsPath);
	}();

	// Verify that GLOBAL.BSA (the most important Arena file) exists.
	const bool arenaPathIsRelative = File::pathIsRelative(
		this->getOptions().getArenaPath());
	const std::string globalBsaPath = [this, arenaPathIsRelative]()
	{
		// Include the base path if the ArenaPath is relative.
		return (arenaPathIsRelative ? this->basePath : "") +
			this->options->getArenaPath() + "/GLOBAL.BSA";
	}();

	DebugAssert(File::exists(globalBsaPath),
		"\"" + this->options->getArenaPath() + "\" not a valid ARENA path.");

	// Initialize virtual file system using the Arena path in the options file.
	VFS::Manager::get().initialize(std::string(
		(arenaPathIsRelative ? this->basePath : "") + this->options->getArenaPath()));

	// Initialize the OpenAL Soft audio manager.
	this->audioManager.init(*this->options.get());

	// Initialize the SDL renderer and window with the given settings.
	this->renderer = std::unique_ptr<Renderer>(new Renderer(
		this->options->getScreenWidth(), this->options->getScreenHeight(),
		this->options->isFullscreen(), this->options->getLetterboxAspect()));

	// Initialize the texture manager with the SDL window's pixel format.
	this->textureManager = std::unique_ptr<TextureManager>(new TextureManager(
		*this->renderer.get()));

	// Initialize the font manager. Fonts (i.e., FONT_A.DAT) are loaded on demand.
	this->fontManager = std::unique_ptr<FontManager>(new FontManager());

	// Load various plain text assets.
	this->textAssets = std::unique_ptr<TextAssets>(new TextAssets());

	// Load city data file.
	this->cityDataFile = std::unique_ptr<CityDataFile>(new CityDataFile("CITYDATA.00"));

	// Set window icon (treat black as transparent for 24-bit PPMs).
	int iconWidth, iconHeight;
	std::unique_ptr<uint32_t[]> iconPixels = PPMFile::read(
		this->basePath + "data/icon.ppm", iconWidth, iconHeight);
	Surface icon(Surface::createSurfaceWithFormatFrom(iconPixels.get(),
		iconWidth, iconHeight, Renderer::DEFAULT_BPP,
		iconWidth * sizeof(*iconPixels.get()), Renderer::DEFAULT_PIXELFORMAT));
	SDL_SetColorKey(icon.get(), SDL_TRUE, SDL_MapRGBA(icon.get()->format, 0, 0, 0, 255));
	this->renderer->setWindowIcon(icon.get());

	// Initialize panel and music to default.
	this->panel = Panel::defaultPanel(this);
	this->setMusic(MusicName::PercIntro);

	// Use a texture as the cursor instead.
	SDL_ShowCursor(SDL_FALSE);

	// Leave some members null for now. The game data is initialized when the player
	// enters the game world, and the "next panel" is a temporary used by the game
	// to avoid corruption between panel events which change the panel.
	this->gameData = nullptr;
	this->nextPanel = nullptr;
	this->nextSubPanel = nullptr;

	// This keeps the programmer from deleting a sub-panel the same frame it's in use.
	// The pop is delayed until the beginning of the next frame.
	this->requestedSubPanelPop = false;
}

Game::~Game()
{

}

AudioManager &Game::getAudioManager()
{
	return this->audioManager;
}

const InputManager &Game::getInputManager() const
{
	return this->inputManager;
}

FontManager &Game::getFontManager() const
{
	return *this->fontManager.get();
}

bool Game::gameDataIsActive() const
{
	return this->gameData.get() != nullptr;
}

GameData &Game::getGameData() const
{
	// The caller should not request the game data when there is no active session.
	assert(this->gameDataIsActive());

	return *this->gameData.get();
}

Options &Game::getOptions() const
{
	return *this->options.get();
}

Renderer &Game::getRenderer() const
{
	return *this->renderer.get();
}

TextureManager &Game::getTextureManager() const
{
	return *this->textureManager.get();
}

TextAssets &Game::getTextAssets() const
{
	return *this->textAssets.get();
}

CityDataFile &Game::getCityDataFile() const
{
	return *this->cityDataFile.get();
}

const FPSCounter &Game::getFPSCounter() const
{
	return this->fpsCounter;
}

void Game::setPanel(std::unique_ptr<Panel> nextPanel)
{
	this->nextPanel = std::move(nextPanel);
}

void Game::pushSubPanel(std::unique_ptr<Panel> nextSubPanel)
{
	this->nextSubPanel = std::move(nextSubPanel);
}

void Game::popSubPanel()
{
	// The active sub-panel must not pop more than one sub-panel, because it may
	// have unintended side effects for other panels below it.
	DebugAssert(!this->requestedSubPanelPop, "Already scheduled to pop this sub-panel.");

	// If there are no sub-panels, then there is only the main panel, and panels
	// should never have any sub-panels to pop.
	DebugAssert(this->subPanels.size() > 0, "No sub-panels to pop.");

	this->requestedSubPanelPop = true;
}

void Game::setMusic(MusicName name)
{
	const std::string &filename = MusicFile::fromName(name);
	this->audioManager.playMusic(filename);
}

void Game::setGameData(std::unique_ptr<GameData> gameData)
{
	this->gameData = std::move(gameData);
}

void Game::resizeWindow(int width, int height)
{
	// Resize the window, and the 3D renderer if initialized.
	auto &options = this->getOptions();
	const bool fullGameWindow = options.getPlayerInterface() == PlayerInterface::Modern;
	this->renderer->resize(width, height, options.getResolutionScale(), fullGameWindow);
}

void Game::handlePanelChanges()
{
	// If a sub-panel pop was requested, then pop the top of the sub-panel stack.
	if (this->requestedSubPanelPop)
	{
		this->subPanels.pop_back();
		this->requestedSubPanelPop = false;
	}

	// If a new sub-panel was requested, then add it to the stack.
	if (this->nextSubPanel.get() != nullptr)
	{
		this->subPanels.push_back(std::move(this->nextSubPanel));
	}

	// If a new panel was requested, switch to it. If it will be the active panel
	// (i.e., there are no sub-panels), then subsequent events will be sent to it.
	if (this->nextPanel.get() != nullptr)
	{
		this->panel = std::move(this->nextPanel);
	}
}

void Game::handleEvents(bool &running)
{
	// Handle events for the current game state.
	SDL_Event e;
	while (SDL_PollEvent(&e) != 0)
	{
		// Application events and window resizes are handled here.
		bool applicationExit = this->inputManager.applicationExit(e);
		bool resized = this->inputManager.windowResized(e);
		bool takeScreenshot = this->inputManager.keyPressed(e, SDLK_PRINTSCREEN);

		if (applicationExit)
		{
			running = false;
		}

		if (resized)
		{
			int width = e.window.data1;
			int height = e.window.data2;
			this->resizeWindow(width, height);

			// Call each panel's resize method. The panels should not be listening for
			// resize events themselves because it's more of an "application event" than
			// a panel event.
			this->panel->resize(width, height);

			for (auto &subPanel : this->subPanels)
			{
				subPanel->resize(width, height);
			}
		}

		if (takeScreenshot)
		{
			// Save a screenshot to the local folder.
			auto &renderer = this->getRenderer();
			Surface screenshot(renderer.getScreenshot());
			SDL_SaveBMP(screenshot.get(), "out.bmp");
		}

		// Panel-specific events are handled by the active panel or sub-panel. If any
		// sub-panels exist, choose the top one. Otherwise, choose the main panel.
		if (this->subPanels.size() > 0)
		{
			this->subPanels.back()->handleEvent(e);
		}
		else
		{
			this->panel->handleEvent(e);
		}

		// See if the event requested any changes in active panels.
		this->handlePanelChanges();
	}
}

void Game::tick(double dt)
{
	// If any sub-panels are active, tick the top one by delta time. Otherwise,
	// tick the main panel.
	if (this->subPanels.size() > 0)
	{
		this->subPanels.back()->tick(dt);
	}
	else
	{
		this->panel->tick(dt);
	}

	// See if the panel tick requested any changes in active panels.
	this->handlePanelChanges();
}

void Game::render()
{
	// Draw the panel's main content.
	this->panel->render(*this->renderer.get());

	// Draw any sub-panels back to front.
	for (auto &subPanel : this->subPanels)
	{
		subPanel->render(*this->renderer.get());
	}

	// Get the active panel's cursor texture and alignment.
	const std::pair<SDL_Texture*, CursorAlignment> cursor = (this->subPanels.size() > 0) ?
		this->subPanels.back()->getCurrentCursor() : this->panel->getCurrentCursor();

	// Draw cursor if not null. Some panels do not define a cursor (like cinematics),
	// so their cursor is always null.
	if (cursor.first != nullptr)
	{
		// The panel should not be drawing the cursor themselves. It's done here
		// just to make sure that the cursor is drawn only once and is always drawn last.
		this->renderer->drawCursor(cursor.first, cursor.second,
			this->inputManager.getMousePosition(), this->options->getCursorScale());
	}

	this->renderer->present();
}

void Game::loop()
{
	// Longest allowed frame time.
	const int maximumMS = 1000 / Options::MIN_FPS;

	int thisTime = SDL_GetTicks();

	// Primary game loop.
	bool running = true;
	while (running)
	{
		const int lastTime = thisTime;
		thisTime = SDL_GetTicks();

		// Fastest allowed frame time in milliseconds.
		const int minimumMS = 1000 / this->options->getTargetFPS();

		// Delay the current frame if the previous one was too fast.
		int frameTime = thisTime - lastTime;
		if (frameTime < minimumMS)
		{
			SDL_Delay(static_cast<uint32_t>(minimumMS - frameTime));
			thisTime = SDL_GetTicks();
			frameTime = thisTime - lastTime;
		}

		// Clamp the delta time to at most the maximum frame time.
		const double dt = std::fmin(frameTime, maximumMS) / 1000.0;

		// Update the input manager's state.
		this->inputManager.update();

		// Update the audio manager, checking for finished sounds.
		this->audioManager.update();

		// Update FPS counter.
		this->fpsCounter.updateFrameTime(dt);

		// Listen for input events.
		this->handleEvents(running);

		// Animate the current game state by delta time.
		this->tick(dt);

		// Draw to the screen.
		this->render();
	}
}
<commit_msg>Improved delta time calculation in game loop.<commit_after>#include <cassert>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <string>
#include <thread>

#include "SDL.h"

#include "Game.h"

#include "GameData.h"
#include "Options.h"
#include "OptionsParser.h"
#include "PlayerInterface.h"
#include "../Assets/CityDataFile.h"
#include "../Assets/TextAssets.h"
#include "../Interface/Panel.h"
#include "../Media/FontManager.h"
#include "../Media/MusicFile.h"
#include "../Media/MusicName.h"
#include "../Media/PPMFile.h"
#include "../Media/TextureManager.h"
#include "../Rendering/Renderer.h"
#include "../Rendering/Surface.h"
#include "../Utilities/Debug.h"
#include "../Utilities/File.h"
#include "../Utilities/Platform.h"
#include "../Utilities/String.h"

#include "components/vfs/manager.hpp"

Game::Game()
{
	DebugMention("Initializing (Platform: " + std::string(SDL_GetPlatform()) + ").");

	// Get the current working directory. This is most relevant for platforms
	// like macOS, where the base path might be in the app's own "Resources" folder.
	this->basePath = Platform::getBasePath();

	// Get the path to the options folder. This is platform-dependent and points inside
	// the "preferences directory" so it's always writable. Append "options.txt" to access
	// the file itself.
	this->optionsPath = Platform::getOptionsPath();

	// Parse the desired options.txt.
	this->options = [this]()
	{
		// We want any local copy of "options/options.txt" to override the one
		// in the preferences directory for development purposes. At some point,
		// options.txt should be hardcoded in the executable and generated in the
		// preferences directory if it doesn't exist either there or locally.
		const std::string desiredOptionsPath = [this]()
		{
			const std::string localOptionsPath(this->basePath + "options/" + OptionsParser::FILENAME);
			const std::string prefsOptionsPath(this->optionsPath + OptionsParser::FILENAME);

			// Look for the local "options/options.txt" first.
			if (File::exists(localOptionsPath))
			{
				DebugMention("Using local \"options/" + OptionsParser::FILENAME +
					"\" (intended for development purposes).");
				return localOptionsPath;
			}
			else
			{
				// Create "<PrefsOptionsPath>/options.txt" if it doesn't exist.
				if (!File::exists(prefsOptionsPath))
				{
					// @todo: generate new options.txt via hardcoded text in executable? Maybe a bad idea.
					/*DebugMention("Created " + OptionsParser::FILENAME + " in \"" +
						prefsOptionsPath + "\".");*/
					DebugNotImplemented();
				}

				return prefsOptionsPath;
			}
		}();

		return OptionsParser::parse(desiredOptionsPath);
	}();

	// Verify that GLOBAL.BSA (the most important Arena file) exists.
	const bool arenaPathIsRelative = File::pathIsRelative(
		this->getOptions().getArenaPath());
	const std::string globalBsaPath = [this, arenaPathIsRelative]()
	{
		// Include the base path if the ArenaPath is relative.
		return (arenaPathIsRelative ? this->basePath : "") +
			this->options->getArenaPath() + "/GLOBAL.BSA";
	}();

	DebugAssert(File::exists(globalBsaPath),
		"\"" + this->options->getArenaPath() + "\" not a valid ARENA path.");

	// Initialize virtual file system using the Arena path in the options file.
	VFS::Manager::get().initialize(std::string(
		(arenaPathIsRelative ? this->basePath : "") + this->options->getArenaPath()));

	// Initialize the OpenAL Soft audio manager.
	this->audioManager.init(*this->options.get());

	// Initialize the SDL renderer and window with the given settings.
	this->renderer = std::unique_ptr<Renderer>(new Renderer(
		this->options->getScreenWidth(), this->options->getScreenHeight(),
		this->options->isFullscreen(), this->options->getLetterboxAspect()));

	// Initialize the texture manager with the SDL window's pixel format.
	this->textureManager = std::unique_ptr<TextureManager>(new TextureManager(
		*this->renderer.get()));

	// Initialize the font manager. Fonts (i.e., FONT_A.DAT) are loaded on demand.
	this->fontManager = std::unique_ptr<FontManager>(new FontManager());

	// Load various plain text assets.
	this->textAssets = std::unique_ptr<TextAssets>(new TextAssets());

	// Load city data file.
	this->cityDataFile = std::unique_ptr<CityDataFile>(new CityDataFile("CITYDATA.00"));

	// Set window icon (treat black as transparent for 24-bit PPMs).
	int iconWidth, iconHeight;
	std::unique_ptr<uint32_t[]> iconPixels = PPMFile::read(
		this->basePath + "data/icon.ppm", iconWidth, iconHeight);
	Surface icon(Surface::createSurfaceWithFormatFrom(iconPixels.get(),
		iconWidth, iconHeight, Renderer::DEFAULT_BPP,
		iconWidth * sizeof(*iconPixels.get()), Renderer::DEFAULT_PIXELFORMAT));
	SDL_SetColorKey(icon.get(), SDL_TRUE, SDL_MapRGBA(icon.get()->format, 0, 0, 0, 255));
	this->renderer->setWindowIcon(icon.get());

	// Initialize panel and music to default.
	this->panel = Panel::defaultPanel(this);
	this->setMusic(MusicName::PercIntro);

	// Use a texture as the cursor instead.
	SDL_ShowCursor(SDL_FALSE);

	// Leave some members null for now. The game data is initialized when the player
	// enters the game world, and the "next panel" is a temporary used by the game
	// to avoid corruption between panel events which change the panel.
	this->gameData = nullptr;
	this->nextPanel = nullptr;
	this->nextSubPanel = nullptr;

	// This keeps the programmer from deleting a sub-panel the same frame it's in use.
	// The pop is delayed until the beginning of the next frame.
	this->requestedSubPanelPop = false;
}

Game::~Game()
{

}

AudioManager &Game::getAudioManager()
{
	return this->audioManager;
}

const InputManager &Game::getInputManager() const
{
	return this->inputManager;
}

FontManager &Game::getFontManager() const
{
	return *this->fontManager.get();
}

bool Game::gameDataIsActive() const
{
	return this->gameData.get() != nullptr;
}

GameData &Game::getGameData() const
{
	// The caller should not request the game data when there is no active session.
	assert(this->gameDataIsActive());

	return *this->gameData.get();
}

Options &Game::getOptions() const
{
	return *this->options.get();
}

Renderer &Game::getRenderer() const
{
	return *this->renderer.get();
}

TextureManager &Game::getTextureManager() const
{
	return *this->textureManager.get();
}

TextAssets &Game::getTextAssets() const
{
	return *this->textAssets.get();
}

CityDataFile &Game::getCityDataFile() const
{
	return *this->cityDataFile.get();
}

const FPSCounter &Game::getFPSCounter() const
{
	return this->fpsCounter;
}

void Game::setPanel(std::unique_ptr<Panel> nextPanel)
{
	this->nextPanel = std::move(nextPanel);
}

void Game::pushSubPanel(std::unique_ptr<Panel> nextSubPanel)
{
	this->nextSubPanel = std::move(nextSubPanel);
}

void Game::popSubPanel()
{
	// The active sub-panel must not pop more than one sub-panel, because it may
	// have unintended side effects for other panels below it.
	DebugAssert(!this->requestedSubPanelPop, "Already scheduled to pop this sub-panel.");

	// If there are no sub-panels, then there is only the main panel, and panels
	// should never have any sub-panels to pop.
	DebugAssert(this->subPanels.size() > 0, "No sub-panels to pop.");

	this->requestedSubPanelPop = true;
}

void Game::setMusic(MusicName name)
{
	const std::string &filename = MusicFile::fromName(name);
	this->audioManager.playMusic(filename);
}

void Game::setGameData(std::unique_ptr<GameData> gameData)
{
	this->gameData = std::move(gameData);
}

void Game::resizeWindow(int width, int height)
{
	// Resize the window, and the 3D renderer if initialized.
	auto &options = this->getOptions();
	const bool fullGameWindow = options.getPlayerInterface() == PlayerInterface::Modern;
	this->renderer->resize(width, height, options.getResolutionScale(), fullGameWindow);
}

void Game::handlePanelChanges()
{
	// If a sub-panel pop was requested, then pop the top of the sub-panel stack.
	if (this->requestedSubPanelPop)
	{
		this->subPanels.pop_back();
		this->requestedSubPanelPop = false;
	}

	// If a new sub-panel was requested, then add it to the stack.
	if (this->nextSubPanel.get() != nullptr)
	{
		this->subPanels.push_back(std::move(this->nextSubPanel));
	}

	// If a new panel was requested, switch to it. If it will be the active panel
	// (i.e., there are no sub-panels), then subsequent events will be sent to it.
	if (this->nextPanel.get() != nullptr)
	{
		this->panel = std::move(this->nextPanel);
	}
}

void Game::handleEvents(bool &running)
{
	// Handle events for the current game state.
	SDL_Event e;
	while (SDL_PollEvent(&e) != 0)
	{
		// Application events and window resizes are handled here.
		bool applicationExit = this->inputManager.applicationExit(e);
		bool resized = this->inputManager.windowResized(e);
		bool takeScreenshot = this->inputManager.keyPressed(e, SDLK_PRINTSCREEN);

		if (applicationExit)
		{
			running = false;
		}

		if (resized)
		{
			int width = e.window.data1;
			int height = e.window.data2;
			this->resizeWindow(width, height);

			// Call each panel's resize method. The panels should not be listening for
			// resize events themselves because it's more of an "application event" than
			// a panel event.
			this->panel->resize(width, height);

			for (auto &subPanel : this->subPanels)
			{
				subPanel->resize(width, height);
			}
		}

		if (takeScreenshot)
		{
			// Save a screenshot to the local folder.
			auto &renderer = this->getRenderer();
			Surface screenshot(renderer.getScreenshot());
			SDL_SaveBMP(screenshot.get(), "out.bmp");
		}

		// Panel-specific events are handled by the active panel or sub-panel. If any
		// sub-panels exist, choose the top one. Otherwise, choose the main panel.
		if (this->subPanels.size() > 0)
		{
			this->subPanels.back()->handleEvent(e);
		}
		else
		{
			this->panel->handleEvent(e);
		}

		// See if the event requested any changes in active panels.
		this->handlePanelChanges();
	}
}

void Game::tick(double dt)
{
	// If any sub-panels are active, tick the top one by delta time. Otherwise,
	// tick the main panel.
	if (this->subPanels.size() > 0)
	{
		this->subPanels.back()->tick(dt);
	}
	else
	{
		this->panel->tick(dt);
	}

	// See if the panel tick requested any changes in active panels.
	this->handlePanelChanges();
}

void Game::render()
{
	// Draw the panel's main content.
	this->panel->render(*this->renderer.get());

	// Draw any sub-panels back to front.
	for (auto &subPanel : this->subPanels)
	{
		subPanel->render(*this->renderer.get());
	}

	// Get the active panel's cursor texture and alignment.
	const std::pair<SDL_Texture*, CursorAlignment> cursor = (this->subPanels.size() > 0) ?
		this->subPanels.back()->getCurrentCursor() : this->panel->getCurrentCursor();

	// Draw cursor if not null. Some panels do not define a cursor (like cinematics),
	// so their cursor is always null.
	if (cursor.first != nullptr)
	{
		// The panel should not be drawing the cursor themselves. It's done here
		// just to make sure that the cursor is drawn only once and is always drawn last.
		this->renderer->drawCursor(cursor.first, cursor.second,
			this->inputManager.getMousePosition(), this->options->getCursorScale());
	}

	this->renderer->present();
}

void Game::loop()
{
	// Longest allowed frame time in microseconds.
	const std::chrono::duration<int64_t, std::micro> maximumMS(1000000 / Options::MIN_FPS);

	auto thisTime = std::chrono::high_resolution_clock::now();

	// Primary game loop.
	bool running = true;
	while (running)
	{
		const auto lastTime = thisTime;
		thisTime = std::chrono::high_resolution_clock::now();

		// Fastest allowed frame time in microseconds.
		const std::chrono::duration<int64_t, std::micro> minimumMS(
			1000000 / this->options->getTargetFPS());

		// Delay the current frame if the previous one was too fast.
		auto frameTime = std::chrono::duration_cast<std::chrono::microseconds>(thisTime - lastTime);
		if (frameTime < minimumMS)
		{
			const auto sleepTime = minimumMS - frameTime;
			std::this_thread::sleep_for(sleepTime);
			thisTime = std::chrono::high_resolution_clock::now();
			frameTime = std::chrono::duration_cast<std::chrono::microseconds>(thisTime - lastTime);
		}

		// Clamp the delta time to at most the maximum frame time.
		const double dt = std::fmin(frameTime.count(), maximumMS.count()) / 1000000.0;

		// Update the input manager's state.
		this->inputManager.update();

		// Update the audio manager, checking for finished sounds.
		this->audioManager.update();

		// Update FPS counter.
		this->fpsCounter.updateFrameTime(dt);

		// Listen for input events.
		this->handleEvents(running);

		// Animate the current game state by delta time.
		this->tick(dt);

		// Draw to the screen.
		this->render();
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/image/image.h"

#include <algorithm>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/size.h"

#if defined(TOOLKIT_GTK)
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdk.h>
#include <glib-object.h>
#include "ui/gfx/canvas.h"
#include "ui/gfx/gtk_util.h"
#include "ui/gfx/image/cairo_cached_surface.h"
#elif defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#include "skia/ext/skia_utils_mac.h"
#endif

namespace gfx {

namespace internal {

#if defined(OS_MACOSX)
// This is a wrapper around gfx::NSImageToSkBitmap() because this cross-platform
// file cannot include the [square brackets] of ObjC.
ImageSkia NSImageToImageSkia(NSImage* image);
NSImage* ImageSkiaToNSImage(const ImageSkia* image);
#endif

#if defined(TOOLKIT_GTK)
const SkBitmap* GdkPixbufToSkBitmap(GdkPixbuf* pixbuf) {
  CHECK(pixbuf);
  gfx::Canvas canvas(gfx::Size(gdk_pixbuf_get_width(pixbuf),
                               gdk_pixbuf_get_height(pixbuf)), false);
  skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas());
  cairo_t* cr = scoped_platform_paint.GetPlatformSurface();
  gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
  cairo_paint(cr);
  return new SkBitmap(canvas.ExtractBitmap());
}
#endif

class ImageRepSkia;
class ImageRepGdk;
class ImageRepCairoCached;
class ImageRepCocoa;

// An ImageRep is the object that holds the backing memory for an Image. Each
// RepresentationType has an ImageRep subclass that is responsible for freeing
// the memory that the ImageRep holds. When an ImageRep is created, it expects
// to take ownership of the image, without having to retain it or increase its
// reference count.
class ImageRep {
 public:
  explicit ImageRep(Image::RepresentationType rep) : type_(rep) {}

  // Deletes the associated pixels of an ImageRep.
  virtual ~ImageRep() {}

  // Cast helpers ("fake RTTI").
  ImageRepSkia* AsImageRepSkia() {
    CHECK_EQ(type_, Image::kImageRepSkia);
    return reinterpret_cast<ImageRepSkia*>(this);
  }

#if defined(TOOLKIT_GTK)
  ImageRepGdk* AsImageRepGdk() {
    CHECK_EQ(type_, Image::kImageRepGdk);
    return reinterpret_cast<ImageRepGdk*>(this);
  }

  ImageRepCairoCached* AsImageRepCairo() {
    CHECK_EQ(type_, Image::kImageRepCairoCache);
    return reinterpret_cast<ImageRepCairoCached*>(this);
  }
#endif

#if defined(OS_MACOSX)
  ImageRepCocoa* AsImageRepCocoa() {
    CHECK_EQ(type_, Image::kImageRepCocoa);
    return reinterpret_cast<ImageRepCocoa*>(this);
  }
#endif

  Image::RepresentationType type() const { return type_; }

 private:
  Image::RepresentationType type_;
};

class ImageRepSkia : public ImageRep {
 public:
  // Takes ownership of |image|.
  explicit ImageRepSkia(ImageSkia* image)
      : ImageRep(Image::kImageRepSkia),
        image_(image) {
  }

  virtual ~ImageRepSkia() {
  }

  ImageSkia* image() { return image_.get(); }

 private:
  scoped_ptr<ImageSkia> image_;

  DISALLOW_COPY_AND_ASSIGN(ImageRepSkia);
};

#if defined(TOOLKIT_GTK)
class ImageRepGdk : public ImageRep {
 public:
  explicit ImageRepGdk(GdkPixbuf* pixbuf)
      : ImageRep(Image::kImageRepGdk),
        pixbuf_(pixbuf) {
    CHECK(pixbuf);
  }

  virtual ~ImageRepGdk() {
    if (pixbuf_) {
      g_object_unref(pixbuf_);
      pixbuf_ = NULL;
    }
  }

  GdkPixbuf* pixbuf() const { return pixbuf_; }

 private:
  GdkPixbuf* pixbuf_;

  DISALLOW_COPY_AND_ASSIGN(ImageRepGdk);
};

// Represents data that lives on the display server instead of in the client.
class ImageRepCairoCached : public ImageRep {
 public:
  explicit ImageRepCairoCached(GdkPixbuf* pixbuf)
      : ImageRep(Image::kImageRepCairoCache),
        cairo_cache_(new CairoCachedSurface) {
    CHECK(pixbuf);
    cairo_cache_->UsePixbuf(pixbuf);
  }

  virtual ~ImageRepCairoCached() {
    delete cairo_cache_;
  }

  CairoCachedSurface* surface() const { return cairo_cache_; }

 private:
  CairoCachedSurface* cairo_cache_;

  DISALLOW_COPY_AND_ASSIGN(ImageRepCairoCached);
};
#endif  // defined(TOOLKIT_GTK)

#if defined(OS_MACOSX)
class ImageRepCocoa : public ImageRep {
 public:
  explicit ImageRepCocoa(NSImage* image)
      : ImageRep(Image::kImageRepCocoa),
        image_(image) {
    CHECK(image);
  }

  virtual ~ImageRepCocoa() {
    base::mac::NSObjectRelease(image_);
    image_ = nil;
  }

  NSImage* image() const { return image_; }

 private:
  NSImage* image_;

  DISALLOW_COPY_AND_ASSIGN(ImageRepCocoa);
};
#endif  // defined(OS_MACOSX)

// The Storage class acts similarly to the pixels in a SkBitmap: the Image
// class holds a refptr instance of Storage, which in turn holds all the
// ImageReps. This way, the Image can be cheaply copied.
class ImageStorage : public base::RefCounted<ImageStorage> {
 public:
  ImageStorage(gfx::Image::RepresentationType default_type)
      : default_representation_type_(default_type) {
  }

  gfx::Image::RepresentationType default_representation_type() {
    return default_representation_type_;
  }
  gfx::Image::RepresentationMap& representations() { return representations_; }

 private:
  ~ImageStorage() {
    for (gfx::Image::RepresentationMap::iterator it = representations_.begin();
         it != representations_.end();
         ++it) {
      delete it->second;
    }
    representations_.clear();
  }

  // The type of image that was passed to the constructor. This key will always
  // exist in the |representations_| map.
  gfx::Image::RepresentationType default_representation_type_;

  // All the representations of an Image. Size will always be at least one, with
  // more for any converted representations.
  gfx::Image::RepresentationMap representations_;

  friend class base::RefCounted<ImageStorage>;
};

}  // namespace internal

Image::Image() {
  // |storage_| is NULL for empty Images.
}

Image::Image(const ImageSkia& image)
    : storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
  internal::ImageRepSkia* rep = new internal::ImageRepSkia(
      new ImageSkia(image));
  AddRepresentation(rep);
}

Image::Image(const SkBitmap* bitmap)
    : storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
  internal::ImageRepSkia* rep = new internal::ImageRepSkia(
      new ImageSkia(bitmap));
  AddRepresentation(rep);
}

Image::Image(const SkBitmap& bitmap)
    : storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
  internal::ImageRepSkia* rep =
      new internal::ImageRepSkia(new ImageSkia(new SkBitmap(bitmap)));
  AddRepresentation(rep);
}

#if defined(TOOLKIT_GTK)
Image::Image(GdkPixbuf* pixbuf)
    : storage_(new internal::ImageStorage(Image::kImageRepGdk)) {
  internal::ImageRepGdk* rep = new internal::ImageRepGdk(pixbuf);
  AddRepresentation(rep);
}
#endif

#if defined(OS_MACOSX)
Image::Image(NSImage* image)
    : storage_(new internal::ImageStorage(Image::kImageRepCocoa)) {
  internal::ImageRepCocoa* rep = new internal::ImageRepCocoa(image);
  AddRepresentation(rep);
}
#endif

Image::Image(const Image& other) : storage_(other.storage_) {
}

Image& Image::operator=(const Image& other) {
  storage_ = other.storage_;
  return *this;
}

Image::~Image() {
}

const SkBitmap* Image::ToSkBitmap() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepSkia);
  return rep->AsImageRepSkia()->image()->bitmap();
}

const ImageSkia* Image::ToImageSkia() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepSkia);
  return rep->AsImageRepSkia()->image();
}

#if defined(TOOLKIT_GTK)
GdkPixbuf* Image::ToGdkPixbuf() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk);
  return rep->AsImageRepGdk()->pixbuf();
}

CairoCachedSurface* const Image::ToCairo() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepCairoCache);
  return rep->AsImageRepCairo()->surface();
}
#endif

#if defined(OS_MACOSX)
NSImage* Image::ToNSImage() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepCocoa);
  return rep->AsImageRepCocoa()->image();
}
#endif

ImageSkia* Image::CopyImageSkia() const {
  return new ImageSkia(*ToImageSkia());
}

SkBitmap* Image::CopySkBitmap() const {
  return new SkBitmap(*ToSkBitmap());
}

#if defined(TOOLKIT_GTK)
GdkPixbuf* Image::CopyGdkPixbuf() const {
  GdkPixbuf* pixbuf = ToGdkPixbuf();
  g_object_ref(pixbuf);
  return pixbuf;
}
#endif

#if defined(OS_MACOSX)
NSImage* Image::CopyNSImage() const {
  NSImage* image = ToNSImage();
  base::mac::NSObjectRetain(image);
  return image;
}
#endif

#if defined(OS_MACOSX)
Image::operator NSImage*() const {
  return ToNSImage();
}
#endif

bool Image::HasRepresentation(RepresentationType type) const {
  return storage_.get() && storage_->representations().count(type) != 0;
}

size_t Image::RepresentationCount() const {
  if (!storage_.get())
    return 0;

  return storage_->representations().size();
}

bool Image::IsEmpty() const {
  return RepresentationCount() == 0;
}

void Image::SwapRepresentations(gfx::Image* other) {
  storage_.swap(other->storage_);
}

internal::ImageRep* Image::DefaultRepresentation() const {
  CHECK(storage_.get());
  RepresentationMap& representations = storage_->representations();
  RepresentationMap::iterator it =
      representations.find(storage_->default_representation_type());
  DCHECK(it != representations.end());
  return it->second;
}

internal::ImageRep* Image::GetRepresentation(
    RepresentationType rep_type) const {
  CHECK(storage_.get());
  // If the requested rep is the default, return it.
  internal::ImageRep* default_rep = DefaultRepresentation();
  if (rep_type == storage_->default_representation_type())
    return default_rep;

  // Check to see if the representation already exists.
  RepresentationMap::iterator it = storage_->representations().find(rep_type);
  if (it != storage_->representations().end())
    return it->second;

  // At this point, the requested rep does not exist, so it must be converted
  // from the default rep.

  // Handle native-to-Skia conversion.
  if (rep_type == Image::kImageRepSkia) {
    internal::ImageRepSkia* rep = NULL;
#if defined(TOOLKIT_GTK)
    if (storage_->default_representation_type() == Image::kImageRepGdk) {
      internal::ImageRepGdk* pixbuf_rep = default_rep->AsImageRepGdk();
      rep = new internal::ImageRepSkia(new ImageSkia(
          internal::GdkPixbufToSkBitmap(pixbuf_rep->pixbuf())));
    }
    // We don't do conversions from CairoCachedSurfaces to Skia because the
    // data lives on the display server and we'll always have a GdkPixbuf if we
    // have a CairoCachedSurface.
#elif defined(OS_MACOSX)
    if (storage_->default_representation_type() == Image::kImageRepCocoa) {
      internal::ImageRepCocoa* nsimage_rep = default_rep->AsImageRepCocoa();
      ImageSkia image_skia = internal::NSImageToImageSkia(nsimage_rep->image());
      rep = new internal::ImageRepSkia(new ImageSkia(image_skia));
    }
#endif
    CHECK(rep);
    AddRepresentation(rep);
    return rep;
  }
#if defined(TOOLKIT_GTK)
  else if (rep_type == Image::kImageRepCairoCache) {
    // Handle any-to-Cairo conversion. This may recursively create an
    // intermediate pixbuf before we send the data to the display server.
    internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk);
    internal::ImageRepCairoCached* native_rep =
        new internal::ImageRepCairoCached(rep->AsImageRepGdk()->pixbuf());

    CHECK(native_rep);
    AddRepresentation(native_rep);
    return native_rep;
  }
#endif

  // Handle Skia-to-native conversions.
  if (default_rep->type() == Image::kImageRepSkia) {
    internal::ImageRep* native_rep = NULL;
#if defined(USE_AURA)
    NOTIMPLEMENTED();
#elif defined(TOOLKIT_GTK)
    if (rep_type == Image::kImageRepGdk) {
      GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(
          default_rep->AsImageRepSkia()->image()->bitmap());
      native_rep = new internal::ImageRepGdk(pixbuf);
    }
#elif defined(OS_MACOSX)
    if (rep_type == Image::kImageRepCocoa) {
      NSImage* image = internal::ImageSkiaToNSImage(
          default_rep->AsImageRepSkia()->image());
      base::mac::NSObjectRetain(image);
      native_rep = new internal::ImageRepCocoa(image);
    }
#endif
    CHECK(native_rep);
    AddRepresentation(native_rep);
    return native_rep;
  }

  // Something went seriously wrong...
  return NULL;
}

void Image::AddRepresentation(internal::ImageRep* rep) const {
  CHECK(storage_.get());
  storage_->representations().insert(std::make_pair(rep->type(), rep));
}

}  // namespace gfx
<commit_msg>Image(SkBitmap) was calling DeleteSoon. Changed code path slightly such that this is avoided.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/image/image.h"

#include <algorithm>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/size.h"

#if defined(TOOLKIT_GTK)
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdk.h>
#include <glib-object.h>
#include "ui/gfx/canvas.h"
#include "ui/gfx/gtk_util.h"
#include "ui/gfx/image/cairo_cached_surface.h"
#elif defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#include "skia/ext/skia_utils_mac.h"
#endif

namespace gfx {

namespace internal {

#if defined(OS_MACOSX)
// This is a wrapper around gfx::NSImageToSkBitmap() because this cross-platform
// file cannot include the [square brackets] of ObjC.
ImageSkia NSImageToImageSkia(NSImage* image);
NSImage* ImageSkiaToNSImage(const ImageSkia* image);
#endif

#if defined(TOOLKIT_GTK)
const SkBitmap* GdkPixbufToSkBitmap(GdkPixbuf* pixbuf) {
  CHECK(pixbuf);
  gfx::Canvas canvas(gfx::Size(gdk_pixbuf_get_width(pixbuf),
                               gdk_pixbuf_get_height(pixbuf)), false);
  skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas());
  cairo_t* cr = scoped_platform_paint.GetPlatformSurface();
  gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
  cairo_paint(cr);
  return new SkBitmap(canvas.ExtractBitmap());
}
#endif

class ImageRepSkia;
class ImageRepGdk;
class ImageRepCairoCached;
class ImageRepCocoa;

// An ImageRep is the object that holds the backing memory for an Image. Each
// RepresentationType has an ImageRep subclass that is responsible for freeing
// the memory that the ImageRep holds. When an ImageRep is created, it expects
// to take ownership of the image, without having to retain it or increase its
// reference count.
class ImageRep {
 public:
  explicit ImageRep(Image::RepresentationType rep) : type_(rep) {}

  // Deletes the associated pixels of an ImageRep.
  virtual ~ImageRep() {}

  // Cast helpers ("fake RTTI").
  ImageRepSkia* AsImageRepSkia() {
    CHECK_EQ(type_, Image::kImageRepSkia);
    return reinterpret_cast<ImageRepSkia*>(this);
  }

#if defined(TOOLKIT_GTK)
  ImageRepGdk* AsImageRepGdk() {
    CHECK_EQ(type_, Image::kImageRepGdk);
    return reinterpret_cast<ImageRepGdk*>(this);
  }

  ImageRepCairoCached* AsImageRepCairo() {
    CHECK_EQ(type_, Image::kImageRepCairoCache);
    return reinterpret_cast<ImageRepCairoCached*>(this);
  }
#endif

#if defined(OS_MACOSX)
  ImageRepCocoa* AsImageRepCocoa() {
    CHECK_EQ(type_, Image::kImageRepCocoa);
    return reinterpret_cast<ImageRepCocoa*>(this);
  }
#endif

  Image::RepresentationType type() const { return type_; }

 private:
  Image::RepresentationType type_;
};

class ImageRepSkia : public ImageRep {
 public:
  // Takes ownership of |image|.
  explicit ImageRepSkia(ImageSkia* image)
      : ImageRep(Image::kImageRepSkia),
        image_(image) {
  }

  virtual ~ImageRepSkia() {
  }

  ImageSkia* image() { return image_.get(); }

 private:
  scoped_ptr<ImageSkia> image_;

  DISALLOW_COPY_AND_ASSIGN(ImageRepSkia);
};

#if defined(TOOLKIT_GTK)
class ImageRepGdk : public ImageRep {
 public:
  explicit ImageRepGdk(GdkPixbuf* pixbuf)
      : ImageRep(Image::kImageRepGdk),
        pixbuf_(pixbuf) {
    CHECK(pixbuf);
  }

  virtual ~ImageRepGdk() {
    if (pixbuf_) {
      g_object_unref(pixbuf_);
      pixbuf_ = NULL;
    }
  }

  GdkPixbuf* pixbuf() const { return pixbuf_; }

 private:
  GdkPixbuf* pixbuf_;

  DISALLOW_COPY_AND_ASSIGN(ImageRepGdk);
};

// Represents data that lives on the display server instead of in the client.
class ImageRepCairoCached : public ImageRep {
 public:
  explicit ImageRepCairoCached(GdkPixbuf* pixbuf)
      : ImageRep(Image::kImageRepCairoCache),
        cairo_cache_(new CairoCachedSurface) {
    CHECK(pixbuf);
    cairo_cache_->UsePixbuf(pixbuf);
  }

  virtual ~ImageRepCairoCached() {
    delete cairo_cache_;
  }

  CairoCachedSurface* surface() const { return cairo_cache_; }

 private:
  CairoCachedSurface* cairo_cache_;

  DISALLOW_COPY_AND_ASSIGN(ImageRepCairoCached);
};
#endif  // defined(TOOLKIT_GTK)

#if defined(OS_MACOSX)
class ImageRepCocoa : public ImageRep {
 public:
  explicit ImageRepCocoa(NSImage* image)
      : ImageRep(Image::kImageRepCocoa),
        image_(image) {
    CHECK(image);
  }

  virtual ~ImageRepCocoa() {
    base::mac::NSObjectRelease(image_);
    image_ = nil;
  }

  NSImage* image() const { return image_; }

 private:
  NSImage* image_;

  DISALLOW_COPY_AND_ASSIGN(ImageRepCocoa);
};
#endif  // defined(OS_MACOSX)

// The Storage class acts similarly to the pixels in a SkBitmap: the Image
// class holds a refptr instance of Storage, which in turn holds all the
// ImageReps. This way, the Image can be cheaply copied.
class ImageStorage : public base::RefCounted<ImageStorage> {
 public:
  ImageStorage(gfx::Image::RepresentationType default_type)
      : default_representation_type_(default_type) {
  }

  gfx::Image::RepresentationType default_representation_type() {
    return default_representation_type_;
  }
  gfx::Image::RepresentationMap& representations() { return representations_; }

 private:
  ~ImageStorage() {
    for (gfx::Image::RepresentationMap::iterator it = representations_.begin();
         it != representations_.end();
         ++it) {
      delete it->second;
    }
    representations_.clear();
  }

  // The type of image that was passed to the constructor. This key will always
  // exist in the |representations_| map.
  gfx::Image::RepresentationType default_representation_type_;

  // All the representations of an Image. Size will always be at least one, with
  // more for any converted representations.
  gfx::Image::RepresentationMap representations_;

  friend class base::RefCounted<ImageStorage>;
};

}  // namespace internal

Image::Image() {
  // |storage_| is NULL for empty Images.
}

Image::Image(const ImageSkia& image)
    : storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
  internal::ImageRepSkia* rep = new internal::ImageRepSkia(
      new ImageSkia(image));
  AddRepresentation(rep);
}

Image::Image(const SkBitmap* bitmap)
    : storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
  internal::ImageRepSkia* rep = new internal::ImageRepSkia(
      new ImageSkia(bitmap));
  AddRepresentation(rep);
}

Image::Image(const SkBitmap& bitmap)
    : storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
  internal::ImageRepSkia* rep =
      new internal::ImageRepSkia(new ImageSkia(bitmap));
  AddRepresentation(rep);
}

#if defined(TOOLKIT_GTK)
Image::Image(GdkPixbuf* pixbuf)
    : storage_(new internal::ImageStorage(Image::kImageRepGdk)) {
  internal::ImageRepGdk* rep = new internal::ImageRepGdk(pixbuf);
  AddRepresentation(rep);
}
#endif

#if defined(OS_MACOSX)
Image::Image(NSImage* image)
    : storage_(new internal::ImageStorage(Image::kImageRepCocoa)) {
  internal::ImageRepCocoa* rep = new internal::ImageRepCocoa(image);
  AddRepresentation(rep);
}
#endif

Image::Image(const Image& other) : storage_(other.storage_) {
}

Image& Image::operator=(const Image& other) {
  storage_ = other.storage_;
  return *this;
}

Image::~Image() {
}

const SkBitmap* Image::ToSkBitmap() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepSkia);
  return rep->AsImageRepSkia()->image()->bitmap();
}

const ImageSkia* Image::ToImageSkia() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepSkia);
  return rep->AsImageRepSkia()->image();
}

#if defined(TOOLKIT_GTK)
GdkPixbuf* Image::ToGdkPixbuf() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk);
  return rep->AsImageRepGdk()->pixbuf();
}

CairoCachedSurface* const Image::ToCairo() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepCairoCache);
  return rep->AsImageRepCairo()->surface();
}
#endif

#if defined(OS_MACOSX)
NSImage* Image::ToNSImage() const {
  internal::ImageRep* rep = GetRepresentation(Image::kImageRepCocoa);
  return rep->AsImageRepCocoa()->image();
}
#endif

ImageSkia* Image::CopyImageSkia() const {
  return new ImageSkia(*ToImageSkia());
}

SkBitmap* Image::CopySkBitmap() const {
  return new SkBitmap(*ToSkBitmap());
}

#if defined(TOOLKIT_GTK)
GdkPixbuf* Image::CopyGdkPixbuf() const {
  GdkPixbuf* pixbuf = ToGdkPixbuf();
  g_object_ref(pixbuf);
  return pixbuf;
}
#endif

#if defined(OS_MACOSX)
NSImage* Image::CopyNSImage() const {
  NSImage* image = ToNSImage();
  base::mac::NSObjectRetain(image);
  return image;
}
#endif

#if defined(OS_MACOSX)
Image::operator NSImage*() const {
  return ToNSImage();
}
#endif

bool Image::HasRepresentation(RepresentationType type) const {
  return storage_.get() && storage_->representations().count(type) != 0;
}

size_t Image::RepresentationCount() const {
  if (!storage_.get())
    return 0;

  return storage_->representations().size();
}

bool Image::IsEmpty() const {
  return RepresentationCount() == 0;
}

void Image::SwapRepresentations(gfx::Image* other) {
  storage_.swap(other->storage_);
}

internal::ImageRep* Image::DefaultRepresentation() const {
  CHECK(storage_.get());
  RepresentationMap& representations = storage_->representations();
  RepresentationMap::iterator it =
      representations.find(storage_->default_representation_type());
  DCHECK(it != representations.end());
  return it->second;
}

internal::ImageRep* Image::GetRepresentation(
    RepresentationType rep_type) const {
  CHECK(storage_.get());
  // If the requested rep is the default, return it.
  internal::ImageRep* default_rep = DefaultRepresentation();
  if (rep_type == storage_->default_representation_type())
    return default_rep;

  // Check to see if the representation already exists.
  RepresentationMap::iterator it = storage_->representations().find(rep_type);
  if (it != storage_->representations().end())
    return it->second;

  // At this point, the requested rep does not exist, so it must be converted
  // from the default rep.

  // Handle native-to-Skia conversion.
  if (rep_type == Image::kImageRepSkia) {
    internal::ImageRepSkia* rep = NULL;
#if defined(TOOLKIT_GTK)
    if (storage_->default_representation_type() == Image::kImageRepGdk) {
      internal::ImageRepGdk* pixbuf_rep = default_rep->AsImageRepGdk();
      rep = new internal::ImageRepSkia(new ImageSkia(
          internal::GdkPixbufToSkBitmap(pixbuf_rep->pixbuf())));
    }
    // We don't do conversions from CairoCachedSurfaces to Skia because the
    // data lives on the display server and we'll always have a GdkPixbuf if we
    // have a CairoCachedSurface.
#elif defined(OS_MACOSX)
    if (storage_->default_representation_type() == Image::kImageRepCocoa) {
      internal::ImageRepCocoa* nsimage_rep = default_rep->AsImageRepCocoa();
      ImageSkia image_skia = internal::NSImageToImageSkia(nsimage_rep->image());
      rep = new internal::ImageRepSkia(new ImageSkia(image_skia));
    }
#endif
    CHECK(rep);
    AddRepresentation(rep);
    return rep;
  }
#if defined(TOOLKIT_GTK)
  else if (rep_type == Image::kImageRepCairoCache) {
    // Handle any-to-Cairo conversion. This may recursively create an
    // intermediate pixbuf before we send the data to the display server.
    internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk);
    internal::ImageRepCairoCached* native_rep =
        new internal::ImageRepCairoCached(rep->AsImageRepGdk()->pixbuf());

    CHECK(native_rep);
    AddRepresentation(native_rep);
    return native_rep;
  }
#endif

  // Handle Skia-to-native conversions.
  if (default_rep->type() == Image::kImageRepSkia) {
    internal::ImageRep* native_rep = NULL;
#if defined(USE_AURA)
    NOTIMPLEMENTED();
#elif defined(TOOLKIT_GTK)
    if (rep_type == Image::kImageRepGdk) {
      GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(
          default_rep->AsImageRepSkia()->image()->bitmap());
      native_rep = new internal::ImageRepGdk(pixbuf);
    }
#elif defined(OS_MACOSX)
    if (rep_type == Image::kImageRepCocoa) {
      NSImage* image = internal::ImageSkiaToNSImage(
          default_rep->AsImageRepSkia()->image());
      base::mac::NSObjectRetain(image);
      native_rep = new internal::ImageRepCocoa(image);
    }
#endif
    CHECK(native_rep);
    AddRepresentation(native_rep);
    return native_rep;
  }

  // Something went seriously wrong...
  return NULL;
}

void Image::AddRepresentation(internal::ImageRep* rep) const {
  CHECK(storage_.get());
  storage_->representations().insert(std::make_pair(rep->type(), rep));
}

}  // namespace gfx
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;

void ChangePointer(int *);
void ChangeReference(int &);
void ChangeTwoPointers(int *, int *);

int main(int argc, char* argv[]) {
   // basics of pointers in C++
   int x = 5, y = 100; // normal int variables

   // a pointer is a special variable that "points" to another variable.
   // pointers are initialized by assigning the *address* of another variable

   // When DECLARING a variable, & is for reference; * is for pointer
   int *p;
   // do not need to initialize a pointer, unlike a reference.

   // to make a pointer "point" to a variable, set it equal to the address of
   // the variable.

   p = &x; // & means "address of"; &x means "address of x". assigning &x to p
           // makes p point to x.

   // WHAT DOES THIS LOOK LIKE ON THE STACK?
   // remember, a pointer's value in memory is always an address

   /*
   To change the VALUE of the thing p points to, we use the * operator on p to
   "de-reference" the pointer. This gives us access to the actual memory that
   it points to. We can then read or write to that memory as usual.
   */
   *p = 10; // this changes the value of the thing that p points to (which is x)

   // Pointers are type-safe, somewhat: can't assign int* to double*
   // double *cant = &x; // error: cannot convert from 'int *' to 'double *'

   // But you can assign one pointer to another
   int *otherPointer = p;
   // This line DECLARES a pointer and INITIALIZES IT to point to the thing
   // p points to.
   *otherPointer = 100; // what does this change?

   /*
   MINI QUIZ:
   Which of these statements will not compile?

   int *a = &x;
   int *b = &a;
   int *c = 10;
   short *d = &x;
   int *e = *a;
   */

   /*
   So a pointer is kind of like a reference variable... in both cases, a change
   to one variable actually changes another... but with different syntax.
   */
   int &refToX = x;
   int *ptrToX = &x;

   // these two lines do the same exact thing: change the memory for x
   refToX = 20;
   *ptrToX = 20;

   // Pointers, unlike references, can have their "target" changed.
   refToX = y; // LOGIC ERROR: this assigns a copy of y's value to x's value

   ptrToX = &y; // this does not change x's value; it makes ptrToX "point to" y
   *ptrToX = 40;

   // What does this output now?
   cout << "X is: " << refToX << endl;
   cout << "*ptrToX is: " << *ptrToX << " -- y is: " << y << endl;

   /*
   Pointers can be passed to functions. Like references, this allows the
   function to change a parameter so that the caller sees the change.
   */
   ChangePointer(ptrToX);
   // The address ptrToX points to is copied to the function's parameter...
   // then what?
   cout << "After function, *ptrToX == " << *ptrToX << endl;

   // It is more common to pass &y directly to the function.
   ChangePointer(&y);
   cout << "After function, y and *ptrToX == " << *ptrToX << " (" << y << ")"
      << endl;

   return 0;
}

void ChangePointer(int *p) {
   *p = 1000;
}

void ChangeReference(int &r) {
   r = 2000;
}

void ChangeTwoPointers(int *p1, int *p2) {
   *p1 = -1;
   *p2 = -2;
}<commit_msg>Rework to remove "references" notes.<commit_after>#include <iostream>
using namespace std;

// Basics of pointers in C++

void ChangeValue(int);
void ChangePointer(int *);
void ChangeTwoPointers(int *, int *);

int main(int argc, char* argv[]) {
   int x = 5, y = 100; // normal int variables

   // A "pointer" is a special variable that "points" to another variable.
   // Pointers are initialized by assigning the *address* of another variable of
   // the same type.

   int *p;
   // p is a variable of type "pointer to int."
   // The * indicates a pointer variable. Whitespace doesn't matter.
   // int * p, int* p, int *p -- all the same.
   // Like all variables, p has a garbage value until it is assigned something.

   // We assign the addresses of variables to pointers.
   p = &x; // & means "address of"; &x means "address of x". assigning &x to p
           // makes p point to x.

   /*
   To change the VALUE of the thing p points to, we use the * operator on p to
   "de-reference" the pointer. This gives us access to the actual memory that
   it points to. We can then read or write to that memory as usual.
   */

   cout << *p << endl; // Read the value of the thing that p points to.
   *p = 10; // Assign a value to the thing that p points to.

   // We can declare and initialize a pointer in one line:
   int *p2 = &x;

   // Pointers are type-safe, somewhat: can't assign int* to double*
   // double *cant = &x; // error: cannot convert from 'int *' to 'double *'

   // But you can assign one pointer to another
   int *otherPointer = p;
   // This line DECLARES a pointer and INITIALIZES IT to point to the thing
   // p points to.
   *otherPointer = 100; // what does this change?

   /*
   THIS IS IMPORTANT!
   When you copy or assign pointer A to pointer B, you are making B point to the
   same thing that A points to.
   */

   /*
   MINI QUIZ:
   Which of these statements will not compile?

   int *a = &x;
   int *b = &a;
   int *c = 10;
   short *d = &x;
   int *e = *a;
   */

   // Pointers can be made to "point" to something else by assigning them a
   // new address.
   p = &y; // this does not change x's value; it makes p "point to" y
   *p = 40;  // what actual variable changed?

   // What does this output now?
   cout << "*p is: " << *p << " -- y is: " << y << endl;

   /*
   Pointers can be passed to functions. This allows the function to change a
   parameter so that the caller sees the change.

   Before passing pointers as arguments, review passing "normal" variables.
   */
   ChangeValue(x); // x has value 100 before this call; what about after?
                   // That's because variables are passed to functions...
                   // BY ____________ (fill in the blank).

   /*
   Because the "value" of a pointer is a memory address, when a pointer is
   passed by value, the address of the thing it points to is copied to the
   parameter, creating a pointer that points to the same thing as what the
   argument points to.
   */
   ChangePointer(p);
   // The address p points to is copied to the function's parameter...
   // then what?
   cout << "After function, *p == " << *p << endl;

   // It is more common to pass &y directly to the function.
   ChangePointer(&y);
   cout << "After function, y and *p == " << *p << " (" << y << ")"
      << endl;

   return 0;
}

void ChangeValue(int v) {
   v = 500;
}

void ChangePointer(int *p) {
   *p = 1000;
}

void ChangeTwoPointers(int *p1, int *p2) {
   *p1 = -1;
   *p2 = -2;
}<|endoftext|>


<commit_before>#pragma once
#ifndef ENGINE_H
#define ENGINE_H
#include <QObject>
#include <QString>
#include <QMap>
#include <QSqlDatabase>
#include <QPrinter>
#include "translator.hpp"

namespace qtreports {

	class Engine : public QObject {

	public:
		Engine( QObject * parent = 0 );
		~Engine();

		bool	compile( const QString & path );
		bool	setParameters( const QMap< QString, QString > & map );
		bool	setConnection( const QSqlDatabase & connection );

		bool	createPDF( const QString & path );
		bool	createHTML( const QString & path );//etc.
		bool	print();

		const QString		getLastError() const;
		const QWidgetPtr	getWidget() const;
		const bool			isCompiled() const;

	private:
		QString		m_lastError, m_compiledPath;
		QWidgetPtr	m_widget;
		bool		m_isCompiled;

		void		drawPreview( QPrinter * printer );

	};

}
#endif // ENGINE_H<commit_msg>Delete engine.hpp<commit_after><|endoftext|>


<commit_before>//--------------------------------------------------------------------------------
//	File		: MLUtility.cpp
//	Description	:
//	Author		: Su, Hsin-Chnag
//
//	Copyright (c) 2014-2015. All rights reserved.
//	https://github.com/hsiaoyi/Melo
//--------------------------------------------------------------------------------
#if defined(ML_ANDROID)

#include "MLUtility.h"
#include "MLUtilityJni.h"

const std::string MLUtility::getUDIDForVendor(const std::string path, const std::string secretKey)
{
    return getUDIDForVendorJni(path, secretKey);
}

const std::string MLUtility::getPlatform()
{
    return "android";
}

const std::string MLUtility::getDevice()
{
    return getDeviceJni();
}

const std::string MLUtility::getDeviceName()
{
    return getDeviceNameJni();
}

const std::string MLUtility::getOSVersion()
{
    return getOSVersionJni();
}

const std::string MLUtility::getAppVersionName()
{
    return getAppVersionNameJni();
}

const std::string MLUtility::getAppVersionCode()
{
    return getAppVersionCodeJni();
}

const std::string MLUtility::getCountryCode()
{
    return getCountryCodeJni();
}

const std::string MLUtility::getCurrencyCode()
{
    return getCurrencyCodeJni();
}

const std::string MLUtility::getAdvertisementID()
{
    return getAdvertisementIDJni();
}

///////////////////////////////////////////////////////////////////////////////
const std::string MLUtility::getApplicationRoot()
{
    return "";
}

const std::string MLUtility::getResource()
{
    return "";
}

const std::string MLUtility::getDocuments()
{
    return "/Documents/";
}

const std::string MLUtility::getTemp()
{
    return "/Temp/";
}

///////////////////////////////////////////////////////////////////////////////
std::string MLUtility::getIdentifier(const std::string& path, const std::string& secretKey)
{
    return getIdentifierJni(path, secretKey);
}

bool MLUtility::setIdentifier(const std::string& path, const std::string& identifier, const std::string& secretKey)
{
    return setIdentifierJni(path, identifier, secretKey);
}

bool MLUtility::deleteIdentifier(const std::string& path)
{
    return deleteIdentifierJni(path);
}

bool MLUtility::hasIdentifier(const std::string& path)
{
    return hasIdentifierJni(path);
}

///////////////////////////////////////////////////////////////////////////////
const std::string MLUtility::getCertKey(const std::string &rndCode)
{
    return getCertKeyJni(rndCode);
}

const std::string MLUtility::getSha1(const std::string src, unsigned int digestLength)
{
    return getSha1Jni(srcㄝ, digestLength);
}

#endif
<commit_msg>fix android build<commit_after>//--------------------------------------------------------------------------------
//	File		: MLUtility.cpp
//	Description	:
//	Author		: Su, Hsin-Chnag
//
//	Copyright (c) 2014-2015. All rights reserved.
//	https://github.com/hsiaoyi/Melo
//--------------------------------------------------------------------------------
#include "MLUtility.h"
#include "MLUtilityJni.h"

//--------------------------------------------------------------------------------
const std::string MLUtility::getUDIDForVendor(const std::string path, const std::string secretKey)
{
    return getUDIDForVendorJni(path, secretKey);
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getPlatform()
{
    return "android";
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getDevice()
{
    return getDeviceJni();
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getDeviceName()
{
    return getDeviceNameJni();
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getOSVersion()
{
    return getOSVersionJni();
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getAppVersionName()
{
    return getAppVersionNameJni();
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getAppVersionCode()
{
    return getAppVersionCodeJni();
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getCountryCode()
{
    return getCountryCodeJni();
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getCurrencyCode()
{
    return getCurrencyCodeJni();
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getAdvertisementID()
{
    return getAdvertisementIDJni();
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getApplicationRoot()
{
    return "";
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getResource()
{
    return "";
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getDocuments()
{
    return "/Documents/";
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getTemp()
{
    return "/Temp/";
}

//--------------------------------------------------------------------------------
std::string MLUtility::getIdentifier(const std::string& path, const std::string& secretKey)
{
    return getIdentifierJni(path, secretKey);
}

//--------------------------------------------------------------------------------
bool MLUtility::setIdentifier(const std::string& path, const std::string& identifier, const std::string& secretKey)
{
    return setIdentifierJni(path, identifier, secretKey);
}

//--------------------------------------------------------------------------------
bool MLUtility::deleteIdentifier(const std::string& path)
{
    return deleteIdentifierJni(path);
}

//--------------------------------------------------------------------------------
bool MLUtility::hasIdentifier(const std::string& path)
{
    return hasIdentifierJni(path);
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getCertKey(const std::string &rndCode)
{
    return getCertKeyJni(rndCode);
}

//--------------------------------------------------------------------------------
const std::string MLUtility::getSha1(const std::string src, unsigned int digestLength)
{
    return getSha1Jni(src, digestLength);
}
<|endoftext|>


<commit_before>#if !defined(__CINT__) || defined(__MAKECINT__)

#include <Riostream.h>
#include "TSystem.h"
#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TH1.h"
#include "TFile.h"
#include "TObject.h"
#include "TStyle.h"
#include "TROOT.h"

#include "AliAODEvent.h"
#include "AliAODHeader.h"
#include "AliAODEventInfo.h"
#include "AliAODVertex.h"
#include "AliAODTrack.h"
#include "AliAODCluster.h"
#include "AliAODDimuon.h"

#endif

void ReadSpecAOD(const char *fileName = "AliMuonAOD.root") {

  gSystem->Load("libTree.so");
  gSystem->Load("libVMC.so");
  gSystem->Load("libPhysics.so");
  gSystem->Load("STEERBase/libSTEERBase");
  gSystem->Load("AOD/libAOD");
  gROOT->LoadMacro("AliAODEventInfo.cxx++");
  gROOT->LoadMacro("AliAODDimuon.cxx++");

  gStyle->SetOptStat(111111);
  gStyle->SetFrameFillColor(10);
  gStyle->SetCanvasColor(10);
  gStyle->SetOptStat(0);
  TH1F *mass=new TH1F("mass","Invariant mass",100,0.,20.);
  TH1F *rap=new TH1F("rap","Rapidity",100,-5.,0.);
  TH1F *cost=new TH1F("cost","Cost_CS",100,-1.,1.);
  TH1F *pt=new TH1F("pt","Pt",100,0.,50.);
  TH1F *ptmuon=new TH1F("ptmuon","single muon Pt",100,0.,50.);

  // open input file and get the TTree
  TFile inFile(fileName, "READ");
  TTree *aodTree = (TTree*)inFile.Get("AOD");

  AliAODEvent *aod = (AliAODEvent*)aodTree->GetUserInfo()->FindObject("AliAODEvent");

  TClonesArray *Dimuons;
  TClonesArray *tracks;
  TClonesArray *vertices;
  AliAODEventInfo *MuonInfos;

  aodTree->SetBranchAddress("Dimuons",&Dimuons);
  aodTree->SetBranchAddress("tracks",&tracks);
  aodTree->SetBranchAddress("vertices",&vertices);
  aodTree->SetBranchAddress("MuonInfos",&MuonInfos);

  // loop over events
  Int_t nEvents = aodTree->GetEntries();
  for (Int_t nEv = 0; nEv < nEvents; nEv++) {
    cout << "Event: " << nEv+1 << "/" << nEvents << endl;
    aodTree->GetEntry(nEv);
    // loop over tracks
    Int_t nTracks = tracks->GetEntries();
    for (Int_t nTr = 0; nTr < nTracks; nTr++) {
      AliAODTrack *tr = (AliAODTrack *)tracks->At(nTr);
      ptmuon->Fill(tr->Pt());
      // print track info
      cout << nTr+1 << "/" << nTracks << ": track pt: " << tr->Pt();
      if (tr->GetProdVertex()) {
	cout << ", vertex z of this track: " << tr->GetProdVertex()->GetZ();
      }
      cout << endl;
    }
    // loop over dimuons

    Int_t nDimuons = Dimuons->GetEntries();
    cout << nDimuons << " dimuon(s)" << endl;
    for(Int_t nDi=0; nDi < nDimuons; nDi++){
      AliAODDimuon *di=(AliAODDimuon*)Dimuons->At(nDi);
       if((MuonInfos->MUON_Unlike_HPt_L0())){
         mass->Fill(di->M());
         pt->Fill(di->Pt());
         rap->Fill(di->Y());
         cost->Fill(di->CostCS());
         cout << "Dimuon: " << nDi << " q: " << di->Charge()
	      << " m: " << di->M() << " Y: " << di->Y() << " Pt: " << di->Pt()<< " CostCS: " << di->CostCS() << endl  ;
       }
    }
//     // loop over vertices
//     Int_t nVtxs = vertices->GetEntries();
//     for (Int_t nVtx = 0; nVtx < nVtxs; nVtx++) {
//
//       // print track info
//       cout << nVtx+1 << "/" << nVtxs << ": vertex z position: " <<vertices->At(nVtx)->GetZ() << endl;
//     }
  }
  inFile.Close();
  TCanvas *c1=new TCanvas();
  c1->Show();
  c1->Divide(2,2);
  c1->ForceUpdate();
  c1->cd(1);
  mass->DrawClone();
  c1->cd(2);
  rap->DrawClone();
  c1->cd(3);
  pt->DrawClone();
  c1->cd(4);
  cost->DrawClone();

  TCanvas *c2 = new TCanvas();
  c2->cd();
  ptmuon->DrawClone();
  return;
}
<commit_msg>Right definition of libraries to be loaded<commit_after>#if !defined(__CINT__) || defined(__MAKECINT__)

#include <Riostream.h>
#include "TSystem.h"
#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TH1.h"
#include "TFile.h"
#include "TObject.h"
#include "TStyle.h"
#include "TROOT.h"

#include "AliAODEvent.h"
#include "AliAODHeader.h"
#include "AliAODEventInfo.h"
#include "AliAODVertex.h"
#include "AliAODTrack.h"
#include "AliAODCluster.h"
#include "AliAODDimuon.h"

#endif

void ReadSpecAOD(const char *fileName = "AliMuonAOD.root") {

    gSystem->Load("libTree");
    gSystem->Load("libGeom");
    gSystem->Load("libSTEERBase");
    gSystem->Load("libAOD");
    gSystem->Load("libANALYSIS");
    gSystem->Load("libPWG3base.so");

  gStyle->SetOptStat(111111);
  gStyle->SetFrameFillColor(10);
  gStyle->SetCanvasColor(10);
  gStyle->SetOptStat(0);
  TH1F *mass=new TH1F("mass","Invariant mass",100,0.,20.);
  TH1F *rap=new TH1F("rap","Rapidity",100,-5.,0.);
  TH1F *cost=new TH1F("cost","Cost_CS",100,-1.,1.);
  TH1F *pt=new TH1F("pt","Pt",100,0.,50.);
  TH1F *ptmuon=new TH1F("ptmuon","single muon Pt",100,0.,50.);

  // open input file and get the TTree
  TFile inFile(fileName, "READ");
  TTree *aodTree = (TTree*)inFile.Get("AOD");

  AliAODEvent *aod = (AliAODEvent*)aodTree->GetUserInfo()->FindObject("AliAODEvent");

  TClonesArray *Dimuons;
  TClonesArray *tracks;
  TClonesArray *vertices;
  AliAODEventInfo *MuonInfos;

  aodTree->SetBranchAddress("Dimuons",&Dimuons);
  aodTree->SetBranchAddress("tracks",&tracks);
  aodTree->SetBranchAddress("vertices",&vertices);
  aodTree->SetBranchAddress("MuonInfos",&MuonInfos);

  // loop over events
  Int_t nEvents = aodTree->GetEntries();
  for (Int_t nEv = 0; nEv < nEvents; nEv++) {
    cout << "Event: " << nEv+1 << "/" << nEvents << endl;
    aodTree->GetEntry(nEv);
    // loop over tracks
    Int_t nTracks = tracks->GetEntries();
    for (Int_t nTr = 0; nTr < nTracks; nTr++) {
      AliAODTrack *tr = (AliAODTrack *)tracks->At(nTr);
      ptmuon->Fill(tr->Pt());
      // print track info
      cout << nTr+1 << "/" << nTracks << ": track pt: " << tr->Pt();
      if (tr->GetProdVertex()) {
	cout << ", vertex z of this track: " << tr->GetProdVertex()->GetZ();
      }
      cout << endl;
    }
    // loop over dimuons

    Int_t nDimuons = Dimuons->GetEntries();
    cout << nDimuons << " dimuon(s)" << endl;
    for(Int_t nDi=0; nDi < nDimuons; nDi++){
      AliAODDimuon *di=(AliAODDimuon*)Dimuons->At(nDi);
       if((MuonInfos->MUON_Unlike_HPt_L0())){
         mass->Fill(di->M());
         pt->Fill(di->Pt());
         rap->Fill(di->Y());
         cost->Fill(di->CostCS());
         cout << "Dimuon: " << nDi << " q: " << di->Charge()
	      << " m: " << di->M() << " Y: " << di->Y() << " Pt: " << di->Pt()<< " CostCS: " << di->CostCS() << endl  ;
       }
    }
//     // loop over vertices
//     Int_t nVtxs = vertices->GetEntries();
//     for (Int_t nVtx = 0; nVtx < nVtxs; nVtx++) {
//
//       // print track info
//       cout << nVtx+1 << "/" << nVtxs << ": vertex z position: " <<vertices->At(nVtx)->GetZ() << endl;
//     }
  }
  inFile.Close();
  TCanvas *c1=new TCanvas();
  c1->Show();
  c1->Divide(2,2);
  c1->ForceUpdate();
  c1->cd(1);
  mass->DrawClone();
  c1->cd(2);
  rap->DrawClone();
  c1->cd(3);
  pt->DrawClone();
  c1->cd(4);
  cost->DrawClone();

  TCanvas *c2 = new TCanvas();
  c2->cd();
  ptmuon->DrawClone();
  return;
}
<|endoftext|>


<commit_before>#include "Packet.h"

namespace OpenPGP {
namespace Packet {

bool is_key_packet(const uint8_t t){
    return (is_primary_key(t) || is_subkey(t));
}

bool is_primary_key(const uint8_t t){
    return ((t == SECRET_KEY) ||
            (t == PUBLIC_KEY));
}

bool is_subkey(const uint8_t t){
    return ((t == SECRET_SUBKEY) ||
            (t == PUBLIC_SUBKEY));
}

bool is_public(const uint8_t t){
    return ((t == PUBLIC_KEY) ||
            (t == PUBLIC_SUBKEY));
}

bool is_secret(const uint8_t t){
    return ((t == SECRET_KEY) ||
            (t == SECRET_SUBKEY));
}

bool is_user(const uint8_t t){
    return ((t == USER_ID) ||
            (t == USER_ATTRIBUTE));
}

bool is_session_key(const uint8_t t){
    return ((t == PUBLIC_KEY_ENCRYPTED_SESSION_KEY) ||
            (t == SYMMETRIC_KEY_ENCRYPTED_SESSION_KEY));
}

bool is_sym_protected_data(const uint8_t t){
    return ((t == SYMMETRICALLY_ENCRYPTED_DATA) ||
            (t == SYM_ENCRYPTED_INTEGRITY_PROTECTED_DATA));
}

bool is_equals(Tag::Ptr p1, Tag::Ptr p2){
    return p1->raw() == p2->raw();
}

std::string Tag::write_old_length(const std::string & data) const{
    std::string::size_type length = data.size();
    std::string out(1, 0b10000000 | (tag << 2));
    if (partial){
        out[0] |= 3;                                        // partial
    }
    else{
        if (length < 256){
            out[0] |= 0;                                    // 1 octet
            out += std::string(1, length);
        }
        else if ((256 <= length) && (length < 65536)){      // 2 octest
            out[0] |= 1;
            out += unhexlify(makehex(length, 4));
        }
        else if (65536 <= length){                          // 4 octets
            out[0] |= 2;
            out += unhexlify(makehex(length, 8));
        }
    }
    return out + data;
}

// returns formatted length string
std::string Tag::write_new_length(const std::string & data) const{
    std::string::size_type length = data.size();
    std::string out(1, 0b11000000 | tag);
    if (partial){                                           // partial
        uint8_t bits = 0;
        while (length > (1u << bits)){
            bits++;
        }
        length = 224 + bits;
        if (length > 254){
            throw std::runtime_error("Error: Data in partial Tag too large.");
        }

        out += std::string(1, length);
    }
    else{
        if (length < 192){                                  // 1 octet
            out += std::string(1, length);
        }
        else if ((192 <= length) && (length < 8383)){       // 2 octets
            length -= 0xc0;
            out += std::string(1, (length >> 8) + 0xc0 ) + std::string(1, length & 0xff);
        }
        else if (length > 8383){                            // 3 octets
            out += std::string(1, '\xff') + unhexlify(makehex(length, 8));
        }
    }
    return out + data;
}

std::string Tag::show_title() const{
    std::string out = std::string(format?"New":"Old") + ": " + NAME.at(tag) + " (Tag " + std::to_string(tag) + ")";

    switch (partial){
        case 0:
            break;
        case 1:
            out += " (partial start)";
            break;
        case 2:
            out += " (partial continue)";
            break;
        case 3:
            out += " (partial end)";
            break;
        default:
            throw std::runtime_error("Error: Unknown partial type: " + std::to_string(partial));
            break;
    }
    return out;
}

Tag::Tag(const uint8_t t)
    : Tag(t, 0)
{}

Tag::Tag(const uint8_t t, uint8_t ver)
    : tag(t),
      version(ver),
      format(true),
      size(0),
      partial(0)
{}

Tag::Tag(const Tag & copy)
    : tag(copy.tag),
      version(copy.version),
      format(copy.version),
      size(copy.size),
      partial(copy.partial)
{}

Tag::Tag()
    : Tag(UNKNOWN)
{}

Tag::~Tag(){}

std::string Tag::write(const Tag::Format header) const{
    if ((header == NEW) ||      // specified new header
        (tag > 15)){            // tag > 15, so new header is required
        return write_new_length(raw());
    }
    return write_old_length(raw());
}

uint8_t Tag::get_tag() const{
    return tag;
}

bool Tag::get_format() const{
    return format;
}

uint8_t Tag::get_version() const{
    return version;
}

std::size_t Tag::get_size() const{
    return size;
}

uint8_t Tag::get_partial() const{
    return partial;
}

void Tag::set_tag(const uint8_t t){
    tag = t;
}

void Tag::set_format(const bool f){
    format = f;
}

void Tag::set_version(const uint8_t v){
    version = v;
}

void Tag::set_size(const std::size_t s){
    size = s;
}

void Tag::set_partial(const uint8_t p){
    partial = p;
}

Tag & Tag::operator=(const Tag & copy)
{
    tag = copy.tag;
    version = copy.version;
    format = copy.format;
    size = copy.size;
    partial = copy.partial;
    return *this;
}

}
}
<commit_msg>function is_equals removed<commit_after>#include "Packet.h"

namespace OpenPGP {
namespace Packet {

bool is_key_packet(const uint8_t t){
    return (is_primary_key(t) || is_subkey(t));
}

bool is_primary_key(const uint8_t t){
    return ((t == SECRET_KEY) ||
            (t == PUBLIC_KEY));
}

bool is_subkey(const uint8_t t){
    return ((t == SECRET_SUBKEY) ||
            (t == PUBLIC_SUBKEY));
}

bool is_public(const uint8_t t){
    return ((t == PUBLIC_KEY) ||
            (t == PUBLIC_SUBKEY));
}

bool is_secret(const uint8_t t){
    return ((t == SECRET_KEY) ||
            (t == SECRET_SUBKEY));
}

bool is_user(const uint8_t t){
    return ((t == USER_ID) ||
            (t == USER_ATTRIBUTE));
}

bool is_session_key(const uint8_t t){
    return ((t == PUBLIC_KEY_ENCRYPTED_SESSION_KEY) ||
            (t == SYMMETRIC_KEY_ENCRYPTED_SESSION_KEY));
}

bool is_sym_protected_data(const uint8_t t){
    return ((t == SYMMETRICALLY_ENCRYPTED_DATA) ||
            (t == SYM_ENCRYPTED_INTEGRITY_PROTECTED_DATA));
}

std::string Tag::write_old_length(const std::string & data) const{
    std::string::size_type length = data.size();
    std::string out(1, 0b10000000 | (tag << 2));
    if (partial){
        out[0] |= 3;                                        // partial
    }
    else{
        if (length < 256){
            out[0] |= 0;                                    // 1 octet
            out += std::string(1, length);
        }
        else if ((256 <= length) && (length < 65536)){      // 2 octest
            out[0] |= 1;
            out += unhexlify(makehex(length, 4));
        }
        else if (65536 <= length){                          // 4 octets
            out[0] |= 2;
            out += unhexlify(makehex(length, 8));
        }
    }
    return out + data;
}

// returns formatted length string
std::string Tag::write_new_length(const std::string & data) const{
    std::string::size_type length = data.size();
    std::string out(1, 0b11000000 | tag);
    if (partial){                                           // partial
        uint8_t bits = 0;
        while (length > (1u << bits)){
            bits++;
        }
        length = 224 + bits;
        if (length > 254){
            throw std::runtime_error("Error: Data in partial Tag too large.");
        }

        out += std::string(1, length);
    }
    else{
        if (length < 192){                                  // 1 octet
            out += std::string(1, length);
        }
        else if ((192 <= length) && (length < 8383)){       // 2 octets
            length -= 0xc0;
            out += std::string(1, (length >> 8) + 0xc0 ) + std::string(1, length & 0xff);
        }
        else if (length > 8383){                            // 3 octets
            out += std::string(1, '\xff') + unhexlify(makehex(length, 8));
        }
    }
    return out + data;
}

std::string Tag::show_title() const{
    std::string out = std::string(format?"New":"Old") + ": " + NAME.at(tag) + " (Tag " + std::to_string(tag) + ")";

    switch (partial){
        case 0:
            break;
        case 1:
            out += " (partial start)";
            break;
        case 2:
            out += " (partial continue)";
            break;
        case 3:
            out += " (partial end)";
            break;
        default:
            throw std::runtime_error("Error: Unknown partial type: " + std::to_string(partial));
            break;
    }
    return out;
}

Tag::Tag(const uint8_t t)
    : Tag(t, 0)
{}

Tag::Tag(const uint8_t t, uint8_t ver)
    : tag(t),
      version(ver),
      format(true),
      size(0),
      partial(0)
{}

Tag::Tag(const Tag & copy)
    : tag(copy.tag),
      version(copy.version),
      format(copy.version),
      size(copy.size),
      partial(copy.partial)
{}

Tag::Tag()
    : Tag(UNKNOWN)
{}

Tag::~Tag(){}

std::string Tag::write(const Tag::Format header) const{
    if ((header == NEW) ||      // specified new header
        (tag > 15)){            // tag > 15, so new header is required
        return write_new_length(raw());
    }
    return write_old_length(raw());
}

uint8_t Tag::get_tag() const{
    return tag;
}

bool Tag::get_format() const{
    return format;
}

uint8_t Tag::get_version() const{
    return version;
}

std::size_t Tag::get_size() const{
    return size;
}

uint8_t Tag::get_partial() const{
    return partial;
}

void Tag::set_tag(const uint8_t t){
    tag = t;
}

void Tag::set_format(const bool f){
    format = f;
}

void Tag::set_version(const uint8_t v){
    version = v;
}

void Tag::set_size(const std::size_t s){
    size = s;
}

void Tag::set_partial(const uint8_t p){
    partial = p;
}

Tag & Tag::operator=(const Tag & copy)
{
    tag = copy.tag;
    version = copy.version;
    format = copy.format;
    size = copy.size;
    partial = copy.partial;
    return *this;
}

}
}
<|endoftext|>


<commit_before><commit_msg>added option to apply autobinding parameters even to materials without node bindings<commit_after><|endoftext|>


<commit_before>// -------------------------------------------------------------------
/// \file   DstWriter.cxx
/// \brief
///
/// \author  <justo.martin-albo@physics.ox.ac.uk>
/// \date    Creation: 11 Aug 2016
// -------------------------------------------------------------------

#include "DstWriter.h"

#include <Ntuple/NtpMCEventRecord.h>

#include <TTree.h>
#include <TFile.h>
#include <TBranch.h>

DstWriter::DstWriter(): file_(0), tree_(0)
{
}

DstWriter::~DstWriter()
{
  CloseFile();
  delete file_;
}

void DstWriter::OpenFile(const std::string& filename,
                         const std::string& option)
{
  // Close any previously opened file
  CloseFile();

  // Create a new ROOT file returning false if something goes wrong
  file_ = new TFile(filename.c_str(), option.c_str());

  // Create a tree and all its branches
  tree_ = new TTree("NdtfDst", "DUNE ND-TF GArTPC DST");

  tree_->Branch("gmcrec", "genie::NtpMCEventRecord", &(entry_.gmcrec));

  tree_->Branch("RunID",   &(entry_.RunID),   "RunID/I");
  tree_->Branch("EventID", &(entry_.EventID), "EventID/I");
  tree_->Branch("Sample",  &(entry_.Sample),  "Sample/I");

  tree_->Branch("Ev",      &(entry_.Ev),      "Ev/D");
  tree_->Branch("Ev_reco", &(entry_.Ev_reco), "Ev_reco/D");
  tree_->Branch("Y",       &(entry_.Y),       "Y/D");
  tree_->Branch("Y_reco",  &(entry_.Y_reco),  "Y_reco/D");

  tree_->Branch("VertexPosition", entry_.VertexPosition, "VertexPosition[4]/D");

  tree_->Branch("NTracks",  &(entry_.NTracks), "NTracks/I");

  tree_->Branch("TrackID",  (entry_.TrackID),  "TrackID[NTracks]/I");
  tree_->Branch("FamilyTreeLevel", (entry_.FamilyTreeLevel), "FamilyTreeLevel[NTracks]/I");
  tree_->Branch("Pdg",      (entry_.Pdg),      "Pdg[NTracks]/I");
  tree_->Branch("Pdg_reco", (entry_.Pdg),      "Pdg_reco[NTracks]/I");

  tree_->Branch("Momentum", (entry_.Momentum), "Momentum[NTracks][3]/D");
  tree_->Branch("Momentum_reco", (entry_.Momentum_reco), "Momentum_reco[NTracks][3]/D");

  // tree_->Branch("TrackID",        TrackID, "TrackID[NGeantTracks]/I");
  // tree_->Branch("Momentum",       Momentum, "Momentum[NGeantTracks]/D");
  // tree_->Branch("TotalEDep",      TotalEDep, "TotalEDep[NGeantTracks]/D");
  // tree_->Branch("Pdg",            Pdg, "Pdg[NGeantTracks]/I");
  // tree_->Branch("dEdx",           dEdx, "dEdx[NGeantTracks]/D");
  // tree_->Branch("NGeantHits",     NGeantHits, "NGeantHits[NGeantTracks]/I");

  //tree_->SetWeight(3.75E15);
}

void DstWriter::CloseFile()
{
  if (this->IsFileOpen()) {
    file_->Write();
    file_->Close();
  }
}

void DstWriter::Write(DstEntry& entry)
{
  entry_ = entry;
  tree_->Fill();
}

bool DstWriter::IsFileOpen() const
{
  if (!file_) return false;
  else return file_->IsOpen();
}
<commit_msg>Forgotten RecoTrack variable added.<commit_after>// -------------------------------------------------------------------
/// \file   DstWriter.cxx
/// \brief
///
/// \author  <justo.martin-albo@physics.ox.ac.uk>
/// \date    Creation: 11 Aug 2016
// -------------------------------------------------------------------

#include "DstWriter.h"

#include <Ntuple/NtpMCEventRecord.h>

#include <TTree.h>
#include <TFile.h>
#include <TBranch.h>

DstWriter::DstWriter(): file_(0), tree_(0)
{
}

DstWriter::~DstWriter()
{
  CloseFile();
  delete file_;
}

void DstWriter::OpenFile(const std::string& filename,
                         const std::string& option)
{
  // Close any previously opened file
  CloseFile();

  // Create a new ROOT file returning false if something goes wrong
  file_ = new TFile(filename.c_str(), option.c_str());

  // Create a tree and all its branches
  tree_ = new TTree("NdtfDst", "DUNE ND-TF GArTPC DST");

  tree_->Branch("gmcrec", "genie::NtpMCEventRecord", &(entry_.gmcrec));

  tree_->Branch("RunID",   &(entry_.RunID),   "RunID/I");
  tree_->Branch("EventID", &(entry_.EventID), "EventID/I");
  tree_->Branch("Sample",  &(entry_.Sample),  "Sample/I");

  tree_->Branch("Ev",      &(entry_.Ev),      "Ev/D");
  tree_->Branch("Ev_reco", &(entry_.Ev_reco), "Ev_reco/D");
  tree_->Branch("Y",       &(entry_.Y),       "Y/D");
  tree_->Branch("Y_reco",  &(entry_.Y_reco),  "Y_reco/D");

  tree_->Branch("VertexPosition", entry_.VertexPosition, "VertexPosition[4]/D");

  tree_->Branch("NTracks",  &(entry_.NTracks), "NTracks/I");

  tree_->Branch("TrackID",  (entry_.TrackID),  "TrackID[NTracks]/I");
  tree_->Branch("FamilyTreeLevel", (entry_.FamilyTreeLevel), "FamilyTreeLevel[NTracks]/I");
  tree_->Branch("Pdg",      (entry_.Pdg),      "Pdg[NTracks]/I");
  tree_->Branch("Pdg_reco", (entry_.Pdg),      "Pdg_reco[NTracks]/I");
  tree_->Branch("RecoTrack", (entry_.RecoTrack), "RecoTrack[NTracks]/I");

  tree_->Branch("Momentum", (entry_.Momentum), "Momentum[NTracks][3]/D");
  tree_->Branch("Momentum_reco", (entry_.Momentum_reco), "Momentum_reco[NTracks][3]/D");

  // tree_->Branch("TrackID",        TrackID, "TrackID[NGeantTracks]/I");
  // tree_->Branch("Momentum",       Momentum, "Momentum[NGeantTracks]/D");
  // tree_->Branch("TotalEDep",      TotalEDep, "TotalEDep[NGeantTracks]/D");
  // tree_->Branch("Pdg",            Pdg, "Pdg[NGeantTracks]/I");
  // tree_->Branch("dEdx",           dEdx, "dEdx[NGeantTracks]/D");
  // tree_->Branch("NGeantHits",     NGeantHits, "NGeantHits[NGeantTracks]/I");

  //tree_->SetWeight(3.75E15);
}

void DstWriter::CloseFile()
{
  if (this->IsFileOpen()) {
    file_->Write();
    file_->Close();
  }
}

void DstWriter::Write(DstEntry& entry)
{
  entry_ = entry;
  tree_->Fill();
}

bool DstWriter::IsFileOpen() const
{
  if (!file_) return false;
  else return file_->IsOpen();
}
<|endoftext|>