<commit_before>/*
 * Part of libAsmara, a library for accessing AppStream on-disk database
 * Copyright 2014  Sune Vuorela <sune@vuorela.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "component.h"
#include "screenshot.h"
#include <QSharedData>
#include <QStringList>
#include <QUrl>

using namespace Asmara;

class Asmara::ComponentData : public QSharedData {
    public:
        QStringList m_categories;
        QStringList m_compulsoryForDesktops;
        QString m_description;
        QString m_developerName;
        QStringList m_extends;
        QString m_icon;
        QUrl m_iconUrl;
        QString m_id;
        Component::Kind m_kind;
        QString m_name;
        QString m_packageName;
        QString m_projectGroup;
        QString m_projectLicense;
        QString m_summary;
        QMultiHash<Component::UrlKind, QUrl> m_urls;
        QList<Asmara::ScreenShot> m_screenshots;
        bool operator==(const ComponentData& other) const {
            if(m_categories != other.m_categories) {
                return false;
            }
            if(m_compulsoryForDesktops != other.m_compulsoryForDesktops) {
                return false;
            }
            if(m_description != other.m_description) {
                return false;
            }
            if(m_developerName != other.m_developerName) {
                return false;
            }
            if(m_extends != other.m_extends) {
                return false;
            }
            if(m_icon != other.m_icon) {
                return false;
            }
            if(m_iconUrl != other.m_iconUrl) {
                return false;
            }
            if(m_id != other.m_id) {
                return false;
            }
            if(m_kind != other.m_kind) {
                return false;
            }
            if(m_name != other.m_name) {
                return false;
            }
            if(m_packageName != other.m_packageName) {
                return false;
            }
            if(m_projectGroup != other.m_projectGroup) {
                return false;
            }
            if(m_projectLicense != other.m_projectLicense) {
                return false;
            }
            if(m_summary != other.m_summary) {
                return false;
            }
            if(m_urls != other.m_urls) {
                return false;
            }
            if(m_screenshots != other.m_screenshots) {
                return false;
            }
            return true;
        }
};

const QStringList& Component::categories() const {
    return d->m_categories;
}

const QStringList& Component::compulsoryForDesktops() const {
    return d->m_compulsoryForDesktops;
}

const QString& Component::description() const {
    return d->m_description;
}

const QString& Component::developerName() const {
    return d->m_developerName;
}

const QStringList& Component::extends() const {
    return d->m_extends;
}

bool Component::hasCategory(const QString& category) const {
    return d->m_categories.contains(category);
}

const QString& Component::icon() const {
    return d->m_icon;
}

const QUrl& Component::iconUrl() const {
    return d->m_iconUrl;
}

const QString& Component::id() const {
    return d->m_id;
}

bool Component::isCompulsoryForDesktop(const QString& desktop) const {
    return d->m_compulsoryForDesktops.contains(desktop);
}

Component::Kind Component::kind() const {
    return d->m_kind;
}

const QString& Component::name() const {
    return d->m_name;
}

const QString& Component::packageName() const {
    return d->m_packageName;
}

const QString& Component::projectGroup() const {
    return d->m_projectGroup;
}

const QString& Component::projectLicense() const {
    return d->m_projectLicense;
}

void Component::setCategories(const QStringList& categories) {
    d->m_categories = categories;
}

void Component::setCompulsoryForDesktops(const QStringList& desktops) {
    d->m_compulsoryForDesktops = desktops;
}

void Component::setDescription(const QString& description) {
    d->m_description = description;
}

void Component::setDeveloperName(const QString& developerName) {
    d->m_developerName = developerName;
}

void Component::setIcon(const QString& icon) {
    d->m_icon = icon;
}

void Component::setIconUrl(const QUrl& iconUrl) {
    d->m_iconUrl = iconUrl;
}

void Component::setId(QString id) {
    d->m_id = id;
}

void Component::setKind(Component::Kind kind) {
    d->m_kind = kind;
}

void Component::setName(const QString& name) {
    d->m_name = name;
}

void Component::setPackageName(const QString& packageName) {
    d->m_packageName = packageName;
}

void Component::setProjectGroup(const QString& group) {
    d->m_projectGroup = group;
}

void Component::setProjectLicense(const QString& license){
    d->m_projectLicense = license;
}

void Component::setSummary(const QString& summary){
    d->m_summary = summary;
}

const QString& Component::summary() const {
    return d->m_summary;
}

Component::Component(const Component& other) : d(other.d) {

}

Component::Component() : d(new ComponentData) {

}

Component& Component::operator=(const Component& other) {
    this->d = other.d;
    return *this;
}

void Component::setUrls(const QMultiHash< Component::UrlKind, QUrl >& urls) {
    d->m_urls = urls;
}
QList< QUrl > Component::urls(Component::UrlKind kind) const {
    return d->m_urls.values(kind);
}

const QMultiHash< Component::UrlKind, QUrl >& Component::urls() const {
    return d->m_urls;
}

bool Component::operator==(const Component& other) {
    if(this->d == other.d) {
        return true;
    }
    if(this->d && other.d) {
        return *(this->d) == *other.d;
    }
    return false;
}

Component::~Component() {

}

QHash<Component::Kind, QString> buildKindMap() {
    QHash<Component::Kind,QString> map;
    map.insert(Component::KindAddon, QLatin1String("addon"));
    map.insert(Component::KindCodec, QLatin1String("codec"));
    map.insert(Component::KindDesktop, QLatin1String("desktop"));
    map.insert(Component::KindFont, QLatin1String("font"));
    map.insert(Component::KindGeneric, QLatin1String("generic"));
    map.insert(Component::KindInputmethod, QLatin1String("inputmethod"));
    map.insert(Component::KindUnknown, QLatin1String("unknown"));
    return map;
}

QString Component::kindToString(Component::Kind kind) {
    static QHash<Kind, QString> kindMap = buildKindMap();
    return kindMap.value(kind);
}

Component::Kind Component::stringToKind(const QString& kindString) {
    if(kindString ==  QLatin1String("generic")) {
        return KindGeneric;
    }
    if (kindString == QLatin1String("desktop")) {
        return KindDesktop;
    }
    if (kindString == QLatin1String("font")) {
        return KindFont;
    }
    if (kindString == QLatin1String("codec")) {
        return KindCodec;
    }
    if (kindString==QLatin1String("inputmethod")) {
        return KindInputmethod;
    }
    if (kindString == QLatin1String("addon")) {
        return KindAddon;
    }
    return KindUnknown;

}

void Component::setScreenShots(const QList< ScreenShot >& screenshots) {
    d->m_screenshots = screenshots;
}

const QList< ScreenShot >& Component::screenShots() const {
    return d->m_screenshots;
}

Component::UrlKind Component::stringToUrlKind(const QString& urlKindString) {
    if (urlKindString == QLatin1String("homepage")) {
        return UrlKindHomepage;
    }
    if (urlKindString == QLatin1String("bugtracker")) {
        return UrlKindBugtracker;
    }
    if (urlKindString == QLatin1String("faq")) {
        return UrlKindFaq;
    }
    if (urlKindString == QLatin1String("help")) {
        return UrlKindHelp;
    }
    if (urlKindString == QLatin1String("donation")) {
        return UrlKindDonation;
    }
    return UrlKindUnknown;
}

static QHash<Component::UrlKind,QString> buildUrlKindMap() {
    QHash<Component::UrlKind, QString> map;
    map.insert(Component::UrlKindBugtracker,QLatin1String("bugtracker"));
    map.insert(Component::UrlKindDonation,QLatin1String("donation"));
    map.insert(Component::UrlKindFaq,QLatin1String("faq"));
    map.insert(Component::UrlKindHelp,QLatin1String("help"));
    map.insert(Component::UrlKindHomepage, QLatin1String("homepage"));
    map.insert(Component::UrlKindUnknown, QLatin1String("unknown"));
}

QString Component::urlKindToString(Component::UrlKind kind) {
    static const QHash<UrlKind, QString> kindMap = buildUrlKindMap();
    return kindMap.value(kind);
}

<commit_msg>Acually return the map built when converting UrlKinds to strings<commit_after>/*
 * Part of libAsmara, a library for accessing AppStream on-disk database
 * Copyright 2014  Sune Vuorela <sune@vuorela.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "component.h"
#include "screenshot.h"
#include <QSharedData>
#include <QStringList>
#include <QUrl>

using namespace Asmara;

class Asmara::ComponentData : public QSharedData {
    public:
        QStringList m_categories;
        QStringList m_compulsoryForDesktops;
        QString m_description;
        QString m_developerName;
        QStringList m_extends;
        QString m_icon;
        QUrl m_iconUrl;
        QString m_id;
        Component::Kind m_kind;
        QString m_name;
        QString m_packageName;
        QString m_projectGroup;
        QString m_projectLicense;
        QString m_summary;
        QMultiHash<Component::UrlKind, QUrl> m_urls;
        QList<Asmara::ScreenShot> m_screenshots;
        bool operator==(const ComponentData& other) const {
            if(m_categories != other.m_categories) {
                return false;
            }
            if(m_compulsoryForDesktops != other.m_compulsoryForDesktops) {
                return false;
            }
            if(m_description != other.m_description) {
                return false;
            }
            if(m_developerName != other.m_developerName) {
                return false;
            }
            if(m_extends != other.m_extends) {
                return false;
            }
            if(m_icon != other.m_icon) {
                return false;
            }
            if(m_iconUrl != other.m_iconUrl) {
                return false;
            }
            if(m_id != other.m_id) {
                return false;
            }
            if(m_kind != other.m_kind) {
                return false;
            }
            if(m_name != other.m_name) {
                return false;
            }
            if(m_packageName != other.m_packageName) {
                return false;
            }
            if(m_projectGroup != other.m_projectGroup) {
                return false;
            }
            if(m_projectLicense != other.m_projectLicense) {
                return false;
            }
            if(m_summary != other.m_summary) {
                return false;
            }
            if(m_urls != other.m_urls) {
                return false;
            }
            if(m_screenshots != other.m_screenshots) {
                return false;
            }
            return true;
        }
};

const QStringList& Component::categories() const {
    return d->m_categories;
}

const QStringList& Component::compulsoryForDesktops() const {
    return d->m_compulsoryForDesktops;
}

const QString& Component::description() const {
    return d->m_description;
}

const QString& Component::developerName() const {
    return d->m_developerName;
}

const QStringList& Component::extends() const {
    return d->m_extends;
}

bool Component::hasCategory(const QString& category) const {
    return d->m_categories.contains(category);
}

const QString& Component::icon() const {
    return d->m_icon;
}

const QUrl& Component::iconUrl() const {
    return d->m_iconUrl;
}

const QString& Component::id() const {
    return d->m_id;
}

bool Component::isCompulsoryForDesktop(const QString& desktop) const {
    return d->m_compulsoryForDesktops.contains(desktop);
}

Component::Kind Component::kind() const {
    return d->m_kind;
}

const QString& Component::name() const {
    return d->m_name;
}

const QString& Component::packageName() const {
    return d->m_packageName;
}

const QString& Component::projectGroup() const {
    return d->m_projectGroup;
}

const QString& Component::projectLicense() const {
    return d->m_projectLicense;
}

void Component::setCategories(const QStringList& categories) {
    d->m_categories = categories;
}

void Component::setCompulsoryForDesktops(const QStringList& desktops) {
    d->m_compulsoryForDesktops = desktops;
}

void Component::setDescription(const QString& description) {
    d->m_description = description;
}

void Component::setDeveloperName(const QString& developerName) {
    d->m_developerName = developerName;
}

void Component::setIcon(const QString& icon) {
    d->m_icon = icon;
}

void Component::setIconUrl(const QUrl& iconUrl) {
    d->m_iconUrl = iconUrl;
}

void Component::setId(QString id) {
    d->m_id = id;
}

void Component::setKind(Component::Kind kind) {
    d->m_kind = kind;
}

void Component::setName(const QString& name) {
    d->m_name = name;
}

void Component::setPackageName(const QString& packageName) {
    d->m_packageName = packageName;
}

void Component::setProjectGroup(const QString& group) {
    d->m_projectGroup = group;
}

void Component::setProjectLicense(const QString& license){
    d->m_projectLicense = license;
}

void Component::setSummary(const QString& summary){
    d->m_summary = summary;
}

const QString& Component::summary() const {
    return d->m_summary;
}

Component::Component(const Component& other) : d(other.d) {

}

Component::Component() : d(new ComponentData) {

}

Component& Component::operator=(const Component& other) {
    this->d = other.d;
    return *this;
}

void Component::setUrls(const QMultiHash< Component::UrlKind, QUrl >& urls) {
    d->m_urls = urls;
}
QList< QUrl > Component::urls(Component::UrlKind kind) const {
    return d->m_urls.values(kind);
}

const QMultiHash< Component::UrlKind, QUrl >& Component::urls() const {
    return d->m_urls;
}

bool Component::operator==(const Component& other) {
    if(this->d == other.d) {
        return true;
    }
    if(this->d && other.d) {
        return *(this->d) == *other.d;
    }
    return false;
}

Component::~Component() {

}

QHash<Component::Kind, QString> buildKindMap() {
    QHash<Component::Kind,QString> map;
    map.insert(Component::KindAddon, QLatin1String("addon"));
    map.insert(Component::KindCodec, QLatin1String("codec"));
    map.insert(Component::KindDesktop, QLatin1String("desktop"));
    map.insert(Component::KindFont, QLatin1String("font"));
    map.insert(Component::KindGeneric, QLatin1String("generic"));
    map.insert(Component::KindInputmethod, QLatin1String("inputmethod"));
    map.insert(Component::KindUnknown, QLatin1String("unknown"));
    return map;
}

QString Component::kindToString(Component::Kind kind) {
    static QHash<Kind, QString> kindMap = buildKindMap();
    return kindMap.value(kind);
}

Component::Kind Component::stringToKind(const QString& kindString) {
    if(kindString ==  QLatin1String("generic")) {
        return KindGeneric;
    }
    if (kindString == QLatin1String("desktop")) {
        return KindDesktop;
    }
    if (kindString == QLatin1String("font")) {
        return KindFont;
    }
    if (kindString == QLatin1String("codec")) {
        return KindCodec;
    }
    if (kindString==QLatin1String("inputmethod")) {
        return KindInputmethod;
    }
    if (kindString == QLatin1String("addon")) {
        return KindAddon;
    }
    return KindUnknown;

}

void Component::setScreenShots(const QList< ScreenShot >& screenshots) {
    d->m_screenshots = screenshots;
}

const QList< ScreenShot >& Component::screenShots() const {
    return d->m_screenshots;
}

Component::UrlKind Component::stringToUrlKind(const QString& urlKindString) {
    if (urlKindString == QLatin1String("homepage")) {
        return UrlKindHomepage;
    }
    if (urlKindString == QLatin1String("bugtracker")) {
        return UrlKindBugtracker;
    }
    if (urlKindString == QLatin1String("faq")) {
        return UrlKindFaq;
    }
    if (urlKindString == QLatin1String("help")) {
        return UrlKindHelp;
    }
    if (urlKindString == QLatin1String("donation")) {
        return UrlKindDonation;
    }
    return UrlKindUnknown;
}

static QHash<Component::UrlKind,QString> buildUrlKindMap() {
    QHash<Component::UrlKind, QString> map;
    map.insert(Component::UrlKindBugtracker,QLatin1String("bugtracker"));
    map.insert(Component::UrlKindDonation,QLatin1String("donation"));
    map.insert(Component::UrlKindFaq,QLatin1String("faq"));
    map.insert(Component::UrlKindHelp,QLatin1String("help"));
    map.insert(Component::UrlKindHomepage, QLatin1String("homepage"));
    map.insert(Component::UrlKindUnknown, QLatin1String("unknown"));
    return map;
}

QString Component::urlKindToString(Component::UrlKind kind) {
    static const QHash<UrlKind, QString> kindMap = buildUrlKindMap();
    return kindMap.value(kind);
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016-2017 Pelagicore AB
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 * For further information see LICENSE
 */

