<commit_before>/*******************************
Copyright (c) 2016-2017 Grégoire Angerand

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**********************************/
#include "os.h"
#include "os_win.h"

#include <y/utils.h>

#include <iostream>

namespace y {
namespace os {

usize pid() {
	#ifdef Y_OS_WIN
	return GetCurrentProcessId();
	#else
	return getpid();
	#endif
}

MemInfo phys_mem_info() {
	#ifdef Y_OS_WIN
	MEMORYSTATUSEX info;
	info.dwLength = sizeof(info);
	GlobalMemoryStatusEx(&info);
	return MemInfo { info.ullTotalPhys, info.ullAvailPhys };
	#else
	return MemInfo { 0, 0 };
	#endif
}

usize mem_usage() {
	#if defined(Y_OS_WIN) && !defined(Y_NO_PSAPI)
	PROCESS_MEMORY_COUNTERS info;
	info.cb = sizeof(info);
	return windows::GetProcessMemoryInfo_func()(GetCurrentProcess(), &info, DWORD(sizeof(info))) ? info.WorkingSetSize : 0;
	#else
	return 0;
	#endif
}

u64 get_user_time_ns() {
	#ifdef Y_OS_WIN
	FILETIME time;
	FILETIME garbage;
	GetProcessTimes(GetCurrentProcess(), &garbage, &garbage, &garbage, &time);
	return windows::filetime_to_ns(time);
	#else
	return 0;
	#endif
}

u64 get_kernel_time_ns() {
	#ifdef Y_OS_WIN
	FILETIME time;
	FILETIME garbage;
	GetProcessTimes(GetCurrentProcess(), &garbage, &garbage, &time,&garbage);
	return windows::filetime_to_ns(time);
	#else
	return 0;
	#endif
}

AppTimes get_times_ns() {
	#ifdef Y_OS_WIN
	FILETIME user;
	FILETIME kernel;
	FILETIME garbage;
	GetProcessTimes(GetCurrentProcess(), &garbage, &garbage, &kernel, &user);
	return AppTimes { windows::filetime_to_ns(kernel), windows::filetime_to_ns(user) };
	#else
	return AppTimes { 0, 0 };
	#endif
}

}

}

#ifdef Y_OS_WIN

/*y_on_startup() {
	SetConsoleOutputCP(CP_UTF8);
}*/

#endif
<commit_msg>Fix missing include<commit_after>/*******************************
Copyright (c) 2016-2017 Grégoire Angerand

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**********************************/
#include "os.h"
#include "os_win.h"
#include "os_linux.h"

#include <y/utils.h>

#include <iostream>

namespace y {
namespace os {

usize pid() {
	#ifdef Y_OS_WIN
	return GetCurrentProcessId();
	#else
	return getpid();
	#endif
}

MemInfo phys_mem_info() {
	#ifdef Y_OS_WIN
	MEMORYSTATUSEX info;
	info.dwLength = sizeof(info);
	GlobalMemoryStatusEx(&info);
	return MemInfo { info.ullTotalPhys, info.ullAvailPhys };
	#else
	return MemInfo { 0, 0 };
	#endif
}

usize mem_usage() {
	#if defined(Y_OS_WIN) && !defined(Y_NO_PSAPI)
	PROCESS_MEMORY_COUNTERS info;
	info.cb = sizeof(info);
	return windows::GetProcessMemoryInfo_func()(GetCurrentProcess(), &info, DWORD(sizeof(info))) ? info.WorkingSetSize : 0;
	#else
	return 0;
	#endif
}

u64 get_user_time_ns() {
	#ifdef Y_OS_WIN
	FILETIME time;
	FILETIME garbage;
	GetProcessTimes(GetCurrentProcess(), &garbage, &garbage, &garbage, &time);
	return windows::filetime_to_ns(time);
	#else
	return 0;
	#endif
}

u64 get_kernel_time_ns() {
	#ifdef Y_OS_WIN
	FILETIME time;
	FILETIME garbage;
	GetProcessTimes(GetCurrentProcess(), &garbage, &garbage, &time,&garbage);
	return windows::filetime_to_ns(time);
	#else
	return 0;
	#endif
}

AppTimes get_times_ns() {
	#ifdef Y_OS_WIN
	FILETIME user;
	FILETIME kernel;
	FILETIME garbage;
	GetProcessTimes(GetCurrentProcess(), &garbage, &garbage, &kernel, &user);
	return AppTimes { windows::filetime_to_ns(kernel), windows::filetime_to_ns(user) };
	#else
	return AppTimes { 0, 0 };
	#endif
}

}

}

#ifdef Y_OS_WIN

/*y_on_startup() {
	SetConsoleOutputCP(CP_UTF8);
}*/

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014, Robert Escriva
// 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 Ygor 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 OWNER 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.

// C
#include <signal.h>

// STL
#include <memory>

// e
#include <e/popt.h>

// armnod
#include "ygor.h"

int
main(int argc, const char* argv[])
{
    e::argparser ap;
    std::auto_ptr<armnod_argparser> apl(armnod_argparser::create(""));
    ap.autohelp();
    ap.add("Generator:", apl->parser());

    if (!ap.parse(argc, argv))
    {
        return EXIT_FAILURE;
    }

    if (ap.args_sz() > 0)
    {
        ap.usage();
        std::cerr << "\nerror:  command takes no positional arguments" << std::endl;
        return EXIT_FAILURE;
    }

    sigset_t mask;
    sigfillset(&mask);
    sigdelset(&mask, SIGPROF);
    sigprocmask(SIG_SETMASK, &mask, NULL);
    armnod_generator* gen(armnod_generator_create(apl->config()));

    for (uint64_t i = 0; ; ++i)
    {
        if ((i & 0xffff) == 0)
        {
            sigpending(&mask);

            if (sigismember(&mask, SIGHUP) ||
                sigismember(&mask, SIGINT) ||
                sigismember(&mask, SIGTERM) ||
                sigismember(&mask, SIGPIPE) ||
                sigismember(&mask, SIGKILL))
            {
                break;
            }
        }

        const char* string = armnod_generate(gen);

        if (!string)
        {
            break;
        }

        printf("%s\n", string);
    }

    armnod_generator_destroy(gen);
    return EXIT_SUCCESS;
}
<commit_msg>Respond to signals faster in "ygor armnod"<commit_after>// Copyright (c) 2013-2014, Robert Escriva
// 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 Ygor 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 OWNER 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.

// C
#include <signal.h>

// STL
#include <memory>

// e
#include <e/popt.h>

// armnod
#include "ygor.h"

