<commit_before>/*
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "RConnectSocket.hxx"
#include "net/Resolver.hxx"
#include "net/AddressInfo.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "system/Error.hxx"
#include "io/FileDescriptor.hxx"

UniqueSocketDescriptor
ResolveConnectSocket(const char *host_and_port, int default_port,
                     const struct addrinfo &hints)
{
    const auto ail = Resolve(host_and_port, default_port, &hints);
    const auto &ai = ail.front();

    UniqueSocketDescriptor s;
    if (!s.CreateNonBlock(ai.GetFamily(), ai.GetType(), ai.GetProtocol()))
        throw MakeErrno("Failed to create socket");

    if (!s.Connect(ai)) {
        if (errno != EINPROGRESS)
            throw MakeErrno("Failed to connect");

        int w = FileDescriptor(s.Get()).WaitWritable(60000);
        if (w < 0)
            throw MakeErrno("Connect wait error");
        else if (w == 0)
            throw std::runtime_error("Connect timeout");

        int err = s.GetError();
        if (err != 0)
            throw MakeErrno(err, "Failed to connect");
    }

    return s;
}
<commit_msg>net/RConnectSocket: eliminate obsolete FileDescriptor cast<commit_after>/*
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "RConnectSocket.hxx"
#include "net/Resolver.hxx"
#include "net/AddressInfo.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "system/Error.hxx"

UniqueSocketDescriptor
ResolveConnectSocket(const char *host_and_port, int default_port,
                     const struct addrinfo &hints)
{
    const auto ail = Resolve(host_and_port, default_port, &hints);
    const auto &ai = ail.front();

    UniqueSocketDescriptor s;
    if (!s.CreateNonBlock(ai.GetFamily(), ai.GetType(), ai.GetProtocol()))
        throw MakeErrno("Failed to create socket");

    if (!s.Connect(ai)) {
        if (errno != EINPROGRESS)
            throw MakeErrno("Failed to connect");

        int w = s.WaitWritable(60000);
        if (w < 0)
            throw MakeErrno("Connect wait error");
        else if (w == 0)
            throw std::runtime_error("Connect timeout");

        int err = s.GetError();
        if (err != 0)
            throw MakeErrno(err, "Failed to connect");
    }

    return s;
}
<|endoftext|>


<commit_before>#include "genome.h"
#include <vector>
#include <algorithm>

Genome::Genome(const TrainingParameters& parameters) :
	parameters(parameters),
	genes(parameters.numberOfInputs * parameters.numberOfOutputs)
{
	auto *currentGene = &genes.front();
	for (auto in = 0U; in < parameters.numberOfInputs; ++in) {
		for (auto out = 0U; out < parameters.numberOfOutputs; ++out) {
			currentGene->from = in;
			currentGene->to = out + parameters.numberOfInputs;
			++currentGene;
		}
	}
}

std::size_t Genome::ExtrapolateNeuronCount() const {
	auto CompareToNeuron = [](const Gene& lhs, const Gene& rhs) {
		return lhs.to < rhs.to;
	};
	auto maxNeuronGene = std::max_element(genes.begin(), genes.end(), CompareToNeuron);
	// TODO jnf Maybe add lookup table
	return maxNeuronGene->to + 1U;
}

std::size_t Genome::GetGeneCount() const {
	return genes.size();
}

Genome& Genome::operator=(const Genome& other)
{
	this->genes = other.genes;
	const_cast<TrainingParameters&>(this->parameters) = other.parameters;
	return *this;
}

void Genome::MutateGenes() {
	if (ShouldAddConnection()) {
		AddRandomConnection();
	}
	else
	if (ShouldAddNeuron()) {
		AddRandomNeuron();
	}
	else {
		ShuffleWeights();
	}
}

bool Genome::DidChanceOccure(float chance)
{
	auto num = rand() % 100;
	return num < int(100.0f * chance);
}

void Genome::AddRandomNeuron()
{
	Gene* randGene = nullptr;
	do {
		int num = rand() % genes.size();
		randGene = &genes[num];
	} while (!randGene->isEnabled);

	auto indexOfNewNeuron = ExtrapolateNeuronCount();

	Gene g1;
    g1.from = randGene->from;
	g1.to = indexOfNewNeuron;

	Gene g2;
	g2.from = indexOfNewNeuron;
    g2.to = randGene->to;

	randGene->isEnabled = false;
	genes.push_back(std::move(g1));
	genes.push_back(std::move(g2));
}

void Genome::AddRandomConnection()
{
	auto GetRandomNumberBetween = [](size_t min, size_t max) {
		return rand() % (max - min) + min;
	};

	Gene newConnection;
	auto highestNeuronIndex = ExtrapolateNeuronCount() - 1U;

	newConnection.from = GetRandomNumberBetween(0U, highestNeuronIndex - 1U);
	newConnection.to = GetRandomNumberBetween(newConnection.from + 1, highestNeuronIndex);

	genes.push_back(newConnection);
}

void Genome::ShuffleWeights()
{
	for (size_t i = 0; i < genes.size(); i++) {
		if (ShouldMutateWeight()) {
			MutateWeightOfGeneAt(i);
		}
	}
}

void Genome::MutateWeightOfGeneAt(size_t index)
{
	constexpr float chanceOfTotalWeightReset = 0.1f;
	if (DidChanceOccure(chanceOfTotalWeightReset)) {
		genes[index].SetRandomWeight();
	} else {
		PerturbWeightAt(index);
	}
}

void Genome::PerturbWeightAt(size_t index)
{
	constexpr float perturbanceBoundaries = 0.2f;
	auto perturbance = (float)(rand() % 10'000) / 10'000.0f * perturbanceBoundaries;
	if (rand() % 2) {
		perturbance = -perturbance;
	}
	genes[index].weight *= perturbance;
}

double Genome::GetGeneticalDistanceFrom(const Genome& other) const
{
	double totalWeightDifference = 0.0;
	size_t numberOfOverlapingGenes = 0;

	size_t sizeOfSmallerGenome = std::min(this->GetGeneCount(), other.GetGeneCount());
	auto IsHistoricalMarkingSameAt = [&](size_t i) {
		return this->GetGeneAt(i).historicalMarking == other[i].historicalMarking;
	};

	for (size_t i = 0; i < sizeOfSmallerGenome && IsHistoricalMarkingSameAt(i); ++i) {
		totalWeightDifference += (double)std::abs(this->GetGeneAt(i).weight - other[i].weight);
		++numberOfOverlapingGenes;
	}

	auto numberOfDisjointGenes = this->GetGeneCount() + other.GetGeneCount() - (size_t)2 * numberOfOverlapingGenes;
	auto sizeOfBiggerGenome = std::max(this->GetGeneCount(), other.GetGeneCount());
	auto disjointGenesInfluence = (double)numberOfDisjointGenes / (double)sizeOfBiggerGenome;

	auto averageWeightDifference = totalWeightDifference / (double)numberOfOverlapingGenes;

	disjointGenesInfluence *= (double)parameters.advanced.speciation.importanceOfDisjointGenes;
	averageWeightDifference *= (double)parameters.advanced.speciation.importanceOfAverageWeightDifference;

	return disjointGenesInfluence + averageWeightDifference;
}<commit_msg>Continued work on #2<commit_after>#include "genome.h"
#include <vector>
#include <algorithm>

Genome::Genome(const TrainingParameters& parameters) :
	parameters(parameters),
	genes(parameters.numberOfInputs * parameters.numberOfOutputs)
{
	auto *currentGene = &genes.front();
	for (auto in = 0U; in < parameters.numberOfInputs; ++in) {
		for (auto out = 0U; out < parameters.numberOfOutputs; ++out) {
			currentGene->from = in;
			currentGene->to = out + parameters.numberOfInputs;
			++currentGene;
		}
	}
}

std::size_t Genome::ExtrapolateNeuronCount() const {
	auto CompareToNeuron = [](const Gene& lhs, const Gene& rhs) {
		return lhs.to < rhs.to;
	};
	auto maxNeuronGene = std::max_element(genes.begin(), genes.end(), CompareToNeuron);
	// TODO jnf Maybe add lookup table
	return maxNeuronGene->to + 1U;
}

std::size_t Genome::GetGeneCount() const {
	return genes.size();
}

Genome& Genome::operator=(const Genome& other)
{
	this->genes = other.genes;
	const_cast<TrainingParameters&>(this->parameters) = other.parameters;
	return *this;
}

void Genome::MutateGenes() {
	if (ShouldAddConnection()) {
		AddRandomConnection();
	}
	else
	if (ShouldAddNeuron()) {
		AddRandomNeuron();
	}
	else {
		ShuffleWeights();
	}
}

bool Genome::DidChanceOccure(float chance)
{
	auto num = rand() % 100;
	return num < int(100.0f * chance);
}

void Genome::AddRandomNeuron()
{
	Gene* randGene = nullptr;
	do {
		int num = rand() % genes.size();
		randGene = &genes[num];
	} while (!randGene->isEnabled);

	auto indexOfNewNeuron = ExtrapolateNeuronCount();

	Gene g1;
    g1.from = randGene->from;
	g1.to = indexOfNewNeuron;
    g1.weight = randGene->weight;

	Gene g2;
	g2.from = indexOfNewNeuron;
    g2.to = randGene->to;
    g2.weight = randGene->weight;

	randGene->isEnabled = false;
	genes.push_back(std::move(g1));
	genes.push_back(std::move(g2));
}

void Genome::AddRandomConnection()
{
	auto GetRandomNumberBetween = [](size_t min, size_t max) {
		return rand() % (max - min) + min;
	};

	Gene newConnection;
	auto highestNeuronIndex = ExtrapolateNeuronCount() - 1U;

	newConnection.from = GetRandomNumberBetween(0U, highestNeuronIndex - 1U);
	newConnection.to = GetRandomNumberBetween(newConnection.from + 1, highestNeuronIndex);

	//genes.push_back(newConnection);
}

void Genome::ShuffleWeights()
{
	for (size_t i = 0; i < genes.size(); i++) {
		if (ShouldMutateWeight()) {
			MutateWeightOfGeneAt(i);
		}
	}
}

void Genome::MutateWeightOfGeneAt(size_t index)
{
	constexpr float chanceOfTotalWeightReset = 0.1f;
	if (DidChanceOccure(chanceOfTotalWeightReset)) {
		genes[index].SetRandomWeight();
	} else {
		PerturbWeightAt(index);
	}
}

void Genome::PerturbWeightAt(size_t index)
{
	constexpr float perturbanceBoundaries = 0.2f;
	auto perturbance = (float)(rand() % 10'000) / 10'000.0f * perturbanceBoundaries;
	if (rand() % 2) {
		perturbance = -perturbance;
	}
	genes[index].weight *= perturbance;
}

double Genome::GetGeneticalDistanceFrom(const Genome& other) const
{
	double totalWeightDifference = 0.0;
	size_t numberOfOverlapingGenes = 0;

	size_t sizeOfSmallerGenome = std::min(this->GetGeneCount(), other.GetGeneCount());
	auto IsHistoricalMarkingSameAt = [&](size_t i) {
		return this->GetGeneAt(i).historicalMarking == other[i].historicalMarking;
	};

	for (size_t i = 0; i < sizeOfSmallerGenome && IsHistoricalMarkingSameAt(i); ++i) {
		totalWeightDifference += (double)std::abs(this->GetGeneAt(i).weight - other[i].weight);
		++numberOfOverlapingGenes;
	}

	auto numberOfDisjointGenes = this->GetGeneCount() + other.GetGeneCount() - (size_t)2 * numberOfOverlapingGenes;
	auto sizeOfBiggerGenome = std::max(this->GetGeneCount(), other.GetGeneCount());
	auto disjointGenesInfluence = (double)numberOfDisjointGenes / (double)sizeOfBiggerGenome;

	auto averageWeightDifference = totalWeightDifference / (double)numberOfOverlapingGenes;

	disjointGenesInfluence *= (double)parameters.advanced.speciation.importanceOfDisjointGenes;
	averageWeightDifference *= (double)parameters.advanced.speciation.importanceOfAverageWeightDifference;

	return disjointGenesInfluence + averageWeightDifference;
}<|endoftext|>


<commit_before>//-----------------------------------------------------------------------------
// Jikken - 3D Abstract High Performance Graphics API
// Copyright(c) 2017 Jeff Hutchinson
// Copyright(c) 2017 Tim Barnes
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//-----------------------------------------------------------------------------

#include <cassert>
#include <cstdlib>
#include "vulkan/VulkanGraphicsDevice.hpp"
#include "vulkan/VulkanUtil.hpp"
//just temp
#include <GLFW/glfw3.h>

namespace Jikken
{
	VulkanGraphicsDevice::VulkanGraphicsDevice() :
		mInstance(VK_NULL_HANDLE),
		mSurface(VK_NULL_HANDLE),
		mPhysicalDevice(VK_NULL_HANDLE),
		mDevice(VK_NULL_HANDLE),
		mGraphicsQueue(VK_NULL_HANDLE),
		mGraphicsQueueIndex(UINT32_MAX),
		mDebugCallback(VK_NULL_HANDLE),
		mAllocCallback(nullptr)
	{
	}

	VulkanGraphicsDevice::~VulkanGraphicsDevice()
	{
		//wait for device to be idle
		if (mDevice)
			vkDeviceWaitIdle(mDevice);

		// cleanup other stuff

		// destroy logical device
		if (mDevice)
			vkDestroyDevice(mDevice, mAllocCallback);

		if (mSurface)
			vkDestroySurfaceKHR(mInstance, mSurface, mAllocCallback);

		if (mDebugCallback)
		{
			auto debugReportDestroyFunc = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(mInstance, "vkDestroyDebugReportCallbackEXT");
			if (debugReportDestroyFunc != nullptr)
			{
				debugReportDestroyFunc(mInstance, mDebugCallback, mAllocCallback);
			}
		}

		if (mInstance)
			vkDestroyInstance(mInstance, mAllocCallback);
	}

	bool VulkanGraphicsDevice::init(void *glfwWinHandle)
	{
		if (!glfwVulkanSupported())
		{
			std::printf("Vulkan is not supported\n");
			return false;
		}

		//validation layers
	#ifdef _DEBUG
		bool validationLayersEnabled = true;
	#else
		bool validationLayersEnabled = false
	#endif

		//grab vulkan instance extension list
		uint32_t extensionsCount = 0;
		VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &extensionsCount, nullptr);
		if (result != VK_SUCCESS || extensionsCount == 0)
		{
			std::printf("vkEnumerateInstanceExtensionProperties failed\n");
			return false;
		}

		std::vector<VkExtensionProperties> instanceExtensionList(extensionsCount);
		result = vkEnumerateInstanceExtensionProperties(nullptr, &extensionsCount, instanceExtensionList.data());

		if (result != VK_SUCCESS)
		{
			std::printf("vkEnumerateInstanceExtensionProperties failed\n");
			return false;
		}

		//get required extensions from glfw
		uint32_t glfwExtCount = 0;
		const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtCount);
		if (glfwExtCount == 0)
		{
			std::printf("Failed to find any required extensions\n");
			return false;
		}

		std::vector<const char*> requiredExtensions(glfwExtensions, glfwExtensions + glfwExtCount);

		if (validationLayersEnabled)
			requiredExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);

		// check required extension list against all availble extensions
		for (const auto &ext : requiredExtensions)
		{
			if (!vkutils::checkExtension(ext, instanceExtensionList))
			{
				std::printf("Required extension: %s not found\n", ext);
				return false;
			}
		}

		//setup validation layers - just VK_LAYER_LUNARG_standard_validation for now. There are plenty more though ;)
		const std::vector<const char*> validationLayers = { "VK_LAYER_LUNARG_standard_validation" };

		uint32_t layerCount = 0;

		if (validationLayersEnabled)
		{
			vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
			std::vector<VkLayerProperties> availableLayers(layerCount);
			vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());

			for (const auto &layer : validationLayers)
			{
				//this is not fatal so just disable validation layers if it is not found
				if (!vkutils::checkLayer(layer, availableLayers))
				{
					std::printf("Could not find validation layer: %s Disabling validation layers\n", layer);
					validationLayersEnabled = false;
				}
			}
		}

		//setup application and instance info
		VkApplicationInfo appInfo = {};
		appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
		appInfo.pApplicationName = "Jikken";
		appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
		appInfo.pEngineName = "Jikken";
		appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
		appInfo.apiVersion = VK_API_VERSION_1_0;

		VkInstanceCreateInfo createInfo = {};
		createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
		createInfo.flags = 0;
		createInfo.pApplicationInfo = &appInfo;
		createInfo.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size());
		createInfo.ppEnabledExtensionNames = requiredExtensions.data();
		if (validationLayersEnabled)
		{
			createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
			createInfo.ppEnabledLayerNames = validationLayers.data();
		}
		else
			createInfo.enabledLayerCount = 0;

		//finally create vulkan instance
		result = vkCreateInstance(&createInfo, mAllocCallback, &mInstance);

		if (result != VK_SUCCESS)
		{
			std::printf("vkCreateInstance failed\n");
			return false;
		}

		//setup debug callback if validation layers enabled
		if (validationLayersEnabled)
		{
			VkDebugReportCallbackCreateInfoEXT debugCreateInfo = {};
			debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
			debugCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
			debugCreateInfo.pfnCallback = vkutils::debugCallback;

			auto debugReportFunc = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(mInstance, "vkCreateDebugReportCallbackEXT");
			if (debugReportFunc != nullptr)
			{
				result = debugReportFunc(mInstance, &debugCreateInfo, mAllocCallback, &mDebugCallback);

				if (result != VK_SUCCESS)
				{
					std::printf("vkCreateDebugReportCallbackEXT failed\n");
					return false;
				}
			}
			else
			{
				std::printf("Failed to retrieve vkCreateDebugReportCallbackEXT address. Debug callbacks will be disabled\n");
				validationLayersEnabled = false;
			}
		}

		//create window surface
		result = glfwCreateWindowSurface(mInstance, static_cast<GLFWwindow*>(glfwWinHandle), mAllocCallback, &mSurface);
		if (result != VK_SUCCESS)
		{
			std::printf("Failed to create vulkan window surface\n");
			return false;
		}

		//find physical devices
		uint32_t numDevices = 0;
		result = vkEnumeratePhysicalDevices(mInstance, &numDevices, nullptr);
		if (result != VK_SUCCESS || numDevices == 0)
		{
			std::printf("vkEnumeratePhysicalDevices failed\n");
			return false;
		}

		std::vector<VkPhysicalDevice> physicalDevices(numDevices);
		result = vkEnumeratePhysicalDevices(mInstance, &numDevices, physicalDevices.data());
		if (result != VK_SUCCESS)
		{
			std::printf("vkEnumeratePhysicalDevices failed\n");
			return false;
		}

		//get our queue index and hopefully find an acceptable device
		for (const auto &device : physicalDevices)
		{
			//break on first acceptable device
			if (vkutils::checkPhysicalDevice(device, mSurface, mGraphicsQueueIndex))
			{
				mPhysicalDevice = device;
				break;
			}
		}

		if (mGraphicsQueueIndex == UINT32_MAX)
		{
			std::printf("Failed to find suitable graphics queue\n");
			return false;
		}

		if (mPhysicalDevice == VK_NULL_HANDLE)
		{
			std::printf("Failed to select a physical device\n");
			return false;
		}

		//print some information about our physical device
		vkutils::printDeviceInfo(mPhysicalDevice);

		//create logical device
		std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
		float queuePriority = 1.0f;
		VkDeviceQueueCreateInfo queueCreateInfo = {};
		queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
		queueCreateInfo.flags = 0;
		queueCreateInfo.queueFamilyIndex = mGraphicsQueueIndex;
		queueCreateInfo.queueCount = 1;
		queueCreateInfo.pQueuePriorities = &queuePriority;
		queueCreateInfos.push_back(queueCreateInfo);

		//need swap chain extension - this extension is already checked above with checkPhysicalDevice, no need to check again
		std::vector<const char*> requiredDeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };

		VkDeviceCreateInfo deviceCreateInfo = {};
		deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
		deviceCreateInfo.flags = 0;
		deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtensions.size());
		deviceCreateInfo.ppEnabledExtensionNames = requiredDeviceExtensions.data();
		deviceCreateInfo.queueCreateInfoCount = 1;
		deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
		deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());

		deviceCreateInfo.enabledLayerCount = 0;
		if (validationLayersEnabled)
		{
			deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
			deviceCreateInfo.ppEnabledLayerNames = validationLayers.data();
		}

		//create vulkan device
		//todo: for some reason NVidia drivers spew out vkCreateSampler errors here, find out why because we are not calling that function!
		result = vkCreateDevice(mPhysicalDevice, &deviceCreateInfo, mAllocCallback, &mDevice);
		if (result != VK_SUCCESS)
		{
			std::printf("vkCreateDevice failed\n");
			return false;
		}

		//grab graphics queue handle
		vkGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue);

		if (!mGraphicsQueue)
		{
			std::printf("Failed to retrieve graphics queue\n");
			return false;
		}

		return true;
	}

	ShaderHandle VulkanGraphicsDevice::createShader(const std::vector<ShaderDetails> &shaders)
	{
		return InvalidHandle;
	}

	BufferHandle VulkanGraphicsDevice::createBuffer(BufferType type, BufferUsageHint hint, size_t dataSize, float *data)
	{
		return InvalidHandle;
	}

	LayoutHandle VulkanGraphicsDevice::createVertexInputLayout(const std::vector<VertexInputLayout> &attributes)
	{
		return InvalidHandle;
	}

	VertexArrayHandle VulkanGraphicsDevice::createVAO(LayoutHandle layout, BufferHandle vertexBuffer, BufferHandle indexBuffer)
	{
		return InvalidHandle;
	}

	void VulkanGraphicsDevice::bindConstantBuffer(ShaderHandle shader, BufferHandle cBuffer, int32_t index)
	{
	}

	void VulkanGraphicsDevice::deleteVertexInputLayout(LayoutHandle handle)
	{
	}

	void VulkanGraphicsDevice::deleteVAO(VertexArrayHandle handle)
	{
	}

	void VulkanGraphicsDevice::deleteBuffer(BufferHandle handle)
	{
	}

	void VulkanGraphicsDevice::deleteShader(ShaderHandle handle)
	{
	}

	void VulkanGraphicsDevice::submitCommandQueue(CommandQueue *cmdQueue)
	{
	}

	void VulkanGraphicsDevice::present()
	{
	}
}<commit_msg>todo comment update<commit_after>//-----------------------------------------------------------------------------
// Jikken - 3D Abstract High Performance Graphics API
// Copyright(c) 2017 Jeff Hutchinson
// Copyright(c) 2017 Tim Barnes
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//-----------------------------------------------------------------------------

#include <cassert>
#include <cstdlib>
#include "vulkan/VulkanGraphicsDevice.hpp"
#include "vulkan/VulkanUtil.hpp"
//just temp
#include <GLFW/glfw3.h>

namespace Jikken
{
	VulkanGraphicsDevice::VulkanGraphicsDevice() :
		mInstance(VK_NULL_HANDLE),
		mSurface(VK_NULL_HANDLE),
		mPhysicalDevice(VK_NULL_HANDLE),
		mDevice(VK_NULL_HANDLE),
		mGraphicsQueue(VK_NULL_HANDLE),
		mGraphicsQueueIndex(UINT32_MAX),
		mDebugCallback(VK_NULL_HANDLE),
		mAllocCallback(nullptr)
	{
	}

	VulkanGraphicsDevice::~VulkanGraphicsDevice()
	{
		//wait for device to be idle
		if (mDevice)
			vkDeviceWaitIdle(mDevice);

		// cleanup other stuff

		// destroy logical device
		if (mDevice)
			vkDestroyDevice(mDevice, mAllocCallback);

		if (mSurface)
			vkDestroySurfaceKHR(mInstance, mSurface, mAllocCallback);

		if (mDebugCallback)
		{
			auto debugReportDestroyFunc = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(mInstance, "vkDestroyDebugReportCallbackEXT");
			if (debugReportDestroyFunc != nullptr)
			{
				debugReportDestroyFunc(mInstance, mDebugCallback, mAllocCallback);
			}
		}

		if (mInstance)
			vkDestroyInstance(mInstance, mAllocCallback);
	}

	bool VulkanGraphicsDevice::init(void *glfwWinHandle)
	{
		if (!glfwVulkanSupported())
		{
			std::printf("Vulkan is not supported\n");
		//	return false;
		}

		//validation layers
	#ifdef _DEBUG
		bool validationLayersEnabled = true;
	#else
		bool validationLayersEnabled = false
	#endif

		//grab vulkan instance extension list
		uint32_t extensionsCount = 0;
		VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &extensionsCount, nullptr);
		if (result != VK_SUCCESS || extensionsCount == 0)
		{
			std::printf("vkEnumerateInstanceExtensionProperties failed\n");
			return false;
		}

		std::vector<VkExtensionProperties> instanceExtensionList(extensionsCount);
		result = vkEnumerateInstanceExtensionProperties(nullptr, &extensionsCount, instanceExtensionList.data());

		if (result != VK_SUCCESS)
		{
			std::printf("vkEnumerateInstanceExtensionProperties failed\n");
			return false;
		}

		//get required extensions from glfw
		uint32_t glfwExtCount = 0;
		const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtCount);
		if (glfwExtCount == 0)
		{
			std::printf("Failed to find any required extensions\n");
			return false;
		}

		std::vector<const char*> requiredExtensions(glfwExtensions, glfwExtensions + glfwExtCount);

		if (validationLayersEnabled)
			requiredExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);

		// check required extension list against all availble extensions
		for (const auto &ext : requiredExtensions)
		{
			if (!vkutils::checkExtension(ext, instanceExtensionList))
			{
				std::printf("Required extension: %s not found\n", ext);
				return false;
			}
		}

		//setup validation layers - just VK_LAYER_LUNARG_standard_validation for now. There are plenty more though ;)
		const std::vector<const char*> validationLayers = { "VK_LAYER_LUNARG_standard_validation" };

		uint32_t layerCount = 0;

		if (validationLayersEnabled)
		{
			vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
			std::vector<VkLayerProperties> availableLayers(layerCount);
			vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());

			for (const auto &layer : validationLayers)
			{
				//this is not fatal so just disable validation layers if it is not found
				if (!vkutils::checkLayer(layer, availableLayers))
				{
					std::printf("Could not find validation layer: %s Disabling validation layers\n", layer);
					validationLayersEnabled = false;
				}
			}
		}

		//setup application and instance info
		VkApplicationInfo appInfo = {};
		appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
		appInfo.pApplicationName = "Jikken";
		appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
		appInfo.pEngineName = "Jikken";
		appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
		appInfo.apiVersion = VK_API_VERSION_1_0;

		VkInstanceCreateInfo createInfo = {};
		createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
		createInfo.flags = 0;
		createInfo.pApplicationInfo = &appInfo;
		createInfo.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size());
		createInfo.ppEnabledExtensionNames = requiredExtensions.data();
		if (validationLayersEnabled)
		{
			createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
			createInfo.ppEnabledLayerNames = validationLayers.data();
		}
		else
			createInfo.enabledLayerCount = 0;

		//finally create vulkan instance
		result = vkCreateInstance(&createInfo, mAllocCallback, &mInstance);

		if (result != VK_SUCCESS)
		{
			std::printf("vkCreateInstance failed\n");
			return false;
		}

		//setup debug callback if validation layers enabled
		if (validationLayersEnabled)
		{
			VkDebugReportCallbackCreateInfoEXT debugCreateInfo = {};
			debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
			debugCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
			debugCreateInfo.pfnCallback = vkutils::debugCallback;

			auto debugReportFunc = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(mInstance, "vkCreateDebugReportCallbackEXT");
			if (debugReportFunc != nullptr)
			{
				result = debugReportFunc(mInstance, &debugCreateInfo, mAllocCallback, &mDebugCallback);

				if (result != VK_SUCCESS)
				{
					std::printf("vkCreateDebugReportCallbackEXT failed\n");
					return false;
				}
			}
			else
			{
				std::printf("Failed to retrieve vkCreateDebugReportCallbackEXT address. Debug callbacks will be disabled\n");
				validationLayersEnabled = false;
			}
		}

		//create window surface
		result = glfwCreateWindowSurface(mInstance, static_cast<GLFWwindow*>(glfwWinHandle), mAllocCallback, &mSurface);
		if (result != VK_SUCCESS)
		{
			std::printf("Failed to create vulkan window surface\n");
			return false;
		}

		//find physical devices
		uint32_t numDevices = 0;
		result = vkEnumeratePhysicalDevices(mInstance, &numDevices, nullptr);
		if (result != VK_SUCCESS || numDevices == 0)
		{
			std::printf("vkEnumeratePhysicalDevices failed\n");
			return false;
		}

		std::vector<VkPhysicalDevice> physicalDevices(numDevices);
		result = vkEnumeratePhysicalDevices(mInstance, &numDevices, physicalDevices.data());
		if (result != VK_SUCCESS)
		{
			std::printf("vkEnumeratePhysicalDevices failed\n");
			return false;
		}

		//get our queue index and hopefully find an acceptable device
		for (const auto &device : physicalDevices)
		{
			//break on first acceptable device
			if (vkutils::checkPhysicalDevice(device, mSurface, mGraphicsQueueIndex))
			{
				mPhysicalDevice = device;
				break;
			}
		}

		if (mGraphicsQueueIndex == UINT32_MAX)
		{
			std::printf("Failed to find suitable graphics queue\n");
			return false;
		}

		if (mPhysicalDevice == VK_NULL_HANDLE)
		{
			std::printf("Failed to select a physical device\n");
			return false;
		}

		//print some information about our physical device
		vkutils::printDeviceInfo(mPhysicalDevice);

		//create logical device
		std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
		float queuePriority = 1.0f;
		VkDeviceQueueCreateInfo queueCreateInfo = {};
		queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
		queueCreateInfo.flags = 0;
		queueCreateInfo.queueFamilyIndex = mGraphicsQueueIndex;
		queueCreateInfo.queueCount = 1;
		queueCreateInfo.pQueuePriorities = &queuePriority;
		queueCreateInfos.push_back(queueCreateInfo);

		//need swap chain extension - this extension is already checked above with checkPhysicalDevice, no need to check again
		std::vector<const char*> requiredDeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };

		VkDeviceCreateInfo deviceCreateInfo = {};
		deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
		deviceCreateInfo.flags = 0;
		deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtensions.size());
		deviceCreateInfo.ppEnabledExtensionNames = requiredDeviceExtensions.data();
		deviceCreateInfo.queueCreateInfoCount = 1;
		deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
		deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());

		deviceCreateInfo.enabledLayerCount = 0;
		if (validationLayersEnabled)
		{
			deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
			deviceCreateInfo.ppEnabledLayerNames = validationLayers.data();
		}

		//create vulkan device
		//todo: for some reason this is creating vkCreateSampler errors here, find out why because we are not calling that function.
		//happens on both intel/nv drivers and also happens with lunarg demo, possible lunarg debug layer bug??
		result = vkCreateDevice(mPhysicalDevice, &deviceCreateInfo, mAllocCallback, &mDevice);
		if (result != VK_SUCCESS)
		{
			std::printf("vkCreateDevice failed\n");
			return false;
		}

		//grab graphics queue handle
		vkGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue);

		if (!mGraphicsQueue)
		{
			std::printf("Failed to retrieve graphics queue\n");
			return false;
		}

		return true;
	}

	ShaderHandle VulkanGraphicsDevice::createShader(const std::vector<ShaderDetails> &shaders)
	{
		return InvalidHandle;
	}

	BufferHandle VulkanGraphicsDevice::createBuffer(BufferType type, BufferUsageHint hint, size_t dataSize, float *data)
	{
		return InvalidHandle;
	}

	LayoutHandle VulkanGraphicsDevice::createVertexInputLayout(const std::vector<VertexInputLayout> &attributes)
	{
		return InvalidHandle;
	}

	VertexArrayHandle VulkanGraphicsDevice::createVAO(LayoutHandle layout, BufferHandle vertexBuffer, BufferHandle indexBuffer)
	{
		return InvalidHandle;
	}

	void VulkanGraphicsDevice::bindConstantBuffer(ShaderHandle shader, BufferHandle cBuffer, int32_t index)
	{
	}

	void VulkanGraphicsDevice::deleteVertexInputLayout(LayoutHandle handle)
	{
	}

	void VulkanGraphicsDevice::deleteVAO(VertexArrayHandle handle)
	{
	}

	void VulkanGraphicsDevice::deleteBuffer(BufferHandle handle)
	{
	}

	void VulkanGraphicsDevice::deleteShader(ShaderHandle handle)
	{
	}

	void VulkanGraphicsDevice::submitCommandQueue(CommandQueue *cmdQueue)
	{
	}

	void VulkanGraphicsDevice::present()
	{
	}
}<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

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

#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "otbImage.h"
#include "otbMeanDifferenceImageFilter.h"
#include "otbCommandProgressUpdate.h"

int otbMeanDiffChangeDetectionTest(int argc, char* argv[] )
{

  if ( argc < 5 )
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " inputImageFile1 inputImageFile2  radius outputImageFile " << std::endl;
    return -1;
  }

  // Define the dimension of the images
  const unsigned int Dimension = 2;

  // Declare the types of the images
  typedef double InternalPixelType;
  typedef double OutputPixelType;
  typedef otb::Image<InternalPixelType, Dimension>  InputImageType1;
  typedef otb::Image<InternalPixelType, Dimension>  InputImageType2;
  typedef otb::Image<InternalPixelType, Dimension>  ChangeImageType;
  typedef otb::Image<OutputPixelType, Dimension>  OutputImageType;

  typedef otb::ImageFileReader< InputImageType1 >  ReaderType1;
  typedef otb::ImageFileReader< InputImageType2 >  ReaderType2;
  typedef otb::ImageFileWriter< OutputImageType >  WriterType;
  typedef itk::RescaleIntensityImageFilter< ChangeImageType,
  OutputImageType > RescalerType;

  // Declare the type for the filter
  typedef otb::MeanDifferenceImageFilter<
  InputImageType1,
  InputImageType2,
  ChangeImageType  >       FilterType;

  ReaderType1::Pointer reader1 = ReaderType1::New();
  ReaderType2::Pointer reader2 = ReaderType2::New();
  WriterType::Pointer writer = WriterType::New();
  FilterType::Pointer   filter = FilterType::New();
  RescalerType::Pointer rescaler = RescalerType::New();

  const char * inputFilename1  = argv[1];
  const char * inputFilename2  = argv[2];
  const char * outputFilename = argv[4];

  reader1->SetFileName( inputFilename1  );
  reader2->SetFileName( inputFilename2  );
  writer->SetFileName( outputFilename );
  rescaler->SetOutputMinimum( 0 );
  rescaler->SetOutputMaximum( 255 );

  filter->SetInput1( reader1->GetOutput() );
  filter->SetInput2( reader2->GetOutput() );
  filter->SetRadius( atoi(argv[3]) );

  rescaler->SetInput( filter->GetOutput() );
  writer->SetInput( rescaler->GetOutput() );

  typedef otb::CommandProgressUpdate<FilterType> CommandType;

  CommandType::Pointer observer = CommandType::New();
  filter->AddObserver(itk::ProgressEvent(), observer);

  writer->Update();

  return EXIT_SUCCESS;

}

<commit_msg>ENH : revert changes on meandiff test<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

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

#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "otbImage.h"
#include "otbMeanDifferenceImageFilter.h"
#include "otbCommandProgressUpdate.h"

int otbMeanDiffChangeDetectionTest(int argc, char* argv[] )
{

  if ( argc < 5 )
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " inputImageFile1 inputImageFile2  radius outputImageFile " << std::endl;
    return -1;
  }

  // Define the dimension of the images
  const unsigned int Dimension = 2;

  // Declare the types of the images
  typedef double InternalPixelType;
  typedef double OutputPixelType;
  typedef otb::Image<InternalPixelType, Dimension>  InputImageType1;
  typedef otb::Image<InternalPixelType, Dimension>  InputImageType2;
  typedef otb::Image<InternalPixelType, Dimension>  ChangeImageType;
  typedef otb::Image<OutputPixelType, Dimension>  OutputImageType;

  typedef otb::ImageFileReader< InputImageType1 >  ReaderType1;
  typedef otb::ImageFileReader< InputImageType2 >  ReaderType2;
  typedef otb::ImageFileWriter< OutputImageType >  WriterType;
  typedef itk::RescaleIntensityImageFilter< ChangeImageType,
  OutputImageType > RescalerType;

  // Declare the type for the filter
  typedef otb::MeanDifferenceImageFilter<
  InputImageType1,
  InputImageType2,
  ChangeImageType  >       FilterType;

  ReaderType1::Pointer reader1 = ReaderType1::New();
  ReaderType2::Pointer reader2 = ReaderType2::New();
  WriterType::Pointer writer = WriterType::New();
  FilterType::Pointer   filter = FilterType::New();
  RescalerType::Pointer rescaler = RescalerType::New();

  const char * inputFilename1  = argv[1];
  const char * inputFilename2  = argv[2];
  const char * outputFilename = argv[4];

  reader1->SetFileName( inputFilename1  );
  reader2->SetFileName( inputFilename2  );
  writer->SetFileName( outputFilename );
  rescaler->SetOutputMinimum( -1 );
  rescaler->SetOutputMaximum( 1 );

  filter->SetInput1( reader1->GetOutput() );
  filter->SetInput2( reader2->GetOutput() );
  filter->SetRadius( atoi(argv[3]) );

  rescaler->SetInput( filter->GetOutput() );
  writer->SetInput( rescaler->GetOutput() );

  typedef otb::CommandProgressUpdate<FilterType> CommandType;

  CommandType::Pointer observer = CommandType::New();
  filter->AddObserver(itk::ProgressEvent(), observer);

  writer->Update();

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>// SafeArryGUID.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <objbase.h>
#include <string>
#include<atlsafe.h>
#include<iostream>
using namespace std;

string GuidToString(const GUID &guid)
{
	char buf[64] = { 0 };
	sprintf_s(buf, sizeof(buf), "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
		guid.Data1, guid.Data2, guid.Data3,
		guid.Data4[0], guid.Data4[1],
		guid.Data4[2], guid.Data4[3],
		guid.Data4[4], guid.Data4[5],
		guid.Data4[6], guid.Data4[7]);
	return string(buf);
}

void Put1GuidInSafeArry()
{
	GUID guid;
	CoCreateGuid(&guid);

	auto guidStri = GuidToString(guid);

	cout << guidStri << endl;

	//TODO... put the guid into safearry..
	SAFEARRAY* p_safe_arry;
	SAFEARRAYBOUND safe_arry_bound[2] = { 0 };
	auto guidsize = sizeof(GUID);
	safe_arry_bound[0].cElements = guidsize;
	safe_arry_bound[0].lLbound = 0;
	safe_arry_bound[1].cElements = guidsize;
	safe_arry_bound[1].lLbound = 0;

	p_safe_arry = SafeArrayCreate(VT_ARRAY, 1, safe_arry_bound);
	auto pnData = reinterpret_cast<char*>(p_safe_arry->pvData);
	memcpy_s(pnData, guidsize, guidStri.c_str(), guidsize);
	//TODO...
	//do something..
	SafeArrayDestroy(p_safe_arry);
}

void Put2GuidInSafeArry()
{
	GUID guid, guid2;
	CoCreateGuid(&guid);
	CoCreateGuid(&guid2);

	//TODO... put the guid into safearry..
	SAFEARRAY* p_safe_arry;
	SAFEARRAYBOUND safe_arry_bound[2] = { 0 };
	safe_arry_bound[0].cElements = 2;
	safe_arry_bound[0].lLbound = 0;
	safe_arry_bound[1].cElements = 16;
	safe_arry_bound[1].lLbound = 0;

	p_safe_arry = SafeArrayCreate(VT_CLSID, 2, safe_arry_bound);
	auto pnData = reinterpret_cast<GUID*>(p_safe_arry->pvData);
	pnData[0] = guid;
	pnData[1] = guid2;
	//TODO...
	//do something..
	//TODO...

	SafeArrayDestroy(p_safe_arry);
}

void Put1GuidInSafeArryByStack()
{
	GUID guid;

	//TODO... put the guid into safearry..
	SAFEARRAY* pArray = nullptr;
	auto hr = SafeArrayAllocDescriptorEx(VT_CLSID, 1, &pArray);
	pArray->cbElements = sizeof(GUID);
	pArray->rgsabound[0].cElements = 1;
	pArray->rgsabound[0].lLbound = 16;
	pArray->pvData = &guid;
	pArray->fFeatures = FADF_AUTO;
	//_bstr_t bstr;
}

void CComSafeArrayGUID()
{
	//CComSafeArray<GUID> comsafeguid(10);
}

void LearnSafeArray()
{
	SAFEARRAY *pArray = nullptr;
	HRESULT hr = SafeArrayAllocDescriptor(1, &pArray);//SAFEARRAYṹĶ
	pArray->cbElements = sizeof(GUID);
	pArray->rgsabound[0].cElements = 10;
	pArray->rgsabound[0].lLbound = 0;

	GUID guid, guid2;
	CoCreateGuid(&guid);
	CoCreateGuid(&guid2);
	GUID _guidarr[] = { guid,guid2 };
	pArray->pvData = _guidarr;
	pArray->fFeatures = FADF_AUTO | FADF_FIXEDSIZE;

	//CComSafeArray<VARIANT> saguid;
//	saguid.Attach(pArray);

	//auto count = saguid.GetCount();

	//auto t = saguid.GetType();

	GUID* p_GUIDArry = nullptr;
	SafeArrayAccessData(pArray, (PVOID*)&p_GUIDArry);

	auto retv = p_GUIDArry[0];
	auto retv1 = p_GUIDArry[1];

	long Low(0), High(0);
	hr = SafeArrayGetLBound(pArray, 1, &Low);//ά1ʼ
	hr = SafeArrayGetUBound(pArray, 1, &High);//ά1ʼ

	SafeArrayUnaccessData(pArray);
	SafeArrayDestroy(pArray);

	cin.get();
}

void TestSafeArry()
{
	LearnSafeArray();
	//CComSafeArrayBound bound(2);
	//CComSafeArray<GUID>  guid_Array;
	//GUID guid, guid2;
	//CoCreateGuid(&guid);
	//CoCreateGuid(&guid2);
	//guid_Array.Add(guid);
	//guid_Array.Add(guid2);

	//auto count = guid_Array.GetCount();
	//auto demention = guid_Array.GetDimensions();
	//auto upperbound = guid_Array.GetUpperBound();
	//auto p_safeArry = &guid_Array;
	//GUID guid3;
	//CoCreateGuid(&guid3);
	//p_safeArry->SetAt(1, guid3);
}

int _tmain(int argc, _TCHAR* argv[])
{
	TestSafeArry();
	Put1GuidInSafeArry();
	Put2GuidInSafeArry();
	Put1GuidInSafeArryByStack();
	return 0;
}<commit_msg>update GUID using...<commit_after>// SafeArryGUID.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <objbase.h>
#include <string>
#include<atlsafe.h>
#include<iostream>
using namespace std;

string GuidToString(const GUID &guid)
{
	char buf[64] = { 0 };
	sprintf_s(buf, sizeof(buf), "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
		guid.Data1, guid.Data2, guid.Data3,
		guid.Data4[0], guid.Data4[1],
		guid.Data4[2], guid.Data4[3],
		guid.Data4[4], guid.Data4[5],
		guid.Data4[6], guid.Data4[7]);
	return string(buf);
}

void Put1GuidInSafeArry()
{
	GUID guid;
	CoCreateGuid(&guid);

	auto guidStri = GuidToString(guid);

	cout << guidStri << endl;

	//TODO... put the guid into safearry..
	SAFEARRAY* p_safe_arry;
	SAFEARRAYBOUND safe_arry_bound[2] = { 0 };
	auto guidsize = sizeof(GUID);
	safe_arry_bound[0].cElements = guidsize;
	safe_arry_bound[0].lLbound = 0;
	safe_arry_bound[1].cElements = guidsize;
	safe_arry_bound[1].lLbound = 0;

	p_safe_arry = SafeArrayCreate(VT_ARRAY, 1, safe_arry_bound);
	auto pnData = reinterpret_cast<char*>(p_safe_arry->pvData);
	memcpy_s(pnData, guidsize, guidStri.c_str(), guidsize);
	//TODO...
	//do something..
	SafeArrayDestroy(p_safe_arry);
}

void Put2GuidInSafeArry()
{
	GUID guid, guid2;
	CoCreateGuid(&guid);
	CoCreateGuid(&guid2);

	//TODO... put the guid into safearry..
	SAFEARRAY* p_safe_arry;
	SAFEARRAYBOUND safe_arry_bound[1] = { 0 };
	safe_arry_bound[0].cElements = 5;
	safe_arry_bound[0].lLbound = 0;

	p_safe_arry = SafeArrayCreate(VT_VARIANT, 1, safe_arry_bound);

	long Low(0), High(0);
	SafeArrayGetLBound(p_safe_arry, 1, &Low);
	SafeArrayGetUBound(p_safe_arry, 1, &High);

	////p_safe_arry->cbElements = sizeof(GUID);
	//long lDimension;
	//lDimension = 0;
	//SafeArrayPutElement(p_safe_arry, &lDimension, &guid);
	//lDimension = 1;

	//SafeArrayPutElement(p_safe_arry, &lDimension, &guid2);
	////TODO...
	//GUID guidout = { 0 };
	//SafeArrayGetElement(p_safe_arry, &lDimension, &guidout);

	GUID* pData = NULL;
	HRESULT hr = SafeArrayAccessData(p_safe_arry, (void**)&pData);
	pData[0] = guid;
	pData[1] = guid2;
	//TODO...
	SafeArrayUnaccessData(p_safe_arry);
	SafeArrayDestroy(p_safe_arry);
}

void Put1GuidInSafeArryByStack()
{
	GUID guid;

	//TODO... put the guid into safearry..
	SAFEARRAY* pArray = nullptr;
	auto hr = SafeArrayAllocDescriptorEx(VT_CLSID, 1, &pArray);
	pArray->cbElements = sizeof(GUID);
	pArray->rgsabound[0].cElements = 1;
	pArray->rgsabound[0].lLbound = 16;
	pArray->pvData = &guid;
	pArray->fFeatures = FADF_AUTO;
	//_bstr_t bstr;
}

void CComSafeArrayGUID()
{
	//CComSafeArray<GUID> comsafeguid(10);
}

void LearnSafeArray()
{
	SAFEARRAY *pArray = nullptr;
	HRESULT hr = SafeArrayAllocDescriptor(1, &pArray);//SAFEARRAYṹĶ
	pArray->cbElements = sizeof(GUID);
	pArray->rgsabound[0].cElements = 10;
	pArray->rgsabound[0].lLbound = 0;

	GUID guid, guid2;
	CoCreateGuid(&guid);
	CoCreateGuid(&guid2);
	GUID _guidarr[] = { guid,guid2 };
	pArray->pvData = _guidarr;
	pArray->fFeatures = FADF_AUTO | FADF_FIXEDSIZE;

	//CComSafeArray<VARIANT> saguid;
//	saguid.Attach(pArray);

	//auto count = saguid.GetCount();

	//auto t = saguid.GetType();

	GUID* p_GUIDArry = nullptr;
	SafeArrayAccessData(pArray, (PVOID*)&p_GUIDArry);

	auto retv = p_GUIDArry[0];
	auto retv1 = p_GUIDArry[1];

	long Low(0), High(0);
	hr = SafeArrayGetLBound(pArray, 1, &Low);//ά1ʼ
	hr = SafeArrayGetUBound(pArray, 1, &High);//ά1ʼ

	SafeArrayUnaccessData(pArray);
	SafeArrayDestroy(pArray);

	//	cin.get();
}

void TestSafeArry()
{
	LearnSafeArray();
	//CComSafeArrayBound bound(2);
	//CComSafeArray<GUID>  guid_Array;
	//GUID guid, guid2;
	//CoCreateGuid(&guid);
	//CoCreateGuid(&guid2);
	//guid_Array.Add(guid);
	//guid_Array.Add(guid2);

	//auto count = guid_Array.GetCount();
	//auto demention = guid_Array.GetDimensions();
	//auto upperbound = guid_Array.GetUpperBound();
	//auto p_safeArry = &guid_Array;
	//GUID guid3;
	//CoCreateGuid(&guid3);
	//p_safeArry->SetAt(1, guid3);
}

int _tmain(int argc, _TCHAR* argv[])
{
	TestSafeArry();
	//Put1GuidInSafeArry();
	Put2GuidInSafeArry();
	Put1GuidInSafeArryByStack();
	return 0;
}<|endoftext|>


<commit_before>// SafeArryGUID.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <objbase.h>
#include <string>
#include<atlsafe.h>
#include<iostream>
using namespace std;

string GuidToString(const GUID &guid)
{
	char buf[64] = { 0 };
	sprintf_s(buf, sizeof(buf), "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
		guid.Data1, guid.Data2, guid.Data3,
		guid.Data4[0], guid.Data4[1],
		guid.Data4[2], guid.Data4[3],
		guid.Data4[4], guid.Data4[5],
		guid.Data4[6], guid.Data4[7]);
	return string(buf);
}

void Put1GuidInSafeArry()
{
	GUID guid;
	CoCreateGuid(&guid);

	auto guidStri = GuidToString(guid);

	cout << guidStri << endl;

	//TODO... put the guid into safearry..
	SAFEARRAY* p_safe_arry;
	SAFEARRAYBOUND safe_arry_bound[2] = { 0 };
	auto guidsize = sizeof(GUID);
	safe_arry_bound[0].cElements = guidsize;
	safe_arry_bound[0].lLbound = 0;
	safe_arry_bound[1].cElements = guidsize;
	safe_arry_bound[1].lLbound = 0;

	p_safe_arry = SafeArrayCreate(VT_ARRAY, 1, safe_arry_bound);
	auto pnData = reinterpret_cast<char*>(p_safe_arry->pvData);
	memcpy_s(pnData, guidsize, guidStri.c_str(), guidsize);
	//TODO...
	//do something..
	SafeArrayDestroy(p_safe_arry);
}

void Put2GuidInSafeArry()
{
	GUID guid, guid2;
	CoCreateGuid(&guid);
	CoCreateGuid(&guid2);

	//TODO... put the guid into safearry..
	SAFEARRAY* p_safe_arry;
	SAFEARRAYBOUND safe_arry_bound[2] = { 0 };
	safe_arry_bound[0].cElements = 2;
	safe_arry_bound[0].lLbound = 0;
	safe_arry_bound[1].cElements = 16;
	safe_arry_bound[1].lLbound = 0;

	p_safe_arry = SafeArrayCreate(VT_CLSID, 2, safe_arry_bound);
	auto pnData = reinterpret_cast<GUID*>(p_safe_arry->pvData);
	pnData[0] = guid;
	pnData[1] = guid2;
	//TODO...
	//do something..
	//TODO...

	SafeArrayDestroy(p_safe_arry);
}

void Put1GuidInSafeArryByStack()
{
	GUID guid;

	//TODO... put the guid into safearry..
	SAFEARRAY* pArray = nullptr;
	auto hr = SafeArrayAllocDescriptorEx(VT_CLSID, 1, &pArray);
	pArray->cbElements = sizeof(GUID);
	pArray->rgsabound[0].cElements = 1;
	pArray->rgsabound[0].lLbound = 16;
	pArray->pvData = &guid;
	pArray->fFeatures = FADF_AUTO;
	//_bstr_t bstr;
}

void CComSafeArrayGUID()
{
	//CComSafeArray<GUID> comsafeguid(10);
}

void LearnSafeArray()
{
	VARIANT var_Chunk;
	SAFEARRAY *psa;
	SAFEARRAYBOUND rgsabund[1];

	rgsabund[0].cElements = sizeof(GUID);
	rgsabund[0].lLbound = 0;

	//psa = SafeArrayCreate(VT_UI1,1,rgsabund);

	var_Chunk.vt = VT_RECORD | VT_ARRAY;
	//var_Chunk.parray =
}

int _tmain(int argc, _TCHAR* argv[])
{
	Put1GuidInSafeArry();
	Put1GuidInSafeArry();
	Put1GuidInSafeArryByStack();
	return 0;
}<commit_msg>update<commit_after>// SafeArryGUID.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <objbase.h>
#include <string>
#include<atlsafe.h>
#include<iostream>
using namespace std;

string GuidToString(const GUID &guid)
{
	char buf[64] = { 0 };
	sprintf_s(buf, sizeof(buf), "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
		guid.Data1, guid.Data2, guid.Data3,
		guid.Data4[0], guid.Data4[1],
		guid.Data4[2], guid.Data4[3],
		guid.Data4[4], guid.Data4[5],
		guid.Data4[6], guid.Data4[7]);
	return string(buf);
}

void Put1GuidInSafeArry()
{
	GUID guid;
	CoCreateGuid(&guid);

	auto guidStri = GuidToString(guid);

	cout << guidStri << endl;

	//TODO... put the guid into safearry..
	SAFEARRAY* p_safe_arry;
	SAFEARRAYBOUND safe_arry_bound[2] = { 0 };
	auto guidsize = sizeof(GUID);
	safe_arry_bound[0].cElements = guidsize;
	safe_arry_bound[0].lLbound = 0;
	safe_arry_bound[1].cElements = guidsize;
	safe_arry_bound[1].lLbound = 0;

	p_safe_arry = SafeArrayCreate(VT_ARRAY, 1, safe_arry_bound);
	auto pnData = reinterpret_cast<char*>(p_safe_arry->pvData);
	memcpy_s(pnData, guidsize, guidStri.c_str(), guidsize);
	//TODO...
	//do something..
	SafeArrayDestroy(p_safe_arry);
}

void Put2GuidInSafeArry()
{
	GUID guid, guid2;
	CoCreateGuid(&guid);
	CoCreateGuid(&guid2);

	//TODO... put the guid into safearry..
	SAFEARRAY* p_safe_arry;
	SAFEARRAYBOUND safe_arry_bound[2] = { 0 };
	safe_arry_bound[0].cElements = 2;
	safe_arry_bound[0].lLbound = 0;
	safe_arry_bound[1].cElements = 16;
	safe_arry_bound[1].lLbound = 0;

	p_safe_arry = SafeArrayCreate(VT_CLSID, 2, safe_arry_bound);
	auto pnData = reinterpret_cast<GUID*>(p_safe_arry->pvData);
	pnData[0] = guid;
	pnData[1] = guid2;
	//TODO...
	//do something..
	//TODO...

	SafeArrayDestroy(p_safe_arry);
}

void Put1GuidInSafeArryByStack()
{
	GUID guid;

	//TODO... put the guid into safearry..
	SAFEARRAY* pArray = nullptr;
	auto hr = SafeArrayAllocDescriptorEx(VT_CLSID, 1, &pArray);
	pArray->cbElements = sizeof(GUID);
	pArray->rgsabound[0].cElements = 1;
	pArray->rgsabound[0].lLbound = 16;
	pArray->pvData = &guid;
	pArray->fFeatures = FADF_AUTO;
	//_bstr_t bstr;
}

void CComSafeArrayGUID()
{
	//CComSafeArray<GUID> comsafeguid(10);
}

void LearnSafeArray()
{
	VARIANT var_Chunk;
	SAFEARRAY *psa;
	SAFEARRAYBOUND rgsabund[1];

	rgsabund[0].cElements = sizeof(GUID);
	rgsabund[0].lLbound = 0;

	//psa = SafeArrayCreate(VT_UI1,1,rgsabund);

	var_Chunk.vt = VT_RECORD | VT_ARRAY;
	//var_Chunk.parray =
}

int _tmain(int argc, _TCHAR* argv[])
{
	Put1GuidInSafeArry();
	Put2GuidInSafeArry();
	Put1GuidInSafeArryByStack();
	return 0;
}<|endoftext|>


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

#ifndef QVLC_CONTROLLER_H_
#define QVLC_CONTROLLER_H_

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "qt4.hpp"

#include <QFrame>
#include <QString>
#include <QSizeGrip>

#define MAIN_TB1_DEFAULT "64;39;64;38;65"
#define MAIN_TB2_DEFAULT "0-2;64;3;1;4;64;7;9;64;10;20;19;64-4;37;65;35-4"
#define ADV_TB_DEFAULT "12;11;13;14"
#define INPT_TB_DEFAULT "5-1;15-1;33;6-1"
#define FSC_TB_DEFAULT "0-2;64;3;1;4;64;37;64;38;64;8;65;35-4;34"

#define I_PLAY_TOOLTIP N_("Play\nIf the playlist is empty, open a medium")

class QPixmap;
class QLabel;

class QGridLayout;
class QHBoxLayout;
class QBoxLayout;

class QAbstractSlider;
class QAbstractButton;
class SeekSlider;
class QToolButton;

class VolumeClickHandler;
class WidgetListing;

class QSignalMapper;
class QTimer;

typedef enum buttonType_e
{
    PLAY_BUTTON,
    STOP_BUTTON,
    OPEN_BUTTON,
    PREV_SLOW_BUTTON,
    NEXT_FAST_BUTTON,
    SLOWER_BUTTON,
    FASTER_BUTTON,
    FULLSCREEN_BUTTON,
    DEFULLSCREEN_BUTTON,
    EXTENDED_BUTTON,
    PLAYLIST_BUTTON,
    SNAPSHOT_BUTTON,
    RECORD_BUTTON,
    ATOB_BUTTON,
    FRAME_BUTTON,
    REVERSE_BUTTON,
    SKIP_BACK_BUTTON,
    SKIP_FW_BUTTON,
    QUIT_BUTTON,
    RANDOM_BUTTON,
    LOOP_BUTTON,
    INFO_BUTTON,
    PREVIOUS_BUTTON,
    NEXT_BUTTON,
    OPEN_SUB_BUTTON,
    BUTTON_MAX,

    SPLITTER = 0x20,
    INPUT_SLIDER,
    TIME_LABEL,
    VOLUME,
    VOLUME_SPECIAL,
    MENU_BUTTONS,
    TELETEXT_BUTTONS,
    ADVANCED_CONTROLLER,
    PLAYBACK_BUTTONS,
    SPECIAL_MAX,

    WIDGET_SPACER = 0x40,
    WIDGET_SPACER_EXTEND,
    WIDGET_MAX,
} buttonType_e;

static const char* const nameL[BUTTON_MAX] = { N_("Play"), N_("Stop"), N_("Open"),
    N_("Previous/Backward"), N_("Next/Forward"), N_("Slower"), N_("Faster"), N_("Fullscreen"),
   N_("De-Fullscreen"), N_("Extended panel"), N_("Playlist"), N_("Snapshot"),
   N_("Record"), N_("A->B Loop"), N_("Frame By Frame"), N_("Trickplay Reverse"),
   N_("Step backward" ), N_("Step forward"), N_("Quit"), N_("Random"),
   N_("Loop/Repeat mode"), N_("Information"), N_("Previous"), N_("Next"),
   N_("Open subtitles file")};
static const char* const tooltipL[BUTTON_MAX] = { I_PLAY_TOOLTIP,
    N_("Stop playback"), N_("Open a medium"),
    N_("Previous media in the playlist, skip backward when keep-pressed"),
    N_("Next media in the playlist, skip forward when keep-pressed"), N_("Slower"), N_("Faster"),
    N_("Toggle the video in fullscreen"), N_("Toggle the video out fullscreen"),
    N_("Show extended settings" ), N_( "Show playlist" ),
    N_( "Take a snapshot" ), N_( "Record" ),
    N_( "Loop from point A to point B continuously." ), N_("Frame by frame"),
    N_("Reverse"), N_("Step backward"), N_("Step forward"), N_("Quit"),
    N_("Random"), N_("Change the loop and repeat modes"), N_("Information"),
    N_("Previous media in the playlist"), N_("Next media in the playlist"),
    N_("Open subtitles file")};
static const QString iconL[BUTTON_MAX] ={ ":/toolbar/play_b", ":/toolbar/stop_b",
    ":/toolbar/eject", ":/toolbar/previous_b", ":/toolbar/next_b",
    ":/toolbar/slower", ":/toolbar/faster", ":/toolbar/fullscreen",
    ":/toolbar/defullscreen", ":/toolbar/extended", ":/toolbar/playlist",
    ":/toolbar/snapshot", ":/toolbar/record", ":/toolbar/atob_nob",
    ":/toolbar/frame", ":/toolbar/reverse", ":/toolbar/skip_back",
    ":/toolbar/skip_fw", ":/toolbar/clear", ":/buttons/playlist/shuffle_on",
    ":/buttons/playlist/repeat_all", ":/menu/info",
    ":/toolbar/previous_b", ":/toolbar/next_b", "" };

enum
{
   WIDGET_NORMAL = 0x0,
   WIDGET_FLAT   = 0x1,
   WIDGET_BIG    = 0x2,
   WIDGET_SHINY  = 0x4,
};

class AdvControlsWidget;
class AbstractController : public QFrame
{
    friend class WidgetListing; /* For ToolBar Edition HACKS */

    Q_OBJECT
