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

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <vector>
#include <iostream>
#include <iomanip>

#include "pefile.h"
#include "pemap.h"
#include "pepatch.h"

namespace {

/**
 * A range of memory to patch. This is used to keep track of what needs to be
 * patched in the PE file.
 *
 * All the patch locations need to be found before finishing parsing. If we
 * patched while parsing, then parsing could fail and we could be left with an
 * incomplete patch. Thus, we keep a list of patches and patch everything all at
 * once to mitigate failure cases.
 */
struct Patch
{
    // Location to patch.
    size_t offset;

    // Length of the data.
    size_t length;

    // Data overwrite the given location with.
    const uint8_t* data;

    // Name of the patch. Useful to see what's going on.
    const char* name;

    Patch(size_t offset, size_t length, const uint8_t* data, const char* name = NULL)
        : offset(offset),
          length(length),
          data(data),
          name(name)
    {}

    template<typename T>
    Patch(size_t offset, const T* data, const char* name = NULL)
        : offset(offset),
          length(sizeof(T)),
          data((const uint8_t*)data),
          name(name)
    {
    }

    friend std::ostream& operator<<(std::ostream& os, const Patch& patch);

    /**
     * Applies the patch. Note that no bounds checking is done. It is assumed
     * that it has already been done.
     */
    void apply(uint8_t* buf, bool dryRun) {
        std::cout << *this << std::endl;

        if (!dryRun) {
            for (size_t i = 0; i < length; ++i)
                buf[offset+i] = data[i];
        }
    }
};

std::ostream& operator<<(std::ostream& os, const Patch& patch) {
    os << "Patching '" << patch.name
       << "' at offset 0x" << std::hex << patch.offset << std::dec
       << " (" << patch.length << " bytes)";
    return os;
}

class Patches
{
private:
    // List of patches
    std::vector<Patch> _patches;

    uint8_t* _buf;

public:

    Patches(uint8_t* buf) : _buf(buf) {}

    void add(Patch patch) {
        _patches.push_back(patch);
    }

    template<typename T>
    void add(const T* addr, const T* data, const char* name = NULL)
    {
        add(Patch((const uint8_t*)addr - _buf, data, name));
    }

    void apply(bool dryRun = false) {
        for (auto&& patch: _patches)
            patch.apply(_buf, dryRun);
    }
};

/**
 * Helper class to parse image headers.
 */
class PEFile
{
private:

    const uint8_t* _buf;
    const size_t _length;

    // Pointer to the optional header.
    const uint8_t* _optional;

    void _init();

public:

    const IMAGE_DOS_HEADER* dosHeader;
    const IMAGE_FILE_HEADER* fileHeader;
    const IMAGE_SECTION_HEADER* sectionHeaders;

    PEFile(const uint8_t* buf, size_t length);

    /**
     * The Magic field of the optional header. This is used to determine if the
     * optional header is 32- or 64-bit.
     */
    uint16_t magic() const {
        return *(uint16_t*)_optional;
    }

    /**
     * Returns the optional header of the given type.
     */
    template<typename T>
    const T* optional() const {
        // Bounds check
        if (_optional + sizeof(T) >= _buf + _length)
            throw InvalidImage("missing IMAGE_OPTIONAL_HEADER");

        return (T*)_optional;
    }

    /**
     * Translates a relative virtual address (RVA) to a physical address within
     * the mapped file. Note that this does not do any bounds checking. You must
     * check the bounds before dereferencing the returned pointer.
     */
    const uint8_t* translate(size_t rva) const {

        const IMAGE_SECTION_HEADER* s = sectionHeaders;

        for (size_t i = 0; i < fileHeader->NumberOfSections; ++i) {
            if (rva >= s->VirtualAddress &&
                rva < s->VirtualAddress + s->Misc.VirtualSize)
                break;

            ++s;
        }

        return _buf + rva - s->VirtualAddress + s->PointerToRawData;
    }

    /**
     * Checks if the given image address is valid.
     */
    bool isValidAddress(const uint8_t* p) const {
        return p >= _buf && p < _buf + _length;
    }
};

PEFile::PEFile(const uint8_t* buf, size_t length)
    : _buf(buf), _length(length)
{
    _init();
}

void PEFile::_init() {

    const uint8_t* p = _buf;
    const uint8_t* end = _buf + _length;

    if (p + sizeof(IMAGE_DOS_HEADER) >= end)
        throw InvalidImage("missing DOS header");

    dosHeader = (IMAGE_DOS_HEADER*)p;
    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
        throw InvalidImage("invalid DOS signature");

    // Skip to the NT headers. Note that we don't parse this section as
    // IMAGE_NT_HEADERS32/IMAGE_NT_HEADERS64 because we don't yet know if this
    // image is 32- or 64-bit. That information is in the first field of the
    // optional header.
    p += dosHeader->e_lfanew;

    //
    // Check the signature
    //
    if (p + sizeof(uint32_t) >= end)
        throw InvalidImage("missing PE signature");

    const uint32_t signature = *(uint32_t*)p;
    if (signature != *(const uint32_t*)"PE\0\0")
        throw InvalidImage("invalid PE signature");

    p += sizeof(signature);

    //
    // Parse the image file header
    //
    if (p + sizeof(IMAGE_FILE_HEADER) >= end)
        throw InvalidImage("missing IMAGE_FILE_HEADER");

    fileHeader = (IMAGE_FILE_HEADER*)p;

    p += sizeof(IMAGE_FILE_HEADER);

    //
    // The optional header is here. Parsing of this is delayed because it can
    // either be a 32- or 64-bit structure.
    //
    _optional = p;

    p += fileHeader->SizeOfOptionalHeader;

    //
    // Section headers. There are IMAGE_FILE_HEADER.NumberOfSections of these.
    //
    sectionHeaders = (IMAGE_SECTION_HEADER*)p;
}

/**
 * Patches the timestamp associated with a data directory.
 */
template<typename T>
void patchDataDirectory(const PEFile& pe, Patches& patches,
        const IMAGE_DATA_DIRECTORY* imageDataDirs,
        uint32_t entry, const char* name, uint32_t timestamp) {

    const IMAGE_DATA_DIRECTORY& imageDataDir = imageDataDirs[entry];

    // Doesn't exist? Nothing to patch.
    if (imageDataDir.VirtualAddress == 0)
        return;

    if (imageDataDir.Size < sizeof(T)) {
        // Note that we check if the size is less than our defined struct.
        // Microsoft is free to add elements to the end of the struct in future
        // versions as that still maintains ABI compatibility.
        throw InvalidImage("invalid IMAGE_DATA_DIRECTORY size");
    }

    const uint8_t* p = pe.translate(imageDataDir.VirtualAddress);
    if (!pe.isValidAddress(p))
        throw InvalidImage("invalid IMAGE_DATA_DIRECTORY offset");

    const T* dir = (const T*)p;

    if (dir->TimeDateStamp != 0)
        patches.add(&dir->TimeDateStamp, &timestamp, name);
}

/**
 * Patches the image based on the optional header type. The optional header can
 * be either 32- or 64-bit.
 */
template<typename T>
void patchOptionalHeader(const PEFile& pe,
        Patches& patches, uint32_t timestamp) {

    const T* optional = pe.optional<T>();

    patches.add(&optional->CheckSum, &timestamp,
            "OptionalHeader.CheckSum");

    const IMAGE_DATA_DIRECTORY* dataDirs = optional->DataDirectory;

    // Patch exports directory timestamp
    patchDataDirectory<IMAGE_EXPORT_DIRECTORY>(pe, patches,
            dataDirs, IMAGE_DIRECTORY_ENTRY_EXPORT,
            "IMAGE_EXPORT_DIRECTORY.TimeDateStamp", timestamp);

    // Patch resource directory timestamp
    patchDataDirectory<IMAGE_RESOURCE_DIRECTORY>(pe, patches,
            dataDirs, IMAGE_DIRECTORY_ENTRY_RESOURCE,
            "IMAGE_RESOURCE_DIRECTORY.TimeDateStamp", timestamp);
}

}