#include "configdefinition.h"

/**
 * Developers guide to adding a config item:
 *
 *   * Add a definition of the string used as key
 *
 *   * If the config will be possible to set with a command line option, also add
 *     an "intial value" set to something which is possible to use for testing if
 *     the user set it, i.e. an "impossible" value.
 *
 *   * Add an entry for the config to the CONFIGS data
 */

namespace softwarecontainer {

typedef std::vector<std::tuple<std::string, std::string, ConfigType, MandatoryFlag>> ConfigItems;

const MandatoryFlag Mandatory = true;
const MandatoryFlag Optional = false;

const int ITEM_INDEX_GROUP = 0;
const int ITEM_INDEX_KEY = 1;
const int ITEM_INDEX_TYPE = 2;
const int ITEM_INDEX_MANDATORY = 3;

// Illegal values used as initial command line option values to check if user
// set them or not
const std::string ConfigDefinition::SC_CONFIG_PATH_INITIAL_VALUE = "";
const int ConfigDefinition::SHUTDOWN_TIMEOUT_INITIAL_VALUE = -2;
const std::string ConfigDefinition::SERVICE_MANIFEST_DIR_INITIAL_VALUE = "";
const std::string ConfigDefinition::DEFAULT_SERVICE_MANIFEST_DIR_INITIAL_VALUE = "";
const bool ConfigDefinition::USE_SESSION_BUS_INITIAL_VALUE = false;

// Config group "SoftwareContainer"
const std::string ConfigDefinition::SC_GROUP = "SoftwareContainer";

// Config keys for SoftwareContainer group
const std::string ConfigDefinition::SC_USE_SESSION_BUS_KEY = "session-bus";
const std::string ConfigDefinition::SC_SHUTDOWN_TIMEOUT_KEY = "shutdown-timeout";
const std::string ConfigDefinition::SC_SHARED_MOUNTS_DIR_KEY = "shared-mounts-dir";
const std::string ConfigDefinition::SC_LXC_CONFIG_PATH_KEY = "deprecated-lxc-config-path";
const std::string ConfigDefinition::SC_SERVICE_MANIFEST_DIR_KEY = "service-manifest-dir";
const std::string ConfigDefinition::SC_DEFAULT_SERVICE_MANIFEST_DIR_KEY = "default-service-manifest-dir";

#ifdef ENABLE_NETWORKGATEWAY
const std::string ConfigDefinition::SC_CREATE_BRIDGE_KEY = "create-bridge";
const std::string ConfigDefinition::SC_BRIDGE_DEVICE_KEY = "bridge-device";
const std::string ConfigDefinition::SC_BRIDGE_IP_KEY = "bridge-ip";
const std::string ConfigDefinition::SC_BRIDGE_NETADDR_KEY = "bridge-netaddr";
const std::string ConfigDefinition::SC_BRIDGE_NETMASK_KEY = "bridge-netmask";
const std::string ConfigDefinition::SC_BRIDGE_NETMASK_BITLENGTH_KEY = "bridge-netmask-bitlength";
#endif

/*
 * Used to create a mapping between group-key pairs and a type, as well as defining what configs
 * are mandatory.
 *
 * Configs that might be mandatory, i.e. that fact is decided externally by CMake, need to be added
 * with the definition and not the 'Optional' or 'Mandatory' flags directly.
 */
const ConfigItems CONFIGS
{
#ifdef ENABLE_NETWORKGATEWAY
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_CREATE_BRIDGE_KEY,
                    ConfigType::Boolean,
                    ConfigDefinition::convertDefineToFlag(
                        SC_CREATE_BRIDGE_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_DEVICE_KEY,
                    ConfigType::String,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_DEVICE_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_IP_KEY,
                    ConfigType::String,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_IP_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_NETMASK_BITLENGTH_KEY,
                    ConfigType::Integer,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_NETMASK_BITLENGTH_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_NETMASK_KEY,
                    ConfigType::String,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_NETMASK_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_NETADDR_KEY,
                    ConfigType::String,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_NETADDR_MANDATORY_FLAG /* set by cmake */)),
#endif // ENABLE_NETWORKGATEWAY
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_USE_SESSION_BUS_KEY,
                    ConfigType::Boolean,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_SHUTDOWN_TIMEOUT_KEY,
                    ConfigType::Integer,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_SHARED_MOUNTS_DIR_KEY,
                    ConfigType::String,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_LXC_CONFIG_PATH_KEY,
                    ConfigType::String,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_SERVICE_MANIFEST_DIR_KEY,
                    ConfigType::String,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_DEFAULT_SERVICE_MANIFEST_DIR_KEY,
                    ConfigType::String,
                    Optional)
};

