<commit_before>/*
* Copyright (c) 2013 Fredrik Mellbin
*
* This file is part of VapourSynth.
*
* VapourSynth 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.
*
* VapourSynth 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 VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
#include <QtCore/QWaitCondition>
#include <QtCore/QFile>
#include <QtCore/QMap>
#include "VSScript.h"
#include "VSHelper.h"

const VSAPI *vsapi = NULL;
VSScript *se = NULL;
VSNodeRef *node = NULL;
FILE *outfile = NULL;

int requests = 0;
int index = 0;
int outputFrames = 0;
int requestedFrames = 0;
int completedFrames = 0;
int totalFrames = 0;
int numPlanes = 0;
bool y4m = false;
bool outputError = false;
QMap<int, const VSFrameRef *> reorderMap;

QString errorMessage;
QWaitCondition condition;
QMutex mutex;

void VS_CC frameDoneCallback(void *userData, const VSFrameRef *f, int n, VSNodeRef *, const char *errorMsg) {
    completedFrames++;

    if (f) {
        reorderMap.insert(n, f);
        while (reorderMap.contains(outputFrames)) {
            const VSFrameRef *frame = reorderMap.take(outputFrames);
            if (outputError)
                goto fwriteError;
            if (y4m) {
                if (!fwrite("FRAME\n", 6, 1, outfile)) {
                    errorMessage = "Error: fwrite() call failed";
                    totalFrames = requestedFrames;
                    outputError = true;
                    goto fwriteError;
                }
            }

            const VSFormat *fi = vsapi->getFrameFormat(frame);
            for (int p = 0; p < fi->numPlanes; p++) {
                int stride = vsapi->getStride(frame, p);
                const uint8_t *readPtr = vsapi->getReadPtr(frame, p);
                int rowSize = vsapi->getFrameWidth(frame, p) * fi->bytesPerSample;
                int height = vsapi->getFrameHeight(frame, p);
                for (int y = 0; y < height; y++) {
                    if (!fwrite(readPtr, rowSize, 1, outfile)) {
                        errorMessage = "Error: fwrite() call failed";
                        totalFrames = requestedFrames;
                        outputError = true;
                        goto fwriteError;
                    }
                    readPtr += stride;
                }
            }
            fwriteError:
            vsapi->freeFrame(frame);
            outputFrames++;
        }
    } else {
        outputError = true;
        totalFrames = requestedFrames;
        if (errorMsg)
            errorMessage = QString("Error: Failed to retrieve frame ") + n + QString(" with error: ") + QString::fromUtf8(errorMsg);
        else
            errorMessage = QString("Error: Failed to retrieve frame ") + n;
    }

    if (requestedFrames < totalFrames) {
        vsapi->getFrameAsync(requestedFrames, node, frameDoneCallback, NULL);
        requestedFrames++;
    }

    if (totalFrames == completedFrames) {
        QMutexLocker lock(&mutex);
        condition.wakeOne();
    }
}

bool outputNode() {
    if (requests < 1) {
		const VSCoreInfo *info = vsapi->getCoreInfo(vseval_getCore());
        requests = info->numThreads;
	}

	const VSVideoInfo *vi = vsapi->getVideoInfo(node);
	totalFrames = vi->numFrames;

	if (y4m && (vi->format->colorFamily != cmGray && vi->format->colorFamily != cmYUV)) {
		errorMessage = "Error: Can only apply y4m headers to YUV and Gray format clips";
		fprintf(stderr, "%s", errorMessage.toUtf8().constData());
        outputError = true;
		return outputError;
	}

    QString y4mFormat;
    QString numBits;

    if (y4m) {
        if (vi->format->colorFamily == cmGray) {
            y4mFormat = "mono";
            if (vi->format->bitsPerSample > 8)
				y4mFormat = y4mFormat + QString::number(vi->format->bitsPerSample);
		} else if (vi->format->colorFamily == cmYUV) {
			if (vi->format->subSamplingW == 1 && vi->format->subSamplingH == 1)
                y4mFormat = "420";
			else if (vi->format->subSamplingW == 1 && vi->format->subSamplingH == 0)
                y4mFormat = "422";
			else if (vi->format->subSamplingW == 0 && vi->format->subSamplingH == 0)
                y4mFormat = "444";
			else if (vi->format->subSamplingW == 2 && vi->format->subSamplingH == 2)
                y4mFormat = "410";
			else if (vi->format->subSamplingW == 2 && vi->format->subSamplingH == 0)
                y4mFormat = "411";
			else if (vi->format->subSamplingW == 0 && vi->format->subSamplingH == 1)
                y4mFormat = "440";
            if (vi->format->bitsPerSample > 8)
                y4mFormat = y4mFormat + "p" + QString::number(vi->format->bitsPerSample);
		}
    }
	if (!y4mFormat.isEmpty())
        y4mFormat = "C" + y4mFormat + " ";

	QString header = "YUV4MPEG2 " + y4mFormat + "W" + QString::number(vi->width) + " H" + QString::number(vi->height) + " F" + QString::number(vi->fpsNum)  + ":" + QString::number(vi->fpsDen)  + " Ip A0:0\n";
    QByteArray rawHeader = header.toUtf8();

    if (y4m) {
        if (!fwrite(rawHeader.constData(), rawHeader.size(), 1, outfile)) {
            errorMessage = "Error: fwrite() call failed";
			fprintf(stderr, "%s", errorMessage.toUtf8().constData());
			outputError = true;
			return outputError;
        }
    }

	QMutexLocker lock(&mutex);

	int intitalRequestSize = std::min(requests, totalFrames);
	requestedFrames = intitalRequestSize;
	for (int n = 0; n < intitalRequestSize; n++)
		vsapi->getFrameAsync(n, node, frameDoneCallback, NULL);

	condition.wait(&mutex);

    if (outputError) {
        fprintf(stderr, "%s", errorMessage.toUtf8().constData());
    }

    return outputError;
}

// script output y4m index requests
#ifdef _WIN32
int wmain(int argc, wchar_t **argv) {
#else
int main(int argc, char **argv) {
#endif

    if (argc < 3) {
        fprintf(stderr, "VSPipe\n");
        fprintf(stderr, "Write to stdout: vspipe script.vpy - [options]\n");
        fprintf(stderr, "Write to file: vspipe script.vpy <outfile> [options]\n");
        fprintf(stderr, "Available options:\n");
		fprintf(stderr, "Select output index: -index N (default: 0)\n");
		fprintf(stderr, "Set number of concurrent frame requests: -requests N (default: number of threads)\n");
		fprintf(stderr, "Add YUV4MPEG headers: -y4m (default: off)\n");
        return 1;
    }

	for (int arg = 3; arg < argc; arg++) {
		QString argString = QString::fromWCharArray(argv[arg]);;
		if (argString == "-y4m") {
			y4m = true;
		} else if (argString == "-index") {
			bool ok = false;
			if (argc <= arg + 1) {
				fprintf(stderr, "No index number specified");
				return 1;
			}
			QString numString = QString::fromWCharArray(argv[arg+1]);
			index = numString.toInt(&ok);
			if (!ok) {
				fprintf(stderr, "Couldn't convert %s to an integer", numString.toUtf8().constData());
				return 1;
			}
			arg++;
		} else if (argString == "-requests") {
			bool ok = false;
			if (argc <= arg + 1) {
				fprintf(stderr, "No request number specified");
				return 1;
			}
			QString numString = QString::fromWCharArray(argv[arg+1]);
			requests = numString.toInt(&ok);
			if (!ok) {
				fprintf(stderr, "Couldn't convert %s to an integer", numString.toUtf8().constData());
				return 1;
			}
			arg++;
		} else {
			fprintf(stderr, "Unknown argument: %s\n", argString.toUtf8().constData());
			return 1;
		}
	}

    if (!vseval_init()) {
        fprintf(stderr, "Failed to initialize VapourSynth environment\n");
        return 1;
    }

    vsapi = vseval_getVSApi();
    if (!vsapi) {
        fprintf(stderr, "Failed to get VapourSynth API\n");
        vseval_finalize();
        return 1;
    }

	QFile scriptFile(QString::fromWCharArray(argv[1]));
	if (!scriptFile.open(QIODevice::ReadOnly)) {
        fprintf(stderr, "Failed to to open script file for reading\n");
        vseval_finalize();
        return 1;
	}

	if (scriptFile.size() > 1024*1024*16) {
        fprintf(stderr, "Script files bigger than 16MB not allowed\n");
        vseval_finalize();
        return 1;
	}

    QByteArray scriptData = scriptFile.readAll();
    if (scriptData.isEmpty()) {
        fprintf(stderr, "Failed to read script file or file is empty\n");
        vseval_finalize();
        return 1;
    }

	if (vseval_evaluateScript(&se, scriptData.constData(), QString::fromWCharArray(argv[1]).toUtf8())) {
        fprintf(stderr, "Script evaluation failed:\n%s", vseval_getError(se));
        vseval_freeScript(se);
        vseval_finalize();
        return 1;
    }

    node = vseval_getOutput(se, index);
    if (!node) {
       fprintf(stderr, "Failed to retrieve output node. Invalid index specified?\n");
       vseval_freeScript(se);
       vseval_finalize();
       return 1;
    }

    const VSVideoInfo *vi = vsapi->getVideoInfo(node);
    if (!isConstantFormat(vi) || vi->numFrames == 0) {
        fprintf(stderr, "Cannot output clips with varying dimensions or unknown length\n");
        vseval_freeScript(se);
        vseval_finalize();
        return 1;
    }

    outfile = stdout;

	bool error = outputNode();

    vseval_freeScript(se);
    vseval_finalize();

	return error ? 1 : 0;
}

/*
VapourSynthFile::~VapourSynthFile() {
    if (vi) {
        vi = NULL;
		while (pending_requests > 0) {};
		vseval_freeScript(se);
    }
}
*/
<commit_msg>Proper unicode support in vspipe<commit_after>/*
* Copyright (c) 2013 Fredrik Mellbin
*
* This file is part of VapourSynth.
*
* VapourSynth 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.
*
* VapourSynth 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 VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
#include <QtCore/QWaitCondition>
#include <QtCore/QFile>
#include <QtCore/QMap>
#include "VSScript.h"
#include "VSHelper.h"

#ifdef _WIN32
static inline QString nativeToQString(const wchar_t *str) {
	return QString::fromWCharArray(str);
}
#else
static inline QString nativeToQString(const char *str) {
	return QString::fromLocal8Bit(str);
}
#endif

const VSAPI *vsapi = NULL;
VSScript *se = NULL;
VSNodeRef *node = NULL;
FILE *outfile = NULL;

int requests = 0;
int index = 0;
int outputFrames = 0;
int requestedFrames = 0;
int completedFrames = 0;
int totalFrames = 0;
int numPlanes = 0;
bool y4m = false;
bool outputError = false;
QMap<int, const VSFrameRef *> reorderMap;

QString errorMessage;
QWaitCondition condition;
QMutex mutex;

void VS_CC frameDoneCallback(void *userData, const VSFrameRef *f, int n, VSNodeRef *, const char *errorMsg) {
    completedFrames++;

    if (f) {
        reorderMap.insert(n, f);
        while (reorderMap.contains(outputFrames)) {
            const VSFrameRef *frame = reorderMap.take(outputFrames);
            if (outputError)
                goto fwriteError;
            if (y4m) {
                if (!fwrite("FRAME\n", 6, 1, outfile)) {
                    errorMessage = "Error: fwrite() call failed";
                    totalFrames = requestedFrames;
                    outputError = true;
                    goto fwriteError;
                }
            }

            const VSFormat *fi = vsapi->getFrameFormat(frame);
            for (int p = 0; p < fi->numPlanes; p++) {
                int stride = vsapi->getStride(frame, p);
                const uint8_t *readPtr = vsapi->getReadPtr(frame, p);
                int rowSize = vsapi->getFrameWidth(frame, p) * fi->bytesPerSample;
                int height = vsapi->getFrameHeight(frame, p);
                for (int y = 0; y < height; y++) {
                    if (!fwrite(readPtr, rowSize, 1, outfile)) {
                        errorMessage = "Error: fwrite() call failed";
                        totalFrames = requestedFrames;
                        outputError = true;
                        goto fwriteError;
                    }
                    readPtr += stride;
                }
            }
            fwriteError:
            vsapi->freeFrame(frame);
            outputFrames++;
        }
    } else {
        outputError = true;
        totalFrames = requestedFrames;
        if (errorMsg)
            errorMessage = QString("Error: Failed to retrieve frame ") + n + QString(" with error: ") + QString::fromUtf8(errorMsg);
        else
            errorMessage = QString("Error: Failed to retrieve frame ") + n;
    }

    if (requestedFrames < totalFrames) {
        vsapi->getFrameAsync(requestedFrames, node, frameDoneCallback, NULL);
        requestedFrames++;
    }

    if (totalFrames == completedFrames) {
        QMutexLocker lock(&mutex);
        condition.wakeOne();
    }
}

bool outputNode() {
    if (requests < 1) {
		const VSCoreInfo *info = vsapi->getCoreInfo(vseval_getCore());
        requests = info->numThreads;
	}

	const VSVideoInfo *vi = vsapi->getVideoInfo(node);
	totalFrames = vi->numFrames;

	if (y4m && (vi->format->colorFamily != cmGray && vi->format->colorFamily != cmYUV)) {
		errorMessage = "Error: Can only apply y4m headers to YUV and Gray format clips";
		fprintf(stderr, "%s", errorMessage.toUtf8().constData());
        outputError = true;
		return outputError;
	}

    QString y4mFormat;
    QString numBits;

    if (y4m) {
        if (vi->format->colorFamily == cmGray) {
            y4mFormat = "mono";
            if (vi->format->bitsPerSample > 8)
				y4mFormat = y4mFormat + QString::number(vi->format->bitsPerSample);
		} else if (vi->format->colorFamily == cmYUV) {
			if (vi->format->subSamplingW == 1 && vi->format->subSamplingH == 1)
                y4mFormat = "420";
			else if (vi->format->subSamplingW == 1 && vi->format->subSamplingH == 0)
                y4mFormat = "422";
			else if (vi->format->subSamplingW == 0 && vi->format->subSamplingH == 0)
                y4mFormat = "444";
			else if (vi->format->subSamplingW == 2 && vi->format->subSamplingH == 2)
                y4mFormat = "410";
			else if (vi->format->subSamplingW == 2 && vi->format->subSamplingH == 0)
                y4mFormat = "411";
			else if (vi->format->subSamplingW == 0 && vi->format->subSamplingH == 1)
                y4mFormat = "440";
            if (vi->format->bitsPerSample > 8)
                y4mFormat = y4mFormat + "p" + QString::number(vi->format->bitsPerSample);
		}
    }
	if (!y4mFormat.isEmpty())
        y4mFormat = "C" + y4mFormat + " ";

	QString header = "YUV4MPEG2 " + y4mFormat + "W" + QString::number(vi->width) + " H" + QString::number(vi->height) + " F" + QString::number(vi->fpsNum)  + ":" + QString::number(vi->fpsDen)  + " Ip A0:0\n";
    QByteArray rawHeader = header.toUtf8();

    if (y4m) {
        if (!fwrite(rawHeader.constData(), rawHeader.size(), 1, outfile)) {
            errorMessage = "Error: fwrite() call failed";
			fprintf(stderr, "%s", errorMessage.toUtf8().constData());
			outputError = true;
			return outputError;
        }
    }

	QMutexLocker lock(&mutex);

	int intitalRequestSize = std::min(requests, totalFrames);
	requestedFrames = intitalRequestSize;
	for (int n = 0; n < intitalRequestSize; n++)
		vsapi->getFrameAsync(n, node, frameDoneCallback, NULL);

	condition.wait(&mutex);

    if (outputError) {
        fprintf(stderr, "%s", errorMessage.toUtf8().constData());
    }

    return outputError;
}

// script output y4m index requests
#ifdef _WIN32
int wmain(int argc, wchar_t **argv) {
#else
int main(int argc, char **argv) {
#endif

    if (argc < 3) {
        fprintf(stderr, "VSPipe\n");
        fprintf(stderr, "Write to stdout: vspipe script.vpy - [options]\n");
        fprintf(stderr, "Write to file: vspipe script.vpy <outfile> [options]\n");
        fprintf(stderr, "Available options:\n");
		fprintf(stderr, "Select output index: -index N (default: 0)\n");
		fprintf(stderr, "Set number of concurrent frame requests: -requests N (default: number of threads)\n");
		fprintf(stderr, "Add YUV4MPEG headers: -y4m (default: off)\n");
        return 1;
    }

	for (int arg = 3; arg < argc; arg++) {
		QString argString = nativeToQString(argv[arg]);
		if (argString == "-y4m") {
			y4m = true;
		} else if (argString == "-index") {
			bool ok = false;
			if (argc <= arg + 1) {
				fprintf(stderr, "No index number specified");
				return 1;
			}
			QString numString = nativeToQString(argv[arg+1]);
			index = numString.toInt(&ok);
			if (!ok) {
				fprintf(stderr, "Couldn't convert %s to an integer", numString.toUtf8().constData());
				return 1;
			}
			arg++;
		} else if (argString == "-requests") {
			bool ok = false;
			if (argc <= arg + 1) {
				fprintf(stderr, "No request number specified");
				return 1;
			}
			QString numString = nativeToQString(argv[arg+1]);
			requests = numString.toInt(&ok);
			if (!ok) {
				fprintf(stderr, "Couldn't convert %s to an integer", numString.toUtf8().constData());
				return 1;
			}
			arg++;
		} else {
			fprintf(stderr, "Unknown argument: %s\n", argString.toUtf8().constData());
			return 1;
		}
	}

    if (!vseval_init()) {
        fprintf(stderr, "Failed to initialize VapourSynth environment\n");
        return 1;
    }

    vsapi = vseval_getVSApi();
    if (!vsapi) {
        fprintf(stderr, "Failed to get VapourSynth API\n");
        vseval_finalize();
        return 1;
    }

	QFile scriptFile(nativeToQString(argv[1]));
	if (!scriptFile.open(QIODevice::ReadOnly)) {
        fprintf(stderr, "Failed to to open script file for reading\n");
        vseval_finalize();
        return 1;
	}

	if (scriptFile.size() > 1024*1024*16) {
        fprintf(stderr, "Script files bigger than 16MB not allowed\n");
        vseval_finalize();
        return 1;
	}

    QByteArray scriptData = scriptFile.readAll();
    if (scriptData.isEmpty()) {
        fprintf(stderr, "Failed to read script file or file is empty\n");
        vseval_finalize();
        return 1;
    }

	if (vseval_evaluateScript(&se, scriptData.constData(), nativeToQString(argv[1]).toUtf8())) {
        fprintf(stderr, "Script evaluation failed:\n%s", vseval_getError(se));
        vseval_freeScript(se);
        vseval_finalize();
        return 1;
    }

    node = vseval_getOutput(se, index);
    if (!node) {
       fprintf(stderr, "Failed to retrieve output node. Invalid index specified?\n");
       vseval_freeScript(se);
       vseval_finalize();
       return 1;
    }

    const VSVideoInfo *vi = vsapi->getVideoInfo(node);
    if (!isConstantFormat(vi) || vi->numFrames == 0) {
        fprintf(stderr, "Cannot output clips with varying dimensions or unknown length\n");
        vseval_freeScript(se);
        vseval_finalize();
        return 1;
    }

    outfile = stdout;

	bool error = outputNode();

    vseval_freeScript(se);
    vseval_finalize();

	return error ? 1 : 0;
}

/*
VapourSynthFile::~VapourSynthFile() {
    if (vi) {
        vi = NULL;
		while (pending_requests > 0) {};
		vseval_freeScript(se);
    }
}
*/
<|endoftext|>