void patchImage(const char* imagePath, const char* pdbPath, bool dryRun) {
    MemMap image(imagePath);
    MemMap pdb(pdbPath);

    // Replacement for timestamps
    const uint32_t timestamp = 0;

    uint8_t* buf = (uint8_t*)image.buf();
    const size_t length = image.length();

    PEFile pe = PEFile(buf, length);

    Patches patches(buf);

    patches.add(&pe.fileHeader->TimeDateStamp, &timestamp,
            "IMAGE_FILE_HEADER.TimeDateStamp");

    switch (pe.magic()) {
        case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
            // Patch as a PE32 file
            patchOptionalHeader<IMAGE_OPTIONAL_HEADER32>(pe,
                    patches, timestamp);
            break;

        case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
            // Patch as a PE32+ file
            patchOptionalHeader<IMAGE_OPTIONAL_HEADER64>(pe,
                    patches, timestamp);
            break;

        default:
            throw InvalidImage("unsupported IMAGE_NT_HEADERS.OptionalHeader");
    }

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

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <vector>
#include <iostream>
#include <iomanip>

#include "pefile.h"
#include "pemap.h"
#include "pepatch.h"

namespace {

/**
 * A range of memory to patch. This is used to keep track of what needs to be
 * patched in the PE file.
 *
 * All the patch locations need to be found before finishing parsing. If we
 * patched while parsing, then parsing could fail and we could be left with an
 * incomplete patch. Thus, we keep a list of patches and patch everything all at
 * once to mitigate failure cases.
 */
struct Patch
{
    // Location to patch.
    size_t offset;

    // Length of the data.
    size_t length;

    // Data overwrite the given location with.
    const uint8_t* data;

    // Name of the patch. Useful to see what's going on.
    const char* name;

    Patch(size_t offset, size_t length, const uint8_t* data, const char* name = NULL)
        : offset(offset),
          length(length),
          data(data),
          name(name)
    {}

    template<typename T>
    Patch(size_t offset, const T* data, const char* name = NULL)
        : offset(offset),
          length(sizeof(T)),
          data((const uint8_t*)data),
          name(name)
    {
    }

    friend std::ostream& operator<<(std::ostream& os, const Patch& patch);

    /**
     * Applies the patch. Note that no bounds checking is done. It is assumed
     * that it has already been done.
     */
    void apply(uint8_t* buf, bool dryRun) {
        std::cout << *this << std::endl;

        if (!dryRun) {
            for (size_t i = 0; i < length; ++i)
                buf[offset+i] = data[i];
        }
    }
};

std::ostream& operator<<(std::ostream& os, const Patch& patch) {
    os << "Patching '" << patch.name
       << "' at offset 0x" << std::hex << patch.offset << std::dec
       << " (" << patch.length << " bytes)";
    return os;
}

class Patches
{
private:
    // List of patches
    std::vector<Patch> _patches;

    uint8_t* _buf;

public:

    Patches(uint8_t* buf) : _buf(buf) {}

    void add(Patch patch) {
        _patches.push_back(patch);
    }

    template<typename T>
    void add(const T* addr, const T* data, const char* name = NULL)
    {
        add(Patch((const uint8_t*)addr - _buf, data, name));
    }

    void apply(bool dryRun = false) {
        for (auto&& patch: _patches)
            patch.apply(_buf, dryRun);
    }
};

/**
 * Helper class to parse image headers.
 */
class PEFile
{
private:

    const uint8_t* _buf;
    const size_t _length;

    // Pointer to the optional header.
    const uint8_t* _optional;

    void _init();

public:

    const IMAGE_DOS_HEADER* dosHeader;
    const IMAGE_FILE_HEADER* fileHeader;
    const IMAGE_SECTION_HEADER* sectionHeaders;

    PEFile(const uint8_t* buf, size_t length);

    /**
     * The Magic field of the optional header. This is used to determine if the
     * optional header is 32- or 64-bit.
     */
    uint16_t magic() const {
        return *(uint16_t*)_optional;
    }

    /**
     * Returns the optional header of the given type.
     */
    template<typename T>
    const T* optional() const {
        // Bounds check
        if (_optional + sizeof(T) >= _buf + _length)
            throw InvalidImage("missing IMAGE_OPTIONAL_HEADER");

        return (T*)_optional;
    }

    /**
     * Translates a relative virtual address (RVA) to a physical address within
     * the mapped file. Note that this does not do any bounds checking. You must
     * check the bounds before dereferencing the returned pointer.
     */
    const uint8_t* translate(size_t rva) const {

        const IMAGE_SECTION_HEADER* s = sectionHeaders;

        for (size_t i = 0; i < fileHeader->NumberOfSections; ++i) {
            if (rva >= s->VirtualAddress &&
                rva < s->VirtualAddress + s->Misc.VirtualSize)
                break;

            ++s;
        }

        return _buf + rva - s->VirtualAddress + s->PointerToRawData;
    }

    /**
     * Checks if the given image address is valid.
     */
    bool isValidAddress(const uint8_t* p) const {
        return p >= _buf && p < _buf + _length;
    }
};

PEFile::PEFile(const uint8_t* buf, size_t length)
    : _buf(buf), _length(length)
{
    _init();
}

void PEFile::_init() {

    const uint8_t* p = _buf;
    const uint8_t* end = _buf + _length;

    if (p + sizeof(IMAGE_DOS_HEADER) >= end)
        throw InvalidImage("missing DOS header");

    dosHeader = (IMAGE_DOS_HEADER*)p;
    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
        throw InvalidImage("invalid DOS signature");

    // Skip to the NT headers. Note that we don't parse this section as
    // IMAGE_NT_HEADERS32/IMAGE_NT_HEADERS64 because we don't yet know if this
    // image is 32- or 64-bit. That information is in the first field of the
    // optional header.
    p += dosHeader->e_lfanew;

    //
    // Check the signature
    //
    if (p + sizeof(uint32_t) >= end)
        throw InvalidImage("missing PE signature");

    const uint32_t signature = *(uint32_t*)p;
    if (signature != *(const uint32_t*)"PE\0\0")
        throw InvalidImage("invalid PE signature");

    p += sizeof(signature);

    //
    // Parse the image file header
    //
    if (p + sizeof(IMAGE_FILE_HEADER) >= end)
        throw InvalidImage("missing IMAGE_FILE_HEADER");

    fileHeader = (IMAGE_FILE_HEADER*)p;

    p += sizeof(IMAGE_FILE_HEADER);

    //
    // The optional header is here. Parsing of this is delayed because it can
    // either be a 32- or 64-bit structure.
    //
    _optional = p;

    p += fileHeader->SizeOfOptionalHeader;

    //
    // Section headers. There are IMAGE_FILE_HEADER.NumberOfSections of these.
    //
    sectionHeaders = (IMAGE_SECTION_HEADER*)p;
}

/**
 * Patches the timestamp associated with a data directory.
 */
template<typename T>
void patchDataDirectory(const PEFile& pe, Patches& patches,
        const IMAGE_DATA_DIRECTORY* imageDataDirs,
        uint32_t entry, const char* name, uint32_t timestamp) {

    const IMAGE_DATA_DIRECTORY& imageDataDir = imageDataDirs[entry];

    // Doesn't exist? Nothing to patch.
    if (imageDataDir.VirtualAddress == 0)
        return;

    if (imageDataDir.Size < sizeof(T)) {
        // Note that we check if the size is less than our defined struct.
        // Microsoft is free to add elements to the end of the struct in future
        // versions as that still maintains ABI compatibility.
        throw InvalidImage("IMAGE_DATA_DIRECTORY.Size is invalid");
    }

    const uint8_t* p = pe.translate(imageDataDir.VirtualAddress);
    if (!pe.isValidAddress(p))
        throw InvalidImage("IMAGE_DATA_DIRECTORY.VirtualAddress is invalid");

    const T* dir = (const T*)p;

    if (dir->TimeDateStamp != 0)
        patches.add(&dir->TimeDateStamp, &timestamp, name);
}

/**
 * There are 0 or more debug data directories. We need to patch the timestamp in
 * all of them.
 */
void patchDebugDataDirectories(const PEFile& pe, Patches& patches,
        const IMAGE_DATA_DIRECTORY* imageDataDirs, uint32_t timestamp) {

    const IMAGE_DATA_DIRECTORY& imageDataDir = imageDataDirs[IMAGE_DIRECTORY_ENTRY_DEBUG];

    // Doesn't exist? Nothing to patch.
    if (imageDataDir.VirtualAddress == 0)
        return;

    const uint8_t* p = pe.translate(imageDataDir.VirtualAddress);
    if (!pe.isValidAddress(p))
        throw InvalidImage("invalid IMAGE_DATA_DIRECTORY.VirtualAddress is invalid");

    // The first debug data directory
    const IMAGE_DEBUG_DIRECTORY* dir = (const IMAGE_DEBUG_DIRECTORY*)p;

    // There can be multiple debug data directories in this section. This is how
    // to calculate the number of them.
    const size_t debugDirCount = imageDataDir.Size /
        sizeof(IMAGE_DEBUG_DIRECTORY);

    for (size_t i = 0; i < debugDirCount; ++i) {
        if (dir->TimeDateStamp != 0)
            patches.add(&dir->TimeDateStamp, &timestamp,
                    "IMAGE_DEBUG_DIRECTORY.TimeDateStamp");

        ++dir;
    }
}

/**
 * Patches the image based on the optional header type. The optional header can
 * be either 32- or 64-bit.
 */
template<typename T>
void patchOptionalHeader(const PEFile& pe,
        Patches& patches, uint32_t timestamp) {

    const T* optional = pe.optional<T>();

    patches.add(&optional->CheckSum, &timestamp,
            "OptionalHeader.CheckSum");

    const IMAGE_DATA_DIRECTORY* dataDirs = optional->DataDirectory;

    // Patch exports directory timestamp
    patchDataDirectory<IMAGE_EXPORT_DIRECTORY>(pe, patches,
            dataDirs, IMAGE_DIRECTORY_ENTRY_EXPORT,
            "IMAGE_EXPORT_DIRECTORY.TimeDateStamp", timestamp);

    // Patch resource directory timestamp
    patchDataDirectory<IMAGE_RESOURCE_DIRECTORY>(pe, patches,
            dataDirs, IMAGE_DIRECTORY_ENTRY_RESOURCE,
            "IMAGE_RESOURCE_DIRECTORY.TimeDateStamp", timestamp);

    // Patch the debug directories
    patchDebugDataDirectories(pe, patches, dataDirs, timestamp);
}

}

void patchImage(const char* imagePath, const char* pdbPath, bool dryRun) {
    MemMap image(imagePath);
    MemMap pdb(pdbPath);

    // Replacement for timestamps
    const uint32_t timestamp = 0;

    uint8_t* buf = (uint8_t*)image.buf();
    const size_t length = image.length();

    PEFile pe = PEFile(buf, length);

    Patches patches(buf);

    patches.add(&pe.fileHeader->TimeDateStamp, &timestamp,
            "IMAGE_FILE_HEADER.TimeDateStamp");

    switch (pe.magic()) {
        case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
            // Patch as a PE32 file
            patchOptionalHeader<IMAGE_OPTIONAL_HEADER32>(pe, patches,
                    timestamp);
            break;

        case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
            // Patch as a PE32+ file
            patchOptionalHeader<IMAGE_OPTIONAL_HEADER64>(pe, patches,
                    timestamp);
            break;

        default:
            throw InvalidImage("unsupported IMAGE_NT_HEADERS.OptionalHeader");
    }

    patches.apply(dryRun);
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by FThauer FHammer   *
 *   f.thauer@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <qapplication.h>

#ifdef __APPLE__
	#include <QMacStyle>
#endif

#include "session.h"
#include "startwindowimpl.h"
#include "configfile.h"
#include "startsplash.h"
#include "game_defs.h"
#include <net/socket_startup.h>

#include <curl/curl.h>
#include <QtGui>
#include <QtCore>

#include <iostream>
#include <cstdlib>
#include <ctime>

#ifdef _MSC_VER
	#ifdef _DEBUG
		#define _CRTDBG_MAP_ALLOC
		#include <crtdbg.h>

		#define ENABLE_LEAK_CHECK() \
			{ \
				int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); \
				tmpFlag |= _CRTDBG_LEAK_CHECK_DF; \
				_CrtSetDbgFlag(tmpFlag); \
			}
	#endif
#endif

#ifndef ENABLE_LEAK_CHECK
	#define ENABLE_LEAK_CHECK()
#endif

//Uncomment this for RELEASE
// #include <QtPlugin>
// Q_IMPORT_PLUGIN(qjpeg)
// Q_IMPORT_PLUGIN(qgif)

using namespace std;

class startWindowImpl;
class Game;

int main( int argc, char **argv )
{

	//ENABLE_LEAK_CHECK();

	//_CrtSetBreakAlloc(49937);
	socket_startup();
	curl_global_init(CURL_GLOBAL_NOTHING);

	/////// can be removed for non-qt-guis ////////////
	QApplication a( argc, argv );

	//create defaultconfig
	ConfigFile *myConfig = new ConfigFile(argv[0], false);

	// set PlastiqueStyle even for mac-version to prevent artefacts on styled widgets
	a.setStyle(new QPlastiqueStyle);

	QString	myAppDataPath = QString::fromUtf8(myConfig->readConfigString("AppDataDir").c_str());
	//set QApplication default font

	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/n019003l.pfb");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/VeraBd.ttf");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/c059013l.pfb");

#ifdef _WIN32
	QString font1String("font-family: \"Arial\";");
	a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 12px; }");
#else
// 	#ifdef __APPLE__
// 		QString font1String("font-family: \"Lucida Grande\";");
// 	#else
	QString font1String("font-family: \"Nimbus Sans L\";");
// 	#endif
	a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 12px; }");
#endif

	QPixmap *pixmap = new QPixmap(myAppDataPath + "gfx/gui/misc/welcomepokerth.png");
     	StartSplash splash(*pixmap);
     	splash.show();
	splash.showMessage(QString("Version %1").arg(POKERTH_BETA_RELEASE_STRING), 0x0042, QColor(153,213,0));

	//Set translations
	QTranslator qtTranslator;
        qtTranslator.load(QString(myAppDataPath +"translations/qt_") + QString::fromStdString(myConfig->readConfigString("Language")));
        a.installTranslator(&qtTranslator);

	QTranslator translator;
	translator.load(QString(myAppDataPath +"translations/pokerth_") + QString::fromStdString(myConfig->readConfigString("Language")));
	a.installTranslator(&translator);

#ifdef __APPLE__
	QDir dir(QApplication::applicationDirPath());
	dir.cdUp();
	dir.cd("plugins");
	QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif

	qRegisterMetaType<unsigned>("unsigned");
	qRegisterMetaType<boost::shared_ptr<Game> >("boost::shared_ptr<Game>");
	qRegisterMetaType<ServerStats>("ServerStats");
	///////////////////////////////////////////////////

	boost::shared_ptr<startWindowImpl>(new startWindowImpl(myConfig));
// 	boost::shared_ptr<GuiInterface> myGuiInterface(new GuiWrapper(myConfig));
// 	{
// 		boost::shared_ptr<Session> session(new Session(myGuiInterface.get(), myConfig));
// 		session->init(); // TODO handle error
// 		myGuiInterface->setSession(session);
// 	}

	int retVal = a.exec();

	curl_global_cleanup();
	socket_cleanup();
	return retVal;

}
<commit_msg>Fix main window creation.<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by FThauer FHammer   *
 *   f.thauer@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <qapplication.h>

#ifdef __APPLE__
	#include <QMacStyle>
#endif

#include "session.h"
#include "startwindowimpl.h"
#include "configfile.h"
#include "startsplash.h"
#include "game_defs.h"
#include <net/socket_startup.h>

#include <curl/curl.h>
#include <QtGui>
#include <QtCore>

#include <iostream>
#include <cstdlib>
#include <ctime>

#ifdef _MSC_VER
	#ifdef _DEBUG
		#define _CRTDBG_MAP_ALLOC
		#include <crtdbg.h>

		#define ENABLE_LEAK_CHECK() \
			{ \
				int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); \
				tmpFlag |= _CRTDBG_LEAK_CHECK_DF; \
				_CrtSetDbgFlag(tmpFlag); \
			}
	#endif
#endif

#ifndef ENABLE_LEAK_CHECK
	#define ENABLE_LEAK_CHECK()
#endif