MandatoryFlag ConfigDefinition::convertDefineToFlag(bool defined)
{
    return defined ? Mandatory : Optional;
}

MandatoryConfigs ConfigDefinition::mandatory()
{
    MandatoryConfigs mandatoryConfigs = MandatoryConfigs();

    for (auto config : CONFIGS) {
        std::string group = std::get<ITEM_INDEX_GROUP>(config);
        std::string key = std::get<ITEM_INDEX_KEY>(config);
        MandatoryFlag mandatoryFlag = std::get<ITEM_INDEX_MANDATORY>(config);

        if (Mandatory == mandatoryFlag) {
            mandatoryConfigs.push_back(UniqueKey(group, key));
        }
    }

    return mandatoryConfigs;
}

TypeMap ConfigDefinition::typeMap()
{
    TypeMap typeMap = TypeMap();

    for (auto config : CONFIGS) {
        std::string group = std::get<ITEM_INDEX_GROUP>(config);
        std::string key = std::get<ITEM_INDEX_KEY>(config);
        ConfigType configType = std::get<ITEM_INDEX_TYPE>(config);

        typeMap[UniqueKey(group, key)] = configType;
    }

    return typeMap;
}

} // namespace softwarecontainer
<commit_msg>configdefinition: name change to match conf file<commit_after>/*
 * Copyright (C) 2016-2017 Pelagicore AB
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 * For further information see LICENSE
 */

#include "configdefinition.h"

/**
 * Developers guide to adding a config item:
 *
 *   * Add a definition of the string used as key
 *
 *   * If the config will be possible to set with a command line option, also add
 *     an "intial value" set to something which is possible to use for testing if
 *     the user set it, i.e. an "impossible" value.
 *
 *   * Add an entry for the config to the CONFIGS data
 */

namespace softwarecontainer {

typedef std::vector<std::tuple<std::string, std::string, ConfigType, MandatoryFlag>> ConfigItems;

const MandatoryFlag Mandatory = true;
const MandatoryFlag Optional = false;

const int ITEM_INDEX_GROUP = 0;
const int ITEM_INDEX_KEY = 1;
const int ITEM_INDEX_TYPE = 2;
const int ITEM_INDEX_MANDATORY = 3;

// Illegal values used as initial command line option values to check if user
// set them or not
const std::string ConfigDefinition::SC_CONFIG_PATH_INITIAL_VALUE = "";
const int ConfigDefinition::SHUTDOWN_TIMEOUT_INITIAL_VALUE = -2;
const std::string ConfigDefinition::SERVICE_MANIFEST_DIR_INITIAL_VALUE = "";
const std::string ConfigDefinition::DEFAULT_SERVICE_MANIFEST_DIR_INITIAL_VALUE = "";
const bool ConfigDefinition::USE_SESSION_BUS_INITIAL_VALUE = false;

// Config group "SoftwareContainer"
const std::string ConfigDefinition::SC_GROUP = "SoftwareContainer";

// Config keys for SoftwareContainer group
const std::string ConfigDefinition::SC_USE_SESSION_BUS_KEY = "use-session-bus";
const std::string ConfigDefinition::SC_SHUTDOWN_TIMEOUT_KEY = "shutdown-timeout";
const std::string ConfigDefinition::SC_SHARED_MOUNTS_DIR_KEY = "shared-mounts-dir";
const std::string ConfigDefinition::SC_LXC_CONFIG_PATH_KEY = "deprecated-lxc-config-path";
const std::string ConfigDefinition::SC_SERVICE_MANIFEST_DIR_KEY = "service-manifest-dir";
const std::string ConfigDefinition::SC_DEFAULT_SERVICE_MANIFEST_DIR_KEY = "default-service-manifest-dir";

#ifdef ENABLE_NETWORKGATEWAY
const std::string ConfigDefinition::SC_CREATE_BRIDGE_KEY = "create-bridge";
const std::string ConfigDefinition::SC_BRIDGE_DEVICE_KEY = "bridge-device";
const std::string ConfigDefinition::SC_BRIDGE_IP_KEY = "bridge-ip";
const std::string ConfigDefinition::SC_BRIDGE_NETADDR_KEY = "bridge-netaddr";
const std::string ConfigDefinition::SC_BRIDGE_NETMASK_KEY = "bridge-netmask";
const std::string ConfigDefinition::SC_BRIDGE_NETMASK_BITLENGTH_KEY = "bridge-netmask-bitlength";
#endif

/*
 * Used to create a mapping between group-key pairs and a type, as well as defining what configs
 * are mandatory.
 *
 * Configs that might be mandatory, i.e. that fact is decided externally by CMake, need to be added
 * with the definition and not the 'Optional' or 'Mandatory' flags directly.
 */
const ConfigItems CONFIGS
{
#ifdef ENABLE_NETWORKGATEWAY
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_CREATE_BRIDGE_KEY,
                    ConfigType::Boolean,
                    ConfigDefinition::convertDefineToFlag(
                        SC_CREATE_BRIDGE_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_DEVICE_KEY,
                    ConfigType::String,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_DEVICE_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_IP_KEY,
                    ConfigType::String,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_IP_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_NETMASK_BITLENGTH_KEY,
                    ConfigType::Integer,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_NETMASK_BITLENGTH_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_NETMASK_KEY,
                    ConfigType::String,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_NETMASK_MANDATORY_FLAG /* set by cmake */)),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_BRIDGE_NETADDR_KEY,
                    ConfigType::String,
                    ConfigDefinition::convertDefineToFlag(
                        SC_BRIDGE_NETADDR_MANDATORY_FLAG /* set by cmake */)),
#endif // ENABLE_NETWORKGATEWAY
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_USE_SESSION_BUS_KEY,
                    ConfigType::Boolean,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_SHUTDOWN_TIMEOUT_KEY,
                    ConfigType::Integer,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_SHARED_MOUNTS_DIR_KEY,
                    ConfigType::String,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_LXC_CONFIG_PATH_KEY,
                    ConfigType::String,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_SERVICE_MANIFEST_DIR_KEY,
                    ConfigType::String,
                    Optional),
    std::make_tuple(ConfigDefinition::SC_GROUP,
                    ConfigDefinition::SC_DEFAULT_SERVICE_MANIFEST_DIR_KEY,
                    ConfigType::String,
                    Optional)
};

MandatoryFlag ConfigDefinition::convertDefineToFlag(bool defined)
{
    return defined ? Mandatory : Optional;
}

MandatoryConfigs ConfigDefinition::mandatory()
{
    MandatoryConfigs mandatoryConfigs = MandatoryConfigs();

    for (auto config : CONFIGS) {
        std::string group = std::get<ITEM_INDEX_GROUP>(config);
        std::string key = std::get<ITEM_INDEX_KEY>(config);
        MandatoryFlag mandatoryFlag = std::get<ITEM_INDEX_MANDATORY>(config);

        if (Mandatory == mandatoryFlag) {
            mandatoryConfigs.push_back(UniqueKey(group, key));
        }
    }

    return mandatoryConfigs;
}

TypeMap ConfigDefinition::typeMap()
{
    TypeMap typeMap = TypeMap();

    for (auto config : CONFIGS) {
        std::string group = std::get<ITEM_INDEX_GROUP>(config);
        std::string key = std::get<ITEM_INDEX_KEY>(config);
        ConfigType configType = std::get<ITEM_INDEX_TYPE>(config);

        typeMap[UniqueKey(group, key)] = configType;
    }

    return typeMap;
}

} // namespace softwarecontainer
<|endoftext|>


<commit_before>#include <stdexcept>
#include <utility>
#include "test_tool.hpp"

namespace test_tool
{
    emulator::emulator(question_data const& question)
        : question_(question.clone())
    {
    }

    auto emulator::start(answer_type const& answer) -> return_type
    {
        auto const emulated = emulate_movement(answer);
        auto const cost     = count_cost(answer);
        auto const correct  = count_correct(emulated);

        std::cerr << "correct: " << correct << std::endl;

        return return_type{
            cost,
            question_.size.first * question_.size.second - correct
        };
    }

    point_type emulator::target_point(char const identifier, point_type const& reference) const
    {
        switch (identifier) {
            case 'U':
                return {reference.x, reference.y - 1};
            case 'D':
                return {reference.x, reference.y + 1};
            case 'L':
                return {reference.x - 1, reference.y};
            case 'R':
                return {reference.x + 1, reference.y};
        }
        throw std::runtime_error("emulator::target_point: Undefined identifier");
    }