int
main(int argc, const char* argv[])
{
    e::argparser ap;
    std::auto_ptr<armnod_argparser> apl(armnod_argparser::create(""));
    ap.autohelp();
    ap.add("Generator:", apl->parser());

    if (!ap.parse(argc, argv))
    {
        return EXIT_FAILURE;
    }

    if (ap.args_sz() > 0)
    {
        ap.usage();
        std::cerr << "\nerror:  command takes no positional arguments" << std::endl;
        return EXIT_FAILURE;
    }

    sigset_t mask;
    sigfillset(&mask);
    sigdelset(&mask, SIGPROF);
    sigprocmask(SIG_SETMASK, &mask, NULL);
    armnod_generator* gen(armnod_generator_create(apl->config()));

    for (uint64_t i = 0; ; ++i)
    {
        if ((i & 0xf) == 0)
        {
            sigpending(&mask);

            if (sigismember(&mask, SIGHUP) ||
                sigismember(&mask, SIGINT) ||
                sigismember(&mask, SIGTERM) ||
                sigismember(&mask, SIGPIPE) ||
                sigismember(&mask, SIGKILL))
            {
                break;
            }
        }

        const char* string = armnod_generate(gen);

        if (!string)
        {
            break;
        }

        printf("%s\n", string);
    }

    armnod_generator_destroy(gen);
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
  Copyright (C) 2008-2015 The Communi Project

  You may use this file under the terms of BSD license as follows:

  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 copyright holder 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 HOLDERS OR CONTRIBUTORS BE LIABLE FOR
  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "zncmanager.h"
#include "ignoremanager.h"
#include <ircbuffermodel.h>
#include <ircconnection.h>
#include <irccommand.h>
#include <ircmessage.h>
#include <ircbuffer.h>

IRC_USE_NAMESPACE

ZncManager::ZncManager(QObject* parent) : QObject(parent)
{
    d.model = 0;
    d.timestamp = QDateTime::fromTime_t(0);
    setModel(qobject_cast<IrcBufferModel*>(parent));
}

ZncManager::~ZncManager()
{
}

IrcBufferModel* ZncManager::model() const
{
    return d.model;
}

void ZncManager::setModel(IrcBufferModel* model)
{
    if (d.model != model) {
        if (d.model && d.model->connection()) {
            IrcConnection* connection = d.model->connection();
            disconnect(connection, SIGNAL(connected()), this, SLOT(requestPlayback()));
            connection->removeMessageFilter(this);
            disconnect(model, SIGNAL(removed(IrcBuffer*)), this, SLOT(clearBuffer(IrcBuffer*)));
        }
        d.model = model;
        if (d.model && d.model->connection()) {
            IrcNetwork* network = d.model->network();
            QStringList caps = network->requestedCapabilities();
            caps += "batch";
            caps += "server-time";
            caps += "echo-message";
            caps += "znc.in/batch";
            caps += "znc.in/playback";
            caps += "znc.in/server-time";
            caps += "znc.in/echo-message";
            caps += "znc.in/server-time-iso";
            network->setRequestedCapabilities(caps);

            IrcConnection* connection = d.model->connection();
            connect(connection, SIGNAL(connected()), this, SLOT(requestPlayback()));
            connection->installMessageFilter(this);
            connect(model, SIGNAL(removed(IrcBuffer*)), this, SLOT(clearBuffer(IrcBuffer*)));
        }
        emit modelChanged(model);
    }
}

bool ZncManager::messageFilter(IrcMessage* message)
{
    if (message->connection()->isConnected() && message->tags().contains("time")) {
        QDateTime timestamp = message->tags().value("time").toDateTime();
        if (timestamp.isValid()) {
            message->setTimeStamp(timestamp.toTimeSpec(Qt::LocalTime));
            d.timestamp = qMax(timestamp, d.timestamp);
        }
    }

    if (message->type() == IrcMessage::Batch) {
        IrcBatchMessage* batch = static_cast<IrcBatchMessage*>(message);
        if (batch->batch() == "znc.in/playback") {
            IrcBuffer* buffer = d.model->add(batch->parameters().value(2));
            foreach (IrcMessage* msg, batch->messages()) {
                msg->setFlags(msg->flags() | IrcMessage::Playback);
                if (msg->type() == IrcMessage::Private)
                    processMessage(static_cast<IrcPrivateMessage*>(msg));
            }
            buffer->receiveMessage(batch);
            return true;
        }
    }

    return IgnoreManager::instance()->messageFilter(message);
}

void ZncManager::processMessage(IrcPrivateMessage* message)
{
    if (message->nick() == "*buffextras") {
        const QString msg = message->content();
        const int idx = msg.indexOf(" ");
        const QString prefix = msg.left(idx);
        const QString content = msg.mid(idx + 1);

        message->setPrefix(prefix);
        if (content.startsWith("joined")) {
            message->setTag("intent", "JOIN");
            message->setParameters(QStringList() << message->target());
        } else if (content.startsWith("parted")) {
            message->setTag("intent", "PART");
            QString reason = content.mid(content.indexOf("[") + 1);
            reason.chop(1);
            message->setParameters(QStringList() << message->target() << reason);
        } else if (content.startsWith("quit")) {
            message->setTag("intent", "QUIT");
            QString reason = content.mid(content.indexOf("[") + 1);
            reason.chop(1);
            message->setParameters(QStringList() << reason);
        } else if (content.startsWith("is")) {
            message->setTag("intent", "NICK");
            const QStringList tokens = content.split(" ", QString::SkipEmptyParts);
            message->setParameters(QStringList() << tokens.last());
        } else if (content.startsWith("set")) {
            message->setTag("intent", "MODE");
            QStringList tokens = content.split(" ", QString::SkipEmptyParts);
            const QString user = tokens.takeLast();
            const QString mode = tokens.takeLast();
            message->setParameters(QStringList() << message->target() << mode << user);
        } else if (content.startsWith("changed")) {
            message->setTag("intent", "TOPIC");
            const QString topic = content.mid(content.indexOf(":") + 2);
            message->setParameters(QStringList() << message->target() << topic);
        } else if (content.startsWith("kicked")) {
            message->setTag("intent", "KICK");
            QString reason = content.mid(content.indexOf("[") + 1);
            reason.chop(1);
            QStringList tokens = content.split(" ", QString::SkipEmptyParts);
            message->setParameters(QStringList() << message->target() << tokens.value(1) << reason);
        }
    }
}

void ZncManager::requestPlayback()
{
    if (d.model->network()->isCapable("znc.in/playback")) {
        IrcConnection* connection = d.model->connection();
        IrcCommand* cmd = IrcCommand::createMessage("*playback", QString("PLAY * %1").arg(d.timestamp.isValid() ? d.timestamp.toTime_t() : 0));
        cmd->setParent(this);
        connection->sendCommand(cmd);
    }
}

void ZncManager::clearBuffer(IrcBuffer* buffer)
{
    if (d.model->network()->isCapable("znc.in/playback") && !buffer->title().contains("*"))
        buffer->sendCommand(IrcCommand::createMessage("*playback", QString("CLEAR %1").arg(buffer->title())));
}
<commit_msg>ZncManager: remove server-time parsing (was promoted to libcommuni)<commit_after>/*
  Copyright (C) 2008-2015 The Communi Project

  You may use this file under the terms of BSD license as follows:

  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 copyright holder 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 HOLDERS OR CONTRIBUTORS BE LIABLE FOR
  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "zncmanager.h"
#include "ignoremanager.h"
#include <ircbuffermodel.h>
#include <ircconnection.h>
#include <irccommand.h>
#include <ircmessage.h>
#include <ircbuffer.h>

IRC_USE_NAMESPACE

ZncManager::ZncManager(QObject* parent) : QObject(parent)
{
    d.model = 0;
    d.timestamp = QDateTime::fromTime_t(0);
    setModel(qobject_cast<IrcBufferModel*>(parent));
}

ZncManager::~ZncManager()
{
}

IrcBufferModel* ZncManager::model() const
{
    return d.model;
}

void ZncManager::setModel(IrcBufferModel* model)
{
    if (d.model != model) {
        if (d.model && d.model->connection()) {
            IrcConnection* connection = d.model->connection();
            disconnect(connection, SIGNAL(connected()), this, SLOT(requestPlayback()));
            connection->removeMessageFilter(this);
            disconnect(model, SIGNAL(removed(IrcBuffer*)), this, SLOT(clearBuffer(IrcBuffer*)));
        }
        d.model = model;
        if (d.model && d.model->connection()) {
            IrcNetwork* network = d.model->network();
            QStringList caps = network->requestedCapabilities();
            caps += "batch";
            caps += "server-time";
            caps += "echo-message";
            caps += "znc.in/batch";
            caps += "znc.in/playback";
            caps += "znc.in/server-time";
            caps += "znc.in/echo-message";
            caps += "znc.in/server-time-iso";
            network->setRequestedCapabilities(caps);

            IrcConnection* connection = d.model->connection();
            connect(connection, SIGNAL(connected()), this, SLOT(requestPlayback()));
            connection->installMessageFilter(this);
            connect(model, SIGNAL(removed(IrcBuffer*)), this, SLOT(clearBuffer(IrcBuffer*)));
        }
        emit modelChanged(model);
    }
}

bool ZncManager::messageFilter(IrcMessage* message)
{
    if (message->connection()->isConnected())
        d.timestamp = qMax(d.timestamp, message->timeStamp());

    if (message->type() == IrcMessage::Batch) {
        IrcBatchMessage* batch = static_cast<IrcBatchMessage*>(message);
        if (batch->batch() == "znc.in/playback") {
            IrcBuffer* buffer = d.model->add(batch->parameters().value(2));
            foreach (IrcMessage* msg, batch->messages()) {
                msg->setFlags(msg->flags() | IrcMessage::Playback);
                if (msg->type() == IrcMessage::Private)
                    processMessage(static_cast<IrcPrivateMessage*>(msg));
            }
            buffer->receiveMessage(batch);
            return true;
        }
    }

    return IgnoreManager::instance()->messageFilter(message);
}

void ZncManager::processMessage(IrcPrivateMessage* message)
{
    if (message->nick() == "*buffextras") {
        const QString msg = message->content();
        const int idx = msg.indexOf(" ");
        const QString prefix = msg.left(idx);
        const QString content = msg.mid(idx + 1);

        message->setPrefix(prefix);
        if (content.startsWith("joined")) {
            message->setTag("intent", "JOIN");
            message->setParameters(QStringList() << message->target());
        } else if (content.startsWith("parted")) {
            message->setTag("intent", "PART");
            QString reason = content.mid(content.indexOf("[") + 1);
            reason.chop(1);
            message->setParameters(QStringList() << message->target() << reason);
        } else if (content.startsWith("quit")) {
            message->setTag("intent", "QUIT");
            QString reason = content.mid(content.indexOf("[") + 1);
            reason.chop(1);
            message->setParameters(QStringList() << reason);
        } else if (content.startsWith("is")) {
            message->setTag("intent", "NICK");
            const QStringList tokens = content.split(" ", QString::SkipEmptyParts);
            message->setParameters(QStringList() << tokens.last());
        } else if (content.startsWith("set")) {
            message->setTag("intent", "MODE");
            QStringList tokens = content.split(" ", QString::SkipEmptyParts);
            const QString user = tokens.takeLast();
            const QString mode = tokens.takeLast();
            message->setParameters(QStringList() << message->target() << mode << user);
        } else if (content.startsWith("changed")) {
            message->setTag("intent", "TOPIC");
            const QString topic = content.mid(content.indexOf(":") + 2);
            message->setParameters(QStringList() << message->target() << topic);
        } else if (content.startsWith("kicked")) {
            message->setTag("intent", "KICK");
            QString reason = content.mid(content.indexOf("[") + 1);
            reason.chop(1);
            QStringList tokens = content.split(" ", QString::SkipEmptyParts);
            message->setParameters(QStringList() << message->target() << tokens.value(1) << reason);
        }
    }
}

void ZncManager::requestPlayback()
{
    if (d.model->network()->isCapable("znc.in/playback")) {
        IrcConnection* connection = d.model->connection();
        IrcCommand* cmd = IrcCommand::createMessage("*playback", QString("PLAY * %1").arg(d.timestamp.isValid() ? d.timestamp.toTime_t() : 0));
        cmd->setParent(this);
        connection->sendCommand(cmd);
    }
}

void ZncManager::clearBuffer(IrcBuffer* buffer)
{
    if (d.model->network()->isCapable("znc.in/playback") && !buffer->title().contains("*"))
        buffer->sendCommand(IrcCommand::createMessage("*playback", QString("CLEAR %1").arg(buffer->title())));
}
<|endoftext|>


<commit_before>/****************************************************************************
 * Copyright (c) 2012-2018 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 *                                                                          *
 * SPDX-License-Identifier: BSD-3-Clause                                    *
 ****************************************************************************/
#ifndef DTK_DETAILS_DISTRIBUTOR_HPP
#define DTK_DETAILS_DISTRIBUTOR_HPP

#include <Teuchos_ArrayView.hpp>
#include <Tpetra_Distributor.hpp>

#include <Kokkos_Parallel.hpp>

#include <mpi.h>

#include <algorithm>

#define REORDER_RECV YES

namespace DataTransferKit
{
namespace Details
{

// clang-format off
// copy/paste from https://github.com/kokkos/kokkos-tutorials/blob/ee619447cee9e57b831e34b151d0868958b6b1e5/Intro-Full/Exercises/mpi_exch/mpi_exch.cpp
// * added Experimental nested namespace qualifier for Max
// * declared function static to avoid multiple definition error at link time
// * return early if input argument is empty
// * replace parallel_reduce with std::max_element because I couldn't get it to compile
// * append size to offsets in main driver but might want to handle it here
static void extract_and_sort_ranks(
    Kokkos::View<int*, Kokkos::HostSpace> destination_ranks,
    Kokkos::View<int*, Kokkos::HostSpace> permutation,
    std::vector<int>& unique_ranks,
    std::vector<int>& offsets,
    std::vector<int>& counts) {
  int mpi_rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
  auto n = destination_ranks.extent(0);
if ( n == 0 ) return;
  using ST = decltype(n);
  Kokkos::View<int*, Kokkos::HostSpace> tmp_ranks("tmp ranks", destination_ranks.extent(0));
  Kokkos::deep_copy(tmp_ranks, destination_ranks);
  int offset = 0;
  // this implements a "sort" which is O(N * R) where (R) is
  // the total number of unique destination ranks.
  // it performs better than other algorithms in
  // the case when (R) is small, but results may vary
  while (true) {
    int next_biggest_rank;
    //Kokkos::parallel_reduce("find next biggest rank", n, KOKKOS_LAMBDA(ST i, int& local_max) {
    //  auto r = tmp_ranks(i);
    //  local_max = (r > local_max) ? r : local_max;
    //}, Kokkos::Experimental::Max<int, Kokkos::HostSpace>(next_biggest_rank));
    next_biggest_rank = *std::max_element(tmp_ranks.data(), tmp_ranks.data() + n);
    if (next_biggest_rank == -1) break;
    unique_ranks.push_back(next_biggest_rank);
    offsets.push_back(offset);
    Kokkos::View<int, Kokkos::HostSpace> total("total");
    Kokkos::parallel_scan("process biggest rank items", Kokkos::RangePolicy<Kokkos::Serial>(0, n),
    KOKKOS_LAMBDA(ST i, int& index, const bool last_pass) {
      if (last_pass && (tmp_ranks(i) == next_biggest_rank)) {
        permutation(i) = index + offset;
      }
      if (tmp_ranks(i) == next_biggest_rank) ++index;
      if (last_pass) {
        if (i + 1 == tmp_ranks.extent(0)) {
          total() = index;
        }
        if (tmp_ranks(i) == next_biggest_rank) {
          tmp_ranks(i) = -1;
        }
      }
    });
    auto host_total = Kokkos::create_mirror_view_and_copy(
        Kokkos::HostSpace(), total);
    auto count = host_total();
    counts.push_back(count);
    offset += count;
  }
}
// clang-format on

class Distributor
{
  public:
    Distributor( Teuchos::RCP<Teuchos::Comm<int> const> comm )
        : _distributor( comm )
        , _comm(
              *( Teuchos::rcp_dynamic_cast<Teuchos::MpiComm<int> const>( comm )
                     ->getRawMpiComm() ) )
    {
    }

    template <typename T>
    static T *notNullPtr( T *p )
    {
        return p ? p : reinterpret_cast<T *>( -1 );
    }

    size_t
    createFromSends( Teuchos::ArrayView<int const> const &export_proc_ids )
    {
        static_assert(
            std::is_same<typename View::non_const_value_type, int>::value, "" );
        int comm_rank;
        MPI_Comm_rank( _comm, &comm_rank );

        auto const n = export_proc_ids.size();
        Kokkos::View<int const *, Kokkos::HostSpace,
                     Kokkos::MemoryTraits<Kokkos::Unmanaged>>
            tmp( export_proc_ids.getRawPtr(), n );
        Kokkos::View<int *, Kokkos::HostSpace> destination_ranks(
            "destination_ranks", n );
        Kokkos::deep_copy( destination_ranks, tmp );

        _permute = Kokkos::View<int *, Kokkos::HostSpace>( "permute", n );
        std::vector<int> destinations;
        extract_and_sort_ranks( destination_ranks, _permute, destinations,
                                _dest_offsets, _dest_counts );

        if ( _dest_counts.empty() )
            _dest_offsets.push_back( 0 );
        else
            _dest_offsets.push_back( _dest_offsets.back() +
                                     _dest_counts.back() );

        {
            int const reorder = 0; // Ranking may *not* be reordered
            int const sources[1] = {comm_rank};
            int const degrees[1] = {static_cast<int>( destinations.size() )};

            MPI_Dist_graph_create(
                _comm, 1, sources, degrees, notNullPtr( destinations.data() ),
                MPI_UNWEIGHTED, MPI_INFO_NULL, reorder, &_comm_dist_graph );
        }

        int indegrees;
        int outdegrees;
        int weighted;
        MPI_Dist_graph_neighbors_count( _comm_dist_graph, &indegrees,
                                        &outdegrees, &weighted );
        assert( weighted == 0 );
        assert( outdegrees == (int)destinations.size() );

        std::vector<int> sources( indegrees );
        MPI_Dist_graph_neighbors( _comm_dist_graph, indegrees,
                                  notNullPtr( sources.data() ), MPI_UNWEIGHTED,
                                  outdegrees, notNullPtr( destinations.data() ),
                                  MPI_UNWEIGHTED );

        _src_counts.resize( indegrees );
        MPI_Neighbor_alltoall( _dest_counts.data(), 1, MPI_INT,
                               _src_counts.data(), 1, MPI_INT,
                               _comm_dist_graph );

        _src_offsets.resize( indegrees + 1 );
        // exclusive scan
        _src_offsets[0] = 0;
        for ( int i = 0; i < indegrees; ++i )
            _src_offsets[i + 1] = _src_offsets[i] + _src_counts[i];

        int const nn = _distributor.createFromSends( export_proc_ids );
        assert( _src_offsets.back() == nn ); // check return value

        for ( int i = 0; i < indegrees; ++i )
        {
            auto it = std::find( std::begin( _distributor.getProcsFrom() ),
                                 std::end( _distributor.getProcsFrom() ),
                                 sources[i] );
            assert( it != std::end( _distributor.getProcsFrom() ) );
            int j =
                std::distance( std::begin( _distributor.getProcsFrom() ), it );
            assert( _src_counts[i] == (int)_distributor.getLengthsFrom()[j] );
        }

        for ( int i = 0; i < outdegrees; ++i )
        {
            auto it = std::find( std::begin( _distributor.getProcsTo() ),
                                 std::end( _distributor.getProcsTo() ),
                                 destinations[i] );
            assert( it != std::end( _distributor.getProcsTo() ) );
            int j =
                std::distance( std::begin( _distributor.getProcsTo() ), it );
            assert( _dest_counts[i] == (int)_distributor.getLengthsTo()[j] );
        }

#if defined( REORDER_RECV )
        int comm_size = -1;
        MPI_Comm_size( _comm, &comm_size );
        _permute_recv.resize( _src_offsets.back() );
        int offset = 0;
        for ( int i = 0; i < comm_size; ++i )
        {
            auto const it = std::find( sources.begin(), sources.end(), i );
            if ( it != sources.end() )
            {
                int const j = std::distance( sources.begin(), it );
                std::iota( &_permute_recv[offset],
                           &_permute_recv[offset] + _src_counts[j],
                           _src_offsets[j] );
                offset += _src_counts[j];
            }
        }
        assert( offset == (int)_permute_recv.size() );
#endif

        return _src_offsets.back();
    }
    template <typename Packet>
    void doPostsAndWaits( Teuchos::ArrayView<Packet const> const &exports,
                          size_t numPackets,
                          Teuchos::ArrayView<Packet> const &imports )
    {

        std::vector<int> dest_counts = _dest_counts;
        std::vector<int> dest_offsets = _dest_offsets;
        std::vector<int> src_counts = _src_counts;
        std::vector<int> src_offsets = _src_offsets;
        for ( auto pv :
              {&dest_counts, &dest_offsets, &src_counts, &src_offsets} )
            for ( auto &x : *pv )
                x *= numPackets * sizeof( Packet );

        std::vector<Packet> dest_buffer( exports.size() );
        std::vector<Packet> src_buffer( imports.size() );

        assert( (size_t)src_offsets.back() ==
                imports.size() * sizeof( Packet ) );
        assert( (size_t)dest_offsets.back() ==
                exports.size() * sizeof( Packet ) );

        for ( int i = 0; i < _dest_offsets.back(); ++i )
            std::copy( &exports[numPackets * i],
                       &exports[numPackets * i] + numPackets,
                       &dest_buffer[numPackets * _permute[i]] );

        MPI_Neighbor_alltoallv(
            notNullPtr( dest_buffer.data() ), notNullPtr( dest_counts.data() ),
            dest_offsets.data(), MPI_BYTE, notNullPtr( src_buffer.data() ),
            notNullPtr( src_counts.data() ), src_offsets.data(), MPI_BYTE,
            _comm_dist_graph );

#if defined( REORDER_RECV )
        for ( int i = 0; i < _src_offsets.back(); ++i )
            std::copy( &src_buffer[numPackets * _permute_recv[i]],
                       &src_buffer[numPackets * _permute_recv[i]] + numPackets,
                       &imports[numPackets * i] );
#else
        std::copy( src_buffer.begin(), src_buffer.end(), imports.getRawPtr() );
#endif

        size_t num_receives = _distributor.getNumReceives();
        size_t num_sends = _distributor.getNumSends();
        if ( _distributor.hasSelfMessage() )
        {
            ++num_receives;
            ++num_sends;
        }
        assert( num_receives == _src_counts.size() );
        assert( num_sends == _dest_counts.size() );

        //_distributor.doPostsAndWaits( exports, numPackets, imports );
    }
    size_t getTotalReceiveLength() const
    {
        auto n = _distributor.getTotalReceiveLength();
        assert( n ==
                std::accumulate( std::begin( _distributor.getLengthsFrom() ),
                                 std::end( _distributor.getLengthsFrom() ),
                                 size_t{0} ) );
        assert( n == static_cast<size_t>( _src_offsets.back() ) );
        return n;
    }
    size_t getTotalSendLength() const
    {
        auto n = std::accumulate( std::begin( _distributor.getLengthsTo() ),
                                  std::end( _distributor.getLengthsTo() ),
                                  size_t{0} );
        assert( n == static_cast<size_t>( _dest_offsets.back() ) );
        return n;
    }

  private:
    Tpetra::Distributor _distributor;
    MPI_Comm _comm;
    MPI_Comm _comm_dist_graph;
    Kokkos::View<int *, Kokkos::HostSpace> _permute;
    std::vector<int> _dest_offsets;
    std::vector<int> _dest_counts;
    std::vector<int> _src_offsets;
    std::vector<int> _src_counts;
#if defined( REORDER_RECV )
    std::vector<int> _permute_recv;
#endif
};

} // namespace Details
} // namespace DataTransferKit

#endif
<commit_msg>Remove Tpetra::Distributor<commit_after>/****************************************************************************
 * Copyright (c) 2012-2018 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 *                                                                          *
 * SPDX-License-Identifier: BSD-3-Clause                                    *
 ****************************************************************************/
#ifndef DTK_DETAILS_DISTRIBUTOR_HPP
#define DTK_DETAILS_DISTRIBUTOR_HPP

#include <Teuchos_ArrayView.hpp>
#include <Teuchos_DefaultMpiComm.hpp>

#include <Kokkos_Core.hpp> // FIXME

#include <mpi.h>

#include <algorithm>

#define REORDER_RECV YES

namespace DataTransferKit
{
namespace Details
{

// clang-format off
// copy/paste from https://github.com/kokkos/kokkos-tutorials/blob/ee619447cee9e57b831e34b151d0868958b6b1e5/Intro-Full/Exercises/mpi_exch/mpi_exch.cpp
// * added Experimental nested namespace qualifier for Max
// * declared function static to avoid multiple definition error at link time
// * return early if input argument is empty
// * replace parallel_reduce with std::max_element because I couldn't get it to compile
// * append size to offsets in main driver but might want to handle it here
static void extract_and_sort_ranks(
    Kokkos::View<int*, Kokkos::HostSpace> destination_ranks,
    Kokkos::View<int*, Kokkos::HostSpace> permutation,
    std::vector<int>& unique_ranks,
    std::vector<int>& offsets,
    std::vector<int>& counts) {
  int mpi_rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
  auto n = destination_ranks.extent(0);
if ( n == 0 ) return;
  using ST = decltype(n);
  Kokkos::View<int*, Kokkos::HostSpace> tmp_ranks("tmp ranks", destination_ranks.extent(0));
  Kokkos::deep_copy(tmp_ranks, destination_ranks);
  int offset = 0;
  // this implements a "sort" which is O(N * R) where (R) is
  // the total number of unique destination ranks.
  // it performs better than other algorithms in
  // the case when (R) is small, but results may vary
  while (true) {
    int next_biggest_rank;
    //Kokkos::parallel_reduce("find next biggest rank", n, KOKKOS_LAMBDA(ST i, int& local_max) {
    //  auto r = tmp_ranks(i);
    //  local_max = (r > local_max) ? r : local_max;
    //}, Kokkos::Experimental::Max<int, Kokkos::HostSpace>(next_biggest_rank));
    next_biggest_rank = *std::max_element(tmp_ranks.data(), tmp_ranks.data() + n);
    if (next_biggest_rank == -1) break;
    unique_ranks.push_back(next_biggest_rank);
    offsets.push_back(offset);
    Kokkos::View<int, Kokkos::HostSpace> total("total");
    Kokkos::parallel_scan("process biggest rank items", Kokkos::RangePolicy<Kokkos::Serial>(0, n),
    KOKKOS_LAMBDA(ST i, int& index, const bool last_pass) {
      if (last_pass && (tmp_ranks(i) == next_biggest_rank)) {
        permutation(i) = index + offset;
      }
      if (tmp_ranks(i) == next_biggest_rank) ++index;
      if (last_pass) {
        if (i + 1 == tmp_ranks.extent(0)) {
          total() = index;
        }
        if (tmp_ranks(i) == next_biggest_rank) {
          tmp_ranks(i) = -1;
        }
      }
    });
    auto host_total = Kokkos::create_mirror_view_and_copy(
        Kokkos::HostSpace(), total);
    auto count = host_total();
    counts.push_back(count);
    offset += count;
  }
}
// clang-format on

class Distributor
{
  public:
    Distributor( Teuchos::RCP<Teuchos::Comm<int> const> comm )
        : _comm(
              *( Teuchos::rcp_dynamic_cast<Teuchos::MpiComm<int> const>( comm )
                     ->getRawMpiComm() ) )
    {
    }

    template <typename T>
    static T *notNullPtr( T *p )
    {
        return p ? p : reinterpret_cast<T *>( -1 );
    }

    size_t
    createFromSends( Teuchos::ArrayView<int const> const &export_proc_ids )
    {
        static_assert(
            std::is_same<typename View::non_const_value_type, int>::value, "" );
        int comm_rank;
        MPI_Comm_rank( _comm, &comm_rank );

        auto const n = export_proc_ids.size();
        Kokkos::View<int const *, Kokkos::HostSpace,
                     Kokkos::MemoryTraits<Kokkos::Unmanaged>>
            tmp( export_proc_ids.getRawPtr(), n );
        Kokkos::View<int *, Kokkos::HostSpace> destination_ranks(
            "destination_ranks", n );
        Kokkos::deep_copy( destination_ranks, tmp );

        _permute = Kokkos::View<int *, Kokkos::HostSpace>( "permute", n );
        std::vector<int> destinations;
        extract_and_sort_ranks( destination_ranks, _permute, destinations,
                                _dest_offsets, _dest_counts );

        if ( _dest_counts.empty() )
            _dest_offsets.push_back( 0 );
        else
            _dest_offsets.push_back( _dest_offsets.back() +
                                     _dest_counts.back() );

        {
            int const reorder = 0; // Ranking may *not* be reordered
            int const sources[1] = {comm_rank};
            int const degrees[1] = {static_cast<int>( destinations.size() )};

            MPI_Dist_graph_create(
                _comm, 1, sources, degrees, notNullPtr( destinations.data() ),
                MPI_UNWEIGHTED, MPI_INFO_NULL, reorder, &_comm_dist_graph );
        }

        int indegrees;
        int outdegrees;
        int weighted;
        MPI_Dist_graph_neighbors_count( _comm_dist_graph, &indegrees,
                                        &outdegrees, &weighted );
        assert( weighted == 0 );
        assert( outdegrees == (int)destinations.size() );

        std::vector<int> sources( indegrees );
        MPI_Dist_graph_neighbors( _comm_dist_graph, indegrees,
                                  notNullPtr( sources.data() ), MPI_UNWEIGHTED,
                                  outdegrees, notNullPtr( destinations.data() ),
                                  MPI_UNWEIGHTED );

        _src_counts.resize( indegrees );
        MPI_Neighbor_alltoall( _dest_counts.data(), 1, MPI_INT,
                               _src_counts.data(), 1, MPI_INT,
                               _comm_dist_graph );

        _src_offsets.resize( indegrees + 1 );
        // exclusive scan
        _src_offsets[0] = 0;
        for ( int i = 0; i < indegrees; ++i )
            _src_offsets[i + 1] = _src_offsets[i] + _src_counts[i];

#if defined( REORDER_RECV )
        int comm_size = -1;
        MPI_Comm_size( _comm, &comm_size );
        _permute_recv.resize( _src_offsets.back() );
        int offset = 0;
        for ( int i = 0; i < comm_size; ++i )
        {
            auto const it = std::find( sources.begin(), sources.end(), i );
            if ( it != sources.end() )
            {
                int const j = std::distance( sources.begin(), it );
                std::iota( &_permute_recv[offset],
                           &_permute_recv[offset] + _src_counts[j],
                           _src_offsets[j] );
                offset += _src_counts[j];
            }
        }
        assert( offset == (int)_permute_recv.size() );
#endif

        return _src_offsets.back();
    }
    template <typename Packet>
    void doPostsAndWaits( Teuchos::ArrayView<Packet const> const &exports,
                          size_t numPackets,
                          Teuchos::ArrayView<Packet> const &imports )
    {

        std::vector<int> dest_counts = _dest_counts;
        std::vector<int> dest_offsets = _dest_offsets;
        std::vector<int> src_counts = _src_counts;
        std::vector<int> src_offsets = _src_offsets;
        for ( auto pv :
              {&dest_counts, &dest_offsets, &src_counts, &src_offsets} )
            for ( auto &x : *pv )
                x *= numPackets * sizeof( Packet );

        std::vector<Packet> dest_buffer( exports.size() );
        std::vector<Packet> src_buffer( imports.size() );

        assert( (size_t)src_offsets.back() ==
                imports.size() * sizeof( Packet ) );
        assert( (size_t)dest_offsets.back() ==
                exports.size() * sizeof( Packet ) );

        for ( int i = 0; i < _dest_offsets.back(); ++i )
            std::copy( &exports[numPackets * i],
                       &exports[numPackets * i] + numPackets,
                       &dest_buffer[numPackets * _permute[i]] );

        MPI_Neighbor_alltoallv(
            notNullPtr( dest_buffer.data() ), notNullPtr( dest_counts.data() ),
            dest_offsets.data(), MPI_BYTE, notNullPtr( src_buffer.data() ),
            notNullPtr( src_counts.data() ), src_offsets.data(), MPI_BYTE,
            _comm_dist_graph );

#if defined( REORDER_RECV )
        for ( int i = 0; i < _src_offsets.back(); ++i )
            std::copy( &src_buffer[numPackets * _permute_recv[i]],
                       &src_buffer[numPackets * _permute_recv[i]] + numPackets,
                       &imports[numPackets * i] );
#else
        std::copy( src_buffer.begin(), src_buffer.end(), imports.getRawPtr() );
#endif
    }
    size_t getTotalReceiveLength() const { return _src_offsets.back(); }
    size_t getTotalSendLength() const { return _dest_offsets.back(); }

  private:
    MPI_Comm _comm;
    MPI_Comm _comm_dist_graph;
    Kokkos::View<int *, Kokkos::HostSpace> _permute;
    std::vector<int> _dest_offsets;
    std::vector<int> _dest_counts;
    std::vector<int> _src_offsets;
    std::vector<int> _src_counts;
#if defined( REORDER_RECV )
    std::vector<int> _permute_recv;
#endif
};

} // namespace Details
} // namespace DataTransferKit

#endif
<|endoftext|>


<commit_before>
#include <test.hpp>

TEST_CASE("read string field") {

    SECTION("empty") {
        const std::string buffer = load_data("string/data-empty");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        REQUIRE(item.get_string() == "");
        REQUIRE(!item.next());
    }

    SECTION("one") {
        const std::string buffer = load_data("string/data-one");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        REQUIRE(item.get_string() == "x");
        REQUIRE(!item.next());
    }

    SECTION("string") {
        const std::string buffer = load_data("string/data-string");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        REQUIRE(item.get_string() == "foobar");
        REQUIRE(!item.next());
    }

    SECTION("end_of_buffer") {
        const std::string buffer = load_data("string/data-string");

        for (std::string::size_type i = 1; i < buffer.size(); ++i) {
            protozero::pbf_reader item(buffer.data(), i);
            REQUIRE(item.next());
            REQUIRE_THROWS_AS(item.get_string(), protozero::end_of_buffer_exception);
        }
    }

}

TEST_CASE("write string field") {

    std::string buffer_test;
    protozero::pbf_writer pbf_test(buffer_test);

    SECTION("empty") {
        pbf_test.add_string(1, "");
        REQUIRE(buffer_test == load_data("string/data-empty"));
    }

    SECTION("one") {
        pbf_test.add_string(1, "x");
        REQUIRE(buffer_test == load_data("string/data-one"));
    }

    SECTION("string") {
        pbf_test.add_string(1, "foobar");
        REQUIRE(buffer_test == load_data("string/data-string"));
    }

}

<commit_msg>Add test for get_view().<commit_after>
#include <test.hpp>

TEST_CASE("read string field using get_string") {

    SECTION("empty") {
        const std::string buffer = load_data("string/data-empty");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        REQUIRE(item.get_string() == "");
        REQUIRE(!item.next());
    }

    SECTION("one") {
        const std::string buffer = load_data("string/data-one");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        REQUIRE(item.get_string() == "x");
        REQUIRE(!item.next());
    }

    SECTION("string") {
        const std::string buffer = load_data("string/data-string");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        REQUIRE(item.get_string() == "foobar");
        REQUIRE(!item.next());
    }

    SECTION("end_of_buffer") {
        const std::string buffer = load_data("string/data-string");

        for (std::string::size_type i = 1; i < buffer.size(); ++i) {
            protozero::pbf_reader item(buffer.data(), i);
            REQUIRE(item.next());
            REQUIRE_THROWS_AS(item.get_string(), protozero::end_of_buffer_exception);
        }
    }

}

TEST_CASE("read string field using get_view") {

    SECTION("empty") {
        const std::string buffer = load_data("string/data-empty");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        auto v = item.get_view();
        REQUIRE(v.size() == 0);
        REQUIRE(!item.next());
    }

    SECTION("one") {
        const std::string buffer = load_data("string/data-one");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        auto v = item.get_view();
        REQUIRE(*v.data() == 'x');
        REQUIRE(v.size() == 1);
        REQUIRE(!item.next());
    }

    SECTION("string") {
        const std::string buffer = load_data("string/data-string");

        protozero::pbf_reader item(buffer);

        REQUIRE(item.next());
        REQUIRE(std::string(item.get_view()) == "foobar");
        REQUIRE(!item.next());
    }

    SECTION("end_of_buffer") {
        const std::string buffer = load_data("string/data-string");

        for (std::string::size_type i = 1; i < buffer.size(); ++i) {
            protozero::pbf_reader item(buffer.data(), i);
            REQUIRE(item.next());
            REQUIRE_THROWS_AS(item.get_view(), protozero::end_of_buffer_exception);
        }
    }

}

TEST_CASE("write string field") {

    std::string buffer_test;
    protozero::pbf_writer pbf_test(buffer_test);

    SECTION("empty") {
        pbf_test.add_string(1, "");
        REQUIRE(buffer_test == load_data("string/data-empty"));
    }

    SECTION("one") {
        pbf_test.add_string(1, "x");
        REQUIRE(buffer_test == load_data("string/data-one"));
    }

    SECTION("string") {
        pbf_test.add_string(1, "foobar");
        REQUIRE(buffer_test == load_data("string/data-string"));
    }

}

<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"
#include <typeinfo>

template<typename Dst, typename Src>
bool test_assign(const Dst&, const Src&, int vectorization, int unrolling)
{
  return ei_assign_traits<Dst,Src>::Vectorization==vectorization
    && ei_assign_traits<Dst,Src>::Unrolling==unrolling;
}

template<typename Xpr>
bool test_sum(const Xpr&, int vectorization, int unrolling)
{
  return ei_sum_traits<Xpr>::Vectorization==vectorization
    && ei_sum_traits<Xpr>::Unrolling==unrolling;
}

void test_vectorization_logic()
{

#ifdef EIGEN_VECTORIZE

  VERIFY(test_assign(Vector4f(),Vector4f(),
    InnerVectorization,CompleteUnrolling));
  VERIFY(test_assign(Vector4f(),Vector4f()+Vector4f(),
    InnerVectorization,CompleteUnrolling));
  VERIFY(test_assign(Vector4f(),Vector4f().cwise() * Vector4f(),
    InnerVectorization,CompleteUnrolling));

  VERIFY(test_assign(Matrix4f(),Matrix4f(),
    InnerVectorization,CompleteUnrolling));
  VERIFY(test_assign(Matrix4f(),Matrix4f()+Matrix4f(),
    InnerVectorization,CompleteUnrolling));
  VERIFY(test_assign(Matrix4f(),Matrix4f().cwise() * Matrix4f(),
    InnerVectorization,CompleteUnrolling));

  VERIFY(test_assign(Matrix<float,16,16>(),Matrix<float,16,16>()+Matrix<float,16,16>(),
    InnerVectorization,InnerUnrolling));

  VERIFY(test_assign(Matrix<float,16,16,DontAlign>(),Matrix<float,16,16>()+Matrix<float,16,16>(),
    NoVectorization,InnerUnrolling));

  VERIFY(test_assign(Matrix<float,6,2>(),Matrix<float,6,2>().cwise() / Matrix<float,6,2>(),
    LinearVectorization,CompleteUnrolling));

  VERIFY(test_assign(Matrix<float,17,17>(),Matrix<float,17,17>()+Matrix<float,17,17>(),
    NoVectorization,InnerUnrolling));

  VERIFY(test_assign(Matrix<float,4,4>(),Matrix<float,17,17>().block<4,4>(2,3)+Matrix<float,17,17>().block<4,4>(10,4),
    NoVectorization,CompleteUnrolling));

  VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3),
    SliceVectorization,NoUnrolling));

  VERIFY(test_sum(VectorXf(10),
    LinearVectorization,NoUnrolling));

  VERIFY(test_sum(Matrix<float,5,2>(),
    NoVectorization,CompleteUnrolling));

  VERIFY(test_sum(Matrix<float,6,2>(),
    LinearVectorization,CompleteUnrolling));

  VERIFY(test_sum(Matrix<float,16,16>(),
    LinearVectorization,NoUnrolling));

  VERIFY(test_sum(Matrix<float,16,16>().block<4,4>(1,2),
    NoVectorization,CompleteUnrolling));

  VERIFY(test_sum(Matrix<float,16,16>().block<8,1>(1,2),
    LinearVectorization,CompleteUnrolling));

  VERIFY(test_sum(Matrix<double,7,3>(),
    NoVectorization,CompleteUnrolling));

