<commit_before>/*
* This source file is part of ArkGameFrame
* For the latest info, see https://github.com/ArkGame
*
* Copyright (c) 2013-2018 ArkGame authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#pragma once

#include "AFMacros.hpp"

#if ARK_PLATFORM == PLATFORM_WIN
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#endif

class AFMisc
{
public:
    static uint32_t GetNearest2N(uint32_t size)
    {
        if (size == 0)
        {
            return 0;
        }

        if (size <= 8)
        {
            return 8;
        }

        if (size > (1 << 16))
        {
            return 0;
        }

        if ((size & (size - 1)) == 0)
        {
            return size;
        }

        int count = 0;

        while (size)
        {
            size = size >> 1;
            ++count;
        }

        return 1 << count;
    }

    static bool IsZeroFloat(const float value)
    {
        return std::abs(value) < std::numeric_limits<float>::epsilon();
    }

    static bool IsZeroDouble(const double value)
    {
        return std::abs(value) < std::numeric_limits<double>::epsilon();
    }

    static bool IsFloatEqual(const float lhs, const float rhs)
    {
        return std::abs(lhs - rhs) < std::numeric_limits<float>::epsilon();
    }

    static bool IsDoubleEqual(const double lhs, const double rhs)
    {
        return std::abs(lhs - rhs) < std::numeric_limits<double>::epsilon();
    }

    template<typename T>
    static bool ARK_FROM_STR(const std::string& strValue, T& nValue)
    {
        try
        {
            nValue = ARK_LEXICAL_CAST<T>(strValue);
            return true;
        }
        catch (std::system_error& ex)
        {
            std::cout << "ARK_FROM_STR failed, code = " << ex.code().message() << " msg = " << ex.what() << std::endl;
            ARK_ASSERT_NO_EFFECT(0);
            return false;
        }

        return false;
    }

    template<typename T>
    static bool ARK_TO_STR(std::string& strValue, const T& nValue)
    {
        try
        {
            strValue = ARK_LEXICAL_CAST<std::string>(nValue);
            return true;
        }
        catch (std::system_error& ex)
        {
            std::cout << "ARK_TO_STR failed, code = " << ex.code().message() << " msg = " << ex.what() << std::endl;
            ARK_ASSERT_NO_EFFECT(0);
            return false;
        }

        return false;
    }

    static std::string ToLower(std::string s)
    {
        std::transform(s.begin(), s.end(), s.begin(),
                       [](unsigned char c)
        {
            return std::tolower(c);
        });

        return s;
    }
    static std::string ToUpper(std::string s)
    {
        std::transform(s.begin(), s.end(), s.begin(),
                       [](unsigned char c)
        {
            return std::toupper(c);
        });

        return s;
    }

    static bool IsDigit(const std::string& str)
    {
        if (str.empty())
        {
            return false;
        }

        string::const_iterator start = str.begin();
        if (*start == '-')
            ++start;

        return (std::all_of(start, str.end(), [](unsigned char c)
        {
            return isdigit(c);
        }));
    }

    static bool IsDomain(const std::string& host)
    {
        return (inet_addr(host.c_str()) != INADDR_NONE);
    }

    static bool GetHost(const std::string& host, bool& is_ip_v6, std::string& ip)
    {
        struct addrinfo hints, *answer, *curr;

        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_CANONNAME;
        hints.ai_protocol = 0;  /* any protocol */

        char ip_v4[16] = { 0 };
        char ip_v6[128] = { 0 };
        int ret = getaddrinfo(host.c_str(), NULL, &hints, &answer);
        for (curr = answer; curr != NULL; curr = curr->ai_next)
        {
            if (curr->ai_protocol == IPPROTO_IPV6)
            {
                is_ip_v6 = true;
                inet_ntop(AF_INET6, &(((struct sockaddr_in6*)(curr->ai_addr))->sin6_addr), ip_v6, sizeof(ip_v6));
                ip = ip_v6;
            }
            else if (curr->ai_protocol == IPPROTO_IPV4)
            {
                is_ip_v6 = false;
                inet_ntop(AF_INET, &(((struct sockaddr_in*)(curr->ai_addr))->sin_addr), ip_v4, sizeof(ip_v4));
                ip = ip_v4;
            }

            return true;
        }

        return false;
    }
};<commit_msg>check IPV4 or V6 by using AF_FAMILY<commit_after>/*
* This source file is part of ArkGameFrame
* For the latest info, see https://github.com/ArkGame
*
* Copyright (c) 2013-2018 ArkGame authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#pragma once

#include "AFMacros.hpp"

#if ARK_PLATFORM == PLATFORM_WIN
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#endif

class AFMisc
{
public:
    static uint32_t GetNearest2N(uint32_t size)
    {
        if (size == 0)
        {
            return 0;
        }

        if (size <= 8)
        {
            return 8;
        }

        if (size > (1 << 16))
        {
            return 0;
        }

        if ((size & (size - 1)) == 0)
        {
            return size;
        }

        int count = 0;

        while (size)
        {
            size = size >> 1;
            ++count;
        }

        return 1 << count;
    }

    static bool IsZeroFloat(const float value)
    {
        return std::abs(value) < std::numeric_limits<float>::epsilon();
    }

    static bool IsZeroDouble(const double value)
    {
        return std::abs(value) < std::numeric_limits<double>::epsilon();
    }

    static bool IsFloatEqual(const float lhs, const float rhs)
    {
        return std::abs(lhs - rhs) < std::numeric_limits<float>::epsilon();
    }

    static bool IsDoubleEqual(const double lhs, const double rhs)
    {
        return std::abs(lhs - rhs) < std::numeric_limits<double>::epsilon();
    }

    template<typename T>
    static bool ARK_FROM_STR(const std::string& strValue, T& nValue)
    {
        try
        {
            nValue = ARK_LEXICAL_CAST<T>(strValue);
            return true;
        }
        catch (std::system_error& ex)
        {
            std::cout << "ARK_FROM_STR failed, code = " << ex.code().message() << " msg = " << ex.what() << std::endl;
            ARK_ASSERT_NO_EFFECT(0);
            return false;
        }

        return false;
    }

    template<typename T>
    static bool ARK_TO_STR(std::string& strValue, const T& nValue)
    {
        try
        {
            strValue = ARK_LEXICAL_CAST<std::string>(nValue);
            return true;
        }
        catch (std::system_error& ex)
        {
            std::cout << "ARK_TO_STR failed, code = " << ex.code().message() << " msg = " << ex.what() << std::endl;
            ARK_ASSERT_NO_EFFECT(0);
            return false;
        }

        return false;
    }

    static std::string ToLower(std::string s)
    {
        std::transform(s.begin(), s.end(), s.begin(),
                       [](unsigned char c)
        {
            return std::tolower(c);
        });

        return s;
    }
    static std::string ToUpper(std::string s)
    {
        std::transform(s.begin(), s.end(), s.begin(),
                       [](unsigned char c)
        {
            return std::toupper(c);
        });

        return s;
    }

    static bool IsDigit(const std::string& str)
    {
        if (str.empty())
        {
            return false;
        }

        string::const_iterator start = str.begin();
        if (*start == '-')
            ++start;

        return (std::all_of(start, str.end(), [](unsigned char c)
        {
            return isdigit(c);
        }));
    }

    static bool IsDomain(const std::string& host)
    {
        return (inet_addr(host.c_str()) != INADDR_NONE);
    }

    static bool GetHost(const std::string& host, bool& is_ip_v6, std::string& ip)
    {
        struct addrinfo hints, *answer, *curr;

        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_CANONNAME;
        hints.ai_protocol = 0;  /* any protocol */

        char ip_v4[16] = { 0 };
        char ip_v6[128] = { 0 };
        int ret = getaddrinfo(host.c_str(), NULL, &hints, &answer);
        if (ret != 0)
        {
            return false;
        }

        for (curr = answer; curr != NULL; curr = curr->ai_next)
        {
            int pf_family = answer->ai_family;
            switch (answer->ai_family)
            {
            case PF_INET:
                {
                    is_ip_v6 = false;
                    inet_ntop(AF_INET, &(((struct sockaddr_in*)(curr->ai_addr))->sin_addr), ip_v4, sizeof(ip_v4));
                    ip = ip_v4;
                }
                break;
            case PF_INET6:
                {
                    is_ip_v6 = true;
                    inet_ntop(AF_INET6, &(((struct sockaddr_in6*)(curr->ai_addr))->sin6_addr), ip_v6, sizeof(ip_v6));
                    ip = ip_v6;
                }
                break;
            default:
                return false;
            }

            return true;
        }

        return false;
    }
};<|endoftext|>


