<commit_before>//=============================================================================================================
/**
* @file     main.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     July, 2012
*
* @section  LICENSE
*
* Copyright (C) 2012, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of the Massachusetts General Hospital 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 MASSACHUSETTS GENERAL HOSPITAL 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.
*
*
* @brief    Example of an lnt application
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <fs/label.h>
#include <fs/surface.h>
#include <fs/annotationset.h>

#include <fiff/fiff_evoked.h>
#include <mne/mne_sourceestimate.h>
#include <inverse/minimumNorm/minimumnorm.h>

#include <disp3D/inverseview.h>

#include <iostream>

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QGuiApplication>
#include <QSet>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace MNELIB;
using namespace FSLIB;
using namespace FIFFLIB;
using namespace INVERSELIB;
using namespace DISP3DLIB;

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

//=============================================================================================================
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);

    //########################################################################################
    // Source Estimate

    QFile t_fileFwd("./MNE-sample-data/MEG/sample/sample_audvis-meg-eeg-oct-6-fwd.fif");
    QFile t_fileCov("./MNE-sample-data/MEG/sample/sample_audvis-cov.fif");
    QFile t_fileEvoked("./MNE-sample-data/MEG/sample/sample_audvis-ave.fif");
    AnnotationSet t_annotationSet("./MNE-sample-data/subjects/sample/label/lh.aparc.a2009s.annot", "./MNE-sample-data/subjects/sample/label/rh.aparc.a2009s.annot");
    SurfaceSet t_surfSet("./MNE-sample-data/subjects/sample/surf/lh.white", "./MNE-sample-data/subjects/sample/surf/rh.white");

    QString t_sFileClusteredInverse("");//QFile t_fileClusteredInverse("./clusteredInverse-inv.fif");

    double snr = 1.0;
    double lambda2 = 1.0 / pow(snr, 2);
    QString method("dSPM"); //"MNE" | "dSPM" | "sLORETA"

    // Load data
    fiff_int_t setno = 1;
    QPair<QVariant, QVariant> baseline(QVariant(), 0);
    FiffEvoked evoked(t_fileEvoked, setno, baseline);
    if(evoked.isEmpty())
        return 1;

    std::cout << "Evoked description: " << evoked.comment.toLatin1().constData() << std::endl;

    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;

    FiffCov noise_cov(t_fileCov);

    // regularize noise covariance
    noise_cov = noise_cov.regularize(evoked.info, 0.05, 0.05, 0.1, true);

    //
    // Cluster forward solution;
    //
    MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution_ccr(t_annotationSet, 40);

    //
    // make an inverse operators
    //
    FiffInfo info = evoked.info;

    MNEInverseOperator inverse_operator(info, t_clusteredFwd, noise_cov, 0.2f, 0.8f);

    if(!t_sFileClusteredInverse.isEmpty())
    {
        QFile t_fileClusteredInverse(t_sFileClusteredInverse);
        inverse_operator.write(t_fileClusteredInverse);
    }

    //
    // Compute inverse solution
    //
    MinimumNorm minimumNorm(inverse_operator, lambda2, method);
    MNESourceEstimate sourceEstimate = minimumNorm.calculateInverse(evoked);

    if(sourceEstimate.isEmpty())
        return 1;

//    // View activation time-series
//    std::cout << "\nsourceEstimate:\n" << sourceEstimate.data.block(0,0,10,10) << std::endl;
//    std::cout << "time\n" << sourceEstimate.times.block(0,0,1,10) << std::endl;
//    std::cout << "timeMin\n" << sourceEstimate.times[0] << std::endl;
//    std::cout << "timeMax\n" << sourceEstimate.times[sourceEstimate.times.size()-1] << std::endl;
//    std::cout << "time step\n" << sourceEstimate.tstep << std::endl;

    //Source Estimate end
    //########################################################################################

    QList<Label> t_qListLabels;
    QList<RowVector4i> t_qListRGBAs;

    //ToDo overload toLabels using instead of t_surfSet rr of MNESourceSpace
    t_annotationSet.toLabels(t_surfSet, t_qListLabels, t_qListRGBAs);

    InverseView view(minimumNorm.getSourceSpace(), t_qListLabels, t_qListRGBAs, 24, true, false);

    if (view.stereoType() != QGLView::RedCyanAnaglyph)
        view.camera()->setEyeSeparation(0.3f);
    QStringList args = QCoreApplication::arguments();
    int w_pos = args.indexOf("-width");
    int h_pos = args.indexOf("-height");
    if (w_pos >= 0 && h_pos >= 0)
    {
        bool ok = true;
        int w = args.at(w_pos + 1).toInt(&ok);
        if (!ok)
        {
            qWarning() << "Could not parse width argument:" << args;
            return 1;
        }
        int h = args.at(h_pos + 1).toInt(&ok);
        if (!ok)
        {
            qWarning() << "Could not parse height argument:" << args;
            return 1;
        }
        view.resize(w, h);
    }
    else
    {
        view.resize(800, 600);
    }
    view.setTitle(QString("Online Brain Monitoring - %1").arg(evoked.comment));
    view.show();

    //only one time point - P100
    qint32 sample = 0;
    for(qint32 i = 0; i < sourceEstimate.times.size(); ++i)
    {
        if(sourceEstimate.times(i) >= 0.05f)
        {
            sample = i;
            break;
        }
    }
    sample += (qint32)ceil(0.106/sourceEstimate.tstep); //100ms
    sourceEstimate = sourceEstimate.reduce(sample, 1);

    //Push Estimate
    view.pushSourceEstimate(sourceEstimate);

    return a.exec();
}
<commit_msg>lnt photo fix<commit_after>//=============================================================================================================
/**
* @file     main.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     July, 2012
*
* @section  LICENSE
*
* Copyright (C) 2012, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of the Massachusetts General Hospital 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 MASSACHUSETTS GENERAL HOSPITAL 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.
*
*
* @brief    Example of an lnt application
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <fs/label.h>
#include <fs/surface.h>
#include <fs/annotationset.h>

#include <fiff/fiff_evoked.h>
#include <mne/mne_sourceestimate.h>
#include <inverse/minimumNorm/minimumnorm.h>

#include <disp3D/inverseview.h>

#include <iostream>

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QGuiApplication>
#include <QSet>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace MNELIB;
using namespace FSLIB;
using namespace FIFFLIB;
using namespace INVERSELIB;
using namespace DISP3DLIB;

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

//=============================================================================================================
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);

    //########################################################################################
    // Source Estimate

    QFile t_fileFwd("./MNE-sample-data/MEG/sample/sample_audvis-meg-eeg-oct-6-fwd.fif");
    QFile t_fileCov("./MNE-sample-data/MEG/sample/sample_audvis-cov.fif");
    QFile t_fileEvoked("./MNE-sample-data/MEG/sample/sample_audvis-ave.fif");
    AnnotationSet t_annotationSet("./MNE-sample-data/subjects/sample/label/lh.aparc.a2009s.annot", "./MNE-sample-data/subjects/sample/label/rh.aparc.a2009s.annot");
    SurfaceSet t_surfSet("./MNE-sample-data/subjects/sample/surf/lh.white", "./MNE-sample-data/subjects/sample/surf/rh.white");

    QString t_sFileClusteredInverse("");//QFile t_fileClusteredInverse("./clusteredInverse-inv.fif");

    double snr = 1.0;
    double lambda2 = 1.0 / pow(snr, 2);
    QString method("dSPM"); //"MNE" | "dSPM" | "sLORETA"

    // Load data
    fiff_int_t setno = 1;
    QPair<QVariant, QVariant> baseline(QVariant(), 0);
    FiffEvoked evoked(t_fileEvoked, setno, baseline);
    if(evoked.isEmpty())
        return 1;

    std::cout << "Evoked description: " << evoked.comment.toLatin1().constData() << std::endl;

    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;

    FiffCov noise_cov(t_fileCov);

    // regularize noise covariance
    noise_cov = noise_cov.regularize(evoked.info, 0.05, 0.05, 0.1, true);

    //
    // Cluster forward solution;
    //
    MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution_ccr(t_annotationSet, 40);

    //
    // make an inverse operators
    //
    FiffInfo info = evoked.info;

    MNEInverseOperator inverse_operator(info, t_clusteredFwd, noise_cov, 0.2f, 0.8f);

    if(!t_sFileClusteredInverse.isEmpty())
    {
        QFile t_fileClusteredInverse(t_sFileClusteredInverse);
        inverse_operator.write(t_fileClusteredInverse);
    }

    //
    // Compute inverse solution
    //
    MinimumNorm minimumNorm(inverse_operator, lambda2, method);
    MNESourceEstimate sourceEstimate = minimumNorm.calculateInverse(evoked);

    if(sourceEstimate.isEmpty())
        return 1;

//    // View activation time-series
//    std::cout << "\nsourceEstimate:\n" << sourceEstimate.data.block(0,0,10,10) << std::endl;
//    std::cout << "time\n" << sourceEstimate.times.block(0,0,1,10) << std::endl;
//    std::cout << "timeMin\n" << sourceEstimate.times[0] << std::endl;
//    std::cout << "timeMax\n" << sourceEstimate.times[sourceEstimate.times.size()-1] << std::endl;
//    std::cout << "time step\n" << sourceEstimate.tstep << std::endl;

    //Source Estimate end
    //########################################################################################

    QList<Label> t_qListLabels;
    QList<RowVector4i> t_qListRGBAs;

    //ToDo overload toLabels using instead of t_surfSet rr of MNESourceSpace
    t_annotationSet.toLabels(t_surfSet, t_qListLabels, t_qListRGBAs);

    InverseView view(minimumNorm.getSourceSpace(), t_qListLabels, t_qListRGBAs, 24, true, false);

    if (view.stereoType() != QGLView::RedCyanAnaglyph)
        view.camera()->setEyeSeparation(0.3f);
    QStringList args = QCoreApplication::arguments();
    int w_pos = args.indexOf("-width");
    int h_pos = args.indexOf("-height");
    if (w_pos >= 0 && h_pos >= 0)
    {
        bool ok = true;
        int w = args.at(w_pos + 1).toInt(&ok);
        if (!ok)
        {
            qWarning() << "Could not parse width argument:" << args;
            return 1;
        }
        int h = args.at(h_pos + 1).toInt(&ok);
        if (!ok)
        {
            qWarning() << "Could not parse height argument:" << args;
            return 1;
        }
        view.resize(w, h);
    }
    else
    {
        view.resize(800, 600);
    }
    view.setTitle(QString("Online Brain Monitoring - %1").arg(evoked.comment));
    view.show();

//    //only one time point - P100
//    qint32 sample = 0;
//    for(qint32 i = 0; i < sourceEstimate.times.size(); ++i)
//    {
//        if(sourceEstimate.times(i) >= 0.05f)
//        {
//            sample = i;
//            break;
//        }
//    }
//    sample += (qint32)ceil(0.106/sourceEstimate.tstep); //100ms
//    sourceEstimate = sourceEstimate.reduce(sample, 1);

    //Push Estimate
    view.pushSourceEstimate(sourceEstimate);

    return a.exec();
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <memory>
#include <boost/variant/variant.hpp>

#include "ContextAnnotator.hpp"

#include "ast/Program.hpp"

#include "Context.hpp"
#include "GlobalContext.hpp"
#include "FunctionContext.hpp"
#include "BlockContext.hpp"

using namespace eddic;

class AnnotateVisitor : public boost::static_visitor<> {
    private:
        std::shared_ptr<GlobalContext> globalContext;
        std::shared_ptr<FunctionContext> functionContext;
        std::shared_ptr<Context> currentContext;

    public:
        void operator()(ASTProgram& program){
            currentContext = globalContext = std::make_shared<GlobalContext>();

            program.context = currentContext;

            for(auto& block : program.blocks){
                boost::apply_visitor(*this, block);
            }
        }

        void operator()(FunctionDeclaration& function){
            currentContext = functionContext = std::make_shared<FunctionContext>(currentContext);

            function.context = currentContext;

            for(auto& instruction : function.instructions){
                boost::apply_visitor(*this, instruction);
            }

            currentContext = currentContext->parent();
        }

        void operator()(ASTWhile& while_){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            boost::apply_visitor(*this, while_.condition);

            for(auto& instruction : while_.instructions){
                boost::apply_visitor(*this, instruction);
            }

            currentContext = currentContext->parent();
        }

        void operator()(ASTFor& for_){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            visit(for_.start);
            visit(for_.condition);
            visit(for_.repeat);

            for(auto& instruction : for_.instructions){
                boost::apply_visitor(*this, instruction);
            }

            currentContext = currentContext->parent();
        }

        void operator()(ASTForeach& foreach){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            foreach.context = currentContext;

            for(auto& instruction : foreach.instructions){
                boost::apply_visitor(*this, instruction);
            }

            currentContext = currentContext->parent();
        }

        void operator()(ASTIf& if_){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            boost::apply_visitor(*this, if_.condition);

            for(auto& instruction : if_.instructions){
                boost::apply_visitor(*this, instruction);
            }

            for(auto& elseIf : if_.elseIfs){
                (*this)(elseIf);
            }

            if(if_.else_){
                (*this)(*if_.else_);
            }

            currentContext = currentContext->parent();
        }

        void operator()(ASTElseIf& elseIf){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            boost::apply_visitor(*this, elseIf.condition);

            for(auto& instruction : elseIf.instructions){
                boost::apply_visitor(*this, instruction);
            }

            currentContext = currentContext->parent();
        }

        void operator()(ASTElse& else_){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            for(auto& instruction : else_.instructions){
                boost::apply_visitor(*this, instruction);
            }

            currentContext = currentContext->parent();
        }

        void operator()(ASTFunctionCall& functionCall){
            for(auto& value : functionCall.values){
                boost::apply_visitor(*this, value);
            }
        }

        void operator()(ASTDeclaration& declaration){
            declaration.context = currentContext;

            boost::apply_visitor(*this, declaration.value);
        }

        void operator()(ASTAssignment& assignment){
            assignment.context = currentContext;

            boost::apply_visitor(*this, assignment.value);
        }

        void operator()(ASTComposedValue& value){
            boost::apply_visitor(*this, value.first);

            for(auto& operation : value.operations){
                boost::apply_visitor(*this, operation.get<1>());
            }
        }

        void operator()(ASTBinaryCondition& binaryCondition){
            boost::apply_visitor(*this, binaryCondition);
        }

        //Find a way to simplify the 6 following operators
        void operator()(ASTEquals& equals){
            boost::apply_visitor(*this, equals.lhs);
            boost::apply_visitor(*this, equals.rhs);
        }

        void operator()(ASTNotEquals& notEquals){
            boost::apply_visitor(*this, notEquals.lhs);
            boost::apply_visitor(*this, notEquals.rhs);
        }

        void operator()(ASTLess& less){
            boost::apply_visitor(*this, less.lhs);
            boost::apply_visitor(*this, less.rhs);
        }

        void operator()(ASTLessEquals& less){
            boost::apply_visitor(*this, less.lhs);
            boost::apply_visitor(*this, less.rhs);
        }

        void operator()(ASTGreater& greater){
            boost::apply_visitor(*this, greater.lhs);
            boost::apply_visitor(*this, greater.rhs);
        }

        void operator()(ASTGreaterEquals& greater){
            boost::apply_visitor(*this, greater.lhs);
            boost::apply_visitor(*this, greater.rhs);
        }

        void operator()(Node& node){
            node.context = currentContext;
        }

        void operator()(TerminalNode&){
            //A terminal node has no context
        }

        //Utility operators
        template<typename T>
        void visit(boost::optional<T> optional){
            if(optional){
                boost::apply_visitor(*this, *optional);
            }
        }
};

void ContextAnnotator::annotate(ASTProgram& program){
    AnnotateVisitor visitor;
    visitor(program);
}
<commit_msg>Use lambda expressions instead of for_loop<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <algorithm>

#include <memory>
#include <boost/variant/variant.hpp>

#include "ContextAnnotator.hpp"

#include "ast/Program.hpp"

#include "Context.hpp"
#include "GlobalContext.hpp"
#include "FunctionContext.hpp"
#include "BlockContext.hpp"

using namespace eddic;

class AnnotateVisitor : public boost::static_visitor<> {
    private:
        std::shared_ptr<GlobalContext> globalContext;
        std::shared_ptr<FunctionContext> functionContext;
        std::shared_ptr<Context> currentContext;

    public:
        void operator()(ASTProgram& program){
            currentContext = globalContext = std::make_shared<GlobalContext>();

            program.context = currentContext;

            for_each(program.blocks.begin(), program.blocks.end(),
                [&](FirstLevelBlock& block){ boost::apply_visitor(*this, block); });
        }

        void operator()(FunctionDeclaration& function){
            currentContext = functionContext = std::make_shared<FunctionContext>(currentContext);

            function.context = currentContext;

            for_each(function.instructions.begin(), function.instructions.end(),
                [&](ASTInstruction& instruction){ boost::apply_visitor(*this, instruction); });

            currentContext = currentContext->parent();
        }

        void operator()(ASTWhile& while_){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            boost::apply_visitor(*this, while_.condition);

            for_each(while_.instructions.begin(), while_.instructions.end(),
                [&](ASTInstruction& instruction){ boost::apply_visitor(*this, instruction); });

            currentContext = currentContext->parent();
        }

        void operator()(ASTFor& for_){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            visit(for_.start);
            visit(for_.condition);
            visit(for_.repeat);

            for_each(for_.instructions.begin(), for_.instructions.end(),
                [&](ASTInstruction& instruction){ boost::apply_visitor(*this, instruction); });

            currentContext = currentContext->parent();
        }

        void operator()(ASTForeach& foreach){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            foreach.context = currentContext;

            for_each(foreach.instructions.begin(), foreach.instructions.end(),
                [&](ASTInstruction& instruction){ boost::apply_visitor(*this, instruction); });

            currentContext = currentContext->parent();
        }

        void operator()(ASTIf& if_){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            boost::apply_visitor(*this, if_.condition);

            for_each(if_.instructions.begin(), if_.instructions.end(),
                [&](ASTInstruction& instruction){ boost::apply_visitor(*this, instruction); });

            for(auto& elseIf : if_.elseIfs){
                (*this)(elseIf);
            }

            if(if_.else_){
                (*this)(*if_.else_);
            }

            currentContext = currentContext->parent();
        }

        void operator()(ASTElseIf& elseIf){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            boost::apply_visitor(*this, elseIf.condition);

            for_each(elseIf.instructions.begin(), elseIf.instructions.end(),
                [&](ASTInstruction& instruction){ boost::apply_visitor(*this, instruction); });

            currentContext = currentContext->parent();
        }

        void operator()(ASTElse& else_){
            currentContext = std::make_shared<BlockContext>(currentContext, functionContext);

            for_each(else_.instructions.begin(), else_.instructions.end(),
                [&](ASTInstruction& instruction){ boost::apply_visitor(*this, instruction); });

            currentContext = currentContext->parent();
        }

        void operator()(ASTFunctionCall& functionCall){
            for_each(functionCall.values.begin(), functionCall.values.end(),
                [&](ASTValue& value){ boost::apply_visitor(*this, value); });
        }

        void operator()(ASTDeclaration& declaration){
            declaration.context = currentContext;

            boost::apply_visitor(*this, declaration.value);
        }

        void operator()(ASTAssignment& assignment){
            assignment.context = currentContext;

            boost::apply_visitor(*this, assignment.value);
        }

        void operator()(ASTComposedValue& value){
            boost::apply_visitor(*this, value.first);

            for_each(value.operations.begin(), value.operations.end(),
                [&](boost::tuple<char, ASTValue>& operation){ boost::apply_visitor(*this, operation.get<1>()); });
        }

        void operator()(ASTBinaryCondition& binaryCondition){
            boost::apply_visitor(*this, binaryCondition);
        }

        //Find a way to simplify the 6 following operators
        void operator()(ASTEquals& equals){
            boost::apply_visitor(*this, equals.lhs);
            boost::apply_visitor(*this, equals.rhs);
        }

        void operator()(ASTNotEquals& notEquals){
            boost::apply_visitor(*this, notEquals.lhs);
            boost::apply_visitor(*this, notEquals.rhs);
        }

        void operator()(ASTLess& less){
            boost::apply_visitor(*this, less.lhs);
            boost::apply_visitor(*this, less.rhs);
        }

        void operator()(ASTLessEquals& less){
            boost::apply_visitor(*this, less.lhs);
            boost::apply_visitor(*this, less.rhs);
        }

        void operator()(ASTGreater& greater){
            boost::apply_visitor(*this, greater.lhs);
            boost::apply_visitor(*this, greater.rhs);
        }

        void operator()(ASTGreaterEquals& greater){
            boost::apply_visitor(*this, greater.lhs);
            boost::apply_visitor(*this, greater.rhs);
        }

        void operator()(Node& node){
            node.context = currentContext;
        }

        void operator()(TerminalNode&){
            //A terminal node has no context
        }

        //Utility operators
        template<typename T>
        void visit(boost::optional<T> optional){
            if(optional){
                boost::apply_visitor(*this, *optional);
            }
        }
};

void ContextAnnotator::annotate(ASTProgram& program){
    AnnotateVisitor visitor;
    visitor(program);
}
<|endoftext|>


<commit_before>#include <system_error>
#include <cerrno>
#include <cstdlib>
#include <array>

#include <fmt/format.h>

#include "prefix.hpp"
#include "python.hpp"
#include "plugin_handler.hpp"

namespace bookwyrm::core {

void plugin_handler::load_plugins()
{
    vector<fs::path> plugin_paths;
#ifdef DEBUG
    /* Bookwyrm must be run from build/ in DEBUG mode. */
    plugin_paths = { fs::canonical(fs::path("../src/core/plugins")) };