public:
    AbstractController( intf_thread_t  *_p_i, QWidget *_parent = 0 );

protected:
    intf_thread_t       *p_intf;

    QSignalMapper       *toolbarActionsMapper;
    QHBoxLayout         *controlLayout;
    /* Change to BoxLayout if both dir are needed */

    AdvControlsWidget   *advControls;

    void parseAndCreate( const QString& config, QBoxLayout *controlLayout );

    virtual void createAndAddWidget( QBoxLayout *controlLayout, int i_index,
                                     buttonType_e i_type, int i_option );

    QWidget *createWidget( buttonType_e, int options = WIDGET_NORMAL );
private:
    static void setupButton( QAbstractButton * );
    QFrame *discFrame();
    QFrame *telexFrame();
    void applyAttributes( QToolButton *, bool b_flat, bool b_big );

    QHBoxLayout         *buttonGroupLayout;
protected slots:
    virtual void setStatus( int );

signals:
    void inputExists( bool ); /// This might be useful in the IM ?
    void inputPlaying( bool ); /// This might be useful in the IM ?
    void inputIsRecordable( bool ); /// same ?
    void inputIsTrickPlayable( bool ); /// same ?
};

/* Advanced Button Bar */
class AdvControlsWidget : public AbstractController
{
    Q_OBJECT
public:
    AdvControlsWidget( intf_thread_t *, QWidget *_parent = 0 );
};