    auto emulator::emulate_movement(answer_type const& answer) -> locate_type
    {
        locate_type state = question_.block;
        point_type selected{-1, -1};

        for(auto const& select : answer.list)
        {
            selected = select.position;
            std::cerr << (boost::format("selecting (%d,%d)") % selected.x % selected.y).str() << std::endl;
            for(const char action : select.actions)
            {
#ifdef _DEBUG
                // debug
                std::cerr << "Current state:" << std::endl;
                for(auto a : state) {
                    for(point_type p : a) {
                        std::cerr << "(" << p.x << "," << p.y << ") ";
                    }
                    std::cerr << std::endl;
                }
#endif

                // 移動先を見つけて交換(std::vectorからあふれた時はatが例外を送出する)
                auto const target = target_point(action, selected);
#ifdef _DEBUG
                std::cerr << (boost::format("%c: moving from (%d,%d) to (%d,%d)") % action % selected.x % selected.y % target.x % target.y).str() << std::endl;
#endif
                std::swap(
                    state.at(selected.y).at(selected.x),
                    state.at(target  .y).at(target  .x)
                    );

                // 更新
                selected = target;
            }
        }

        return state;
    }

    int emulator::count_cost(answer_type const& answer)
    {
        int cost = 0;

        for(auto const& select : answer.list)
        {
            cost += question_.cost_select;
            for(char const action : select.actions)
            {
                cost += question_.cost_change;
            }
        }

        return cost;
    }

    int emulator::count_correct(locate_type const& locate)
    {
        int correct = 0;
        for(int i = 0; i < locate.size(); ++i)
        {
            for(int j = 0; j < locate.at(i).size(); ++j)
            {
                if(locate.at(i).at(j) == point_type{j, i}) ++correct;
            }
        }
        return correct;
    }

} // namespace test_tool

<commit_msg>releaseで出力が消しきれてなかった<commit_after>#include <stdexcept>
#include <utility>
#include "test_tool.hpp"

namespace test_tool
{
    emulator::emulator(question_data const& question)
        : question_(question.clone())
    {
    }

    auto emulator::start(answer_type const& answer) -> return_type
    {
        auto const emulated = emulate_movement(answer);
        auto const cost     = count_cost(answer);
        auto const correct  = count_correct(emulated);

        std::cerr << "correct: " << correct << std::endl;

        return return_type{
            cost,
            question_.size.first * question_.size.second - correct
        };
    }

    point_type emulator::target_point(char const identifier, point_type const& reference) const
    {
        switch (identifier) {
            case 'U':
                return {reference.x, reference.y - 1};
            case 'D':
                return {reference.x, reference.y + 1};
            case 'L':
                return {reference.x - 1, reference.y};
            case 'R':
                return {reference.x + 1, reference.y};
        }
        throw std::runtime_error("emulator::target_point: Undefined identifier");
    }

    auto emulator::emulate_movement(answer_type const& answer) -> locate_type
    {
        locate_type state = question_.block;
        point_type selected{-1, -1};

        for(auto const& select : answer.list)
        {
            selected = select.position;
#ifdef _DEBUG
            std::cerr << (boost::format("selecting (%d,%d)") % selected.x % selected.y).str() << std::endl;
#endif
            for(const char action : select.actions)
            {
#ifdef _DEBUG
                // debug
                std::cerr << "Current state:" << std::endl;
                for(auto a : state) {
                    for(point_type p : a) {
                        std::cerr << "(" << p.x << "," << p.y << ") ";
                    }
                    std::cerr << std::endl;
                }
#endif

                // 移動先を見つけて交換(std::vectorからあふれた時はatが例外を送出する)
                auto const target = target_point(action, selected);
#ifdef _DEBUG
                std::cerr << (boost::format("%c: moving from (%d,%d) to (%d,%d)") % action % selected.x % selected.y % target.x % target.y).str() << std::endl;
#endif
                std::swap(
                    state.at(selected.y).at(selected.x),
                    state.at(target  .y).at(target  .x)
                    );

                // 更新
                selected = target;
            }
        }

        return state;
    }

    int emulator::count_cost(answer_type const& answer)
    {
        int cost = 0;

        for(auto const& select : answer.list)
        {
            cost += question_.cost_select;
            for(char const action : select.actions)
            {
                cost += question_.cost_change;
            }
        }

        return cost;
    }

    int emulator::count_correct(locate_type const& locate)
    {
        int correct = 0;
        for(int i = 0; i < locate.size(); ++i)
        {
            for(int j = 0; j < locate.at(i).size(); ++j)
            {
                if(locate.at(i).at(j) == point_type{j, i}) ++correct;
            }
        }
        return correct;
    }

} // namespace test_tool

<|endoftext|>


<commit_before>//===--- ClangdMain.cpp - clangd server loop ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "ClangdLSPServer.h"
#include "JSONRPCDispatcher.h"
#include "Path.h"
#include "Trace.h"
#include "index/SymbolYAML.h"
#include "index/dex/DexIndex.h"
#include "clang/Basic/Version.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <thread>

using namespace clang;
using namespace clang::clangd;

namespace {

enum class PCHStorageFlag { Disk, Memory };

// Build an in-memory static index for global symbols from a YAML-format file.
// The size of global symbols should be relatively small, so that all symbols
// can be managed in memory.
std::unique_ptr<SymbolIndex> buildStaticIndex(llvm::StringRef YamlSymbolFile) {
  auto Buffer = llvm::MemoryBuffer::getFile(YamlSymbolFile);
  if (!Buffer) {
    llvm::errs() << "Can't open " << YamlSymbolFile << "\n";
    return nullptr;
  }
  auto Slab = symbolsFromYAML(Buffer.get()->getBuffer());
  SymbolSlab::Builder SymsBuilder;
  for (auto Sym : Slab)
    SymsBuilder.insert(Sym);

  return UseDex ? DexIndex::build(std::move(SymsBuilder).build())
                : MemIndex::build(std::move(SymsBuilder).build());
}

} // namespace

static llvm::cl::opt<Path> CompileCommandsDir(
    "compile-commands-dir",
    llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
                   "is invalid, clangd will look in the current directory and "
                   "parent paths of each source file."));

static llvm::cl::opt<unsigned>
    WorkerThreadsCount("j",
                       llvm::cl::desc("Number of async workers used by clangd"),
                       llvm::cl::init(getDefaultAsyncThreadsCount()));

// FIXME: also support "plain" style where signatures are always omitted.
enum CompletionStyleFlag {
  Detailed,
  Bundled,
};
static llvm::cl::opt<CompletionStyleFlag> CompletionStyle(
    "completion-style",
    llvm::cl::desc("Granularity of code completion suggestions"),
    llvm::cl::values(
        clEnumValN(Detailed, "detailed",
                   "One completion item for each semantically distinct "
                   "completion, with full type information."),
        clEnumValN(Bundled, "bundled",
                   "Similar completion items (e.g. function overloads) are "
                   "combined. Type information shown where possible.")),
    llvm::cl::init(Detailed));

// FIXME: Flags are the wrong mechanism for user preferences.
// We should probably read a dotfile or similar.
static llvm::cl::opt<bool> IncludeIneligibleResults(
    "include-ineligible-results",
    llvm::cl::desc(
        "Include ineligible completion results (e.g. private members)"),
    llvm::cl::init(clangd::CodeCompleteOptions().IncludeIneligibleResults),
    llvm::cl::Hidden);

static llvm::cl::opt<JSONStreamStyle> InputStyle(
    "input-style", llvm::cl::desc("Input JSON stream encoding"),
    llvm::cl::values(
        clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"),
        clEnumValN(JSONStreamStyle::Delimited, "delimited",
                   "messages delimited by --- lines, with # comment support")),
    llvm::cl::init(JSONStreamStyle::Standard));

static llvm::cl::opt<bool>
    PrettyPrint("pretty", llvm::cl::desc("Pretty-print JSON output"),
                llvm::cl::init(false));

static llvm::cl::opt<Logger::Level> LogLevel(
    "log", llvm::cl::desc("Verbosity of log messages written to stderr"),
    llvm::cl::values(clEnumValN(Logger::Error, "error", "Error messages only"),
                     clEnumValN(Logger::Info, "info",
                                "High level execution tracing"),
                     clEnumValN(Logger::Debug, "verbose", "Low level details")),
    llvm::cl::init(Logger::Info));

static llvm::cl::opt<bool> Test(
    "lit-test",
    llvm::cl::desc(
        "Abbreviation for -input-style=delimited -pretty -run-synchronously. "
        "Intended to simplify lit tests."),
    llvm::cl::init(false), llvm::cl::Hidden);

static llvm::cl::opt<PCHStorageFlag> PCHStorage(
    "pch-storage",
    llvm::cl::desc("Storing PCHs in memory increases memory usages, but may "
                   "improve performance"),
    llvm::cl::values(
        clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"),
        clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")),
    llvm::cl::init(PCHStorageFlag::Disk));

static llvm::cl::opt<int> LimitResults(
    "limit-results",
    llvm::cl::desc("Limit the number of results returned by clangd. "
                   "0 means no limit."),
    llvm::cl::init(100));

static llvm::cl::opt<bool> RunSynchronously(
    "run-synchronously",
    llvm::cl::desc("Parse on main thread. If set, -j is ignored"),
    llvm::cl::init(false), llvm::cl::Hidden);

static llvm::cl::opt<Path>
    ResourceDir("resource-dir",
                llvm::cl::desc("Directory for system clang headers"),
                llvm::cl::init(""), llvm::cl::Hidden);

static llvm::cl::opt<Path> InputMirrorFile(
    "input-mirror-file",
    llvm::cl::desc(
        "Mirror all LSP input to the specified file. Useful for debugging."),
    llvm::cl::init(""), llvm::cl::Hidden);

static llvm::cl::opt<bool> EnableIndex(
    "index",
    llvm::cl::desc("Enable index-based features such as global code completion "
                   "and searching for symbols. "
                   "Clang uses an index built from symbols in opened files"),
    llvm::cl::init(true));

static llvm::cl::opt<bool>
    ShowOrigins("debug-origin",
                llvm::cl::desc("Show origins of completion items"),
                llvm::cl::init(clangd::CodeCompleteOptions().ShowOrigins),
                llvm::cl::Hidden);

static llvm::cl::opt<bool> HeaderInsertionDecorators(
    "header-insertion-decorators",
    llvm::cl::desc("Prepend a circular dot or space before the completion "
                   "label, depending on whether "
                   "an include line will be inserted or not."),
    llvm::cl::init(true));

static llvm::cl::opt<Path> YamlSymbolFile(
    "yaml-symbol-file",
    llvm::cl::desc(
        "YAML-format global symbol file to build the static index. Clangd will "
        "use the static index for global code completion.\n"
        "WARNING: This option is experimental only, and will be removed "
        "eventually. Don't rely on it."),
    llvm::cl::init(""), llvm::cl::Hidden);

enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs };

static llvm::cl::opt<CompileArgsFrom> CompileArgsFrom(
    "compile_args_from", llvm::cl::desc("The source of compile commands"),
    llvm::cl::values(clEnumValN(LSPCompileArgs, "lsp",
                                "All compile commands come from LSP and "
                                "'compile_commands.json' files are ignored"),
                     clEnumValN(FilesystemCompileArgs, "filesystem",
                                "All compile commands come from the "
                                "'compile_commands.json' files")),
    llvm::cl::init(FilesystemCompileArgs), llvm::cl::Hidden);

static llvm::cl::opt<bool>
    UseDex("use-dex-index",
           llvm::cl::desc("Use experimental Dex static index."),
           llvm::cl::init(false), llvm::cl::Hidden);

int main(int argc, char *argv[]) {
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
    OS << clang::getClangToolFullVersion("clangd") << "\n";
  });
  llvm::cl::ParseCommandLineOptions(
      argc, argv,
      "clangd is a language server that provides IDE-like features to editors. "
      "\n\nIt should be used via an editor plugin rather than invoked directly."
      "For more information, see:"
      "\n\thttps://clang.llvm.org/extra/clangd.html"
      "\n\thttps://microsoft.github.io/language-server-protocol/");
  if (Test) {
    RunSynchronously = true;
    InputStyle = JSONStreamStyle::Delimited;
    PrettyPrint = true;
  }

  if (!RunSynchronously && WorkerThreadsCount == 0) {
    llvm::errs() << "A number of worker threads cannot be 0. Did you mean to "
                    "specify -run-synchronously?";
    return 1;
  }

  if (RunSynchronously) {
    if (WorkerThreadsCount.getNumOccurrences())
      llvm::errs() << "Ignoring -j because -run-synchronously is set.\n";
    WorkerThreadsCount = 0;
  }

  // Validate command line arguments.
  llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
  if (!InputMirrorFile.empty()) {
    std::error_code EC;
    InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC,
                              llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
    if (EC) {
      InputMirrorStream.reset();
      llvm::errs() << "Error while opening an input mirror file: "
                   << EC.message();
    }
  }

  // Setup tracing facilities if CLANGD_TRACE is set. In practice enabling a
  // trace flag in your editor's config is annoying, launching with
  // `CLANGD_TRACE=trace.json vim` is easier.
  llvm::Optional<llvm::raw_fd_ostream> TraceStream;
  std::unique_ptr<trace::EventTracer> Tracer;
  if (auto *TraceFile = getenv("CLANGD_TRACE")) {
    std::error_code EC;
    TraceStream.emplace(TraceFile, /*ref*/ EC,
                        llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
    if (EC) {
      TraceStream.reset();
      llvm::errs() << "Error while opening trace file " << TraceFile << ": "
                   << EC.message();
    } else {
      Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
    }
  }

  llvm::Optional<trace::Session> TracingSession;
  if (Tracer)
    TracingSession.emplace(*Tracer);

  JSONOutput Out(llvm::outs(), llvm::errs(), LogLevel,
                 InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
                 PrettyPrint);

  clangd::LoggingSession LoggingSession(Out);

  // If --compile-commands-dir arg was invoked, check value and override default
  // path.
  llvm::Optional<Path> CompileCommandsDirPath;
  if (CompileCommandsDir.empty()) {
    CompileCommandsDirPath = llvm::None;
  } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) ||
             !llvm::sys::fs::exists(CompileCommandsDir)) {
    llvm::errs() << "Path specified by --compile-commands-dir either does not "
                    "exist or is not an absolute "
                    "path. The argument will be ignored.\n";
    CompileCommandsDirPath = llvm::None;
  } else {
    CompileCommandsDirPath = CompileCommandsDir;
  }

  ClangdServer::Options Opts;
  switch (PCHStorage) {
  case PCHStorageFlag::Memory:
    Opts.StorePreamblesInMemory = true;
    break;
  case PCHStorageFlag::Disk:
    Opts.StorePreamblesInMemory = false;
    break;
  }
  if (!ResourceDir.empty())
    Opts.ResourceDir = ResourceDir;
  Opts.BuildDynamicSymbolIndex = EnableIndex;
  std::unique_ptr<SymbolIndex> StaticIdx;
  if (EnableIndex && !YamlSymbolFile.empty()) {
    StaticIdx = buildStaticIndex(YamlSymbolFile);
    Opts.StaticIndex = StaticIdx.get();
  }
  Opts.AsyncThreadsCount = WorkerThreadsCount;

  clangd::CodeCompleteOptions CCOpts;
  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
  CCOpts.Limit = LimitResults;
  CCOpts.BundleOverloads = CompletionStyle != Detailed;
  CCOpts.ShowOrigins = ShowOrigins;
  if (!HeaderInsertionDecorators) {
    CCOpts.IncludeIndicator.Insert.clear();
    CCOpts.IncludeIndicator.NoInsert.clear();
  }

  // Initialize and run ClangdLSPServer.
  ClangdLSPServer LSPServer(
      Out, CCOpts, CompileCommandsDirPath,
      /*ShouldUseInMemoryCDB=*/CompileArgsFrom == LSPCompileArgs, Opts);
  constexpr int NoShutdownRequestErrorCode = 1;
  llvm::set_thread_name("clangd.main");
  // Change stdin to binary to not lose \r\n on windows.
  llvm::sys::ChangeStdinToBinary();
  return LSPServer.run(stdin, InputStyle) ? 0 : NoShutdownRequestErrorCode;
}
<commit_msg>[clangd] NFC: Fix broken build<commit_after>//===--- ClangdMain.cpp - clangd server loop ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "ClangdLSPServer.h"
#include "JSONRPCDispatcher.h"
#include "Path.h"
#include "Trace.h"
#include "index/SymbolYAML.h"
#include "index/dex/DexIndex.h"
#include "clang/Basic/Version.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <thread>

using namespace clang;
using namespace clang::clangd;

static llvm::cl::opt<bool>
    UseDex("use-dex-index",
           llvm::cl::desc("Use experimental Dex static index."),
           llvm::cl::init(false), llvm::cl::Hidden);

namespace {

enum class PCHStorageFlag { Disk, Memory };

// Build an in-memory static index for global symbols from a YAML-format file.
// The size of global symbols should be relatively small, so that all symbols
// can be managed in memory.
std::unique_ptr<SymbolIndex> buildStaticIndex(llvm::StringRef YamlSymbolFile) {
  auto Buffer = llvm::MemoryBuffer::getFile(YamlSymbolFile);
  if (!Buffer) {
    llvm::errs() << "Can't open " << YamlSymbolFile << "\n";
    return nullptr;
  }
  auto Slab = symbolsFromYAML(Buffer.get()->getBuffer());
  SymbolSlab::Builder SymsBuilder;
  for (auto Sym : Slab)
    SymsBuilder.insert(Sym);

  return UseDex ? dex::DexIndex::build(std::move(SymsBuilder).build())
                : MemIndex::build(std::move(SymsBuilder).build());
}

} // namespace

static llvm::cl::opt<Path> CompileCommandsDir(
    "compile-commands-dir",
    llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
                   "is invalid, clangd will look in the current directory and "
                   "parent paths of each source file."));

static llvm::cl::opt<unsigned>
    WorkerThreadsCount("j",
                       llvm::cl::desc("Number of async workers used by clangd"),
                       llvm::cl::init(getDefaultAsyncThreadsCount()));

// FIXME: also support "plain" style where signatures are always omitted.
enum CompletionStyleFlag {
  Detailed,
  Bundled,
};
static llvm::cl::opt<CompletionStyleFlag> CompletionStyle(
    "completion-style",
    llvm::cl::desc("Granularity of code completion suggestions"),
    llvm::cl::values(
        clEnumValN(Detailed, "detailed",
                   "One completion item for each semantically distinct "
                   "completion, with full type information."),
        clEnumValN(Bundled, "bundled",
                   "Similar completion items (e.g. function overloads) are "
                   "combined. Type information shown where possible.")),
    llvm::cl::init(Detailed));

// FIXME: Flags are the wrong mechanism for user preferences.
// We should probably read a dotfile or similar.
static llvm::cl::opt<bool> IncludeIneligibleResults(
    "include-ineligible-results",
    llvm::cl::desc(
        "Include ineligible completion results (e.g. private members)"),
    llvm::cl::init(clangd::CodeCompleteOptions().IncludeIneligibleResults),
    llvm::cl::Hidden);

static llvm::cl::opt<JSONStreamStyle> InputStyle(
    "input-style", llvm::cl::desc("Input JSON stream encoding"),
    llvm::cl::values(
        clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"),
        clEnumValN(JSONStreamStyle::Delimited, "delimited",
                   "messages delimited by --- lines, with # comment support")),
    llvm::cl::init(JSONStreamStyle::Standard));

static llvm::cl::opt<bool>
    PrettyPrint("pretty", llvm::cl::desc("Pretty-print JSON output"),
                llvm::cl::init(false));

static llvm::cl::opt<Logger::Level> LogLevel(
    "log", llvm::cl::desc("Verbosity of log messages written to stderr"),
    llvm::cl::values(clEnumValN(Logger::Error, "error", "Error messages only"),
                     clEnumValN(Logger::Info, "info",
                                "High level execution tracing"),
                     clEnumValN(Logger::Debug, "verbose", "Low level details")),
    llvm::cl::init(Logger::Info));