#else
    plugin_paths = { fs::canonical(fs::path(std::string(INSTALL_PREFIX) + "/etc/bookwyrm/plugins")) };

    /* if (fs::path conf = std::getenv("XDG_CONFIG_HOME"); !conf.empty()) */
    /*     plugin_paths.push_back(conf / "bookwyrm/plugins"); */
    /* else if (fs::path home = std::getenv("HOME"); !home.empty()) */
    /*     plugin_paths.push_back(home / ".config/bookwyrm/plugins"); */
    /* else */
    /*     log(log_level::err, "couldn't find any plugin directories."); */
#endif

    /*
     * Append the plugin paths to Python's sys.path,
     * allowing them to be imported.
     */
    auto sys_path = py::reinterpret_borrow<py::list>(py::module::import("sys").attr("path"));
    for (auto &p : plugin_paths)
        sys_path.append(p.string().c_str());

    /* And add the path to where pybookwyrm.so is available. */
    const std::string lib_path = fmt::format("{}/usr/lib", INSTALL_PREFIX);
    sys_path.append(lib_path.c_str());

    /*
     * Find all Python modules and populate the
     * list of plugins by loading them.
     *
     * The first occurance of a module will be imported,
     * the latter ones will be ignored by Python. So we
     * either need to prepend the paths to sys.path, or
     * make sure that we don't clash with the many module
     * names in Python.
     */
    vector<py::module> plugins;
    for (const auto &plugin_path : plugin_paths) {
        for (const fs::path &p : fs::directory_iterator(plugin_path)) {
            if (p.extension() != ".py") continue;
            if (!debug_ && p.stem().string().rfind("debug-", 0) == 0) continue;

            if (!readable_file(p)) {
                log(log_level::err, fmt::format("can't load module '{}': not a regular file or unreadable"
                        "; ignoring...", p.string()));
                continue;
            }

            try {
                string module = p.stem();
                log(log_level::debug, fmt::format("loading module '{}'...", module));
                plugins.emplace_back(py::module::import(module.c_str()));
            } catch (const py::error_already_set &err) {
                log(log_level::err, fmt::format("{}; ignoring...", err.what()));
            }
        }
    }

    if (plugins.empty())
        throw std::runtime_error("couldn't find any valid plugin scripts");

    plugins_ = std::move(plugins);
}