<commit_before>/***************************************************************************
                          kmailcvt2.cpp  -  description
                             -------------------
    begin                : Wed Aug  2 11:23:04 CEST 2000
    copyright            : (C) 2000 by Hans Dijkema
    email                : kmailcvt@hum.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kmailcvt.h"
#include <kaboutdialog.h>
#include <klocale.h>
#include <qgrid.h>
#include <qlayout.h>

//////////////////////////////////////////////////////////////////////////////
//
// Add filters here
//
//////////////////////////////////////////////////////////////////////////////

#include "filter_oe4.hxx"
#include "filter_oe5.hxx"
#include "filter_pmail.hxx"
#include "filter_pab.hxx"
#include "filter_eudora_ab.hxx"
#include "filter_ldif.hxx"

void Kmailcvt2::doFilters(void)
{
  imports->add(new filter_oe5);
  imports->add(new filter_pmail);
  imports->add(new filter_oe4);
  imports->add(new filter_pab);
  imports->add(new filter_ldif);
  imports->add(new filter_eudora_ab);
}

Kmailcvt2::Kmailcvt2(QWidget *parent, const char *name) : QWidget(parent, name)
{
  QGridLayout *grid1 = new QGridLayout(this,15,8,15,7);
  info=new filterInfo(this);

  grid1->addMultiCellWidget(info, 2,14,0,7);
  imports=new filters(info,this);
  grid1->addMultiCellWidget(imports, 0,0,0,5);
  doFilters();

  import=new QPushButton(i18n("&Import"),this);
  grid1->addWidget(import, 0,6);

  quit=new QPushButton(i18n("&Quit"),this);
  grid1->addWidget(quit, 0,7);

  about=new QPushButton(i18n("&About"),this);
  grid1->addWidget(about,1 ,7);

  connect(import,SIGNAL(clicked()),SLOT(startFilter()));
  connect(quit,SIGNAL(clicked()),SLOT(Quit()));
  connect(about,SIGNAL(clicked()),SLOT(About()));

  setCaption(KMAILCVT KMAILCVT_VERSION);
}

Kmailcvt2::~Kmailcvt2()
{
  delete imports;
  delete import;
  delete quit;
}

void Kmailcvt2::startFilter()
{
  import->setEnabled(false);
  imports->setEnabled(false);
  quit->setEnabled(false);
  about->setEnabled(false);

  imports->import();

  imports->setEnabled(true);
  import->setEnabled(true);
  quit->setEnabled(true);
  about->setEnabled(true);
}

void Kmailcvt2::Quit()
{
  close();
}

void Kmailcvt2::About()
{
QString cap=KMAILCVT KMAILCVT_VERSION;
/*
KAboutDialog dlg(KAboutDialog::AbtAppStandard,
                 cap,
                 KAboutDialog::Ok,
                 KAboutDialog::Ok,
                 this,
                 "kmailcvt2_about",
                 true
                );

  dlg.setTitle("Welcome to KMailCvt");
  dlg.setProduct(KMAILCVT,
                 KMAILCVT_VERSION,
                 "Hans Dijkema",
                 "2000"
                );
  dlg.setImage();
  dlg.addTextPage("Description",
                  "Converts various formats to Kmail and K Addressbook\n\n"
                  "Currently supported:\n\n"
                  "  - MS Outlook Express 5.0 .DBX format\n"
                  "  - MS Exchange Personal Addressbook .PAB format\n"
                  "\n"
                  "You are invited to contribute other import (or output)\n"
                  "formats. I you want to contribute, please contact me at\n"
                  "kmailcvt@hum.org\n"
                 );
*/
KAboutDialog dlg(this,"KmailCvt2");
  dlg.setLogo(KApplication::kApplication()->icon());
  {QString name="(c) 2000 Hans Dijkema",
           email="kmailcvt@hum.org",
           url="http://www.hum.org/kmailcvt.html",
           work=i18n("\n"
                "Converts various import formats to Kmail and K Addressbook  \n"
                "Currently supported formats:\n\n"
                );
           work+=imports->getFilters();
           work+=i18n("\n"
                "You are invited to contribute other import (or output)\n"
                "formats. I you want to contribute, please contact me.\n"
                "Translations are welcome too!"
                );
    dlg.setAuthor(name,email,url,work);
    dlg.adjust();
  }
  dlg.setVersion(KMAILCVT KMAILCVT_VERSION);
  {int X,Y;
     dlg.adjustSize();
     X=(width()-dlg.width())/2+x();
     Y=(height()-dlg.height())/2+y();
     dlg.move(X,Y);
  }
  dlg.show();
}

<commit_msg>Include kmailcvt.moc<commit_after>/***************************************************************************
                          kmailcvt2.cpp  -  description
                             -------------------
    begin                : Wed Aug  2 11:23:04 CEST 2000
    copyright            : (C) 2000 by Hans Dijkema
    email                : kmailcvt@hum.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kmailcvt.h"
#include <kaboutdialog.h>
#include <klocale.h>
#include <qgrid.h>
#include <qlayout.h>

//////////////////////////////////////////////////////////////////////////////
//
// Add filters here
//
//////////////////////////////////////////////////////////////////////////////

#include "filter_oe4.hxx"
#include "filter_oe5.hxx"
#include "filter_pmail.hxx"
#include "filter_pab.hxx"
#include "filter_eudora_ab.hxx"
#include "filter_ldif.hxx"

void Kmailcvt2::doFilters(void)
{
  imports->add(new filter_oe5);
  imports->add(new filter_pmail);
  imports->add(new filter_oe4);
  imports->add(new filter_pab);
  imports->add(new filter_ldif);
  imports->add(new filter_eudora_ab);
}

Kmailcvt2::Kmailcvt2(QWidget *parent, const char *name) : QWidget(parent, name)
{
  QGridLayout *grid1 = new QGridLayout(this,15,8,15,7);
  info=new filterInfo(this);

  grid1->addMultiCellWidget(info, 2,14,0,7);
  imports=new filters(info,this);
  grid1->addMultiCellWidget(imports, 0,0,0,5);
  doFilters();

  import=new QPushButton(i18n("&Import"),this);
  grid1->addWidget(import, 0,6);

  quit=new QPushButton(i18n("&Quit"),this);
  grid1->addWidget(quit, 0,7);

  about=new QPushButton(i18n("&About"),this);
  grid1->addWidget(about,1 ,7);

  connect(import,SIGNAL(clicked()),SLOT(startFilter()));
  connect(quit,SIGNAL(clicked()),SLOT(Quit()));
  connect(about,SIGNAL(clicked()),SLOT(About()));

  setCaption(KMAILCVT KMAILCVT_VERSION);
}

Kmailcvt2::~Kmailcvt2()
{
  delete imports;
  delete import;
  delete quit;
}

void Kmailcvt2::startFilter()
{
  import->setEnabled(false);
  imports->setEnabled(false);
  quit->setEnabled(false);
  about->setEnabled(false);

  imports->import();

  imports->setEnabled(true);
  import->setEnabled(true);
  quit->setEnabled(true);
  about->setEnabled(true);
}

void Kmailcvt2::Quit()
{
  close();
}

void Kmailcvt2::About()
{
QString cap=KMAILCVT KMAILCVT_VERSION;
/*
KAboutDialog dlg(KAboutDialog::AbtAppStandard,
                 cap,
                 KAboutDialog::Ok,
                 KAboutDialog::Ok,
                 this,
                 "kmailcvt2_about",
                 true
                );

  dlg.setTitle("Welcome to KMailCvt");
  dlg.setProduct(KMAILCVT,
                 KMAILCVT_VERSION,
                 "Hans Dijkema",
                 "2000"
                );
  dlg.setImage();
  dlg.addTextPage("Description",
                  "Converts various formats to Kmail and K Addressbook\n\n"
                  "Currently supported:\n\n"
                  "  - MS Outlook Express 5.0 .DBX format\n"
                  "  - MS Exchange Personal Addressbook .PAB format\n"
                  "\n"
                  "You are invited to contribute other import (or output)\n"
                  "formats. I you want to contribute, please contact me at\n"
                  "kmailcvt@hum.org\n"
                 );
*/
KAboutDialog dlg(this,"KmailCvt2");
  dlg.setLogo(KApplication::kApplication()->icon());
  {QString name="(c) 2000 Hans Dijkema",
           email="kmailcvt@hum.org",
           url="http://www.hum.org/kmailcvt.html",
           work=i18n("\n"
                "Converts various import formats to Kmail and K Addressbook  \n"
                "Currently supported formats:\n\n"
                );
           work+=imports->getFilters();
           work+=i18n("\n"
                "You are invited to contribute other import (or output)\n"
                "formats. I you want to contribute, please contact me.\n"
                "Translations are welcome too!"
                );
    dlg.setAuthor(name,email,url,work);
    dlg.adjust();
  }
  dlg.setVersion(KMAILCVT KMAILCVT_VERSION);
  {int X,Y;
     dlg.adjustSize();
     X=(width()-dlg.width())/2+x();
     Y=(height()-dlg.height())/2+y();
     dlg.move(X,Y);
  }
  dlg.show();
}

#include "kmailcvt.moc"
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _OSL_MUTEX_HXX_
#define _OSL_MUTEX_HXX_

#ifdef __cplusplus

#include <osl/mutex.h>

namespace osl
{
    /** A mutual exclusion synchronization object
    */
    class Mutex {

    public:
        /** Create a thread-local mutex.
            @return 0 if the mutex could not be created, otherwise a handle to the mutex.
            @seealso ::osl_createMutex()
        */
        Mutex()
        {
            mutex = osl_createMutex();
        }

        /** Release the OS-structures and free mutex data-structure.
            @seealso ::osl_destroyMutex()
        */
        ~Mutex()
        {
            osl_destroyMutex(mutex);
        }

        /** Acquire the mutex, block if already acquired by another thread.
            @return sal_False if system-call fails.
            @seealso ::osl_acquireMutex()
        */
        sal_Bool acquire()
        {
            return osl_acquireMutex(mutex);
        }

        /** Try to acquire the mutex without blocking.
            @return sal_False if it could not be acquired.
            @seealso ::osl_tryToAcquireMutex()
        */
        sal_Bool tryToAcquire()
        {
            return osl_tryToAcquireMutex(mutex);
        }

        /** Release the mutex.
            @return sal_False if system-call fails.
            @seealso ::osl_releaseMutex()
        */
        sal_Bool release()
        {
            return osl_releaseMutex(mutex);
        }

        /** Returns a global static mutex object.
            The global and static mutex object can be used to initialize other
            static objects in a thread safe manner.
            @return the global mutex object
            @seealso ::osl_getGlobalMutex()
        */
        static Mutex * getGlobalMutex()
        {
            return (Mutex *)osl_getGlobalMutex();
        }

    private:
        oslMutex mutex;