#endif // EIGEN_VECTORIZE

}
<commit_msg>update vectorization_logic unit test wrt previous sum/redux change<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"
#include <typeinfo>

template<typename Dst, typename Src>
bool test_assign(const Dst&, const Src&, int vectorization, int unrolling)
{
  return ei_assign_traits<Dst,Src>::Vectorization==vectorization
    && ei_assign_traits<Dst,Src>::Unrolling==unrolling;
}

template<typename Xpr>
bool test_redux(const Xpr&, int vectorization, int unrolling)
{
  typedef ei_redux_traits<ei_scalar_sum_op<typename Xpr::Scalar>,Xpr> traits;
  return traits::Vectorization==vectorization && traits::Unrolling==unrolling;
}

void test_vectorization_logic()
{

#ifdef EIGEN_VECTORIZE

  VERIFY(test_assign(Vector4f(),Vector4f(),
    InnerVectorization,CompleteUnrolling));
  VERIFY(test_assign(Vector4f(),Vector4f()+Vector4f(),
    InnerVectorization,CompleteUnrolling));
  VERIFY(test_assign(Vector4f(),Vector4f().cwise() * Vector4f(),
    InnerVectorization,CompleteUnrolling));

  VERIFY(test_assign(Matrix4f(),Matrix4f(),
    InnerVectorization,CompleteUnrolling));
  VERIFY(test_assign(Matrix4f(),Matrix4f()+Matrix4f(),
    InnerVectorization,CompleteUnrolling));
  VERIFY(test_assign(Matrix4f(),Matrix4f().cwise() * Matrix4f(),
    InnerVectorization,CompleteUnrolling));

  VERIFY(test_assign(Matrix<float,16,16>(),Matrix<float,16,16>()+Matrix<float,16,16>(),
    InnerVectorization,InnerUnrolling));

  VERIFY(test_assign(Matrix<float,16,16,DontAlign>(),Matrix<float,16,16>()+Matrix<float,16,16>(),
    NoVectorization,InnerUnrolling));

  VERIFY(test_assign(Matrix<float,6,2>(),Matrix<float,6,2>().cwise() / Matrix<float,6,2>(),
    LinearVectorization,CompleteUnrolling));

  VERIFY(test_assign(Matrix<float,17,17>(),Matrix<float,17,17>()+Matrix<float,17,17>(),
    NoVectorization,InnerUnrolling));

  VERIFY(test_assign(Matrix<float,4,4>(),Matrix<float,17,17>().block<4,4>(2,3)+Matrix<float,17,17>().block<4,4>(10,4),
    NoVectorization,CompleteUnrolling));

  VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3),
    SliceVectorization,NoUnrolling));

  VERIFY(test_redux(VectorXf(10),
    LinearVectorization,NoUnrolling));

  VERIFY(test_redux(Matrix<float,5,2>(),
    NoVectorization,CompleteUnrolling));

  VERIFY(test_redux(Matrix<float,6,2>(),
    LinearVectorization,CompleteUnrolling));

  VERIFY(test_redux(Matrix<float,16,16>(),
    LinearVectorization,NoUnrolling));

  VERIFY(test_redux(Matrix<float,16,16>().block<4,4>(1,2),
    NoVectorization,CompleteUnrolling));

  VERIFY(test_redux(Matrix<float,16,16>().block<8,1>(1,2),
    LinearVectorization,CompleteUnrolling));

  VERIFY(test_redux(Matrix<double,7,3>(),
    NoVectorization,CompleteUnrolling));