<commit_before>#include <glt/window.hpp>
#include <glt/app.hpp>
#include <algorithm>
#include <sstream>
#include <iostream>

namespace glt {

void setupCallbacks(GLFWwindow *window)
{
    glfwSetKeyCallback(window, OnKeyEvent);
    glfwSetCharCallback(window, OnTextInput);
    glfwSetCursorEnterCallback(window, OnCursorEnter);
    glfwSetCursorPosCallback(window, OnMouseMove);
    glfwSetMouseButtonCallback(window, OnMouseButtonEvent);
    glfwSetScrollCallback(window, OnScroll);
}

Window::Window(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
    : _window(nullptr)
{
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, GLT_OPEN_GL_MAJOR_VERSION);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, GLT_OPEN_GL_MINOR_VERSION);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    _window = glfwCreateWindow(width, height, title, monitor, share);
    glfwSetWindowUserPointer(_window, (void*) this);
    setupCallbacks(_window);
}

inline void destory(GLFWwindow *window)
{
    if (window != nullptr)
    {
        glfwDestroyWindow(window);
        window = nullptr;
    }
}

Window::~Window() { destory(_window); }

Window::Window(Window&& rhs) : Window()
{
    std::swap(_window, rhs._window);
    glfwSetWindowUserPointer(_window, (void*) this);
    setupCallbacks(_window);
}

Window& Window::operator=(Window&& rhs)
{
    destory(_window);
    std::swap(_window, rhs._window);
    glfwSetWindowUserPointer(_window, (void*) this);
    setupCallbacks(_window);

    return *this;
}

inline void Window::makeCurrentContext()
{
    glfwMakeContextCurrent(_window);
}

inline void Window::show() { glfwShowWindow(_window); }
inline void Window::hide() { glfwHideWindow(_window); }
inline bool Window::shouldClose() { return static_cast<bool>(glfwWindowShouldClose(_window)); }
inline void Window::swapBuffers() { glfwSwapBuffers(_window); }

std::tuple<int, int> Window::getFramebufferSize()
{
    int width, height;
    glfwGetFramebufferSize(_window, &width, &height);
    return std::make_tuple(width, height);
}

std::tuple<int, int> Window::getSize()
{
    int width, height;
    glfwGetWindowSize(_window, &width, &height);
    return std::make_tuple(width, height);
}

inline void Window::setInputMode(int mode, int value)
{
    glfwSetInputMode(_window, mode, value);
}

inline void Window::setCursor(GLFWcursor *cursor)
{
    glfwSetCursor(_window, cursor);
}

void OnKeyEvent(GLFWwindow *win, int key, int scancode, int action, int mods)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onKeyEvent(key, scancode, action, mods);
}

void OnTextInput(GLFWwindow * win, unsigned int codepoint)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onTextInput(codepoint);
}

void OnCursorEnter(GLFWwindow *win, int entered)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onCursorEnter(entered);
}

void OnMouseMove(GLFWwindow *win, double xpos, double ypos)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onMouseMove(xpos, ypos);
}

void OnMouseButtonEvent(GLFWwindow * win, int button, int action, int mods)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onMouseButtonEvent(button, action, mods);
}

void OnScroll(GLFWwindow *win, double xoffset, double yoffset)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onScroll(xoffset, yoffset);
}

inline void pollEvents() { glfwPollEvents(); }

const int   WIDTH  = 1024;
const int   HEIGHT = 768;
const char *TITLE  = "OpenGL Window";

Window easyWindow(int width, int height, const char *title, std::ostream &out)
{
    Window window(width, height, title, nullptr, nullptr);

    if (window.valid() == false)
    {
        out << "Could not create window.\n"
            << "Has an App been created?" << std::endl;
        exit(EXIT_FAILURE);
    }

    window.makeCurrentContext();

    if (initGlTools() == false)
    {
        out << "Failed to load OpenGL." << std::endl;
        exit(EXIT_FAILURE);
    }

    return window;
}

inline Window easyWindow(int width, int height, const char *title)
{
    return easyWindow(width, height, title, std::cerr);
}

inline Window easyWindow(int width, int height, std::ostream &out)
{
    return easyWindow(width, height, TITLE, out);
}

inline Window easyWindow(int width, int height)
{
    return easyWindow(width, height, TITLE, std::cerr);
}

inline Window easyWindow(const char *title, std::ostream &out)
{
    return easyWindow(WIDTH, HEIGHT, title, out);
}

inline Window easyWindow(const char *title)
{
    return easyWindow(WIDTH, HEIGHT, title, std::cerr);
}

inline Window easyWindow(std::ostream &out)
{
    return easyWindow(WIDTH, HEIGHT, TITLE, out);
}