//Uncomment this for RELEASE
// #include <QtPlugin>
// Q_IMPORT_PLUGIN(qjpeg)
// Q_IMPORT_PLUGIN(qgif)

using namespace std;

class startWindowImpl;
class Game;

int main( int argc, char **argv )
{

	//ENABLE_LEAK_CHECK();

	//_CrtSetBreakAlloc(49937);
	socket_startup();
	curl_global_init(CURL_GLOBAL_NOTHING);

	/////// can be removed for non-qt-guis ////////////
	QApplication a( argc, argv );

	//create defaultconfig
	ConfigFile *myConfig = new ConfigFile(argv[0], false);

	// set PlastiqueStyle even for mac-version to prevent artefacts on styled widgets
	a.setStyle(new QPlastiqueStyle);

	QString	myAppDataPath = QString::fromUtf8(myConfig->readConfigString("AppDataDir").c_str());
	//set QApplication default font

	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/n019003l.pfb");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/VeraBd.ttf");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/c059013l.pfb");

#ifdef _WIN32
	QString font1String("font-family: \"Arial\";");
	a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 12px; }");
#else
// 	#ifdef __APPLE__
// 		QString font1String("font-family: \"Lucida Grande\";");
// 	#else
	QString font1String("font-family: \"Nimbus Sans L\";");
// 	#endif
	a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 12px; }");
#endif

	QPixmap *pixmap = new QPixmap(myAppDataPath + "gfx/gui/misc/welcomepokerth.png");
     	StartSplash splash(*pixmap);
     	splash.show();
	splash.showMessage(QString("Version %1").arg(POKERTH_BETA_RELEASE_STRING), 0x0042, QColor(153,213,0));

	//Set translations
	QTranslator qtTranslator;
        qtTranslator.load(QString(myAppDataPath +"translations/qt_") + QString::fromStdString(myConfig->readConfigString("Language")));
        a.installTranslator(&qtTranslator);

	QTranslator translator;
	translator.load(QString(myAppDataPath +"translations/pokerth_") + QString::fromStdString(myConfig->readConfigString("Language")));
	a.installTranslator(&translator);

#ifdef __APPLE__
	QDir dir(QApplication::applicationDirPath());
	dir.cdUp();
	dir.cd("plugins");
	QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif

	qRegisterMetaType<unsigned>("unsigned");
	qRegisterMetaType<boost::shared_ptr<Game> >("boost::shared_ptr<Game>");
	qRegisterMetaType<ServerStats>("ServerStats");
	///////////////////////////////////////////////////

	startWindowImpl *mainWin = new startWindowImpl(myConfig);
	int retVal = a.exec();

	curl_global_cleanup();
	socket_cleanup();
	return retVal;

}
<|endoftext|>