#endif // EIGEN_VECTORIZE

}
<|endoftext|>


<commit_before>#include "geometry/RipsExpander.hh"

#include "tests/Base.hh"

#include "filtrations/Data.hh"

#include "topology/Simplex.hh"
#include "topology/SimplicialComplex.hh"

#include <iterator>
#include <set>
#include <vector>

#include <cmath>

using namespace aleph::geometry;
using namespace aleph::topology;
using namespace aleph;

/** Checks whether co-faces are preceded by their faces in a filtration */
template <class InputIterator> bool isConsistentFiltration( InputIterator begin, InputIterator end )
{
  using Simplex = typename std::iterator_traits<InputIterator>::value_type;

  // Contains all simplices that have already been 'seen' during the
  // traversal. If an unseen face is encountered, we have identified
  // an error.
  std::set<Simplex> seen;

  for( auto it = begin; it != end; ++it )
  {
    seen.insert( *it );

    for( auto itFace = it->begin_boundary(); itFace != it->end_boundary(); ++itFace )
      if( seen.find( *itFace ) == seen.end() )
        return false;
  }

  return true;
}

template <class Data, class Vertex> void triangle()
{
  ALEPH_TEST_BEGIN( "Triangle" );

  using Simplex           = Simplex<Data, Vertex>;
  using SimplicialComplex = SimplicialComplex<Simplex>;

  std::vector<Simplex> simplices
    = { {0}, {1}, {2}, {0,1}, {0,2}, {1,2} };

  SimplicialComplex K( simplices.begin(), simplices.end() );
  RipsExpander<SimplicialComplex> ripsExpander;

  auto vr1 = ripsExpander( K, 2 );
  auto vr2 = ripsExpander( K, 3 );

  ALEPH_ASSERT_THROW( vr1.empty() == false );
  ALEPH_ASSERT_THROW( vr2.empty() == false );
  ALEPH_ASSERT_THROW( vr1.size()  == vr2.size() );
  ALEPH_ASSERT_THROW( vr1.size()  == 7 );

  ALEPH_TEST_END();
}