inline Window easyWindow()
{
    return easyWindow(WIDTH, HEIGHT, TITLE, std::cerr);
}

} // end namespace glt
<commit_msg>Initialize Window callbacks to empty functions<commit_after>#include <glt/window.hpp>
#include <glt/app.hpp>
#include <algorithm>
#include <sstream>
#include <iostream>

namespace glt {

void setupCallbacks(GLFWwindow *window)
{
    glfwSetKeyCallback(window, OnKeyEvent);
    glfwSetCharCallback(window, OnTextInput);
    glfwSetCursorEnterCallback(window, OnCursorEnter);
    glfwSetCursorPosCallback(window, OnMouseMove);
    glfwSetMouseButtonCallback(window, OnMouseButtonEvent);
    glfwSetScrollCallback(window, OnScroll);
}

Window::Window(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
    : _window(nullptr)
    , _onCursorEnter([](int){})
    , _onKeyEvent([](int,int,int,int){})
    , _onTextInput([](unsigned int){})
    , _onMouseMove([](double,double){})
    , _onMouseButtonEvent([](int,int,int){})
    , _onScroll([](double, double){})
{
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, GLT_OPEN_GL_MAJOR_VERSION);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, GLT_OPEN_GL_MINOR_VERSION);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    _window = glfwCreateWindow(width, height, title, monitor, share);
    glfwSetWindowUserPointer(_window, (void*) this);
    setupCallbacks(_window);
}

inline void destory(GLFWwindow *window)
{
    if (window != nullptr)
    {
        glfwDestroyWindow(window);
        window = nullptr;
    }
}

Window::~Window() { destory(_window); }

Window::Window(Window&& rhs) : Window()
{
    std::swap(_window,             rhs._window);
    std::swap(_onCursorEnter,      rhs._onCursorEnter);
    std::swap(_onKeyEvent,         rhs._onKeyEvent);
    std::swap(_onTextInput,        rhs._onTextInput);
    std::swap(_onMouseMove,        rhs._onMouseMove);
    std::swap(_onMouseButtonEvent, rhs._onMouseButtonEvent);
    std::swap(_onScroll,           rhs._onScroll);
    glfwSetWindowUserPointer(_window, (void*) this);
    setupCallbacks(_window);
}

Window& Window::operator=(Window&& rhs)
{
    destory(_window);
    std::swap(_window,             rhs._window);
    std::swap(_onCursorEnter,      rhs._onCursorEnter);
    std::swap(_onKeyEvent,         rhs._onKeyEvent);
    std::swap(_onTextInput,        rhs._onTextInput);
    std::swap(_onMouseMove,        rhs._onMouseMove);
    std::swap(_onMouseButtonEvent, rhs._onMouseButtonEvent);
    std::swap(_onScroll,           rhs._onScroll);
    glfwSetWindowUserPointer(_window, (void*) this);
    setupCallbacks(_window);

    return *this;
}

inline void Window::makeCurrentContext()
{
    glfwMakeContextCurrent(_window);
}

inline void Window::show() { glfwShowWindow(_window); }
inline void Window::hide() { glfwHideWindow(_window); }
inline bool Window::shouldClose() { return static_cast<bool>(glfwWindowShouldClose(_window)); }
inline void Window::swapBuffers() { glfwSwapBuffers(_window); }

std::tuple<int, int> Window::getFramebufferSize()
{
    int width, height;
    glfwGetFramebufferSize(_window, &width, &height);
    return std::make_tuple(width, height);
}

std::tuple<int, int> Window::getSize()
{
    int width, height;
    glfwGetWindowSize(_window, &width, &height);
    return std::make_tuple(width, height);
}

inline void Window::setInputMode(int mode, int value)
{
    glfwSetInputMode(_window, mode, value);
}

inline void Window::setCursor(GLFWcursor *cursor)
{
    glfwSetCursor(_window, cursor);
}

void OnKeyEvent(GLFWwindow *win, int key, int scancode, int action, int mods)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onKeyEvent(key, scancode, action, mods);
}

void OnTextInput(GLFWwindow * win, unsigned int codepoint)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onTextInput(codepoint);
}

void OnCursorEnter(GLFWwindow *win, int entered)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onCursorEnter(entered);
}

void OnMouseMove(GLFWwindow *win, double xpos, double ypos)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onMouseMove(xpos, ypos);
}

void OnMouseButtonEvent(GLFWwindow * win, int button, int action, int mods)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onMouseButtonEvent(button, action, mods);
}

void OnScroll(GLFWwindow *win, double xoffset, double yoffset)
{
    auto window = (Window*) glfwGetWindowUserPointer(win);
    window->_onScroll(xoffset, yoffset);
}

inline void pollEvents() { glfwPollEvents(); }

const int   WIDTH  = 1024;
const int   HEIGHT = 768;
const char *TITLE  = "OpenGL Window";

Window easyWindow(int width, int height, const char *title, std::ostream &out)
{
    Window window(width, height, title, nullptr, nullptr);

    if (window.valid() == false)
    {
        out << "Could not create window.\n"
            << "Has an App been created?" << std::endl;
        exit(EXIT_FAILURE);
    }

    window.makeCurrentContext();

    if (initGlTools() == false)
    {
        out << "Failed to load OpenGL." << std::endl;
        exit(EXIT_FAILURE);
    }

    return window;
}

inline Window easyWindow(int width, int height, const char *title)
{
    return easyWindow(width, height, title, std::cerr);
}

inline Window easyWindow(int width, int height, std::ostream &out)
{
    return easyWindow(width, height, TITLE, out);
}

inline Window easyWindow(int width, int height)
{
    return easyWindow(width, height, TITLE, std::cerr);
}

inline Window easyWindow(const char *title, std::ostream &out)
{
    return easyWindow(WIDTH, HEIGHT, title, out);
}

inline Window easyWindow(const char *title)
{
    return easyWindow(WIDTH, HEIGHT, title, std::cerr);
}

inline Window easyWindow(std::ostream &out)
{
    return easyWindow(WIDTH, HEIGHT, TITLE, out);
}

inline Window easyWindow()
{
    return easyWindow(WIDTH, HEIGHT, TITLE, std::cerr);
}

} // end namespace glt
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "AlembicXform.h"
#include "CommonProfiler.h"

using namespace XSI;
using namespace MATH;

void SaveXformSample(XSI::CRef parentKineStateRef, XSI::CRef kineStateRef, AbcG::OXformSchema & schema,AbcG::XformSample & sample, double time, bool xformCache, bool globalSpace, bool flattenHierarchy)
{

   // check if we are exporting in global space
   if(globalSpace)
   {
      if(schema.getNumSamples() > 0)
         return;

      // store identity matrix
      sample.setTranslation(Imath::V3d(0.0,0.0,0.0));
      sample.setRotation(Imath::V3d(1.0,0.0,0.0),0.0);
      sample.setScale(Imath::V3d(1.0,1.0,1.0));

      // save the sample
      schema.set(sample);
      return;
   }

   // check if the transform is animated
   //if(schema.getNumSamples() > 0)
   //{
   //   X3DObject parent(kineState.GetParent3DObject());
   //   if(!isRefAnimated(kineState.GetParent3DObject().GetRef(),xformCache))
   //      return;
   //}

   KinematicState kineState(kineStateRef);
   CTransformation globalTransform = kineState.GetTransform(time);
   CTransformation transform;

   if(flattenHierarchy){
      transform = globalTransform;
   }
   else{
      KinematicState parentKineState(parentKineStateRef);
      CMatrix4 parentGlobalTransform4 = parentKineState.GetTransform(time).GetMatrix4();
      CMatrix4 transform4 = globalTransform.GetMatrix4();
      parentGlobalTransform4.InvertInPlace();
      transform4.MulInPlace(parentGlobalTransform4);
      transform.SetMatrix4(transform4);
   }

   // store the transform
   CVector3 trans = transform.GetTranslation();
   CVector3 axis;
   double angle = transform.GetRotationAxisAngle(axis);
   CVector3 scale = transform.GetScaling();
   sample.setTranslation(Imath::V3d(trans.GetX(),trans.GetY(),trans.GetZ()));
   sample.setRotation(Imath::V3d(axis.GetX(),axis.GetY(),axis.GetZ()),RadiansToDegrees(angle));
   sample.setScale(Imath::V3d(scale.GetX(),scale.GetY(),scale.GetZ()));

   //ESS_LOG_WARNING("time: "<<time<<" trans: ("<<trans.GetX()<<", "<<trans.GetY()<<", "<<trans.GetZ()<<") angle: "<<angle<<" axis: ("<<axis.GetX()<<", "<<axis.GetY()<<", "<<axis.GetZ());

   // save the sample
   schema.set(sample);
}

ESS_CALLBACK_START( alembic_xform_Define, CRef& )
   return alembicOp_Define(in_ctxt);
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_xform_DefineLayout, CRef& )
   return alembicOp_DefineLayout(in_ctxt);
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_xform_Update, CRef& )
	ESS_PROFILE_SCOPE("alembic_xform_Update");
	OperatorContext ctxt( in_ctxt );

	if((bool)ctxt.GetParameterValue(L"muted"))
		return CStatus::OK;

	CValue udVal = ctxt.GetUserData();
	alembic_UD * p = (alembic_UD*)(CValue::siPtrType)udVal;

	CString path = ctxt.GetParameterValue(L"path");
	CString identifier = ctxt.GetParameterValue(L"identifier");

	AbcG::IObject iObj = getObjectFromArchive(path,identifier);
	if(!iObj.valid()) {
		return CStatus::OK;
	}
	AbcG::IXform obj(iObj,Abc::kWrapExisting);
	if(!obj.valid()) {
		return CStatus::OK;
	}

	double time = ctxt.GetParameterValue(L"time");
	if(p->times.size() == 0 || abs(p->lastTime - time) < 0.001)
	{
		p->times.clear();
		for(size_t i=0;i<obj.getSchema().getNumSamples();i++)
		{
			p->times.push_back((double)obj.getSchema().getTimeSampling()->getSampleTime( i ));
		}
	}

	Abc::M44d matrix;	// constructor creates an identity matrix

	// if no time samples, default to identity matrix
	if( p->times.size() > 0 ) {

    SampleInfo sampleInfo = getSampleInfo(
			  time,
			  obj.getSchema().getTimeSampling(),
			  obj.getSchema().getNumSamples()
			  );

		if( p->indexToMatrices.find(sampleInfo.floorIndex) == p->indexToMatrices.end() ) {
			AbcG::XformSample sample;
			obj.getSchema().get(sample,sampleInfo.floorIndex);
			p->indexToMatrices.insert( std::map<size_t,Abc::M44d>::value_type( sampleInfo.floorIndex, sample.getMatrix() ) );
		}
		if( sampleInfo.ceilIndex < p->times.size() ) {
			if( p->indexToMatrices.find(sampleInfo.ceilIndex) == p->indexToMatrices.end() ) {
				AbcG::XformSample sample;
				obj.getSchema().get(sample,sampleInfo.ceilIndex);
				p->indexToMatrices.insert( std::map<size_t,Abc::M44d>::value_type( sampleInfo.ceilIndex, sample.getMatrix() ) );
			}
		}

		if( sampleInfo.alpha == 1.0f )
		{
			matrix = p->indexToMatrices[ sampleInfo.floorIndex ];
		}
		else
		{
			matrix = p->indexToMatrices[ sampleInfo.floorIndex ] * sampleInfo.alpha + p->indexToMatrices[ sampleInfo.ceilIndex ] * ( 1 - sampleInfo.alpha );
		}
	}
	p->lastTime = time;

	CMatrix4 xsiMatrix;
	xsiMatrix.Set(
			  matrix.getValue()[0],matrix.getValue()[1],matrix.getValue()[2],matrix.getValue()[3],
			  matrix.getValue()[4],matrix.getValue()[5],matrix.getValue()[6],matrix.getValue()[7],
			  matrix.getValue()[8],matrix.getValue()[9],matrix.getValue()[10],matrix.getValue()[11],
			  matrix.getValue()[12],matrix.getValue()[13],matrix.getValue()[14],matrix.getValue()[15]);
	CTransformation xsiTransform;
	xsiTransform.SetMatrix4(xsiMatrix);

	KinematicState state(ctxt.GetOutputTarget());
	state.PutTransform(xsiTransform);

	return CStatus::OK;
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_xform_Init, CRef& )
   Context ctxt( in_ctxt );
   CustomOperator op(ctxt.GetSource());

   CValue val = (CValue::siPtrType) new alembic_UD(op.GetObjectID());
   ctxt.PutUserData( val ) ;

   return CStatus::OK;
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_xform_Term, CRef& )
   Context ctxt( in_ctxt );
   CustomOperator op(ctxt.GetSource());
   delRefArchive(op.GetParameterValue(L"path").GetAsText());

   CValue udVal = ctxt.GetUserData();
   alembic_UD * p = (alembic_UD*)(CValue::siPtrType)udVal;
   if(p!=NULL)
   {
      delete(p);
      p = NULL;
   }

   return CStatus::OK;
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_visibility_Define, CRef& )
   return alembicOp_Define(in_ctxt);
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_visibility_DefineLayout, CRef& )
   return alembicOp_DefineLayout(in_ctxt);
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_visibility_Update, CRef& )
   ESS_PROFILE_SCOPE("alembic_visibility_Update");
   OperatorContext ctxt( in_ctxt );

   if((bool)ctxt.GetParameterValue(L"muted"))
      return CStatus::OK;

   CString path = ctxt.GetParameterValue(L"path");
   CString identifier = ctxt.GetParameterValue(L"identifier");

  AbcG::IObject obj = getObjectFromArchive(path,identifier);
   if(!obj.valid())
      return CStatus::OK;

  AbcG::IVisibilityProperty visibilityProperty =
     AbcG::GetVisibilityProperty(obj);
   if(!visibilityProperty.valid())
      return CStatus::OK;

   SampleInfo sampleInfo = getSampleInfo(
      ctxt.GetParameterValue(L"time"),
      getTimeSamplingFromObject(obj),
      visibilityProperty.getNumSamples()
   );

   AbcA::int8_t rawVisibilityValue = visibilityProperty.getValue ( sampleInfo.floorIndex );
  AbcG::ObjectVisibility visibilityValue =AbcG::ObjectVisibility ( rawVisibilityValue );

   Property prop(ctxt.GetOutputTarget());
   switch(visibilityValue)
   {
      case AbcG::kVisibilityVisible:
      {
         prop.PutParameterValue(L"viewvis",true);
         prop.PutParameterValue(L"rendvis",true);
         break;
      }
      case AbcG::kVisibilityHidden:
      {
         prop.PutParameterValue(L"viewvis",false);
         prop.PutParameterValue(L"rendvis",false);
         break;
      }
      default:
      {
         break;
      }
   }

   return CStatus::OK;
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_visibility_Term, CRef& )
   return alembicOp_Term(in_ctxt);