<commit_before>/* This file is part of Ingen.
 * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <cassert>
#include <raul/Atom.hpp>
#include "interface/EngineInterface.hpp"
#include "client/NodeModel.hpp"
#include "client/PatchModel.hpp"
#include "client/PluginUI.hpp"
#include "App.hpp"
#include "GladeFactory.hpp"
#include "NodeControlWindow.hpp"
#include "NodeModule.hpp"
#include "PatchCanvas.hpp"
#include "PatchWindow.hpp"
#include "Port.hpp"
#include "RenameWindow.hpp"
#include "SubpatchModule.hpp"
#include "WindowFactory.hpp"

namespace Ingen {
namespace GUI {

NodeModule::NodeModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> node)
	: FlowCanvas::Module(canvas, node->path().name())
	, _node(node)
	, _gui_widget(NULL)
	, _gui_container(NULL)
	, _gui_item(NULL)
	, _gui_window(NULL)
	, _last_gui_request_width(0)
	, _last_gui_request_height(0)
{
	assert(_node);

	node->signal_new_port.connect(sigc::bind(sigc::mem_fun(this, &NodeModule::add_port), true));
	node->signal_removed_port.connect(sigc::mem_fun(this, &NodeModule::remove_port));
	node->signal_variable.connect(sigc::mem_fun(this, &NodeModule::set_variable));
	node->signal_polyphonic.connect(sigc::mem_fun(this, &NodeModule::set_stacked_border));
	node->signal_renamed.connect(sigc::mem_fun(this, &NodeModule::rename));

	set_stacked_border(node->polyphonic());
}

NodeModule::~NodeModule()
{
	NodeControlWindow* win = App::instance().window_factory()->control_window(_node);

	if (win) {
		// Should remove from window factory via signal
		delete win;
	}
}

void
NodeModule::create_menu()
{
	Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference();
	xml->get_widget_derived("object_menu", _menu);
	_menu->init(_node);
	_menu->signal_embed_gui.connect(sigc::mem_fun(this, &NodeModule::embed_gui));
	_menu->signal_popup_gui.connect(sigc::hide_return(sigc::mem_fun(this, &NodeModule::popup_gui)));

	set_menu(_menu);
}

boost::shared_ptr<NodeModule>
NodeModule::create(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> node)
{
	boost::shared_ptr<NodeModule> ret;

	SharedPtr<PatchModel> patch = PtrCast<PatchModel>(node);
	if (patch)
		ret = boost::shared_ptr<NodeModule>(new SubpatchModule(canvas, patch));
	else
		ret = boost::shared_ptr<NodeModule>(new NodeModule(canvas, node));

	for (GraphObject::Variables::const_iterator m = node->variables().begin(); m != node->variables().end(); ++m)
		ret->set_variable(m->first, m->second);

	for (PortModelList::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) {
		ret->add_port(*p, false);
	}

	ret->resize();

	return ret;
}

void
NodeModule::value_changed(uint32_t index, const Atom& value)
{
	float control = value.get_float();
	if (_plugin_ui) {
		SLV2UIInstance inst = _plugin_ui->instance();
		const LV2UI_Descriptor* ui_descriptor = slv2_ui_instance_get_descriptor(inst);
		LV2UI_Handle ui_handle = slv2_ui_instance_get_handle(inst);
		if (ui_descriptor->port_event)
		  ui_descriptor->port_event(ui_handle, index, 4, 0, &control);
	}
}

void
NodeModule::embed_gui(bool embed)
{
	if (embed) {

		if (_gui_window) {
			cerr << "LV2 GUI already popped up, cannot embed" << endl;
			return;
		}

		GtkWidget* c_widget = NULL;

		if (!_gui_item) {

			const PluginModel* const plugin = dynamic_cast<const PluginModel*>(_node->plugin());
			assert(plugin);

			_plugin_ui = plugin->ui(App::instance().world(), _node);

			if (_plugin_ui) {
				c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_plugin_ui->instance());
				_gui_widget = Glib::wrap(c_widget);
				assert(_gui_widget);

				if (_gui_container)
					delete _gui_container;

				_gui_container = manage(new Gtk::EventBox());
				_gui_container->set_name("ingen_embedded_node_gui_container");
				_gui_container->set_border_width(2);
				_gui_container->add(*_gui_widget);
				_gui_container->show_all();

				const double y = 4 + _canvas_title.property_text_height();
				_gui_item = new Gnome::Canvas::Widget(*this, 2.0, y, *_gui_container);
			}
		}

		if (_gui_item) {

			assert(_gui_widget);
			_gui_widget->show_all();
			_gui_item->show();

			Gtk::Requisition r = _gui_container->size_request();
			gui_size_request(&r, true);

			_gui_item->raise_to_top();

			_gui_container->signal_size_request().connect(sigc::bind(
					sigc::mem_fun(this, &NodeModule::gui_size_request), false));

			for (PortModelList::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p)
				if ((*p)->type().is_control() && (*p)->is_output())
					App::instance().engine()->enable_port_broadcasting((*p)->path());

		} else {
			cerr << "ERROR: Failed to create canvas item for LV2 UI" << endl;
		}

	} else { // un-embed

		if (_gui_item) {
			delete _gui_item;
			_gui_item = NULL;
			_gui_container = NULL; // managed
			_gui_widget = NULL; // managed
			_plugin_ui.reset();
		}

		_ports_y_offset = 0;
		_minimum_width = 0; // resize() takes care of it..

		for (PortModelList::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p)
			if ((*p)->type().is_control() && (*p)->is_output())
				App::instance().engine()->disable_port_broadcasting((*p)->path());
	}

	if (embed && _gui_item) {
		initialise_gui_values();
		set_base_color(0x212222FF);
	} else {
		set_default_base_color();
	}

	resize();
}

void
NodeModule::gui_size_request(Gtk::Requisition* r, bool force)
{
	if (!force && _last_gui_request_width == r->width && _last_gui_request_height == r->height)
		return;

	if (r->width + 4 > _width)
		set_minimum_width(r->width + 4);

	_ports_y_offset = r->height + 2;

	resize();

	Gtk::Allocation allocation;
	allocation.set_width(r->width + 4);
	allocation.set_height(r->height + 4);

	_gui_container->size_allocate(allocation);
	_gui_item->property_width() = _width - 4;
	_gui_item->property_height() = r->height;

	_last_gui_request_width = r->width;
	_last_gui_request_height = r->height;
}

void
NodeModule::rename()
{
	set_name(_node->path().name());
	resize();
}

void
NodeModule::add_port(SharedPtr<PortModel> port, bool resize_to_fit)
{
	uint32_t index = _ports.size(); // FIXME: kluge, engine needs to tell us this

	Module::add_port(boost::shared_ptr<Port>(
			new Port(PtrCast<NodeModule>(shared_from_this()), port)));

	port->signal_value_changed.connect(sigc::bind<0>(
			sigc::mem_fun(this, &NodeModule::value_changed), index));

	if (resize_to_fit)
		resize();
}

void
NodeModule::remove_port(SharedPtr<PortModel> port)
{
	SharedPtr<FlowCanvas::Port> p = Module::remove_port(port->path().name());
	p.reset();
}

bool
NodeModule::popup_gui()
{
#ifdef HAVE_SLV2
	if (_node->plugin()->type() == PluginModel::LV2) {
		if (_plugin_ui) {
			cerr << "LV2 GUI already embedded, cannot pop up" << endl;
			return false;
		}

		const PluginModel* const plugin = dynamic_cast<const PluginModel*>(_node->plugin());
		assert(plugin);

		_plugin_ui = plugin->ui(App::instance().world(), _node);

		if (_plugin_ui) {
			GtkWidget* c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_plugin_ui->instance());
			_gui_widget = Glib::wrap(c_widget);

			_gui_window = new Gtk::Window();
			_gui_window->add(*_gui_widget);
			_gui_widget->show_all();
			initialise_gui_values();

			_gui_window->signal_unmap().connect(
					sigc::mem_fun(this, &NodeModule::on_gui_window_close));
			_gui_window->present();

			return true;
		} else {
			cerr << "No LV2 GUI" << endl;
		}
	}
#endif
	return false;
}

void
NodeModule::on_gui_window_close()
{
	delete _gui_window;
	_gui_window = NULL;
	_plugin_ui.reset();
	_gui_widget = NULL;
}

void
NodeModule::initialise_gui_values()
{
	uint32_t index=0;
	for (PortModelList::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) {
		if ((*p)->type().is_control())
			value_changed(index, (*p)->value());
		++index;
	}
}

void
NodeModule::show_control_window()
{
	App::instance().window_factory()->present_controls(_node);
}

void
NodeModule::on_double_click(GdkEventButton* ev)
{
	if ( ! popup_gui() )
		show_control_window();
}

void
NodeModule::store_location()
{
	const float x = static_cast<float>(property_x());
	const float y = static_cast<float>(property_y());

	const Atom& existing_x = _node->get_variable("ingenuity:canvas-x");
	const Atom& existing_y = _node->get_variable("ingenuity:canvas-y");

	if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT
			|| existing_x.get_float() != x || existing_y.get_float() != y) {
		App::instance().engine()->set_variable(_node->path(), "ingenuity:canvas-x", Atom(x));
		App::instance().engine()->set_variable(_node->path(), "ingenuity:canvas-y", Atom(y));
	}
}

void
NodeModule::set_variable(const string& key, const Atom& value)
{
	if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT)
		move_to(value.get_float(), property_y());
	else if (key == "ingenuity:canvas-y" && value.type() == Atom::FLOAT)
		move_to(property_x(), value.get_float());
}

} // namespace GUI
} // namespace Ingen
<commit_msg>Spell kludge correctly :)<commit_after>/* This file is part of Ingen.
 * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <cassert>
#include <raul/Atom.hpp>
#include "interface/EngineInterface.hpp"
#include "client/NodeModel.hpp"
#include "client/PatchModel.hpp"
#include "client/PluginUI.hpp"
#include "App.hpp"
#include "GladeFactory.hpp"
#include "NodeControlWindow.hpp"
#include "NodeModule.hpp"
#include "PatchCanvas.hpp"
#include "PatchWindow.hpp"
#include "Port.hpp"
#include "RenameWindow.hpp"
#include "SubpatchModule.hpp"
#include "WindowFactory.hpp"

namespace Ingen {
namespace GUI {

NodeModule::NodeModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> node)
	: FlowCanvas::Module(canvas, node->path().name())
	, _node(node)
	, _gui_widget(NULL)
	, _gui_container(NULL)
	, _gui_item(NULL)
	, _gui_window(NULL)
	, _last_gui_request_width(0)
	, _last_gui_request_height(0)
{
	assert(_node);

	node->signal_new_port.connect(sigc::bind(sigc::mem_fun(this, &NodeModule::add_port), true));
	node->signal_removed_port.connect(sigc::mem_fun(this, &NodeModule::remove_port));
	node->signal_variable.connect(sigc::mem_fun(this, &NodeModule::set_variable));
	node->signal_polyphonic.connect(sigc::mem_fun(this, &NodeModule::set_stacked_border));
	node->signal_renamed.connect(sigc::mem_fun(this, &NodeModule::rename));

	set_stacked_border(node->polyphonic());
}

NodeModule::~NodeModule()
{
	NodeControlWindow* win = App::instance().window_factory()->control_window(_node);

	if (win) {
		// Should remove from window factory via signal
		delete win;
	}
}

void
NodeModule::create_menu()
{
	Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference();
	xml->get_widget_derived("object_menu", _menu);
	_menu->init(_node);
	_menu->signal_embed_gui.connect(sigc::mem_fun(this, &NodeModule::embed_gui));
	_menu->signal_popup_gui.connect(sigc::hide_return(sigc::mem_fun(this, &NodeModule::popup_gui)));

	set_menu(_menu);
}

boost::shared_ptr<NodeModule>
NodeModule::create(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> node)
{
	boost::shared_ptr<NodeModule> ret;

	SharedPtr<PatchModel> patch = PtrCast<PatchModel>(node);
	if (patch)
		ret = boost::shared_ptr<NodeModule>(new SubpatchModule(canvas, patch));
	else
		ret = boost::shared_ptr<NodeModule>(new NodeModule(canvas, node));

	for (GraphObject::Variables::const_iterator m = node->variables().begin(); m != node->variables().end(); ++m)
		ret->set_variable(m->first, m->second);

	for (PortModelList::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) {
		ret->add_port(*p, false);
	}

	ret->resize();

	return ret;
}

void
NodeModule::value_changed(uint32_t index, const Atom& value)
{
	float control = value.get_float();
	if (_plugin_ui) {
		SLV2UIInstance inst = _plugin_ui->instance();
		const LV2UI_Descriptor* ui_descriptor = slv2_ui_instance_get_descriptor(inst);
		LV2UI_Handle ui_handle = slv2_ui_instance_get_handle(inst);
		if (ui_descriptor->port_event)
		  ui_descriptor->port_event(ui_handle, index, 4, 0, &control);
	}
}

void
NodeModule::embed_gui(bool embed)
{
	if (embed) {

		if (_gui_window) {
			cerr << "LV2 GUI already popped up, cannot embed" << endl;
			return;
		}

		GtkWidget* c_widget = NULL;

		if (!_gui_item) {

			const PluginModel* const plugin = dynamic_cast<const PluginModel*>(_node->plugin());
			assert(plugin);

			_plugin_ui = plugin->ui(App::instance().world(), _node);

			if (_plugin_ui) {
				c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_plugin_ui->instance());
				_gui_widget = Glib::wrap(c_widget);
				assert(_gui_widget);

				if (_gui_container)
					delete _gui_container;

				_gui_container = manage(new Gtk::EventBox());
				_gui_container->set_name("ingen_embedded_node_gui_container");
				_gui_container->set_border_width(2);
				_gui_container->add(*_gui_widget);
				_gui_container->show_all();

				const double y = 4 + _canvas_title.property_text_height();
				_gui_item = new Gnome::Canvas::Widget(*this, 2.0, y, *_gui_container);
			}
		}

		if (_gui_item) {

			assert(_gui_widget);
			_gui_widget->show_all();
			_gui_item->show();

			Gtk::Requisition r = _gui_container->size_request();
			gui_size_request(&r, true);

			_gui_item->raise_to_top();

			_gui_container->signal_size_request().connect(sigc::bind(
					sigc::mem_fun(this, &NodeModule::gui_size_request), false));

			for (PortModelList::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p)
				if ((*p)->type().is_control() && (*p)->is_output())
					App::instance().engine()->enable_port_broadcasting((*p)->path());

		} else {
			cerr << "ERROR: Failed to create canvas item for LV2 UI" << endl;
		}

	} else { // un-embed

		if (_gui_item) {
			delete _gui_item;
			_gui_item = NULL;
			_gui_container = NULL; // managed
			_gui_widget = NULL; // managed
			_plugin_ui.reset();
		}

		_ports_y_offset = 0;
		_minimum_width = 0; // resize() takes care of it..

		for (PortModelList::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p)
			if ((*p)->type().is_control() && (*p)->is_output())
				App::instance().engine()->disable_port_broadcasting((*p)->path());
	}

	if (embed && _gui_item) {
		initialise_gui_values();
		set_base_color(0x212222FF);
	} else {
		set_default_base_color();
	}

	resize();
}

void
NodeModule::gui_size_request(Gtk::Requisition* r, bool force)
{
	if (!force && _last_gui_request_width == r->width && _last_gui_request_height == r->height)
		return;

	if (r->width + 4 > _width)
		set_minimum_width(r->width + 4);

	_ports_y_offset = r->height + 2;

	resize();

	Gtk::Allocation allocation;
	allocation.set_width(r->width + 4);
	allocation.set_height(r->height + 4);

	_gui_container->size_allocate(allocation);
	_gui_item->property_width() = _width - 4;
	_gui_item->property_height() = r->height;

	_last_gui_request_width = r->width;
	_last_gui_request_height = r->height;
}

void
NodeModule::rename()
{
	set_name(_node->path().name());
	resize();
}

void
NodeModule::add_port(SharedPtr<PortModel> port, bool resize_to_fit)
{
	uint32_t index = _ports.size(); // FIXME: kludge, engine needs to tell us this

	Module::add_port(boost::shared_ptr<Port>(
			new Port(PtrCast<NodeModule>(shared_from_this()), port)));

	port->signal_value_changed.connect(sigc::bind<0>(
			sigc::mem_fun(this, &NodeModule::value_changed), index));

	if (resize_to_fit)
		resize();
}

void
NodeModule::remove_port(SharedPtr<PortModel> port)
{
	SharedPtr<FlowCanvas::Port> p = Module::remove_port(port->path().name());
	p.reset();
}

bool
NodeModule::popup_gui()
{
#ifdef HAVE_SLV2
	if (_node->plugin()->type() == PluginModel::LV2) {
		if (_plugin_ui) {
			cerr << "LV2 GUI already embedded, cannot pop up" << endl;
			return false;
		}

		const PluginModel* const plugin = dynamic_cast<const PluginModel*>(_node->plugin());
		assert(plugin);

		_plugin_ui = plugin->ui(App::instance().world(), _node);

		if (_plugin_ui) {
			GtkWidget* c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_plugin_ui->instance());
			_gui_widget = Glib::wrap(c_widget);

			_gui_window = new Gtk::Window();
			_gui_window->add(*_gui_widget);
			_gui_widget->show_all();
			initialise_gui_values();

			_gui_window->signal_unmap().connect(
					sigc::mem_fun(this, &NodeModule::on_gui_window_close));
			_gui_window->present();

			return true;
		} else {
			cerr << "No LV2 GUI" << endl;
		}
	}
#endif
	return false;
}

void
NodeModule::on_gui_window_close()
{
	delete _gui_window;
	_gui_window = NULL;
	_plugin_ui.reset();
	_gui_widget = NULL;
}

void
NodeModule::initialise_gui_values()
{
	uint32_t index=0;
	for (PortModelList::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) {
		if ((*p)->type().is_control())
			value_changed(index, (*p)->value());
		++index;
	}
}

void
NodeModule::show_control_window()
{
	App::instance().window_factory()->present_controls(_node);
}

void
NodeModule::on_double_click(GdkEventButton* ev)
{
	if ( ! popup_gui() )
		show_control_window();
}

void
NodeModule::store_location()
{
	const float x = static_cast<float>(property_x());
	const float y = static_cast<float>(property_y());

	const Atom& existing_x = _node->get_variable("ingenuity:canvas-x");
	const Atom& existing_y = _node->get_variable("ingenuity:canvas-y");

	if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT
			|| existing_x.get_float() != x || existing_y.get_float() != y) {
		App::instance().engine()->set_variable(_node->path(), "ingenuity:canvas-x", Atom(x));
		App::instance().engine()->set_variable(_node->path(), "ingenuity:canvas-y", Atom(y));
	}
}

void
NodeModule::set_variable(const string& key, const Atom& value)
{
	if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT)
		move_to(value.get_float(), property_y());
	else if (key == "ingenuity:canvas-y" && value.type() == Atom::FLOAT)
		move_to(property_x(), value.get_float());
}

} // namespace GUI
} // namespace Ingen
<|endoftext|>


<commit_before>#pragma once

#include "types.hh"
#include "hash.hh"
#include "store-api.hh"

#include <map>
#include <variant>

namespace nix {

/* Abstract syntax of derivations. */

struct DerivationOutput
{
    StorePath path;
    std::string hashAlgo; /* hash used for expected hash computation */
    std::string hash; /* expected hash, may be null */
    DerivationOutput(StorePath && path, std::string && hashAlgo, std::string && hash)
        : path(std::move(path))
        , hashAlgo(std::move(hashAlgo))
        , hash(std::move(hash))
    { }
    void parseHashInfo(bool & recursive, Hash & hash) const;
};

typedef std::map<string, DerivationOutput> DerivationOutputs;

/* For inputs that are sub-derivations, we specify exactly which
   output IDs we are interested in. */
typedef std::map<StorePath, StringSet> DerivationInputs;

typedef std::map<string, string> StringPairs;

struct BasicDerivation
{
    DerivationOutputs outputs; /* keyed on symbolic IDs */
    StorePathSet inputSrcs; /* inputs that are sources */
    string platform;
    Path builder;
    Strings args;
    StringPairs env;

    BasicDerivation() { }
    explicit BasicDerivation(const BasicDerivation & other);
    virtual ~BasicDerivation() { };

    /* Return the path corresponding to the output identifier `id' in
       the given derivation. */
    const StorePath & findOutput(const std::string & id) const;

    bool isBuiltin() const;

    /* Return true iff this is a fixed-output derivation. */
    bool isFixedOutput() const;

    /* Return the output paths of a derivation. */
    StorePathSet outputPaths() const;

};

struct Derivation : BasicDerivation
{
    DerivationInputs inputDrvs; /* inputs that are sub-derivations */

    /* Print a derivation. */
    std::string unparse(const Store & store, bool maskOutputs,
        std::map<std::string, StringSet> * actualInputs = nullptr) const;

    Derivation() { }
    Derivation(Derivation && other) = default;
    explicit Derivation(const Derivation & other);
};

class Store;

/* Write a derivation to the Nix store, and return its path. */
StorePath writeDerivation(ref<Store> store,
    const Derivation & drv, const string & name, RepairFlag repair = NoRepair);

/* Read a derivation from a file. */
Derivation readDerivation(const Store & store, const Path & drvPath);

// FIXME: remove
bool isDerivation(const string & fileName);

typedef std::variant<
    Hash, // regular DRV normalized hash
    std::map<std::string, Hash> // known CA drv's output hashes
> DrvHashModulo;

