<commit_before>/*
 * Copyright (c) 2014 Netflix, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NETFLIX OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "DialServer.h"
#include <curl/curl.h>

using namespace std;

enum DIAL_COMMAND{
    COMMAND_LAUNCH,
    COMMAND_STATUS,
    COMMAND_KILL,
    COMMAND_HIDE
};
const char* DIAL_COMMAND_STR[] = {"LAUNCH", "STATUS", "KILL", "HIDE"};

static size_t header_cb(void* ptr, size_t size, size_t nmemb, void* userdata)
{
    if ((size * nmemb) != 0) {
        string newHeader((char*)ptr);
        string *header = static_cast<string*>(userdata);
        header->append(newHeader);
        ATRACE("%s: Adding header: %s", __FUNCTION__, newHeader.c_str());
    }
    return (size * nmemb);
}

static size_t receiveData(void *ptr, size_t size, size_t nmemb, void *userdata)
{
    if ((size * nmemb) != 0) {
        string *body= static_cast<string*>(userdata);
        body->append((char*)ptr);
        ATRACE("%s: Adding to Body: %s", __FUNCTION__, (char*)ptr);
    }
    return (size * nmemb);
}

int DialServer::sendCommand(
        string &url,
        int command,
        string &payload,
        string &responseHeaders,
        string &responseBody )
{
    CURL *curl;
    CURLcode res = CURLE_OK;
    struct curl_slist *slist = NULL;

    if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
    {
        fprintf(stderr, "curl_global_init() failed\n");
        return 0;
    }

    if ((curl = curl_easy_init()) == NULL)
    {
        fprintf(stderr, "curl_easy_init() failed\n");
        curl_global_cleanup();
        return 0;
    }

    if (command == COMMAND_LAUNCH || command == COMMAND_HIDE)
    {
        curl_easy_setopt(curl, CURLOPT_POST, true);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size());
        if( payload.size() )
        {
            slist = curl_slist_append(slist, "Expect:");
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
        }
#ifdef DEBUG
        else ATRACE("Sending empty POST\n");
#endif
    }
    else if (command == COMMAND_KILL)
    {
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
    }
    ATRACE("Sending %s:%s\n", DIAL_COMMAND_STR[command], url.c_str());

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveData);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody);
    res = curl_easy_perform(curl);

    if (curl_slist!=NULL) curl_slist_free_all(slist);
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return (res == CURLE_OK);
}

string DialServer::getIpAddress()
{
    // m_appsUrl=http://192.168.1.103:36269/apps/
    if( m_ipAddr.empty() )
    {
        size_t begin = m_appsUrl.find("//");
        if( begin != m_appsUrl.npos )
        {
            begin += 2; // move to the start of the IP address
            size_t end = m_appsUrl.find(":", begin);
            if( end != m_appsUrl.npos )
            {
                m_ipAddr = m_appsUrl.substr( begin, end-begin );
                ATRACE("IP ADDRESS: %s\n", m_ipAddr.c_str() );
            }
        }
    }
    return m_ipAddr;
}

bool DialServer::getFriendlyName( string& name )
{
    bool retval = false;
    if( !m_ddxml.empty() )
    {
        string friendlyName = "<friendlyName>";
        size_t pos;
        if( ( pos = m_ddxml.find( friendlyName ) ) != m_ddxml.npos )
        {
            string friendlyNameEnd = "</friendlyName>";
            size_t end = m_ddxml.find( friendlyNameEnd );
            name = m_ddxml.substr( pos + friendlyName.size(),
                        (end - (pos + friendlyName.size())) );
            ATRACE("***Friendly name=%s***", name.c_str());
            retval = true;
        }
#ifdef DEBUG
        else
        {
            ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
        }
#endif
    }

    return retval;
}

bool DialServer::getUuid( string& uuid )
{
    bool retval = false;
    if( !m_ddxml.empty() )
    {
        string udn = "<UDN>";
        size_t pos;
        if( ( pos = m_ddxml.find( udn ) ) != m_ddxml.npos )
        {
            string udnEnd = "</UDN>";
            size_t end = m_ddxml.find( udnEnd );
            uuid = m_ddxml.substr( pos + udn.size(),
                        (end - (pos + udn.size())) );
            ATRACE("***UUID=%s***", uuid.c_str() );
            retval = true;
        }
#ifdef DEBUG
        else
        {
            ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
        }
#endif
    }

    return retval;
}

string DialServer::getMacAddress()
{
    return m_macAddr;
}

int  DialServer::getWakeOnLanTimeout()
{
    return m_wakeUpTimeout;
}

int DialServer::launchApplication(
    string &application,
    string &payload,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: Launch %s\n", __FUNCTION__, application.c_str());
    string appUrl = m_appsUrl;
    int status = sendCommand( appUrl.append(application), COMMAND_LAUNCH, payload, responseHeaders, responseBody);
    return status;
}

int DialServer::getStatus(
    string &application,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: GetStatus %s\n", __FUNCTION__, application.c_str());
    string emptyPayload;
    string appUrl = m_appsUrl;
    int status = sendCommand( appUrl.append(application), COMMAND_STATUS, emptyPayload, responseHeaders, responseBody );

    if (!status) return 0;
    ATRACE("Body: %s\n", responseBody.c_str());
    unsigned found = responseBody.find("href=");
    if( found != string::npos )
    {
        // The start of href is after href= and the quote
        unsigned href_start = found + 5 + 1;

        // get the body from the start of href to the end, then find
        // the last quote delimiter.
        string tmp = responseBody.substr( href_start );
        unsigned href_end = tmp.find("\"");
        m_stopEndPoint = responseBody.substr( href_start, href_end );
    }
    return 0;
}

int DialServer::stopApplication(
    string &application,
    string &responseHeaders )
{
    ATRACE("%s: Quit %s\n", __FUNCTION__, application.c_str());
    string emptyPayload, responseBody;  // dropping this
    string appUrl = m_appsUrl;

    // just call status to update the run endpoint
    getStatus( application, responseHeaders, responseBody );

    int status = sendCommand(
                             (appUrl.append(application)).append("/"+m_stopEndPoint),
                             COMMAND_KILL, emptyPayload, responseHeaders, responseBody );
    return status;
}

int DialServer::hideApplication(
    string &application,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: Hide %s\n", __FUNCTION__, application.c_str());
    string emptyPayload;
    string appUrl = m_appsUrl;

    // just call status to update the run endpoint
    getStatus( application, responseHeaders, responseBody );

    int status = sendCommand(
                             (appUrl.append(application)).append("/"+m_stopEndPoint).append("/hide"),
                             COMMAND_HIDE, emptyPayload, responseHeaders, responseBody );
    return status;
}

int DialServer::getHttpResponseHeader(
    string &responseHeaders,
    string &header,
    string &value )
{
    return 0;
}
<commit_msg>Fixed typo to get client compiling<commit_after>/*
 * Copyright (c) 2014 Netflix, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NETFLIX OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "DialServer.h"
#include <curl/curl.h>

using namespace std;

enum DIAL_COMMAND{
    COMMAND_LAUNCH,
    COMMAND_STATUS,
    COMMAND_KILL,
    COMMAND_HIDE
};
const char* DIAL_COMMAND_STR[] = {"LAUNCH", "STATUS", "KILL", "HIDE"};

static size_t header_cb(void* ptr, size_t size, size_t nmemb, void* userdata)
{
    if ((size * nmemb) != 0) {
        string newHeader((char*)ptr);
        string *header = static_cast<string*>(userdata);
        header->append(newHeader);
        ATRACE("%s: Adding header: %s", __FUNCTION__, newHeader.c_str());
    }
    return (size * nmemb);
}

static size_t receiveData(void *ptr, size_t size, size_t nmemb, void *userdata)
{
    if ((size * nmemb) != 0) {
        string *body= static_cast<string*>(userdata);
        body->append((char*)ptr);
        ATRACE("%s: Adding to Body: %s", __FUNCTION__, (char*)ptr);
    }
    return (size * nmemb);
}

int DialServer::sendCommand(
        string &url,
        int command,
        string &payload,
        string &responseHeaders,
        string &responseBody )
{
    CURL *curl;
    CURLcode res = CURLE_OK;
    struct curl_slist *slist = NULL;

    if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
    {
        fprintf(stderr, "curl_global_init() failed\n");
        return 0;
    }

    if ((curl = curl_easy_init()) == NULL)
    {
        fprintf(stderr, "curl_easy_init() failed\n");
        curl_global_cleanup();
        return 0;
    }

    if (command == COMMAND_LAUNCH || command == COMMAND_HIDE)
    {
        curl_easy_setopt(curl, CURLOPT_POST, true);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size());
        if( payload.size() )
        {
            slist = curl_slist_append(slist, "Expect:");
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
        }
#ifdef DEBUG
        else ATRACE("Sending empty POST\n");
#endif
    }
    else if (command == COMMAND_KILL)
    {
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
    }
    ATRACE("Sending %s:%s\n", DIAL_COMMAND_STR[command], url.c_str());

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveData);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody);
    res = curl_easy_perform(curl);

    if (slist!=NULL) curl_slist_free_all(slist);
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return (res == CURLE_OK);
}

string DialServer::getIpAddress()
{
    // m_appsUrl=http://192.168.1.103:36269/apps/
    if( m_ipAddr.empty() )
    {
        size_t begin = m_appsUrl.find("//");
        if( begin != m_appsUrl.npos )
        {
            begin += 2; // move to the start of the IP address
            size_t end = m_appsUrl.find(":", begin);
            if( end != m_appsUrl.npos )
            {
                m_ipAddr = m_appsUrl.substr( begin, end-begin );
                ATRACE("IP ADDRESS: %s\n", m_ipAddr.c_str() );
            }
        }
    }
    return m_ipAddr;
}

bool DialServer::getFriendlyName( string& name )
{
    bool retval = false;
    if( !m_ddxml.empty() )
    {
        string friendlyName = "<friendlyName>";
        size_t pos;
        if( ( pos = m_ddxml.find( friendlyName ) ) != m_ddxml.npos )
        {
            string friendlyNameEnd = "</friendlyName>";
            size_t end = m_ddxml.find( friendlyNameEnd );
            name = m_ddxml.substr( pos + friendlyName.size(),
                        (end - (pos + friendlyName.size())) );
            ATRACE("***Friendly name=%s***", name.c_str());
            retval = true;
        }
#ifdef DEBUG
        else
        {
            ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
        }
#endif
    }

    return retval;
}

bool DialServer::getUuid( string& uuid )
{
    bool retval = false;
    if( !m_ddxml.empty() )
    {
        string udn = "<UDN>";
        size_t pos;
        if( ( pos = m_ddxml.find( udn ) ) != m_ddxml.npos )
        {
            string udnEnd = "</UDN>";
            size_t end = m_ddxml.find( udnEnd );
            uuid = m_ddxml.substr( pos + udn.size(),
                        (end - (pos + udn.size())) );
            ATRACE("***UUID=%s***", uuid.c_str() );
            retval = true;
        }
#ifdef DEBUG
        else
        {
            ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
        }
#endif
    }

    return retval;
}

string DialServer::getMacAddress()
{
    return m_macAddr;
}

int  DialServer::getWakeOnLanTimeout()
{
    return m_wakeUpTimeout;
}

int DialServer::launchApplication(
    string &application,
    string &payload,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: Launch %s\n", __FUNCTION__, application.c_str());
    string appUrl = m_appsUrl;
    int status = sendCommand( appUrl.append(application), COMMAND_LAUNCH, payload, responseHeaders, responseBody);
    return status;
}

int DialServer::getStatus(
    string &application,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: GetStatus %s\n", __FUNCTION__, application.c_str());
    string emptyPayload;
    string appUrl = m_appsUrl;
    int status = sendCommand( appUrl.append(application), COMMAND_STATUS, emptyPayload, responseHeaders, responseBody );

    if (!status) return 0;
    ATRACE("Body: %s\n", responseBody.c_str());
    unsigned found = responseBody.find("href=");
    if( found != string::npos )
    {
        // The start of href is after href= and the quote
        unsigned href_start = found + 5 + 1;

        // get the body from the start of href to the end, then find
        // the last quote delimiter.
        string tmp = responseBody.substr( href_start );
        unsigned href_end = tmp.find("\"");
        m_stopEndPoint = responseBody.substr( href_start, href_end );
    }
    return 0;
}

int DialServer::stopApplication(
    string &application,
    string &responseHeaders )
{
    ATRACE("%s: Quit %s\n", __FUNCTION__, application.c_str());
    string emptyPayload, responseBody;  // dropping this
    string appUrl = m_appsUrl;

    // just call status to update the run endpoint
    getStatus( application, responseHeaders, responseBody );

    int status = sendCommand(
                             (appUrl.append(application)).append("/"+m_stopEndPoint),
                             COMMAND_KILL, emptyPayload, responseHeaders, responseBody );
    return status;
}

int DialServer::hideApplication(
    string &application,
    string &responseHeaders,
    string &responseBody )
{
    ATRACE("%s: Hide %s\n", __FUNCTION__, application.c_str());
    string emptyPayload;
    string appUrl = m_appsUrl;

    // just call status to update the run endpoint
    getStatus( application, responseHeaders, responseBody );

    int status = sendCommand(
                             (appUrl.append(application)).append("/"+m_stopEndPoint).append("/hide"),
                             COMMAND_HIDE, emptyPayload, responseHeaders, responseBody );
    return status;
}

int DialServer::getHttpResponseHeader(
    string &responseHeaders,
    string &header,
    string &value )
{
    return 0;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2017 Hans-Kristian Arntzen
 *
 * 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 "application.hpp"
#include "vulkan_symbol_wrapper.h"
#include "vulkan.hpp"
#include "GLFW/glfw3.h"

#ifdef _WIN32
#include <windows.h>
#endif

using namespace std;
using namespace Vulkan;

namespace Granite
{
static void fb_size_cb(GLFWwindow *window, int width, int height);
static void key_cb(GLFWwindow *window, int key, int, int action, int);
static void button_cb(GLFWwindow *window, int button, int action, int);
static void cursor_cb(GLFWwindow *window, double x, double y);
static void enter_cb(GLFWwindow *window, int entered);

struct ApplicationPlatformGLFW : ApplicationPlatform
{
public:
	ApplicationPlatformGLFW(unsigned width, unsigned height)
	{
		if (!glfwInit())
			throw runtime_error("Failed to initialize GLFW.");

		if (!Context::init_loader(glfwGetInstanceProcAddress))
			throw runtime_error("Failed to initialize Vulkan loader.");

		glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
		window = glfwCreateWindow(width, height, "GLFW Window", nullptr, nullptr);

		glfwSetWindowUserPointer(window, this);
		glfwSetFramebufferSizeCallback(window, fb_size_cb);
		glfwSetKeyCallback(window, key_cb);
		glfwSetMouseButtonCallback(window, button_cb);
		glfwSetCursorPosCallback(window, cursor_cb);
		glfwSetCursorEnterCallback(window, enter_cb);

		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Stopped);
		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Paused);
		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Running);
	}

	bool alive(Vulkan::WSI &) override
	{
		glfwPollEvents();
		return !killed && !glfwWindowShouldClose(window);
	}

	void poll_input() override
	{
		glfwPollEvents();
		get_input_tracker().dispatch_current_state(get_frame_timer().get_frame_time());
	}

	vector<const char *> get_instance_extensions() override
	{
		uint32_t count;
		const char **ext = glfwGetRequiredInstanceExtensions(&count);
		return { ext, ext + count };
	}

	VkSurfaceKHR create_surface(VkInstance instance, VkPhysicalDevice) override
	{
		VkSurfaceKHR surface = VK_NULL_HANDLE;
		if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS)
			return VK_NULL_HANDLE;

		int actual_width, actual_height;
		glfwGetFramebufferSize(window, &actual_width, &actual_height);
		width = unsigned(actual_width);
		height = unsigned(actual_height);
		return surface;
	}

	uint32_t get_surface_width() override
	{
		return width;
	}

	uint32_t get_surface_height() override
	{
		return height;
	}

	~ApplicationPlatformGLFW()
	{
		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Paused);
		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Stopped);

		if (window)
			glfwDestroyWindow(window);
	}

	void notify_resize(unsigned width, unsigned height)
	{
		resize = true;
		this->width = width;
		this->height = height;
	}

private:
	GLFWwindow *window = nullptr;
	unsigned width = 0;
	unsigned height = 0;
};

static void fb_size_cb(GLFWwindow *window, int width, int height)
{
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));
	VK_ASSERT(width != 0 && height != 0);
	glfw->notify_resize(width, height);
}

static Key glfw_key_to_granite(int key)
{
#define k(glfw, granite) case GLFW_KEY_##glfw: return Key::granite
	switch (key)
	{
	k(A, A);
	k(B, B);
	k(C, C);
	k(D, D);
	k(E, E);
	k(F, F);
	k(G, G);
	k(H, H);
	k(I, I);
	k(J, J);
	k(K, K);
	k(L, L);
	k(M, M);
	k(N, N);
	k(O, O);
	k(P, P);
	k(Q, Q);
	k(R, R);
	k(S, S);
	k(T, T);
	k(U, U);
	k(V, V);
	k(W, W);
	k(X, X);
	k(Y, Y);
	k(Z, Z);
	k(LEFT_CONTROL, LeftCtrl);
	k(LEFT_ALT, LeftAlt);
	k(LEFT_SHIFT, LeftShift);
	k(ENTER, Return);
	k(SPACE, Space);
	k(ESCAPE, Escape);
	default:
		return Key::Unknown;
	}
#undef k
}

static void key_cb(GLFWwindow *window, int key, int, int action, int)
{
	KeyState state;
	switch (action)
	{
	case GLFW_PRESS:
		state = KeyState::Pressed;
		break;

	default:
	case GLFW_RELEASE:
		state = KeyState::Released;
		break;

	case GLFW_REPEAT:
		state = KeyState::Repeat;
		break;
	}

	auto gkey = glfw_key_to_granite(key);
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));
	glfw->get_input_tracker().key_event(gkey, state);
}

static void button_cb(GLFWwindow *window, int button, int action, int)
{
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));

	MouseButton btn;
	switch (button)
	{
	default:
	case GLFW_MOUSE_BUTTON_LEFT:
		btn = MouseButton::Left;
		break;
	case GLFW_MOUSE_BUTTON_RIGHT:
		btn = MouseButton::Right;
		break;
	case GLFW_MOUSE_BUTTON_MIDDLE:
		btn = MouseButton::Middle;
		break;
	}
	glfw->get_input_tracker().mouse_button_event(btn, action == GLFW_PRESS);
}

static void cursor_cb(GLFWwindow *window, double x, double y)
{
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));
	glfw->get_input_tracker().mouse_move_event(x, y);
}

static void enter_cb(GLFWwindow *window, int entered)
{
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));
	if (entered)
	{
		double x, y;
		glfwGetCursorPos(window, &x, &y);
		glfw->get_input_tracker().mouse_enter(x, y);
	}
	else
		glfw->get_input_tracker().mouse_leave();
}

unique_ptr<ApplicationPlatform> create_default_application_platform(unsigned width, unsigned height)
{
	return unique_ptr<ApplicationPlatform>(new ApplicationPlatformGLFW(width, height));
}
}

#ifdef _WIN32
int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	char granite_str[] = "granite";
	char *granite_ptr[] = { granite_str, nullptr };
	return Granite::application_main(1, granite_ptr);
}
#else
int main(int argc, char *argv[])
{
	return Granite::application_main(argc, argv);
}
#endif
<commit_msg>Fix calling convention mismatch on GLFW Windows.<commit_after>/* Copyright (c) 2017 Hans-Kristian Arntzen
 *
 * 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 "application.hpp"
#include "vulkan_symbol_wrapper.h"
#include "vulkan.hpp"
#include "GLFW/glfw3.h"

#ifdef _WIN32
#include <windows.h>
#endif

using namespace std;
using namespace Vulkan;

namespace Granite
{
static void fb_size_cb(GLFWwindow *window, int width, int height);
static void key_cb(GLFWwindow *window, int key, int, int action, int);
static void button_cb(GLFWwindow *window, int button, int action, int);
static void cursor_cb(GLFWwindow *window, double x, double y);
static void enter_cb(GLFWwindow *window, int entered);

// glfwGetProcAddr uses different calling convention on Windows.
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *name)
{
	return glfwGetInstanceProcAddress(instance, name);
}

struct ApplicationPlatformGLFW : ApplicationPlatform
{
public:
	ApplicationPlatformGLFW(unsigned width, unsigned height)
	{
		if (!glfwInit())
			throw runtime_error("Failed to initialize GLFW.");

		if (!Context::init_loader(GetInstanceProcAddr))
			throw runtime_error("Failed to initialize Vulkan loader.");

		glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
		window = glfwCreateWindow(width, height, "GLFW Window", nullptr, nullptr);

		glfwSetWindowUserPointer(window, this);
		glfwSetFramebufferSizeCallback(window, fb_size_cb);
		glfwSetKeyCallback(window, key_cb);
		glfwSetMouseButtonCallback(window, button_cb);
		glfwSetCursorPosCallback(window, cursor_cb);
		glfwSetCursorEnterCallback(window, enter_cb);

		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Stopped);
		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Paused);
		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Running);
	}

	bool alive(Vulkan::WSI &) override
	{
		glfwPollEvents();
		return !killed && !glfwWindowShouldClose(window);
	}

	void poll_input() override
	{
		glfwPollEvents();
		get_input_tracker().dispatch_current_state(get_frame_timer().get_frame_time());
	}

	vector<const char *> get_instance_extensions() override
	{
		uint32_t count;
		const char **ext = glfwGetRequiredInstanceExtensions(&count);
		return { ext, ext + count };
	}

	VkSurfaceKHR create_surface(VkInstance instance, VkPhysicalDevice) override
	{
		VkSurfaceKHR surface = VK_NULL_HANDLE;
		if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS)
			return VK_NULL_HANDLE;

		int actual_width, actual_height;
		glfwGetFramebufferSize(window, &actual_width, &actual_height);
		width = unsigned(actual_width);
		height = unsigned(actual_height);
		return surface;
	}

	uint32_t get_surface_width() override
	{
		return width;
	}

	uint32_t get_surface_height() override
	{
		return height;
	}

	~ApplicationPlatformGLFW()
	{
		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Paused);
		EventManager::get_global().dequeue_all_latched(ApplicationLifecycleEvent::get_type_id());
		EventManager::get_global().enqueue_latched<ApplicationLifecycleEvent>(ApplicationLifecycle::Stopped);

		if (window)
			glfwDestroyWindow(window);
	}

	void notify_resize(unsigned width, unsigned height)
	{
		resize = true;
		this->width = width;
		this->height = height;
	}

private:
	GLFWwindow *window = nullptr;
	unsigned width = 0;
	unsigned height = 0;
};

static void fb_size_cb(GLFWwindow *window, int width, int height)
{
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));
	VK_ASSERT(width != 0 && height != 0);
	glfw->notify_resize(width, height);
}

static Key glfw_key_to_granite(int key)
{
#define k(glfw, granite) case GLFW_KEY_##glfw: return Key::granite
	switch (key)
	{
	k(A, A);
	k(B, B);
	k(C, C);
	k(D, D);
	k(E, E);
	k(F, F);
	k(G, G);
	k(H, H);
	k(I, I);
	k(J, J);
	k(K, K);
	k(L, L);
	k(M, M);
	k(N, N);
	k(O, O);
	k(P, P);
	k(Q, Q);
	k(R, R);
	k(S, S);
	k(T, T);
	k(U, U);
	k(V, V);
	k(W, W);
	k(X, X);
	k(Y, Y);
	k(Z, Z);
	k(LEFT_CONTROL, LeftCtrl);
	k(LEFT_ALT, LeftAlt);
	k(LEFT_SHIFT, LeftShift);
	k(ENTER, Return);
	k(SPACE, Space);
	k(ESCAPE, Escape);
	default:
		return Key::Unknown;
	}
#undef k
}

static void key_cb(GLFWwindow *window, int key, int, int action, int)
{
	KeyState state;
	switch (action)
	{
	case GLFW_PRESS:
		state = KeyState::Pressed;
		break;

	default:
	case GLFW_RELEASE:
		state = KeyState::Released;
		break;

	case GLFW_REPEAT:
		state = KeyState::Repeat;
		break;
	}

	auto gkey = glfw_key_to_granite(key);
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));
	glfw->get_input_tracker().key_event(gkey, state);
}

static void button_cb(GLFWwindow *window, int button, int action, int)
{
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));

	MouseButton btn;
	switch (button)
	{
	default:
	case GLFW_MOUSE_BUTTON_LEFT:
		btn = MouseButton::Left;
		break;
	case GLFW_MOUSE_BUTTON_RIGHT:
		btn = MouseButton::Right;
		break;
	case GLFW_MOUSE_BUTTON_MIDDLE:
		btn = MouseButton::Middle;
		break;
	}
	glfw->get_input_tracker().mouse_button_event(btn, action == GLFW_PRESS);
}

static void cursor_cb(GLFWwindow *window, double x, double y)
{
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));
	glfw->get_input_tracker().mouse_move_event(x, y);
}

static void enter_cb(GLFWwindow *window, int entered)
{
	auto *glfw = static_cast<ApplicationPlatformGLFW *>(glfwGetWindowUserPointer(window));
	if (entered)
	{
		double x, y;
		glfwGetCursorPos(window, &x, &y);
		glfw->get_input_tracker().mouse_enter(x, y);
	}
	else
		glfw->get_input_tracker().mouse_leave();
}

unique_ptr<ApplicationPlatform> create_default_application_platform(unsigned width, unsigned height)
{
	return unique_ptr<ApplicationPlatform>(new ApplicationPlatformGLFW(width, height));
}
}

#ifdef _WIN32
int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	char granite_str[] = "granite";
	char *granite_ptr[] = { granite_str, nullptr };
	return Granite::application_main(1, granite_ptr);
}
#else
int main(int argc, char *argv[])
{
	return Granite::application_main(argc, argv);
}
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_PROB_NEG_BINOMIAL_RNG_HPP
#define STAN_MATH_PRIM_PROB_NEG_BINOMIAL_RNG_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/constants.hpp>
#include <stan/math/prim/fun/max_size.hpp>
#include <boost/random/gamma_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/variate_generator.hpp>

namespace stan {
namespace math {

/** \ingroup prob_dists
 * Return a negative binomial random variate with the specified shape and
 * inverse scale parameters using the given random number generator.
 *
 * alpha and beta can each be a scalar or a one-dimensional container. Any
 * non-scalar inputs must be the same size.
 *
 * @tparam T_shape type of shape parameter
 * @tparam T_inv type of inverse scale parameter
 * @tparam RNG type of random number generator
 * @param alpha (Sequence of) positive shape parameter(s)
 * @param beta (Sequence of) positive inverse scale parameter(s)
 * @param rng random number generator
 * @return (Sequence of) negative binomial random variate(s)
 * @throw std::domain_error if alpha or beta are nonpositive
 * @throw std::invalid_argument if non-scalar arguments are of different
 * sizes
 */