plugin_handler::~plugin_handler()
{
    for (auto &t : threads_)
        t.detach();

    frontend_.reset();
}

void plugin_handler::async_search()
{
    assert(!plugins_.empty());

    /* Ensure pybind internals are initialized. */
    py::get_shared_data("");

    for (py::module m : plugins_) {
        threads_.emplace_back([m, wanted = wanted_, instance = this]() mutable {
            /* Required whenever we need to run anything Python. */
            auto gil = std::make_unique<py::gil_scoped_acquire>();

            /*
             * We have to go manual here. Normally, when unwinding on pthread exit,
             * Python operations may be performed without holding the GIL, leading to a segfault.
             *
             * This fix may only work on Linux, since abi::__forced_unwind is an implementation detail.
             */
            py::object func;
            py::tuple args = py::make_tuple(wanted, instance);

            try {
                func = m.attr("find");
                m.release().dec_ref();
                PyObject_Call(func.ptr(), args.ptr(), nullptr);
            } catch (abi::__forced_unwind&) {
                /*
                 * Forced stack unwinding at thread exit —
                 * if Python is shutting down, don't clean up Python state.
                 */
                if (!Py_IsInitialized()) {
                    args.release();
                    func.release();
                    gil.release();
                }

                /* Important rethrow! But what do we catch? */
                throw;
            } catch (const py::error_already_set &err) {
                instance->log(log_level::err, fmt::format("module '{}' did something wrong: {}; ignoring...",
                    m.attr("__name__").cast<string>(), err.what()));
            }
        });
    }

    /*
     * We have called all Python code we need to from here,
     * so we release the GIL and let the modules do their job.
     */
    this->nogil = std::make_unique<py::gil_scoped_release>();
}

void plugin_handler::add_item(std::tuple<nonexacts_t, exacts_t, misc_t> item_comps)
{
    const item item(item_comps);
    if (!item.matches(wanted_) || item.misc.uris.size() == 0)
        return;

    std::lock_guard<std::mutex> guard(items_mutex_);

    bool inserted = false;
    std::tie(std::ignore, inserted) = items_.insert(item);

    if (auto fe = frontend_.lock(); fe && inserted)
        fe->update();
}

void plugin_handler::log(log_level lvl, string msg)
{
    if (frontend_.expired()) {
        buffer_.emplace_back(lvl, msg);
    } else if (!buffer_.empty()) {
        auto fe = frontend_.lock();
        if (!fe) return;

        for (const auto& [level, message] : buffer_)
            fe->log(level, message);

        buffer_.clear();
    } else {
        if (auto fe = frontend_.lock(); fe)
            fe->log(lvl, msg);
    }
}

/* ns butler */
}
<commit_msg>core: flush plugin handler log buffer upon destruction<commit_after>#include <system_error>
#include <cerrno>
#include <cstdlib>
#include <array>

#include <fmt/format.h>

#include "prefix.hpp"
#include "python.hpp"
#include "plugin_handler.hpp"

namespace bookwyrm::core {

void plugin_handler::load_plugins()
{
    vector<fs::path> plugin_paths;
#ifdef DEBUG
    /* Bookwyrm must be run from build/ in DEBUG mode. */
    plugin_paths = { fs::canonical(fs::path("../src/core/plugins")) };
#else
    plugin_paths = { fs::canonical(fs::path(std::string(INSTALL_PREFIX) + "/etc/bookwyrm/plugins")) };

    /* if (fs::path conf = std::getenv("XDG_CONFIG_HOME"); !conf.empty()) */
    /*     plugin_paths.push_back(conf / "bookwyrm/plugins"); */
    /* else if (fs::path home = std::getenv("HOME"); !home.empty()) */
    /*     plugin_paths.push_back(home / ".config/bookwyrm/plugins"); */
    /* else */
    /*     log(log_level::err, "couldn't find any plugin directories."); */
#endif

    /*
     * Append the plugin paths to Python's sys.path,
     * allowing them to be imported.
     */
    auto sys_path = py::reinterpret_borrow<py::list>(py::module::import("sys").attr("path"));
    for (auto &p : plugin_paths)
        sys_path.append(p.string().c_str());

    /* And add the path to where pybookwyrm.so is available. */
    const std::string lib_path = fmt::format("{}/usr/lib", INSTALL_PREFIX);
    sys_path.append(lib_path.c_str());

    log(log_level::err, fmt::format("looking for scripts in {}", plugin_paths[0].string()));
    log(log_level::err, fmt::format("coercing CPython to look for pybookwyrm in {}", lib_path));

    /*
     * Find all Python modules and populate the
     * list of plugins by loading them.
     *
     * The first occurance of a module will be imported,
     * the latter ones will be ignored by Python. So we
     * either need to prepend the paths to sys.path, or
     * make sure that we don't clash with the many module
     * names in Python.
     */
    vector<py::module> plugins;
    for (const auto &plugin_path : plugin_paths) {
        for (const fs::path &p : fs::directory_iterator(plugin_path)) {
            if (p.extension() != ".py") continue;
            if (!debug_ && p.stem().string().rfind("debug-", 0) == 0) continue;

            if (!readable_file(p)) {
                log(log_level::err, fmt::format("can't load module '{}': not a regular file or unreadable"
                        "; ignoring...", p.string()));
                continue;
            }

            try {
                string module = p.stem();
                log(log_level::debug, fmt::format("loading module '{}'...", module));
                plugins.emplace_back(py::module::import(module.c_str()));
            } catch (const py::error_already_set &err) {
                log(log_level::err, fmt::format("{}; ignoring...", err.what()));
            }
        }
    }

    if (plugins.empty())
        throw std::runtime_error("couldn't find any valid plugin scripts");

    plugins_ = std::move(plugins);
}

plugin_handler::~plugin_handler()
{
    /* Flush log entries. */
    // TODO: respect [--debug] and print log level before msg.
    for (const auto& [lvl, msg] : buffer_)
        (lvl <= log_level::warn ? std::cout : std::cerr) << msg << "\n";

    for (auto &t : threads_)
        t.detach();

    frontend_.reset();
}

void plugin_handler::async_search()
{
    assert(!plugins_.empty());

    /* Ensure pybind internals are initialized. */
    py::get_shared_data("");

    for (py::module m : plugins_) {
        threads_.emplace_back([m, wanted = wanted_, instance = this]() mutable {
            /* Required whenever we need to run anything Python. */
            auto gil = std::make_unique<py::gil_scoped_acquire>();

            /*
             * We have to go manual here. Normally, when unwinding on pthread exit,
             * Python operations may be performed without holding the GIL, leading to a segfault.
             *
             * This fix may only work on Linux, since abi::__forced_unwind is an implementation detail.
             */
            py::object func;
            py::tuple args = py::make_tuple(wanted, instance);

            try {
                func = m.attr("find");
                m.release().dec_ref();
                PyObject_Call(func.ptr(), args.ptr(), nullptr);
            } catch (abi::__forced_unwind&) {
                /*
                 * Forced stack unwinding at thread exit —
                 * if Python is shutting down, don't clean up Python state.
                 */
                if (!Py_IsInitialized()) {
                    args.release();
                    func.release();
                    gil.release();
                }

                /* Important rethrow! But what do we catch? */
                throw;
            } catch (const py::error_already_set &err) {
                instance->log(log_level::err, fmt::format("module '{}' did something wrong: {}; ignoring...",
                    m.attr("__name__").cast<string>(), err.what()));
            }
        });
    }

    /*
     * We have called all Python code we need to from here,
     * so we release the GIL and let the modules do their job.
     */
    this->nogil = std::make_unique<py::gil_scoped_release>();
}

void plugin_handler::add_item(std::tuple<nonexacts_t, exacts_t, misc_t> item_comps)
{
    const item item(item_comps);
    if (!item.matches(wanted_) || item.misc.uris.size() == 0)
        return;

    std::lock_guard<std::mutex> guard(items_mutex_);

    bool inserted = false;
    std::tie(std::ignore, inserted) = items_.insert(item);

    if (auto fe = frontend_.lock(); fe && inserted)
        fe->update();
}

void plugin_handler::log(log_level lvl, string msg)
{
    if (frontend_.expired()) {
        buffer_.emplace_back(lvl, msg);
    } else if (!buffer_.empty()) {
        auto fe = frontend_.lock();
        if (!fe) return;

        for (const auto& [level, message] : buffer_)
            fe->log(level, message);

        buffer_.clear();
    } else {
        if (auto fe = frontend_.lock(); fe)
            fe->log(lvl, msg);
    }
}

/* ns butler */
}
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2012-2021 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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.
 *
 * 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.
 *
 *********************************************************************************/