template <class Data, class Vertex> void quad()
{
  ALEPH_TEST_BEGIN( "Quad" );

  using Simplex           = Simplex<Data, Vertex>;
  using SimplicialComplex = SimplicialComplex<Simplex>;

  std::vector<Simplex> simplices
    = { {0},
        {1},
        {2},
        {3},
        Simplex( {0,1}, Data(1) ),
        Simplex( {0,2}, Data( std::sqrt(2.0) ) ),
        Simplex( {1,2}, Data(1) ),
        Simplex( {2,3}, Data(1) ),
        Simplex( {0,3}, Data(1) ),
        Simplex( {1,3}, Data( std::sqrt(2.0) ) ) };

  SimplicialComplex K( simplices.begin(), simplices.end() );
  RipsExpander<SimplicialComplex> ripsExpander;

  auto vr1 = ripsExpander( K, 1 );
  auto vr2 = ripsExpander( K, 2 );
  auto vr3 = ripsExpander( K, 3 );

  vr1 = ripsExpander.assignMaximumWeight( vr1 );
  vr2 = ripsExpander.assignMaximumWeight( vr2 );
  vr3 = ripsExpander.assignMaximumWeight( vr3 );

  vr1.sort( filtrations::Data<Simplex>() );
  vr2.sort( filtrations::Data<Simplex>() );
  vr3.sort( filtrations::Data<Simplex>() );

  ALEPH_ASSERT_THROW( vr1.empty() == false );
  ALEPH_ASSERT_THROW( vr2.empty() == false );
  ALEPH_ASSERT_THROW( vr3.empty() == false );

  ALEPH_ASSERT_THROW( vr1.size() == simplices.size()     );
  ALEPH_ASSERT_THROW( vr2.size() == vr1.size()       + 4 ); // +4 triangles
  ALEPH_ASSERT_THROW( vr3.size() == vr2.size()       + 1 ); // +1 tetrahedron

  ALEPH_ASSERT_THROW( isConsistentFiltration( vr1.begin(), vr1.end() ) );
  ALEPH_ASSERT_THROW( isConsistentFiltration( vr2.begin(), vr2.end() ) );
  ALEPH_ASSERT_THROW( isConsistentFiltration( vr3.begin(), vr3.end() ) );

  ALEPH_TEST_END();
}