        /** The underlying oslMutex has no reference count.

        Since the underlying oslMutex is not a reference counted object, copy
        constructed Mutex may work on an already destructed oslMutex object.

        */
        Mutex(const Mutex&);

        /** The underlying oslMutex has no reference count.

        When destructed, the Mutex object destroys the undelying oslMutex,
        which might cause severe problems in case it's a temporary object.

        */
        Mutex(oslMutex Mutex);

        /** This assignment operator is private for the same reason as
            the copy constructor.
        */
        Mutex& operator= (const Mutex&);

        /** This assignment operator is private for the same reason as
            the constructor taking a oslMutex argument.
        */
        Mutex& operator= (oslMutex);
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class Guard
    {
    private:
        Guard( const Guard& );
        const Guard& operator = ( const Guard& );

    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        Guard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        Guard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface. */
        ~Guard()
        {
            pT->release();
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class ClearableGuard
    {
    private:
        ClearableGuard( const ClearableGuard& );
        const ClearableGuard& operator = ( const ClearableGuard& );
    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface if not already released by clear().
        */
        ~ClearableGuard()
        {
            if (pT)
                pT->release();
        }

        /** Releases the mutex or interface.
        */
        void clear()
        {
            if(pT)
            {
                pT->release();
                pT = NULL;
            }
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template< class T >
    class ResettableGuard : public ClearableGuard< T >
    {
    private:
        ResettableGuard(ResettableGuard &); // not defined
        void operator =(ResettableGuard &); // not defined

    protected:
        T* pResetT;
    public:
        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T* pT_ ) :
                ClearableGuard<T>( pT_ ),
                pResetT( pT_ )
        {}

        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T& rT ) :
                ClearableGuard<T>( rT ),
                pResetT( &rT )
        {}

        /** Re-aquires the mutex or interface.
        */
        void reset()
        {
            if( pResetT )
            {
                this->pT = pResetT;
                this->pT->acquire();
            }
        }
    };

    typedef Guard<Mutex> MutexGuard;
    typedef ClearableGuard<Mutex> ClearableMutexGuard;
    typedef ResettableGuard< Mutex > ResettableMutexGuard;
}

#endif  /* __cplusplus */
#endif  /* _OSL_MUTEX_HXX_ */

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Create an abstract interface to be used to implement a SolarMutex<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _OSL_MUTEX_HXX_
#define _OSL_MUTEX_HXX_

#ifdef __cplusplus

#include <osl/mutex.h>

namespace osl
{
    /** A mutual exclusion synchronization object
    */
    class Mutex {

    public:
        /** Create a thread-local mutex.
            @return 0 if the mutex could not be created, otherwise a handle to the mutex.
            @seealso ::osl_createMutex()
        */
        Mutex()
        {
            mutex = osl_createMutex();
        }

        /** Release the OS-structures and free mutex data-structure.
            @seealso ::osl_destroyMutex()
        */
        ~Mutex()
        {
            osl_destroyMutex(mutex);
        }

        /** Acquire the mutex, block if already acquired by another thread.
            @return sal_False if system-call fails.
            @seealso ::osl_acquireMutex()
        */
        sal_Bool acquire()
        {
            return osl_acquireMutex(mutex);
        }

        /** Try to acquire the mutex without blocking.
            @return sal_False if it could not be acquired.
            @seealso ::osl_tryToAcquireMutex()
        */
        sal_Bool tryToAcquire()
        {
            return osl_tryToAcquireMutex(mutex);
        }

        /** Release the mutex.
            @return sal_False if system-call fails.
            @seealso ::osl_releaseMutex()
        */
        sal_Bool release()
        {
            return osl_releaseMutex(mutex);
        }

        /** Returns a global static mutex object.
            The global and static mutex object can be used to initialize other
            static objects in a thread safe manner.
            @return the global mutex object
            @seealso ::osl_getGlobalMutex()
        */
        static Mutex * getGlobalMutex()
        {
            return (Mutex *)osl_getGlobalMutex();
        }

    private:
        oslMutex mutex;

        /** The underlying oslMutex has no reference count.

        Since the underlying oslMutex is not a reference counted object, copy
        constructed Mutex may work on an already destructed oslMutex object.

        */
        Mutex(const Mutex&);

        /** The underlying oslMutex has no reference count.

        When destructed, the Mutex object destroys the undelying oslMutex,
        which might cause severe problems in case it's a temporary object.

        */
        Mutex(oslMutex Mutex);

        /** This assignment operator is private for the same reason as
            the copy constructor.
        */
        Mutex& operator= (const Mutex&);

        /** This assignment operator is private for the same reason as
            the constructor taking a oslMutex argument.
        */
        Mutex& operator= (oslMutex);
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class Guard
    {
    private:
        Guard( const Guard& );
        const Guard& operator = ( const Guard& );

    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        Guard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        Guard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface. */
        ~Guard()
        {
            pT->release();
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class ClearableGuard
    {
    private:
        ClearableGuard( const ClearableGuard& );
        const ClearableGuard& operator = ( const ClearableGuard& );
    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface if not already released by clear().
        */
        ~ClearableGuard()
        {
            if (pT)
                pT->release();
        }

        /** Releases the mutex or interface.
        */
        void clear()
        {
            if(pT)
            {
                pT->release();
                pT = NULL;
            }
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template< class T >
    class ResettableGuard : public ClearableGuard< T >
    {
    private:
        ResettableGuard(ResettableGuard &); // not defined
        void operator =(ResettableGuard &); // not defined

    protected:
        T* pResetT;
    public:
        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T* pT_ ) :
                ClearableGuard<T>( pT_ ),
                pResetT( pT_ )
        {}

        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T& rT ) :
                ClearableGuard<T>( rT ),
                pResetT( &rT )
        {}

        /** Re-aquires the mutex or interface.
        */
        void reset()
        {
            if( pResetT )
            {
                this->pT = pResetT;
                this->pT->acquire();
            }
        }
    };

    typedef Guard<Mutex> MutexGuard;
    typedef ClearableGuard<Mutex> ClearableMutexGuard;
    typedef ResettableGuard< Mutex > ResettableMutexGuard;

    /** SolarMutex interface, needed for SolarMutex.
        Deprecated, used just for Application::GetSolarMutex().
    */
    class SolarMutex
    {
        public:
            /** Blocks if mutex is already in use
            */
            virtual void SAL_CALL acquire() = 0;

            /** Tries to get the mutex without blocking.
            */
            virtual sal_Bool SAL_CALL tryToAcquire() = 0;

            /** Releases the mutex.
            */
            virtual void SAL_CALL release() = 0;

        protected:
            SolarMutex() {}
            virtual ~SolarMutex() {}
    };
}

#endif  /* __cplusplus */
#endif  /* _OSL_MUTEX_HXX_ */

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: mutex.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: jl $ $Date: 2001-03-14 08:29:56 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _OSL_MUTEX_HXX_
#define _OSL_MUTEX_HXX_

#ifdef __cplusplus

#include <osl/mutex.h>

namespace osl
{

    class Mutex {
        oslMutex mutex;

        // these make no sense
        Mutex( oslMutex ) {}
        Mutex( const Mutex & ) {}

    public:
        /** Create a thread-local mutex.
            @return 0 if the mutex could not be created, otherwise a handle to the mutex.
        */
        Mutex()
        {
            mutex = osl_createMutex();
        }

        /** Release the OS-structures and free mutex data-structure.
        */
        ~Mutex()
        {
            osl_destroyMutex(mutex);
        }

        /** Acquire the mutex, block if already acquired by another thread.
            @return False if system-call fails.
        */
        sal_Bool acquire()
        {
            return osl_acquireMutex(mutex);
        }

        /** Try to acquire the mutex without blocking.
            @return False if it could not be acquired.
        */
        sal_Bool tryToAcquire()
        {
            return osl_tryToAcquireMutex(mutex);
        }

        /** Release the mutex.
            @return False if system-call fails.
        */
        sal_Bool release()
        {
            return osl_releaseMutex(mutex);
        }

        static Mutex * getGlobalMutex()
        {
            return (Mutex *)osl_getGlobalMutex();
        }
    };

    template<class T>
    class Guard
    {
    protected:
        T * pT;
    public:

        Guard(T * pT) : pT(pT)
        {
            pT->acquire();
        }

        Guard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases mutex. */
        ~Guard()
        {
            pT->release();
        }
    };

    template<class T>
    class ClearableGuard
    {
    protected:
        T * pT;
    public:

        ClearableGuard(T * pT) : pT(pT)
        {
            pT->acquire();
        }

        ClearableGuard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases mutex. */
        ~ClearableGuard()
        {
            if (pT)
                pT->release();
        }

        /** Releases mutex. */
        void clear()
        {
            if(pT)
            {
                pT->release();
                pT = NULL;
            }
        }
    };

    typedef Guard<Mutex> MutexGuard;
    typedef ClearableGuard<Mutex> ClearableMutexGuard;

}

#endif  /* __cplusplus */
#endif  /* _OSL_MUTEX_HXX_ */

<commit_msg>#88659# add: ResettableGuard<commit_after>/*************************************************************************
 *
 *  $RCSfile: mutex.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: pl $ $Date: 2001-06-22 10:49:45 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _OSL_MUTEX_HXX_
#define _OSL_MUTEX_HXX_

#ifdef __cplusplus

#include <osl/mutex.h>

namespace osl
{

    class Mutex {
        oslMutex mutex;

        // these make no sense
        Mutex( oslMutex ) {}
        Mutex( const Mutex & ) {}

    public:
        /** Create a thread-local mutex.
            @return 0 if the mutex could not be created, otherwise a handle to the mutex.
        */
        Mutex()
        {
            mutex = osl_createMutex();
        }

        /** Release the OS-structures and free mutex data-structure.
        */
        ~Mutex()
        {
            osl_destroyMutex(mutex);
        }

        /** Acquire the mutex, block if already acquired by another thread.
            @return False if system-call fails.
        */
        sal_Bool acquire()
        {
            return osl_acquireMutex(mutex);
        }

        /** Try to acquire the mutex without blocking.
            @return False if it could not be acquired.
        */
        sal_Bool tryToAcquire()
        {
            return osl_tryToAcquireMutex(mutex);
        }

        /** Release the mutex.
            @return False if system-call fails.
        */
        sal_Bool release()
        {
            return osl_releaseMutex(mutex);
        }

        static Mutex * getGlobalMutex()
        {
            return (Mutex *)osl_getGlobalMutex();
        }
    };

    template<class T>
    class Guard
    {
    protected:
        T * pT;
    public:

        Guard(T * pT) : pT(pT)
        {
            pT->acquire();
        }

        Guard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases mutex. */
        ~Guard()
        {
            pT->release();
        }
    };

    template<class T>
    class ClearableGuard
    {
    protected:
        T * pT;
    public:

        ClearableGuard(T * pT) : pT(pT)
        {
            pT->acquire();
        }

        ClearableGuard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases mutex. */
        ~ClearableGuard()
        {
            if (pT)
                pT->release();
        }

        /** Releases mutex. */
        void clear()
        {
            if(pT)
            {
                pT->release();
                pT = NULL;
            }
        }
    };

    template< class T >
    class ResettableGuard : public ClearableGuard< T >
    {
    protected:
        T* pResetT;
    public:
        ResettableGuard( T* pT ) :
                ClearableGuard( pT ),
                pResetT( pT )
        {}

        ResettableGuard( T& rT ) :
                ClearableGuard( rT ),
                pResetT( &rT )
        {}

        void reset()
        {
            if( pResetT )
            {
                pT = pResetT;
                pT->acquire();
            }
        }
    };

    typedef Guard<Mutex> MutexGuard;
    typedef ClearableGuard<Mutex> ClearableMutexGuard;
    typedef ResettableGuard< Mutex > ResettableMutexGuard;
}

#endif  /* __cplusplus */
#endif  /* _OSL_MUTEX_HXX_ */

<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright David Doria 2011 daviddoria@gmail.com
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "PoissonEditingGUI.h"

// Custom
#include "ImageFileSelector.h"
#include "HelpersOutput.h"
#include "HelpersQt.h"
#include "Mask.h"
#include "PoissonEditing.h"
#include "PoissonEditingComputationThread.h"
#include "PoissonEditingComputationObject.h"

// ITK
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

// Qt
#include <QIcon>
#include <QFileDialog>
#include <QGraphicsPixmapItem>

// Called by all constructors
void PoissonEditingGUI::DefaultConstructor()
{
  this->setupUi(this);

  this->progressBar->setMinimum(0);
  this->progressBar->setMaximum(0);
  this->progressBar->hide();

  this->ComputationThread = new PoissonEditingComputationThreadClass;
  connect(this->ComputationThread, SIGNAL(StartProgressBarSignal()), this, SLOT(slot_StartProgressBar()));
  connect(this->ComputationThread, SIGNAL(StopProgressBarSignal()), this, SLOT(slot_StopProgressBar()));
  connect(this->ComputationThread, SIGNAL(IterationCompleteSignal()), this, SLOT(slot_IterationComplete()));

  this->Image = ImageType::New();
  this->MaskImage = Mask::New();
  this->Result = ImageType::New();

  this->Scene = new QGraphicsScene;
  this->graphicsView->setScene(this->Scene);

  this->ImagePixmapItem = NULL;
  this->MaskImagePixmapItem = NULL;
  this->ResultPixmapItem = NULL;
}

// Default constructor
PoissonEditingGUI::PoissonEditingGUI()
{
  DefaultConstructor();
};

PoissonEditingGUI::PoissonEditingGUI(const std::string& imageFileName, const std::string& maskFileName)
{
  DefaultConstructor();
  this->SourceImageFileName = imageFileName;
  this->MaskImageFileName = maskFileName;
  OpenImageAndMask(this->SourceImageFileName, this->MaskImageFileName);
}

void PoissonEditingGUI::showEvent ( QShowEvent * event )
{
  this->graphicsView->fitInView(this->ImagePixmapItem, Qt::KeepAspectRatio);
}

void PoissonEditingGUI::resizeEvent ( QResizeEvent * event )
{
  this->graphicsView->fitInView(this->ImagePixmapItem, Qt::KeepAspectRatio);
}

void PoissonEditingGUI::on_btnFill_clicked()
{
  ComputationThread->Operation = ComputationThreadClass::ALLSTEPS;
  PoissonEditingComputationObject* computationObject = new PoissonEditingComputationObject;
  computationObject->MaskImage = this->MaskImage;
  computationObject->Image = this->Image;
  computationObject->Result = this->Result;
  ComputationThread->SetObject(computationObject);
  ComputationThread->start();
}

void PoissonEditingGUI::on_actionSaveResult_activated()
{
  // Get a filename to save
  QString fileName = QFileDialog::getSaveFileName(this, "Save File", ".", "Image Files (*.jpg *.jpeg *.bmp *.png *.mha)");

  if(fileName.toStdString().empty())
    {
    std::cout << "Filename was empty." << std::endl;
    return;
    }

  HelpersOutput::WriteImage<ImageType>(this->Result, fileName.toStdString());
  HelpersOutput::WriteRGBImage<ImageType>(this->Result, fileName.toStdString() + ".png");
  this->statusBar()->showMessage("Saved result.");
}

void PoissonEditingGUI::OpenImageAndMask(const std::string& imageFileName, const std::string& maskFileName)
{
  // Load and display image
  typedef itk::ImageFileReader<ImageType> ImageReaderType;
  ImageReaderType::Pointer imageReader = ImageReaderType::New();
  imageReader->SetFileName(imageFileName);
  imageReader->Update();

  Helpers::DeepCopyVectorImage<ImageType>(imageReader->GetOutput(), this->Image);

  QImage qimageImage = HelpersQt::GetQImageRGBA<ImageType>(this->Image);
  this->ImagePixmapItem = this->Scene->addPixmap(QPixmap::fromImage(qimageImage));
  this->graphicsView->fitInView(this->ImagePixmapItem);
  this->ImagePixmapItem->setVisible(this->chkShowInput->isChecked());

  // Load and display mask
  typedef itk::ImageFileReader<Mask> MaskReaderType;
  MaskReaderType::Pointer maskReader = MaskReaderType::New();
  maskReader->SetFileName(maskFileName);
  maskReader->Update();

  Helpers::DeepCopy<Mask>(maskReader->GetOutput(), this->MaskImage);

  QImage qimageMask = HelpersQt::GetQMaskImage(this->MaskImage);
  this->MaskImagePixmapItem = this->Scene->addPixmap(QPixmap::fromImage(qimageMask));
  this->MaskImagePixmapItem->setVisible(this->chkShowMask->isChecked());
}

void PoissonEditingGUI::on_actionOpenImage_activated()
{
  std::cout << "on_actionOpenImage_activated" << std::endl;
  std::vector<std::string> namedImages;
  namedImages.push_back("Image");
  namedImages.push_back("Mask");

  ImageFileSelector* fileSelector(new ImageFileSelector(namedImages));
  fileSelector->exec();

  int result = fileSelector->result();
  if(result) // The user clicked 'ok'
    {
    OpenImageAndMask(fileSelector->GetNamedImageFileName("Image"), fileSelector->GetNamedImageFileName("Mask"));
    }
  else
    {
    // std::cout << "User clicked cancel." << std::endl;
    // The user clicked 'cancel' or closed the dialog, do nothing.
    }
}

void PoissonEditingGUI::on_chkShowInput_clicked()
{
  if(!this->ImagePixmapItem)
    {
    return;
    }
  this->ImagePixmapItem->setVisible(this->chkShowInput->isChecked());
}

void PoissonEditingGUI::on_chkShowOutput_clicked()
{
  if(!this->ResultPixmapItem)
    {
    return;
    }
  this->ResultPixmapItem->setVisible(this->chkShowOutput->isChecked());
}

void PoissonEditingGUI::on_chkShowMask_clicked()
{
  if(!this->MaskImagePixmapItem)
    {
    return;
    }
  this->MaskImagePixmapItem->setVisible(this->chkShowMask->isChecked());
}

void PoissonEditingGUI::slot_StartProgressBar()
{
  this->progressBar->show();
}

void PoissonEditingGUI::slot_StopProgressBar()
{
  this->progressBar->hide();
}

void PoissonEditingGUI::slot_IterationComplete()
{
  QImage qimage = HelpersQt::GetQImageRGBA<ImageType>(this->Result);
  this->ResultPixmapItem = this->Scene->addPixmap(QPixmap::fromImage(qimage));
  this->ResultPixmapItem->setVisible(this->chkShowOutput->isChecked());
}
<commit_msg>Fix crash if no input is specified to constructor.<commit_after>/*=========================================================================
 *
 *  Copyright David Doria 2011 daviddoria@gmail.com
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "PoissonEditingGUI.h"

// Custom
#include "ImageFileSelector.h"
#include "HelpersOutput.h"
#include "HelpersQt.h"
#include "Mask.h"
#include "PoissonEditing.h"
#include "PoissonEditingComputationThread.h"
#include "PoissonEditingComputationObject.h"

// ITK
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

// Qt
#include <QIcon>
#include <QFileDialog>
#include <QGraphicsPixmapItem>

// Called by all constructors
void PoissonEditingGUI::DefaultConstructor()
{
  std::cout << "DefaultConstructor()" << std::endl;
  this->setupUi(this);

  this->progressBar->setMinimum(0);
  this->progressBar->setMaximum(0);
  this->progressBar->hide();

  this->ComputationThread = new PoissonEditingComputationThreadClass;
  connect(this->ComputationThread, SIGNAL(StartProgressBarSignal()), this, SLOT(slot_StartProgressBar()));
  connect(this->ComputationThread, SIGNAL(StopProgressBarSignal()), this, SLOT(slot_StopProgressBar()));
  connect(this->ComputationThread, SIGNAL(IterationCompleteSignal()), this, SLOT(slot_IterationComplete()));

  this->Image = ImageType::New();
  this->MaskImage = Mask::New();
  this->Result = ImageType::New();

  this->Scene = new QGraphicsScene;
  this->graphicsView->setScene(this->Scene);

  this->ImagePixmapItem = NULL;
  this->MaskImagePixmapItem = NULL;
  this->ResultPixmapItem = NULL;
}

// Default constructor
PoissonEditingGUI::PoissonEditingGUI()
{
  std::cout << "PoissonEditingGUI()" << std::endl;
  DefaultConstructor();
};

PoissonEditingGUI::PoissonEditingGUI(const std::string& imageFileName, const std::string& maskFileName)
{
  std::cout << "PoissonEditingGUI(string, string)" << std::endl;
  DefaultConstructor();
  this->SourceImageFileName = imageFileName;
  this->MaskImageFileName = maskFileName;
  OpenImageAndMask(this->SourceImageFileName, this->MaskImageFileName);
}

void PoissonEditingGUI::showEvent ( QShowEvent * event )
{
  if(this->ImagePixmapItem)
    {
    this->graphicsView->fitInView(this->ImagePixmapItem, Qt::KeepAspectRatio);
    }
}

void PoissonEditingGUI::resizeEvent ( QResizeEvent * event )
{
  if(this->ImagePixmapItem)
    {
    this->graphicsView->fitInView(this->ImagePixmapItem, Qt::KeepAspectRatio);
    }
}

void PoissonEditingGUI::on_btnFill_clicked()
{
  ComputationThread->Operation = ComputationThreadClass::ALLSTEPS;
  PoissonEditingComputationObject* computationObject = new PoissonEditingComputationObject;
  computationObject->MaskImage = this->MaskImage;
  computationObject->Image = this->Image;
  computationObject->Result = this->Result;
  ComputationThread->SetObject(computationObject);
  ComputationThread->start();
}

void PoissonEditingGUI::on_actionSaveResult_activated()
{
  // Get a filename to save
  QString fileName = QFileDialog::getSaveFileName(this, "Save File", ".", "Image Files (*.jpg *.jpeg *.bmp *.png *.mha)");

  if(fileName.toStdString().empty())
    {
    std::cout << "Filename was empty." << std::endl;
    return;
    }

  HelpersOutput::WriteImage<ImageType>(this->Result, fileName.toStdString());
  HelpersOutput::WriteRGBImage<ImageType>(this->Result, fileName.toStdString() + ".png");
  this->statusBar()->showMessage("Saved result.");
}

void PoissonEditingGUI::OpenImageAndMask(const std::string& imageFileName, const std::string& maskFileName)
{
  // Load and display image
  typedef itk::ImageFileReader<ImageType> ImageReaderType;
  ImageReaderType::Pointer imageReader = ImageReaderType::New();
  imageReader->SetFileName(imageFileName);
  imageReader->Update();

  Helpers::DeepCopyVectorImage<ImageType>(imageReader->GetOutput(), this->Image);

  QImage qimageImage = HelpersQt::GetQImageRGBA<ImageType>(this->Image);
  this->ImagePixmapItem = this->Scene->addPixmap(QPixmap::fromImage(qimageImage));
  this->graphicsView->fitInView(this->ImagePixmapItem);
  this->ImagePixmapItem->setVisible(this->chkShowInput->isChecked());

  // Load and display mask
  typedef itk::ImageFileReader<Mask> MaskReaderType;
  MaskReaderType::Pointer maskReader = MaskReaderType::New();
  maskReader->SetFileName(maskFileName);
  maskReader->Update();

  Helpers::DeepCopy<Mask>(maskReader->GetOutput(), this->MaskImage);

  QImage qimageMask = HelpersQt::GetQMaskImage(this->MaskImage);
  this->MaskImagePixmapItem = this->Scene->addPixmap(QPixmap::fromImage(qimageMask));
  this->MaskImagePixmapItem->setVisible(this->chkShowMask->isChecked());
}

void PoissonEditingGUI::on_actionOpenImage_activated()
{
  std::cout << "on_actionOpenImage_activated" << std::endl;
  std::vector<std::string> namedImages;
  namedImages.push_back("Image");
  namedImages.push_back("Mask");

  ImageFileSelector* fileSelector(new ImageFileSelector(namedImages));
  fileSelector->exec();

  int result = fileSelector->result();
  if(result) // The user clicked 'ok'
    {
    OpenImageAndMask(fileSelector->GetNamedImageFileName("Image"), fileSelector->GetNamedImageFileName("Mask"));
    }
  else
    {
    // std::cout << "User clicked cancel." << std::endl;
    // The user clicked 'cancel' or closed the dialog, do nothing.
    }
}

void PoissonEditingGUI::on_chkShowInput_clicked()
{
  if(!this->ImagePixmapItem)
    {
    return;
    }
  this->ImagePixmapItem->setVisible(this->chkShowInput->isChecked());
}

void PoissonEditingGUI::on_chkShowOutput_clicked()
{
  if(!this->ResultPixmapItem)
    {
    return;
    }
  this->ResultPixmapItem->setVisible(this->chkShowOutput->isChecked());
}

void PoissonEditingGUI::on_chkShowMask_clicked()
{
  if(!this->MaskImagePixmapItem)
    {
    return;
    }
  this->MaskImagePixmapItem->setVisible(this->chkShowMask->isChecked());
}

void PoissonEditingGUI::slot_StartProgressBar()
{
  this->progressBar->show();
}

void PoissonEditingGUI::slot_StopProgressBar()
{
  this->progressBar->hide();
}

void PoissonEditingGUI::slot_IterationComplete()
{
  QImage qimage = HelpersQt::GetQImageRGBA<ImageType>(this->Result);
  this->ResultPixmapItem = this->Scene->addPixmap(QPixmap::fromImage(qimage));
  this->ResultPixmapItem->setVisible(this->chkShowOutput->isChecked());
}
<|endoftext|>


<commit_before>
#include "ksp_plugin/vessel.hpp"

#include <algorithm>
#include <list>
#include <vector>

#include "integrators/embedded_explicit_runge_kutta_nyström_integrator.hpp"
#include "ksp_plugin/pile_up.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/make_not_null.hpp"

namespace principia {
namespace ksp_plugin {
namespace internal_vessel {

using base::FindOrDie;
using base::make_not_null_unique;
using geometry::BarycentreCalculator;
using geometry::Position;
using integrators::DormandElMikkawyPrince1986RKN434FM;
using integrators::McLachlanAtela1992Order5Optimal;
using quantities::IsFinite;
using quantities::Time;
using quantities::si::Kilogram;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Second;

Vessel::Vessel(not_null<Celestial const*> const parent,
               not_null<Ephemeris<Barycentric>*> const ephemeris,
               Ephemeris<Barycentric>::AdaptiveStepParameters const&
                   prediction_adaptive_step_parameters)
    : body_(),
      prediction_adaptive_step_parameters_(prediction_adaptive_step_parameters),
      parent_(parent),
      ephemeris_(ephemeris),
      psychohistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
      prediction_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}

not_null<MasslessBody const*> Vessel::body() const {
  return &body_;
}

not_null<Celestial const*> Vessel::parent() const {
  return parent_;
}

void Vessel::set_parent(not_null<Celestial const*> const parent) {
  parent_ = parent;
}

void Vessel::AddPart(not_null<std::unique_ptr<Part>> part) {
  PartId const id = part->part_id();
  LOG(INFO) << "Adding part " << id << " to vessel at " << this;
  parts_.emplace(id, std::move(part));
}

not_null<std::unique_ptr<Part>> Vessel::ExtractPart(PartId const id) {
  LOG(INFO) << "Extracting part " << id << " from vessel at " << this;
  auto const it = parts_.find(id);
  CHECK(it != parts_.end()) << id;
  auto result = std::move(it->second);
  parts_.erase(it);
  return result;
}

void Vessel::KeepPart(PartId const id) {
  LOG(ERROR)<<"Keeping part " << id << " in vessel at " << this;
  kept_parts_.insert(FindOrDie(parts_, id).get());
}

void Vessel::FreeParts() {
  LOG(ERROR)<<"Freeing " << parts_.size() - kept_parts_.size() << " parts";
  for (auto it = parts_.begin(); it != parts_.end();) {
    not_null<Part*> part = it->second.get();
    if (kept_parts_.count(part) == 0) {
      part->clear_pile_up();
      it = parts_.erase(it);
    } else {
      ++it;
    }
  }
  CHECK(!parts_.empty());
  kept_parts_.clear();
}

void Vessel::PreparePsychohistory(Instant const& t) {
  CHECK(!parts_.empty());
  if (psychohistory_->Size() == 0) {
    LOG(INFO) << "Preparing psychohistory of vessel at " << this;
    BarycentreCalculator<DegreesOfFreedom<Barycentric>, Mass> calculator;
    ForAllParts([&calculator](Part& part) {
      calculator.Add(part.degrees_of_freedom(), part.mass());
    });
    psychohistory_->Append(t, calculator.Get());
    psychohistory_is_authoritative_ = true;
  }
}

not_null<Part*> Vessel::part(PartId const id) const {
  return FindOrDie(parts_, id).get();
}

void Vessel::ForSomePart(std::function<void(Part&)> action) const {
  CHECK(!parts_.empty());
  action(*parts_.begin()->second);
}

void Vessel::ForAllParts(std::function<void(Part&)> action) const {
  for (auto const& pair : parts_) {
    action(*pair.second);
  }
}

DiscreteTrajectory<Barycentric> const& Vessel::prediction() const {
  return *prediction_;
}

void Vessel::set_prediction_adaptive_step_parameters(
    Ephemeris<Barycentric>::AdaptiveStepParameters const&
        prediction_adaptive_step_parameters) {
  prediction_adaptive_step_parameters_ = prediction_adaptive_step_parameters;
}

Ephemeris<Barycentric>::AdaptiveStepParameters const&
Vessel::prediction_adaptive_step_parameters() const {
  return prediction_adaptive_step_parameters_;
}

FlightPlan& Vessel::flight_plan() const {
  CHECK(has_flight_plan());
  return *flight_plan_;
}

bool Vessel::has_flight_plan() const {
  return flight_plan_ != nullptr;
}

void Vessel::AdvanceTime(Instant const& time) {
  std::vector<DiscreteTrajectory<Barycentric>::Iterator> its;
  for (auto const& pair : parts_) {
    Part const& part = *pair.second;
    its.push_back(part.tail().Begin());
  }
  for (;;) {
    Part const& first_part = *parts_.begin()->second;
    Instant const time = its[0].time();
    bool const at_end_of_tail = its[0] == first_part.tail().last();
    bool const tail_is_authoritative = first_part.tail_is_authoritative();

    BarycentreCalculator<DegreesOfFreedom<Barycentric>, Mass> calculator;
    int i = 0;
    for (auto const& pair : parts_) {
      Part& part = *pair.second;
      auto& it = its[i];
      calculator.Add(it.degrees_of_freedom(), part.mass());
      CHECK_EQ(time, it.time());
      CHECK_EQ(at_end_of_tail, it == part.tail().last());
      CHECK_EQ(tail_is_authoritative, part.tail_is_authoritative());
      if (at_end_of_tail) {
        part.tail().ForgetBefore(astronomy::InfiniteFuture);
      } else {
        ++it;
      }
      ++i;
    }
    DegreesOfFreedom<Barycentric> const vessel_degrees_of_freedom =
        calculator.Get();
    AppendToPsychohistory(
        time,
        vessel_degrees_of_freedom,
        /*authoritative=*/!at_end_of_tail || tail_is_authoritative);

    if (at_end_of_tail) {
      return;
    }
  }
}

void Vessel::ForgetBefore(Instant const& time) {
  // TODO(egg): do something about the psychohistory. I think bad things happen
  // if it becomes empty though.
  prediction_->ForgetBefore(time);
  if (flight_plan_ != nullptr) {
    flight_plan_->ForgetBefore(time, [this]() { flight_plan_.reset(); });
  }
}

void Vessel::CreateFlightPlan(
    Instant const& final_time,
    Mass const& initial_mass,
    Ephemeris<Barycentric>::AdaptiveStepParameters const&
        flight_plan_adaptive_step_parameters) {
  auto const last = last_authoritative();
  flight_plan_ = std::make_unique<FlightPlan>(
      initial_mass,
      /*initial_time=*/last.time(),
      /*initial_degrees_of_freedom=*/last.degrees_of_freedom(),
      final_time,
      ephemeris_,
      flight_plan_adaptive_step_parameters);
}

void Vessel::DeleteFlightPlan() {
  flight_plan_.reset();
}

void Vessel::UpdatePrediction(Instant const& last_time) {
  prediction_ = make_not_null_unique<DiscreteTrajectory<Barycentric>>();
  auto const last = psychohistory_->last();
  prediction_->Append(last.time(), last.degrees_of_freedom());
  FlowPrediction(last_time);
}

DiscreteTrajectory<Barycentric> const& Vessel::psychohistory() const {
  return *psychohistory_;
}

bool Vessel::psychohistory_is_authoritative() const {
  return psychohistory_is_authoritative_;
}

void Vessel::WriteToMessage(
    not_null<serialization::Vessel*> const message) const {
  // TODO(phl): Implement.
  body_.WriteToMessage(message->mutable_body());
  prediction_adaptive_step_parameters_.WriteToMessage(
      message->mutable_prediction_adaptive_step_parameters());
  for (auto const& pair : parts_) {
    auto const& part = pair.second;
    part->WriteToMessage(message->add_parts());
  }
  for (auto const& part : kept_parts_) {
    message->add_kept_parts(part->part_id());
  }
  psychohistory_->WriteToMessage(message->mutable_psychohistory(),
                                 /*forks=*/{});
  message->set_psychohistory_is_authoritative(psychohistory_is_authoritative_);
  prediction_->WriteToMessage(message->mutable_prediction(),
                              /*forks=*/{});
  if (flight_plan_ != nullptr) {
    flight_plan_->WriteToMessage(message->mutable_flight_plan());
  }
}

not_null<std::unique_ptr<Vessel>> Vessel::ReadFromMessage(
    serialization::Vessel const& message,
    not_null<Celestial const*> const parent,
    not_null<Ephemeris<Barycentric>*> const ephemeris,
    std::function<void(PartId)> const& deletion_callback) {
  // NOTE(egg): for now we do not read the |MasslessBody| as it can contain no
  // information.
  auto vessel = make_not_null_unique<Vessel>(
      parent,
      ephemeris,
      Ephemeris<Barycentric>::AdaptiveStepParameters::ReadFromMessage(
          message.prediction_adaptive_step_parameters()));
  for (auto const& serialized_part : message.parts()) {
    PartId const part_id = serialized_part.part_id();
    auto part = Part::ReadFromMessage(
        serialized_part,
        [deletion_callback, part_id]() { deletion_callback(part_id); });
    vessel->parts_.emplace(part_id, std::move(part));
  }
  for (PartId const part_id : message.kept_parts()) {
    vessel->kept_parts_.insert(vessel->parts_.at(part_id).get());
  }
  vessel->psychohistory_ =
      DiscreteTrajectory<Barycentric>::ReadFromMessage(message.psychohistory(),
                                                       /*forks=*/{});
  vessel->psychohistory_is_authoritative_ =
      message.psychohistory_is_authoritative();
  vessel->prediction_ =
      DiscreteTrajectory<Barycentric>::ReadFromMessage(message.prediction(),
                                                       /*forks=*/{});
  if (message.has_flight_plan()) {
    // TODO(phl): Remove compatibility code.  The |root| is only needed
    // pre-Буняковский.
    vessel->flight_plan_ = FlightPlan::ReadFromMessage(
        message.flight_plan(), /*root=*/nullptr, ephemeris);
  }
  return std::move(vessel);
}

Vessel::Vessel()
    : body_(),
      prediction_adaptive_step_parameters_(DefaultPredictionParameters()),
      parent_(testing_utilities::make_not_null<Celestial const*>()),
      ephemeris_(testing_utilities::make_not_null<Ephemeris<Barycentric>*>()),
      psychohistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
      prediction_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}

void Vessel::AppendToPsychohistory(
    Instant const& time,
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom,
    bool const authoritative) {
  if (!psychohistory_is_authoritative_) {
    psychohistory_->ForgetAfter((--psychohistory_->last()).time());
  }
  psychohistory_->Append(time, degrees_of_freedom);
  psychohistory_is_authoritative_ = authoritative;
}

void Vessel::FlowPrediction(Instant const& time) {
  if (time > prediction_->last().time()) {
    bool const finite_time = IsFinite(time - prediction_->last().time());
    Instant const t = finite_time ? time : ephemeris_->t_max();
    // This will not prolong the ephemeris if |time| is infinite (but it may do
    // so if it is finite).
    bool const reached_t = ephemeris_->FlowWithAdaptiveStep(
        prediction_.get(),
        Ephemeris<Barycentric>::NoIntrinsicAcceleration,
        t,
        prediction_adaptive_step_parameters_,
        FlightPlan::max_ephemeris_steps_per_frame,
        /*last_point_only=*/false);
    if (!finite_time && reached_t) {
      // This will prolong the ephemeris by |max_ephemeris_steps_per_frame|.
      ephemeris_->FlowWithAdaptiveStep(
        prediction_.get(),
        Ephemeris<Barycentric>::NoIntrinsicAcceleration,
        time,
        prediction_adaptive_step_parameters_,
        FlightPlan::max_ephemeris_steps_per_frame,
        /*last_point_only=*/false);
    }
  }
}

DiscreteTrajectory<Barycentric>::Iterator Vessel::last_authoritative() const {
  auto it = psychohistory_->last();
  if (!psychohistory_is_authoritative_) {
    --it;
  }
  return it;
}

Ephemeris<Barycentric>::FixedStepParameters DefaultHistoryParameters() {
  return Ephemeris<Barycentric>::FixedStepParameters(
             McLachlanAtela1992Order5Optimal<Position<Barycentric>>(),
             /*step=*/10 * Second);
}

Ephemeris<Barycentric>::AdaptiveStepParameters DefaultProlongationParameters() {
  return Ephemeris<Barycentric>::AdaptiveStepParameters(
             DormandElMikkawyPrince1986RKN434FM<Position<Barycentric>>(),
             /*max_steps=*/std::numeric_limits<std::int64_t>::max(),
             /*length_integration_tolerance=*/1 * Milli(Metre),
             /*speed_integration_tolerance=*/1 * Milli(Metre) / Second);
}

Ephemeris<Barycentric>::AdaptiveStepParameters DefaultPredictionParameters() {
  return Ephemeris<Barycentric>::AdaptiveStepParameters(
             DormandElMikkawyPrince1986RKN434FM<Position<Barycentric>>(),
             /*max_steps=*/1000,
             /*length_integration_tolerance=*/1 * Metre,
             /*speed_integration_tolerance=*/1 * Metre / Second);
}

}  // namespace internal_vessel
}  // namespace ksp_plugin
}  // namespace principia
<commit_msg>remove spammy traces<commit_after>
#include "ksp_plugin/vessel.hpp"