/* Slider Bar */
class InputControlsWidget : public AbstractController
{
    Q_OBJECT
public:
    InputControlsWidget( intf_thread_t * , QWidget *_parent = 0 );
};

/* Button Bar */
class ControlsWidget : public AbstractController
{
    Q_OBJECT
public:
    /* p_intf, advanced control visible or not, blingbling or not */
    ControlsWidget( intf_thread_t *_p_i, bool b_advControls,
                    QWidget *_parent = 0 );

    void setGripVisible( bool b_visible )
    { grip->setVisible( b_visible ); }

protected:
    friend class MainInterface;

    bool b_advancedVisible;

private:
    QSizeGrip *grip;

protected slots:
    void toggleAdvanced();

signals:
    void advancedControlsToggled( bool );
};

/* to trying transparency with fullscreen controller on windows enable that */
/* it can be enabled on-non windows systems,
   but it will be transparent only with composite manager */
#define HAVE_TRANSPARENCY 1

/* Default value of opacity for FS controller */
#define DEFAULT_OPACITY 0.70

/***********************************
 * Fullscreen controller
 ***********************************/
class FullscreenControllerWidget : public AbstractController
{
    Q_OBJECT
public:
    FullscreenControllerWidget( intf_thread_t *, QWidget *_parent = 0  );
    virtual ~FullscreenControllerWidget();