#include <inviwo/core/util/assertion.h>
#include <inviwo/core/util/logcentral.h>

#include <fmt/format.h>

#ifndef WIN32
#include <signal.h>
#else
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
#endif

namespace inviwo {

#if defined(IVW_DEBUG) || defined(IVW_FORCE_ASSERTIONS)

void assertion(std::string_view fileName, std::string_view functionName, long lineNumber,
               std::string_view error) {

    const auto message = fmt::format("Assertion failed in ({}:{}, {}): {}", fileName, lineNumber,
                                     functionName, error);
    if (LogCentral::isInitialized()) {
        LogCentral::getPtr()->logAssertion(fileName, functionName, lineNumber, message);
    }

    util::debugBreak();
    exit(-1);
}

#else

void assertion(std::string_view, std::string_view, long, std::string_view) {}

#endif  // _DEBUG

void util::debugBreak() {
#ifdef WIN32
    if (IsDebuggerPresent()) {
        __debugbreak();
    }
#else
    raise(SIGTRAP);
#endif
}

}  // namespace inviwo
<commit_msg>Core: Apple fix for debugbreak<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2012-2021 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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.
 *
 * 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.
 *
 *********************************************************************************/

#include <inviwo/core/util/assertion.h>
#include <inviwo/core/util/logcentral.h>

#include <fmt/format.h>

#ifndef WIN32
#include <signal.h>
#endif

#if defined(WIN32)
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
#elif defined(__APPLE__)
#include <assert.h>
#include <unistd.h>
#include <sys/sysctl.h>

// Function is taken from https://developer.apple.com/library/mac/qa/qa1361/_index.html
// Returns true if the current process is being debugged (either running under the
// debugger or has a debugger attached post facto).
static bool runningInDebugger() {
    int junk;
    int mib[4];
    struct kinfo_proc info;
    size_t size;

    // Initialize the flags so that, if sysctl fails for some bizarre
    // reason, we get a predictable result.
    info.kp_proc.p_flag = 0;

    // Initialize mib, which tells sysctl the info we want, in this case
    // we're looking for information about a specific process ID.
    mib[0] = CTL_KERN;
    mib[1] = KERN_PROC;
    mib[2] = KERN_PROC_PID;
    mib[3] = getpid();

    // Call sysctl.
    size = sizeof(info);
    junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
    ghoul_assert(junk == 0, "sysctl call failed");

    // We're being debugged if the P_TRACED flag is set.
    return ((info.kp_proc.p_flag & P_TRACED) != 0);
}
#endif

namespace inviwo {

#if defined(IVW_DEBUG) || defined(IVW_FORCE_ASSERTIONS)

void assertion(std::string_view fileName, std::string_view functionName, long lineNumber,
               std::string_view error) {

    const auto message = fmt::format("Assertion failed in ({}:{}, {}): {}", fileName, lineNumber,
                                     functionName, error);
    if (LogCentral::isInitialized()) {
        LogCentral::getPtr()->logAssertion(fileName, functionName, lineNumber, message);
    }

    util::debugBreak();
    exit(-1);
}

#else

void assertion(std::string_view, std::string_view, long, std::string_view) {}

#endif  // _DEBUG

void util::debugBreak() {
#ifdef WIN32
    if (IsDebuggerPresent()) {
        __debugbreak();
    }
#elif __APPLE__
    if (runningInDebugger()) {
        raise(SIGTRAP);
    }
#else
    raise(SIGTRAP);
#endif
}

}  // namespace inviwo
<|endoftext|>


<commit_before>// This code is based on Sabberstone project.
// Copyright (c) 2017-2019 SabberStone Team, darkfriend77 & rnilva
// RosettaStone is hearthstone simulator using C++ with reinforcement learning.
// Copyright (c) 2019 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

#include <Rosetta/Games/Game.hpp>
#include <Rosetta/Tasks/SimpleTasks/ConditionTask.hpp>
#include <Rosetta/Tasks/SimpleTasks/IncludeTask.hpp>

#include <utility>

namespace RosettaStone::SimpleTasks
{
ConditionTask::ConditionTask(EntityType entityType,
                             std::vector<SelfCondition> selfConditions)
    : ITask(entityType), m_selfConditions(std::move(selfConditions))
{
    // Do nothing
}

TaskID ConditionTask::GetTaskID() const
{
    return TaskID::CONDITION;
}

TaskStatus ConditionTask::Impl(Player& player)
{
    auto entities =
        IncludeTask::GetEntities(m_entityType, player, m_source, m_target);
    if (entities.empty())
    {
        return TaskStatus::STOP;
    }

    bool flag = true;
    for (auto& condition : m_selfConditions)
    {
        flag = flag && condition.Evaluate(m_source);
    }

    player.GetGame()->taskStack.source = m_source;
    player.GetGame()->taskStack.target = m_target;
    player.GetGame()->taskStack.flag = flag;

    return TaskStatus::COMPLETE;
}
}  // namespace RosettaStone::SimpleTasks
<commit_msg>fix: Correct code to evaluate entities instead of source<commit_after>// This code is based on Sabberstone project.
// Copyright (c) 2017-2019 SabberStone Team, darkfriend77 & rnilva
// RosettaStone is hearthstone simulator using C++ with reinforcement learning.
// Copyright (c) 2019 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

#include <Rosetta/Games/Game.hpp>
#include <Rosetta/Tasks/SimpleTasks/ConditionTask.hpp>
#include <Rosetta/Tasks/SimpleTasks/IncludeTask.hpp>

#include <utility>

namespace RosettaStone::SimpleTasks
{
ConditionTask::ConditionTask(EntityType entityType,
                             std::vector<SelfCondition> selfConditions)
    : ITask(entityType), m_selfConditions(std::move(selfConditions))
{
    // Do nothing
}

TaskID ConditionTask::GetTaskID() const
{
    return TaskID::CONDITION;
}

TaskStatus ConditionTask::Impl(Player& player)
{
    auto entities =
        IncludeTask::GetEntities(m_entityType, player, m_source, m_target);
    if (entities.empty())
    {
        return TaskStatus::STOP;
    }

    bool flag = true;

    for (auto& entity : entities)
    {
        for (auto& condition : m_selfConditions)
        {
            flag = flag && condition.Evaluate(entity);
        }
    }

    player.GetGame()->taskStack.source = m_source;
    player.GetGame()->taskStack.target = m_target;
    player.GetGame()->taskStack.flag = flag;

    return TaskStatus::COMPLETE;
}
}  // namespace RosettaStone::SimpleTasks
<|endoftext|>


<commit_before>//
//  yamiHikariGameAppDelegate.cpp
//  yamiHikariGame
//
//  Created by slightair on 2013/07/16.
//  Copyright __MyCompanyName__ 2013年. All rights reserved.
//

#include "AppDelegate.h"

#include "cocos2d.h"
#include "SimpleAudioEngine.h"
#include "Constants.h"
#include "TitleScene.h"

#define kDefaultDesignResolutionWidth 320
#define kDefaultDesignResolutionHeight 480
#define kIPadDesignResolutionWidth 768
#define kIPadDesignResolutionHeight 1024

#define kIPhone4inchHeight 568
#define kIPhone3_5inchHeight 480
#define kIPadHeight 1024

#define kIPhone4inchScreenHeight 1136

USING_NS_CC;
using namespace CocosDenshion;

AppDelegate::AppDelegate()
{

}