#include <algorithm>
#include <list>
#include <vector>

#include "integrators/embedded_explicit_runge_kutta_nyström_integrator.hpp"
#include "ksp_plugin/pile_up.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/make_not_null.hpp"

namespace principia {
namespace ksp_plugin {
namespace internal_vessel {

using base::FindOrDie;
using base::make_not_null_unique;
using geometry::BarycentreCalculator;
using geometry::Position;
using integrators::DormandElMikkawyPrince1986RKN434FM;
using integrators::McLachlanAtela1992Order5Optimal;
using quantities::IsFinite;
using quantities::Time;
using quantities::si::Kilogram;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Second;

Vessel::Vessel(not_null<Celestial const*> const parent,
               not_null<Ephemeris<Barycentric>*> const ephemeris,
               Ephemeris<Barycentric>::AdaptiveStepParameters const&
                   prediction_adaptive_step_parameters)
    : body_(),
      prediction_adaptive_step_parameters_(prediction_adaptive_step_parameters),
      parent_(parent),
      ephemeris_(ephemeris),
      psychohistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
      prediction_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}

not_null<MasslessBody const*> Vessel::body() const {
  return &body_;
}

not_null<Celestial const*> Vessel::parent() const {
  return parent_;
}

void Vessel::set_parent(not_null<Celestial const*> const parent) {
  parent_ = parent;
}

void Vessel::AddPart(not_null<std::unique_ptr<Part>> part) {
  PartId const id = part->part_id();
  LOG(INFO) << "Adding part " << id << " to vessel at " << this;
  parts_.emplace(id, std::move(part));
}

not_null<std::unique_ptr<Part>> Vessel::ExtractPart(PartId const id) {
  LOG(INFO) << "Extracting part " << id << " from vessel at " << this;
  auto const it = parts_.find(id);
  CHECK(it != parts_.end()) << id;
  auto result = std::move(it->second);
  parts_.erase(it);
  return result;
}

void Vessel::KeepPart(PartId const id) {
  kept_parts_.insert(FindOrDie(parts_, id).get());
}

void Vessel::FreeParts() {
  for (auto it = parts_.begin(); it != parts_.end();) {
    not_null<Part*> part = it->second.get();
    if (kept_parts_.count(part) == 0) {
      part->clear_pile_up();
      it = parts_.erase(it);
    } else {
      ++it;
    }
  }
  CHECK(!parts_.empty());
  kept_parts_.clear();
}

void Vessel::PreparePsychohistory(Instant const& t) {
  CHECK(!parts_.empty());
  if (psychohistory_->Size() == 0) {
    LOG(INFO) << "Preparing psychohistory of vessel at " << this;
    BarycentreCalculator<DegreesOfFreedom<Barycentric>, Mass> calculator;
    ForAllParts([&calculator](Part& part) {
      calculator.Add(part.degrees_of_freedom(), part.mass());
    });
    psychohistory_->Append(t, calculator.Get());
    psychohistory_is_authoritative_ = true;
  }
}

not_null<Part*> Vessel::part(PartId const id) const {
  return FindOrDie(parts_, id).get();
}

void Vessel::ForSomePart(std::function<void(Part&)> action) const {
  CHECK(!parts_.empty());
  action(*parts_.begin()->second);
}

void Vessel::ForAllParts(std::function<void(Part&)> action) const {
  for (auto const& pair : parts_) {
    action(*pair.second);
  }
}

DiscreteTrajectory<Barycentric> const& Vessel::prediction() const {
  return *prediction_;
}

void Vessel::set_prediction_adaptive_step_parameters(
    Ephemeris<Barycentric>::AdaptiveStepParameters const&
        prediction_adaptive_step_parameters) {
  prediction_adaptive_step_parameters_ = prediction_adaptive_step_parameters;
}

Ephemeris<Barycentric>::AdaptiveStepParameters const&
Vessel::prediction_adaptive_step_parameters() const {
  return prediction_adaptive_step_parameters_;
}

FlightPlan& Vessel::flight_plan() const {
  CHECK(has_flight_plan());
  return *flight_plan_;
}

bool Vessel::has_flight_plan() const {
  return flight_plan_ != nullptr;
}

void Vessel::AdvanceTime(Instant const& time) {
  std::vector<DiscreteTrajectory<Barycentric>::Iterator> its;
  for (auto const& pair : parts_) {
    Part const& part = *pair.second;
    its.push_back(part.tail().Begin());
  }
  for (;;) {
    Part const& first_part = *parts_.begin()->second;
    Instant const time = its[0].time();
    bool const at_end_of_tail = its[0] == first_part.tail().last();
    bool const tail_is_authoritative = first_part.tail_is_authoritative();

    BarycentreCalculator<DegreesOfFreedom<Barycentric>, Mass> calculator;
    int i = 0;
    for (auto const& pair : parts_) {
      Part& part = *pair.second;
      auto& it = its[i];
      calculator.Add(it.degrees_of_freedom(), part.mass());
      CHECK_EQ(time, it.time());
      CHECK_EQ(at_end_of_tail, it == part.tail().last());
      CHECK_EQ(tail_is_authoritative, part.tail_is_authoritative());
      if (at_end_of_tail) {
        part.tail().ForgetBefore(astronomy::InfiniteFuture);
      } else {
        ++it;
      }
      ++i;
    }
    DegreesOfFreedom<Barycentric> const vessel_degrees_of_freedom =
        calculator.Get();
    AppendToPsychohistory(
        time,
        vessel_degrees_of_freedom,
        /*authoritative=*/!at_end_of_tail || tail_is_authoritative);

    if (at_end_of_tail) {
      return;
    }
  }
}

void Vessel::ForgetBefore(Instant const& time) {
  // TODO(egg): do something about the psychohistory. I think bad things happen
  // if it becomes empty though.
  prediction_->ForgetBefore(time);
  if (flight_plan_ != nullptr) {
    flight_plan_->ForgetBefore(time, [this]() { flight_plan_.reset(); });
  }
}

void Vessel::CreateFlightPlan(
    Instant const& final_time,
    Mass const& initial_mass,
    Ephemeris<Barycentric>::AdaptiveStepParameters const&
        flight_plan_adaptive_step_parameters) {
  auto const last = last_authoritative();
  flight_plan_ = std::make_unique<FlightPlan>(
      initial_mass,
      /*initial_time=*/last.time(),
      /*initial_degrees_of_freedom=*/last.degrees_of_freedom(),
      final_time,
      ephemeris_,
      flight_plan_adaptive_step_parameters);
}

void Vessel::DeleteFlightPlan() {
  flight_plan_.reset();
}

void Vessel::UpdatePrediction(Instant const& last_time) {
  prediction_ = make_not_null_unique<DiscreteTrajectory<Barycentric>>();
  auto const last = psychohistory_->last();
  prediction_->Append(last.time(), last.degrees_of_freedom());
  FlowPrediction(last_time);
}

DiscreteTrajectory<Barycentric> const& Vessel::psychohistory() const {
  return *psychohistory_;
}

bool Vessel::psychohistory_is_authoritative() const {
  return psychohistory_is_authoritative_;
}

void Vessel::WriteToMessage(
    not_null<serialization::Vessel*> const message) const {
  // TODO(phl): Implement.
  body_.WriteToMessage(message->mutable_body());
  prediction_adaptive_step_parameters_.WriteToMessage(
      message->mutable_prediction_adaptive_step_parameters());
  for (auto const& pair : parts_) {
    auto const& part = pair.second;
    part->WriteToMessage(message->add_parts());
  }
  for (auto const& part : kept_parts_) {
    message->add_kept_parts(part->part_id());
  }
  psychohistory_->WriteToMessage(message->mutable_psychohistory(),
                                 /*forks=*/{});
  message->set_psychohistory_is_authoritative(psychohistory_is_authoritative_);
  prediction_->WriteToMessage(message->mutable_prediction(),
                              /*forks=*/{});
  if (flight_plan_ != nullptr) {
    flight_plan_->WriteToMessage(message->mutable_flight_plan());
  }
}

not_null<std::unique_ptr<Vessel>> Vessel::ReadFromMessage(
    serialization::Vessel const& message,
    not_null<Celestial const*> const parent,
    not_null<Ephemeris<Barycentric>*> const ephemeris,
    std::function<void(PartId)> const& deletion_callback) {
  // NOTE(egg): for now we do not read the |MasslessBody| as it can contain no
  // information.
  auto vessel = make_not_null_unique<Vessel>(
      parent,
      ephemeris,
      Ephemeris<Barycentric>::AdaptiveStepParameters::ReadFromMessage(
          message.prediction_adaptive_step_parameters()));
  for (auto const& serialized_part : message.parts()) {
    PartId const part_id = serialized_part.part_id();
    auto part = Part::ReadFromMessage(
        serialized_part,
        [deletion_callback, part_id]() { deletion_callback(part_id); });
    vessel->parts_.emplace(part_id, std::move(part));
  }
  for (PartId const part_id : message.kept_parts()) {
    vessel->kept_parts_.insert(vessel->parts_.at(part_id).get());
  }
  vessel->psychohistory_ =
      DiscreteTrajectory<Barycentric>::ReadFromMessage(message.psychohistory(),
                                                       /*forks=*/{});
  vessel->psychohistory_is_authoritative_ =
      message.psychohistory_is_authoritative();
  vessel->prediction_ =
      DiscreteTrajectory<Barycentric>::ReadFromMessage(message.prediction(),
                                                       /*forks=*/{});
  if (message.has_flight_plan()) {
    // TODO(phl): Remove compatibility code.  The |root| is only needed
    // pre-Буняковский.
    vessel->flight_plan_ = FlightPlan::ReadFromMessage(
        message.flight_plan(), /*root=*/nullptr, ephemeris);
  }
  return std::move(vessel);
}

Vessel::Vessel()
    : body_(),
      prediction_adaptive_step_parameters_(DefaultPredictionParameters()),
      parent_(testing_utilities::make_not_null<Celestial const*>()),
      ephemeris_(testing_utilities::make_not_null<Ephemeris<Barycentric>*>()),
      psychohistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
      prediction_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}

void Vessel::AppendToPsychohistory(
    Instant const& time,
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom,
    bool const authoritative) {
  if (!psychohistory_is_authoritative_) {
    psychohistory_->ForgetAfter((--psychohistory_->last()).time());
  }
  psychohistory_->Append(time, degrees_of_freedom);
  psychohistory_is_authoritative_ = authoritative;
}

void Vessel::FlowPrediction(Instant const& time) {
  if (time > prediction_->last().time()) {
    bool const finite_time = IsFinite(time - prediction_->last().time());
    Instant const t = finite_time ? time : ephemeris_->t_max();
    // This will not prolong the ephemeris if |time| is infinite (but it may do
    // so if it is finite).
    bool const reached_t = ephemeris_->FlowWithAdaptiveStep(
        prediction_.get(),
        Ephemeris<Barycentric>::NoIntrinsicAcceleration,
        t,
        prediction_adaptive_step_parameters_,
        FlightPlan::max_ephemeris_steps_per_frame,
        /*last_point_only=*/false);
    if (!finite_time && reached_t) {
      // This will prolong the ephemeris by |max_ephemeris_steps_per_frame|.
      ephemeris_->FlowWithAdaptiveStep(
        prediction_.get(),
        Ephemeris<Barycentric>::NoIntrinsicAcceleration,
        time,
        prediction_adaptive_step_parameters_,
        FlightPlan::max_ephemeris_steps_per_frame,
        /*last_point_only=*/false);
    }
  }
}

DiscreteTrajectory<Barycentric>::Iterator Vessel::last_authoritative() const {
  auto it = psychohistory_->last();
  if (!psychohistory_is_authoritative_) {
    --it;
  }
  return it;
}

Ephemeris<Barycentric>::FixedStepParameters DefaultHistoryParameters() {
  return Ephemeris<Barycentric>::FixedStepParameters(
             McLachlanAtela1992Order5Optimal<Position<Barycentric>>(),
             /*step=*/10 * Second);
}

Ephemeris<Barycentric>::AdaptiveStepParameters DefaultProlongationParameters() {
  return Ephemeris<Barycentric>::AdaptiveStepParameters(
             DormandElMikkawyPrince1986RKN434FM<Position<Barycentric>>(),
             /*max_steps=*/std::numeric_limits<std::int64_t>::max(),
             /*length_integration_tolerance=*/1 * Milli(Metre),
             /*speed_integration_tolerance=*/1 * Milli(Metre) / Second);
}

Ephemeris<Barycentric>::AdaptiveStepParameters DefaultPredictionParameters() {
  return Ephemeris<Barycentric>::AdaptiveStepParameters(
             DormandElMikkawyPrince1986RKN434FM<Position<Barycentric>>(),
             /*max_steps=*/1000,
             /*length_integration_tolerance=*/1 * Metre,
             /*speed_integration_tolerance=*/1 * Metre / Second);
}

}  // namespace internal_vessel
}  // namespace ksp_plugin
}  // namespace principia
<|endoftext|>