ESS_CALLBACK_END
<commit_msg>fixed #205<commit_after>#include "stdafx.h"
#include "AlembicXform.h"
#include "CommonProfiler.h"

using namespace XSI;
using namespace MATH;

void SaveXformSample(XSI::CRef parentKineStateRef, XSI::CRef kineStateRef, AbcG::OXformSchema & schema,AbcG::XformSample & sample, double time, bool xformCache, bool globalSpace, bool flattenHierarchy)
{

   // check if we are exporting in global space
   if(globalSpace)
   {
      if(schema.getNumSamples() > 0)
         return;

      // store identity matrix
      sample.setTranslation(Imath::V3d(0.0,0.0,0.0));
      sample.setRotation(Imath::V3d(1.0,0.0,0.0),0.0);
      sample.setScale(Imath::V3d(1.0,1.0,1.0));

      // save the sample
      schema.set(sample);
      return;
   }

   // check if the transform is animated
   //if(schema.getNumSamples() > 0)
   //{
   //   X3DObject parent(kineState.GetParent3DObject());
   //   if(!isRefAnimated(kineState.GetParent3DObject().GetRef(),xformCache))
   //      return;
   //}

   KinematicState kineState(kineStateRef);
   CTransformation globalTransform = kineState.GetTransform(time);
   CTransformation transform;

   if(flattenHierarchy){
      transform = globalTransform;
   }
   else{
      KinematicState parentKineState(parentKineStateRef);
      CMatrix4 parentGlobalTransform4 = parentKineState.GetTransform(time).GetMatrix4();
      CMatrix4 transform4 = globalTransform.GetMatrix4();
      parentGlobalTransform4.InvertInPlace();
      transform4.MulInPlace(parentGlobalTransform4);
      transform.SetMatrix4(transform4);
   }

   // store the transform
   CVector3 trans = transform.GetTranslation();
   CVector3 axis;
   double angle = transform.GetRotationAxisAngle(axis);
   CVector3 scale = transform.GetScaling();
   sample.setTranslation(Imath::V3d(trans.GetX(),trans.GetY(),trans.GetZ()));
   sample.setRotation(Imath::V3d(axis.GetX(),axis.GetY(),axis.GetZ()),RadiansToDegrees(angle));
   sample.setScale(Imath::V3d(scale.GetX(),scale.GetY(),scale.GetZ()));

   //ESS_LOG_WARNING("time: "<<time<<" trans: ("<<trans.GetX()<<", "<<trans.GetY()<<", "<<trans.GetZ()<<") angle: "<<angle<<" axis: ("<<axis.GetX()<<", "<<axis.GetY()<<", "<<axis.GetZ());

   // save the sample
   schema.set(sample);
}

ESS_CALLBACK_START( alembic_xform_Define, CRef& )
   return alembicOp_Define(in_ctxt);
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_xform_DefineLayout, CRef& )
   return alembicOp_DefineLayout(in_ctxt);
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_xform_Update, CRef& )
	ESS_PROFILE_SCOPE("alembic_xform_Update");
	OperatorContext ctxt( in_ctxt );

	if((bool)ctxt.GetParameterValue(L"muted"))
		return CStatus::OK;

	CValue udVal = ctxt.GetUserData();
	alembic_UD * p = (alembic_UD*)(CValue::siPtrType)udVal;

	CString path = ctxt.GetParameterValue(L"path");
	CString identifier = ctxt.GetParameterValue(L"identifier");

	AbcG::IObject iObj = getObjectFromArchive(path,identifier);
	if(!iObj.valid()) {
		return CStatus::OK;
	}
	AbcG::IXform obj(iObj,Abc::kWrapExisting);
	if(!obj.valid()) {
		return CStatus::OK;
	}

	double time = ctxt.GetParameterValue(L"time");
	Abc::M44d matrix;	// constructor creates an identity matrix

	// if no time samples, default to identity matrix
  if( obj.getSchema().getNumSamples() > 0 ) {

    SampleInfo sampleInfo = getSampleInfo(
		    time,
		    obj.getSchema().getTimeSampling(),
		    obj.getSchema().getNumSamples()
		    );

	  if( p->indexToMatrices.find(sampleInfo.floorIndex) == p->indexToMatrices.end() ) {
		  AbcG::XformSample sample;
		  obj.getSchema().get(sample,sampleInfo.floorIndex);
		  p->indexToMatrices.insert( std::map<size_t,Abc::M44d>::value_type( sampleInfo.floorIndex, sample.getMatrix() ) );
	  }
	  if( sampleInfo.ceilIndex < obj.getSchema().getNumSamples() ) {
		  if( p->indexToMatrices.find(sampleInfo.ceilIndex) == p->indexToMatrices.end() ) {
			  AbcG::XformSample sample;
			  obj.getSchema().get(sample,sampleInfo.ceilIndex);
			  p->indexToMatrices.insert( std::map<size_t,Abc::M44d>::value_type( sampleInfo.ceilIndex, sample.getMatrix() ) );
		  }
	  }

	  if( sampleInfo.alpha == 1.0f )
	  {
		  matrix = p->indexToMatrices[ sampleInfo.floorIndex ];
	  }
	  else
	  {
		  matrix = p->indexToMatrices[ sampleInfo.floorIndex ] * sampleInfo.alpha + p->indexToMatrices[ sampleInfo.ceilIndex ] * ( 1 - sampleInfo.alpha );
	  }
  }

	CMatrix4 xsiMatrix;
	xsiMatrix.Set(
			  matrix.getValue()[0],matrix.getValue()[1],matrix.getValue()[2],matrix.getValue()[3],
			  matrix.getValue()[4],matrix.getValue()[5],matrix.getValue()[6],matrix.getValue()[7],
			  matrix.getValue()[8],matrix.getValue()[9],matrix.getValue()[10],matrix.getValue()[11],
			  matrix.getValue()[12],matrix.getValue()[13],matrix.getValue()[14],matrix.getValue()[15]);
	CTransformation xsiTransform;
	xsiTransform.SetMatrix4(xsiMatrix);

	KinematicState state(ctxt.GetOutputTarget());
	state.PutTransform(xsiTransform);

	return CStatus::OK;
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_xform_Init, CRef& )
   Context ctxt( in_ctxt );
   CustomOperator op(ctxt.GetSource());

   CValue val = (CValue::siPtrType) new alembic_UD(op.GetObjectID());
   ctxt.PutUserData( val ) ;

   return CStatus::OK;
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_xform_Term, CRef& )
   Context ctxt( in_ctxt );
   CustomOperator op(ctxt.GetSource());
   delRefArchive(op.GetParameterValue(L"path").GetAsText());

   CValue udVal = ctxt.GetUserData();
   alembic_UD * p = (alembic_UD*)(CValue::siPtrType)udVal;
   if(p!=NULL)
   {
      delete(p);
      p = NULL;
   }

   return CStatus::OK;
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_visibility_Define, CRef& )
   return alembicOp_Define(in_ctxt);
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_visibility_DefineLayout, CRef& )
   return alembicOp_DefineLayout(in_ctxt);
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_visibility_Update, CRef& )
   ESS_PROFILE_SCOPE("alembic_visibility_Update");
   OperatorContext ctxt( in_ctxt );

   if((bool)ctxt.GetParameterValue(L"muted"))
      return CStatus::OK;

   CString path = ctxt.GetParameterValue(L"path");
   CString identifier = ctxt.GetParameterValue(L"identifier");

  AbcG::IObject obj = getObjectFromArchive(path,identifier);
   if(!obj.valid())
      return CStatus::OK;

  AbcG::IVisibilityProperty visibilityProperty =
     AbcG::GetVisibilityProperty(obj);
   if(!visibilityProperty.valid())
      return CStatus::OK;

   SampleInfo sampleInfo = getSampleInfo(
      ctxt.GetParameterValue(L"time"),
      getTimeSamplingFromObject(obj),
      visibilityProperty.getNumSamples()
   );

   AbcA::int8_t rawVisibilityValue = visibilityProperty.getValue ( sampleInfo.floorIndex );
  AbcG::ObjectVisibility visibilityValue =AbcG::ObjectVisibility ( rawVisibilityValue );

   Property prop(ctxt.GetOutputTarget());
   switch(visibilityValue)
   {
      case AbcG::kVisibilityVisible:
      {
         prop.PutParameterValue(L"viewvis",true);
         prop.PutParameterValue(L"rendvis",true);
         break;
      }
      case AbcG::kVisibilityHidden:
      {
         prop.PutParameterValue(L"viewvis",false);
         prop.PutParameterValue(L"rendvis",false);
         break;
      }
      default:
      {
         break;
      }
   }

   return CStatus::OK;
ESS_CALLBACK_END

ESS_CALLBACK_START( alembic_visibility_Term, CRef& )
   return alembicOp_Term(in_ctxt);
ESS_CALLBACK_END
<|endoftext|>


<commit_before>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include "core/Setup.h"

#if OUZEL_COMPILE_DIRECT3D11

#include "DepthStencilStateResourceD3D11.hpp"
#include "RenderDeviceD3D11.hpp"