AppDelegate::~AppDelegate()
{
}

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    CCDirector *pDirector = CCDirector::sharedDirector();
    CCEGLView *openGLView = CCEGLView::sharedOpenGLView();
    CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils();

    std::vector<std::string> searchResolutionsOrder;

    pDirector->setOpenGLView(openGLView);

    // turn on display FPS
    pDirector->setDisplayStats(true);

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    CCSize screenSize = openGLView->getFrameSize();

    TargetPlatform platform = CCApplication::sharedApplication()->getTargetPlatform();
    if (platform == kTargetIphone) {
        if (screenSize.height == kIPhone4inchScreenHeight) {
            openGLView->setDesignResolutionSize(kDefaultDesignResolutionWidth, kIPhone4inchHeight, kResolutionExactFit);
        }
        else {
            openGLView->setDesignResolutionSize(kDefaultDesignResolutionWidth, kDefaultDesignResolutionHeight, kResolutionExactFit);
        }
    }
    else {
        openGLView->setDesignResolutionSize(kIPadDesignResolutionWidth, kIPadDesignResolutionHeight, kResolutionExactFit);
    }

    float retinaThreshold = platform == kTargetIphone ? kIPhone3_5inchHeight : kIPadHeight;
    if (screenSize.height > retinaThreshold) {
        searchResolutionsOrder.push_back("ios-hd");
        pDirector->setContentScaleFactor(2.0f);
    }
    else {
        searchResolutionsOrder.push_back("default");
    }
#else
    // Android, etc...
    openGLView->setDesignResolutionSize(defaultDesignResolutionSize.width, defaultDesignResolutionSize.height, kResolutionExactFit);
    searchResolutionsOrder.push_back("default");
#endif

    fileUtils->setSearchResolutionsOrder(searchResolutionsOrder);

    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60);

    CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("spriteSheet.plist");

    CocosDenshion::SimpleAudioEngine::sharedEngine()->setEffectsVolume(SoundEffectVolume);
    CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(SEItemGet);
    CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(SEBadItemGet);
    CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(SEGameOver);

    // create a scene. it's an autorelease object
    CCScene *pScene = TitleScene::scene();

    // run
    pDirector->runWithScene(pScene);

    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->stopAnimation();
    SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
    SimpleAudioEngine::sharedEngine()->pauseAllEffects();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    CCDirector::sharedDirector()->startAnimation();
    SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
    SimpleAudioEngine::sharedEngine()->resumeAllEffects();
}
<commit_msg>FPS表示を無効にした<commit_after>//
//  yamiHikariGameAppDelegate.cpp
//  yamiHikariGame
//
//  Created by slightair on 2013/07/16.
//  Copyright __MyCompanyName__ 2013年. All rights reserved.
//

#include "AppDelegate.h"

#include "cocos2d.h"
#include "SimpleAudioEngine.h"
#include "Constants.h"
#include "TitleScene.h"

#define kDefaultDesignResolutionWidth 320
#define kDefaultDesignResolutionHeight 480
#define kIPadDesignResolutionWidth 768
#define kIPadDesignResolutionHeight 1024

#define kIPhone4inchHeight 568
#define kIPhone3_5inchHeight 480
#define kIPadHeight 1024

#define kIPhone4inchScreenHeight 1136

USING_NS_CC;
using namespace CocosDenshion;

AppDelegate::AppDelegate()
{

}

AppDelegate::~AppDelegate()
{
}

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    CCDirector *pDirector = CCDirector::sharedDirector();
    CCEGLView *openGLView = CCEGLView::sharedOpenGLView();
    CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils();

    std::vector<std::string> searchResolutionsOrder;

    pDirector->setOpenGLView(openGLView);

    // turn on display FPS
    pDirector->setDisplayStats(false);

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    CCSize screenSize = openGLView->getFrameSize();

    TargetPlatform platform = CCApplication::sharedApplication()->getTargetPlatform();
    if (platform == kTargetIphone) {
        if (screenSize.height == kIPhone4inchScreenHeight) {
            openGLView->setDesignResolutionSize(kDefaultDesignResolutionWidth, kIPhone4inchHeight, kResolutionExactFit);
        }
        else {
            openGLView->setDesignResolutionSize(kDefaultDesignResolutionWidth, kDefaultDesignResolutionHeight, kResolutionExactFit);
        }
    }
    else {
        openGLView->setDesignResolutionSize(kIPadDesignResolutionWidth, kIPadDesignResolutionHeight, kResolutionExactFit);
    }

    float retinaThreshold = platform == kTargetIphone ? kIPhone3_5inchHeight : kIPadHeight;
    if (screenSize.height > retinaThreshold) {
        searchResolutionsOrder.push_back("ios-hd");
        pDirector->setContentScaleFactor(2.0f);
    }
    else {
        searchResolutionsOrder.push_back("default");
    }
#else
    // Android, etc...
    openGLView->setDesignResolutionSize(defaultDesignResolutionSize.width, defaultDesignResolutionSize.height, kResolutionExactFit);
    searchResolutionsOrder.push_back("default");
#endif

    fileUtils->setSearchResolutionsOrder(searchResolutionsOrder);

    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60);

    CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("spriteSheet.plist");

    CocosDenshion::SimpleAudioEngine::sharedEngine()->setEffectsVolume(SoundEffectVolume);
    CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(SEItemGet);
    CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(SEBadItemGet);
    CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(SEGameOver);

    // create a scene. it's an autorelease object
    CCScene *pScene = TitleScene::scene();

    // run
    pDirector->runWithScene(pScene);

    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->stopAnimation();
    SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
    SimpleAudioEngine::sharedEngine()->pauseAllEffects();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    CCDirector::sharedDirector()->startAnimation();
    SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
    SimpleAudioEngine::sharedEngine()->resumeAllEffects();
}
<|endoftext|>


<commit_before>#include "pydbc/descriptions/number_description.h"

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit_toolbox/extensions/assert_equal_with_different_types.h>
#include <sqlext.h>

class number_description_test : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE( number_description_test );

	CPPUNIT_TEST( positive_integer );
	CPPUNIT_TEST( negative_integer );

CPPUNIT_TEST_SUITE_END();

public:

	void positive_integer();
	void negative_integer();

};

// Registers the fixture with the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( number_description_test );

void number_description_test::positive_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 1234567890 from low to high bytes
				{0xd2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = 1234567890;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::negative_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // - sign
				// binary representation of 1234567890 from low to high bytes
				{0xd2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = -1234567890;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}
<commit_msg>Add tests for number description.<commit_after>#include "pydbc/descriptions/number_description.h"

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit_toolbox/extensions/assert_equal_with_different_types.h>
#include <sqlext.h>
#include <limits.h>
#include <stdexcept>

class number_description_test : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE( number_description_test );

	CPPUNIT_TEST( positive_integer );
	CPPUNIT_TEST( negative_integer );
	CPPUNIT_TEST( max_positive_integer );
	CPPUNIT_TEST( min_negative_integer );
	CPPUNIT_TEST( larger_than_max_positive_overflows );

CPPUNIT_TEST_SUITE_END();

public:

	void positive_integer();
	void negative_integer();
	void max_positive_integer();
	void min_negative_integer();
	void larger_than_max_positive_overflows();

};

// Registers the fixture with the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( number_description_test );