<commit_before>//
// Created by Dennis Goldfarb on 11/21/16.
//

#include <iostream>

#include <OpenMS/FORMAT/FASTAFile.h>
#include <OpenMS/CHEMISTRY/AASequence.h>
#include <OpenMS/CHEMISTRY/ElementDB.h>
#include <OpenMS/CHEMISTRY/Residue.h>
#include <OpenMS/CHEMISTRY/EnzymaticDigestion.h>

using namespace OpenMS;

static const OpenMS::ElementDB* elementDB = OpenMS::ElementDB::getInstance();

static const int binSize = 1000;

std::set<AASequence> uniquePeptides;
std::map<int, int> sulfurs2count;
std::map<int, int> massBin2count;

bool isValidPeptide(AASequence& pep) {
    String p = pep.toString();
    if (p.hasSubstring("U") || p.hasSubstring("B") || p.hasSubstring("Z") || p.hasSubstring("J") || p.hasSubstring("X"))
    {
        return false;
    }
    return true;
}

void outputDistribution()
{
    for (auto itr : sulfurs2count)
    {
        std::cout << itr.first << "\t" << itr.second << std::endl;
    }
    for (auto itr : massBin2count)
    {
        std::cout << itr.first * binSize << "\t" << itr.second << std::endl;
    }
}