int main()
{
  triangle<double, unsigned>();
  triangle<double, short   >();
  triangle<float,  unsigned>();
  triangle<float,  short   >();

  quad<double, unsigned>();
  quad<double, short   >();
  quad<float,  unsigned>();
  quad<float,  short   >();
}
<commit_msg>Started implementing test case for comparing Rips expansion strategies<commit_after>#include "geometry/RipsExpander.hh"
#include "geometry/RipsExpanderTopDown.hh"

#include "tests/Base.hh"

#include "filtrations/Data.hh"

#include "topology/Simplex.hh"
#include "topology/SimplicialComplex.hh"

#include <iterator>
#include <set>
#include <vector>

#include <cmath>

using namespace aleph::geometry;
using namespace aleph::topology;
using namespace aleph;

/** Checks whether co-faces are preceded by their faces in a filtration */
template <class InputIterator> bool isConsistentFiltration( InputIterator begin, InputIterator end )
{
  using Simplex = typename std::iterator_traits<InputIterator>::value_type;

  // Contains all simplices that have already been 'seen' during the
  // traversal. If an unseen face is encountered, we have identified
  // an error.
  std::set<Simplex> seen;

  for( auto it = begin; it != end; ++it )
  {
    seen.insert( *it );

    for( auto itFace = it->begin_boundary(); itFace != it->end_boundary(); ++itFace )
      if( seen.find( *itFace ) == seen.end() )
        return false;
  }

  return true;
}

template <class Data, class Vertex> void triangle()
{
  ALEPH_TEST_BEGIN( "Triangle" );

  using Simplex           = Simplex<Data, Vertex>;
  using SimplicialComplex = SimplicialComplex<Simplex>;

  std::vector<Simplex> simplices
    = { {0}, {1}, {2}, {0,1}, {0,2}, {1,2} };

  SimplicialComplex K( simplices.begin(), simplices.end() );
  RipsExpander<SimplicialComplex> ripsExpander;

  auto vr1 = ripsExpander( K, 2 );
  auto vr2 = ripsExpander( K, 3 );

  ALEPH_ASSERT_THROW( vr1.empty() == false );
  ALEPH_ASSERT_THROW( vr2.empty() == false );
  ALEPH_ASSERT_THROW( vr1.size()  == vr2.size() );
  ALEPH_ASSERT_THROW( vr1.size()  == 7 );

  ALEPH_TEST_END();
}

template <class Data, class Vertex> void quad()
{
  ALEPH_TEST_BEGIN( "Quad" );

  using Simplex           = Simplex<Data, Vertex>;
  using SimplicialComplex = SimplicialComplex<Simplex>;

  std::vector<Simplex> simplices
    = { {0},
        {1},
        {2},
        {3},
        Simplex( {0,1}, Data(1) ),
        Simplex( {0,2}, Data( std::sqrt(2.0) ) ),
        Simplex( {1,2}, Data(1) ),
        Simplex( {2,3}, Data(1) ),
        Simplex( {0,3}, Data(1) ),
        Simplex( {1,3}, Data( std::sqrt(2.0) ) ) };

  SimplicialComplex K( simplices.begin(), simplices.end() );
  RipsExpander<SimplicialComplex> ripsExpander;

  auto vr1 = ripsExpander( K, 1 );
  auto vr2 = ripsExpander( K, 2 );
  auto vr3 = ripsExpander( K, 3 );

  vr1 = ripsExpander.assignMaximumWeight( vr1 );
  vr2 = ripsExpander.assignMaximumWeight( vr2 );
  vr3 = ripsExpander.assignMaximumWeight( vr3 );

  vr1.sort( filtrations::Data<Simplex>() );
  vr2.sort( filtrations::Data<Simplex>() );
  vr3.sort( filtrations::Data<Simplex>() );

  ALEPH_ASSERT_THROW( vr1.empty() == false );
  ALEPH_ASSERT_THROW( vr2.empty() == false );
  ALEPH_ASSERT_THROW( vr3.empty() == false );

  ALEPH_ASSERT_THROW( vr1.size() == simplices.size()     );
  ALEPH_ASSERT_THROW( vr2.size() == vr1.size()       + 4 ); // +4 triangles
  ALEPH_ASSERT_THROW( vr3.size() == vr2.size()       + 1 ); // +1 tetrahedron

  ALEPH_ASSERT_THROW( isConsistentFiltration( vr1.begin(), vr1.end() ) );
  ALEPH_ASSERT_THROW( isConsistentFiltration( vr2.begin(), vr2.end() ) );
  ALEPH_ASSERT_THROW( isConsistentFiltration( vr3.begin(), vr3.end() ) );

  ALEPH_TEST_END();
}

template <class Data, class Vertex> void expanderComparison()
{
  ALEPH_TEST_BEGIN( "Rips expander comparison" );

  using Simplex           = Simplex<Data, Vertex>;
  using SimplicialComplex = SimplicialComplex<Simplex>;

  std::vector<Simplex> simplices
    = { {0},
        {1},
        {2},
        {3},
        Simplex( {0,1}, Data(1) ),
        Simplex( {0,2}, Data( std::sqrt(2.0) ) ),
        Simplex( {1,2}, Data(1) ),
        Simplex( {2,3}, Data(1) ),
        Simplex( {0,3}, Data(1) ),
        Simplex( {1,3}, Data( std::sqrt(2.0) ) ) };

  SimplicialComplex K( simplices.begin(), simplices.end() );

  RipsExpander<SimplicialComplex> re;
  RipsExpanderTopDown<SimplicialComplex> retd;

  auto K1 = re( K, 3 );
  auto K2 = retd( K, 3 );

  ALEPH_ASSERT_EQUAL( K1.size(), K2.size() );

  ALEPH_TEST_END();
}

int main()
{
  triangle<double, unsigned>();
  triangle<double, short   >();
  triangle<float,  unsigned>();
  triangle<float,  short   >();

  quad<double, unsigned>();
  quad<double, short   >();
  quad<float,  unsigned>();
  quad<float,  short   >();

  expanderComparison<double, unsigned>();
  expanderComparison<double, short   >();
  expanderComparison<float,  unsigned>();
  expanderComparison<float,  short   >();
}
<|endoftext|>


<commit_before>/*
 *
 * copyright (c) 2010 ZAO Inventos (inventos.ru)
 * copyright (c) 2010 jk@inventos.ru
 * copyright (c) 2010 kuzalex@inventos.ru
 * copyright (c) 2010 artint@inventos.ru
 *
 * This file is part of mp4frag.
 *
 * mp4grag 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.
 *
 * mp4frag 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.
 */

#ifndef __mp4_hh__c6051ba6_1c2a_4b5d_b3ec_a4d3401a9df3
#define __mp4_hh__c6051ba6_1c2a_4b5d_b3ec_a4d3401a9df3

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <vector>
#include <iostream>
#include <stack>

namespace mp4 {

    class Context;

    class Parser : public ::boost::enable_shared_from_this<Parser> {
        friend class Context;
    protected:
        Context *_ctx;
        uint32_t _total;
        uint32_t _wants;
        uint32_t _to_skip;
        ::boost::shared_ptr<Parser> _up;
    public:
        Parser() : _ctx(0), _total(0), _wants(0), _to_skip(0) {}
        virtual ~Parser();
        virtual void parse(const char *data) = 0;
        size_t wants() const { return _wants; }
        void skip(uint32_t to_skip) { _to_skip = to_skip; }
    };

    struct Track {
        uint64_t _duration;
        uint32_t _timescale;
        uint32_t _pwidth, _pheight;
        std::vector<uint32_t> _sample_size;
        std::vector<std::pair<uint32_t, uint32_t> > _compos_deltas;
        std::vector<uint64_t> _chunk_offsets;
        std::vector<uint64_t> _stss;
        std::vector<std::pair<uint64_t, uint64_t> > _stts;
        std::vector<char> _extradata;

        struct SampleToChunk {
            uint32_t _first_chunk;
            uint32_t _samples_per_chunk;
            uint32_t _desc_index;
            SampleToChunk() {}
            SampleToChunk(uint32_t f, uint32_t s, uint32_t d) : _first_chunk(f), _samples_per_chunk(s), _desc_index(d) {}
        };
        std::vector<SampleToChunk> _samples_to_chunk;

        Track() : _duration(0), _pwidth(0), _pheight(0) {}
    };

    struct SampleInfo {
        uint64_t _timestamp;
        uint64_t _number;
        uint64_t _offset;
        uint32_t _composition_offset;
        uint32_t _timescale;
        uint32_t _sample_size;
        bool _video;
        bool _keyframe;

        double timestamp() const { return double(_timestamp) / _timescale; }
    };

    class MetaInfo {
        friend class Context;
        std::vector<SampleInfo> _samples;
        uint32_t _width;
        uint32_t _height;
        uint32_t _bitrate;
        double _duration;
        bool _has_video, _has_audio;
    };

    class Context {
    public:
        std::vector<SampleInfo> _samples;
    private:
        ::boost::shared_ptr<Parser> _parser;
        std::vector<char> _buffer;

    public:
        unsigned wants() const { return _parser->_wants; }
        unsigned total() const { return _parser->_total; }
        unsigned to_skip() const { return _parser->_to_skip; }

    public:
        Context();
        virtual ~Context();

        void skip(unsigned count) {
            _parser->_to_skip = count;
            assert ( _parser->_to_skip <= _parser->_total );
        }
        void push_state(const ::boost::shared_ptr<Parser>& p, unsigned total, unsigned wants);
        void pop_state();
        size_t feed(const char *data, size_t sz);
        ::boost::shared_ptr<Track> _current_parsed;