    /* Vout */
    void fullscreenChanged( vout_thread_t *, bool b_fs, int i_timeout );
    void mouseChanged( vout_thread_t *, int i_mousex, int i_mousey );

signals:
    void keyPressed( QKeyEvent * );

public slots:
    void setVoutList( vout_thread_t **, int );

protected:
    friend class MainInterface;

    virtual void mouseMoveEvent( QMouseEvent *event );
    virtual void mousePressEvent( QMouseEvent *event );
    virtual void mouseReleaseEvent( QMouseEvent *event );
    virtual void enterEvent( QEvent *event );
    virtual void leaveEvent( QEvent *event );
    virtual void keyPressEvent( QKeyEvent *event );

private slots:
    void showFSC();
    void planHideFSC();
    void hideFSC() { hide(); }
    void slowHideFSC();
    void centerFSC( int );

private:
    virtual void customEvent( QEvent *event );

    QTimer *p_hideTimer;
#if HAVE_TRANSPARENCY
    QTimer *p_slowHideTimer;
    bool b_slow_hide_begin;
    int  i_slow_hide_timeout;
    float f_opacity;
#endif

    int i_mouse_last_x, i_mouse_last_y;
    bool b_mouse_over;
    int i_screennumber;
    QRect screenRes;

    /* List of vouts currently tracked */
    QList<vout_thread_t *> vout;