/* Returns hashes with the details of fixed-output subderivations
   expunged.

   A fixed-output derivation is a derivation whose outputs have a
   specified content hash and hash algorithm. (Currently they must have
   exactly one output (`out'), which is specified using the `outputHash'
   and `outputHashAlgo' attributes, but the algorithm doesn't assume
   this.) We don't want changes to such derivations to propagate upwards
   through the dependency graph, changing output paths everywhere.

   For instance, if we change the url in a call to the `fetchurl'
   function, we do not want to rebuild everything depending on it---after
   all, (the hash of) the file being downloaded is unchanged.  So the
   *output paths* should not change. On the other hand, the *derivation
   paths* should change to reflect the new dependency graph.

   For fixed output derivations, this returns a map from the names of
   each output to hashes unique up to the outputs' contents.

   For regular derivations, it returns a single hash of the derivation
   ATerm, after subderivations have been likewise expunged from that
   derivation.
 */
DrvHashModulo hashDerivationModulo(Store & store, const Derivation & drv, bool maskOutputs);

/* Memoisation of hashDerivationModulo(). */
typedef std::map<StorePath, DrvHashModulo> DrvHashes;

extern DrvHashes drvHashes; // FIXME: global, not thread-safe

bool wantOutput(const string & output, const std::set<string> & wanted);

struct Source;
struct Sink;

Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv);
void writeDerivation(Sink & out, const Store & store, const BasicDerivation & drv);

std::string hashPlaceholder(const std::string & outputName);

}
<commit_msg>Apply suggestions from code review<commit_after>#pragma once

#include "types.hh"
#include "hash.hh"
#include "store-api.hh"

#include <map>
#include <variant>

namespace nix {

/* Abstract syntax of derivations. */

struct DerivationOutput
{
    StorePath path;
    std::string hashAlgo; /* hash used for expected hash computation */
    std::string hash; /* expected hash, may be null */
    DerivationOutput(StorePath && path, std::string && hashAlgo, std::string && hash)
        : path(std::move(path))
        , hashAlgo(std::move(hashAlgo))
        , hash(std::move(hash))
    { }
    void parseHashInfo(bool & recursive, Hash & hash) const;
};

typedef std::map<string, DerivationOutput> DerivationOutputs;

/* For inputs that are sub-derivations, we specify exactly which
   output IDs we are interested in. */
typedef std::map<StorePath, StringSet> DerivationInputs;

typedef std::map<string, string> StringPairs;

struct BasicDerivation
{
    DerivationOutputs outputs; /* keyed on symbolic IDs */
    StorePathSet inputSrcs; /* inputs that are sources */
    string platform;
    Path builder;
    Strings args;
    StringPairs env;

    BasicDerivation() { }
    explicit BasicDerivation(const BasicDerivation & other);
    virtual ~BasicDerivation() { };

    /* Return the path corresponding to the output identifier `id' in
       the given derivation. */
    const StorePath & findOutput(const std::string & id) const;

    bool isBuiltin() const;

    /* Return true iff this is a fixed-output derivation. */
    bool isFixedOutput() const;

    /* Return the output paths of a derivation. */
    StorePathSet outputPaths() const;

};

struct Derivation : BasicDerivation
{
    DerivationInputs inputDrvs; /* inputs that are sub-derivations */

    /* Print a derivation. */
    std::string unparse(const Store & store, bool maskOutputs,
        std::map<std::string, StringSet> * actualInputs = nullptr) const;

    Derivation() { }
    Derivation(Derivation && other) = default;
    explicit Derivation(const Derivation & other);
};

class Store;

/* Write a derivation to the Nix store, and return its path. */
StorePath writeDerivation(ref<Store> store,
    const Derivation & drv, const string & name, RepairFlag repair = NoRepair);

/* Read a derivation from a file. */
Derivation readDerivation(const Store & store, const Path & drvPath);

// FIXME: remove
bool isDerivation(const string & fileName);

typedef std::variant<
    Hash, // regular DRV normalized hash
    std::map<std::string, Hash> // known CA drv's output hashes
> DrvHashModulo;

/* Returns hashes with the details of fixed-output subderivations
   expunged.

   A fixed-output derivation is a derivation whose outputs have a
   specified content hash and hash algorithm. (Currently they must have
   exactly one output (`out'), which is specified using the `outputHash'
   and `outputHashAlgo' attributes, but the algorithm doesn't assume
   this.) We don't want changes to such derivations to propagate upwards
   through the dependency graph, changing output paths everywhere.

   For instance, if we change the url in a call to the `fetchurl'
   function, we do not want to rebuild everything depending on it---after
   all, (the hash of) the file being downloaded is unchanged.  So the
   *output paths* should not change. On the other hand, the *derivation
   paths* should change to reflect the new dependency graph.

   For fixed-output derivations, this returns a map from the name of
   each output to its hash, unique up to the output's contents.

   For regular derivations, it returns a single hash of the derivation
   ATerm, after subderivations have been likewise expunged from that
   derivation.
 */
DrvHashModulo hashDerivationModulo(Store & store, const Derivation & drv, bool maskOutputs);

/* Memoisation of hashDerivationModulo(). */
typedef std::map<StorePath, DrvHashModulo> DrvHashes;

extern DrvHashes drvHashes; // FIXME: global, not thread-safe

bool wantOutput(const string & output, const std::set<string> & wanted);

struct Source;
struct Sink;

Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv);
void writeDerivation(Sink & out, const Store & store, const BasicDerivation & drv);

std::string hashPlaceholder(const std::string & outputName);

}
<|endoftext|>


<commit_before>#pragma once

#include "evaluation.hpp"
#include "mapping.hpp"

#include <string>

namespace vakkenranking
{
	class printer
	{
		void operator=(printer&) = delete;
		printer() = delete;

		static std::string round(double x, size_t digits)
		{
			double multiplier = std::pow(10, digits);

			std::stringstream str;
			str << std::round(x * multiplier) / multiplier;

			size_t find = str.str().find('.');
			if(find == std::string::npos)
			{
				find = str.str().size();
				str << '.';
			}

			int current_digits = str.str().size() - find - 1;
			int todo_digits = (int)digits - current_digits;

			if(todo_digits > 0)
				for(int i = 0; i < todo_digits; i++)
					str << '0';

			return str.str();
		}

	public:
		static void print_csv(const std::vector<evaluation>& old_data, const std::vector<evaluation>& new_data)
		{
			const auto mapping_f = mapping::create_mapping_f(old_data);
			const std::string sep = ",";

			for(const auto& e : new_data)
			{
				const auto e_old = mapping_f(e.code);

				std::cout << '"' << e.code << '"' << sep
					<< '"' << round(e.course_grade.avg(), 1) << '"' << sep
					<< '"' << round(e.course_grade.stdev(), 1) << '"' << sep
					<< '"' << e.course_grade.count() << '"' << sep
					<< '"' << round(e.teacher_grade.avg(), 1) << '"' << sep
					<< '"' << round(e.teacher_grade.stdev(), 1) << '"' << sep
					<< '"' << e.teacher_grade.count() << '"' << sep;

				if(e_old.to)
					std::cout
						<< '"' << round(e_old.to.get().course_grade.avg(), 1) << '"' << sep
						<< '"' << round(e_old.to.get().course_grade.stdev(), 1) << '"' << sep
						<< '"' << e_old.to.get().course_grade.count() << '"'
						<< std::endl;
				else
					std::cout
						<< '"' << '"' << sep
						<< '"' << '"' << sep
						<< '"' << '"'
						<< std::endl;
			}
		}

		static void print(const std::vector<evaluation>& old_data, const std::vector<evaluation>& new_data)
		{
			const static size_t slice_count = 3;

			std::vector<std::vector<evaluation>> slices(slice_count);
			const size_t slice_size = ceil((double)new_data.size() / (double)slice_count);

			for(size_t i = 0; i < slice_count; ++i)
				for(size_t j = i * slice_size; j < (i+1) * slice_size && j < new_data.size(); ++j)
					slices[i].push_back(new_data[j]);

			const auto mapping_f = mapping::create_mapping_f(old_data);
			size_t n = 0;

			std::cout << "<!DOCTYPE html>\n\n"
				<< "\t<meta charset=\"UTF-8\" />\n"
				<< "\t<title>OLC III - Vakkenranking najaar 2013-2014</title>\n"
				<< "\t<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"http://olciii.nl/wp-content/themes/twentyeleven/style.css\">\n"
				<< "\t\n"
				<< "\n"
				<< "\n"
				<< "\n"
				<< "\t
Vakkenranking Informatica najaar 2013-2014
\n"
				<< "\t
Opleidingscommissie Informatica & Informatiekunde 2013-2014
\n"
				<< "\n"
				<< "
\n"
				<< "
\n";

			for(size_t i = 0; i < slices.size(); ++i)
			{
				const auto& slice = slices[i];

				if(i == 0)
				{
					std::cout << "
\n";

					std::cout << "
\n"
						<< "\t#	\n"
						<< "\tVak (vakcode)	\n"
						<< "\tx	\n"
						<< "\tn	\n"
						<< "\tσ	\n"
						<< "\txoud	\n"
						<< "\t 	\n"
						<< "
\n";
				}
				else
				{
					std::cout << "
\n";

					std::cout << "
\n"
						<< "\t#	\n"
						<< "\tVak (vakcode)	\n"
						<< "\tx	\n"
						<< "\tn	\n"
						<< "\tσ	\n"
						<< "\txoud	\n"
						<< "\t 	\n"
						<< "
\n";
				}

				for(size_t j = 0; j < slice.size(); ++j)
				{
					const evaluation& e = slice[j];
					const auto e_old = mapping_f(e.code);

					const double avg = e.course_grade.avg();

					if(j == slice.size() - 1) //Last element in slice
						std::cout << "
\n";
					else
						std::cout << "
\n";

					std::cout << "\t" << n << "	\n"
						<< "\t" << e.name << " (" << e.code << ")	\n"
						<< "\t" << round(avg, 1) << "	\n"
						<< "\t" << e.course_grade.count() << "	\n"
						<< "\t" << round(e.course_grade.stdev(), 1) << "	\n";

					if(e_old.to)
					{
						const static size_t threshold = 5;
						const static double max_diff = 1.0;
						const static double sig_diff = 0.4;

						const double old_avg = e_old.to.get().course_grade.avg();
						const double diff = avg - old_avg;

						std::cout
							<< "\t" << round(old_avg, 1) << "	\n"
							<< "\t"
							<< "<div style=\"color: ";

						if(e.course_grade.count() <= threshold || e_old.to.get().course_grade.count() <= threshold)
							std::cout << "lightgray";
						else if(diff >= max_diff)
							std::cout << "green";
						else if(diff >= sig_diff)
							std::cout << "green";
						else if(diff <= -max_diff)
							std::cout << "red";
						else if(diff <= sig_diff)
							std::cout << "red";

						std::cout << "\">";

						if(diff >= max_diff)
							std::cout << "▲▲";
						else if(diff >= sig_diff)
							std::cout << "▲";
						else if(diff <= -max_diff)
							std::cout << "▼▼";
						else if(diff <= -sig_diff)
							std::cout << "▼";

						std::cout << "
";
					}
					else
					{
						std::cout << "\t 	\n";
						std::cout << "\t";

						if(e_old.mapping_type == mapping::type_e::unfound)
							std::cout << "?";
						else if(e_old.mapping_type == mapping::type_e::added)
							std::cout << "!";
						else
							std::cout << "666";

						std::cout << "	\n";
					}

					std::cout << "
\n";
					n++;
				}

				std::cout << "
\n" << std::endl;
			}

			std::cout << "

\n"
				<< "
▲ = 0.4 ≤ δ ≤ 1.0; ▲▲ = δ > 1.0
\n"
				<< "▼ grijs = niet significant aantal deelnemers
\n"
				<< "▼ kleur = significant aantal deelnemers
\n"
				<< "! = cursus nieuw in 2013-2014
\n"
				<< "? = geen enquêteresultaten uit 2012-2013
\n"
				<< "";
		}
	};
}
<commit_msg>printer: updated for 2013-2014 poster<commit_after>#pragma once

#include "evaluation.hpp"
#include "mapping.hpp"

#include <string>

namespace vakkenranking
{
	class printer
	{
		void operator=(printer&) = delete;
		printer() = delete;