        // valid only after full parsing:
        ::boost::shared_ptr<Track> _video;
        ::boost::shared_ptr<Track> _audio;
        uint32_t _width;
        uint32_t _height;
        uint32_t _pwidth, _pheight;
        std::string _videoextra, _audioextra;
        uint32_t _bitrate;
        double _duration;
        bool _has_video, _has_audio;

        void _unfold(const ::boost::shared_ptr<Track>& track, bool is_video);
        void finalize();

        unsigned find_sample(double timestamp);
        unsigned nsamples() const { return _samples.size(); }
        SampleInfo *get_sample(unsigned si) { return &_samples[si]; }

        bool has_video() const { return _has_video; }
        bool has_audio() const { return _has_audio; }
        uint32_t width() const { return _width; }
        uint32_t height() const { return _height; }
        uint32_t pwidth() const { return _pwidth; }
        uint32_t pheight() const { return _pheight; }
        uint32_t bitrate() const { return _bitrate; }
        double duration() const { return _duration; }
        const std::string& videoextra() const { return _videoextra; }
        const std::string& audioextra() const { return _audioextra; }

    };
}

::std::ostream& operator<<(::std::ostream&, const mp4::Track&);
::std::ostream& operator<<(::std::ostream&, const mp4::SampleInfo&);

#endif
<commit_msg>stdint header<commit_after>/*
 *
 * copyright (c) 2010 ZAO Inventos (inventos.ru)
 * copyright (c) 2010 jk@inventos.ru
 * copyright (c) 2010 kuzalex@inventos.ru
 * copyright (c) 2010 artint@inventos.ru
 *
 * This file is part of mp4frag.
 *
 * mp4grag 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.
 *
 * mp4frag 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.
 */

#ifndef __mp4_hh__c6051ba6_1c2a_4b5d_b3ec_a4d3401a9df3
#define __mp4_hh__c6051ba6_1c2a_4b5d_b3ec_a4d3401a9df3

#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <vector>
#include <iostream>
#include <stack>

namespace mp4 {

    class Context;

    class Parser : public ::boost::enable_shared_from_this<Parser> {
        friend class Context;
    protected:
        Context *_ctx;
        uint32_t _total;
        uint32_t _wants;
        uint32_t _to_skip;
        ::boost::shared_ptr<Parser> _up;
    public:
        Parser() : _ctx(0), _total(0), _wants(0), _to_skip(0) {}
        virtual ~Parser();
        virtual void parse(const char *data) = 0;
        size_t wants() const { return _wants; }
        void skip(uint32_t to_skip) { _to_skip = to_skip; }
    };

    struct Track {
        uint64_t _duration;
        uint32_t _timescale;
        uint32_t _pwidth, _pheight;
        std::vector<uint32_t> _sample_size;
        std::vector<std::pair<uint32_t, uint32_t> > _compos_deltas;
        std::vector<uint64_t> _chunk_offsets;
        std::vector<uint64_t> _stss;
        std::vector<std::pair<uint64_t, uint64_t> > _stts;
        std::vector<char> _extradata;

        struct SampleToChunk {
            uint32_t _first_chunk;
            uint32_t _samples_per_chunk;
            uint32_t _desc_index;
            SampleToChunk() {}
            SampleToChunk(uint32_t f, uint32_t s, uint32_t d) : _first_chunk(f), _samples_per_chunk(s), _desc_index(d) {}
        };
        std::vector<SampleToChunk> _samples_to_chunk;

        Track() : _duration(0), _pwidth(0), _pheight(0) {}
    };

    struct SampleInfo {
        uint64_t _timestamp;
        uint64_t _number;
        uint64_t _offset;
        uint32_t _composition_offset;
        uint32_t _timescale;
        uint32_t _sample_size;
        bool _video;
        bool _keyframe;

        double timestamp() const { return double(_timestamp) / _timescale; }
    };

    class MetaInfo {
        friend class Context;
        std::vector<SampleInfo> _samples;
        uint32_t _width;
        uint32_t _height;
        uint32_t _bitrate;
        double _duration;
        bool _has_video, _has_audio;
    };

    class Context {
    public:
        std::vector<SampleInfo> _samples;
    private:
        ::boost::shared_ptr<Parser> _parser;
        std::vector<char> _buffer;

    public:
        unsigned wants() const { return _parser->_wants; }
        unsigned total() const { return _parser->_total; }
        unsigned to_skip() const { return _parser->_to_skip; }

    public:
        Context();
        virtual ~Context();

        void skip(unsigned count) {
            _parser->_to_skip = count;
            assert ( _parser->_to_skip <= _parser->_total );
        }
        void push_state(const ::boost::shared_ptr<Parser>& p, unsigned total, unsigned wants);
        void pop_state();
        size_t feed(const char *data, size_t sz);
        ::boost::shared_ptr<Track> _current_parsed;

        // valid only after full parsing:
        ::boost::shared_ptr<Track> _video;
        ::boost::shared_ptr<Track> _audio;
        uint32_t _width;
        uint32_t _height;
        uint32_t _pwidth, _pheight;
        std::string _videoextra, _audioextra;
        uint32_t _bitrate;
        double _duration;
        bool _has_video, _has_audio;

        void _unfold(const ::boost::shared_ptr<Track>& track, bool is_video);
        void finalize();

        unsigned find_sample(double timestamp);
        unsigned nsamples() const { return _samples.size(); }
        SampleInfo *get_sample(unsigned si) { return &_samples[si]; }

        bool has_video() const { return _has_video; }
        bool has_audio() const { return _has_audio; }
        uint32_t width() const { return _width; }
        uint32_t height() const { return _height; }
        uint32_t pwidth() const { return _pwidth; }
        uint32_t pheight() const { return _pheight; }
        uint32_t bitrate() const { return _bitrate; }
        double duration() const { return _duration; }
        const std::string& videoextra() const { return _videoextra; }
        const std::string& audioextra() const { return _audioextra; }

    };
}

::std::ostream& operator<<(::std::ostream&, const mp4::Track&);
::std::ostream& operator<<(::std::ostream&, const mp4::SampleInfo&);

#endif
<|endoftext|>


<commit_before>#include "multisource.h"
#include "simple_label.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>

int really_read(int sock, void* in, size_t count)
{
  char* buf = (char*)in;
  size_t done = 0;
  int r = 0;
  while (done < count)
    {
      if ((r = read(sock,buf,count-done)) == 0)
	return 0;
      else
	if (r < 0)
	  {
	    cerr << "argh! bad read! " << endl;
	    perror(NULL);
	    exit(0);
	  }
	else
	  {
	    done += r;
	    buf += r;
	  }
    }
  return done;
}

bool blocking_get_prediction(int sock, prediction &p)
{
  int count = really_read(sock, &p, sizeof(p));
  bool ret = (count == sizeof(p));
  return ret;
}

size_t recv_count = 0;
bool blocking_get_global_prediction(int sock, global_prediction &p)
{
  int count = really_read(sock, &p, sizeof(p));
  bool ret = (count == sizeof(p));
  if (ret)
    recv_count++;
  return ret;
}

void send_prediction(int sock, prediction &p)
{
  if (write(sock, &p, sizeof(p)) < (int)sizeof(p))
    {
      cerr << "argh! bad write! " << endl;
      perror(NULL);
      exit(0);
    }
}

size_t send_count = 0;

void send_global_prediction(int sock, global_prediction p)
{
  if (write(sock, &p, sizeof(p)) < (int)sizeof(p))
    {
      cerr << "argh! bad global write! " << sock << endl;
      perror(NULL);
      exit(0);
    }
  else
    send_count++;
}

void reset(partial_example &ex)
{
  ex.features.erase();
}

size_t num_finished = 0;

int receive_features(parser* p, void* ex)
{
  example* ae = (example*)ex;
  io_buf* input = p->input;
  fd_set fds;
  FD_ZERO(&fds);
  for (int* sock= input->files.begin; sock != input->files.end-num_finished; sock++)
    FD_SET(*sock,&fds);

  while (input->files.index() > num_finished)
    {
      if (select(p->max_fd,&fds,NULL, NULL, NULL) == -1)
	{
	  cerr << "Select failed!" << endl;
	  perror(NULL);
	  exit (1);
	}
      for (int index = 0; index < (int)input->files.index(); index++)
	{
	  int sock = input->files[index];
	  if (FD_ISSET(sock, &fds))
	    {//there is a feature or label to read
	      prediction pre;
	      if (!blocking_get_prediction(sock, pre) )
		{
		  FD_CLR(sock, &fds);
		  int swap_target = input->files.index()-num_finished-1;
		  input->files[index]=input->files[swap_target];
		  input->files[swap_target]=sock;
		  int temp = p->ids[index];
		  p->ids[index]=p->ids[swap_target];
		  p->ids[swap_target] = temp;
		  temp = p->counts[index];
		  p->counts[index]=p->counts[swap_target];
		  p->counts[swap_target] = temp;
		  num_finished++;
		}
	      else
		{
		  if (pre.example_number != ++ (p->counts[index]))
		    cout << "count is off! " << pre.example_number << " != " << p->counts[index] <<
		      " for source " << index << " prediction = " << pre.p << endl;
		  if (pre.example_number == p->finished_count + ring_size - 1)
		    FD_CLR(sock,&fds);//this ones to far ahead, let the buffer fill for awhile.
		  size_t ring_index = pre.example_number % p->pes.index();
		  if (p->pes[ring_index].features.index() == 0)
		    p->pes[ring_index].example_number = pre.example_number;
		  if (p->pes[ring_index].example_number != (int)pre.example_number)
		    cerr << "Error, example " << p->pes[ring_index].example_number << " != " << pre.example_number << endl;
		  feature f = {pre.p, p->ids[index]};
		  push(p->pes[ring_index].features, f);
		  if (sock == p->label_sock) // The label source
		    {
		      label_data ld;
		      size_t len = sizeof(ld.label)+sizeof(ld.weight);
		      char c[len];
		      really_read(sock,c,len);
		      bufread_simple_label(&(p->pes[ring_index].ld), c);
		    }

		  if( p->pes[ring_index].features.index() == input->count )
		    {
		      push( ae->indices, multindex );
		      push_many( ae->atomics[multindex], p->pes[ring_index].features.begin, p->pes[ring_index].features.index() );
		      label_data* ld = (label_data*)ae->ld;
		      *ld = p->pes[ring_index].ld;
		      reset(p->pes[ring_index]);
		      p->finished_count++;
		      return ae->atomics[multindex].index();
		    }
		}
	    }
	  else  if (p->counts[index] < p->finished_count + ring_size -1)
	    FD_SET(sock,&fds);
	}
    }
  return 0;
}

<commit_msg>fixed multisource.cc for many sources<commit_after>#include "multisource.h"
#include "simple_label.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>