namespace ouzel
{
    namespace graphics
    {
        static D3D11_COMPARISON_FUNC getCompareFunction(DepthStencilState::CompareFunction compareFunction)
        {
            switch (compareFunction)
            {
                case DepthStencilState::CompareFunction::NEVER: return D3D11_COMPARISON_NEVER;
                case DepthStencilState::CompareFunction::LESS: return D3D11_COMPARISON_LESS;
                case DepthStencilState::CompareFunction::EQUAL: return D3D11_COMPARISON_EQUAL;
                case DepthStencilState::CompareFunction::LESS_EQUAL: return D3D11_COMPARISON_LESS_EQUAL;
                case DepthStencilState::CompareFunction::GREATER: return D3D11_COMPARISON_GREATER;
                case DepthStencilState::CompareFunction::NOT_EQUAL: return D3D11_COMPARISON_NOT_EQUAL;
                case DepthStencilState::CompareFunction::GREATER_EQUAL: return D3D11_COMPARISON_GREATER_EQUAL;
                case DepthStencilState::CompareFunction::ALWAYS: return D3D11_COMPARISON_ALWAYS;
            }

            return D3D11_COMPARISON_NEVER;
        }

        DepthStencilStateResourceD3D11::DepthStencilStateResourceD3D11(RenderDeviceD3D11& renderDeviceD3D11,
                                                                       bool initDepthTest,
                                                                       bool initDepthWrite,
                                                                       DepthStencilState::CompareFunction initCompareFunction):
            RenderResourceD3D11(renderDeviceD3D11)
        {
            D3D11_DEPTH_STENCIL_DESC depthStencilStateDesc;
            depthStencilStateDesc.DepthEnable = initDepthTest ? TRUE : FALSE;
            depthStencilStateDesc.DepthWriteMask = initDepthWrite ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
            depthStencilStateDesc.DepthFunc = getCompareFunction(initCompareFunction);
            depthStencilStateDesc.StencilEnable = FALSE;
            depthStencilStateDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
            depthStencilStateDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
            depthStencilStateDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
            depthStencilStateDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
            depthStencilStateDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;

            hr = device->CreateDepthStencilState(&depthStencilStateDesc, &depthStencilState);
            if (FAILED(hr))
                throw SystemError("Failed to create Direct3D 11 depth stencil state, error: " + std::to_string(hr));
        }

        DepthStencilStateResourceD3D11::~DepthStencilStateResourceD3D11()
        {
            if (depthStencilState) depthStencilState->Release();
        }
    } // namespace graphics
} // namespace ouzel

#endif
<commit_msg>Fix the Windows build<commit_after>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include "core/Setup.h"

#if OUZEL_COMPILE_DIRECT3D11

#include "DepthStencilStateResourceD3D11.hpp"
#include "RenderDeviceD3D11.hpp"
#include "utils/Errors.hpp"

namespace ouzel
{
    namespace graphics
    {
        static D3D11_COMPARISON_FUNC getCompareFunction(DepthStencilState::CompareFunction compareFunction)
        {
            switch (compareFunction)
            {
                case DepthStencilState::CompareFunction::NEVER: return D3D11_COMPARISON_NEVER;
                case DepthStencilState::CompareFunction::LESS: return D3D11_COMPARISON_LESS;
                case DepthStencilState::CompareFunction::EQUAL: return D3D11_COMPARISON_EQUAL;
                case DepthStencilState::CompareFunction::LESS_EQUAL: return D3D11_COMPARISON_LESS_EQUAL;
                case DepthStencilState::CompareFunction::GREATER: return D3D11_COMPARISON_GREATER;
                case DepthStencilState::CompareFunction::NOT_EQUAL: return D3D11_COMPARISON_NOT_EQUAL;
                case DepthStencilState::CompareFunction::GREATER_EQUAL: return D3D11_COMPARISON_GREATER_EQUAL;
                case DepthStencilState::CompareFunction::ALWAYS: return D3D11_COMPARISON_ALWAYS;
            }

            return D3D11_COMPARISON_NEVER;
        }

        DepthStencilStateResourceD3D11::DepthStencilStateResourceD3D11(RenderDeviceD3D11& renderDeviceD3D11,
                                                                       bool initDepthTest,
                                                                       bool initDepthWrite,
                                                                       DepthStencilState::CompareFunction initCompareFunction):
            RenderResourceD3D11(renderDeviceD3D11)
        {
            D3D11_DEPTH_STENCIL_DESC depthStencilStateDesc;
            depthStencilStateDesc.DepthEnable = initDepthTest ? TRUE : FALSE;
            depthStencilStateDesc.DepthWriteMask = initDepthWrite ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
            depthStencilStateDesc.DepthFunc = getCompareFunction(initCompareFunction);
            depthStencilStateDesc.StencilEnable = FALSE;
            depthStencilStateDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
            depthStencilStateDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
            depthStencilStateDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
            depthStencilStateDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
            depthStencilStateDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
            depthStencilStateDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;

            HRESULT hr = renderDevice.getDevice()->CreateDepthStencilState(&depthStencilStateDesc, &depthStencilState);
            if (FAILED(hr))
                throw SystemError("Failed to create Direct3D 11 depth stencil state, error: " + std::to_string(hr));
        }

        DepthStencilStateResourceD3D11::~DepthStencilStateResourceD3D11()
        {
            if (depthStencilState) depthStencilState->Release();
        }
    } // namespace graphics
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>#ifndef WIZARDBATTLE_RULES_WIZARD_H
#define WIZARDBATTLE_RULES_WIZARD_H

namespace WizardBattle
{
	namespace Rules
	{
		class Wizard
		{
		private:
		public:
			const unsigned int x, y;
			const bool alive;

			Wizard(unsigned int x, unsigned int y)
				: x(x), y(y), alive(false) { };

			const Wizard kill() const;
		};
	}
}

#endif
<commit_msg>shuffled wizard constructor a bit, added definition for kill<commit_after>#ifndef WIZARDBATTLE_RULES_WIZARD_H
#define WIZARDBATTLE_RULES_WIZARD_H

namespace WizardBattle
{
	namespace Rules
	{
		class Wizard
		{
		private:
			Wizard(unsigned int x, unsigned int y, bool alive)
				: x(x), y(y), alive(alive) { };
		public:
			const unsigned int x, y;
			const bool alive;

			Wizard(unsigned int x, unsigned int y)
				: Wizard(x, y, true) { };

			const Wizard kill() const
			{
				return Wizard(x, y, false);
			};
		};
	}
}

#endif
<|endoftext|>


<commit_before>#include "File.h"
#include "Index.h"
#include "RegExpIndexer.h"
#include "ConsoleLog.h"
#include "FieldIndexer.h"

#include <tclap/CmdLine.h>

#include <iostream>
#include <stdexcept>
#include <limits.h>
#include "ExternalIndexer.h"

using namespace std;
using namespace TCLAP;

namespace {

string getRealPath(const string &relPath) {
    char realPathBuf[PATH_MAX];
    auto result = realpath(relPath.c_str(), realPathBuf);
    if (result == nullptr) return relPath;
    return string(relPath);
}

}

int Main(int argc, const char *argv[]) {
    CmdLine cmd("Create indices in a compressed text file");
    UnlabeledValueArg<string> inputFile(
            "input-file", "Read input from <file>", true, "", "file", cmd);
    SwitchArg verbose("v", "verbose", "Be more verbose", cmd);
    SwitchArg debug("", "debug", "Be even more verbose", cmd);
    SwitchArg forceColour("", "colour", "Use colour even on non-TTY", cmd);
    SwitchArg forceColor("", "color", "Use color even on non-TTY", cmd);
    SwitchArg numeric("n", "numeric", "Assume the index is numeric", cmd);
    SwitchArg unique("u", "unique", "Assume each line's index is unique", cmd);
    ValueArg<uint64_t> checkpointEvery(
            "", "checkpoint-every",
            "Create an compression checkpoint every <bytes>", false,
            0, "bytes", cmd);
    ValueArg<string> regex("", "regex", "Create an index using <regex>", false,
                           "", "regex", cmd);
    ValueArg<uint64_t> skipFirst("", "skip-first", "Skip the first <num> lines",
                                 false, 0, "num", cmd);
    ValueArg<int> field("f", "field", "Create an index using field <num> "
                                "(delimited by -d/--delimiter)",
                        false, 0, "num", cmd);
    ValueArg<char> delimiter("d", "delimiter",
                             "Use <char> as the field delimiter", false, ' ',
                             "char", cmd);
    ValueArg<string> externalIndexer(
            "p", "pipe",
            "Create indices by piping output through <CMD> which should output "
                    "a single line for each input line. "
                    "Multiple keys should be separated by the --delimiter "
                    "character (which defaults to a space). "
                    "The CMD should be unbuffered "
                    "(man stdbuf(1) for one way of doing this).\n"
                    "Example:  --pipe 'jq --raw-output --unbuffered .eventId')",
            false, "", "CMD", cmd);
    ValueArg<string> indexFilename("", "index-file",
                                   "Store index in <index-file> "
                                           "(default <file>.zindex)", false, "",
                                   "index-file", cmd);
    cmd.parse(argc, argv);

    ConsoleLog log(
            debug.isSet() ? Log::Severity::Debug : verbose.isSet()
                                                   ? Log::Severity::Info
                                                   : Log::Severity::Warning,
            forceColour.isSet() || forceColor.isSet());

    try {
        auto realPath = getRealPath(inputFile.getValue());
        File in(fopen(realPath.c_str(), "rb"));
        if (in.get() == nullptr) {
            log.debug("Unable to open ", inputFile.getValue(), " (as ",
                      realPath,
                      ")");
            log.error("Could not open ", inputFile.getValue(), " for reading");
            return 1;
        }

        auto outputFile = indexFilename.isSet() ? indexFilename.getValue() :
                          inputFile.getValue() + ".zindex";
        Index::Builder builder(log, move(in), realPath, outputFile,
                               skipFirst.getValue());
        if (regex.isSet() && field.isSet()) {
            throw std::runtime_error(
                    "Sorry; multiple indices are not supported yet");
        }
        if (regex.isSet()) {
            builder.addIndexer("default", regex.getValue(), numeric.isSet(),
                               unique.isSet(),
                               std::unique_ptr<LineIndexer>(
                                       new RegExpIndexer(regex.getValue())));
        }
        if (field.isSet()) {
            ostringstream name;
            name << "Field " << field.getValue() << " delimited by '"
            << delimiter.getValue() << "'";
            builder.addIndexer("default", name.str(), numeric.isSet(),
                               unique.isSet(), std::unique_ptr<LineIndexer>(
                            new FieldIndexer(delimiter.getValue(),
                                             field.getValue())));
        }
        if (externalIndexer.isSet()) {
            auto indexer = std::unique_ptr<LineIndexer>(
                    new ExternalIndexer(log,
                                        externalIndexer.getValue(),
                                        delimiter.getValue()));
            builder.addIndexer("default", externalIndexer.getValue(),
                               numeric.isSet(), unique.isSet(),
                               std::move(indexer));
        }
        if (checkpointEvery.isSet())
            builder.indexEvery(checkpointEvery.getValue());
        builder.build();
    } catch (const exception &e) {
        log.error(e.what());
    }
    return 0;
}

int main(int argc, const char *argv[]) {
    try {
        return Main(argc, argv);
    } catch (const exception &e) {
        cerr << e.what() << endl;
        return 1;
    }
}
<commit_msg>Typo in the help message<commit_after>#include "File.h"
#include "Index.h"
#include "RegExpIndexer.h"
#include "ConsoleLog.h"
#include "FieldIndexer.h"

#include <tclap/CmdLine.h>

#include <iostream>
#include <stdexcept>
#include <limits.h>
#include "ExternalIndexer.h"

using namespace std;
using namespace TCLAP;

namespace {

string getRealPath(const string &relPath) {
    char realPathBuf[PATH_MAX];
    auto result = realpath(relPath.c_str(), realPathBuf);
    if (result == nullptr) return relPath;
    return string(relPath);
}

}

int Main(int argc, const char *argv[]) {
    CmdLine cmd("Create indices in a compressed text file");
    UnlabeledValueArg<string> inputFile(
            "input-file", "Read input from <file>", true, "", "file", cmd);
    SwitchArg verbose("v", "verbose", "Be more verbose", cmd);
    SwitchArg debug("", "debug", "Be even more verbose", cmd);
    SwitchArg forceColour("", "colour", "Use colour even on non-TTY", cmd);
    SwitchArg forceColor("", "color", "Use color even on non-TTY", cmd);
    SwitchArg numeric("n", "numeric", "Assume the index is numeric", cmd);
    SwitchArg unique("u", "unique", "Assume each line's index is unique", cmd);
    ValueArg<uint64_t> checkpointEvery(
            "", "checkpoint-every",
            "Create a compression checkpoint every <bytes>", false,
            0, "bytes", cmd);
    ValueArg<string> regex("", "regex", "Create an index using <regex>", false,
                           "", "regex", cmd);
    ValueArg<uint64_t> skipFirst("", "skip-first", "Skip the first <num> lines",
                                 false, 0, "num", cmd);
    ValueArg<int> field("f", "field", "Create an index using field <num> "
                                "(delimited by -d/--delimiter)",
                        false, 0, "num", cmd);
    ValueArg<char> delimiter("d", "delimiter",
                             "Use <char> as the field delimiter", false, ' ',
                             "char", cmd);
    ValueArg<string> externalIndexer(
            "p", "pipe",
            "Create indices by piping output through <CMD> which should output "
                    "a single line for each input line. "
                    "Multiple keys should be separated by the --delimiter "
                    "character (which defaults to a space). "
                    "The CMD should be unbuffered "
                    "(man stdbuf(1) for one way of doing this).\n"
                    "Example:  --pipe 'jq --raw-output --unbuffered .eventId')",
            false, "", "CMD", cmd);
    ValueArg<string> indexFilename("", "index-file",
                                   "Store index in <index-file> "
                                           "(default <file>.zindex)", false, "",
                                   "index-file", cmd);
    cmd.parse(argc, argv);

    ConsoleLog log(
            debug.isSet() ? Log::Severity::Debug : verbose.isSet()
                                                   ? Log::Severity::Info
                                                   : Log::Severity::Warning,
            forceColour.isSet() || forceColor.isSet());

    try {
        auto realPath = getRealPath(inputFile.getValue());
        File in(fopen(realPath.c_str(), "rb"));
        if (in.get() == nullptr) {
            log.debug("Unable to open ", inputFile.getValue(), " (as ",
                      realPath,
                      ")");
            log.error("Could not open ", inputFile.getValue(), " for reading");
            return 1;
        }

        auto outputFile = indexFilename.isSet() ? indexFilename.getValue() :
                          inputFile.getValue() + ".zindex";
        Index::Builder builder(log, move(in), realPath, outputFile,
                               skipFirst.getValue());
        if (regex.isSet() && field.isSet()) {
            throw std::runtime_error(
                    "Sorry; multiple indices are not supported yet");
        }
        if (regex.isSet()) {
            builder.addIndexer("default", regex.getValue(), numeric.isSet(),
                               unique.isSet(),
                               std::unique_ptr<LineIndexer>(
                                       new RegExpIndexer(regex.getValue())));
        }
        if (field.isSet()) {
            ostringstream name;
            name << "Field " << field.getValue() << " delimited by '"
            << delimiter.getValue() << "'";
            builder.addIndexer("default", name.str(), numeric.isSet(),
                               unique.isSet(), std::unique_ptr<LineIndexer>(
                            new FieldIndexer(delimiter.getValue(),
                                             field.getValue())));
        }
        if (externalIndexer.isSet()) {
            auto indexer = std::unique_ptr<LineIndexer>(
                    new ExternalIndexer(log,
                                        externalIndexer.getValue(),
                                        delimiter.getValue()));
            builder.addIndexer("default", externalIndexer.getValue(),
                               numeric.isSet(), unique.isSet(),
                               std::move(indexer));
        }
        if (checkpointEvery.isSet())
            builder.indexEvery(checkpointEvery.getValue());
        builder.build();
    } catch (const exception &e) {
        log.error(e.what());
    }
    return 0;
}

int main(int argc, const char *argv[]) {
    try {
        return Main(argc, argv);
    } catch (const exception &e) {
        cerr << e.what() << endl;
        return 1;
    }
}
<|endoftext|>


<commit_before>#ifndef slic3r_GUI_Utils_hpp_
#define slic3r_GUI_Utils_hpp_

#include <memory>
#include <string>
#include <ostream>
#include <functional>

#include <boost/optional.hpp>

#include <wx/frame.h>
#include <wx/dialog.h>
#include <wx/event.h>
#include <wx/filedlg.h>
#include <wx/gdicmn.h>
#include <wx/panel.h>
#include <wx/dcclient.h>
#include <wx/debug.h>

class wxCheckBox;
class wxTopLevelWindow;
class wxRect;

namespace Slic3r {
namespace GUI {

wxTopLevelWindow* find_toplevel_parent(wxWindow *window);

void on_window_geometry(wxTopLevelWindow *tlw, std::function<void()> callback);

enum { DPI_DEFAULT = 96 };

int get_dpi_for_window(wxWindow *window);

struct DpiChangedEvent : public wxEvent {
    int dpi;
    wxRect rect;