		static std::string round(double x, size_t digits)
		{
			double multiplier = std::pow(10, digits);

			std::stringstream str;
			str << std::round(x * multiplier) / multiplier;

			size_t find = str.str().find('.');
			if(find == std::string::npos)
			{
				find = str.str().size();
				str << '.';
			}

			int current_digits = str.str().size() - find - 1;
			int todo_digits = (int)digits - current_digits;

			if(todo_digits > 0)
				for(int i = 0; i < todo_digits; i++)
					str << '0';

			return str.str();
		}

	public:
		static void print_csv(const std::vector<evaluation>& old_data, const std::vector<evaluation>& new_data)
		{
			const auto mapping_f = mapping::create_mapping_f(old_data);
			const std::string sep = ",";

			for(const auto& e : new_data)
			{
				const auto e_old = mapping_f(e.code);

				std::cout << '"' << e.code << '"' << sep
					<< '"' << round(e.course_grade.avg(), 1) << '"' << sep
					<< '"' << round(e.course_grade.stdev(), 1) << '"' << sep
					<< '"' << e.course_grade.count() << '"' << sep
					<< '"' << round(e.teacher_grade.avg(), 1) << '"' << sep
					<< '"' << round(e.teacher_grade.stdev(), 1) << '"' << sep
					<< '"' << e.teacher_grade.count() << '"' << sep;

				if(e_old.to)
					std::cout
						<< '"' << round(e_old.to.get().course_grade.avg(), 1) << '"' << sep
						<< '"' << round(e_old.to.get().course_grade.stdev(), 1) << '"' << sep
						<< '"' << e_old.to.get().course_grade.count() << '"'
						<< std::endl;
				else
					std::cout
						<< '"' << '"' << sep
						<< '"' << '"' << sep
						<< '"' << '"'
						<< std::endl;
			}
		}

		static void print(const std::vector<evaluation>& old_data, const std::vector<evaluation>& new_data)
		{
			const static size_t slice_count = 3;

			std::vector<std::vector<evaluation>> slices(slice_count);
			const size_t slice_size = ceil((double)new_data.size() / (double)slice_count);

			for(size_t i = 0; i < slice_count; ++i)
				for(size_t j = i * slice_size; j < (i+1) * slice_size && j < new_data.size(); ++j)
					slices[i].push_back(new_data[j]);

			const auto mapping_f = mapping::create_mapping_f(old_data);
			size_t n = 0;

			std::cout << "<!DOCTYPE html>\n\n"
				<< "\t<meta charset=\"UTF-8\" />\n"
				<< "\t<title>OLC III - Vakkenranking 2013-2014</title>\n"
				<< "\t<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"http://olciii.nl/wp-content/themes/twentyeleven/style.css\">\n"
				<< "\t\n"
				<< "\n"
				<< "\n"
				<< "\n"
				<< "\t
Vakkenranking Informatica 2013-2014
\n"
				<< "\t
door Wouter Geraedts <radboud@woutergeraedts.nl>
\n"
				<< "\n"
				<< "
\n"
				<< "
\n";

			for(size_t i = 0; i < slices.size(); ++i)
			{
				const auto& slice = slices[i];

				if(i == 0)
				{
					std::cout << "
\n";

					std::cout << "
\n"
						<< "\t#	\n"
						<< "\tCode	\n"
						<< "\tNaam	\n"
						<< "\tx	\n"
						<< "\tn	\n"
						<< "\tσ	\n"
						<< "\txoud	\n"
						<< "\t 	\n"
						<< "
\n";
				}
				else
				{
					std::cout << "
\n";

					std::cout << "
\n"
						<< "\t#	\n"
						<< "\tCode	\n"
						<< "\tNaam	\n"
						<< "\tx	\n"
						<< "\tn	\n"
						<< "\tσ	\n"
						<< "\txoud	\n"
						<< "\t 	\n"
						<< "
\n";
				}

				for(size_t j = 0; j < slice.size(); ++j)
				{
					const evaluation& e = slice[j];
					const auto e_old = mapping_f(e.code);

					const double avg = e.course_grade.avg();

					if(j == slice.size() - 1) //Last element in slice
						std::cout << "
\n";
					else
						std::cout << "
\n";

					std::cout << "\t" << n << "	\n"
						<< "\t" << e.code << "	\n"
						<< "\t" << e.name << "	\n"
						<< "\t" << round(avg, 1) << "	\n"
						<< "\t" << e.course_grade.count() << "	\n"
						<< "\t" << round(e.course_grade.stdev(), 1) << "	\n";

					if(e_old.to)
					{
						const static size_t threshold = 5;
						const static double max_diff = 1.0;
						const static double sig_diff = 0.4;

						const double old_avg = e_old.to.get().course_grade.avg();
						const double diff = avg - old_avg;

						std::cout
							<< "\t" << round(old_avg, 1) << "	\n"
							<< "\t"
							<< "<div style=\"color: ";

						if(e.course_grade.count() <= threshold || e_old.to.get().course_grade.count() <= threshold)
							std::cout << "#BBB";
						else if(diff >= max_diff)
							std::cout << "green";
						else if(diff >= sig_diff)
							std::cout << "green";
						else if(diff <= -max_diff)
							std::cout << "red";
						else if(diff <= sig_diff)
							std::cout << "red";

						std::cout << "\">";

						if(diff >= max_diff)
							std::cout << "▲▲";
						else if(diff >= sig_diff)
							std::cout << "▲";
						else if(diff <= -max_diff)
							std::cout << "▼▼";
						else if(diff <= -sig_diff)
							std::cout << "▼";

						std::cout << "
";
					}
					else
					{
						std::cout << "\t 	\n";
						std::cout << "\t";

						if(e_old.mapping_type == mapping::type_e::unfound)
							std::cout << "?";
						else if(e_old.mapping_type == mapping::type_e::added)
							std::cout << "!";
						else
							std::cout << "666";

						std::cout << "	\n";
					}

					std::cout << "
\n";
					n++;
				}

				std::cout << "
\n" << std::endl;
			}

			std::cout << "

\n"
				<< "
\n"
				<< "
▲	→	0.4 ≤ δ ≤ 1.0
\n"
				<< "
▲▲	→	δ > 1.0
\n"
				<< "
▼ grijs	→	niet significant aantal deelnemers
\n"
				<< "
▼ kleur	→	significant aantal deelnemers
\n"
				<< "
!	→	cursus nieuw in 2013-2014
\n"
				<< "
?	→	geen enquêteresultaten uit 2012-2013
\n"
				<< "";
		}
	};
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2017 Daniele Bartolini and individual contributors.
 * License: https://github.com/taylor001/crown/blob/master/LICENSE
 */

#include "config.h"
#include "device.h"
#include "error.h"
#include "log.h"
#include "lua_environment.h"
#include "lua_resource.h"
#include "lua_stack.h"
#include "resource_manager.h"
#include <stdarg.h>

namespace { const crown::log_internal::System LUA = { "Lua" }; }

namespace crown
{
extern void load_api(LuaEnvironment& env);

// When an error occurs, logs the error message and pauses the engine.
static int error_handler(lua_State* L)
{
	lua_getfield(L, LUA_GLOBALSINDEX, "debug");
	if (!lua_istable(L, -1))
	{
		lua_pop(L, 1);
		return 0;
	}

	lua_getfield(L, -1, "traceback");
	if (!lua_isfunction(L, -1))
	{
		lua_pop(L, 2);
		return 0;
	}

	lua_pushvalue(L, 1); // Pass error message
	lua_pushinteger(L, 2);
	lua_call(L, 2, 1); // Call debug.traceback

	loge(LUA, lua_tostring(L, -1)); // Print error message
	lua_pop(L, 1); // Remove error message from stack
	lua_pop(L, 1); // Remove debug.traceback from stack

	device()->pause();
	return 0;
}

// Redirects require to the resource manager.
static int require(lua_State* L)
{
	LuaStack stack(L);
	const LuaResource* lr = (LuaResource*)device()->_resource_manager->get(RESOURCE_TYPE_SCRIPT, stack.get_resource_id(1));
	luaL_loadbuffer(L, lua_resource::program(lr), lr->size, "");
	return 1;
}

LuaEnvironment::LuaEnvironment()
	: L(NULL)
	, _vec3_used(0)
	, _quat_used(0)
	, _mat4_used(0)
{
	L = luaL_newstate();
	CE_ASSERT(L, "Unable to create lua state");
}

LuaEnvironment::~LuaEnvironment()
{
	lua_close(L);
}

void LuaEnvironment::load_libs()
{
	lua_gc(L, LUA_GCSTOP, 0);

	// Open default libraries
	luaL_openlibs(L);

	// Register crown libraries
	load_api(*this);

	// Register custom loader
	lua_getfield(L, LUA_GLOBALSINDEX, "package");
	lua_getfield(L, -1, "loaders");
	lua_remove(L, -2);

	int num_loaders = 0;
	lua_pushnil(L);
	while (lua_next(L, -2) != 0)
	{
		lua_pop(L, 1);
		num_loaders++;
	}
	lua_pushinteger(L, num_loaders + 1);
	lua_pushcfunction(L, require);
	lua_rawset(L, -3);
	lua_pop(L, 1);

	// Create metatable for lightuserdata
	lua_pushlightuserdata(L, 0);
	lua_getfield(L, LUA_REGISTRYINDEX, "Lightuserdata_mt");
	lua_setmetatable(L, -2);
	lua_pop(L, 1);

	// Ensure stack is clean
	CE_ASSERT(lua_gettop(L) == 0, "Stack not clean");

	lua_gc(L, LUA_GCRESTART, 0);
}

LuaStack LuaEnvironment::execute(const LuaResource* lr)
{
	LuaStack stack(L);
	lua_pushcfunction(L, error_handler);
	luaL_loadbuffer(L, lua_resource::program(lr), lr->size, "<unknown>");
	lua_pcall(L, 0, 1, -2);
	lua_pop(L, 1);
	return stack;
}

LuaStack LuaEnvironment::execute_string(const char* s)
{
	LuaStack stack(L);
	lua_pushcfunction(L, error_handler);
	luaL_loadstring(L, s);
	lua_pcall(L, 0, 0, -2);
	lua_pop(L, 1);
	return stack;
}

void LuaEnvironment::add_module_function(const char* module, const char* name, const lua_CFunction func)
{
	luaL_Reg entry[2];
	entry[0].name = name;
	entry[0].func = func;
	entry[1].name = NULL;
	entry[1].func = NULL;

	luaL_register(L, module, entry);
	lua_pop(L, 1);
}

void LuaEnvironment::add_module_function(const char* module, const char* name, const char* func)
{
	// Create module if it does not exist
	luaL_Reg entry;
	entry.name = NULL;
	entry.func = NULL;
	luaL_register(L, module, &entry);
	lua_pop(L, 1);

	lua_getglobal(L, module);
	lua_getglobal(L, func);
	lua_setfield(L, -2, name);
	lua_setglobal(L, module);
}

void LuaEnvironment::set_module_constructor(const char* module, const lua_CFunction func)
{
	// Create module if it does not exist
	luaL_Reg entry;
	entry.name = NULL;
	entry.func = NULL;
	luaL_register(L, module, &entry);
	lua_pop(L, 1);

	// Create dummy tables to be used as module's metatable
	lua_createtable(L, 0, 1);
	lua_pushstring(L, "__call");
	lua_pushcfunction(L, func);
	lua_settable(L, 1); // dummy.__call = func
	lua_getglobal(L, module);
	lua_pushvalue(L, -2); // Duplicate dummy metatable
	lua_setmetatable(L, -2); // setmetatable(module, dummy)
	lua_pop(L, -1);
}

void LuaEnvironment::call_global(const char* func, u8 argc, ...)
{
	CE_ENSURE(NULL != func);

	LuaStack stack(L);

	va_list vl;
	va_start(vl, argc);

	lua_pushcfunction(L, error_handler);
	lua_getglobal(L, func);

	for (u8 i = 0; i < argc; i++)
	{
		const int type = va_arg(vl, int);
		switch (type)
		{
		case ARGUMENT_FLOAT:
			stack.push_float(va_arg(vl, f64));
			break;

		default:
			CE_FATAL("Unknown argument type");
			break;
		}
	}

	va_end(vl);
	lua_pcall(L, argc, 0, -argc - 2);
	lua_pop(L, -1);

	CE_ASSERT(lua_gettop(L) == 0, "Stack not clean");
}

LuaStack LuaEnvironment::get_global(const char* global)
{
	LuaStack stack(L);
	lua_getglobal(L, global);
	return stack;
}

Vector3* LuaEnvironment::next_vector3(const Vector3& v)
{
	CE_ASSERT(_vec3_used < CROWN_MAX_LUA_VECTOR3, "Maximum number of Vector3 reached");
	return &(_vec3_buffer[_vec3_used++] = v);
}

Quaternion* LuaEnvironment::next_quaternion(const Quaternion& q)
{
	CE_ASSERT(_quat_used < CROWN_MAX_LUA_QUATERNION, "Maximum number of Quaternion reached");
	return &(_quat_buffer[_quat_used++] = q);
}

Matrix4x4* LuaEnvironment::next_matrix4x4(const Matrix4x4& m)
{
	CE_ASSERT(_mat4_used < CROWN_MAX_LUA_MATRIX4X4, "Maximum number of Matrix4x4 reached");
	return &(_mat4_buffer[_mat4_used++] = m);
}

bool LuaEnvironment::is_vector3(const Vector3* p) const
{
	return p >= &_vec3_buffer[0]
		&& p <= &_vec3_buffer[CROWN_MAX_LUA_VECTOR3 - 1];
}

bool LuaEnvironment::is_quaternion(const Quaternion* p) const
{
	return p >= &_quat_buffer[0]
		&& p <= &_quat_buffer[CROWN_MAX_LUA_QUATERNION - 1];
}

bool LuaEnvironment::is_matrix4x4(const Matrix4x4* p) const
{
	return p >= &_mat4_buffer[0]
		&& p <= &_mat4_buffer[CROWN_MAX_LUA_MATRIX4X4 - 1];
}

void LuaEnvironment::temp_count(u32& num_vec3, u32& num_quat, u32& num_mat4)
{
	num_vec3 = _vec3_used;
	num_quat = _quat_used;
	num_mat4 = _mat4_used;
}

void LuaEnvironment::set_temp_count(u32 num_vec3, u32 num_quat, u32 num_mat4)
{
	_vec3_used = num_vec3;
	_quat_used = num_quat;
	_mat4_used = num_mat4;
}

void LuaEnvironment::reset_temporaries()
{
	_vec3_used = 0;
	_quat_used = 0;
	_mat4_used = 0;
}

} // namespace crown
<commit_msg>Revert "Create module if it does not exist"<commit_after>/*
 * Copyright (c) 2012-2017 Daniele Bartolini and individual contributors.
 * License: https://github.com/taylor001/crown/blob/master/LICENSE
 */

#include "config.h"
#include "device.h"
#include "error.h"
#include "log.h"
#include "lua_environment.h"
#include "lua_resource.h"
#include "lua_stack.h"
#include "resource_manager.h"
#include <stdarg.h>

namespace { const crown::log_internal::System LUA = { "Lua" }; }

namespace crown
{
extern void load_api(LuaEnvironment& env);

// When an error occurs, logs the error message and pauses the engine.
static int error_handler(lua_State* L)
{
	lua_getfield(L, LUA_GLOBALSINDEX, "debug");
	if (!lua_istable(L, -1))
	{
		lua_pop(L, 1);
		return 0;
	}

	lua_getfield(L, -1, "traceback");
	if (!lua_isfunction(L, -1))
	{
		lua_pop(L, 2);
		return 0;
	}

	lua_pushvalue(L, 1); // Pass error message
	lua_pushinteger(L, 2);
	lua_call(L, 2, 1); // Call debug.traceback

	loge(LUA, lua_tostring(L, -1)); // Print error message
	lua_pop(L, 1); // Remove error message from stack
	lua_pop(L, 1); // Remove debug.traceback from stack

	device()->pause();
	return 0;
}

// Redirects require to the resource manager.
static int require(lua_State* L)
{
	LuaStack stack(L);
	const LuaResource* lr = (LuaResource*)device()->_resource_manager->get(RESOURCE_TYPE_SCRIPT, stack.get_resource_id(1));
	luaL_loadbuffer(L, lua_resource::program(lr), lr->size, "");
	return 1;
}

LuaEnvironment::LuaEnvironment()
	: L(NULL)
	, _vec3_used(0)
	, _quat_used(0)
	, _mat4_used(0)
{
	L = luaL_newstate();
	CE_ASSERT(L, "Unable to create lua state");
}

LuaEnvironment::~LuaEnvironment()
{
	lua_close(L);
}

void LuaEnvironment::load_libs()
{
	lua_gc(L, LUA_GCSTOP, 0);

	// Open default libraries
	luaL_openlibs(L);

	// Register crown libraries
	load_api(*this);

	// Register custom loader
	lua_getfield(L, LUA_GLOBALSINDEX, "package");
	lua_getfield(L, -1, "loaders");
	lua_remove(L, -2);

	int num_loaders = 0;
	lua_pushnil(L);
	while (lua_next(L, -2) != 0)
	{
		lua_pop(L, 1);
		num_loaders++;
	}
	lua_pushinteger(L, num_loaders + 1);
	lua_pushcfunction(L, require);
	lua_rawset(L, -3);
	lua_pop(L, 1);

	// Create metatable for lightuserdata
	lua_pushlightuserdata(L, 0);
	lua_getfield(L, LUA_REGISTRYINDEX, "Lightuserdata_mt");
	lua_setmetatable(L, -2);
	lua_pop(L, 1);

	// Ensure stack is clean
	CE_ASSERT(lua_gettop(L) == 0, "Stack not clean");

	lua_gc(L, LUA_GCRESTART, 0);
}

LuaStack LuaEnvironment::execute(const LuaResource* lr)
{
	LuaStack stack(L);
	lua_pushcfunction(L, error_handler);
	luaL_loadbuffer(L, lua_resource::program(lr), lr->size, "<unknown>");
	lua_pcall(L, 0, 1, -2);
	lua_pop(L, 1);
	return stack;
}

LuaStack LuaEnvironment::execute_string(const char* s)
{
	LuaStack stack(L);
	lua_pushcfunction(L, error_handler);
	luaL_loadstring(L, s);
	lua_pcall(L, 0, 0, -2);
	lua_pop(L, 1);
	return stack;
}

void LuaEnvironment::add_module_function(const char* module, const char* name, const lua_CFunction func)
{
	luaL_newmetatable(L, module);
	luaL_Reg entry[2];

	entry[0].name = name;
	entry[0].func = func;
	entry[1].name = NULL;
	entry[1].func = NULL;

	luaL_register(L, NULL, entry);
	lua_setglobal(L, module);
	lua_pop(L, -1);
}

void LuaEnvironment::add_module_function(const char* module, const char* name, const char* func)
{
	luaL_newmetatable(L, module);
	lua_getglobal(L, func);
	lua_setfield(L, -2, name);
	lua_setglobal(L, module);
}

void LuaEnvironment::set_module_constructor(const char* module, const lua_CFunction func)
{
	// Create dummy tables to be used as module's metatable
	lua_createtable(L, 0, 1);
	lua_pushstring(L, "__call");
	lua_pushcfunction(L, func);
	lua_settable(L, 1); // dummy.__call = func
	lua_getglobal(L, module);
	lua_pushvalue(L, -2); // Duplicate dummy metatable
	lua_setmetatable(L, -2); // setmetatable(module, dummy)
	lua_pop(L, -1);
}

void LuaEnvironment::call_global(const char* func, u8 argc, ...)
{
	CE_ENSURE(NULL != func);

	LuaStack stack(L);

	va_list vl;
	va_start(vl, argc);

	lua_pushcfunction(L, error_handler);
	lua_getglobal(L, func);

	for (u8 i = 0; i < argc; i++)
	{
		const int type = va_arg(vl, int);
		switch (type)
		{
		case ARGUMENT_FLOAT:
			stack.push_float(va_arg(vl, f64));
			break;

		default:
			CE_FATAL("Unknown argument type");
			break;
		}
	}

	va_end(vl);
	lua_pcall(L, argc, 0, -argc - 2);
	lua_pop(L, -1);

	CE_ASSERT(lua_gettop(L) == 0, "Stack not clean");
}

LuaStack LuaEnvironment::get_global(const char* global)
{
	LuaStack stack(L);
	lua_getglobal(L, global);
	return stack;
}

Vector3* LuaEnvironment::next_vector3(const Vector3& v)
{
	CE_ASSERT(_vec3_used < CROWN_MAX_LUA_VECTOR3, "Maximum number of Vector3 reached");
	return &(_vec3_buffer[_vec3_used++] = v);
}

Quaternion* LuaEnvironment::next_quaternion(const Quaternion& q)
{
	CE_ASSERT(_quat_used < CROWN_MAX_LUA_QUATERNION, "Maximum number of Quaternion reached");
	return &(_quat_buffer[_quat_used++] = q);
}

Matrix4x4* LuaEnvironment::next_matrix4x4(const Matrix4x4& m)
{
	CE_ASSERT(_mat4_used < CROWN_MAX_LUA_MATRIX4X4, "Maximum number of Matrix4x4 reached");
	return &(_mat4_buffer[_mat4_used++] = m);
}

bool LuaEnvironment::is_vector3(const Vector3* p) const
{
	return p >= &_vec3_buffer[0]
		&& p <= &_vec3_buffer[CROWN_MAX_LUA_VECTOR3 - 1];
}

bool LuaEnvironment::is_quaternion(const Quaternion* p) const
{
	return p >= &_quat_buffer[0]
		&& p <= &_quat_buffer[CROWN_MAX_LUA_QUATERNION - 1];
}

bool LuaEnvironment::is_matrix4x4(const Matrix4x4* p) const
{
	return p >= &_mat4_buffer[0]
		&& p <= &_mat4_buffer[CROWN_MAX_LUA_MATRIX4X4 - 1];
}

void LuaEnvironment::temp_count(u32& num_vec3, u32& num_quat, u32& num_mat4)
{
	num_vec3 = _vec3_used;
	num_quat = _quat_used;
	num_mat4 = _mat4_used;
}

void LuaEnvironment::set_temp_count(u32 num_vec3, u32 num_quat, u32 num_mat4)
{
	_vec3_used = num_vec3;
	_quat_used = num_quat;
	_mat4_used = num_mat4;
}

void LuaEnvironment::reset_temporaries()
{
	_vec3_used = 0;
	_quat_used = 0;
	_mat4_used = 0;
}

} // namespace crown
<|endoftext|>


<commit_before>#include <iostream>
#include <functional>
#include <vector>

struct State {};

class FrameReplay {
public:

    using init_function_t = std::function<void(const std::vector<uint8_t*>&)>;
    using draw_function_t = std::function<void(const State&, const std::vector<uint8_t*>&)>;

    FrameReplay(uint32_t frameId,
                init_function_t initFunc = [](const std::vector<uint8_t*> &){},
                draw_function_t drawFunc = [](const State&, const std::vector<uint8_t*> &){})
        : frameId_(frameId),
          initFunc_(initFunc),
          drawFunc_(drawFunc)
    {}

    uint32_t getFrameId() const { return frameId_; }
    void setInitFunc(init_function_t initFunc) { initFunc_ = initFunc; }
    void setDrawFunc(draw_function_t drawFunc) { drawFunc_ = drawFunc; }
    void init(const std::vector<uint8_t*> &buffer) { initFunc_(buffer); }
    void draw(const State &engine, const std::vector<uint8_t*> &buffer) { drawFunc_(engine, buffer); }

private:
    uint32_t frameId_;
    init_function_t initFunc_;
    draw_function_t drawFunc_;
};

int main()
{
    std::vector<FrameReplay*> frames;
    {
        // frame #0
        // some resources
        static int res77;
        static const char arr_0[] = "frame #0 vs";
        auto frame = new FrameReplay(0, [&](const std::vector<uint8_t*> &) { res77 = 1; },
                                        [&](const State&, const std::vector<uint8_t*> &)
                                        {
                                            std::cout << "res77: " << res77 << " ";
                                            std::cout << "arr_0: " << arr_0 << std::endl;
                                        } );
        frames.push_back(frame);
    }
    {
        // frame #1
        // some resources
        static int res77;
        static const char arr_0[] = "frame #1 vs";
        auto frame = new FrameReplay(1);
        frame->setInitFunc([&](const std::vector<uint8_t*> &) { res77 = 2; });
        frame->setDrawFunc([&](const State&, const std::vector<uint8_t*> &)
                                        {
                                            std::cout << "res77: " << res77 << " ";
                                            std::cout << "arr_0: " << arr_0 << std::endl;
                                        } );
        frames.push_back(frame);
    }

    for (const auto& f : frames) {
        std::cout << "frame #" << f->getFrameId() << std::endl;
        f->init({});
        f->draw({},{});
    }
}

<commit_msg>put into namespace the lambda closure sample.<commit_after>#include <iostream>
#include <functional>
#include <vector>

namespace abc {

struct State {};

class FrameReplay {
public:

    using init_function_t = std::function<void(const std::vector<uint8_t*>&)>;
    using draw_function_t = std::function<void(const State&, const std::vector<uint8_t*>&)>;

    FrameReplay(uint32_t frameId,
                init_function_t initFunc = [](const std::vector<uint8_t*> &){},
                draw_function_t drawFunc = [](const State&, const std::vector<uint8_t*> &){})
        : frameId_(frameId),
          initFunc_(initFunc),
          drawFunc_(drawFunc)
    {}

    uint32_t getFrameId() const { return frameId_; }
    void setInitFunc(init_function_t initFunc) { initFunc_ = initFunc; }
    void setDrawFunc(draw_function_t drawFunc) { drawFunc_ = drawFunc; }
    void setHeight(int h) { height_ = h; }
    void setWidth(int w) { width_ = w; }
    void init(const std::vector<uint8_t*> &buffer) const { initFunc_(buffer); }
    void draw(const State &engine, const std::vector<uint8_t*> &buffer) const { drawFunc_(engine, buffer); }

private:
    uint32_t frameId_;
    init_function_t initFunc_;
    draw_function_t drawFunc_;
    int height_;
    int width_;
};

std::vector<FrameReplay*> init()
{
    std::vector<FrameReplay*> frames;
    {
        // frame #0
        // some resources
        static int res77;
        static const char arr_0[] = "frame #0 vs";
        auto frame = new FrameReplay(0, [&](const std::vector<uint8_t*> &) { res77 = 1; },
                                        [&](const State&, const std::vector<uint8_t*> &)
                                        {
                                            std::cout << "res77: " << res77 << " ";
                                            std::cout << "arr_0: " << arr_0 << std::endl;
                                        } );
        frames.push_back(frame);
    }
    {
        // frame #1
        // some resources
        static int res77;
        static const char arr_0[] = "frame #1 vs";
        auto frame = new FrameReplay(1);
        frame->setInitFunc([&](const std::vector<uint8_t*> &) { res77 = 2; });
        frame->setDrawFunc([&](const State&, const std::vector<uint8_t*> &)
                                        {
                                            std::cout << "res77: " << res77 << " ";
                                            std::cout << "arr_0: " << arr_0 << std::endl;
                                        } );
        frames.push_back(frame);
    }

    // NVRO
    return frames;
}

}

int main()
{
    auto frames = abc::init();
    for (const auto& f : frames) {
        std::cout << "frame #" << f->getFrameId() << std::endl;
        f->init({});
        f->draw({},{});
    }

}
<|endoftext|>


<commit_before>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file     g_dfs_server.cpp
* @version
* @brief
* @author   duye
* @date     2014-09-24
* @note
*
*  1. 2014-09-24 duye Created this file
*
*/

#include <g_dfs_server.h>
#include <g_logger.h>

static const GInt8* LOG_PREFIX = "dfs.server.startup";

namespace gdfs {

DfsServer::DfsServer() : gcom::HostServer() {}

DfsServer::DfsServer(const std::string& dfs_cfg_file_path) : gcom::HostServer(), m_dfsCfgFilePath(dfs_cfg_file_path) {}

DfsServer::~DfsServer()
{
    DfsServerFactory::DestroyServer(HTTP_SERVER, m_httpServer);
    DfsServerFactory::DestroyServer(FTP_SERVER, m_httpServer);
    DfsServerFactory::DestroyServer(CLI_SERVER, m_httpServer);
}

GResult DfsServer::start()
{
    G_LOG_IN();

    if (getServerState() == HOST_SERVER_WORK)
    {
        return G_YES;
    }

    if (m_dfsCfgFilePath.empty())
    {
        m_dfsCfgFilePath = DEF_DFS_CFG_FILE_PATH;
    }

    IS_NO_R(m_cfgMgr.load(m_dfsCfgFilePath));
    IS_NO_R(initService());

    m_serverState = HOST_SERVER_WORK;

    // start routine() thread
    this->startTask();

    G_LOG_OUT();

    return G_YES;
}

GResult DfsServer::stop()
{
    G_LOG_IN();

    m_httpServer->stop();
    m_ftpServer->stop();
    m_cliServer->stop();

    G_LOG_OUT();

    return G_NO;
}

DfsServerState DfsServer::routine()
{
    G_LOG_IN();

    m_httpServer->start();
    m_ftpServer->start();
    m_cliServer->start();

    for (;;)
    {
        // startup all server
        gcom::NetworkServerMonitor::keepServer(m_httpServer);
        gcom::NetworkServerMonitor::keepServer(m_ftpServer);
        gcom::NetworkServerMonitor::keepServer(m_cliServer);
        gsys::System::sleep(5);
    }

    G_LOG_OUT();

    return G_YES;
}

GResult DfsServer::initService()
{
    G_LOG_IN();

    m_httpServer = DfsServerFactory::createServer(HTTP_SERVER);
    m_ftpServer = DfsServerFactory::createServer(FTP_SERVER);
    m_cliServer = DfsServerFactory::createServer(CLI_SERVER);

    G_LOG_OUT();

    return G_YES;
}
}
<commit_msg>Update g_dfs_server.cpp<commit_after>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file     g_dfs_server.cpp
* @version
* @brief
* @author   duye
* @date     2014-09-24
* @note
*
*  1. 2014-09-24 duye Created this file
*
*/

#include <g_dfs_server.h>
#include <g_logger.h>

static const GInt8* LOG_PREFIX = "dfs.server.startup";

namespace gdfs {

DfsServer::DfsServer() : gcom::HostServer() {}

DfsServer::DfsServer(const std::string& dfs_cfg_file_path) : gcom::HostServer(), m_dfsCfgFilePath(dfs_cfg_file_path) {}

DfsServer::~DfsServer()
{
    gcom::ServerFactory::intance().destroyServer(m_httpServer);
    gcom::ServerFactory::intance().destroyServer(m_ftpServer);
    gcom::ServerFactory::intance().destroyServer(m_cliServer);
}

GResult DfsServer::start()
{
    G_LOG_IN();

    if (getServerState() == HOST_SERVER_WORK)
    {
        return G_YES;
    }

    if (m_dfsCfgFilePath.empty())
    {
        m_dfsCfgFilePath = DEF_DFS_CFG_FILE_PATH;
    }

    IS_NO_R(m_cfgMgr.load(m_dfsCfgFilePath));
    IS_NO_R(initService());

    m_serverState = HOST_SERVER_WORK;

    // start routine() thread
    this->startTask();

    G_LOG_OUT();

    return G_YES;
}

GResult DfsServer::stop()
{
    G_LOG_IN();

    m_httpServer->stop();
    m_ftpServer->stop();
    m_cliServer->stop();

    G_LOG_OUT();

    return G_NO;
}

DfsServerState DfsServer::routine()
{
    G_LOG_IN();

    m_httpServer->start();
    m_ftpServer->start();
    m_cliServer->start();

    for (;;)
    {
        // startup all server
        gcom::NetworkServerMonitor::keepServer(m_httpServer);
        gcom::NetworkServerMonitor::keepServer(m_ftpServer);
        gcom::NetworkServerMonitor::keepServer(m_cliServer);
        gsys::System::sleep(5);
    }

    G_LOG_OUT();

    return G_YES;
}

GResult DfsServer::initService()
{
    G_LOG_IN();

    m_httpServer = gcom::ServerFactory::intance().createServer(HTTP_SERVER);
    m_ftpServer = gcom::ServerFactory::intance().createServer(FTP_SERVER);
    m_cliServer = gcom::ServerFactory::intance().createServer(CLI_SERVER);

    G_LOG_OUT();

    return G_YES;
}

}
<|endoftext|>


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

#include "exception.h"

#include "log.h"

#include <string.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <stdarg.h>

#define BUFFER_SIZE 1024

const char*
Exception::init_traceback()
{
	void* callstack[128];

	// retrieve current stack addresses
	int frames = backtrace(callstack, sizeof(callstack) / sizeof(void*));

	traceback = "Traceback:";

	if (frames == 0) {
		traceback += "\n    <empty, possibly corrupt>";
		return traceback.c_str();
	}

	// resolve addresses into strings containing "filename(function+address)"
	char** strs = backtrace_symbols(callstack, frames);

	// iterate over the returned symbol lines. skip the first, it is the
	// address of this function.
	for (int i = 0; i < frames; ++i) {
		int status = 0;
		const char *sep = "\t ()+";
		char *mangled, *lasts;
		std::string result;
		for (mangled = strtok_r(strs[i], sep, &lasts); mangled; mangled = strtok_r(nullptr, sep, &lasts)) {
			char* unmangled = abi::__cxa_demangle(mangled, nullptr, 0, &status);
			if (!result.empty()) {
				result += " ";
			}
			if (status == 0) {
				result += unmangled;
			} else {
				result += mangled;
			}
			free(unmangled);
		}
		traceback += "\n    " + result;
	}

	free(strs);

	return traceback.c_str();
}

Exception::Exception(const char *filename, int line, const char *format, ...)
	: std::runtime_error("")
{
	char buffer[BUFFER_SIZE];

	va_list argptr;
	va_start(argptr, format);
	vsnprintf(buffer, BUFFER_SIZE, format, argptr);
	va_end(argptr);
	msg.assign(buffer);

	snprintf(buffer, BUFFER_SIZE, "%s:%d", filename, line);
	context.assign(std::string(buffer) + ": " + msg);

#ifdef TRACEBACKS
	init_traceback();
#endif
}
<commit_msg>Allways print file:line on exception logs when TRACEBACKS is on<commit_after>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "exception.h"

#include "log.h"

#include <string.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <stdarg.h>

#define BUFFER_SIZE 1024

const char*
Exception::init_traceback()
{
	void* callstack[128];

	// retrieve current stack addresses
	int frames = backtrace(callstack, sizeof(callstack) / sizeof(void*));

	traceback = "Traceback:";

	if (frames == 0) {
		traceback += "\n    <empty, possibly corrupt>";
		return traceback.c_str();
	}

	// resolve addresses into strings containing "filename(function+address)"
	char** strs = backtrace_symbols(callstack, frames);

	// iterate over the returned symbol lines. skip the first, it is the
	// address of this function.
	for (int i = 0; i < frames; ++i) {
		int status = 0;
		const char *sep = "\t ()+";
		char *mangled, *lasts;
		std::string result;
		for (mangled = strtok_r(strs[i], sep, &lasts); mangled; mangled = strtok_r(nullptr, sep, &lasts)) {
			char* unmangled = abi::__cxa_demangle(mangled, nullptr, 0, &status);
			if (!result.empty()) {
				result += " ";
			}
			if (status == 0) {
				result += unmangled;
			} else {
				result += mangled;
			}
			free(unmangled);
		}
		traceback += "\n    " + result;
	}

	free(strs);

	return traceback.c_str();
}

Exception::Exception(const char *filename, int line, const char *format, ...)
	: std::runtime_error("")
{
	char buffer[BUFFER_SIZE];

	va_list argptr;
	va_start(argptr, format);
	vsnprintf(buffer, BUFFER_SIZE, format, argptr);
	va_end(argptr);
	msg.assign(buffer);

	snprintf(buffer, BUFFER_SIZE, "%s:%d", filename, line);
	context.assign(std::string(buffer) + ": " + msg);

#ifdef TRACEBACKS
	msg.assign(std::string(buffer) + ": " + msg);

	init_traceback();
#endif
}
<|endoftext|>


<commit_before><commit_msg>When pasting from other apps, fall back on Fragment span.<commit_after><|endoftext|>


<commit_before><commit_msg>refacotr InfoBar to use RenderContext<commit_after><|endoftext|>