int really_read(int sock, void* in, size_t count)
{
  char* buf = (char*)in;
  size_t done = 0;
  int r = 0;
  while (done < count)
    {
      if ((r = read(sock,buf,count-done)) == 0)
	return 0;
      else
	if (r < 0)
	  {
	    cerr << "argh! bad read! " << endl;
	    perror(NULL);
	    exit(0);
	  }
	else
	  {
	    done += r;
	    buf += r;
	  }
    }
  return done;
}

bool blocking_get_prediction(int sock, prediction &p)
{
  int count = really_read(sock, &p, sizeof(p));
  bool ret = (count == sizeof(p));
  return ret;
}

size_t recv_count = 0;
bool blocking_get_global_prediction(int sock, global_prediction &p)
{
  int count = really_read(sock, &p, sizeof(p));
  bool ret = (count == sizeof(p));
  if (ret)
    recv_count++;
  return ret;
}

void send_prediction(int sock, prediction &p)
{
  if (write(sock, &p, sizeof(p)) < (int)sizeof(p))
    {
      cerr << "argh! bad write! " << endl;
      perror(NULL);
      exit(0);
    }
}

size_t send_count = 0;

void send_global_prediction(int sock, global_prediction p)
{
  if (write(sock, &p, sizeof(p)) < (int)sizeof(p))
    {
      cerr << "argh! bad global write! " << sock << endl;
      perror(NULL);
      exit(0);
    }
  else
    send_count++;
}

void reset(partial_example &ex)
{
  ex.features.erase();
}

size_t num_finished = 0;

int receive_features(parser* p, void* ex)
{
  example* ae = (example*)ex;
  io_buf* input = p->input;
  fd_set fds;
  FD_ZERO(&fds);
  for (int* sock= input->files.begin; sock != input->files.end-num_finished; sock++)
    FD_SET(*sock,&fds);

  while (input->files.index() > num_finished)
    {
      if (select(p->max_fd,&fds,NULL, NULL, NULL) == -1)
	{
	  cerr << "Select failed!" << endl;
	  perror(NULL);
	  exit (1);
	}
      for (int index = 0; index < (int)(input->files.index()-num_finished); index++)
	{
	  int sock = input->files[index];
	  if (FD_ISSET(sock, &fds))
	    {//there is a feature or label to read
	      prediction pre;
	      if (!blocking_get_prediction(sock, pre) )
		{
		  FD_CLR(sock, &fds);
		  int swap_target = input->files.index()-num_finished-1;
		  input->files[index]=input->files[swap_target];
		  input->files[swap_target]=sock;
		  int temp = p->ids[index];
		  p->ids[index]=p->ids[swap_target];
		  p->ids[swap_target] = temp;
		  temp = p->counts[index];
		  p->counts[index]=p->counts[swap_target];
		  p->counts[swap_target] = temp;
		  num_finished++;
		  index--;
		}
	      else
		{
		  if (pre.example_number != ++ (p->counts[index]))
		    cout << "count is off! " << pre.example_number << " != " << p->counts[index] <<
		      " for source " << index << " prediction = " << pre.p << endl;
		  if (pre.example_number == p->finished_count + ring_size - 1)
		    FD_CLR(sock,&fds);//this ones to far ahead, let the buffer fill for awhile.
		  size_t ring_index = pre.example_number % p->pes.index();
		  if (p->pes[ring_index].features.index() == 0)
		    p->pes[ring_index].example_number = pre.example_number;
		  if (p->pes[ring_index].example_number != (int)pre.example_number)
		    cerr << "Error, example " << p->pes[ring_index].example_number << " != " << pre.example_number << endl;
		  feature f = {pre.p, p->ids[index]};
		  push(p->pes[ring_index].features, f);
		  if (sock == p->label_sock) // The label source
		    {
		      label_data ld;
		      size_t len = sizeof(ld.label)+sizeof(ld.weight);
		      char c[len];
		      really_read(sock,c,len);
		      bufread_simple_label(&(p->pes[ring_index].ld), c);
		    }

		  if( p->pes[ring_index].features.index() == input->count )
		    {
		      push( ae->indices, multindex );
		      push_many( ae->atomics[multindex], p->pes[ring_index].features.begin, p->pes[ring_index].features.index() );
		      label_data* ld = (label_data*)ae->ld;
		      *ld = p->pes[ring_index].ld;
		      reset(p->pes[ring_index]);
		      p->finished_count++;
		      return ae->atomics[multindex].index();
		    }
		}
	    }
	  else  if (p->counts[index] < p->finished_count + ring_size -1)
	    FD_SET(sock,&fds);
	}
    }
  return 0;
}

<|endoftext|>


<commit_before><commit_msg>Revert r18683: "Add more CHECKs to ClientSocketPoolBase." Looks like it might have broken block-test.html somehow.<commit_after><|endoftext|>


<commit_before>// Copyright eeGeo Ltd (2012-2015), All Rights Reserved

#include "MyPinCreationConfirmationViewModel.h"

namespace ExampleApp
{
    namespace MyPinCreation
    {
        namespace View
        {
            MyPinCreationConfirmationViewModel::MyPinCreationConfirmationViewModel(Eegeo::Helpers::TIdentity identity,
                    bool initiallyOnScreen,
                    Reaction::View::IReactionControllerModel& reactionControllerModel)

                : m_screenControl(initiallyOnScreen, identity)
                , m_openable(identity, reactionControllerModel)
            {

            }

            ScreenControl::View::IScreenControlViewModel& MyPinCreationConfirmationViewModel::GetScreenControlViewModel()
            {
                return m_screenControl;
            }

            OpenableControl::View::IOpenableControlViewModel& MyPinCreationConfirmationViewModel::GetOpenableControlViewModel()
            {
                return m_openable;
            }

            Eegeo::Helpers::TIdentity MyPinCreationConfirmationViewModel::GetIdentity() const
            {
                return m_screenControl.GetIdentity();
            }

            void MyPinCreationConfirmationViewModel::AddToScreen()
            {
                m_screenControl.AddToScreen();
            }

            void MyPinCreationConfirmationViewModel::RemoveFromScreen()
            {
                m_screenControl.RemoveFromScreen();
            }

            void MyPinCreationConfirmationViewModel::UpdateOnScreenState(float onScreenState)
            {
                m_screenControl.UpdateOnScreenState(onScreenState);
            }

            void MyPinCreationConfirmationViewModel::InsertOnScreenStateChangedCallback(Eegeo::Helpers::ICallback2<ScreenControl::View::IScreenControlViewModel&, float>& callback)
            {
                m_screenControl.InsertOnScreenStateChangedCallback(callback);
            }

            void MyPinCreationConfirmationViewModel::RemoveOnScreenStateChangedCallback(Eegeo::Helpers::ICallback2<ScreenControl::View::IScreenControlViewModel&, float>& callback)
            {
                m_screenControl.RemoveOnScreenStateChangedCallback(callback);
            }

            bool MyPinCreationConfirmationViewModel::IsFullyOffScreen() const
            {
                return m_screenControl.IsFullyOffScreen();
            }

            bool MyPinCreationConfirmationViewModel::IsFullyOnScreen() const
            {
                return m_screenControl.IsFullyOnScreen();
            }

            float MyPinCreationConfirmationViewModel::OnScreenState() const
            {
                return m_screenControl.OnScreenState();
            }

            bool MyPinCreationConfirmationViewModel::IsAddedToScreen() const
            {
                return m_screenControl.IsAddedToScreen();
            }

            bool MyPinCreationConfirmationViewModel::TryOpen()
            {
                if(!m_screenControl.IsAddedToScreen())
                {
                    return false;
                }
                return m_openable.TryAcquireReactorControl();
            }

            void MyPinCreationConfirmationViewModel::Close()
            {
                m_openable.ReleaseReactorControl();
            }
        }
    }
}
<commit_msg>Removing Added to Screen check from MyPinCreationConfirmationViewModel. Buddy Tom H<commit_after>// Copyright eeGeo Ltd (2012-2015), All Rights Reserved

#include "MyPinCreationConfirmationViewModel.h"

namespace ExampleApp
{
    namespace MyPinCreation
    {
        namespace View
        {
            MyPinCreationConfirmationViewModel::MyPinCreationConfirmationViewModel(Eegeo::Helpers::TIdentity identity,
                    bool initiallyOnScreen,
                    Reaction::View::IReactionControllerModel& reactionControllerModel)

                : m_screenControl(initiallyOnScreen, identity)
                , m_openable(identity, reactionControllerModel)
            {

            }

            ScreenControl::View::IScreenControlViewModel& MyPinCreationConfirmationViewModel::GetScreenControlViewModel()
            {
                return m_screenControl;
            }

            OpenableControl::View::IOpenableControlViewModel& MyPinCreationConfirmationViewModel::GetOpenableControlViewModel()
            {
                return m_openable;
            }

            Eegeo::Helpers::TIdentity MyPinCreationConfirmationViewModel::GetIdentity() const
            {
                return m_screenControl.GetIdentity();
            }

            void MyPinCreationConfirmationViewModel::AddToScreen()
            {
                m_screenControl.AddToScreen();
            }

            void MyPinCreationConfirmationViewModel::RemoveFromScreen()
            {
                m_screenControl.RemoveFromScreen();
            }

            void MyPinCreationConfirmationViewModel::UpdateOnScreenState(float onScreenState)
            {
                m_screenControl.UpdateOnScreenState(onScreenState);
            }

            void MyPinCreationConfirmationViewModel::InsertOnScreenStateChangedCallback(Eegeo::Helpers::ICallback2<ScreenControl::View::IScreenControlViewModel&, float>& callback)
            {
                m_screenControl.InsertOnScreenStateChangedCallback(callback);
            }

            void MyPinCreationConfirmationViewModel::RemoveOnScreenStateChangedCallback(Eegeo::Helpers::ICallback2<ScreenControl::View::IScreenControlViewModel&, float>& callback)
            {
                m_screenControl.RemoveOnScreenStateChangedCallback(callback);
            }

            bool MyPinCreationConfirmationViewModel::IsFullyOffScreen() const
            {
                return m_screenControl.IsFullyOffScreen();
            }

            bool MyPinCreationConfirmationViewModel::IsFullyOnScreen() const
            {
                return m_screenControl.IsFullyOnScreen();
            }

            float MyPinCreationConfirmationViewModel::OnScreenState() const
            {
                return m_screenControl.OnScreenState();
            }

            bool MyPinCreationConfirmationViewModel::IsAddedToScreen() const
            {
                return m_screenControl.IsAddedToScreen();
            }

            bool MyPinCreationConfirmationViewModel::TryOpen()
            {
                return m_openable.TryAcquireReactorControl();
            }

            void MyPinCreationConfirmationViewModel::Close()
            {
                m_openable.ReleaseReactorControl();
            }
        }
    }
}
<|endoftext|>