    /* Shared variable between FSC and VLC (protected by a lock) */
    vlc_mutex_t lock;
    bool        b_fullscreen;
    int         i_hide_timeout;  /* FSC hiding timeout, same as mouse hiding timeout */
    int i_mouse_last_move_x;
    int i_mouse_last_move_y;
};

#endif
<commit_msg>Qt: Fix protectedness of customEvent<commit_after>/*****************************************************************************
 * Controller.hpp : Controller for the main interface
 ****************************************************************************
 * Copyright (C) 2006-2008 the VideoLAN team
 * $Id$
 *
 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifndef QVLC_CONTROLLER_H_
#define QVLC_CONTROLLER_H_

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "qt4.hpp"

#include <QFrame>
#include <QString>
#include <QSizeGrip>

#define MAIN_TB1_DEFAULT "64;39;64;38;65"
#define MAIN_TB2_DEFAULT "0-2;64;3;1;4;64;7;9;64;10;20;19;64-4;37;65;35-4"
#define ADV_TB_DEFAULT "12;11;13;14"
#define INPT_TB_DEFAULT "5-1;15-1;33;6-1"
#define FSC_TB_DEFAULT "0-2;64;3;1;4;64;37;64;38;64;8;65;35-4;34"

#define I_PLAY_TOOLTIP N_("Play\nIf the playlist is empty, open a medium")

class QPixmap;
class QLabel;

class QGridLayout;
class QHBoxLayout;
class QBoxLayout;

class QAbstractSlider;
class QAbstractButton;
class SeekSlider;
class QToolButton;

class VolumeClickHandler;
class WidgetListing;

class QSignalMapper;
class QTimer;

typedef enum buttonType_e
{
    PLAY_BUTTON,
    STOP_BUTTON,
    OPEN_BUTTON,
    PREV_SLOW_BUTTON,
    NEXT_FAST_BUTTON,
    SLOWER_BUTTON,
    FASTER_BUTTON,
    FULLSCREEN_BUTTON,
    DEFULLSCREEN_BUTTON,
    EXTENDED_BUTTON,
    PLAYLIST_BUTTON,
    SNAPSHOT_BUTTON,
    RECORD_BUTTON,
    ATOB_BUTTON,
    FRAME_BUTTON,
    REVERSE_BUTTON,
    SKIP_BACK_BUTTON,
    SKIP_FW_BUTTON,
    QUIT_BUTTON,
    RANDOM_BUTTON,
    LOOP_BUTTON,
    INFO_BUTTON,
    PREVIOUS_BUTTON,
    NEXT_BUTTON,
    OPEN_SUB_BUTTON,
    BUTTON_MAX,

    SPLITTER = 0x20,
    INPUT_SLIDER,
    TIME_LABEL,
    VOLUME,
    VOLUME_SPECIAL,
    MENU_BUTTONS,
    TELETEXT_BUTTONS,
    ADVANCED_CONTROLLER,
    PLAYBACK_BUTTONS,
    SPECIAL_MAX,

    WIDGET_SPACER = 0x40,
    WIDGET_SPACER_EXTEND,
    WIDGET_MAX,
} buttonType_e;

static const char* const nameL[BUTTON_MAX] = { N_("Play"), N_("Stop"), N_("Open"),
    N_("Previous/Backward"), N_("Next/Forward"), N_("Slower"), N_("Faster"), N_("Fullscreen"),
   N_("De-Fullscreen"), N_("Extended panel"), N_("Playlist"), N_("Snapshot"),
   N_("Record"), N_("A->B Loop"), N_("Frame By Frame"), N_("Trickplay Reverse"),
   N_("Step backward" ), N_("Step forward"), N_("Quit"), N_("Random"),
   N_("Loop/Repeat mode"), N_("Information"), N_("Previous"), N_("Next"),
   N_("Open subtitles file")};
static const char* const tooltipL[BUTTON_MAX] = { I_PLAY_TOOLTIP,
    N_("Stop playback"), N_("Open a medium"),
    N_("Previous media in the playlist, skip backward when keep-pressed"),
    N_("Next media in the playlist, skip forward when keep-pressed"), N_("Slower"), N_("Faster"),
    N_("Toggle the video in fullscreen"), N_("Toggle the video out fullscreen"),
    N_("Show extended settings" ), N_( "Show playlist" ),
    N_( "Take a snapshot" ), N_( "Record" ),
    N_( "Loop from point A to point B continuously." ), N_("Frame by frame"),
    N_("Reverse"), N_("Step backward"), N_("Step forward"), N_("Quit"),
    N_("Random"), N_("Change the loop and repeat modes"), N_("Information"),
    N_("Previous media in the playlist"), N_("Next media in the playlist"),
    N_("Open subtitles file")};
static const QString iconL[BUTTON_MAX] ={ ":/toolbar/play_b", ":/toolbar/stop_b",
    ":/toolbar/eject", ":/toolbar/previous_b", ":/toolbar/next_b",
    ":/toolbar/slower", ":/toolbar/faster", ":/toolbar/fullscreen",
    ":/toolbar/defullscreen", ":/toolbar/extended", ":/toolbar/playlist",
    ":/toolbar/snapshot", ":/toolbar/record", ":/toolbar/atob_nob",
    ":/toolbar/frame", ":/toolbar/reverse", ":/toolbar/skip_back",
    ":/toolbar/skip_fw", ":/toolbar/clear", ":/buttons/playlist/shuffle_on",
    ":/buttons/playlist/repeat_all", ":/menu/info",
    ":/toolbar/previous_b", ":/toolbar/next_b", "" };

enum
{
   WIDGET_NORMAL = 0x0,
   WIDGET_FLAT   = 0x1,
   WIDGET_BIG    = 0x2,
   WIDGET_SHINY  = 0x4,
};

class AdvControlsWidget;
class AbstractController : public QFrame
{
    friend class WidgetListing; /* For ToolBar Edition HACKS */

    Q_OBJECT