static llvm::cl::opt<bool> Test(
    "lit-test",
    llvm::cl::desc(
        "Abbreviation for -input-style=delimited -pretty -run-synchronously. "
        "Intended to simplify lit tests."),
    llvm::cl::init(false), llvm::cl::Hidden);

static llvm::cl::opt<PCHStorageFlag> PCHStorage(
    "pch-storage",
    llvm::cl::desc("Storing PCHs in memory increases memory usages, but may "
                   "improve performance"),
    llvm::cl::values(
        clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"),
        clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")),
    llvm::cl::init(PCHStorageFlag::Disk));

static llvm::cl::opt<int> LimitResults(
    "limit-results",
    llvm::cl::desc("Limit the number of results returned by clangd. "
                   "0 means no limit."),
    llvm::cl::init(100));

static llvm::cl::opt<bool> RunSynchronously(
    "run-synchronously",
    llvm::cl::desc("Parse on main thread. If set, -j is ignored"),
    llvm::cl::init(false), llvm::cl::Hidden);

static llvm::cl::opt<Path>
    ResourceDir("resource-dir",
                llvm::cl::desc("Directory for system clang headers"),
                llvm::cl::init(""), llvm::cl::Hidden);

static llvm::cl::opt<Path> InputMirrorFile(
    "input-mirror-file",
    llvm::cl::desc(
        "Mirror all LSP input to the specified file. Useful for debugging."),
    llvm::cl::init(""), llvm::cl::Hidden);

static llvm::cl::opt<bool> EnableIndex(
    "index",
    llvm::cl::desc("Enable index-based features such as global code completion "
                   "and searching for symbols. "
                   "Clang uses an index built from symbols in opened files"),
    llvm::cl::init(true));

static llvm::cl::opt<bool>
    ShowOrigins("debug-origin",
                llvm::cl::desc("Show origins of completion items"),
                llvm::cl::init(clangd::CodeCompleteOptions().ShowOrigins),
                llvm::cl::Hidden);

static llvm::cl::opt<bool> HeaderInsertionDecorators(
    "header-insertion-decorators",
    llvm::cl::desc("Prepend a circular dot or space before the completion "
                   "label, depending on whether "
                   "an include line will be inserted or not."),
    llvm::cl::init(true));

static llvm::cl::opt<Path> YamlSymbolFile(
    "yaml-symbol-file",
    llvm::cl::desc(
        "YAML-format global symbol file to build the static index. Clangd will "
        "use the static index for global code completion.\n"
        "WARNING: This option is experimental only, and will be removed "
        "eventually. Don't rely on it."),
    llvm::cl::init(""), llvm::cl::Hidden);

enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs };

static llvm::cl::opt<CompileArgsFrom> CompileArgsFrom(
    "compile_args_from", llvm::cl::desc("The source of compile commands"),
    llvm::cl::values(clEnumValN(LSPCompileArgs, "lsp",
                                "All compile commands come from LSP and "
                                "'compile_commands.json' files are ignored"),
                     clEnumValN(FilesystemCompileArgs, "filesystem",
                                "All compile commands come from the "
                                "'compile_commands.json' files")),
    llvm::cl::init(FilesystemCompileArgs), llvm::cl::Hidden);

int main(int argc, char *argv[]) {
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
    OS << clang::getClangToolFullVersion("clangd") << "\n";
  });
  llvm::cl::ParseCommandLineOptions(
      argc, argv,
      "clangd is a language server that provides IDE-like features to editors. "
      "\n\nIt should be used via an editor plugin rather than invoked directly."
      "For more information, see:"
      "\n\thttps://clang.llvm.org/extra/clangd.html"
      "\n\thttps://microsoft.github.io/language-server-protocol/");
  if (Test) {
    RunSynchronously = true;
    InputStyle = JSONStreamStyle::Delimited;
    PrettyPrint = true;
  }

  if (!RunSynchronously && WorkerThreadsCount == 0) {
    llvm::errs() << "A number of worker threads cannot be 0. Did you mean to "
                    "specify -run-synchronously?";
    return 1;
  }

  if (RunSynchronously) {
    if (WorkerThreadsCount.getNumOccurrences())
      llvm::errs() << "Ignoring -j because -run-synchronously is set.\n";
    WorkerThreadsCount = 0;
  }

  // Validate command line arguments.
  llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
  if (!InputMirrorFile.empty()) {
    std::error_code EC;
    InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC,
                              llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
    if (EC) {
      InputMirrorStream.reset();
      llvm::errs() << "Error while opening an input mirror file: "
                   << EC.message();
    }
  }

  // Setup tracing facilities if CLANGD_TRACE is set. In practice enabling a
  // trace flag in your editor's config is annoying, launching with
  // `CLANGD_TRACE=trace.json vim` is easier.
  llvm::Optional<llvm::raw_fd_ostream> TraceStream;
  std::unique_ptr<trace::EventTracer> Tracer;
  if (auto *TraceFile = getenv("CLANGD_TRACE")) {
    std::error_code EC;
    TraceStream.emplace(TraceFile, /*ref*/ EC,
                        llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
    if (EC) {
      TraceStream.reset();
      llvm::errs() << "Error while opening trace file " << TraceFile << ": "
                   << EC.message();
    } else {
      Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
    }
  }

  llvm::Optional<trace::Session> TracingSession;
  if (Tracer)
    TracingSession.emplace(*Tracer);

  JSONOutput Out(llvm::outs(), llvm::errs(), LogLevel,
                 InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
                 PrettyPrint);

  clangd::LoggingSession LoggingSession(Out);

  // If --compile-commands-dir arg was invoked, check value and override default
  // path.
  llvm::Optional<Path> CompileCommandsDirPath;
  if (CompileCommandsDir.empty()) {
    CompileCommandsDirPath = llvm::None;
  } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) ||
             !llvm::sys::fs::exists(CompileCommandsDir)) {
    llvm::errs() << "Path specified by --compile-commands-dir either does not "
                    "exist or is not an absolute "
                    "path. The argument will be ignored.\n";
    CompileCommandsDirPath = llvm::None;
  } else {
    CompileCommandsDirPath = CompileCommandsDir;
  }

  ClangdServer::Options Opts;
  switch (PCHStorage) {
  case PCHStorageFlag::Memory:
    Opts.StorePreamblesInMemory = true;
    break;
  case PCHStorageFlag::Disk:
    Opts.StorePreamblesInMemory = false;
    break;
  }
  if (!ResourceDir.empty())
    Opts.ResourceDir = ResourceDir;
  Opts.BuildDynamicSymbolIndex = EnableIndex;
  std::unique_ptr<SymbolIndex> StaticIdx;
  if (EnableIndex && !YamlSymbolFile.empty()) {
    StaticIdx = buildStaticIndex(YamlSymbolFile);
    Opts.StaticIndex = StaticIdx.get();
  }
  Opts.AsyncThreadsCount = WorkerThreadsCount;

  clangd::CodeCompleteOptions CCOpts;
  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
  CCOpts.Limit = LimitResults;
  CCOpts.BundleOverloads = CompletionStyle != Detailed;
  CCOpts.ShowOrigins = ShowOrigins;
  if (!HeaderInsertionDecorators) {
    CCOpts.IncludeIndicator.Insert.clear();
    CCOpts.IncludeIndicator.NoInsert.clear();
  }

  // Initialize and run ClangdLSPServer.
  ClangdLSPServer LSPServer(
      Out, CCOpts, CompileCommandsDirPath,
      /*ShouldUseInMemoryCDB=*/CompileArgsFrom == LSPCompileArgs, Opts);
  constexpr int NoShutdownRequestErrorCode = 1;
  llvm::set_thread_name("clangd.main");
  // Change stdin to binary to not lose \r\n on windows.
  llvm::sys::ChangeStdinToBinary();
  return LSPServer.run(stdin, InputStyle) ? 0 : NoShutdownRequestErrorCode;
}
<|endoftext|>