    DpiChangedEvent(wxEventType eventType, int dpi, wxRect rect)
        : wxEvent(0, eventType), dpi(dpi), rect(rect)
    {}

    virtual wxEvent *Clone() const
    {
        return new DpiChangedEvent(*this);
    }
};

wxDECLARE_EVENT(EVT_DPI_CHANGED, DpiChangedEvent);

template<class P> class DPIAware : public P
{
public:
    DPIAware(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition,
        const wxSize &size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE, const wxString &name=wxFrameNameStr)
        : P(parent, id, title, pos, size, style, name)
    {
        m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT;
        m_normal_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
        // An analog of em_unit value from GUI_App.
        m_em_unit = std::max<size_t>(10, 10 * m_scale_factor);

        m_prev_scale_factor = m_scale_factor;

        recalc_font();

        this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) {
            m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT;

            if (!m_can_rescale)
                return;

            if (is_new_scale_factor())
                rescale(evt.rect);
        });

        this->Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event)
        {
            event.Skip();

            // Suppress application rescaling, when a MainFrame moving is not ended
            m_can_rescale = false;
        });

        this->Bind(wxEVT_MOVE_END, [this](wxMoveEvent& event)
        {
            event.Skip();

            m_can_rescale = is_new_scale_factor();

            // If scale factor is different after moving of MainFrame ...
            if (m_can_rescale)
                // ... rescale application
                rescale(event.GetRect());
            else
            // set value to _true_ in purpose of possibility of a display dpi changing from System Settings
                m_can_rescale = true;
        });
    }

    virtual ~DPIAware() {}

    float   scale_factor() const        { return m_scale_factor; }
    float   prev_scale_factor() const   { return m_prev_scale_factor; }

    int     em_unit() const             { return m_em_unit; }
    int     font_size() const           { return m_font_size; }
    const wxFont& normal_font() const   { return m_normal_font; }

protected:
    virtual void on_dpi_changed(const wxRect &suggested_rect) = 0;

private:
    float m_scale_factor;
    int m_em_unit;
    int m_font_size;

    wxFont m_normal_font;
    float m_prev_scale_factor;
    bool  m_can_rescale{ true };

    void recalc_font()
    {
        wxClientDC dc(this);
        const auto metrics = dc.GetFontMetrics();
        m_font_size = metrics.height;
//         m_em_unit = metrics.averageWidth;
    }

    // check if new scale is differ from previous
    bool    is_new_scale_factor() const { return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; }

    // recursive function for scaling fonts for all controls in Window
    void    scale_controls_fonts(wxWindow *window, const float scale_f)
    {
        auto children = window->GetChildren();

        for (auto child : children) {
            scale_controls_fonts(child, scale_f);
            child->SetFont(child->GetFont().Scaled(scale_f));
        }

        window->Layout();
    }

    void    rescale(const wxRect &suggested_rect)
    {
        this->Freeze();
        const float relative_scale_factor = m_scale_factor / m_prev_scale_factor;

        // rescale fonts of all controls
        scale_controls_fonts(this, relative_scale_factor);
        this->SetFont(this->GetFont().Scaled(relative_scale_factor));

        // rescale normal_font value
        m_normal_font = m_normal_font.Scaled(relative_scale_factor);

        // An analog of em_unit value from GUI_App.
        m_em_unit = std::max<size_t>(10, 10 * m_scale_factor);

        // rescale missed controls sizes and images
        on_dpi_changed(suggested_rect);

        this->Layout();
        this->Thaw();

        // reset previous scale factor from current scale factor value
        m_prev_scale_factor = m_scale_factor;
    }

};

typedef DPIAware<wxFrame> DPIFrame;
typedef DPIAware<wxDialog> DPIDialog;

class EventGuard
{
    // This is a RAII-style smart-ptr-like guard that will bind any event to any event handler
    // and unbind it as soon as it goes out of scope or unbind() is called.
    // This can be used to solve the annoying problem of wx events being delivered to freed objects.

private:
    // This is a way to type-erase both the event type as well as the handler:

    struct EventStorageBase {
        virtual ~EventStorageBase() {}
    };

    template<class EvTag, class Fun>
    struct EventStorageFun : EventStorageBase {
        wxEvtHandler *emitter;
        EvTag tag;
        Fun fun;

        EventStorageFun(wxEvtHandler *emitter, const EvTag &tag, Fun fun)
            : emitter(emitter)
            , tag(tag)
            , fun(std::move(fun))
        {
            emitter->Bind(this->tag, this->fun);
        }

        virtual ~EventStorageFun() { emitter->Unbind(tag, fun); }
    };

    template<typename EvTag, typename Class, typename EvArg, typename EvHandler>
    struct EventStorageMethod : EventStorageBase {
        typedef void(Class::* MethodPtr)(EvArg &);

        wxEvtHandler *emitter;
        EvTag tag;
        MethodPtr method;
        EvHandler *handler;

        EventStorageMethod(wxEvtHandler *emitter, const EvTag &tag, MethodPtr method, EvHandler *handler)
            : emitter(emitter)
            , tag(tag)
            , method(method)
            , handler(handler)
        {
            emitter->Bind(tag, method, handler);
        }

        virtual ~EventStorageMethod() { emitter->Unbind(tag, method, handler); }
    };

    std::unique_ptr<EventStorageBase> event_storage;
public:
    EventGuard() {}
    EventGuard(const EventGuard&) = delete;
    EventGuard(EventGuard &&other) : event_storage(std::move(other.event_storage)) {}

    template<class EvTag, class Fun>
    EventGuard(wxEvtHandler *emitter, const EvTag &tag, Fun fun)
        :event_storage(new EventStorageFun<EvTag, Fun>(emitter, tag, std::move(fun)))
    {}

    template<typename EvTag, typename Class, typename EvArg, typename EvHandler>
    EventGuard(wxEvtHandler *emitter, const EvTag &tag, void(Class::* method)(EvArg &), EvHandler *handler)
        :event_storage(new EventStorageMethod<EvTag, Class, EvArg, EvHandler>(emitter, tag, method, handler))
    {}

    EventGuard& operator=(const EventGuard&) = delete;
    EventGuard& operator=(EventGuard &&other)
    {
        event_storage = std::move(other.event_storage);
        return *this;
    }

    void unbind() { event_storage.reset(nullptr); }
    explicit operator bool() const { return !!event_storage; }
};

class CheckboxFileDialog : public wxFileDialog
{
public:
    CheckboxFileDialog(wxWindow *parent,
        const wxString &checkbox_label,
        bool checkbox_value,
        const wxString &message = wxFileSelectorPromptStr,
        const wxString &default_dir = wxEmptyString,
        const wxString &default_file = wxEmptyString,
        const wxString &wildcard = wxFileSelectorDefaultWildcardStr,
        long style = wxFD_DEFAULT_STYLE,
        const wxPoint &pos = wxDefaultPosition,
        const wxSize &size = wxDefaultSize,
        const wxString &name = wxFileDialogNameStr
    );

    bool get_checkbox_value() const;

private:
    struct ExtraPanel : public wxPanel
    {
        wxCheckBox *cbox;

        ExtraPanel(wxWindow *parent);
        static wxWindow* ctor(wxWindow *parent);
    };

    wxString checkbox_label;
};

class WindowMetrics
{
private:
    wxRect rect;
    bool maximized;

    WindowMetrics() : maximized(false) {}
public:
    static WindowMetrics from_window(wxTopLevelWindow *window);
    static boost::optional<WindowMetrics> deserialize(const std::string &str);

    wxRect get_rect() const { return rect; }
    bool get_maximized() const { return maximized; }

    void sanitize_for_display(const wxRect &screen_rect);
    std::string serialize() const;
};