public:
    AbstractController( intf_thread_t  *_p_i, QWidget *_parent = 0 );

protected:
    intf_thread_t       *p_intf;

    QSignalMapper       *toolbarActionsMapper;
    QHBoxLayout         *controlLayout;
    /* Change to BoxLayout if both dir are needed */

    AdvControlsWidget   *advControls;

    void parseAndCreate( const QString& config, QBoxLayout *controlLayout );

    virtual void createAndAddWidget( QBoxLayout *controlLayout, int i_index,
                                     buttonType_e i_type, int i_option );

    QWidget *createWidget( buttonType_e, int options = WIDGET_NORMAL );
private:
    static void setupButton( QAbstractButton * );
    QFrame *discFrame();
    QFrame *telexFrame();
    void applyAttributes( QToolButton *, bool b_flat, bool b_big );

    QHBoxLayout         *buttonGroupLayout;
protected slots:
    virtual void setStatus( int );

signals:
    void inputExists( bool ); /// This might be useful in the IM ?
    void inputPlaying( bool ); /// This might be useful in the IM ?
    void inputIsRecordable( bool ); /// same ?
    void inputIsTrickPlayable( bool ); /// same ?
};

/* Advanced Button Bar */
class AdvControlsWidget : public AbstractController
{
    Q_OBJECT
public:
    AdvControlsWidget( intf_thread_t *, QWidget *_parent = 0 );
};