<commit_before><commit_msg>Fix size of symchronization state message for tracked vehicles<commit_after><|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI Widget View クラス @n
			カスタム描画・テンプレート
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "gl_fw/glutils.hpp"
#include "widgets/widget_director.hpp"
#include "widgets/widget_frame.hpp"
#include "widgets/widget_utils.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	GUI widget_view クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct widget_view : public widget {

		typedef widget_view value_type;

		typedef std::function< void() > update_func_type;
		typedef std::function< void() > render_func_type;
		typedef std::function< void() > service_func_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_view パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {

			update_func_type	update_func_;
			render_func_type	render_func_;
			service_func_type	service_func_;

			param() { }
		};

	private:
		widget_director&	wd_;

		param				param_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_view(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		virtual ~widget_view() { }

		//-----------------------------------------------------------------//
		/*!
			@brief	型を取得
		*/
		//-----------------------------------------------------------------//
		type_id type() const override { return get_type_id<value_type>(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	widget 型の基本名称を取得
			@return widget 型の基本名称
		*/
		//-----------------------------------------------------------------//
		const char* type_name() const override { return "view"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ハイブリッド・ウィジェットのサイン
			@return ハイブリッド・ウィジェットの場合「true」を返す。
		*/
		//-----------------------------------------------------------------//
		bool hybrid() const override { return false; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得(ro)
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		const param& get_local_param() const { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		param& at_local_param() { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			// 標準的に固定
			at_param().state_.set(widget::state::POSITION_LOCK);
			at_param().state_.set(widget::state::SIZE_LOCK);
			at_param().state_.set(widget::state::MOVE_ROOT);
			at_param().state_.set(widget::state::AREA_ROOT);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(get_param().parents_ && get_state(widget::state::AREA_ROOT)) {
				if(get_param().parents_->type() == get_type_id<widget_frame>()) {
					widget_frame* w = static_cast<widget_frame*>(at_param().parents_);
					w->get_draw_area(at_rect());
				}
			}
			if(param_.update_func_ != nullptr) param_.update_func_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
			using namespace gl;
			core& core = core::get_instance();
			const vtx::spos& vsz = core.get_size();
			const vtx::spos& siz = core.get_rect().size;
			const widget::param& wp = get_param();

			glPushMatrix();

			int sx = vsz.x / siz.x;
			int sy = vsz.y / siz.y;
			glViewport(wp.clip_.org.x * sx, vsz.y - wp.clip_.org.y * sy - wp.clip_.size.y * sy,
				wp.clip_.size.x * sx, wp.clip_.size.y * sy);
			wd_.at_mobj().setup_matrix(wp.clip_.size.x, wp.clip_.size.y);

			if(param_.render_func_ != nullptr) param_.render_func_();

			glPopMatrix();
			glViewport(0, 0, vsz.x, vsz.y);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-----------------------------------------------------------------//
		void service() override
		{
			if(param_.service_func_ != nullptr) param_.service_func_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のセーブ
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool save(sys::preference& pre) override
		{
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override
		{
			return true;
		}
	};
}
<commit_msg>update render func<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI Widget View クラス @n
			カスタム描画・テンプレート
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "gl_fw/glutils.hpp"
#include "widgets/widget_director.hpp"
#include "widgets/widget_frame.hpp"
#include "widgets/widget_utils.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	GUI widget_view クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct widget_view : public widget {

		typedef widget_view value_type;

		typedef std::function< void() > update_func_type;
		typedef std::function< void(const vtx::spos& size) > render_func_type;
		typedef std::function< void() > service_func_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_view パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {

			update_func_type	update_func_;
			render_func_type	render_func_;
			service_func_type	service_func_;

			param() { }
		};

	private:
		widget_director&	wd_;

		param				param_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_view(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		virtual ~widget_view() { }

		//-----------------------------------------------------------------//
		/*!
			@brief	型を取得
		*/
		//-----------------------------------------------------------------//
		type_id type() const override { return get_type_id<value_type>(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	widget 型の基本名称を取得
			@return widget 型の基本名称
		*/
		//-----------------------------------------------------------------//
		const char* type_name() const override { return "view"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ハイブリッド・ウィジェットのサイン
			@return ハイブリッド・ウィジェットの場合「true」を返す。
		*/
		//-----------------------------------------------------------------//
		bool hybrid() const override { return false; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得(ro)
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		const param& get_local_param() const { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		param& at_local_param() { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			// 標準的に固定
			at_param().state_.set(widget::state::POSITION_LOCK);
			at_param().state_.set(widget::state::SIZE_LOCK);
			at_param().state_.set(widget::state::MOVE_ROOT);
			at_param().state_.set(widget::state::AREA_ROOT);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(get_param().parents_ && get_state(widget::state::AREA_ROOT)) {
				if(get_param().parents_->type() == get_type_id<widget_frame>()) {
					widget_frame* w = static_cast<widget_frame*>(at_param().parents_);
					w->get_draw_area(at_rect());
				}
			}
			if(param_.update_func_ != nullptr) param_.update_func_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
			using namespace gl;
			core& core = core::get_instance();
			const vtx::spos& vsz = core.get_size();
			const vtx::spos& siz = core.get_rect().size;
			const widget::param& wp = get_param();

			glPushMatrix();

			int sx = vsz.x / siz.x;
			int sy = vsz.y / siz.y;
			glViewport(wp.clip_.org.x * sx, vsz.y - wp.clip_.org.y * sy - wp.clip_.size.y * sy,
				wp.clip_.size.x * sx, wp.clip_.size.y * sy);
			wd_.at_mobj().setup_matrix(wp.clip_.size.x, wp.clip_.size.y);

			if(param_.render_func_ != nullptr) param_.render_func_(wp.clip_.size);

			glPopMatrix();
			glViewport(0, 0, vsz.x, vsz.y);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-----------------------------------------------------------------//
		void service() override
		{
			if(param_.service_func_ != nullptr) param_.service_func_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のセーブ
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool save(sys::preference& pre) override
		{
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override
		{
			return true;
		}
	};
}
<|endoftext|>


<commit_before>#ifndef INCLUDE_AL_BUFFER_HPP
#define INCLUDE_AL_BUFFER_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2012. The Regents of the University of California.
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

		Redistributions of source code must retain the above copyright notice,
		this list of conditions and the following disclaimer.

		Redistributions in binary form must reproduce the above copyright
		notice, this list of conditions and the following disclaimer in the
		documentation and/or other materials provided with the distribution.

		Neither the name of the University of California nor the names of its
		contributors may be used to endorse or promote products derived from
		this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.

	File description:
	Variably sized one-dimensional array

	File author(s):
	Lance Putnam, 2010, putnam.lance@gmail.com
*/

#include <algorithm>
#include <vector>

namespace al{

/// Buffer

/// This buffer automatically expands itself as new elements are added.
/// Additionally, its logical size can be reduced without triggering memory
/// deallocations.
template <class T, class Alloc=std::allocator<T> >
class Buffer : protected Alloc{
	typedef Alloc super;
public:

	/// @param[in] size			Initial size
	explicit Buffer(int size=0)
	:	mElems(size), mSize(size)
	{}

	/// @param[in] size			Initial size
	/// @param[in] capacity		Initial capacity
	Buffer(int size, int capacity)
	:	mElems(capacity), mSize(size)
	{}

	~Buffer(){}

	int capacity() const { return mElems.size(); }		///< Returns total capacity
	int size() const { return mSize; }					///< Returns size
	const T * elems() const { return &mElems[0]; }		///< Returns C pointer to elements
	T * elems(){ return &mElems[0]; }					///< Returns C pointer to elements

	/// Get element at index
	T& operator[](int i){ return mElems[i]; }

	/// Get element at index (read-only)
	const T& operator[](int i) const { return mElems[i]; }

	/// Assign value to elements

	/// This function fills a Buffer with n copies of the given value. Note that
	/// the assignment completely changes the buffer and that the resulting size
	/// is the same as the number of elements assigned. Old data may be lost.
	void assign(int n, const T& v){ mElems.assign(n,v); }

	/// Get last element
	T& last(){ return mElems[size()-1]; }
	const T& last() const { return mElems[size()-1]; }

	/// Resets size to zero without deallocating allocated memory
	void reset(){ mSize=0; }

	/// Resize buffer

	/// This will set both the size and capacity of the buffer to the requested
	/// size. If the number is smaller than the current size the buffer is
	/// truncated, otherwise the buffer is extended and new elements are
	/// default-constructed.
	void resize(int n){
		mElems.resize(n);
		setSize(n);
	}

	/// Set size of buffer

	/// If the requested size is larger than the current capacity, then the
	/// buffer will be resized.
	void size(int n){
		if(capacity() < n) resize(n);
		else setSize(n);
	}

	/// Appends element to end of buffer growing its size if necessary
	void append(const T& v, double growFactor=2){

		// Grow array if too small
		if(size() >= capacity()){
			// Copy argument since it may be an element in current memory range
			// which may become invalid after the resize.
			const T vsafecopy = v;
			mElems.resize((size() ? size() : 4)*growFactor);
			super::construct(elems()+size(), vsafecopy);
		}
		else{
			super::construct(elems()+size(), v);
		}
		++mSize;
	}
	/// synonym for append():
	void push_back(const T& v, double growFactor=2) { append(v, growFactor); }

	/// Append elements of another Buffer

	/// Note: not safe to apply this to itself
	///
	void append(const Buffer<T>& src){
		append(src.elems(), src.size());
	}

	/// Append elements of an array
	void append(const T * src, int len){
		int oldsize = size();
		size(size() + len);
		std::copy(src, src + len, mElems.begin() + oldsize);
	}

	/// Repeat last element
	void repeatLast(){ append(last()); }

	/// Insert new elements after each existing element

	/// @param[in] n	Expansion factor; new size is n times old size
	/// @param[in] dup	If true, new elements are duplicates of existing elements.
	///					If false, new elements are default constructed.
	template <int n, bool dup>
	void expand(){
		size(size()*n);
		const int Nd = dup ? n : 1;
		for(int i=size()/n-1; i>=0; --i){
			const T& v = (*this)[i];
			for(int j=0; j<Nd; ++j) Alloc::construct(elems()+n*i+j, v);
		}
	}

private:
	std::vector<T, Alloc> mElems;
	int mSize;		// logical size array

	void setSize(int n){ mSize=n; }
};

/// Ring buffer

/// This buffer allows potentially large amounts of data to be buffered without
/// moving memory. This is accomplished by use of a moving write tap.
template <class T, class Alloc=std::allocator<T> >
class RingBuffer : protected Alloc {
public:

	/// Default constructor; does not allocate memory
	RingBuffer(): mPos(-1){}

	/// @param[in] size		number of elements
	/// @param[in] v		value to initialize elements to
	explicit RingBuffer(unsigned size, const T& v=T()){
		resize(size,v);
	}

	/// Get number of elements
	int size() const { return mElems.size(); }

	/// Get absolute index of most recently written element
	int pos() const { return mPos; }

	/// Get element at absolute index
	T& operator[](int i){ return mElems[i]; }

	/// Get element at absolute index (read-only)
	const T& operator[](int i) const { return mElems[i]; }

	/// Write new element
	void write(const T& v){
		++mPos; if(pos() == size()){ mPos=0; }
		Alloc::construct(&mElems[0] + pos(), v);
	}

	/// Get reference to element relative to newest element
	T& read(int i){ return mElems[wrapOnce(pos()-i, size())]; }

	/// Get reference to element relative to newest element (read-only)
	const T& read(int i) const { return mElems[wrapOnce(pos()-i, size())]; }

	/// Resize buffer

	/// @param[in] n	number of elements
	/// @param[in] v	initialization value of newly allocated elements
	void resize(int n, const T& v=T()){
		mElems.resize(n,v);
		if(mPos >=n) mPos = n-1;
	}

protected:
	std::vector<T, Alloc> mElems;
	int mPos;

	// Moves value one period closer to interval [0, max)
	static int wrapOnce(int v, int max){
		if(v <  0)   return v+max;
		if(v >= max) return v-max;
		return v;
	}
};

/// Constant size shift buffer

/// This is a first-in, first-out buffer with a constant number of elements.
/// Adding new elements to the buffer physically moves existing elements. The
/// advantage of moving memory like this is that elements stay logically ordered
/// making access faster and operating on the history easier.
template <int N, class T>
class ShiftBuffer{
public:

	/// @param[in] v	Value to initialize all elements to
	ShiftBuffer(const T& v=T()){ assign(v); }

	/// Get number of elements
	static int size(){ return N; }

	/// Get pointer to elements (read-only)
	const T * elems() const { return &mElems[0]; }

	/// Get pointer to elements
	T * elems(){ return &mElems[0]; }

	/// Get reference to element at index
	T& operator[](int i){ return mElems[i];}

	/// Get reference to element at index (read-only)
	const T& operator[](int i) const { return mElems[i]; }

	/// Push new element onto buffer. Newest element is at index 0.
	void operator()(const T& v){
		for(int i=N-1; i>0; --i) mElems[i] = mElems[i-1];
		mElems[0]=v;
	}

	/// Set all elements to argument
	void assign(const T& v){ for(int i=0;i<N;++i) mElems[i]=v; }

	/// Zero bytes of all elements
	void zero(){ memset(mElems, 0, N * sizeof(T)); }

protected:
	T mElems[N];
};

} // al::

#endif
<commit_msg>Add newest and readFrom methods to RingBuffer<commit_after>#ifndef INCLUDE_AL_BUFFER_HPP
#define INCLUDE_AL_BUFFER_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2012. The Regents of the University of California.
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

		Redistributions of source code must retain the above copyright notice,
		this list of conditions and the following disclaimer.

		Redistributions in binary form must reproduce the above copyright
		notice, this list of conditions and the following disclaimer in the
		documentation and/or other materials provided with the distribution.

		Neither the name of the University of California nor the names of its
		contributors may be used to endorse or promote products derived from
		this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.

	File description:
	Variably sized one-dimensional array

	File author(s):
	Lance Putnam, 2010, putnam.lance@gmail.com
*/

#include <algorithm>
#include <vector>

namespace al{

/// Buffer

/// This buffer automatically expands itself as new elements are added.
/// Additionally, its logical size can be reduced without triggering memory
/// deallocations.
template <class T, class Alloc=std::allocator<T> >
class Buffer : protected Alloc{
	typedef Alloc super;
public:

	/// @param[in] size			Initial size
	explicit Buffer(int size=0)
	:	mElems(size), mSize(size)
	{}

	/// @param[in] size			Initial size
	/// @param[in] capacity		Initial capacity
	Buffer(int size, int capacity)
	:	mElems(capacity), mSize(size)
	{}

	~Buffer(){}

	int capacity() const { return mElems.size(); }		///< Returns total capacity
	int size() const { return mSize; }					///< Returns size
	const T * elems() const { return &mElems[0]; }		///< Returns C pointer to elements
	T * elems(){ return &mElems[0]; }					///< Returns C pointer to elements

	/// Get element at index
	T& operator[](int i){ return mElems[i]; }

	/// Get element at index (read-only)
	const T& operator[](int i) const { return mElems[i]; }

	/// Assign value to elements

	/// This function fills a Buffer with n copies of the given value. Note that
	/// the assignment completely changes the buffer and that the resulting size
	/// is the same as the number of elements assigned. Old data may be lost.
	void assign(int n, const T& v){ mElems.assign(n,v); }

	/// Get last element
	T& last(){ return mElems[size()-1]; }
	const T& last() const { return mElems[size()-1]; }

	/// Resets size to zero without deallocating allocated memory
	void reset(){ mSize=0; }

	/// Resize buffer

	/// This will set both the size and capacity of the buffer to the requested
	/// size. If the number is smaller than the current size the buffer is
	/// truncated, otherwise the buffer is extended and new elements are
	/// default-constructed.
	void resize(int n){
		mElems.resize(n);
		setSize(n);
	}

	/// Set size of buffer

	/// If the requested size is larger than the current capacity, then the
	/// buffer will be resized.
	void size(int n){
		if(capacity() < n) resize(n);
		else setSize(n);
	}

	/// Appends element to end of buffer growing its size if necessary
	void append(const T& v, double growFactor=2){

		// Grow array if too small
		if(size() >= capacity()){
			// Copy argument since it may be an element in current memory range
			// which may become invalid after the resize.
			const T vsafecopy = v;
			mElems.resize((size() ? size() : 4)*growFactor);
			super::construct(elems()+size(), vsafecopy);
		}
		else{
			super::construct(elems()+size(), v);
		}
		++mSize;
	}
	/// synonym for append():
	void push_back(const T& v, double growFactor=2) { append(v, growFactor); }

	/// Append elements of another Buffer

	/// Note: not safe to apply this to itself
	///
	void append(const Buffer<T>& src){
		append(src.elems(), src.size());
	}

	/// Append elements of an array
	void append(const T * src, int len){
		int oldsize = size();
		size(size() + len);
		std::copy(src, src + len, mElems.begin() + oldsize);
	}

	/// Repeat last element
	void repeatLast(){ append(last()); }

	/// Insert new elements after each existing element

	/// @param[in] n	Expansion factor; new size is n times old size
	/// @param[in] dup	If true, new elements are duplicates of existing elements.
	///					If false, new elements are default constructed.
	template <int n, bool dup>
	void expand(){
		size(size()*n);
		const int Nd = dup ? n : 1;
		for(int i=size()/n-1; i>=0; --i){
			const T& v = (*this)[i];
			for(int j=0; j<Nd; ++j) Alloc::construct(elems()+n*i+j, v);
		}
	}

private:
	std::vector<T, Alloc> mElems;
	int mSize;		// logical size array

	void setSize(int n){ mSize=n; }
};

/// Ring buffer

/// This buffer allows potentially large amounts of data to be buffered without
/// moving memory. This is accomplished by use of a moving write tap.
template <class T, class Alloc=std::allocator<T> >
class RingBuffer : protected Alloc {
public:

	/// Default constructor; does not allocate memory
	RingBuffer(): mPos(-1), mFill(0){}

	/// @param[in] size		number of elements
	/// @param[in] v		value to initialize elements to
	explicit RingBuffer(unsigned size, const T& v=T())
	:	mPos(size), mFill(0)
	{
		resize(size,v);
	}

	/// Get number of elements
	int size() const { return mElems.size(); }

	/// Get absolute index of most recently written element
	int pos() const { return mPos; }

	/// Get fill amount of buffer
	int fill() const { return mFill; }

	/// Get element at absolute index
	T& operator[](int i){ return mElems[i]; }

	/// Get element at absolute index (read-only)
	const T& operator[](int i) const { return mElems[i]; }

	/// Write new element
	void write(const T& v){
		if(mFill < size()) ++mFill;
		++mPos; if(pos() == size()){ mPos=0; }
		Alloc::construct(&mElems[0] + pos(), v);
	}

	/// Get reference to element relative to newest element
	T& read(int i){ return mElems[wrapOnce(pos()-i, size())]; }

	/// Get reference to element relative to newest element (read-only)
	const T& read(int i) const { return readFrom(pos(), i); }

	/// Get reference to older element relative to some newer element (read-only)

	/// @param[in] from		absolute index the read is relative to
	/// @param[in] dist		distance into past relative to 'from' of the returned element
	const T& readFrom(int from, int dist) const {
		return mElems[wrapOnce(from-dist, size())];
	}

	/// \returns reference to newest element
	T& newest(){ return mElems[pos()]; }

	/// \returns reference to newest element (read-only)
	const T& newest() const { return mElems[pos()]; }

	/// Resize buffer

	/// @param[in] n	number of elements
	/// @param[in] v	initialization value of newly allocated elements
	void resize(int n, const T& v=T()){
		mElems.resize(n,v);
		if(mPos >=n) mPos = n-1;
	}

protected:
	std::vector<T, Alloc> mElems;
	int mPos;
	int mFill;

	// Moves value one period closer to interval [0, max)
	static int wrapOnce(int v, int max){
		if(v <  0)   return v+max;
		if(v >= max) return v-max;
		return v;
	}
};

/// Constant size shift buffer

/// This is a first-in, first-out buffer with a constant number of elements.
/// Adding new elements to the buffer physically moves existing elements. The
/// advantage of moving memory like this is that elements stay logically ordered
/// making access faster and operating on the history easier.
template <int N, class T>
class ShiftBuffer{
public:

	/// @param[in] v	Value to initialize all elements to
	ShiftBuffer(const T& v=T()){ assign(v); }

	/// Get number of elements
	static int size(){ return N; }

	/// Get pointer to elements (read-only)
	const T * elems() const { return &mElems[0]; }

	/// Get pointer to elements
	T * elems(){ return &mElems[0]; }

	/// Get reference to element at index
	T& operator[](int i){ return mElems[i];}

	/// Get reference to element at index (read-only)
	const T& operator[](int i) const { return mElems[i]; }

	/// Push new element onto buffer. Newest element is at index 0.
	void operator()(const T& v){
		for(int i=N-1; i>0; --i) mElems[i] = mElems[i-1];
		mElems[0]=v;
	}

	/// Set all elements to argument
	void assign(const T& v){ for(int i=0;i<N;++i) mElems[i]=v; }

	/// Zero bytes of all elements
	void zero(){ memset(mElems, 0, N * sizeof(T)); }

protected:
	T mElems[N];
};

} // al::

#endif
<|endoftext|>