void countSulfurs(AASequence& pep)
{
    int pep_s = pep.getFormula().getNumberOf(ElementDB::getInstance()->getElement("Sulfur"));

    if (sulfurs2count.find(pep_s) == sulfurs2count.end()) {
        sulfurs2count[pep_s] = 0;
    }

    sulfurs2count[pep_s]++;

    int massBin = pep.getMonoWeight()/binSize;

    massBin2count[massBin]++;
}

void digestProtein(FASTAFile::FASTAEntry& protein, EnzymaticDigestion& digestor)
{
    static Size MIN_PEPTIDE_LENGTH = 5;
    static Size MAX_PEPTIDE_LENGTH = 100;

    std::vector<AASequence> peptides;
    digestor.digest(AASequence::fromString(protein.sequence), peptides);
    for (Size j = 0; j < peptides.size(); ++j)
    {
        if (peptides[j].size() >= MIN_PEPTIDE_LENGTH && peptides[j].size() <= MAX_PEPTIDE_LENGTH
            && isValidPeptide(peptides[j]) && uniquePeptides.find(peptides[j]) == uniquePeptides.end())
        {
            uniquePeptides.insert(peptides[j]);
            countSulfurs(peptides[j]);
        }
    }
}

void digestFASTA(std::string fasta_path)
{
    std::vector<FASTAFile::FASTAEntry> proteins;
    FASTAFile().load(fasta_path, proteins);

    EnzymaticDigestion digestor; // default parameters are fully tryptic with 0 missed cleavages

    for (Size i = 0; i < proteins.size(); ++i)
    {
        digestProtein(proteins[i], digestor);
    }
}