/* Slider Bar */
class InputControlsWidget : public AbstractController
{
    Q_OBJECT
public:
    InputControlsWidget( intf_thread_t * , QWidget *_parent = 0 );
};

/* Button Bar */
class ControlsWidget : public AbstractController
{
    Q_OBJECT
public:
    /* p_intf, advanced control visible or not, blingbling or not */
    ControlsWidget( intf_thread_t *_p_i, bool b_advControls,
                    QWidget *_parent = 0 );

    void setGripVisible( bool b_visible )
    { grip->setVisible( b_visible ); }

protected:
    friend class MainInterface;

    bool b_advancedVisible;

private:
    QSizeGrip *grip;

protected slots:
    void toggleAdvanced();

signals:
    void advancedControlsToggled( bool );
};

/* to trying transparency with fullscreen controller on windows enable that */
/* it can be enabled on-non windows systems,
   but it will be transparent only with composite manager */
#define HAVE_TRANSPARENCY 1

/* Default value of opacity for FS controller */
#define DEFAULT_OPACITY 0.70

/***********************************
 * Fullscreen controller
 ***********************************/
class FullscreenControllerWidget : public AbstractController
{
    Q_OBJECT
public:
    FullscreenControllerWidget( intf_thread_t *, QWidget *_parent = 0  );
    virtual ~FullscreenControllerWidget();

    /* Vout */
    void fullscreenChanged( vout_thread_t *, bool b_fs, int i_timeout );
    void mouseChanged( vout_thread_t *, int i_mousex, int i_mousey );

signals:
    void keyPressed( QKeyEvent * );

public slots:
    void setVoutList( vout_thread_t **, int );

protected:
    friend class MainInterface;

    virtual void mouseMoveEvent( QMouseEvent *event );
    virtual void mousePressEvent( QMouseEvent *event );
    virtual void mouseReleaseEvent( QMouseEvent *event );
    virtual void enterEvent( QEvent *event );
    virtual void leaveEvent( QEvent *event );
    virtual void keyPressEvent( QKeyEvent *event );

    virtual void customEvent( QEvent *event );

private slots:
    void showFSC();
    void planHideFSC();
    void hideFSC() { hide(); }
    void slowHideFSC();
    void centerFSC( int );

private:
    QTimer *p_hideTimer;
#if HAVE_TRANSPARENCY
    QTimer *p_slowHideTimer;
    bool b_slow_hide_begin;
    int  i_slow_hide_timeout;
    float f_opacity;
#endif

    int i_mouse_last_x, i_mouse_last_y;
    bool b_mouse_over;
    int i_screennumber;
    QRect screenRes;

    /* List of vouts currently tracked */
    QList<vout_thread_t *> vout;

    /* Shared variable between FSC and VLC (protected by a lock) */
    vlc_mutex_t lock;
    bool        b_fullscreen;
    int         i_hide_timeout;  /* FSC hiding timeout, same as mouse hiding timeout */
    int i_mouse_last_move_x;
    int i_mouse_last_move_y;
};

#endif
<|endoftext|>