template <typename T_shape, typename T_inv, class RNG>
inline typename VectorBuilder<true, int, T_shape, T_inv>::type neg_binomial_rng(
    const T_shape& alpha, const T_inv& beta, RNG& rng) {
  using boost::gamma_distribution;
  using boost::variate_generator;
  using boost::random::poisson_distribution;
  using T_alpha_ref = ref_type_t<T_shape>;
  using T_beta_ref = ref_type_t<T_inv_scale>;
  static const char* function = "neg_binomial_rng";
  check_consistent_sizes(function, "Shape parameter", alpha,
                         "Inverse scale Parameter", beta);
  T_alpha_ref alpha_ref = alpha;
  T_beta_ref beta_ref = beta;
  check_positive_finite(function, "Shape parameter", alpha_ref);
  check_positive_finite(function, "Inverse scale parameter", beta_ref);

  scalar_seq_view<T_alpha_ref> alpha_vec(alpha_ref);
  scalar_seq_view<T_beta_ref> beta_vec(beta_ref);
  size_t N = max_size(alpha, beta);
  VectorBuilder<true, int, T_shape, T_inv> output(N);

  for (size_t n = 0; n < N; ++n) {
    double rng_from_gamma = variate_generator<RNG&, gamma_distribution<> >(
        rng, gamma_distribution<>(alpha_vec[n], 1.0 / beta_vec[n]))();

    // same as the constraints for poisson_rng
    check_less(function, "Random number that came from gamma distribution",
               rng_from_gamma, POISSON_MAX_RATE);
    check_not_nan(function, "Random number that came from gamma distribution",
                  rng_from_gamma);
    check_nonnegative(function,
                      "Random number that came from gamma distribution",
                      rng_from_gamma);

    output[n] = variate_generator<RNG&, poisson_distribution<> >(
        rng, poisson_distribution<>(rng_from_gamma))();
  }

  return output.data();
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>bugfix<commit_after>#ifndef STAN_MATH_PRIM_PROB_NEG_BINOMIAL_RNG_HPP
#define STAN_MATH_PRIM_PROB_NEG_BINOMIAL_RNG_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/constants.hpp>
#include <stan/math/prim/fun/max_size.hpp>
#include <boost/random/gamma_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/variate_generator.hpp>

namespace stan {
namespace math {

/** \ingroup prob_dists
 * Return a negative binomial random variate with the specified shape and
 * inverse scale parameters using the given random number generator.
 *
 * alpha and beta can each be a scalar or a one-dimensional container. Any
 * non-scalar inputs must be the same size.
 *
 * @tparam T_shape type of shape parameter
 * @tparam T_inv type of inverse scale parameter
 * @tparam RNG type of random number generator
 * @param alpha (Sequence of) positive shape parameter(s)
 * @param beta (Sequence of) positive inverse scale parameter(s)
 * @param rng random number generator
 * @return (Sequence of) negative binomial random variate(s)
 * @throw std::domain_error if alpha or beta are nonpositive
 * @throw std::invalid_argument if non-scalar arguments are of different
 * sizes
 */
template <typename T_shape, typename T_inv, class RNG>
inline typename VectorBuilder<true, int, T_shape, T_inv>::type neg_binomial_rng(
    const T_shape& alpha, const T_inv& beta, RNG& rng) {
  using boost::gamma_distribution;
  using boost::variate_generator;
  using boost::random::poisson_distribution;
  using T_alpha_ref = ref_type_t<T_shape>;
  using T_beta_ref = ref_type_t<T_inv>;
  static const char* function = "neg_binomial_rng";
  check_consistent_sizes(function, "Shape parameter", alpha,
                         "Inverse scale Parameter", beta);
  T_alpha_ref alpha_ref = alpha;
  T_beta_ref beta_ref = beta;
  check_positive_finite(function, "Shape parameter", alpha_ref);
  check_positive_finite(function, "Inverse scale parameter", beta_ref);

  scalar_seq_view<T_alpha_ref> alpha_vec(alpha_ref);
  scalar_seq_view<T_beta_ref> beta_vec(beta_ref);
  size_t N = max_size(alpha, beta);
  VectorBuilder<true, int, T_shape, T_inv> output(N);

  for (size_t n = 0; n < N; ++n) {
    double rng_from_gamma = variate_generator<RNG&, gamma_distribution<> >(
        rng, gamma_distribution<>(alpha_vec[n], 1.0 / beta_vec[n]))();

    // same as the constraints for poisson_rng
    check_less(function, "Random number that came from gamma distribution",
               rng_from_gamma, POISSON_MAX_RATE);
    check_not_nan(function, "Random number that came from gamma distribution",
                  rng_from_gamma);
    check_nonnegative(function,
                      "Random number that came from gamma distribution",
                      rng_from_gamma);

    output[n] = variate_generator<RNG&, poisson_distribution<> >(
        rng, poisson_distribution<>(rng_from_gamma))();
  }

  return output.data();
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/*                            Package   : libhex
 * boundingbox.cc             Created   : 2008/02/24
 *                            Author    : Alex Tingle
 *
 *    Copyright (C) 2008, Alex Tingle.
 *
 *    This file is part of the libhex application.
 *
 *    libhex is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    libhex is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "hex.h"

#include <cmath>

namespace hex {

std::set<Hex*>
BoundingBox::hexes(void) const
{
  // FIXME: Correct this algorithm so that it only yields hexes that are
  // actually in the bbox - and includes all of the hexes that ARE.
  std::set<Hex*> result;
  for(int i=hex0->i; i<=hex1->i; ++i)
    for(int j=hex0->j; j<=hex1->j; ++j)
      result.insert(hex0->grid().hex(i,j));
  return result;
}

void BoundingBox::frame(void)
{
  point0.x -= (hex::I / 2.0);
  point0.y -= hex::K;
  point1.x += (hex::I / 2.0);
  point1.y += hex::K;
}

BoundingBox::BoundingBox(
    const Point& point0_, const Point& point1_,
    Hex* const hex0_, Hex* const hex1_
  )
  : point0( point0_ ),
    point1( point1_ ),
    hex0( hex0_ ),
    hex1( hex1_ )
{}

BoundingBox::BoundingBox(const Grid& grid, bool frame_)
{
  Hex* h0 = grid.hex(0,0);
  Hex* h1 = grid.hex( grid.cols()-1, grid.rows()-1 );
  *this = BoundingBox(h0,h1,frame_);
}

BoundingBox::BoundingBox(const std::set<Hex*>& a, bool frame_)
  throw (hex::invalid_argument)
{
  if(a.empty())
      throw hex::invalid_argument("BoundingBox::make(<empty set>)");
  int i0 = INT_MAX;
  int j0 = INT_MAX;
  int i1 = INT_MIN;
  int j1 = INT_MIN;
  for(std::set<Hex*>::const_iterator h=a.begin(); h!=a.end(); ++h)
  {
    i0 = std::min(i0,(**h).i);
    j0 = std::min(j0,(**h).j);
    i1 = std::max(i1,(**h).i);
    j1 = std::max(j1,(**h).j);
  }
  const Grid& g = (**a.begin()).grid();
  Hex* hex0 = g.hex(i0,j0);
  Hex* hex1 = g.hex(i1,j1);
  *this = BoundingBox(hex0,hex1,frame_);
}

BoundingBox::BoundingBox(const Grid& grid, const Point& p0, const Point& p1)
{
  int i0 = std::max( 0, int(p0.x)-1 ); // Calculate the boundary hexes.
  int j0 = std::max( 0, int(p0.y / hex::J) );
  int i1 = int( ceil(p1.x) );
  int j1 = int( ceil(p1.y / hex::J) );
  *this = BoundingBox(p0, p1, grid.hex(i0,j0), grid.hex(i1,j1));
}

BoundingBox::BoundingBox(Hex* hex0_, Hex* hex1_, bool frame_)
{
  *this = BoundingBox(hex0_->centre(), hex1_->centre(), hex0_, hex1_);
  if(frame_)
      frame();
}

} // end namespace hex
<commit_msg>Fixed bug in BBOX calculation.<commit_after>/*                            Package   : libhex
 * boundingbox.cc             Created   : 2008/02/24
 *                            Author    : Alex Tingle
 *
 *    Copyright (C) 2008, Alex Tingle.
 *
 *    This file is part of the libhex application.
 *
 *    libhex is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    libhex is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "hex.h"

#include <cmath>

namespace hex {

std::set<Hex*>
BoundingBox::hexes(void) const
{
  // FIXME: Correct this algorithm so that it only yields hexes that are
  // actually in the bbox - and includes all of the hexes that ARE.
  std::set<Hex*> result;
  for(int i=hex0->i; i<=hex1->i; ++i)
    for(int j=hex0->j; j<=hex1->j; ++j)
      result.insert(hex0->grid().hex(i,j));
  return result;
}

void BoundingBox::frame(void)
{
  point0.x -= (hex::I / 2.0);
  point0.y -= hex::K;
  point1.x += (hex::I / 2.0);
  point1.y += hex::K;
}

BoundingBox::BoundingBox(
    const Point& point0_, const Point& point1_,
    Hex* const hex0_, Hex* const hex1_
  )
  : point0( point0_ ),
    point1( point1_ ),
    hex0( hex0_ ),
    hex1( hex1_ )
{}

BoundingBox::BoundingBox(const Grid& grid, bool frame_)
{
  Hex* h0 = grid.hex(0,0);
  Hex* h1 = grid.hex( grid.cols()-1, grid.rows()-1 );
  *this = BoundingBox(h0,h1,frame_);
}

BoundingBox::BoundingBox(const std::set<Hex*>& a, bool frame_)
  throw (hex::invalid_argument)
{
  if(a.empty())
      throw hex::invalid_argument("BoundingBox::make(<empty set>)");
  int i0 = INT_MAX;
  int j0 = INT_MAX;
  int i1 = INT_MIN;
  int j1 = INT_MIN;
  for(std::set<Hex*>::const_iterator h=a.begin(); h!=a.end(); ++h)
  {
    i0 = std::min(i0,(**h).i);
    j0 = std::min(j0,(**h).j);
    i1 = std::max(i1,(**h).i);
    j1 = std::max(j1,(**h).j);
  }
  const Grid& g = (**a.begin()).grid();
  Hex* hex0 = g.hex(i0,j0);
  Hex* hex1 = g.hex(i1,j1);
  *this = BoundingBox(hex0,hex1,frame_);
}

BoundingBox::BoundingBox(const Grid& grid, const Point& p0, const Point& p1)
{
  int i0 = std::max( 0, int(p0.x)-1 ); // Calculate the boundary hexes.
  int j0 = std::max( 0, int(p0.y / hex::J) );
  int i1 = std::min( grid.cols()-1, int( ceil(p1.x) ) );
  int j1 = std::min( grid.rows()-1, int( ceil(p1.y / hex::J) ) );
  *this = BoundingBox(p0, p1, grid.hex(i0,j0), grid.hex(i1,j1));
}

BoundingBox::BoundingBox(Hex* hex0_, Hex* hex1_, bool frame_)
{
  *this = BoundingBox(hex0_->centre(), hex1_->centre(), hex0_, hex1_);
  if(frame_)
      frame();
}

} // end namespace hex
<|endoftext|>


<commit_before>#include "varint_vector.hpp"
#include "writer.hpp"
#include "reader.hpp"

#include "../base/assert.hpp"

namespace varint
{

namespace
{
  void VarintEncode(vector<uint8_t> & dst, uint64_t n)
  {
    if (n == 0)
    {
      dst.push_back(0);
    }
    else
    {
      while (n != 0)
      {
        uint8_t b = n & 0x7F;
        n >>= 7;
        b |= (n == 0) ? 0 : 0x80;
        dst.push_back(b);
      }
    }
  }

  uint64_t VarintDecode(Reader * reader, uint64_t & offset)
  {
    uint64_t n = 0;
    int shift = 0;
    while (1)
    {
      uint8_t b = 0;
      reader->Read(offset, &b, 1);
      n |= uint64_t(b & 0x7F) << shift;
      ++offset;
      if ((b & 0x80) == 0)
        break;
      shift += 7;
    }
    return n;
  }
}

VectorBuilder::VectorBuilder(uint64_t numElemPerTableEntry)
  : m_numElemPerTableEntry(numElemPerTableEntry), m_numsCount(0), m_sum(0)
{
}

void VectorBuilder::AddNum(uint64_t num)
{
  if (m_numsCount % m_numElemPerTableEntry == 0)
  {
    TableEntry tableEntry;
    tableEntry.pos = m_serialNums.size();
    tableEntry.sum = m_sum;
    m_selectTable.push_back(tableEntry);
  }
  VarintEncode(m_serialNums, num);
  ++m_numsCount;
  m_sum += num;
}

void VectorBuilder::Finalize(Writer * writer)
{
  vector<uint8_t> header;
  VarintEncode(header, m_numsCount);
  VarintEncode(header, m_numElemPerTableEntry);
  VarintEncode(header, m_selectTable.size());
  VarintEncode(header, m_serialNums.size());

  writer->Write(header.data(), header.size());
  writer->Write(m_selectTable.data(), m_selectTable.size() * sizeof(m_selectTable.front()));
  writer->Write(m_serialNums.data(), m_serialNums.size());
}

void VectorBuilderDelayedLast::AddLast()
{
  if (m_hasLast)
  {
    BaseT::AddNum(m_last);
    m_hasLast = false;
  }
}

void VectorBuilderDelayedLast::AddNum(uint64_t num)
{
  AddLast();

  m_last = num;
  m_hasLast = true;
}

void VectorBuilderDelayedLast::ReplaceLast(uint64_t num)
{
  ASSERT(m_hasLast, ());
  m_last = num;
}

void VectorBuilderDelayedLast::Finalize(Writer * writer)
{
  AddLast();

  BaseT::Finalize(writer);
}

Vector::Vector(Reader * reader)
  : m_reader(reader), m_numsCount(0), m_numElemPerTableEntry(0), m_numTableEntries(0),
    m_serialNumsSize(0), m_selectTableOffset(0), m_serialNumsOffset(0)
{
  uint64_t parseOffset = 0;
  m_numsCount = VarintDecode(m_reader, parseOffset);
  m_numElemPerTableEntry = VarintDecode(m_reader, parseOffset);
  m_numTableEntries = VarintDecode(m_reader, parseOffset);
  m_serialNumsSize = VarintDecode(m_reader, parseOffset);
  m_selectTableOffset = parseOffset;
  m_serialNumsOffset = m_selectTableOffset + sizeof(TableEntry) * m_numTableEntries;
}

void Vector::FindByIndex(uint64_t index, uint32_t & serialPos, uint64_t & sumBefore)
{
  ASSERT_LESS(index, m_numsCount, ());
  uint64_t tableEntryIndex = index / m_numElemPerTableEntry;

  ASSERT_LESS(tableEntryIndex, m_numTableEntries, ());

  uint64_t tableEntryOffset = m_selectTableOffset + tableEntryIndex * sizeof(TableEntry);
  uint64_t indexWithinRange = index % m_numElemPerTableEntry;

  TableEntry tableEntry;
  m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));

  uint64_t sum = tableEntry.sum;
  uint64_t numOffset = m_serialNumsOffset + tableEntry.pos;
  for (uint64_t i = 0; i < indexWithinRange; ++i)
  {
    uint64_t num = VarintDecode(m_reader, numOffset);
    sum += num;
  }
  serialPos = numOffset - m_serialNumsOffset;
  sumBefore = sum;
}

void Vector::FindBySum(uint64_t sum, uint32_t & serialPos, uint64_t & sumBefore, uint64_t & countBefore)
{
  // First do binary search over select table to find the biggest
  // sum that is less or equal to our.
  uint64_t l = 0, r = m_numTableEntries;
  uint64_t countBinarySearchCycles = 0;
  while (r - l > 1)
  {
    ++countBinarySearchCycles;

    uint64_t m = (l + r) / 2;
    uint64_t tableEntryOffset = m_selectTableOffset + m * sizeof(TableEntry);

    TableEntry tableEntry;
    m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));
    if (sum >= tableEntry.sum)
      l = m;
    else
      r = m;
  }

  uint64_t tableEntryIndex = l;
  countBefore = tableEntryIndex * m_numElemPerTableEntry;

  uint64_t tableEntryOffset = m_selectTableOffset + tableEntryIndex * sizeof(TableEntry);
  TableEntry tableEntry;
  m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));

  uint64_t numsSum = tableEntry.sum;
  // At this point nums_sum <= sum.
  uint64_t numOffset = m_serialNumsOffset + tableEntry.pos;
  while (numsSum <= sum)
  {
    uint64_t nextOffset = numOffset;
    uint64_t num = VarintDecode(m_reader, nextOffset);

    if (numsSum + num > sum)
      break;

    numOffset = nextOffset;
    numsSum += num;
    ++countBefore;
  }

  serialPos = numOffset - m_serialNumsOffset;
  sumBefore = numsSum;
}

void Vector::Read(uint32_t & serialPos, uint64_t & num)
{
  ASSERT_LESS(serialPos, m_serialNumsSize, ());

  uint64_t numOffset = m_serialNumsOffset + serialPos;
  num = VarintDecode(m_reader, numOffset);
  serialPos = numOffset - m_serialNumsOffset;
}

}
<commit_msg>Coding: VarintVector: Fix tiny bug, check index overflow in FindBySum search if we run past the last element in the vector.<commit_after>#include "varint_vector.hpp"
#include "writer.hpp"
#include "reader.hpp"

#include "../base/assert.hpp"

namespace varint
{

namespace
{
  void VarintEncode(vector<uint8_t> & dst, uint64_t n)
  {
    if (n == 0)
    {
      dst.push_back(0);
    }
    else
    {
      while (n != 0)
      {
        uint8_t b = n & 0x7F;
        n >>= 7;
        b |= (n == 0) ? 0 : 0x80;
        dst.push_back(b);
      }
    }
  }

  uint64_t VarintDecode(Reader * reader, uint64_t & offset)
  {
    uint64_t n = 0;
    int shift = 0;
    while (1)
    {
      uint8_t b = 0;
      reader->Read(offset, &b, 1);
      n |= uint64_t(b & 0x7F) << shift;
      ++offset;
      if ((b & 0x80) == 0)
        break;
      shift += 7;
    }
    return n;
  }
}

VectorBuilder::VectorBuilder(uint64_t numElemPerTableEntry)
  : m_numElemPerTableEntry(numElemPerTableEntry), m_numsCount(0), m_sum(0)
{
}

void VectorBuilder::AddNum(uint64_t num)
{
  if (m_numsCount % m_numElemPerTableEntry == 0)
  {
    TableEntry tableEntry;
    tableEntry.pos = m_serialNums.size();
    tableEntry.sum = m_sum;
    m_selectTable.push_back(tableEntry);
  }
  VarintEncode(m_serialNums, num);
  ++m_numsCount;
  m_sum += num;
}

void VectorBuilder::Finalize(Writer * writer)
{
  vector<uint8_t> header;
  VarintEncode(header, m_numsCount);
  VarintEncode(header, m_numElemPerTableEntry);
  VarintEncode(header, m_selectTable.size());
  VarintEncode(header, m_serialNums.size());

  writer->Write(header.data(), header.size());
  writer->Write(m_selectTable.data(), m_selectTable.size() * sizeof(m_selectTable.front()));
  writer->Write(m_serialNums.data(), m_serialNums.size());
}

void VectorBuilderDelayedLast::AddLast()
{
  if (m_hasLast)
  {
    BaseT::AddNum(m_last);
    m_hasLast = false;
  }
}

void VectorBuilderDelayedLast::AddNum(uint64_t num)
{
  AddLast();

  m_last = num;
  m_hasLast = true;
}

void VectorBuilderDelayedLast::ReplaceLast(uint64_t num)
{
  ASSERT(m_hasLast, ());
  m_last = num;
}

void VectorBuilderDelayedLast::Finalize(Writer * writer)
{
  AddLast();

  BaseT::Finalize(writer);
}

Vector::Vector(Reader * reader)
  : m_reader(reader), m_numsCount(0), m_numElemPerTableEntry(0), m_numTableEntries(0),
    m_serialNumsSize(0), m_selectTableOffset(0), m_serialNumsOffset(0)
{
  uint64_t parseOffset = 0;
  m_numsCount = VarintDecode(m_reader, parseOffset);
  m_numElemPerTableEntry = VarintDecode(m_reader, parseOffset);
  m_numTableEntries = VarintDecode(m_reader, parseOffset);
  m_serialNumsSize = VarintDecode(m_reader, parseOffset);
  m_selectTableOffset = parseOffset;
  m_serialNumsOffset = m_selectTableOffset + sizeof(TableEntry) * m_numTableEntries;
}

void Vector::FindByIndex(uint64_t index, uint32_t & serialPos, uint64_t & sumBefore)
{
  ASSERT_LESS(index, m_numsCount, ());
  uint64_t tableEntryIndex = index / m_numElemPerTableEntry;

  ASSERT_LESS(tableEntryIndex, m_numTableEntries, ());

  uint64_t tableEntryOffset = m_selectTableOffset + tableEntryIndex * sizeof(TableEntry);
  uint64_t indexWithinRange = index % m_numElemPerTableEntry;

  TableEntry tableEntry;
  m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));

  uint64_t sum = tableEntry.sum;
  uint64_t numOffset = m_serialNumsOffset + tableEntry.pos;
  for (uint64_t i = 0; i < indexWithinRange; ++i)
  {
    uint64_t num = VarintDecode(m_reader, numOffset);
    sum += num;
  }
  serialPos = numOffset - m_serialNumsOffset;
  sumBefore = sum;
}

void Vector::FindBySum(uint64_t sum, uint32_t & serialPos, uint64_t & sumBefore, uint64_t & countBefore)
{
  // First do binary search over select table to find the biggest
  // sum that is less or equal to our.
  uint64_t l = 0, r = m_numTableEntries;
  uint64_t countBinarySearchCycles = 0;
  while (r - l > 1)
  {
    ++countBinarySearchCycles;

    uint64_t m = (l + r) / 2;
    uint64_t tableEntryOffset = m_selectTableOffset + m * sizeof(TableEntry);

    TableEntry tableEntry;
    m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));
    if (sum >= tableEntry.sum)
      l = m;
    else
      r = m;
  }

  uint64_t tableEntryIndex = l;
  countBefore = tableEntryIndex * m_numElemPerTableEntry;

  uint64_t tableEntryOffset = m_selectTableOffset + tableEntryIndex * sizeof(TableEntry);
  TableEntry tableEntry;
  m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));

  uint64_t numsSum = tableEntry.sum;
  // At this point nums_sum <= sum.
  uint64_t numOffset = m_serialNumsOffset + tableEntry.pos;
  while (numsSum <= sum && countBefore < m_numsCount)
  {
    uint64_t nextOffset = numOffset;
    uint64_t num = VarintDecode(m_reader, nextOffset);

    if (numsSum + num > sum)
      break;

    numOffset = nextOffset;
    numsSum += num;
    ++countBefore;
  }

  serialPos = numOffset - m_serialNumsOffset;
  sumBefore = numsSum;
}

void Vector::Read(uint32_t & serialPos, uint64_t & num)
{
  ASSERT_LESS(serialPos, m_serialNumsSize, ());

  uint64_t numOffset = m_serialNumsOffset + serialPos;
  num = VarintDecode(m_reader, numOffset);
  serialPos = numOffset - m_serialNumsOffset;
}

}
<|endoftext|>


<commit_before><commit_msg>Add placeholder for histogramming non-speculative resolve jobs duration. Review URL: http://codereview.chromium.org/573021<commit_after><|endoftext|>


<commit_before>// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

// Purpose:   This file is intended to be the first file #included to any
//            Open CASCADE source. It defines platform-specific pre-processor
//            macros necessary for correct compilation of Open CASCADE code

#ifndef _Standard_Macro_HeaderFile
# define _Standard_Macro_HeaderFile

// Standard OCC macros: Handle(), STANDARD_TYPE()
# define   Handle(ClassName)      Handle_##ClassName
# define   STANDARD_TYPE(aType)   aType##_Type_()

#if defined(__cplusplus) && (__cplusplus >= 201100L)
  // part of C++11 standard
  #define Standard_OVERRIDE override
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
  // MSVC extension since VS2012
  #define Standard_OVERRIDE override
#else
  #define Standard_OVERRIDE
#endif

//======================================================
// Windows-specific definitions
//======================================================

// check if WNT macro is not defined but compiler is MSVC
#if defined(_MSC_VER) && !defined(WNT)
#error "Wrong compiler options has been detected. Add /DWNT option for proper compilation!!!!!"
#endif

# if defined(_WIN32) && !defined(HAVE_NO_DLL)

#  ifndef Standard_EXPORT
#   define Standard_EXPORT __declspec( dllexport )
// For global variables :
#   define Standard_EXPORTEXTERN __declspec( dllexport ) extern
#   define Standard_EXPORTEXTERNC extern "C" __declspec( dllexport )
#  endif  /* Standard_EXPORT */

#  ifndef Standard_IMPORT
#   define Standard_IMPORT __declspec( dllimport ) extern
#   define Standard_IMPORTC extern "C" __declspec( dllimport )
#  endif  /* Standard_IMPORT */

// We must be careful including windows.h: it is really poisonous stuff!
// The most annoying are #defines of many identifiers that you could use in
// normal code without knowing that Windows has its own knowledge of them...
// So lets protect ourselves by switching OFF as much as possible of this in advance.
// If someone needs more from windows.h, he is encouraged to #undef these symbols
// or include windows.h prior to any OCCT stuff.
// Note that we define each symbol to itself, so that it still can be used
// e.g. as name of variable, method etc.
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN   /* exclude extra Windows stuff */
#endif
#ifndef NOMINMAX
#define NOMINMAX NOMINMAX     /* avoid #define min() and max() */
#endif
#ifndef NOMSG
#define NOMSG NOMSG           /* avoid #define SendMessage etc. */
#endif
#ifndef NODRAWTEXT
#define NODRAWTEXT NODRAWTEXT /* avoid #define DrawText etc. */
#endif
#ifndef NONLS
#define NONLS NONLS           /* avoid #define CompareString etc. */
#endif
#ifndef NOGDI
#define NOGDI NOGDI           /* avoid #define SetPrinter (winspool.h) etc. */
#endif
#ifndef NOSERVICE
#define NOSERVICE NOSERVICE
#endif
#ifndef NOKERNEL
#define NOKERNEL NOKERNEL
#endif
#ifndef NOUSER
#define NOUSER NOUSER
#endif
#ifndef NOMCX
#define NOMCX NOMCX
#endif
#ifndef NOIME
#define NOIME NOIME
#endif

# else  /* WNT */

//======================================================
// UNIX definitions
//======================================================

#  ifndef Standard_EXPORT
#   define Standard_EXPORT
// For global variables :
#   define Standard_EXPORTEXTERN extern
#   define Standard_EXPORTEXTERNC extern "C"
#  endif  /* Standard_EXPORT */

#  ifndef Standard_IMPORT
#   define Standard_IMPORT extern
#   define Standard_IMPORTC extern "C"
#  endif  /* Standard_IMPORT */

// Compatibility with old SUN compilers

// This preprocessor directive is a kludge to get around
// a bug in the Sun Workshop 5.0 compiler, it keeps the
// /usr/include/memory.h file from being #included
// with an incompatible extern "C" definition of memchr
// October 18, 2000  <rboehne@ricardo-us.com>
#if __SUNPRO_CC_COMPAT == 5
#define	_MEMORY_H
#endif

# endif  /* WNT */

//======================================================
// Other
//======================================================

# ifndef __Standard_API
//#  ifdef WNT
#   if !defined(_WIN32) || defined(__Standard_DLL) || defined(__FSD_DLL) || defined(__MMgt_DLL) || defined(__OSD_DLL) || defined(__Plugin_DLL) || defined(__Quantity_DLL) || defined(__Resource_DLL) || defined(__SortTools_DLL) || defined(__StdFail_DLL) || defined(__Storage_DLL) || defined(__TColStd_DLL) || defined(__TCollection_DLL) || defined(__TShort_DLL) || defined(__Units_DLL) || defined(__UnitsAPI_DLL) || defined(__Dico_DLL)
#    define __Standard_API Standard_EXPORT
#    define __Standard_APIEXTERN Standard_EXPORTEXTERN
#   else
#    define __Standard_API Standard_IMPORT
#    define __Standard_APIEXTERN Standard_IMPORT
#   endif  // __Standard_DLL
//#  else
//#   define __Standard_API
//#  endif  // WNT
# endif  // __Standard_API

#endif
<commit_msg>submitted/thread_21393/warning/linker-warnings<commit_after>// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

// Purpose:   This file is intended to be the first file #included to any
//            Open CASCADE source. It defines platform-specific pre-processor
//            macros necessary for correct compilation of Open CASCADE code

#ifndef _Standard_Macro_HeaderFile
# define _Standard_Macro_HeaderFile

// Standard OCC macros: Handle(), STANDARD_TYPE()
# define   Handle(ClassName)      Handle_##ClassName
# define   STANDARD_TYPE(aType)   aType##_Type_()

#if defined(__cplusplus) && (__cplusplus >= 201100L)
  // part of C++11 standard
  #define Standard_OVERRIDE override
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
  // MSVC extension since VS2012
  #define Standard_OVERRIDE override
#else
  #define Standard_OVERRIDE
#endif

//======================================================
// Windows-specific definitions
//======================================================

// check if WNT macro is not defined but compiler is MSVC
#if defined(_MSC_VER) && !defined(WNT)
#error "Wrong compiler options has been detected. Add /DWNT option for proper compilation!!!!!"
#endif

# if defined(_WIN32) && !defined(HAVE_NO_DLL)

#  ifndef Standard_EXPORT
#   define Standard_EXPORT __declspec( dllexport )
// For global variables :
#   define Standard_EXPORTEXTERN __declspec( dllexport ) extern
#   define Standard_EXPORTEXTERNC extern "C" __declspec( dllexport )
#  endif  /* Standard_EXPORT */

#  ifndef Standard_IMPORT
#   define Standard_IMPORT __declspec( dllimport ) extern
#   define Standard_IMPORTC extern "C" __declspec( dllimport )
#  endif  /* Standard_IMPORT */

// We must be careful including windows.h: it is really poisonous stuff!
// The most annoying are #defines of many identifiers that you could use in
// normal code without knowing that Windows has its own knowledge of them...
// So lets protect ourselves by switching OFF as much as possible of this in advance.
// If someone needs more from windows.h, he is encouraged to #undef these symbols
// or include windows.h prior to any OCCT stuff.
// Note that we define each symbol to itself, so that it still can be used
// e.g. as name of variable, method etc.
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN   /* exclude extra Windows stuff */
#endif
#ifndef NOMINMAX
#define NOMINMAX NOMINMAX     /* avoid #define min() and max() */
#endif
#ifndef NOMSG
#define NOMSG NOMSG           /* avoid #define SendMessage etc. */
#endif
#ifndef NODRAWTEXT
#define NODRAWTEXT NODRAWTEXT /* avoid #define DrawText etc. */
#endif
#ifndef NONLS
#define NONLS NONLS           /* avoid #define CompareString etc. */
#endif
#ifndef NOGDI
#define NOGDI NOGDI           /* avoid #define SetPrinter (winspool.h) etc. */
#endif
#ifndef NOSERVICE
#define NOSERVICE NOSERVICE
#endif
#ifndef NOKERNEL
#define NOKERNEL NOKERNEL
#endif
#ifndef NOUSER
#define NOUSER NOUSER
#endif
#ifndef NOMCX
#define NOMCX NOMCX
#endif
#ifndef NOIME
#define NOIME NOIME
#endif

# else  /* WNT */

//======================================================
// UNIX definitions
//======================================================

#  ifndef Standard_EXPORT
#   define Standard_EXPORT
// For global variables :
#   define Standard_EXPORTEXTERN extern
#   define Standard_EXPORTEXTERNC extern "C"
#  endif  /* Standard_EXPORT */

#  ifndef Standard_IMPORT
#   define Standard_IMPORT extern
#   define Standard_IMPORTC extern "C"
#  endif  /* Standard_IMPORT */

// Compatibility with old SUN compilers

// This preprocessor directive is a kludge to get around
// a bug in the Sun Workshop 5.0 compiler, it keeps the
// /usr/include/memory.h file from being #included
// with an incompatible extern "C" definition of memchr
// October 18, 2000  <rboehne@ricardo-us.com>
#if __SUNPRO_CC_COMPAT == 5
#define	_MEMORY_H
#endif

# endif  /* WNT */

//======================================================
// Other
//======================================================

# ifndef __Standard_API
//#  ifdef WNT
#   if !defined(_WIN32) || defined(__Standard_DLL) || defined(__FSD_DLL) || defined(__MMgt_DLL) || defined(__OSD_DLL) || defined(__Plugin_DLL) || defined(__Quantity_DLL) || defined(__Resource_DLL) || defined(__SortTools_DLL) || defined(__StdFail_DLL) || defined(__Storage_DLL) || defined(__TColStd_DLL) || defined(__TCollection_DLL) || defined(__TShort_DLL) || defined(__Units_DLL) || defined(__UnitsAPI_DLL) || defined(__Dico_DLL) || defined(__Message_DLL)
#    define __Standard_API Standard_EXPORT
#    define __Standard_APIEXTERN Standard_EXPORTEXTERN
#   else
#    define __Standard_API Standard_IMPORT
#    define __Standard_APIEXTERN Standard_IMPORT
#   endif  // __Standard_DLL
//#  else
//#   define __Standard_API
//#  endif  // WNT
# endif  // __Standard_API

#endif
<|endoftext|>


<commit_before>#ifndef AMGCL_PROFILER_H
#define AMGCL_PROFILER_H

/*
The MIT License

Copyright (c) 2012-2019 Denis Demidov <dennis.demidov@gmail.com>

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.
*/

/**
 * \file   amgcl/profiler.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  Profiler class.
 */

#include <iostream>
#include <iomanip>
#include <map>
#include <string>
#include <vector>
#include <type_traits>

#include <amgcl/perf_counter/clock.hpp>

namespace amgcl {

/// Profiler class.
/**
 * \param Counter     Performance counter to use for profiling.
 * \param SHIFT_WIDTH Indentation for output of profiling results.
 *
 * Provides simple to use, hierarchical profile with nicely formatted output.
 */
template <class Counter = amgcl::perf_counter::clock, unsigned SHIFT_WIDTH = 2>
class profiler {
    public:
        typedef typename Counter::value_type value_type;
        typedef double delta_type;

        /// Initialization.
        /**
         */
        profiler() : name("Profile") {
            init();
        }

        /// Send additional parameters to counter.
        /**
         * \param name Profile title to use with output.
         * \param args Counter arguments.
         */
        template <class... Args>
        profiler(const std::string &name, Args&&... args)
            : name(name), counter(std::forward<Args>(args)...)
        {
            init();
        }

        /// Starts measurement.
        /**
         * \param name interval name.
         */
        void tic(const std::string &name) {
            stack.back()->children[name].begin = counter.current();
            stack.push_back(&stack.back()->children[name]);
        }

        /// Stops measurement.
        /**
         * Returns delta in the measured value since the corresponding tic().
         */
        delta_type toc(const std::string& /*name*/ = "") {
            profile_unit *top = stack.back();
            stack.pop_back();

            value_type current = counter.current();
            delta_type delta   = current - top->begin;

            top->length += delta;
            root.length = current - root.begin;

            return delta;
        }

        void reset() {
            stack.clear();
            root.length = 0;
            root.children.clear();

            stack.push_back(&root);
            root.begin = counter.current();
        }

        struct scoped_ticker {
            profiler &prof;
            scoped_ticker(profiler &prof) : prof(prof) {}
            ~scoped_ticker() {
                prof.toc();
            }
        };

        scoped_ticker scoped_tic(const std::string &name) {
            tic(name);
            return scoped_ticker(*this);
        }
    private:
        struct profile_unit {
            profile_unit() : length(0) {}

            delta_type children_time() const {
                delta_type s = delta_type();
                for(typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
                    s += c->second.length;
                return s;
            }

            size_t total_width(const std::string &name, int level) const {
                size_t w = name.size() + level;
                for(typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
                    w = std::max(w, c->second.total_width(c->first, level + SHIFT_WIDTH));
                return w;
            }

            void print(std::ostream &out, const std::string &name,
                    int level, delta_type total, size_t width) const
            {
                using namespace std;

                out << "[" << setw(level) << "";
                print_line(out, name, length, 100 * length / total, width - level);

                if (children.size()) {
                    delta_type val = length - children_time();
                    double perc = 100.0 * val / total;

                    if (perc > 1e-1) {
                        out << "[" << setw(level + 1) << "";
                        print_line(out, "self", val, perc, width - level - 1);
                    }
                }

                for(typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
                    c->second.print(out, c->first, level + SHIFT_WIDTH, total, width);
            }

            void print_line(std::ostream &out, const std::string &name,
                    delta_type time, double perc, size_t width) const
            {
                using namespace std;

                out << name << ":"
                    << setw(width - name.size()) << ""
                    << setw(10)
                    << fixed << setprecision(3) << time << " " << Counter::units()
                    << "] (" << fixed << setprecision(2) << setw(6) << perc << "%)"
                    << endl;
            }

            value_type begin;
            delta_type length;

            std::map<std::string, profile_unit> children;
        };

        Counter counter;
        std::string name;
        profile_unit root;
        std::vector<profile_unit*> stack;

        void init() {
            stack.reserve(128);
            stack.push_back(&root);
            root.begin = counter.current();
        }

        void print(std::ostream &out) {
            if (stack.back() != &root)
                out << "Warning! Profile is incomplete." << std::endl;

            std::ios_base::fmtflags ff(out.flags());
            auto fp = out.precision();

            root.print(out, name, 0, root.length, root.total_width(name, 0));

            out.flags(ff);
            out.precision(fp);
        }

        /// Sends formatted profiling data to an output stream.
        /**
         * \param out  Output stream.
         * \param prof Profiler.
         */
        friend std::ostream& operator<<(std::ostream &out, profiler &prof) {
            out << std::endl;
            prof.print(out);
            return out << std::endl;
        }
};

} // namespace amgcl

#endif
<commit_msg>Get rid of -Wreorder warning in profiler<commit_after>#ifndef AMGCL_PROFILER_H
#define AMGCL_PROFILER_H

/*
The MIT License

Copyright (c) 2012-2019 Denis Demidov <dennis.demidov@gmail.com>

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.
*/

/**
 * \file   amgcl/profiler.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  Profiler class.
 */

#include <iostream>
#include <iomanip>
#include <map>
#include <string>
#include <vector>
#include <type_traits>

#include <amgcl/perf_counter/clock.hpp>

namespace amgcl {

/// Profiler class.
/**
 * \param Counter     Performance counter to use for profiling.
 * \param SHIFT_WIDTH Indentation for output of profiling results.
 *
 * Provides simple to use, hierarchical profile with nicely formatted output.
 */
template <class Counter = amgcl::perf_counter::clock, unsigned SHIFT_WIDTH = 2>
class profiler {
    public:
        typedef typename Counter::value_type value_type;
        typedef double delta_type;

        /// Initialization.
        /**
         */
        profiler() : name("Profile") {
            init();
        }

        /// Send additional parameters to counter.
        /**
         * \param name Profile title to use with output.
         * \param args Counter arguments.
         */
        template <class... Args>
        profiler(const std::string &name, Args&&... args)
            : name(name), counter(std::forward<Args>(args)...)
        {
            init();
        }

        /// Starts measurement.
        /**
         * \param name interval name.
         */
        void tic(const std::string &name) {
            stack.back()->children[name].begin = counter.current();
            stack.push_back(&stack.back()->children[name]);
        }

        /// Stops measurement.
        /**
         * Returns delta in the measured value since the corresponding tic().
         */
        delta_type toc(const std::string& /*name*/ = "") {
            profile_unit *top = stack.back();
            stack.pop_back();

            value_type current = counter.current();
            delta_type delta   = current - top->begin;

            top->length += delta;
            root.length = current - root.begin;

            return delta;
        }

        void reset() {
            stack.clear();
            root.length = 0;
            root.children.clear();

            stack.push_back(&root);
            root.begin = counter.current();
        }

        struct scoped_ticker {
            profiler &prof;
            scoped_ticker(profiler &prof) : prof(prof) {}
            ~scoped_ticker() {
                prof.toc();
            }
        };

        scoped_ticker scoped_tic(const std::string &name) {
            tic(name);
            return scoped_ticker(*this);
        }
    private:
        struct profile_unit {
            profile_unit() : length(0) {}

            delta_type children_time() const {
                delta_type s = delta_type();
                for(typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
                    s += c->second.length;
                return s;
            }

            size_t total_width(const std::string &name, int level) const {
                size_t w = name.size() + level;
                for(typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
                    w = std::max(w, c->second.total_width(c->first, level + SHIFT_WIDTH));
                return w;
            }

            void print(std::ostream &out, const std::string &name,
                    int level, delta_type total, size_t width) const
            {
                using namespace std;

                out << "[" << setw(level) << "";
                print_line(out, name, length, 100 * length / total, width - level);

                if (children.size()) {
                    delta_type val = length - children_time();
                    double perc = 100.0 * val / total;

                    if (perc > 1e-1) {
                        out << "[" << setw(level + 1) << "";
                        print_line(out, "self", val, perc, width - level - 1);
                    }
                }

                for(typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
                    c->second.print(out, c->first, level + SHIFT_WIDTH, total, width);
            }

            void print_line(std::ostream &out, const std::string &name,
                    delta_type time, double perc, size_t width) const
            {
                using namespace std;

                out << name << ":"
                    << setw(width - name.size()) << ""
                    << setw(10)
                    << fixed << setprecision(3) << time << " " << Counter::units()
                    << "] (" << fixed << setprecision(2) << setw(6) << perc << "%)"
                    << endl;
            }

            value_type begin;
            delta_type length;

            std::map<std::string, profile_unit> children;
        };

        std::string name;
        Counter counter;
        profile_unit root;
        std::vector<profile_unit*> stack;

        void init() {
            stack.reserve(128);
            stack.push_back(&root);
            root.begin = counter.current();
        }

        void print(std::ostream &out) {
            if (stack.back() != &root)
                out << "Warning! Profile is incomplete." << std::endl;

            std::ios_base::fmtflags ff(out.flags());
            auto fp = out.precision();

            root.print(out, name, 0, root.length, root.total_width(name, 0));

            out.flags(ff);
            out.precision(fp);
        }

        /// Sends formatted profiling data to an output stream.
        /**
         * \param out  Output stream.
         * \param prof Profiler.
         */
        friend std::ostream& operator<<(std::ostream &out, profiler &prof) {
            out << std::endl;
            prof.print(out);
            return out << std::endl;
        }
};

} // namespace amgcl

#endif
<|endoftext|>


<commit_before>#include "VideodrommControllerApp.h"

/*
TODO
- 2802 imgui contextual window depending on mouseover
- 2802 imgui vertical : textures
- flip horiz
- check flip H and V (spout also)
- sort fbo names and indexes (warps only 4 or 5 inputs)
- spout texture 10 create shader 10.glsl(ThemeFromBrazil) iChannel0
- warpwrapper handle texture mode 0 for spout (without fbo)
- put sliderInt instead of popups //warps next
- proper slitscan h and v //wip
- proper rotation
- badtv in mix.frag

tempo 142
bpm = (60 * fps) / fpb

where bpm = beats per min
fps = frames per second
fpb = frames per beat

fpb = 4, bpm = 142
fps = 142 / 60 * 4 = 9.46
*/

void VideodrommControllerApp::prepare(Settings *settings)
{
	settings->setWindowSize(40, 10);
	settings->setBorderless();
}
void VideodrommControllerApp::setup()
{
	CI_LOG_V("Controller");
	// Settings
	mVDSettings = VDSettings::create();
	// Session
	mVDSession = VDSession::create(mVDSettings);

	setFrameRate(mVDSession->getTargetFps());
	mMovieDelay = mFadeInDelay = true;
	mVDSession->getWindowsResolution();

	getWindow()->getSignalResize().connect(std::bind(&VideodrommControllerApp::resizeWindow, this));
	getWindow()->getSignalDraw().connect(std::bind(&VideodrommControllerApp::drawRenderWindow, this));

	// mouse cursor and ui
	setUIVisibility(mVDSettings->mCursorVisible);
	// UI
	mVDUI = VDUI::create(mVDSettings, mVDSession);

	setFrameRate(mVDSession->getTargetFps());
	CI_LOG_V("setup");

}
void VideodrommControllerApp::createControlWindow()
{
	mVDUI->resize();

	deleteControlWindows();
	mVDSession->getWindowsResolution();

	mVDSettings->iResolution.x = mVDSettings->mRenderWidth;
	mVDSettings->iResolution.y = mVDSettings->mRenderHeight;

	CI_LOG_V("createRenderWindow, resolution:" + toString(mVDSettings->iResolution.x) + "x" + toString(mVDSettings->iResolution.y));

	string windowName = "render";
	// OK mControlWindow = createWindow(Window::Format().size(mVDSettings->mMainWindowWidth, mVDSettings->mMainWindowHeight));
	mControlWindow = createWindow(Window::Format().size(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight));
	mControlWindow->setPos(mVDSettings->mMainWindowX, mVDSettings->mMainWindowY);
	//mControlWindow->setBorderless();
	mControlWindow->getSignalDraw().connect(std::bind(&VideodrommControllerApp::drawControlWindow, this));
	mControlWindow->getSignalResize().connect(std::bind(&VideodrommControllerApp::resizeWindow, this));

	// create instance of the window and store in vector
	allWindows.push_back(mControlWindow);
	mVDSettings->mRenderPosXY = ivec2(mVDSettings->mRenderX, mVDSettings->mRenderY);
}

void VideodrommControllerApp::deleteControlWindows()
{
#if defined( CINDER_MSW )
	for (auto wRef : allWindows) DestroyWindow((HWND)mControlWindow->getNative());
#endif
	allWindows.clear();
}
void VideodrommControllerApp::cleanup()
{
	CI_LOG_V("shutdown");
	mVDSettings->save();
	mVDSession->save();
	ui::Shutdown();
	quit();
}

void VideodrommControllerApp::resizeWindow()
{
	CI_LOG_V("rs");

	mVDUI->resize();
	if (mVDSettings->mStandalone) {
		// set ui window and io events callbacks
		ui::disconnectWindow(getWindow());
	}
	else {
		ui::disconnectWindow(mControlWindow);
	}
	mVDSession->resize();

}

void VideodrommControllerApp::mouseMove(MouseEvent event)
{
	if (!mVDSession->handleMouseMove(event)) {
		// let your application perform its mouseMove handling here
	}
}

void VideodrommControllerApp::mouseDown(MouseEvent event)
{
	if (!mVDSession->handleMouseDown(event)) {
		// let your application perform its mouseDown handling here
	}
}

void VideodrommControllerApp::mouseDrag(MouseEvent event)
{
	if (!mVDSession->handleMouseDrag(event)) {
		// let your application perform its mouseDrag handling here
	}
}

void VideodrommControllerApp::mouseUp(MouseEvent event)
{
	if (!mVDSession->handleMouseUp(event)) {
		// let your application perform its mouseUp handling here
	}
}

void VideodrommControllerApp::keyDown(KeyEvent event)
{
#if defined( CINDER_COCOA )
	bool isModDown = event.isMetaDown();
#else // windows
	bool isModDown = event.isControlDown();
#endif
	if (isModDown) {
		switch (event.getCode()) {
		case KeyEvent::KEY_r:
			// quit the application
			createControlWindow();
			break;
		case KeyEvent::KEY_d:
			// quit the application
			if (isModDown) deleteControlWindows();
			break;
		}
	}
	else {
		if (!mVDSession->handleKeyDown(event)) {
			switch (event.getCode()) {
			case KeyEvent::KEY_ESCAPE:
				// quit the application
				quit();
				break;
			case KeyEvent::KEY_h:
				// mouse cursor and ui visibility
				mVDSettings->mCursorVisible = !mVDSettings->mCursorVisible;
				setUIVisibility(mVDSettings->mCursorVisible);
				break;
			}
		}
	}
}
void VideodrommControllerApp::keyUp(KeyEvent event)
{
	if (!mVDSession->handleKeyUp(event)) {
	}
}
void VideodrommControllerApp::setUIVisibility(bool visible)
{
	if (visible)
	{
		showCursor();
	}
	else
	{
		hideCursor();
	}
}

void VideodrommControllerApp::update()
{
	CI_LOG_V("up");

	mVDSession->setControlValue(20, getAverageFps());
	mVDSession->update();
	/* obsolete check if a shader has been received from websockets
	if (mVDSettings->mShaderToLoad != "") {
	mVDSession->loadFboFragmentShader(mVDSettings->mShaderToLoad, 1);
	}*/
}
void VideodrommControllerApp::fileDrop(FileDropEvent event)
{
	mVDSession->fileDrop(event);
}

void VideodrommControllerApp::drawRenderWindow()
{
	CI_LOG_V("dr");

	getWindow()->setTitle("(" + mVDSettings->sFps + " fps) " + toString(mVDSettings->iBeat) + " Videodromm");
	//renderSceneToFbo();
	if (mFadeInDelay) {
		mVDSettings->iAlpha = 0.0f;
		if (getElapsedFrames() > mVDSession->getFadeInDelay()) {
			mFadeInDelay = false;
			setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);
			setWindowPos(ivec2(mVDSettings->mRenderX, mVDSettings->mRenderY));
			timeline().apply(&mVDSettings->iAlpha, 0.0f, 1.0f, 1.5f, EaseInCubic());
		}
	}
	/*if (mMovieDelay) {
		if (getElapsedFrames() > mVDSession->getMoviePlaybackDelay()) {
		mMovieDelay = false;
		fs::path movieFile = getAssetPath("") / mVDSettings->mAssetsPath / mVDSession->getMovieFileName();
		mVDTextures->loadMovie(0, movieFile.string());
		}
		}*/
	gl::clear(Color::black());
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
}

void VideodrommControllerApp::drawControlWindow()
{
	CI_LOG_V("dc");

	gl::clear(Color::black());
	//gl::color(Color::white());
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	gl::draw(mVDSession->getMixTexture(), Rectf(10 + mVDSettings->uiLargeW, 170, 650 + mVDSettings->uiLargeW, 650));
	//gl::draw(mVDSession->getMixTexture(), Rectf(0, 170, 350 , 350));

	// imgui
	mVDUI->Run("UI", (int)getAverageFps());
	if (mVDUI->isReady()) {
	}
}

CINDER_APP(VideodrommControllerApp, RendererGl, &VideodrommControllerApp::prepare)
<commit_msg>warps resize at the end<commit_after>#include "VideodrommControllerApp.h"

/*
TODO
- 2802 imgui contextual window depending on mouseover
- 2802 imgui vertical : textures
- flip horiz
- check flip H and V (spout also)
- sort fbo names and indexes (warps only 4 or 5 inputs)
- spout texture 10 create shader 10.glsl(ThemeFromBrazil) iChannel0
- warpwrapper handle texture mode 0 for spout (without fbo)
- put sliderInt instead of popups //warps next
- proper slitscan h and v //wip
- proper rotation
- badtv in mix.frag

tempo 142
bpm = (60 * fps) / fpb

where bpm = beats per min
fps = frames per second
fpb = frames per beat

fpb = 4, bpm = 142
fps = 142 / 60 * 4 = 9.46
*/

void VideodrommControllerApp::prepare(Settings *settings)
{
	settings->setWindowSize(40, 10);
	settings->setBorderless();
}
void VideodrommControllerApp::setup()
{
	CI_LOG_V("Controller");
	// Settings
	mVDSettings = VDSettings::create();
	// Session
	mVDSession = VDSession::create(mVDSettings);

	setFrameRate(mVDSession->getTargetFps());
	mMovieDelay = mFadeInDelay = true;
	mVDSession->getWindowsResolution();

	getWindow()->getSignalResize().connect(std::bind(&VideodrommControllerApp::resizeWindow, this));
	getWindow()->getSignalDraw().connect(std::bind(&VideodrommControllerApp::drawRenderWindow, this));

	// mouse cursor and ui
	setUIVisibility(mVDSettings->mCursorVisible);
	// UI
	mVDUI = VDUI::create(mVDSettings, mVDSession);

	setFrameRate(mVDSession->getTargetFps());
	CI_LOG_V("setup");
}
void VideodrommControllerApp::createControlWindow()
{
	mVDUI->resize();

	deleteControlWindows();
	mVDSession->getWindowsResolution();

	mVDSettings->iResolution.x = mVDSettings->mRenderWidth;
	mVDSettings->iResolution.y = mVDSettings->mRenderHeight;

	CI_LOG_V("createRenderWindow, resolution:" + toString(mVDSettings->iResolution.x) + "x" + toString(mVDSettings->iResolution.y));

	string windowName = "render";
	// OK mControlWindow = createWindow(Window::Format().size(mVDSettings->mMainWindowWidth, mVDSettings->mMainWindowHeight));
	mControlWindow = createWindow(Window::Format().size(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight));
	mControlWindow->setPos(mVDSettings->mMainWindowX, mVDSettings->mMainWindowY);
	//mControlWindow->setBorderless();
	mControlWindow->getSignalDraw().connect(std::bind(&VideodrommControllerApp::drawControlWindow, this));
	mControlWindow->getSignalResize().connect(std::bind(&VideodrommControllerApp::resizeWindow, this));

	// create instance of the window and store in vector
	allWindows.push_back(mControlWindow);
	mVDSettings->mRenderPosXY = ivec2(mVDSettings->mRenderX, mVDSettings->mRenderY);
}

void VideodrommControllerApp::deleteControlWindows()
{
#if defined( CINDER_MSW )
	for (auto wRef : allWindows) DestroyWindow((HWND)mControlWindow->getNative());
#endif
	allWindows.clear();
}
void VideodrommControllerApp::cleanup()
{
	CI_LOG_V("shutdown");
	mVDSettings->save();
	mVDSession->save();
	ui::Shutdown();
	quit();
}

void VideodrommControllerApp::resizeWindow()
{
	mVDUI->resize();
	if (mVDSettings->mStandalone) {
		// set ui window and io events callbacks
		ui::disconnectWindow(getWindow());
	}
	else {
		ui::disconnectWindow(mControlWindow);
	}
}

void VideodrommControllerApp::mouseMove(MouseEvent event)
{
	if (!mVDSession->handleMouseMove(event)) {
		// let your application perform its mouseMove handling here
	}
}

void VideodrommControllerApp::mouseDown(MouseEvent event)
{
	if (!mVDSession->handleMouseDown(event)) {
		// let your application perform its mouseDown handling here
	}
}

void VideodrommControllerApp::mouseDrag(MouseEvent event)
{
	if (!mVDSession->handleMouseDrag(event)) {
		// let your application perform its mouseDrag handling here
	}
}

void VideodrommControllerApp::mouseUp(MouseEvent event)
{
	if (!mVDSession->handleMouseUp(event)) {
		// let your application perform its mouseUp handling here
	}
}

void VideodrommControllerApp::keyDown(KeyEvent event)
{
#if defined( CINDER_COCOA )
	bool isModDown = event.isMetaDown();
#else // windows
	bool isModDown = event.isControlDown();
#endif
	if (isModDown) {
		switch (event.getCode()) {
		case KeyEvent::KEY_r:
			// quit the application
			createControlWindow();
			break;
		case KeyEvent::KEY_d:
			// quit the application
			if (isModDown) deleteControlWindows();
			break;
		}
	}
	else {
		if (!mVDSession->handleKeyDown(event)) {
			switch (event.getCode()) {
			case KeyEvent::KEY_ESCAPE:
				// quit the application
				quit();
				break;
			case KeyEvent::KEY_h:
				// mouse cursor and ui visibility
				mVDSettings->mCursorVisible = !mVDSettings->mCursorVisible;
				setUIVisibility(mVDSettings->mCursorVisible);
				break;
			}
		}
	}
}
void VideodrommControllerApp::keyUp(KeyEvent event)
{
	if (!mVDSession->handleKeyUp(event)) {
	}
}
void VideodrommControllerApp::setUIVisibility(bool visible)
{
	if (visible)
	{
		showCursor();
	}
	else
	{
		hideCursor();
	}
}

void VideodrommControllerApp::update()
{
	mVDSession->setControlValue(20, getAverageFps());
	mVDSession->update();
	/* obsolete check if a shader has been received from websockets
	if (mVDSettings->mShaderToLoad != "") {
	mVDSession->loadFboFragmentShader(mVDSettings->mShaderToLoad, 1);
	}*/
}
void VideodrommControllerApp::fileDrop(FileDropEvent event)
{
	mVDSession->fileDrop(event);
}

void VideodrommControllerApp::drawRenderWindow()
{
	getWindow()->setTitle("(" + mVDSettings->sFps + " fps) " + toString(mVDSettings->iBeat) + " Videodromm");
	//renderSceneToFbo();
	if (mFadeInDelay) {
		mVDSettings->iAlpha = 0.0f;
		if (getElapsedFrames() > mVDSession->getFadeInDelay()) {
			mFadeInDelay = false;
			setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);
			setWindowPos(ivec2(mVDSettings->mRenderX, mVDSettings->mRenderY));
			// warps resize at the end
			mVDSession->resize();
			timeline().apply(&mVDSettings->iAlpha, 0.0f, 1.0f, 1.5f, EaseInCubic());
		}
	}
	/*if (mMovieDelay) {
		if (getElapsedFrames() > mVDSession->getMoviePlaybackDelay()) {
		mMovieDelay = false;
		fs::path movieFile = getAssetPath("") / mVDSettings->mAssetsPath / mVDSession->getMovieFileName();
		mVDTextures->loadMovie(0, movieFile.string());
		}
		}*/
	gl::clear(Color::black());
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
}

void VideodrommControllerApp::drawControlWindow()
{
	CI_LOG_V("dc");

	gl::clear(Color::black());
	//gl::color(Color::white());
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	gl::draw(mVDSession->getMixTexture(), Rectf(10 + mVDSettings->uiLargeW, 170, 650 + mVDSettings->uiLargeW, 650));
	//gl::draw(mVDSession->getMixTexture(), Rectf(0, 170, 350 , 350));

	// imgui
	mVDUI->Run("UI", (int)getAverageFps());
	if (mVDUI->isReady()) {
	}
}

CINDER_APP(VideodrommControllerApp, RendererGl, &VideodrommControllerApp::prepare)
<|endoftext|>