void usage()
{
    std::cout << "GetSulfurDistribution fasta_path" << std::endl;
}

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

    if (argc != 2)
    {
        usage();
    }

    digestFASTA(argv[1]);
    outputDistribution();

    return 0;
}<commit_msg>mass distribution<commit_after>//
// Created by Dennis Goldfarb on 11/21/16.
//

#include <iostream>

#include <OpenMS/FORMAT/FASTAFile.h>
#include <OpenMS/CHEMISTRY/AASequence.h>
#include <OpenMS/CHEMISTRY/ElementDB.h>
#include <OpenMS/CHEMISTRY/Residue.h>
#include <OpenMS/CHEMISTRY/EnzymaticDigestion.h>

using namespace OpenMS;

static const OpenMS::ElementDB* elementDB = OpenMS::ElementDB::getInstance();

static const int binSize = 1000;

std::set<AASequence> uniquePeptides;
std::map<int, int> sulfurs2count;
std::map<int, int> massBin2count;

bool isValidPeptide(AASequence& pep) {
    String p = pep.toString();
    if (p.hasSubstring("U") || p.hasSubstring("B") || p.hasSubstring("Z") || p.hasSubstring("J") || p.hasSubstring("X"))
    {
        return false;
    }
    return true;
}

void outputDistribution()
{
    for (auto itr : sulfurs2count)
    {
        std::cout << itr.first << "\t" << itr.second << std::endl;
    }
    for (auto itr : massBin2count)
    {
        std::cout << itr.first * binSize << "\t" << itr.second << std::endl;
    }
}