<commit_before>/*****************************************************************************
 * ctrl_text.cpp
 *****************************************************************************
 * Copyright (C) 2003 VideoLAN
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulire <ipkiss@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

#include "ctrl_text.hpp"
#include "../events/evt_generic.hpp"
#include "../events/evt_mouse.hpp"
#include "../src/generic_bitmap.hpp"
#include "../src/generic_font.hpp"
#include "../src/os_factory.hpp"
#include "../src/os_graphics.hpp"
#include "../src/os_timer.hpp"
#include "../utils/position.hpp"
#include "../utils/ustring.hpp"
#include "../utils/var_text.hpp"

#define MOVING_TEXT_STEP 3
#define MOVING_TEXT_DELAY 200
#define SEPARATOR_STRING "   "

CtrlText::CtrlText( intf_thread_t *pIntf, VarText &rVariable,
                    const GenericFont &rFont, const UString &rHelp,
                    uint32_t color, VarBool *pVisible ):
    CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
    m_rVariable( rVariable ), m_cmdToManual( this, &transToManual ),
    m_cmdManualMoving( this, &transManualMoving ),
    m_cmdManualStill( this, &transManualStill ),
    m_cmdMove( this, &transMove ),
    m_pEvt( NULL ), m_rFont( rFont ), m_color( color ),
    m_pImg( NULL ), m_pImgDouble( NULL ), m_pCurrImg( NULL ),
    m_xPos( 0 ), m_xOffset( 0 )
{
    m_pTimer = OSFactory::instance( getIntf() )->createOSTimer(
        Callback( this, &updateText ) );

    // States
    m_fsm.addState( "still" );
    m_fsm.addState( "moving" );
    m_fsm.addState( "manual1" );
    m_fsm.addState( "manual2" );
    m_fsm.addState( "outStill" );
    m_fsm.addState( "outMoving" );

    // Transitions
    m_fsm.addTransition( "still", "mouse:left:down", "manual1",
                         &m_cmdToManual );
    m_fsm.addTransition( "manual1", "mouse:left:up", "moving",
                         &m_cmdManualMoving );
    m_fsm.addTransition( "moving", "mouse:left:down", "manual2",
                         &m_cmdToManual );
    m_fsm.addTransition( "manual2", "mouse:left:up", "still",
                         &m_cmdManualStill );
    m_fsm.addTransition( "manual1", "motion", "manual1", &m_cmdMove );
    m_fsm.addTransition( "manual2", "motion", "manual2", &m_cmdMove );
    m_fsm.addTransition( "still", "leave", "outStill" );
    m_fsm.addTransition( "outStill", "enter", "still" );
    m_fsm.addTransition( "moving", "leave", "outMoving" );
    m_fsm.addTransition( "outMoving", "enter", "moving" );

    // Initial state
    m_fsm.setState( "outStill" );

    // Observe the variable
    m_rVariable.addObserver( this );

    // Set the text
    displayText( m_rVariable.get() );
}

CtrlText::~CtrlText()
{
    m_rVariable.delObserver( this );
    if( m_pTimer )
    {
        delete m_pTimer;
    }
    if( m_pImg )
    {
        delete m_pImg;
    }
    if( m_pImgDouble )
    {
        delete m_pImgDouble;
    }
}

void CtrlText::handleEvent( EvtGeneric &rEvent )
{
    // Save the event to use it in callbacks
    m_pEvt = &rEvent;

    m_fsm.handleTransition( rEvent.getAsString() );
}

bool CtrlText::mouseOver( int x, int y ) const
{
    if( m_pCurrImg )
    {
        // We have 3 different ways of deciding when to return true here:
        //  1) the mouse is exactly over the text (so if you click between two
        //     letters, the text control doesn't catch the event)
        //  2) the mouse is over the rectangle of the control
        //  3) the mouse is over the rectangle of the visible text
        // I don't know which one is the best...
#if 0
        return( x >= 0 && x < getPosition()->getWidth()
             && m_pCurrImg->hit( x - m_xPos, y ) );
#endif
#if 1
        return( x >= 0 && x < getPosition()->getWidth()
             && y >= 0 && y < getPosition()->getHeight() );
#endif
#if 0
        return( x >= 0 && x < getPosition()->getWidth()
             && y >= 0 && y < getPosition()->getHeight()
             && x < m_pCurrImg->getWidth() && x < m_pCurrImg->getHeight() );
#endif
    }
    else
    {
        return false;
    }
}

void CtrlText::draw( OSGraphics &rImage, int xDest, int yDest )
{
    if( m_pCurrImg )
    {
        // Compute the dimensions to draw
        int width = min( m_pCurrImg->getWidth() + m_xPos,
                         getPosition()->getWidth() );
        int height = min( m_pCurrImg->getHeight(), getPosition()->getHeight() );
        // Draw the current image
        rImage.drawBitmap( *m_pCurrImg, -m_xPos, 0, xDest, yDest,
                           width, height );
    }
}

void CtrlText::setText( const UString &rText, uint32_t color )
{
    // Change the color
    if( color != 0xFFFFFFFF )
    {
        m_color = color;
    }

    // Change the text
    m_rVariable.set( rText );
}

void CtrlText::onUpdate( Subject<VarText> &rVariable )
{
    displayText( m_rVariable.get() );
}

void CtrlText::displayText( const UString &rText )
{
    // Create the images ('normal' and 'double') from the text
    // 'Normal' image
    if( m_pImg )
    {
        delete m_pImg;
    }
    m_pImg = m_rFont.drawString( rText, m_color );
    if( !m_pImg )
    {
        return;
    }
    // 'Double' image
    const UString doubleStringWithSep = rText + SEPARATOR_STRING + rText;
    if( m_pImgDouble )
    {
        delete m_pImgDouble;
    }
    m_pImgDouble = m_rFont.drawString( doubleStringWithSep, m_color );

    // Update the current image used, as if the control size had changed
    onChangePosition();

    notifyLayout();
}

void CtrlText::onChangePosition()
{
    if( m_pImg && getPosition() )
    {
        if( m_pImg->getWidth() < getPosition()->getWidth() )
        {
            m_pCurrImg = m_pImg;
        }
        else
        {
            m_pCurrImg = m_pImgDouble;
        }
    }
    else
    {
        // m_pImg is a better default value than m_pImgDouble, but anyway we
        // don't care because the control is never drawn without position :)
        m_pCurrImg = m_pImg;
    }
}

void CtrlText::transToManual( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;
    EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;

    // Compute the offset
    pThis->m_xOffset = pEvtMouse->getXPos() - pThis->m_xPos;

    pThis->m_pTimer->stop();
    pThis->captureMouse();
}

void CtrlText::transManualMoving( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;
    pThis->releaseMouse();

    // Start the automatic movement, but only if the text is wider than the
    // control
    if( pThis->m_pImg &&
        pThis->m_pImg->getWidth() >= pThis->getPosition()->getWidth() )
    {
        // The current image may have been set incorrectly in displayText(), so
        // set the correct value
        pThis->m_pCurrImg = pThis->m_pImgDouble;

        pThis->m_pTimer->start( MOVING_TEXT_DELAY, false );
    }
}

void CtrlText::transManualStill( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;
    pThis->releaseMouse();
}

void CtrlText::transMove( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;
    EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;

    // Do nothing if the text fits in the control
    if( pThis->m_pImg &&
        pThis->m_pImg->getWidth() >= pThis->getPosition()->getWidth() )
    {
        // The current image may have been set incorrectly in displayText(), so
        // we set the correct value
        pThis->m_pCurrImg = pThis->m_pImgDouble;

        // Compute the new position of the left side, and make sure it is
        // in the correct range
        pThis->m_xPos = (pEvtMouse->getXPos() - pThis->m_xOffset);
        pThis->adjust( pThis->m_xPos );

        pThis->notifyLayout();
    }
}

void CtrlText::updateText( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;

    pThis->m_xPos -= MOVING_TEXT_STEP;
    pThis->adjust( pThis->m_xPos );

    pThis->notifyLayout();
}

void CtrlText::adjust( int &position )
{
    // {m_pImgDouble->getWidth()  - m_pImg->getWidth()} is the period of the
    // bitmap; remember that the string used to generate m_pImgDouble is of the
    // form: "foo  foo", the number of spaces being a parameter
    if( !m_pImg )
    {
        return;
    }
    position %= m_pImgDouble->getWidth()  - m_pImg->getWidth();
    if( position > 0 )
    {
        position -= m_pImgDouble->getWidth()  - m_pImg->getWidth();
    }
}

<commit_msg>  * ctrl_text.cpp: check if the scrolling is still necessary when the    text is updated (avoid many crashes)<commit_after>/*****************************************************************************
 * ctrl_text.cpp
 *****************************************************************************
 * Copyright (C) 2003 VideoLAN
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulire <ipkiss@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

#include "ctrl_text.hpp"
#include "../events/evt_generic.hpp"
#include "../events/evt_mouse.hpp"
#include "../src/generic_bitmap.hpp"
#include "../src/generic_font.hpp"
#include "../src/os_factory.hpp"
#include "../src/os_graphics.hpp"
#include "../src/os_timer.hpp"
#include "../utils/position.hpp"
#include "../utils/ustring.hpp"
#include "../utils/var_text.hpp"

#define MOVING_TEXT_STEP 3
#define MOVING_TEXT_DELAY 200
#define SEPARATOR_STRING "   "

CtrlText::CtrlText( intf_thread_t *pIntf, VarText &rVariable,
                    const GenericFont &rFont, const UString &rHelp,
                    uint32_t color, VarBool *pVisible ):
    CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
    m_rVariable( rVariable ), m_cmdToManual( this, &transToManual ),
    m_cmdManualMoving( this, &transManualMoving ),
    m_cmdManualStill( this, &transManualStill ),
    m_cmdMove( this, &transMove ),
    m_pEvt( NULL ), m_rFont( rFont ), m_color( color ),
    m_pImg( NULL ), m_pImgDouble( NULL ), m_pCurrImg( NULL ),
    m_xPos( 0 ), m_xOffset( 0 )
{
    m_pTimer = OSFactory::instance( getIntf() )->createOSTimer(
        Callback( this, &updateText ) );

    // States
    m_fsm.addState( "still" );
    m_fsm.addState( "moving" );
    m_fsm.addState( "manual1" );
    m_fsm.addState( "manual2" );
    m_fsm.addState( "outStill" );
    m_fsm.addState( "outMoving" );

    // Transitions
    m_fsm.addTransition( "still", "mouse:left:down", "manual1",
                         &m_cmdToManual );
    m_fsm.addTransition( "manual1", "mouse:left:up", "moving",
                         &m_cmdManualMoving );
    m_fsm.addTransition( "moving", "mouse:left:down", "manual2",
                         &m_cmdToManual );
    m_fsm.addTransition( "manual2", "mouse:left:up", "still",
                         &m_cmdManualStill );
    m_fsm.addTransition( "manual1", "motion", "manual1", &m_cmdMove );
    m_fsm.addTransition( "manual2", "motion", "manual2", &m_cmdMove );
    m_fsm.addTransition( "still", "leave", "outStill" );
    m_fsm.addTransition( "outStill", "enter", "still" );
    m_fsm.addTransition( "moving", "leave", "outMoving" );
    m_fsm.addTransition( "outMoving", "enter", "moving" );

    // Initial state
    m_fsm.setState( "outStill" );

    // Observe the variable
    m_rVariable.addObserver( this );

    // Set the text
    displayText( m_rVariable.get() );
}

CtrlText::~CtrlText()
{
    m_rVariable.delObserver( this );
    if( m_pTimer )
    {
        delete m_pTimer;
    }
    if( m_pImg )
    {
        delete m_pImg;
    }
    if( m_pImgDouble )
    {
        delete m_pImgDouble;
    }
}

void CtrlText::handleEvent( EvtGeneric &rEvent )
{
    // Save the event to use it in callbacks
    m_pEvt = &rEvent;

    m_fsm.handleTransition( rEvent.getAsString() );
}

bool CtrlText::mouseOver( int x, int y ) const
{
    if( m_pCurrImg )
    {
        // We have 3 different ways of deciding when to return true here:
        //  1) the mouse is exactly over the text (so if you click between two
        //     letters, the text control doesn't catch the event)
        //  2) the mouse is over the rectangle of the control
        //  3) the mouse is over the rectangle of the visible text
        // I don't know which one is the best...
#if 0
        return( x >= 0 && x < getPosition()->getWidth()
             && m_pCurrImg->hit( x - m_xPos, y ) );
#endif
#if 1
        return( x >= 0 && x < getPosition()->getWidth()
             && y >= 0 && y < getPosition()->getHeight() );
#endif
#if 0
        return( x >= 0 && x < getPosition()->getWidth()
             && y >= 0 && y < getPosition()->getHeight()
             && x < m_pCurrImg->getWidth() && x < m_pCurrImg->getHeight() );
#endif
    }
    else
    {
        return false;
    }
}

void CtrlText::draw( OSGraphics &rImage, int xDest, int yDest )
{
    if( m_pCurrImg )
    {
        // Compute the dimensions to draw
        int width = min( m_pCurrImg->getWidth() + m_xPos,
                         getPosition()->getWidth() );
        int height = min( m_pCurrImg->getHeight(), getPosition()->getHeight() );
        // Draw the current image
        rImage.drawBitmap( *m_pCurrImg, -m_xPos, 0, xDest, yDest,
                           width, height );
    }
}

void CtrlText::setText( const UString &rText, uint32_t color )
{
    // Change the color
    if( color != 0xFFFFFFFF )
    {
        m_color = color;
    }

    // Change the text
    m_rVariable.set( rText );
}

void CtrlText::onUpdate( Subject<VarText> &rVariable )
{
    displayText( m_rVariable.get() );
}

void CtrlText::displayText( const UString &rText )
{
    // Create the images ('normal' and 'double') from the text
    // 'Normal' image
    if( m_pImg )
    {
        delete m_pImg;
    }
    m_pImg = m_rFont.drawString( rText, m_color );
    if( !m_pImg )
    {
        return;
    }
    // 'Double' image
    const UString doubleStringWithSep = rText + SEPARATOR_STRING + rText;
    if( m_pImgDouble )
    {
        delete m_pImgDouble;
    }
    m_pImgDouble = m_rFont.drawString( doubleStringWithSep, m_color );

    // Update the current image used, as if the control size had changed
    onChangePosition();
    m_xPos = 0;

    // If the control was in the moving state, check if the scrolling is
    // still necessary
    const string &rState = m_fsm.getState();
    if( rState == "moving" || rState == "outMoving" )
    {
        if( m_pImg && m_pImg->getWidth() >= getPosition()->getWidth() )
        {
            m_pCurrImg = m_pImgDouble;
            m_pTimer->start( MOVING_TEXT_DELAY, false );
        }
        else
        {
            m_pTimer->stop();
        }
    }

    notifyLayout();
}

void CtrlText::onChangePosition()
{
    if( m_pImg && getPosition() )
    {
        if( m_pImg->getWidth() < getPosition()->getWidth() )
        {
            m_pCurrImg = m_pImg;
        }
        else
        {
            m_pCurrImg = m_pImgDouble;
        }
    }
    else
    {
        // m_pImg is a better default value than m_pImgDouble, but anyway we
        // don't care because the control is never drawn without position :)
        m_pCurrImg = m_pImg;
    }
}

void CtrlText::transToManual( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;
    EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;

    // Compute the offset
    pThis->m_xOffset = pEvtMouse->getXPos() - pThis->m_xPos;

    pThis->m_pTimer->stop();
    pThis->captureMouse();
}

void CtrlText::transManualMoving( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;
    pThis->releaseMouse();

    // Start the automatic movement, but only if the text is wider than the
    // control
    if( pThis->m_pImg &&
        pThis->m_pImg->getWidth() >= pThis->getPosition()->getWidth() )
    {
        // The current image may have been set incorrectly in displayText(), so
        // set the correct value
        pThis->m_pCurrImg = pThis->m_pImgDouble;

        pThis->m_pTimer->start( MOVING_TEXT_DELAY, false );
    }
}

void CtrlText::transManualStill( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;
    pThis->releaseMouse();
}

void CtrlText::transMove( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;
    EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;

    // Do nothing if the text fits in the control
    if( pThis->m_pImg &&
        pThis->m_pImg->getWidth() >= pThis->getPosition()->getWidth() )
    {
        // The current image may have been set incorrectly in displayText(), so
        // we set the correct value
        pThis->m_pCurrImg = pThis->m_pImgDouble;

        // Compute the new position of the left side, and make sure it is
        // in the correct range
        pThis->m_xPos = (pEvtMouse->getXPos() - pThis->m_xOffset);
        pThis->adjust( pThis->m_xPos );

        pThis->notifyLayout();
    }
}

void CtrlText::updateText( SkinObject *pCtrl )
{
    CtrlText *pThis = (CtrlText*)pCtrl;

    pThis->m_xPos -= MOVING_TEXT_STEP;
    pThis->adjust( pThis->m_xPos );

    pThis->notifyLayout();
}

void CtrlText::adjust( int &position )
{
    // {m_pImgDouble->getWidth()  - m_pImg->getWidth()} is the period of the
    // bitmap; remember that the string used to generate m_pImgDouble is of the
    // form: "foo  foo", the number of spaces being a parameter
    if( !m_pImg )
    {
        return;
    }
    position %= m_pImgDouble->getWidth() - m_pImg->getWidth();
    if( position > 0 )
    {
        position -= m_pImgDouble->getWidth() - m_pImg->getWidth();
    }
}

<|endoftext|>


<commit_before>#include "sass_context_wrapper.h"

extern "C" {
  using namespace std;

  void compile_it(uv_work_t* req) {
    sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);

    if (ctx_w->dctx) {
      compile_data(ctx_w->dctx);
    }
    else if (ctx_w->fctx) {
      compile_file(ctx_w->fctx);
    }
  }

  void compile_data(struct Sass_Data_Context* dctx) {
    sass_compile_data_context(dctx);
  }

  void compile_file(struct Sass_File_Context* fctx) {
    sass_compile_file_context(fctx);
  }

  sass_context_wrapper* sass_make_context_wrapper() {
    auto ctx_w = (sass_context_wrapper*)calloc(1, sizeof(sass_context_wrapper));
    uv_mutex_init(&ctx_w->importer_mutex);
    uv_cond_init(&ctx_w->importer_condition_variable);
    return ctx_w;
  }

  void sass_free_context_wrapper(sass_context_wrapper* ctx_w) {
    if (ctx_w->dctx) {
      sass_delete_data_context(ctx_w->dctx);
    }
    else if (ctx_w->fctx) {
      sass_delete_file_context(ctx_w->fctx);
    }

    NanDisposePersistent(ctx_w->stats);
    delete ctx_w->success_callback;
    delete ctx_w->error_callback;
    delete ctx_w->importer_callback;

    free(ctx_w);
  }
}
<commit_msg>Importer: Destroys vars before leaving the scope.<commit_after>#include "sass_context_wrapper.h"

extern "C" {
  using namespace std;

  void compile_it(uv_work_t* req) {
    sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);

    if (ctx_w->dctx) {
      compile_data(ctx_w->dctx);
    }
    else if (ctx_w->fctx) {
      compile_file(ctx_w->fctx);
    }
  }

  void compile_data(struct Sass_Data_Context* dctx) {
    sass_compile_data_context(dctx);
  }

  void compile_file(struct Sass_File_Context* fctx) {
    sass_compile_file_context(fctx);
  }

  sass_context_wrapper* sass_make_context_wrapper() {
    auto ctx_w = (sass_context_wrapper*)calloc(1, sizeof(sass_context_wrapper));
    uv_mutex_init(&ctx_w->importer_mutex);
    uv_cond_init(&ctx_w->importer_condition_variable);
    return ctx_w;
  }

  void sass_free_context_wrapper(sass_context_wrapper* ctx_w) {
    if (ctx_w->dctx) {
      sass_delete_data_context(ctx_w->dctx);
    }
    else if (ctx_w->fctx) {
      sass_delete_file_context(ctx_w->fctx);
    }

    NanDisposePersistent(ctx_w->stats);

    delete ctx_w->success_callback;
    delete ctx_w->error_callback;
    delete ctx_w->importer_callback;
    delete ctx_w->file;
    delete ctx_w->cookie;

    uv_mutex_destroy(&ctx_w->importer_mutex);
    uv_cond_destroy(&ctx_w->importer_condition_variable);

    free(ctx_w);
  }
}
<|endoftext|>