std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics);

}}

#endif
<commit_msg>Another missing include<commit_after>#ifndef slic3r_GUI_Utils_hpp_
#define slic3r_GUI_Utils_hpp_

#include <memory>
#include <string>
#include <ostream>
#include <functional>

#include <boost/optional.hpp>

#include <wx/frame.h>
#include <wx/dialog.h>
#include <wx/event.h>
#include <wx/filedlg.h>
#include <wx/gdicmn.h>
#include <wx/panel.h>
#include <wx/dcclient.h>
#include <wx/debug.h>
#include <wx/settings.h>

class wxCheckBox;
class wxTopLevelWindow;
class wxRect;

namespace Slic3r {
namespace GUI {

wxTopLevelWindow* find_toplevel_parent(wxWindow *window);

void on_window_geometry(wxTopLevelWindow *tlw, std::function<void()> callback);

enum { DPI_DEFAULT = 96 };

int get_dpi_for_window(wxWindow *window);

struct DpiChangedEvent : public wxEvent {
    int dpi;
    wxRect rect;

    DpiChangedEvent(wxEventType eventType, int dpi, wxRect rect)
        : wxEvent(0, eventType), dpi(dpi), rect(rect)
    {}

    virtual wxEvent *Clone() const
    {
        return new DpiChangedEvent(*this);
    }
};

wxDECLARE_EVENT(EVT_DPI_CHANGED, DpiChangedEvent);

template<class P> class DPIAware : public P
{
public:
    DPIAware(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition,
        const wxSize &size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE, const wxString &name=wxFrameNameStr)
        : P(parent, id, title, pos, size, style, name)
    {
        m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT;
        m_normal_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
        // An analog of em_unit value from GUI_App.
        m_em_unit = std::max<size_t>(10, 10 * m_scale_factor);

        m_prev_scale_factor = m_scale_factor;

        recalc_font();

        this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) {
            m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT;

            if (!m_can_rescale)
                return;

            if (is_new_scale_factor())
                rescale(evt.rect);
        });

        this->Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event)
        {
            event.Skip();

            // Suppress application rescaling, when a MainFrame moving is not ended
            m_can_rescale = false;
        });

        this->Bind(wxEVT_MOVE_END, [this](wxMoveEvent& event)
        {
            event.Skip();

            m_can_rescale = is_new_scale_factor();

            // If scale factor is different after moving of MainFrame ...
            if (m_can_rescale)
                // ... rescale application
                rescale(event.GetRect());
            else
            // set value to _true_ in purpose of possibility of a display dpi changing from System Settings
                m_can_rescale = true;
        });
    }

    virtual ~DPIAware() {}

    float   scale_factor() const        { return m_scale_factor; }
    float   prev_scale_factor() const   { return m_prev_scale_factor; }

    int     em_unit() const             { return m_em_unit; }
    int     font_size() const           { return m_font_size; }
    const wxFont& normal_font() const   { return m_normal_font; }

protected:
    virtual void on_dpi_changed(const wxRect &suggested_rect) = 0;

private:
    float m_scale_factor;
    int m_em_unit;
    int m_font_size;

    wxFont m_normal_font;
    float m_prev_scale_factor;
    bool  m_can_rescale{ true };

    void recalc_font()
    {
        wxClientDC dc(this);
        const auto metrics = dc.GetFontMetrics();
        m_font_size = metrics.height;
//         m_em_unit = metrics.averageWidth;
    }

    // check if new scale is differ from previous
    bool    is_new_scale_factor() const { return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; }

    // recursive function for scaling fonts for all controls in Window
    void    scale_controls_fonts(wxWindow *window, const float scale_f)
    {
        auto children = window->GetChildren();

        for (auto child : children) {
            scale_controls_fonts(child, scale_f);
            child->SetFont(child->GetFont().Scaled(scale_f));
        }

        window->Layout();
    }

    void    rescale(const wxRect &suggested_rect)
    {
        this->Freeze();
        const float relative_scale_factor = m_scale_factor / m_prev_scale_factor;

        // rescale fonts of all controls
        scale_controls_fonts(this, relative_scale_factor);
        this->SetFont(this->GetFont().Scaled(relative_scale_factor));

        // rescale normal_font value
        m_normal_font = m_normal_font.Scaled(relative_scale_factor);

        // An analog of em_unit value from GUI_App.
        m_em_unit = std::max<size_t>(10, 10 * m_scale_factor);

        // rescale missed controls sizes and images
        on_dpi_changed(suggested_rect);

        this->Layout();
        this->Thaw();

        // reset previous scale factor from current scale factor value
        m_prev_scale_factor = m_scale_factor;
    }

};

typedef DPIAware<wxFrame> DPIFrame;
typedef DPIAware<wxDialog> DPIDialog;

class EventGuard
{
    // This is a RAII-style smart-ptr-like guard that will bind any event to any event handler
    // and unbind it as soon as it goes out of scope or unbind() is called.
    // This can be used to solve the annoying problem of wx events being delivered to freed objects.

private:
    // This is a way to type-erase both the event type as well as the handler:

    struct EventStorageBase {
        virtual ~EventStorageBase() {}
    };

    template<class EvTag, class Fun>
    struct EventStorageFun : EventStorageBase {
        wxEvtHandler *emitter;
        EvTag tag;
        Fun fun;

        EventStorageFun(wxEvtHandler *emitter, const EvTag &tag, Fun fun)
            : emitter(emitter)
            , tag(tag)
            , fun(std::move(fun))
        {
            emitter->Bind(this->tag, this->fun);
        }

        virtual ~EventStorageFun() { emitter->Unbind(tag, fun); }
    };

    template<typename EvTag, typename Class, typename EvArg, typename EvHandler>
    struct EventStorageMethod : EventStorageBase {
        typedef void(Class::* MethodPtr)(EvArg &);

        wxEvtHandler *emitter;
        EvTag tag;
        MethodPtr method;
        EvHandler *handler;

        EventStorageMethod(wxEvtHandler *emitter, const EvTag &tag, MethodPtr method, EvHandler *handler)
            : emitter(emitter)
            , tag(tag)
            , method(method)
            , handler(handler)
        {
            emitter->Bind(tag, method, handler);
        }

        virtual ~EventStorageMethod() { emitter->Unbind(tag, method, handler); }
    };

    std::unique_ptr<EventStorageBase> event_storage;
public:
    EventGuard() {}
    EventGuard(const EventGuard&) = delete;
    EventGuard(EventGuard &&other) : event_storage(std::move(other.event_storage)) {}

    template<class EvTag, class Fun>
    EventGuard(wxEvtHandler *emitter, const EvTag &tag, Fun fun)
        :event_storage(new EventStorageFun<EvTag, Fun>(emitter, tag, std::move(fun)))
    {}

    template<typename EvTag, typename Class, typename EvArg, typename EvHandler>
    EventGuard(wxEvtHandler *emitter, const EvTag &tag, void(Class::* method)(EvArg &), EvHandler *handler)
        :event_storage(new EventStorageMethod<EvTag, Class, EvArg, EvHandler>(emitter, tag, method, handler))
    {}

    EventGuard& operator=(const EventGuard&) = delete;
    EventGuard& operator=(EventGuard &&other)
    {
        event_storage = std::move(other.event_storage);
        return *this;
    }

    void unbind() { event_storage.reset(nullptr); }
    explicit operator bool() const { return !!event_storage; }
};

class CheckboxFileDialog : public wxFileDialog
{
public:
    CheckboxFileDialog(wxWindow *parent,
        const wxString &checkbox_label,
        bool checkbox_value,
        const wxString &message = wxFileSelectorPromptStr,
        const wxString &default_dir = wxEmptyString,
        const wxString &default_file = wxEmptyString,
        const wxString &wildcard = wxFileSelectorDefaultWildcardStr,
        long style = wxFD_DEFAULT_STYLE,
        const wxPoint &pos = wxDefaultPosition,
        const wxSize &size = wxDefaultSize,
        const wxString &name = wxFileDialogNameStr
    );

    bool get_checkbox_value() const;

private:
    struct ExtraPanel : public wxPanel
    {
        wxCheckBox *cbox;

        ExtraPanel(wxWindow *parent);
        static wxWindow* ctor(wxWindow *parent);
    };

    wxString checkbox_label;
};

class WindowMetrics
{
private:
    wxRect rect;
    bool maximized;

    WindowMetrics() : maximized(false) {}
public:
    static WindowMetrics from_window(wxTopLevelWindow *window);
    static boost::optional<WindowMetrics> deserialize(const std::string &str);

    wxRect get_rect() const { return rect; }
    bool get_maximized() const { return maximized; }

    void sanitize_for_display(const wxRect &screen_rect);
    std::string serialize() const;
};

std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics);

}}

#endif
<|endoftext|>


<commit_before>#include <common/buffer.h>

#include <ssh/ssh_algorithm_negotiation.h>
#include <ssh/ssh_mac.h>
#include <ssh/ssh_session.h>

namespace {
	struct ssh_mac_algorithm {
		const char *rfc4250_name_;
		CryptoMAC::Algorithm crypto_algorithm_;
		unsigned size_;
	};

	static const struct ssh_mac_algorithm ssh_mac_algorithms[] = {
		{ "hmac-sha1",		CryptoMAC::SHA1,	0 },
		{ "hmac-sha256",	CryptoMAC::SHA256,	0 },
		{ "hmac-md5",		CryptoMAC::MD5,		0 },
		{ "hmac-ripemd160",	CryptoMAC::RIPEMD160,	0 },
		{ "hmac-sha1-96",	CryptoMAC::SHA1,	12 },
		{ "hmac-md5-96",	CryptoMAC::MD5,		12 },
		{ NULL,			CryptoMAC::MD5,		0 }
	};

	class CryptoSSHMAC : public SSH::MAC {
		LogHandle log_;
		CryptoMAC::Instance *instance_;
	public:
		CryptoSSHMAC(const std::string& xname, CryptoMAC::Instance *instance, unsigned xsize)
		: SSH::MAC(xname, xsize == 0 ? instance->size() : xsize, instance->size()),
		  log_("/ssh/mac/crypto/" + xname),
		  instance_(instance)
		{ }

		~CryptoSSHMAC()
		{ }

		MAC *clone(void) const
		{
			return (new CryptoSSHMAC(name_, instance_->clone(), key_size_));
		}

		bool initialize(const Buffer *key)
		{
			return (instance_->initialize(key));
		}

		bool mac(Buffer *out, const Buffer *in)
		{
			return (instance_->mac(out, in));
		}
	};
}

void
SSH::MAC::add_algorithms(Session *session)
{
	const struct ssh_mac_algorithm *alg;

	for (alg = ssh_mac_algorithms; alg->rfc4250_name_ != NULL; alg++) {
		const CryptoMAC::Method *method = CryptoMAC::Method::method(alg->crypto_algorithm_);
		if (method == NULL) {
			DEBUG("/ssh/mac") << "Could not get method for algorithm: " << alg->crypto_algorithm_;
			continue;
		}
		CryptoMAC::Instance *instance = method->instance(alg->crypto_algorithm_);
		if (instance == NULL) {
			DEBUG("/ssh/mac") << "Could not get instance for algorithm: " << alg->crypto_algorithm_;
			continue;
		}
		session->algorithm_negotiation_->add_algorithm(new CryptoSSHMAC(alg->rfc4250_name_, instance, alg->size_));
	}
}

SSH::MAC *
SSH::MAC::algorithm(CryptoMAC::Algorithm xalgorithm)
{
	const struct ssh_mac_algorithm *alg;

	for (alg = ssh_mac_algorithms; alg->rfc4250_name_ != NULL; alg++) {
		if (xalgorithm != alg->crypto_algorithm_)
			continue;
		const CryptoMAC::Method *method = CryptoMAC::Method::method(xalgorithm);
		if (method == NULL) {
			ERROR("/ssh/mac") << "Could not get method for algorithm: " << xalgorithm;
			return (NULL);
		}
		CryptoMAC::Instance *instance = method->instance(xalgorithm);
		if (instance == NULL) {
			ERROR("/ssh/mac") << "Could not get instance for algorithm: " << xalgorithm;
			return (NULL);
		}
		return (new CryptoSSHMAC(alg->rfc4250_name_, instance, alg->size_));
	}
	ERROR("/ssh/mac") << "No SSH MAC support is available for algorithm: " << xalgorithm;
	return (NULL);
}
<commit_msg>Adjust algorithms.<commit_after>#include <common/buffer.h>