void number_description_test::positive_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 1234567890 from low to high bytes
				{0xd2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = 1234567890;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::negative_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // - sign
				// binary representation of 1234567890 from low to high bytes
				{0xd2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = -1234567890;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::max_positive_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 2^63 - 1
				{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = std::numeric_limits<long>::max();
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::min_negative_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // + sign
				// binary representation of 2^63
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = std::numeric_limits<long>::min();
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::larger_than_max_positive_overflows()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 2^63 = maximum positive integer + 1
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	pydbc::number_description description;
	std::cout << "\n\n" << description.make_field(reinterpret_cast<char const *>(&data)) << "\n\n";
	CPPUNIT_ASSERT_THROW(description.make_field(reinterpret_cast<char const *>(&data)), std::overflow_error);
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 The Caroline authors. All right reserved.
// Use of this source file is governed by a MIT license that can be found in the
// License file
/// @author: Vladislav Krikunov <vlad.krikunoff@yandex.ru>

#include "core/serialization.h"

#include <string>
#include <utility>
#include <vector>

#include "base/stream.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"

namespace bitdata {

void GlobalMessage::SetOStream(const std::string& ostream) {
  ostream_name_ = ostream;
  ostream_ = base::Stream::Open(ostream_name_, base::Stream::kWrite);
}

void GlobalMessage::SetIStream(const std::string& istream) {
  istream_name_ = istream;
  istream_ = base::Stream::Open(istream_name_, base::Stream::kRead);
}

void GlobalMessage::MakeMessage(Message* message) {
  size_t size = message->ByteSize();
  int size_of_size = google::protobuf::io
                     ::CodedOutputStream::VarintSize32(size);
  std::unique_ptr<char[]>bit_message(new char[size + size_of_size]);
  google::protobuf::io::ArrayOutputStream stream_message(bit_message.get(),
                                                         size + size_of_size);
  google::protobuf::io::CodedOutputStream coded_message(&stream_message);
  coded_message.WriteVarint32(size);
  message->SerializeToCodedStream(&coded_message);
  ostream_->Write(bit_message.get(), size + size_of_size);
}

void GlobalMessage::GenDMap(const core::DepthMap& depth_map) {
  std::unique_ptr<Message> message(new Message());
  message->mutable_depth_map()->set_width(depth_map.width());
  message->mutable_depth_map()->set_height(depth_map.height());
  for (double depth : depth_map)
    message->mutable_depth_map()->add_data(depth);
  message->set_type(Message::DEPTH_MAP);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenOptFlow(const core::OpticalFlow& optical_flow) {
  std::unique_ptr<Message>message(new Message);
  for (auto pair : optical_flow) {
    OpticalFlowItem* item = message->mutable_optical_flow()->add_item();
    item->mutable_left()->set_x(pair.first.x);
    item->mutable_left()->set_y(pair.first.y);
    item->mutable_right()->set_x(pair.second.x);
    item->mutable_right()->set_y(pair.second.y);
  }
  message->set_type(Message::OPTICAL_FLOW);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenModel(const core::Scene3D& scene) {
  std::unique_ptr<Message>message(new Message());
  std::vector<cv::Point3d> vertexes;
  std::vector<core::Triangle> faces;
  core::SceneElement some_element;
  int vertex_base_index = 0;
  for (auto scene_element : scene) {
    for (auto vertex : scene_element->mesh()->vertexes()) {
      auto transformed_vertex = vertex;
      scene_element->Transform(&transformed_vertex, transformed_vertex);
      auto proto_vertex = message->mutable_model()->add_verticies();
      proto_vertex->set_x(vertex.x);
      proto_vertex->set_y(vertex.y);
      proto_vertex->set_z(vertex.z);
    }
    for (auto face : scene_element->mesh()->faces()) {
      auto proto_face = message->mutable_model()->add_faces();
      proto_face->set_point1(face.Point1() + vertex_base_index);
      proto_face->set_point2(face.Point2() + vertex_base_index);
      proto_face->set_point3(face.Point3() + vertex_base_index);
    }
    vertex_base_index += scene_element->mesh()->vertexes().size();
  }
  message->set_type(Message::MODEL);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenPic(const std::vector<std::pair<cv::Mat,
            core::Position>>& frameset) {
  std::unique_ptr<Message>message(new Message());
  std::vector<uint8_t> left, right;
  std::vector<int> prop;
  prop.push_back(cv::IMWRITE_JPEG_QUALITY);
  prop.push_back(95);
  cv::imencode("*.jpeg", frameset[0].first, left, prop);
  cv::imencode("*.jpeg", frameset[1].first, right, prop);
  message->mutable_images()->mutable_left()->
      set_width(frameset[0].first.size().width);
  message->mutable_images()->mutable_left()->
      set_height(frameset[0].first.size().height);
  message->mutable_images()->mutable_right()->
      set_width(frameset[1].first.size().width);
  message->mutable_images()->mutable_right()->
      set_height(frameset[1].first.size().height);
  this->GenLog(std::to_string(left.size()));
  this->GenLog(std::to_string(right.size()));

  auto it = left.begin(), end = left.end();
  int data = *it , count = 1;
  while (it != end) {
    data << 8;
    data += *(++it);
    if (!(count % 4) || it == end) {
      message->mutable_images()->mutable_left()->add_data(data);
      data = 0;
    }
    ++count;
  }
  it = right.begin(); end = right.end();
  data = *it; count = 1;
  while (it != end) {
    data << 8;
    data += *(++it);
    if(!(count % 4) || it == end) {
      message->mutable_images()->mutable_right()->add_data(data);
      data = 0;
    }
  count++;
  }
  message->set_type(Message::IMAGES);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenLog(const std::string& message) {
  std::unique_ptr<Message>proto_message(new Message());
  proto_message->mutable_log()->set_line(message);
  proto_message->set_type(Message::LOG);
  this->MakeMessage(proto_message.get());
}

void GlobalMessage::Observe(const std::string& message) {
  GenLog(message);
}

}  // namespace bitdata
<commit_msg>Pack fix<commit_after>// Copyright (c) 2014 The Caroline authors. All right reserved.
// Use of this source file is governed by a MIT license that can be found in the
// License file
/// @author: Vladislav Krikunov <vlad.krikunoff@yandex.ru>

#include "core/serialization.h"

#include <string>
#include <utility>
#include <vector>

#include "base/stream.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"

namespace bitdata {

void GlobalMessage::SetOStream(const std::string& ostream) {
  ostream_name_ = ostream;
  ostream_ = base::Stream::Open(ostream_name_, base::Stream::kWrite);
}

void GlobalMessage::SetIStream(const std::string& istream) {
  istream_name_ = istream;
  istream_ = base::Stream::Open(istream_name_, base::Stream::kRead);
}

void GlobalMessage::MakeMessage(Message* message) {
  size_t size = message->ByteSize();
  int size_of_size = google::protobuf::io
                     ::CodedOutputStream::VarintSize32(size);
  std::unique_ptr<char[]>bit_message(new char[size + size_of_size]);
  google::protobuf::io::ArrayOutputStream stream_message(bit_message.get(),
                                                         size + size_of_size);
  google::protobuf::io::CodedOutputStream coded_message(&stream_message);
  coded_message.WriteVarint32(size);
  message->SerializeToCodedStream(&coded_message);
  ostream_->Write(bit_message.get(), size + size_of_size);
}

void GlobalMessage::GenDMap(const core::DepthMap& depth_map) {
  std::unique_ptr<Message> message(new Message());
  message->mutable_depth_map()->set_width(depth_map.width());
  message->mutable_depth_map()->set_height(depth_map.height());
  for (double depth : depth_map)
    message->mutable_depth_map()->add_data(depth);
  message->set_type(Message::DEPTH_MAP);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenOptFlow(const core::OpticalFlow& optical_flow) {
  std::unique_ptr<Message>message(new Message);
  for (auto pair : optical_flow) {
    OpticalFlowItem* item = message->mutable_optical_flow()->add_item();
    item->mutable_left()->set_x(pair.first.x);
    item->mutable_left()->set_y(pair.first.y);
    item->mutable_right()->set_x(pair.second.x);
    item->mutable_right()->set_y(pair.second.y);
  }
  message->set_type(Message::OPTICAL_FLOW);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenModel(const core::Scene3D& scene) {
  std::unique_ptr<Message>message(new Message());
  std::vector<cv::Point3d> vertexes;
  std::vector<core::Triangle> faces;
  core::SceneElement some_element;
  int vertex_base_index = 0;
  for (auto scene_element : scene) {
    for (auto vertex : scene_element->mesh()->vertexes()) {
      auto transformed_vertex = vertex;
      scene_element->Transform(&transformed_vertex, transformed_vertex);
      auto proto_vertex = message->mutable_model()->add_verticies();
      proto_vertex->set_x(vertex.x);
      proto_vertex->set_y(vertex.y);
      proto_vertex->set_z(vertex.z);
    }
    for (auto face : scene_element->mesh()->faces()) {
      auto proto_face = message->mutable_model()->add_faces();
      proto_face->set_point1(face.Point1() + vertex_base_index);
      proto_face->set_point2(face.Point2() + vertex_base_index);
      proto_face->set_point3(face.Point3() + vertex_base_index);
    }
    vertex_base_index += scene_element->mesh()->vertexes().size();
  }
  message->set_type(Message::MODEL);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenPic(const std::vector<std::pair<cv::Mat,
            core::Position>>& frameset) {
  std::unique_ptr<Message>message(new Message());
  std::vector<uint8_t> left, right;
  std::vector<int> prop;
  prop.push_back(cv::IMWRITE_JPEG_QUALITY);
  prop.push_back(95);
  cv::imencode("*.jpeg", frameset[0].first, left, prop);
  cv::imencode("*.jpeg", frameset[1].first, right, prop);
  message->mutable_images()->mutable_left()->
      set_width(frameset[0].first.size().width);
  message->mutable_images()->mutable_left()->
      set_height(frameset[0].first.size().height);
  message->mutable_images()->mutable_right()->
      set_width(frameset[1].first.size().width);
  message->mutable_images()->mutable_right()->
      set_height(frameset[1].first.size().height);
  this->GenLog(std::to_string(left.size()));
  this->GenLog(std::to_string(right.size()));

  auto it = left.begin(), end = left.end();
  int data = 0 , count = 0;
  while (it != end) {
    data << 8;
    data += *(it++);
    if (!(count % 4) || it == end) {
      message->mutable_images()->mutable_left()->add_data(data);
      data = 0;
    }
    ++count;
  }
  it = right.begin(); end = right.end();
  data = 0; count = 0;
  while (it != end) {
    data << 8;
    data += *(it++);
    if(!(count % 4) || it == end) {
      message->mutable_images()->mutable_right()->add_data(data);
      data = 0;
    }
  count++;
  }
  message->set_type(Message::IMAGES);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenLog(const std::string& message) {
  std::unique_ptr<Message>proto_message(new Message());
  proto_message->mutable_log()->set_line(message);
  proto_message->set_type(Message::LOG);
  this->MakeMessage(proto_message.get());
}

void GlobalMessage::Observe(const std::string& message) {
  GenLog(message);
}

}  // namespace bitdata
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2011 Digital Bazaar, Inc. All rights reserved.
 */
#include "monarch/rt/ThreadPool.h"

using namespace std;
using namespace monarch::rt;

ThreadPool::ThreadPool(unsigned int poolSize, size_t stackSize) :
   mThreadSemaphore(poolSize, true),
   mThreadStackSize(stackSize),
   // default thread expire time to 0 (no expiration)
   mThreadExpireTime(0)
{
}

ThreadPool::~ThreadPool()
{
   // terminate all threads
   terminateAllThreads();
}

PooledThread* ThreadPool::getIdleThread()
{
   PooledThread* rval = NULL;

   // lock lists for modification
   mListLock.lock();
   {
      while(rval == NULL && !mIdleThreads.empty())
      {
         rval = mIdleThreads.front();
         mIdleThreads.pop_front();

         // lock thread's job lock until it is assigned a job or marked expired
         //
         // Note: This must be done because the thread could come out of
         // its idle state while we are checking it. If, when we check it,
         // the thread is not expired, then we might accidentally assign it
         // a job, and in the thread's code it will be interrupted just after
         // we check it, resulting in the assigned job never being handled.
         rval->getJobLock()->lock();
         if(rval->isExpired() || rval->isInterrupted())
         {
            // unlock thread, collect thread for clean up
            rval->getJobLock()->unlock();
            mThreads.remove(rval);
            mExpiredThreads.push_front(rval);
            rval = NULL;
         }
      }

      if(rval == NULL)
      {
         // create new thread and add it to the thread list
         rval = new PooledThread(this, getThreadExpireTime());
         mThreads.push_back(rval);

         // lock thread's job lock to prevent it from going idle before
         // its job is assigned
         rval->getJobLock()->lock();
      }

      // remove extra threads if applicable
      if(!mIdleThreads.empty())
      {
         // get the number of extra threads
         int extraThreads =
            mThreads.size() - mThreadSemaphore.getMaxPermitCount();

         // remove extra idle threads
         if(extraThreads > 0)
         {
            removeIdleThreads((unsigned int)extraThreads);
         }
      }
   }
   mListLock.unlock();

   return rval;
}

void ThreadPool::removeIdleThreads(unsigned int count)
{
   // assume list lock is engaged
   for(ThreadList::iterator i = mIdleThreads.begin();
       count > 0 && i != mIdleThreads.end(); --count)
   {
      // interrupt and erase threads
      PooledThread* t = *i;
      t->interrupt();
      i = mIdleThreads.erase(i);
      mThreads.remove(t);
      mExpiredThreads.push_back(t);
   }
}

void ThreadPool::cleanupExpiredThreads()
{
   if(!mExpiredThreads.empty())
   {
      // move threads to cleanup list to avoid potential deadlock
      // issues involved when threads are completing
      mListLock.lock();
      ThreadList cleanup(mExpiredThreads);
      mExpiredThreads.clear();
      mListLock.unlock();

      // join and cleanup threads
      for(ThreadList::iterator i = cleanup.begin(); i != cleanup.end(); ++i)
      {
         (*i)->join();
         delete (*i);
      }
   }
}

bool ThreadPool::runJobOnIdleThread(Runnable& job, bool block)
{
   bool tryAgain = true;
   PooledThread* t = NULL;
   while(t == NULL && tryAgain)
   {
      // wait for other jobs to be assigned/terminated
      mJobLock.lock();
      {
         // get an idle thread
         t = getIdleThread();

         // set job
         t->setJob(&job);

         // unlock thread's job lock now that a job is assigned, so if it was
         // about to become idle or expire, it will pick up its new assignment
         t->getJobLock()->unlock();

         // if the thread hasn't started yet, start it
         if(!t->hasStarted())
         {
            if(!t->start(mThreadStackSize))
            {
               // cannot start a new thread due to limited system resources,
               // so remove it and try again if blocking
               mThreads.remove(t);
               delete t;
               t = NULL;
               tryAgain = block;
            }
         }
      }
      mJobLock.unlock();

      // clean up expired threads
      cleanupExpiredThreads();
   }

   return t != NULL;
}

bool ThreadPool::runJobOnIdleThread(RunnableRef& job, bool block)
{
   bool tryAgain = true;
   PooledThread* t = NULL;
   while(t == NULL)
   {
      // wait for other jobs to be assigned/terminated
      mJobLock.lock();
      {
         // get an idle thread
         t = getIdleThread();

         // set job
         t->setJob(job);

         // unlock thread's job lock now that a job is assigned, so if it was
         // about to become idle or expire, it will pick up its new assignment
         t->getJobLock()->unlock();

         // if the thread hasn't started yet, start it
         if(!t->hasStarted())
         {
            if(!t->start(mThreadStackSize))
            {
               // cannot start a new thread due to limited system resources,
               // so remove it and try again if blocking
               mThreads.remove(t);
               delete t;
               t = NULL;
               tryAgain = block;
            }
         }
      }
      mJobLock.unlock();

      // clean up expired threads
      cleanupExpiredThreads();
   }

   return t != NULL;
}

bool ThreadPool::tryRunJob(Runnable& job)
{
   bool rval;

   // try to acquire a thread permit
   if((rval = mThreadSemaphore.tryAcquire()))
   {
      // run the job on an idle thread
      if(!(rval = runJobOnIdleThread(job, false)))
      {
         // release thread permit, job could not be started
         mThreadSemaphore.release();
      }
   }

   return rval;
}

bool ThreadPool::tryRunJob(RunnableRef& job)
{
   bool rval;

   // try to acquire a thread permit
   if((rval = mThreadSemaphore.tryAcquire()))
   {
      // run the job on an idle thread
      if(!(rval = runJobOnIdleThread(job, false)))
      {
         // release thread permit, job could not be started
         mThreadSemaphore.release();
      }
   }

   return rval;
}

bool ThreadPool::runJob(Runnable& job)
{
   // acquire a thread permit
   bool rval = mThreadSemaphore.acquire();
   if(rval)
   {
      // run the job on an idle thread
      runJobOnIdleThread(job, true);
   }
   return rval;
}

bool ThreadPool::runJob(RunnableRef& job)
{
   // acquire a thread permit
   bool rval = mThreadSemaphore.acquire();
   if(rval)
   {
      // run the job on an idle thread
      runJobOnIdleThread(job, true);
   }
   return rval;
}

void ThreadPool::jobCompleted(PooledThread* t)
{
   // clear the thread's job, there is no need to engage the thread's
   // job lock here because this method is called from the thread itself,
   // and it therefore cannot be idle, waiting to be notified
   t->setJob(NULL);

   // lock lists for modification
   mListLock.lock();
   {
      // add the thread to the front of the idle list, so it is more
      // likely to get assigned a job immediately
      mIdleThreads.push_front(t);
   }
   mListLock.unlock();

   // release thread permit
   mThreadSemaphore.release();
}

void ThreadPool::interruptAllThreads()
{
   // prevent new jobs from being assigned during interruption
   // ensure lists are not modified during interruption
   mJobLock.lock();
   mListLock.lock();
   {
      // interrupt all threads
      for(ThreadList::iterator i = mThreads.begin(); i != mThreads.end(); ++i)
      {
         (*i)->interrupt();
      }
   }
   mJobLock.unlock();
   mListLock.unlock();
}

void ThreadPool::terminateAllThreads()
{
   // prevent new jobs from being assigned
   mJobLock.lock();
   {
      // prepare for list modification
      mListLock.lock();
      {
         // interrupt all the threads
         interruptAllThreads();

         // move all threads to the expired list
         mExpiredThreads.splice(mExpiredThreads.end(), mThreads);
      }
      mListLock.unlock();

      // clean up expired threads
      cleanupExpiredThreads();

      // clear the idle list, no list locking necessary since no jobs
      // are running and no new ones can be assigned while inside of the
      // job lock -- this clear is necessary in case the idle threads
      // list was updating while joining threads in the cleanup code
      mIdleThreads.clear();
   }
   mJobLock.unlock();
}

void ThreadPool::setPoolSize(unsigned int size)
{
   // ensure lists are not modified while removing idle threads
   mListLock.lock();
   {
      // Note: threads are created lazily so if the thread pool size
      // here is greater than the number of threads currently in
      // the pool, those threads will be created as they are needed
      // hence, we do not need to adjust for increases in the pool size
      // only for decreases

      // remove threads as necessary
      if(mThreads.size() > size)
      {
         removeIdleThreads(mThreads.size() - size);
      }

      // set semaphore permits
      mThreadSemaphore.setMaxPermitCount(size);
   }
   mListLock.unlock();
}

inline unsigned int ThreadPool::getPoolSize()
{
   return mThreadSemaphore.getMaxPermitCount();
}

inline void ThreadPool::setThreadStackSize(size_t stackSize)
{
   mThreadStackSize = stackSize;
}

inline size_t ThreadPool::getThreadStackSize()
{
   return mThreadStackSize;
}

void ThreadPool::setThreadExpireTime(uint32_t expireTime)
{
   mThreadExpireTime = expireTime;

   // ensure lists are not modified while updating expire time
   mListLock.lock();
   {
      // update all existing threads
      for(ThreadList::iterator i = mThreads.begin(); i != mThreads.end(); ++i)
      {
         (*i)->setExpireTime(expireTime);
      }
   }
   mListLock.unlock();
}

inline uint32_t ThreadPool::getThreadExpireTime()
{
   return mThreadExpireTime;
}

inline unsigned int ThreadPool::getThreadCount()
{
   return mThreads.size();
}

unsigned int ThreadPool::getRunningThreadCount()
{
   unsigned int rval = 0;

   // ensure lists are not modified while getting difference
   mListLock.lock();
   {
      // subtract idle threads from total threads
      rval = mThreads.size() - mIdleThreads.size();
   }
   mListLock.unlock();

   return rval;
}

inline unsigned int ThreadPool::getIdleThreadCount()
{
   return mIdleThreads.size();
}
<commit_msg>Use tryAgain flag.<commit_after>/*
 * Copyright (c) 2007-2011 Digital Bazaar, Inc. All rights reserved.
 */
#include "monarch/rt/ThreadPool.h"

using namespace std;
using namespace monarch::rt;

ThreadPool::ThreadPool(unsigned int poolSize, size_t stackSize) :
   mThreadSemaphore(poolSize, true),
   mThreadStackSize(stackSize),
   // default thread expire time to 0 (no expiration)
   mThreadExpireTime(0)
{
}

ThreadPool::~ThreadPool()
{
   // terminate all threads
   terminateAllThreads();
}

PooledThread* ThreadPool::getIdleThread()
{
   PooledThread* rval = NULL;

   // lock lists for modification
   mListLock.lock();
   {
      while(rval == NULL && !mIdleThreads.empty())
      {
         rval = mIdleThreads.front();
         mIdleThreads.pop_front();

         // lock thread's job lock until it is assigned a job or marked expired
         //
         // Note: This must be done because the thread could come out of
         // its idle state while we are checking it. If, when we check it,
         // the thread is not expired, then we might accidentally assign it
         // a job, and in the thread's code it will be interrupted just after
         // we check it, resulting in the assigned job never being handled.
         rval->getJobLock()->lock();
         if(rval->isExpired() || rval->isInterrupted())
         {
            // unlock thread, collect thread for clean up
            rval->getJobLock()->unlock();
            mThreads.remove(rval);
            mExpiredThreads.push_front(rval);
            rval = NULL;
         }
      }

      if(rval == NULL)
      {
         // create new thread and add it to the thread list
         rval = new PooledThread(this, getThreadExpireTime());
         mThreads.push_back(rval);

         // lock thread's job lock to prevent it from going idle before
         // its job is assigned
         rval->getJobLock()->lock();
      }

      // remove extra threads if applicable
      if(!mIdleThreads.empty())
      {
         // get the number of extra threads
         int extraThreads =
            mThreads.size() - mThreadSemaphore.getMaxPermitCount();

         // remove extra idle threads
         if(extraThreads > 0)
         {
            removeIdleThreads((unsigned int)extraThreads);
         }
      }
   }
   mListLock.unlock();

   return rval;
}

void ThreadPool::removeIdleThreads(unsigned int count)
{
   // assume list lock is engaged
   for(ThreadList::iterator i = mIdleThreads.begin();
       count > 0 && i != mIdleThreads.end(); --count)
   {
      // interrupt and erase threads
      PooledThread* t = *i;
      t->interrupt();
      i = mIdleThreads.erase(i);
      mThreads.remove(t);
      mExpiredThreads.push_back(t);
   }
}

void ThreadPool::cleanupExpiredThreads()
{
   if(!mExpiredThreads.empty())
   {
      // move threads to cleanup list to avoid potential deadlock
      // issues involved when threads are completing
      mListLock.lock();
      ThreadList cleanup(mExpiredThreads);
      mExpiredThreads.clear();
      mListLock.unlock();

      // join and cleanup threads
      for(ThreadList::iterator i = cleanup.begin(); i != cleanup.end(); ++i)
      {
         (*i)->join();
         delete (*i);
      }
   }
}

bool ThreadPool::runJobOnIdleThread(Runnable& job, bool block)
{
   bool tryAgain = true;
   PooledThread* t = NULL;
   while(t == NULL && tryAgain)
   {
      // wait for other jobs to be assigned/terminated
      mJobLock.lock();
      {
         // get an idle thread
         t = getIdleThread();

         // set job
         t->setJob(&job);

         // unlock thread's job lock now that a job is assigned, so if it was
         // about to become idle or expire, it will pick up its new assignment
         t->getJobLock()->unlock();

         // if the thread hasn't started yet, start it
         if(!t->hasStarted())
         {
            if(!t->start(mThreadStackSize))
            {
               // cannot start a new thread due to limited system resources,
               // so remove it and try again if blocking
               mThreads.remove(t);
               delete t;
               t = NULL;
               tryAgain = block;
            }
         }
      }
      mJobLock.unlock();

      // clean up expired threads
      cleanupExpiredThreads();
   }

   return t != NULL;
}

bool ThreadPool::runJobOnIdleThread(RunnableRef& job, bool block)
{
   bool tryAgain = true;
   PooledThread* t = NULL;
   while(t == NULL && tryAgain)
   {
      // wait for other jobs to be assigned/terminated
      mJobLock.lock();
      {
         // get an idle thread
         t = getIdleThread();

         // set job
         t->setJob(job);

         // unlock thread's job lock now that a job is assigned, so if it was
         // about to become idle or expire, it will pick up its new assignment
         t->getJobLock()->unlock();

         // if the thread hasn't started yet, start it
         if(!t->hasStarted())
         {
            if(!t->start(mThreadStackSize))
            {
               // cannot start a new thread due to limited system resources,
               // so remove it and try again if blocking
               mThreads.remove(t);
               delete t;
               t = NULL;
               tryAgain = block;
            }
         }
      }
      mJobLock.unlock();

      // clean up expired threads
      cleanupExpiredThreads();
   }

   return t != NULL;
}

bool ThreadPool::tryRunJob(Runnable& job)
{
   bool rval;

   // try to acquire a thread permit
   if((rval = mThreadSemaphore.tryAcquire()))
   {
      // run the job on an idle thread
      if(!(rval = runJobOnIdleThread(job, false)))
      {
         // release thread permit, job could not be started
         mThreadSemaphore.release();
      }
   }

   return rval;
}

bool ThreadPool::tryRunJob(RunnableRef& job)
{
   bool rval;

   // try to acquire a thread permit
   if((rval = mThreadSemaphore.tryAcquire()))
   {
      // run the job on an idle thread
      if(!(rval = runJobOnIdleThread(job, false)))
      {
         // release thread permit, job could not be started
         mThreadSemaphore.release();
      }
   }

   return rval;
}

bool ThreadPool::runJob(Runnable& job)
{
   // acquire a thread permit
   bool rval = mThreadSemaphore.acquire();
   if(rval)
   {
      // run the job on an idle thread
      runJobOnIdleThread(job, true);
   }
   return rval;
}

bool ThreadPool::runJob(RunnableRef& job)
{
   // acquire a thread permit
   bool rval = mThreadSemaphore.acquire();
   if(rval)
   {
      // run the job on an idle thread
      runJobOnIdleThread(job, true);
   }
   return rval;
}

void ThreadPool::jobCompleted(PooledThread* t)
{
   // clear the thread's job, there is no need to engage the thread's
   // job lock here because this method is called from the thread itself,
   // and it therefore cannot be idle, waiting to be notified
   t->setJob(NULL);

   // lock lists for modification
   mListLock.lock();
   {
      // add the thread to the front of the idle list, so it is more
      // likely to get assigned a job immediately
      mIdleThreads.push_front(t);
   }
   mListLock.unlock();

   // release thread permit
   mThreadSemaphore.release();
}

void ThreadPool::interruptAllThreads()
{
   // prevent new jobs from being assigned during interruption
   // ensure lists are not modified during interruption
   mJobLock.lock();
   mListLock.lock();
   {
      // interrupt all threads
      for(ThreadList::iterator i = mThreads.begin(); i != mThreads.end(); ++i)
      {
         (*i)->interrupt();
      }
   }
   mJobLock.unlock();
   mListLock.unlock();
}

void ThreadPool::terminateAllThreads()
{
   // prevent new jobs from being assigned
   mJobLock.lock();
   {
      // prepare for list modification
      mListLock.lock();
      {
         // interrupt all the threads
         interruptAllThreads();

         // move all threads to the expired list
         mExpiredThreads.splice(mExpiredThreads.end(), mThreads);
      }
      mListLock.unlock();

      // clean up expired threads
      cleanupExpiredThreads();

      // clear the idle list, no list locking necessary since no jobs
      // are running and no new ones can be assigned while inside of the
      // job lock -- this clear is necessary in case the idle threads
      // list was updating while joining threads in the cleanup code
      mIdleThreads.clear();
   }
   mJobLock.unlock();
}

void ThreadPool::setPoolSize(unsigned int size)
{
   // ensure lists are not modified while removing idle threads
   mListLock.lock();
   {
      // Note: threads are created lazily so if the thread pool size
      // here is greater than the number of threads currently in
      // the pool, those threads will be created as they are needed
      // hence, we do not need to adjust for increases in the pool size
      // only for decreases

      // remove threads as necessary
      if(mThreads.size() > size)
      {
         removeIdleThreads(mThreads.size() - size);
      }

      // set semaphore permits
      mThreadSemaphore.setMaxPermitCount(size);
   }
   mListLock.unlock();
}

inline unsigned int ThreadPool::getPoolSize()
{
   return mThreadSemaphore.getMaxPermitCount();
}

inline void ThreadPool::setThreadStackSize(size_t stackSize)
{
   mThreadStackSize = stackSize;
}

inline size_t ThreadPool::getThreadStackSize()
{
   return mThreadStackSize;
}

void ThreadPool::setThreadExpireTime(uint32_t expireTime)
{
   mThreadExpireTime = expireTime;

   // ensure lists are not modified while updating expire time
   mListLock.lock();
   {
      // update all existing threads
      for(ThreadList::iterator i = mThreads.begin(); i != mThreads.end(); ++i)
      {
         (*i)->setExpireTime(expireTime);
      }
   }
   mListLock.unlock();
}

inline uint32_t ThreadPool::getThreadExpireTime()
{
   return mThreadExpireTime;
}

inline unsigned int ThreadPool::getThreadCount()
{
   return mThreads.size();
}

unsigned int ThreadPool::getRunningThreadCount()
{
   unsigned int rval = 0;

   // ensure lists are not modified while getting difference
   mListLock.lock();
   {
      // subtract idle threads from total threads
      rval = mThreads.size() - mIdleThreads.size();
   }
   mListLock.unlock();

   return rval;
}

inline unsigned int ThreadPool::getIdleThreadCount()
{
   return mIdleThreads.size();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2009 Digital Bazaar, Inc. All rights reserved.
 */
#include "monarch/util/TimeZone.h"
#include "monarch/rt/System.h"

#include <cstring>

using namespace std;
using namespace monarch::rt;
using namespace monarch::util;

TimeZone::TimeZone(unsigned int minutesWest)
{
   mMinutesWest = minutesWest;
}

TimeZone::~TimeZone()
{
}

inline unsigned int TimeZone::getMinutesWest()
{
   return mMinutesWest;
}

TimeZone TimeZone::getTimeZone(const char* tz)
{
   TimeZone rval;

   if(strcmp(tz, "GMT") == 0 || strcmp(tz, "UTC") == 0)
   {
      rval.mMinutesWest = 0;
   }
   else if(strcmp(tz, "EDT") == 0)
   {
      // 4 hours west
      rval.mMinutesWest = 240;
   }
   else if(strcmp(tz, "EST") == 0)
   {
      // 5 hours west
      rval.mMinutesWest = 300;
   }
   else if(strcmp(tz, "PDT") == 0)
   {
      // 7 hours west
      rval.mMinutesWest = 420;
   }
   else if(strcmp(tz, "PST") == 0)
   {
      // 8 hours west
      rval.mMinutesWest = 480;
   }
   else
   {
      rval.mMinutesWest = gGetTimeZoneMinutesWest();
   }

   return rval;
}
<commit_msg>Changed timezone string to case-insensitive comparison.<commit_after>/*
 * Copyright (c) 2007-2009 Digital Bazaar, Inc. All rights reserved.
 */
#include "monarch/util/TimeZone.h"
#include "monarch/rt/System.h"

#include <cstring>

using namespace std;
using namespace monarch::rt;
using namespace monarch::util;

TimeZone::TimeZone(unsigned int minutesWest)
{
   mMinutesWest = minutesWest;
}

TimeZone::~TimeZone()
{
}

inline unsigned int TimeZone::getMinutesWest()
{
   return mMinutesWest;
}

TimeZone TimeZone::getTimeZone(const char* tz)
{
   TimeZone rval;

   if(strcasecmp(tz, "GMT") == 0 || strcasecmp(tz, "UTC") == 0)
   {
      rval.mMinutesWest = 0;
   }
   else if(strcasecmp(tz, "EDT") == 0)
   {
      // 4 hours west
      rval.mMinutesWest = 240;
   }
   else if(strcasecmp(tz, "EST") == 0)
   {
      // 5 hours west
      rval.mMinutesWest = 300;
   }
   else if(strcasecmp(tz, "PDT") == 0)
   {
      // 7 hours west
      rval.mMinutesWest = 420;
   }
   else if(strcasecmp(tz, "PST") == 0)
   {
      // 8 hours west
      rval.mMinutesWest = 480;
   }
   else
   {
      rval.mMinutesWest = gGetTimeZoneMinutesWest();
   }

   return rval;
}
<|endoftext|>