void countSulfurs(AASequence& pep)
{
    int pep_s = pep.getFormula().getNumberOf(ElementDB::getInstance()->getElement("Sulfur"));

    if (sulfurs2count.find(pep_s) == sulfurs2count.end()) {
        sulfurs2count[pep_s] = 0;
    }

    sulfurs2count[pep_s]++;

    int massBin = pep.getMonoWeight()/binSize;

    massBin2count[massBin]++;
}

void digestProtein(FASTAFile::FASTAEntry& protein, EnzymaticDigestion& digestor)
{
    static Size MIN_PEPTIDE_LENGTH = 5;
    static Size MAX_PEPTIDE_LENGTH = 10000;

    std::vector<AASequence> peptides;
    digestor.digest(AASequence::fromString(protein.sequence), peptides);
    for (Size j = 0; j < peptides.size(); ++j)
    {
        if (peptides[j].size() >= MIN_PEPTIDE_LENGTH && peptides[j].size() <= MAX_PEPTIDE_LENGTH
            && isValidPeptide(peptides[j]) && uniquePeptides.find(peptides[j]) == uniquePeptides.end())
        {
            uniquePeptides.insert(peptides[j]);
            countSulfurs(peptides[j]);
        }
    }
}

void digestFASTA(std::string fasta_path)
{
    std::vector<FASTAFile::FASTAEntry> proteins;
    FASTAFile().load(fasta_path, proteins);

    EnzymaticDigestion digestor; // default parameters are fully tryptic with 0 missed cleavages

    for (Size i = 0; i < proteins.size(); ++i)
    {
        digestProtein(proteins[i], digestor);
    }
}

void usage()
{
    std::cout << "GetSulfurDistribution fasta_path" << std::endl;
}

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

    if (argc != 2)
    {
        usage();
    }

    digestFASTA(argv[1]);
    outputDistribution();

    return 0;
}<|endoftext|>