#include <ssh/ssh_algorithm_negotiation.h>
#include <ssh/ssh_mac.h>
#include <ssh/ssh_session.h>

namespace {
	struct ssh_mac_algorithm {
		const char *rfc4250_name_;
		CryptoMAC::Algorithm crypto_algorithm_;
		unsigned size_;
	};

	static const struct ssh_mac_algorithm ssh_mac_algorithms[] = {
		{ "hmac-sha1",		CryptoMAC::SHA1,	0 },
		{ "hmac-sha2-256",	CryptoMAC::SHA256,	0 },
		{ "hmac-sha2-512",	CryptoMAC::SHA512,	0 },
		{ "hmac-ripemd160",	CryptoMAC::RIPEMD160,	0 },
		{ "hmac-md5",		CryptoMAC::MD5,		0 },
		{ "hmac-sha1-96",	CryptoMAC::SHA1,	12 },
		{ "hmac-md5-96",	CryptoMAC::MD5,		12 },
		{ NULL,			CryptoMAC::MD5,		0 }
	};

	class CryptoSSHMAC : public SSH::MAC {
		LogHandle log_;
		CryptoMAC::Instance *instance_;
	public:
		CryptoSSHMAC(const std::string& xname, CryptoMAC::Instance *instance, unsigned xsize)
		: SSH::MAC(xname, xsize == 0 ? instance->size() : xsize, instance->size()),
		  log_("/ssh/mac/crypto/" + xname),
		  instance_(instance)
		{ }

		~CryptoSSHMAC()
		{ }

		MAC *clone(void) const
		{
			return (new CryptoSSHMAC(name_, instance_->clone(), key_size_));
		}

		bool initialize(const Buffer *key)
		{
			return (instance_->initialize(key));
		}

		bool mac(Buffer *out, const Buffer *in)
		{
			return (instance_->mac(out, in));
		}
	};
}

void
SSH::MAC::add_algorithms(Session *session)
{
	const struct ssh_mac_algorithm *alg;

	for (alg = ssh_mac_algorithms; alg->rfc4250_name_ != NULL; alg++) {
		const CryptoMAC::Method *method = CryptoMAC::Method::method(alg->crypto_algorithm_);
		if (method == NULL) {
			DEBUG("/ssh/mac") << "Could not get method for algorithm: " << alg->crypto_algorithm_;
			continue;
		}
		CryptoMAC::Instance *instance = method->instance(alg->crypto_algorithm_);
		if (instance == NULL) {
			DEBUG("/ssh/mac") << "Could not get instance for algorithm: " << alg->crypto_algorithm_;
			continue;
		}
		session->algorithm_negotiation_->add_algorithm(new CryptoSSHMAC(alg->rfc4250_name_, instance, alg->size_));
	}
}

SSH::MAC *
SSH::MAC::algorithm(CryptoMAC::Algorithm xalgorithm)
{
	const struct ssh_mac_algorithm *alg;

	for (alg = ssh_mac_algorithms; alg->rfc4250_name_ != NULL; alg++) {
		if (xalgorithm != alg->crypto_algorithm_)
			continue;
		const CryptoMAC::Method *method = CryptoMAC::Method::method(xalgorithm);
		if (method == NULL) {
			ERROR("/ssh/mac") << "Could not get method for algorithm: " << xalgorithm;
			return (NULL);
		}
		CryptoMAC::Instance *instance = method->instance(xalgorithm);
		if (instance == NULL) {
			ERROR("/ssh/mac") << "Could not get instance for algorithm: " << xalgorithm;
			return (NULL);
		}
		return (new CryptoSSHMAC(alg->rfc4250_name_, instance, alg->size_));
	}
	ERROR("/ssh/mac") << "No SSH MAC support is available for algorithm: " << xalgorithm;
	return (NULL);
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2014 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin-explorer.
 *
 * libbitcoin-explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <bitcoin/explorer/obelisk_client.hpp>

#include <boost/filesystem.hpp>
#include <czmq++/czmqpp.hpp>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/explorer/async_client.hpp>
#include <bitcoin/explorer/primitives/cert_key.hpp>
#include <bitcoin/explorer/primitives/uri.hpp>

using namespace bc;
using namespace bc::client;
using namespace bc::explorer::primitives;
using namespace czmqpp;
using boost::filesystem::path;

namespace libbitcoin {
namespace explorer {

constexpr int zmq_no_linger = 0;
constexpr int zmq_curve_enabled = 1;

obelisk_client::obelisk_client(const period_ms& timeout, uint8_t retries)
    : socket_(context_, ZMQ_DEALER)
{
    stream_ = std::make_shared<socket_stream>(socket_);
    auto base_stream = std::static_pointer_cast<message_stream>(stream_);
    codec_ = std::make_shared<obelisk_codec>(base_stream);
    codec_->set_timeout(timeout);
    codec_->set_retries(retries);
}

obelisk_client::obelisk_client(const connection_type& channel)
    : obelisk_client(channel.wait, channel.retries)
{
}

bool obelisk_client::connect(const uri& address)
{
    // ZMQ *only* returns 0 or -1 for this call, so make boolean.
    bool success = socket_.connect(address.to_string()) == zmq_success;
    if (success)
        socket_.set_linger(zmq_no_linger);

    return success;
}

bool obelisk_client::connect(const uri& address,
    const cert_key& server_public_cert)
{
    if (!zsys_has_curve())
        return false;

    const auto server_key = server_public_cert.get_base85();
    if (!server_key.empty())
        socket_.set_curve_serverkey(server_key);

    return connect(address);
}

bool obelisk_client::connect(const uri& address,
    const cert_key& server_public_cert, const path& client_private_cert_path)
{
    if (!zsys_has_curve())
        return false;

    const auto& cert_path = client_private_cert_path.string();
    if (!cert_path.empty())
    {
        certificate cert(cert_path);
        cert.apply(socket_);
        socket_.set_curve_server(zmq_curve_enabled);
    }

    return connect(address, server_public_cert);
}

bool obelisk_client::connect(const connection_type& channel)
{
    return connect(channel.server, channel.key, channel.cert_path);
}

std::shared_ptr<obelisk_codec> obelisk_client::get_codec()
{
    return codec_;
}

bool obelisk_client::resolve_callbacks()
{
    auto delay = static_cast<int>(codec_->wakeup().count());
    czmqpp::poller poller;
    poller.add(stream_->get_socket());

    while (delay > 0)
    {
        poller.wait(delay);

        if (poller.terminated())
            return false;

        if (poller.expired())
        {
            // recompute the delay and signal the appropriate error callbacks.
            delay = static_cast<int>(codec_->wakeup().count());
            continue;
        }

        stream_->signal_response(codec_);
        if (codec_->outstanding_call_count() == 0)
            break;
    }

    return true;
}

void obelisk_client::poll_until_termination(const client::period_ms& timeout)
{
    czmqpp::poller poller;
    poller.add(stream_->get_socket());

    while (true)
    {
        poller.wait(static_cast<int>(timeout.count()));

        if (poller.terminated())
            break;

        if (!poller.expired())
            stream_->signal_response(codec_);
    }
}

void obelisk_client::poll_until_timeout_cumulative(const period_ms& timeout)
{
    czmqpp::poller poller;
    poller.add(stream_->get_socket());

    // calculate expected expiration time
    auto expiry = std::chrono::steady_clock::now() + timeout;

    while (std::chrono::steady_clock::now() < expiry)
    {
        // calculate maximum interval from now to expiration
        auto max_wait_interval = std::chrono::duration_cast<period_ms>(
            expiry - std::chrono::steady_clock::now());

        poller.wait(static_cast<int>(max_wait_interval.count()));

        if (poller.terminated())
        {
            break;
        }

        if (!poller.expired())
        {
            stream_->signal_response(codec_);
        }
    }
}

} // namespace explorer
} // namespace libbitcoin
<commit_msg>Handle cert load failure error condition.<commit_after>/**
 * Copyright (c) 2011-2014 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin-explorer.
 *
 * libbitcoin-explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <bitcoin/explorer/obelisk_client.hpp>

#include <boost/filesystem.hpp>
#include <czmq++/czmqpp.hpp>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/explorer/async_client.hpp>
#include <bitcoin/explorer/primitives/cert_key.hpp>
#include <bitcoin/explorer/primitives/uri.hpp>

using namespace bc;
using namespace bc::client;
using namespace bc::explorer::primitives;
using namespace czmqpp;
using boost::filesystem::path;

namespace libbitcoin {
namespace explorer {

constexpr int zmq_no_linger = 0;
constexpr int zmq_curve_enabled = 1;

obelisk_client::obelisk_client(const period_ms& timeout, uint8_t retries)
    : socket_(context_, ZMQ_DEALER)
{
    stream_ = std::make_shared<socket_stream>(socket_);
    auto base_stream = std::static_pointer_cast<message_stream>(stream_);
    codec_ = std::make_shared<obelisk_codec>(base_stream);
    codec_->set_timeout(timeout);
    codec_->set_retries(retries);
}

obelisk_client::obelisk_client(const connection_type& channel)
    : obelisk_client(channel.wait, channel.retries)
{
}

bool obelisk_client::connect(const uri& address)
{
    // ZMQ *only* returns 0 or -1 for this call, so make boolean.
    bool success = socket_.connect(address.to_string()) == zmq_success;
    if (success)
        socket_.set_linger(zmq_no_linger);

    return success;
}

bool obelisk_client::connect(const uri& address,
    const cert_key& server_public_cert)
{
    if (!zsys_has_curve())
        return false;

    const auto server_key = server_public_cert.get_base85();
    if (!server_key.empty())
        socket_.set_curve_serverkey(server_key);

    return connect(address);
}

bool obelisk_client::connect(const uri& address,
    const cert_key& server_public_cert, const path& client_private_cert_path)
{
    if (!zsys_has_curve())
        return false;

    const auto& cert_path = client_private_cert_path.string();
    if (!cert_path.empty())
    {
        certificate cert(cert_path);
        if (!cert.valid())
            return false;

        cert.apply(socket_);
        socket_.set_curve_server(zmq_curve_enabled);
    }

    return connect(address, server_public_cert);
}

bool obelisk_client::connect(const connection_type& channel)
{
    return connect(channel.server, channel.key, channel.cert_path);
}

std::shared_ptr<obelisk_codec> obelisk_client::get_codec()
{
    return codec_;
}

bool obelisk_client::resolve_callbacks()
{
    auto delay = static_cast<int>(codec_->wakeup().count());
    czmqpp::poller poller;
    poller.add(stream_->get_socket());

    while (delay > 0)
    {
        poller.wait(delay);

        if (poller.terminated())
            return false;

        if (poller.expired())
        {
            // recompute the delay and signal the appropriate error callbacks.
            delay = static_cast<int>(codec_->wakeup().count());
            continue;
        }

        stream_->signal_response(codec_);
        if (codec_->outstanding_call_count() == 0)
            break;
    }

    return true;
}

void obelisk_client::poll_until_termination(const client::period_ms& timeout)
{
    czmqpp::poller poller;
    poller.add(stream_->get_socket());

    while (true)
    {
        poller.wait(static_cast<int>(timeout.count()));

        if (poller.terminated())
            break;

        if (!poller.expired())
            stream_->signal_response(codec_);
    }
}

void obelisk_client::poll_until_timeout_cumulative(const period_ms& timeout)
{
    czmqpp::poller poller;
    poller.add(stream_->get_socket());

    // calculate expected expiration time
    auto expiry = std::chrono::steady_clock::now() + timeout;

    while (std::chrono::steady_clock::now() < expiry)
    {
        // calculate maximum interval from now to expiration
        auto max_wait_interval = std::chrono::duration_cast<period_ms>(
            expiry - std::chrono::steady_clock::now());

        poller.wait(static_cast<int>(max_wait_interval.count()));

        if (poller.terminated())
        {
            break;
        }

        if (!poller.expired())
        {
            stream_->signal_response(codec_);
        }
    }
}

} // namespace explorer
} // namespace libbitcoin
<|endoftext|>