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

#include <stdio.h>

#include "subtree.hxx"
#ifndef CONFIGMGR_CHANGE_HXX
#include "change.hxx"
#endif
#ifndef CONFIGMGR_TREECHANGELIST_HXX
#include "treechangelist.hxx"
#endif

#ifndef CONFIGMGR_TREEPROVIDER_HXX
#include "treeprovider.hxx"
#endif
#ifndef _CONFIGMGR_TREEACTIONS_HXX_
#include "treeactions.hxx"
#endif

#ifndef _RTL_STRING_HXX_
#include <rtl/string.hxx>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef INCLUDED_DEQUE
#include <deque>
#define INCLUDED_DEQUE
#endif
#ifndef INCLUDED_VECTOR
#include <vector>
#define INCLUDED_VECTOR
#endif
#ifndef INCLUDED_IOSTREAM
#include <iostream>
#define INCLUDED_IOSTREAM
#endif
#ifndef INCLUDED_EXCEPTION
#include <exception>
#define INCLUDED_EXCEPTION
#endif
#ifndef INCLUDED_SET
#include <set>
#define INCLUDED_SET
#endif

using namespace std;
using namespace rtl;
using namespace com::sun::star::uno;

namespace configmgr
{

// ------------------------ ChildListSet implementations ------------------------
    ChildListSet::ChildListSet(ChildListSet const& aSet)
    {
        for(ChildList::iterator it = aSet.GetSet().begin();
            it != aSet.GetSet().end();
            ++it)
            m_aChildList.insert(m_aChildList.end(), (*it)->clone());
    }
    ChildListSet::~ChildListSet()
    {
        for(ChildList::iterator it = m_aChildList.begin();
            it != m_aChildList.end();
            ++it)
            delete *it;
    }

// ---------------------------- Node implementation ----------------------------

    INode::INode(configuration::Attributes _aAttr):m_aAttributes(_aAttr){}
    INode::INode(OUString const& aName, configuration::Attributes _aAttr)
          :m_aName(aName)
          ,m_aAttributes(_aAttr){}
    // CopyCTor will be create automatically

    INode::~INode() {}

    ISubtree*         INode::asISubtree(){return NULL;}
    ISubtree const*   INode::asISubtree() const {return NULL;}
    ValueNode*       INode::asValueNode() {return NULL;}
    ValueNode const* INode::asValueNode() const {return NULL;}

      void INode::forceWritableToFinalized()
      {
        if (!m_aAttributes.bWritable)
        {
            m_aAttributes.bFinalized = true;
            m_aAttributes.bWritable = false;
        }
    }

// ------------------------- SearchNode implementation -------------------------
    SearchNode::SearchNode():INode(configuration::Attributes()){}
    SearchNode::SearchNode(OUString const& aName)
        :INode(aName, configuration::Attributes()){}

    INode* SearchNode::clone() const {return new SearchNode(*this);}

    SearchNode::~SearchNode(){}

    //==========================================================================
    //= OPropagateLevels
    //==========================================================================
    /** fills a subtree with the correct level informations
    */
    struct OPropagateLevels : public NodeModification
    {
    protected:
        sal_Int32   nChildLevel;
    public:
        OPropagateLevels(sal_Int32 _nParentLevel)
        {
            nChildLevel = (ITreeProvider::ALL_LEVELS == _nParentLevel) ? ITreeProvider::ALL_LEVELS : _nParentLevel - 1;
        }
        virtual void handle(ValueNode&) { /* not interested in value nodes */ }
        virtual void handle(ISubtree& _rSubtree)
        {
            if ((ITreeProvider::ALL_LEVELS == nChildLevel) || nChildLevel > _rSubtree.getLevel())
                _rSubtree.setLevel(nChildLevel);
        }
    };

// -------------------------- ISubtree implementation --------------------------
    ISubtree* ISubtree::asISubtree() {return this;}
    ISubtree const* ISubtree::asISubtree() const {return this;}

    //--------------------------------------------------------------------------
    void ISubtree::setLevel(sal_Int16 _nLevel)
    {
        m_nLevel = _nLevel;
        if (0 == _nLevel)
            // nothing more to do, this means "nothing known about any children"
            return;

        // forward the level number to any child subtrees we have
        OPropagateLevels aDeeperInto(_nLevel);
        aDeeperInto.applyToChildren(*this);
    }

// --------------------------- Subtree implementation ---------------------------
    INode* Subtree::clone() const {return new Subtree(*this);}

    INode* Subtree::doGetChild(OUString const& aName) const
    {
        SearchNode searchObj(aName);

#ifdef DEBUG
        for (ChildList::iterator it2 = m_aChildren.GetSet().begin();
            it2 != m_aChildren.GetSet().end();
            ++it2)
        {
            INode* pINode = *it2;
            OUString aName2 = pINode->getName();
            volatile int dummy = 0;
        }
#endif

        ChildList::iterator it = m_aChildren.GetSet().find(&searchObj);
        if (it == m_aChildren.GetSet().end())
            return NULL;
        else
            return *it;
    }

    INode* Subtree::addChild(std::auto_ptr<INode> aNode)    // takes ownership
    {
        OUString aName = aNode->getName();
        std::pair<ChildList::iterator, bool> aInserted =
            m_aChildren.GetSet().insert(aNode.get());
        if (aInserted.second)
            aNode.release();
        return *aInserted.first;
    }

    ::std::auto_ptr<INode> Subtree::removeChild(OUString const& aName)
    {
        SearchNode searchObj(aName);
        ChildList::const_iterator it = m_aChildren.GetSet().find(&searchObj);

        ::std::auto_ptr<INode> aReturn;
        if (m_aChildren.GetSet().end() != it)
        {
            aReturn = ::std::auto_ptr<INode>(*it);
            m_aChildren.GetSet().erase(it);
        }
        return aReturn;
    }

    //==========================================================================
    //= OBuildChangeTree - historic
    //==========================================================================
    /** generates a change tree by comparing two trees
    */
/*  struct OBuildChangeTree : public NodeModification
    {
    protected:
        SubtreeChange&  m_rChangeList;
        INode*          m_pCacheNode;

    public:
        OBuildChangeTree(SubtreeChange& rList, INode* pNode)
            :m_rChangeList(rList)
            ,m_pCacheNode(pNode)
        {
        }

        virtual void handle(ValueNode& _nNode)
        {
            OUString aNodeName = _nNode.getName();
            ISubtree* pTree = m_pCacheNode->asISubtree();
            OSL_ENSURE(pTree, "OBuildChangeTree::handle : node must be a inner node!");
            if (pTree)
            {
                INode* pChild = pTree->getChild(aNodeName);
                ValueNode* pValueNode = pChild ? pChild->asValueNode() : NULL;
                OSL_ENSURE(pValueNode, "OBuildChangeTree::handle : node must be a value node!");

                // if the values differ add a new change
                if (pValueNode && _nNode.getValue() != pValueNode->getValue())
                {
                    ValueChange* pChange = new ValueChange(_nNode.getValue(), *pValueNode);
                    m_rChangeList.addChange(::std::auto_ptr<Change>(pChange));
                }
            }
        }

        virtual void handle(ISubtree& _rSubtree)
        {
            OUString aNodeName = _rSubtree.getName();
            ISubtree* pTree = m_pCacheNode->asISubtree();
            OSL_ENSURE(pTree, "OBuildChangeTree::handle : node must be a inner node!");
            if (pTree)
            {
                INode* pChild = pTree->getChild(aNodeName);
                // node not in cache, so ignore it
                // later, when we get additions and removements within on transaction, then we have to care about
                if (pChild)
                {
                    ISubtree* pSubTree = pChild->asISubtree();
                    OSL_ENSURE(pSubTree, "OBuildChangeTree::handle : node must be a inner node!");
                    // generate a new change

                    SubtreeChange* pChange = new SubtreeChange(_rSubtree);
                    OBuildChangeTree aNextLevel(*pChange, pSubTree);
                    aNextLevel.applyToChildren(_rSubtree);

                    // now count if there are any changes
                    OChangeCounter aCounter;
                    pChange->dispatch(aCounter);

                    if (aCounter.nCount != 0)
                        m_rChangeList.addChange(::std::auto_ptr<Change>(pChange));
                    else
                        delete pChange;
                }
            }
        }
    };

*/
    void Subtree::forEachChild(NodeAction& anAction) const {
        for(ChildList::const_iterator it = m_aChildren.GetSet().begin();
            it != m_aChildren.GetSet().end();
            ++it)
            (**it).dispatch(anAction);
    }

    void Subtree::forEachChild(NodeModification& anAction) {
        for(ChildList::iterator it = m_aChildren.GetSet().begin();
            it != m_aChildren.GetSet().end();
            ++it)
            (**it).dispatch(anAction);
      }

//  // -------------------------- ValueNode implementation --------------------------
      void ValueNode::check_init()  // may throw in the future
      {
          m_aValuePair.check_init();
      }

      void ValueNode::init()
      {
          m_aValuePair.init();
    }

    void ValueNode::setValue(Any const& _aValue)
    {
        m_aValuePair.setFirst(_aValue);
    }

    void ValueNode::changeDefault(Any const& _aValue)
    {
        m_aValuePair.setSecond(_aValue);
    }

    void ValueNode::setDefault()
    {
        // PRE: ????
        // POST: isDefault() == true
        // OSL_ENSURE(false, "ValueNode::setDefault(): this isn't really defined yet.");
        // m_aValue = Any();
        // m_pFirst = NULL;
    }

    INode* ValueNode::clone() const
    {
        return new ValueNode(*this);
    }

    ValueNode* ValueNode::asValueNode() {return this;}
    ValueNode const* ValueNode::asValueNode() const {return this;}

} // namespace configmgr

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

#include <stdio.h>

#include "subtree.hxx"
#ifndef CONFIGMGR_CHANGE_HXX
#include "change.hxx"
#endif
#ifndef CONFIGMGR_TREECHANGELIST_HXX
#include "treechangelist.hxx"
#endif

#ifndef CONFIGMGR_TREEPROVIDER_HXX
#include "treeprovider.hxx"
#endif
#ifndef _CONFIGMGR_TREEACTIONS_HXX_
#include "treeactions.hxx"
#endif

#ifndef _RTL_STRING_HXX_
#include <rtl/string.hxx>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef INCLUDED_DEQUE
#include <deque>
#define INCLUDED_DEQUE
#endif
#ifndef INCLUDED_VECTOR
#include <vector>
#define INCLUDED_VECTOR
#endif
#ifndef INCLUDED_IOSTREAM
#include <iostream>
#define INCLUDED_IOSTREAM
#endif
#ifndef INCLUDED_EXCEPTION
#include <exception>
#define INCLUDED_EXCEPTION
#endif
#ifndef INCLUDED_SET
#include <set>
#define INCLUDED_SET
#endif

using namespace std;
using namespace rtl;
using namespace com::sun::star::uno;

namespace configmgr
{

// ------------------------ ChildListSet implementations ------------------------
    ChildListSet::ChildListSet(ChildListSet const& aSet)
    {
        for(ChildList::iterator it = aSet.GetSet().begin();
            it != aSet.GetSet().end();
            ++it)
            m_aChildList.insert(m_aChildList.end(), (*it)->clone());
    }
    ChildListSet::~ChildListSet()
    {
        for(ChildList::iterator it = m_aChildList.begin();
            it != m_aChildList.end();
            ++it)
            delete *it;
    }

// ---------------------------- Node implementation ----------------------------

    INode::INode(configuration::Attributes _aAttr):m_aAttributes(_aAttr){}
    INode::INode(OUString const& aName, configuration::Attributes _aAttr)
          :m_aName(aName)
          ,m_aAttributes(_aAttr){}
    // CopyCTor will be create automatically

    INode::~INode() {}

    ISubtree*         INode::asISubtree(){return NULL;}
    ISubtree const*   INode::asISubtree() const {return NULL;}
    ValueNode*       INode::asValueNode() {return NULL;}
    ValueNode const* INode::asValueNode() const {return NULL;}

      void INode::forceWritableToFinalized()
      {
        if (!m_aAttributes.bWritable)
        {
            m_aAttributes.bFinalized = true;
            m_aAttributes.bWritable  = true;
        }
    }

// ------------------------- SearchNode implementation -------------------------
    SearchNode::SearchNode():INode(configuration::Attributes()){}
    SearchNode::SearchNode(OUString const& aName)
        :INode(aName, configuration::Attributes()){}

    INode* SearchNode::clone() const {return new SearchNode(*this);}

    SearchNode::~SearchNode(){}

    //==========================================================================
    //= OPropagateLevels
    //==========================================================================
    /** fills a subtree with the correct level informations
    */
    struct OPropagateLevels : public NodeModification
    {
    protected:
        sal_Int32   nChildLevel;
    public:
        OPropagateLevels(sal_Int32 _nParentLevel)
        {
            nChildLevel = (ITreeProvider::ALL_LEVELS == _nParentLevel) ? ITreeProvider::ALL_LEVELS : _nParentLevel - 1;
        }
        virtual void handle(ValueNode&) { /* not interested in value nodes */ }
        virtual void handle(ISubtree& _rSubtree)
        {
            if ((ITreeProvider::ALL_LEVELS == nChildLevel) || nChildLevel > _rSubtree.getLevel())
                _rSubtree.setLevel(nChildLevel);
        }
    };

// -------------------------- ISubtree implementation --------------------------
    ISubtree* ISubtree::asISubtree() {return this;}
    ISubtree const* ISubtree::asISubtree() const {return this;}

    //--------------------------------------------------------------------------
    void ISubtree::setLevel(sal_Int16 _nLevel)
    {
        m_nLevel = _nLevel;
        if (0 == _nLevel)
            // nothing more to do, this means "nothing known about any children"
            return;

        // forward the level number to any child subtrees we have
        OPropagateLevels aDeeperInto(_nLevel);
        aDeeperInto.applyToChildren(*this);
    }

// --------------------------- Subtree implementation ---------------------------
    INode* Subtree::clone() const {return new Subtree(*this);}

    INode* Subtree::doGetChild(OUString const& aName) const
    {
        SearchNode searchObj(aName);

#ifdef DEBUG
        for (ChildList::iterator it2 = m_aChildren.GetSet().begin();
            it2 != m_aChildren.GetSet().end();
            ++it2)
        {
            INode* pINode = *it2;
            OUString aName2 = pINode->getName();
            volatile int dummy = 0;
        }
#endif

        ChildList::iterator it = m_aChildren.GetSet().find(&searchObj);
        if (it == m_aChildren.GetSet().end())
            return NULL;
        else
            return *it;
    }

    INode* Subtree::addChild(std::auto_ptr<INode> aNode)    // takes ownership
    {
        OUString aName = aNode->getName();
        std::pair<ChildList::iterator, bool> aInserted =
            m_aChildren.GetSet().insert(aNode.get());
        if (aInserted.second)
            aNode.release();
        return *aInserted.first;
    }

    ::std::auto_ptr<INode> Subtree::removeChild(OUString const& aName)
    {
        SearchNode searchObj(aName);
        ChildList::const_iterator it = m_aChildren.GetSet().find(&searchObj);

        ::std::auto_ptr<INode> aReturn;
        if (m_aChildren.GetSet().end() != it)
        {
            aReturn = ::std::auto_ptr<INode>(*it);
            m_aChildren.GetSet().erase(it);
        }
        return aReturn;
    }

    //==========================================================================
    //= OBuildChangeTree - historic
    //==========================================================================
    /** generates a change tree by comparing two trees
    */
/*  struct OBuildChangeTree : public NodeModification
    {
    protected:
        SubtreeChange&  m_rChangeList;
        INode*          m_pCacheNode;

    public:
        OBuildChangeTree(SubtreeChange& rList, INode* pNode)
            :m_rChangeList(rList)
            ,m_pCacheNode(pNode)
        {
        }

        virtual void handle(ValueNode& _nNode)
        {
            OUString aNodeName = _nNode.getName();
            ISubtree* pTree = m_pCacheNode->asISubtree();
            OSL_ENSURE(pTree, "OBuildChangeTree::handle : node must be a inner node!");
            if (pTree)
            {
                INode* pChild = pTree->getChild(aNodeName);
                ValueNode* pValueNode = pChild ? pChild->asValueNode() : NULL;
                OSL_ENSURE(pValueNode, "OBuildChangeTree::handle : node must be a value node!");

                // if the values differ add a new change
                if (pValueNode && _nNode.getValue() != pValueNode->getValue())
                {
                    ValueChange* pChange = new ValueChange(_nNode.getValue(), *pValueNode);
                    m_rChangeList.addChange(::std::auto_ptr<Change>(pChange));
                }
            }
        }

        virtual void handle(ISubtree& _rSubtree)
        {
            OUString aNodeName = _rSubtree.getName();
            ISubtree* pTree = m_pCacheNode->asISubtree();
            OSL_ENSURE(pTree, "OBuildChangeTree::handle : node must be a inner node!");
            if (pTree)
            {
                INode* pChild = pTree->getChild(aNodeName);
                // node not in cache, so ignore it
                // later, when we get additions and removements within on transaction, then we have to care about
                if (pChild)
                {
                    ISubtree* pSubTree = pChild->asISubtree();
                    OSL_ENSURE(pSubTree, "OBuildChangeTree::handle : node must be a inner node!");
                    // generate a new change

                    SubtreeChange* pChange = new SubtreeChange(_rSubtree);
                    OBuildChangeTree aNextLevel(*pChange, pSubTree);
                    aNextLevel.applyToChildren(_rSubtree);

                    // now count if there are any changes
                    OChangeCounter aCounter;
                    pChange->dispatch(aCounter);

                    if (aCounter.nCount != 0)
                        m_rChangeList.addChange(::std::auto_ptr<Change>(pChange));
                    else
                        delete pChange;
                }
            }
        }
    };

*/
    void Subtree::forEachChild(NodeAction& anAction) const {
        for(ChildList::const_iterator it = m_aChildren.GetSet().begin();
            it != m_aChildren.GetSet().end();
            ++it)
            (**it).dispatch(anAction);
    }

    void Subtree::forEachChild(NodeModification& anAction) {
        for(ChildList::iterator it = m_aChildren.GetSet().begin();
            it != m_aChildren.GetSet().end();
            ++it)
            (**it).dispatch(anAction);
      }

//  // -------------------------- ValueNode implementation --------------------------
      void ValueNode::check_init()  // may throw in the future
      {
          m_aValuePair.check_init();
      }

      void ValueNode::init()
      {
          m_aValuePair.init();
    }

    void ValueNode::setValue(Any const& _aValue)
    {
        m_aValuePair.setFirst(_aValue);
    }

    void ValueNode::changeDefault(Any const& _aValue)
    {
        m_aValuePair.setSecond(_aValue);
    }

    void ValueNode::setDefault()
    {
        // PRE: ????
        // POST: isDefault() == true
        // OSL_ENSURE(false, "ValueNode::setDefault(): this isn't really defined yet.");
        // m_aValue = Any();
        // m_pFirst = NULL;
    }

    INode* ValueNode::clone() const
    {
        return new ValueNode(*this);
    }

    ValueNode* ValueNode::asValueNode() {return this;}
    ValueNode const* ValueNode::asValueNode() const {return this;}

} // namespace configmgr

<|endoftext|>


<commit_before>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "connectionfactory.h"

#ifdef HAVE_GLIB_DBUS
#include "glibdbusimserverproxy.h"
#include "minputcontextglibdbusconnection.h"
#else
#include "dbusserverconnection.h"
#include "dbusinputcontextconnection.h"
#endif

namespace Maliit {
namespace DBus {

MImServerConnection *createServerConnectionWithDynamicAddress()
{
    const QSharedPointer<Maliit::InputContext::DBus::Address> address(new Maliit::InputContext::DBus::DynamicAddress);
#ifdef HAVE_GLIB_DBUS
    return new GlibDBusIMServerProxy(address);
#else
    return new DBusServerConnection(address);
#endif
}

MImServerConnection *createServerConnectionWithFixedAddress(const QString &fixedAddress)
{
    const QSharedPointer<Maliit::InputContext::DBus::Address> address(new Maliit::InputContext::DBus::FixedAddress(fixedAddress));
#ifdef HAVE_GLIB_DBUS
    return new GlibDBusIMServerProxy(address);
#else
    return new DBusServerConnection(address);
#endif
}

MInputContextConnection *createInputContextConnectionWithDynamicAddress()
{
#ifdef HAVE_GLIB_DBUS
    std::tr1::shared_ptr<Maliit::Server::DBus::Address> address(new Maliit::Server::DBus::DynamicAddress);
    return new MInputContextGlibDBusConnection(address, false);
#else
    QSharedPointer<Maliit::Server::DBus::Address> address(new Maliit::Server::DBus::DynamicAddress);
    return new DBusInputContextConnection(address);
#endif
}

MInputContextConnection *createInputContextConnectionWithFixedAddress(const QString &fixedAddress, bool allowAnonymous)
{
#ifdef HAVE_GLIB_DBUS
    std::tr1::shared_ptr<Maliit::Server::DBus::Address> address(new Maliit::Server::DBus::FixedAddress(fixedAddress));
    return new MInputContextGlibDBusConnection(address, allowAnonymous);
#else
    QSharedPointer<Maliit::Server::DBus::Address> address(new Maliit::Server::DBus::FixedAddress(fixedAddress));
    return new DBusInputContextConnection(address);
#endif
}

} // namespace DBus
} // namespace Maliit
<commit_msg>Fix unused parameter warning<commit_after>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "connectionfactory.h"

#ifdef HAVE_GLIB_DBUS
#include "glibdbusimserverproxy.h"
#include "minputcontextglibdbusconnection.h"
#else
#include "dbusserverconnection.h"
#include "dbusinputcontextconnection.h"
#endif

namespace Maliit {
namespace DBus {

MImServerConnection *createServerConnectionWithDynamicAddress()
{
    const QSharedPointer<Maliit::InputContext::DBus::Address> address(new Maliit::InputContext::DBus::DynamicAddress);
#ifdef HAVE_GLIB_DBUS
    return new GlibDBusIMServerProxy(address);
#else
    return new DBusServerConnection(address);
#endif
}

MImServerConnection *createServerConnectionWithFixedAddress(const QString &fixedAddress)
{
    const QSharedPointer<Maliit::InputContext::DBus::Address> address(new Maliit::InputContext::DBus::FixedAddress(fixedAddress));
#ifdef HAVE_GLIB_DBUS
    return new GlibDBusIMServerProxy(address);
#else
    return new DBusServerConnection(address);
#endif
}

MInputContextConnection *createInputContextConnectionWithDynamicAddress()
{
#ifdef HAVE_GLIB_DBUS
    std::tr1::shared_ptr<Maliit::Server::DBus::Address> address(new Maliit::Server::DBus::DynamicAddress);
    return new MInputContextGlibDBusConnection(address, false);
#else
    QSharedPointer<Maliit::Server::DBus::Address> address(new Maliit::Server::DBus::DynamicAddress);
    return new DBusInputContextConnection(address);
#endif
}

MInputContextConnection *createInputContextConnectionWithFixedAddress(const QString &fixedAddress, bool allowAnonymous)
{
#ifdef HAVE_GLIB_DBUS
    std::tr1::shared_ptr<Maliit::Server::DBus::Address> address(new Maliit::Server::DBus::FixedAddress(fixedAddress));
    return new MInputContextGlibDBusConnection(address, allowAnonymous);
#else
    Q_UNUSED(allowAnonymous);
    QSharedPointer<Maliit::Server::DBus::Address> address(new Maliit::Server::DBus::FixedAddress(fixedAddress));
    return new DBusInputContextConnection(address);
#endif
}

} // namespace DBus
} // namespace Maliit
<|endoftext|>


<commit_before>/*
 * Launch WAS child processes.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#ifndef BENG_PROXY_WAS_LAUNCH_HXX
#define BENG_PROXY_WAS_LAUNCH_HXX

#include "glibfwd.hxx"

#include <sys/types.h>

struct ChildOptions;
template<typename T> struct ConstBuffer;

struct WasProcess {
    pid_t pid;
    int control_fd, input_fd, output_fd;

    void Close();
};

bool
was_launch(WasProcess *process,
           const char *executable_path,
           ConstBuffer<const char *> args,
           ConstBuffer<const char *> env,
           const ChildOptions &options,
           GError **error_r);

#endif
<commit_msg>was/launch: auto-initialize attributes<commit_after>/*
 * Launch WAS child processes.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#ifndef BENG_PROXY_WAS_LAUNCH_HXX
#define BENG_PROXY_WAS_LAUNCH_HXX

#include "glibfwd.hxx"

#include <sys/types.h>

struct ChildOptions;
template<typename T> struct ConstBuffer;

struct WasProcess {
    pid_t pid = -1;
    int control_fd = -1, input_fd = -1, output_fd = -1;

    void Close();
};

bool
was_launch(WasProcess *process,
           const char *executable_path,
           ConstBuffer<const char *> args,
           ConstBuffer<const char *> env,
           const ChildOptions &options,
           GError **error_r);

#endif
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <gtest/gtest.h>
#include <arrayfire.h>
#include <af/dim4.hpp>
#include <af/traits.hpp>
#include <vector>
#include <iostream>
#include <string>
#include <testHelpers.hpp>

using std::vector;
using std::string;
using std::cout;
using std::endl;
using af::cfloat;
using af::cdouble;

template<typename T>
class Resize : public ::testing::Test
{
    public:
        virtual void SetUp() {
            subMat0.push_back(af_make_seq(0, 4, 1));
            subMat0.push_back(af_make_seq(2, 6, 1));
            subMat0.push_back(af_make_seq(0, 2, 1));
        }
        vector<af_seq> subMat0;
};

template<typename T>
class ResizeI : public ::testing::Test
{
    public:
        virtual void SetUp() {
            subMat0.push_back(af_make_seq(0, 4, 1));
            subMat0.push_back(af_make_seq(2, 6, 1));
            subMat0.push_back(af_make_seq(0, 2, 1));

            subMat1.push_back(af_make_seq(0, 5, 1));
            subMat1.push_back(af_make_seq(0, 5, 1));
            subMat1.push_back(af_make_seq(0, 2, 1));
        }
        vector<af_seq> subMat0;
        vector<af_seq> subMat1;
};

// create a list of types to be tested
typedef ::testing::Types<float, double> TestTypesF;
typedef ::testing::Types<int, unsigned, unsigned char> TestTypesI;

// register the type list
TYPED_TEST_CASE(Resize, TestTypesF);
TYPED_TEST_CASE(ResizeI, TestTypesI);

template<typename T>
void resizeTest(string pTestFile, const unsigned resultIdx, const dim_type odim0, const dim_type odim1, const af_interp_type method, bool isSubRef = false, const vector<af_seq> * seqv = NULL)
{
    if (noDoubleTests<T>()) return;

    vector<af::dim4> numDims;
    vector<vector<T> >   in;
    vector<vector<T> >   tests;
    readTests<T, T, float>(pTestFile,numDims,in,tests);

    af::dim4 dims = numDims[0];

    af_array inArray = 0;
    af_array outArray = 0;
    af_array tempArray = 0;
    if (isSubRef) {

        ASSERT_EQ(AF_SUCCESS, af_create_array(&tempArray, &(in[0].front()), dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<T>::af_type));

        ASSERT_EQ(AF_SUCCESS, af_index(&inArray, tempArray, seqv->size(), &seqv->front()));
    } else {
        ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &(in[0].front()), dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<T>::af_type));
    }

    ASSERT_EQ(AF_SUCCESS, af_resize(&outArray, inArray, odim0, odim1, method));

    // Get result
    af::dim4 odims(odim0, odim1, dims[2], dims[3]);
    T* outData = new T[odims.elements()];
    ASSERT_EQ(AF_SUCCESS, af_get_data_ptr((void*)outData, outArray));

    // Compare result
    size_t nElems = tests[resultIdx].size();
    for (size_t elIter = 0; elIter < nElems; ++elIter) {
        ASSERT_NEAR(tests[resultIdx][elIter], outData[elIter], 0.0001) << "at: " << elIter << std::endl;
    }

    // Delete
    delete[] outData;

    if(inArray   != 0) af_destroy_array(inArray);
    if(outArray  != 0) af_destroy_array(outArray);
    if(tempArray != 0) af_destroy_array(tempArray);
}

TYPED_TEST(Resize, Resize3CSquareUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 0, 16, 16, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize3CSquareUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 1, 16, 16, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize, Resize3CSquareDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 2, 4, 4, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize3CSquareDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 3, 4, 4, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize, Resize3CSquareUpNearestSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 4, 10, 10, AF_INTERP_NEAREST,
                          true, &(this->subMat0));
}

TYPED_TEST(Resize, Resize3CSquareUpLinearSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 5, 10, 10, AF_INTERP_BILINEAR,
                          true, &(this->subMat0));
}

TYPED_TEST(Resize, Resize3CSquareDownNearestSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 6, 3, 3, AF_INTERP_NEAREST,
                          true, &(this->subMat0));
}

TYPED_TEST(Resize, Resize3CSquareDownLinearSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 7, 3, 3, AF_INTERP_BILINEAR,
                          true, &(this->subMat0));
}

TYPED_TEST(Resize, Resize1CRectangleUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/rectangle.test"), 0, 12, 16, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize1CRectangleUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/rectangle.test"), 1, 12, 16, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize, Resize1CRectangleDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/rectangle.test"), 2, 6, 2, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize1CRectangleDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/rectangle.test"), 3, 6, 2, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize3CSquareUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 0, 16, 16, AF_INTERP_NEAREST);
}

TYPED_TEST(ResizeI, Resize3CSquareUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 1, 16, 16, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize3CSquareDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 2, 4, 4, AF_INTERP_NEAREST);
}

TYPED_TEST(ResizeI, Resize3CSquareDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 3, 4, 4, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize3CSquareUpNearestSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 4, 10, 10, AF_INTERP_NEAREST,
                          true, &(this->subMat0));
}

TYPED_TEST(ResizeI, Resize3CSquareUpLinearSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 5, 10, 10, AF_INTERP_BILINEAR,
                          true, &(this->subMat0));
}

TYPED_TEST(ResizeI, Resize3CSquareDownNearestSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 6, 3, 3, AF_INTERP_NEAREST,
                          true, &(this->subMat0));
}

TYPED_TEST(ResizeI, Resize3CSquareDownLinearSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 8, 3, 3, AF_INTERP_BILINEAR,
                          true, &(this->subMat1));
}

TYPED_TEST(Resize, Resize1CLargeUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 0, 256, 256, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize1CLargeUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 1, 256, 256, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize, Resize1CLargeDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 2, 32, 32, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize1CLargeDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 3, 32, 32, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize1CLargeUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 0, 256, 256, AF_INTERP_NEAREST);
}

TYPED_TEST(ResizeI, Resize1CLargeUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 1, 256, 256, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize1CLargeDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 2, 32, 32, AF_INTERP_NEAREST);
}

TYPED_TEST(ResizeI, Resize1CLargeDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 3, 32, 32, AF_INTERP_BILINEAR);
}

template<typename T>
void resizeArgsTest(af_err err, string pTestFile, const af::dim4 odims, const af_interp_type method)
{
    if (noDoubleTests<T>()) return;

    vector<af::dim4> numDims;
    vector<vector<T> >   in;
    vector<vector<T> >   tests;
    readTests<T, T, float>(pTestFile,numDims,in,tests);

    af::dim4 dims = numDims[0];

    af_array inArray = 0;
    af_array outArray = 0;
    ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &(in[0].front()), dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<T>::af_type));

    ASSERT_EQ(err, af_resize(&outArray, inArray, odims[0], odims[1], method));

    if(inArray != 0) af_destroy_array(inArray);
    if(outArray != 0) af_destroy_array(outArray);
}

TYPED_TEST(Resize,InvalidArgsDims0)
{
    af::dim4 dims(0, 5, 2, 1);
    resizeArgsTest<TypeParam>(AF_ERR_SIZE, string(TEST_DIR"/resize/square.test"), dims, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize,InvalidArgsMethod)
{
    af::dim4 dims(10, 10, 1, 1);
    resizeArgsTest<TypeParam>(AF_ERR_ARG, string(TEST_DIR"/resize/square.test"), dims, AF_INTERP_CUBIC);
}

///////////////////////////////// CPP ////////////////////////////////////
//
TEST(Resize, CPP)
{
    if (noDoubleTests<float>()) return;

    vector<af::dim4> numDims;
    vector<vector<float> >   in;
    vector<vector<float> >   tests;
    readTests<float, float, float>(string(TEST_DIR"/resize/square.test"),numDims,in,tests);

    af::dim4 dims = numDims[0];
    af::array input(dims, &(in[0].front()));
    af::array output = af::resize(input, 16, 16);

    // Get result
    af::dim4 odims(16, 16, dims[2], dims[3]);
    float* outData = new float[odims.elements()];
    output.host((void*)outData);

    // Compare result
    size_t nElems = tests[0].size();
    for (size_t elIter = 0; elIter < nElems; ++elIter) {
        ASSERT_NEAR(tests[0][elIter], outData[elIter], 0.0001) << "at: " << elIter << std::endl;
    }

    // Delete
    delete[] outData;
}
<commit_msg>Increase resize() test coverage<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <gtest/gtest.h>
#include <arrayfire.h>
#include <af/dim4.hpp>
#include <af/traits.hpp>
#include <vector>
#include <iostream>
#include <string>
#include <testHelpers.hpp>

using std::vector;
using std::string;
using std::cout;
using std::endl;
using af::cfloat;
using af::cdouble;

template<typename T>
class Resize : public ::testing::Test
{
    public:
        virtual void SetUp() {
            subMat0.push_back(af_make_seq(0, 4, 1));
            subMat0.push_back(af_make_seq(2, 6, 1));
            subMat0.push_back(af_make_seq(0, 2, 1));
        }
        vector<af_seq> subMat0;
};

template<typename T>
class ResizeI : public ::testing::Test
{
    public:
        virtual void SetUp() {
            subMat0.push_back(af_make_seq(0, 4, 1));
            subMat0.push_back(af_make_seq(2, 6, 1));
            subMat0.push_back(af_make_seq(0, 2, 1));

            subMat1.push_back(af_make_seq(0, 5, 1));
            subMat1.push_back(af_make_seq(0, 5, 1));
            subMat1.push_back(af_make_seq(0, 2, 1));
        }
        vector<af_seq> subMat0;
        vector<af_seq> subMat1;
};

// create a list of types to be tested
typedef ::testing::Types<float, double> TestTypesF;
typedef ::testing::Types<int, unsigned, unsigned char, char> TestTypesI;

// register the type list
TYPED_TEST_CASE(Resize, TestTypesF);
TYPED_TEST_CASE(ResizeI, TestTypesI);

TYPED_TEST(Resize, InvalidDims)
{
    if (noDoubleTests<TypeParam>()) return;

    vector<TypeParam> in(8,8);

    af_array inArray  = 0;
    af_array outArray = 0;

    af::dim4 dims = af::dim4(8,8,1,1);

    ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &in.front(), dims.ndims(), dims.get(),
                                          (af_dtype) af::dtype_traits<TypeParam>::af_type));
    ASSERT_EQ(AF_ERR_SIZE, af_resize(&outArray, inArray, 0, 0, AF_INTERP_NEAREST));
    ASSERT_EQ(AF_SUCCESS, af_destroy_array(inArray));
}

TYPED_TEST(Resize, InvalidType)
{
    if (noDoubleTests<TypeParam>()) return;

    vector<TypeParam> in(16,8);

    af_array inArray  = 0;
    af_array outArray = 0;

    af::dim4 dims = af::dim4(8,8,1,1);

    ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &in.front(), dims.ndims(), dims.get(),
                                          (af_dtype) af::dtype_traits<cfloat>::af_type));
    ASSERT_EQ(AF_ERR_INVALID_TYPE, af_resize(&outArray, inArray, 16, 16, AF_INTERP_NEAREST));
    ASSERT_EQ(AF_SUCCESS, af_destroy_array(inArray));
}

template<typename T>
void resizeTest(string pTestFile, const unsigned resultIdx, const dim_type odim0, const dim_type odim1, const af_interp_type method, bool isSubRef = false, const vector<af_seq> * seqv = NULL)
{
    if (noDoubleTests<T>()) return;

    vector<af::dim4> numDims;
    vector<vector<T> >   in;
    vector<vector<T> >   tests;
    readTests<T, T, float>(pTestFile,numDims,in,tests);

    af::dim4 dims = numDims[0];

    af_array inArray = 0;
    af_array outArray = 0;
    af_array tempArray = 0;
    if (isSubRef) {

        ASSERT_EQ(AF_SUCCESS, af_create_array(&tempArray, &(in[0].front()), dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<T>::af_type));

        ASSERT_EQ(AF_SUCCESS, af_index(&inArray, tempArray, seqv->size(), &seqv->front()));
    } else {
        ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &(in[0].front()), dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<T>::af_type));
    }

    ASSERT_EQ(AF_SUCCESS, af_resize(&outArray, inArray, odim0, odim1, method));

    // Get result
    af::dim4 odims(odim0, odim1, dims[2], dims[3]);
    T* outData = new T[odims.elements()];
    ASSERT_EQ(AF_SUCCESS, af_get_data_ptr((void*)outData, outArray));

    // Compare result
    size_t nElems = tests[resultIdx].size();
    for (size_t elIter = 0; elIter < nElems; ++elIter) {
        ASSERT_NEAR(tests[resultIdx][elIter], outData[elIter], 0.0001) << "at: " << elIter << std::endl;
    }

    // Delete
    delete[] outData;

    if(inArray   != 0) af_destroy_array(inArray);
    if(outArray  != 0) af_destroy_array(outArray);
    if(tempArray != 0) af_destroy_array(tempArray);
}

TYPED_TEST(Resize, Resize3CSquareUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 0, 16, 16, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize3CSquareUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 1, 16, 16, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize, Resize3CSquareDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 2, 4, 4, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize3CSquareDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 3, 4, 4, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize, Resize3CSquareUpNearestSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 4, 10, 10, AF_INTERP_NEAREST,
                          true, &(this->subMat0));
}

TYPED_TEST(Resize, Resize3CSquareUpLinearSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 5, 10, 10, AF_INTERP_BILINEAR,
                          true, &(this->subMat0));
}

TYPED_TEST(Resize, Resize3CSquareDownNearestSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 6, 3, 3, AF_INTERP_NEAREST,
                          true, &(this->subMat0));
}

TYPED_TEST(Resize, Resize3CSquareDownLinearSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 7, 3, 3, AF_INTERP_BILINEAR,
                          true, &(this->subMat0));
}

TYPED_TEST(Resize, Resize1CRectangleUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/rectangle.test"), 0, 12, 16, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize1CRectangleUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/rectangle.test"), 1, 12, 16, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize, Resize1CRectangleDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/rectangle.test"), 2, 6, 2, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize1CRectangleDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/rectangle.test"), 3, 6, 2, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize3CSquareUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 0, 16, 16, AF_INTERP_NEAREST);
}

TYPED_TEST(ResizeI, Resize3CSquareUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 1, 16, 16, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize3CSquareDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 2, 4, 4, AF_INTERP_NEAREST);
}

TYPED_TEST(ResizeI, Resize3CSquareDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 3, 4, 4, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize3CSquareUpNearestSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 4, 10, 10, AF_INTERP_NEAREST,
                          true, &(this->subMat0));
}

TYPED_TEST(ResizeI, Resize3CSquareUpLinearSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 5, 10, 10, AF_INTERP_BILINEAR,
                          true, &(this->subMat0));
}

TYPED_TEST(ResizeI, Resize3CSquareDownNearestSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 6, 3, 3, AF_INTERP_NEAREST,
                          true, &(this->subMat0));
}

TYPED_TEST(ResizeI, Resize3CSquareDownLinearSubref)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/square.test"), 8, 3, 3, AF_INTERP_BILINEAR,
                          true, &(this->subMat1));
}

TYPED_TEST(Resize, Resize1CLargeUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 0, 256, 256, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize1CLargeUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 1, 256, 256, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize, Resize1CLargeDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 2, 32, 32, AF_INTERP_NEAREST);
}

TYPED_TEST(Resize, Resize1CLargeDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 3, 32, 32, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize1CLargeUpNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 0, 256, 256, AF_INTERP_NEAREST);
}

TYPED_TEST(ResizeI, Resize1CLargeUpLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 1, 256, 256, AF_INTERP_BILINEAR);
}

TYPED_TEST(ResizeI, Resize1CLargeDownNearest)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 2, 32, 32, AF_INTERP_NEAREST);
}

TYPED_TEST(ResizeI, Resize1CLargeDownLinear)
{
    resizeTest<TypeParam>(string(TEST_DIR"/resize/large.test"), 3, 32, 32, AF_INTERP_BILINEAR);
}

template<typename T>
void resizeArgsTest(af_err err, string pTestFile, const af::dim4 odims, const af_interp_type method)
{
    if (noDoubleTests<T>()) return;

    vector<af::dim4> numDims;
    vector<vector<T> >   in;
    vector<vector<T> >   tests;
    readTests<T, T, float>(pTestFile,numDims,in,tests);

    af::dim4 dims = numDims[0];

    af_array inArray = 0;
    af_array outArray = 0;
    ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &(in[0].front()), dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<T>::af_type));

    ASSERT_EQ(err, af_resize(&outArray, inArray, odims[0], odims[1], method));

    if(inArray != 0) af_destroy_array(inArray);
    if(outArray != 0) af_destroy_array(outArray);
}

TYPED_TEST(Resize,InvalidArgsDims0)
{
    af::dim4 dims(0, 5, 2, 1);
    resizeArgsTest<TypeParam>(AF_ERR_SIZE, string(TEST_DIR"/resize/square.test"), dims, AF_INTERP_BILINEAR);
}

TYPED_TEST(Resize,InvalidArgsMethod)
{
    af::dim4 dims(10, 10, 1, 1);
    resizeArgsTest<TypeParam>(AF_ERR_ARG, string(TEST_DIR"/resize/square.test"), dims, AF_INTERP_CUBIC);
}

///////////////////////////////// CPP ////////////////////////////////////
//
TEST(Resize, CPP)
{
    if (noDoubleTests<float>()) return;

    vector<af::dim4> numDims;
    vector<vector<float> >   in;
    vector<vector<float> >   tests;
    readTests<float, float, float>(string(TEST_DIR"/resize/square.test"),numDims,in,tests);

    af::dim4 dims = numDims[0];
    af::array input(dims, &(in[0].front()));
    af::array output = af::resize(input, 16, 16);

    // Get result
    af::dim4 odims(16, 16, dims[2], dims[3]);
    float* outData = new float[odims.elements()];
    output.host((void*)outData);

    // Compare result
    size_t nElems = tests[0].size();
    for (size_t elIter = 0; elIter < nElems; ++elIter) {
        ASSERT_NEAR(tests[0][elIter], outData[elIter], 0.0001) << "at: " << elIter << std::endl;
    }

    // Delete
    delete[] outData;
}

TEST(ResizeScale1, CPP)
{
    if (noDoubleTests<float>()) return;

    vector<af::dim4> numDims;
    vector<vector<float> >   in;
    vector<vector<float> >   tests;
    readTests<float, float, float>(string(TEST_DIR"/resize/square.test"),numDims,in,tests);

    af::dim4 dims = numDims[0];
    af::array input(dims, &(in[0].front()));
    af::array output = af::resize(2.f, input);

    // Get result
    af::dim4 odims(16, 16, dims[2], dims[3]);
    float* outData = new float[odims.elements()];
    output.host((void*)outData);

    // Compare result
    size_t nElems = tests[0].size();
    for (size_t elIter = 0; elIter < nElems; ++elIter) {
        ASSERT_NEAR(tests[0][elIter], outData[elIter], 0.0001) << "at: " << elIter << std::endl;
    }

    // Delete
    delete[] outData;
}

TEST(ResizeScale2, CPP)
{
    if (noDoubleTests<float>()) return;

    vector<af::dim4> numDims;
    vector<vector<float> >   in;
    vector<vector<float> >   tests;
    readTests<float, float, float>(string(TEST_DIR"/resize/square.test"),numDims,in,tests);

    af::dim4 dims = numDims[0];
    af::array input(dims, &(in[0].front()));
    af::array output = af::resize(2.f, 2.f, input);

    // Get result
    af::dim4 odims(16, 16, dims[2], dims[3]);
    float* outData = new float[odims.elements()];
    output.host((void*)outData);

    // Compare result
    size_t nElems = tests[0].size();
    for (size_t elIter = 0; elIter < nElems; ++elIter) {
        ASSERT_NEAR(tests[0][elIter], outData[elIter], 0.0001) << "at: " << elIter << std::endl;
    }

    // Delete
    delete[] outData;
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template<typename MatrixType> void verifySizeOf(const MatrixType&)
{
  typedef typename MatrixType::Scalar Scalar;
  if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)
    VERIFY(std::ptrdiff_t(sizeof(MatrixType))==std::ptrdiff_t(sizeof(Scalar))*std::ptrdiff_t(MatrixType::SizeAtCompileTime));
  else
    VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));
}

void test_sizeof()
{
  CALL_SUBTEST(verifySizeOf(Matrix<float, 1, 1>()) );
  CALL_SUBTEST(verifySizeOf(Matrix4d()) );
  CALL_SUBTEST(verifySizeOf(Matrix<double, 4, 2>()) );
  CALL_SUBTEST(verifySizeOf(Matrix<bool, 7, 5>()) );
  CALL_SUBTEST(verifySizeOf(MatrixXcf(3, 3)) );
  CALL_SUBTEST(verifySizeOf(MatrixXi(8, 12)) );
  CALL_SUBTEST(verifySizeOf(MatrixXcd(20, 20)) );
  CALL_SUBTEST(verifySizeOf(Matrix<float, 100, 100>()) );

  VERIFY(sizeof(std::complex<float>) == 2*sizeof(float));
  VERIFY(sizeof(std::complex<double>) == 2*sizeof(double));
}
<commit_msg>Extend sizeof unit test<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template<typename MatrixType> void verifySizeOf(const MatrixType&)
{
  typedef typename MatrixType::Scalar Scalar;
  if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)
    VERIFY(std::ptrdiff_t(sizeof(MatrixType))==std::ptrdiff_t(sizeof(Scalar))*std::ptrdiff_t(MatrixType::SizeAtCompileTime));
  else
    VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));
}

void test_sizeof()
{
  CALL_SUBTEST(verifySizeOf(Matrix<float, 1, 1>()) );
  CALL_SUBTEST(verifySizeOf(Vector2d()) );
  CALL_SUBTEST(verifySizeOf(Vector4f()) );
  CALL_SUBTEST(verifySizeOf(Matrix4d()) );
  CALL_SUBTEST(verifySizeOf(Matrix<double, 4, 2>()) );
  CALL_SUBTEST(verifySizeOf(Matrix<bool, 7, 5>()) );
  CALL_SUBTEST(verifySizeOf(MatrixXcf(3, 3)) );
  CALL_SUBTEST(verifySizeOf(MatrixXi(8, 12)) );
  CALL_SUBTEST(verifySizeOf(MatrixXcd(20, 20)) );
  CALL_SUBTEST(verifySizeOf(Matrix<float, 100, 100>()) );

  VERIFY(sizeof(std::complex<float>) == 2*sizeof(float));
  VERIFY(sizeof(std::complex<double>) == 2*sizeof(double));
}
<|endoftext|>


<commit_before>#include <Beacon.h>
#include "HCIDumpParser.h"
#include "BeaconEventConsumer.h"

// Uncomment to publish the raw byte[] for the beacon, otherwise, properties are sent
//#define SEND_BINARY_DATA

extern "C" bool stop_scan_frames;

static void generateTestEvents(EventExchanger *exchanger) {
    printf("generateTestEvents, starting...\n");
    beacon_info event;
    int count = 0;
    try {
        bool running = true;
        while (running) {
            count++;
            int32_t minor = count % 150;
            sprintf(event.uuid, "UUID-%.12d", minor);
            event.minor = minor;
            event.rssi = -50 - count % 7;
            event.time = EventsWindow::currentMilliseconds();
            bool stop = beacon_event_callback(&event);
            running = !stop;
            this_thread::sleep_for(chrono::milliseconds(10));
        }
    } catch(exception& e) {
        printf("generateTestEvents failure, %s\n", e.what());
    }
    stop_scan_frames = true;
    printf("generateTestEvents, exiting\n");
}

void HCIDumpParser::processHCI(HCIDumpCommand &parseCommand) {
    HCIDumpParser::parseCommand = parseCommand;
    eventConsumer.setParseCommand(parseCommand);
    string clientID(parseCommand.getClientID());
    if (clientID.empty())
        clientID = parseCommand.getScannerID();
    timeWindow.reset(parseCommand.getAnalyzeWindow());
    // Setup the status information
    statusInformation->setScannerID(parseCommand.getScannerID());
    statusInformation->setStatusInterval(parseCommand.getStatusInterval());
    statusInformation->setStatusQueue(parseCommand.getStatusQueue());

    if (parseCommand.isAnalyzeMode()) {
        printf("Running in analyze mode, window=%d seconds, begin=%lld\n", parseCommand.getAnalyzeWindow(),
               timeWindow.getBegin());
    }
    else if (!parseCommand.isSkipPublish()) {
        publisher.reset(MsgPublisher::create(parseCommand.getPubType(), parseCommand.getBrokerURL(), clientID, "", ""));
        publisher->setUseTopics(!parseCommand.isUseQueues());
        printf("setUseTopics: %s\n", publisher->isUseTopics() ? "true" : "false");
        publisher->setDestinationName(parseCommand.getDestinationName());
        if (batchCount > 0) {
            publisher->setUseTransactions(true);
            printf("Enabled transactions\n");
        }
        publisher->start(parseCommand.isAsyncMode());

        // Create a thread for the consumer unless running in battery test mode
        if(!parseCommand.isBatteryTestMode()) {
            eventExchanger.reset(new EventExchanger);
            eventConsumer.init(eventExchanger, publisher, statusInformation);
            consumerThread.reset(new thread(&BeaconEventConsumer::publishEvents, &eventConsumer));
            printf("Started event consumer thread\n");
        }
    }
    else {
        printf("Skipping publish of parsed beacons\n");
    }

    // If the status interval is > 0, start the health status monitor
    if(parseCommand.getStatusInterval() > 0) {
        statusMonitor.start(publisher, statusInformation);
    }

    if(parseCommand.isGenerateTestData()) {
        // Generate test data
        thread testThread(generateTestEvents, eventExchanger.get());
        testThread.detach();
    }

    // Scan
    char cdev = parseCommand.getHciDev().at(parseCommand.getHciDev().size() - 1);
    int device = cdev - '0';
    scan_frames(device, beacon_event_callback);

    // Join the consumerThread if it was
    eventConsumer.setRunning(false);
    if(consumerThread && consumerThread->joinable()) {
        printf("Joining the consumer thread...\n");
        consumerThread->join();
        printf("done\n");
    }

    // Stop the status monitor
    statusMonitor.stop();
}

void HCIDumpParser::beaconEvent(const beacon_info &info) {
    // Check for heartbeat
    bool isHeartbeat = scannerUUID.compare(info.uuid) == 0;
    if(parseCommand.isBatteryTestMode()) {
        // Send the raw unaveraged heartbeat info, or ignore non-heartbeat events
        if(isHeartbeat)
            sendRawHeartbeat(info);
        return;
    }

    // Merge the event into the current time window
    shared_ptr<EventsBucket> bucket = timeWindow.addEvent(info, isHeartbeat);
    statusInformation->addEvent(info, isHeartbeat);
    // Now handle the bucket if a new one has been created
    if (bucket) {
        if (!parseCommand.isSkipPublish()) {
            eventExchanger->putEvent(bucket);
        }
        else {
            if (parseCommand.isAnalyzeMode()) {
                printBeaconCounts(bucket);
            } else {
                Beacon beacon(parseCommand.getScannerID(), info.uuid, info.code, info.manufacturer, info.major,
                              info.minor, info.power, info.calibrated_power, info.rssi, info.time);
                const char *info = isHeartbeat ? "heartbeat" : "event";
                if (!isHeartbeat || (isHeartbeat && !parseCommand.isSkipHeartbeat()))
                    printBeaconCounts(beacon, bucket);
            }
        }
        // Display either the closest beacon or status
        if(scannerView) {
            if(scannerView->isDisplayBeaconsMode())
                displayClosestBeacon(bucket);
            else
                displayStatus();
        }
    }
}

void HCIDumpParser::cleanup() {
    if (publisher)
        publisher->stop();
}

void HCIDumpParser::printBeaconCounts(Beacon beacon, const shared_ptr<EventsBucket> &bucket) {
    printf("Window: parsed(%s):\n", beacon.toString().c_str());
    printBeaconCounts(bucket);
}

void HCIDumpParser::printBeaconCounts(const shared_ptr<EventsBucket> &bucket) {
    vector<char> tmp;
    bucket->toString(tmp);
    printf("%s\n", tmp.data());
}

void HCIDumpParser::sendRawHeartbeat(const beacon_info &info) {
    Beacon beacon(parseCommand.getScannerID(), info.uuid, info.code, info.manufacturer, info.major, info.minor,
                  info.power, info.calibrated_power, info.rssi, info.time);
    beacon.setMessageType(BeconEventType::SCANNER_HEARTBEAT);
    publisher->publishStatus(beacon);
}

void HCIDumpParser::displayClosestBeacon(const shared_ptr<EventsBucket>& bucket) {
    map<int32_t, beacon_info>::const_iterator iter = bucket->begin();
    int32_t maxRSSI = -100;
    const beacon_info *closest = nullptr;
    const beacon_info *heartbeat = nullptr;
    while (iter != bucket->end()) {
        // Skip the heartbeast beacon...
        if(iter->second.rssi > maxRSSI) {
            if(scannerUUID.compare(iter->second.uuid) == 0)
                heartbeat = &iter->second;
            else {
                maxRSSI = iter->second.rssi;
                closest = &iter->second;
            }
        }
        iter++;
    }
    if(closest != nullptr) {
        Beacon closestBeacon(parseCommand.getScannerID(), closest->uuid, closest->code, closest->manufacturer,
                             closest->major, closest->minor, closest->power, closest->calibrated_power,
                             closest->rssi, closest->time);
        scannerView->displayBeacon(closestBeacon);
    } else if(heartbeat != nullptr) {
        // The only beacon seen was the heartbeat beacon, so display it
        Beacon heartbeatBeacon(parseCommand.getScannerID(), heartbeat->uuid, heartbeat->code, heartbeat->manufacturer,
                               heartbeat->major, heartbeat->minor, heartbeat->power, heartbeat->calibrated_power,
                               heartbeat->rssi, heartbeat->time);
        scannerView->displayHeartbeat(heartbeatBeacon);
    }

}

void HCIDumpParser::displayStatus() {
    scannerView->displayStatus(*statusInformation);
}
<commit_msg>Dump out last 10 heartbeat RSSI every 100<commit_after>#include <Beacon.h>
#include "HCIDumpParser.h"
#include "BeaconEventConsumer.h"

// Uncomment to publish the raw byte[] for the beacon, otherwise, properties are sent
//#define SEND_BINARY_DATA

extern "C" bool stop_scan_frames;

static void generateTestEvents(EventExchanger *exchanger) {
    printf("generateTestEvents, starting...\n");
    beacon_info event;
    int count = 0;
    try {
        bool running = true;
        while (running) {
            count++;
            int32_t minor = count % 150;
            sprintf(event.uuid, "UUID-%.12d", minor);
            event.minor = minor;
            event.rssi = -50 - count % 7;
            event.time = EventsWindow::currentMilliseconds();
            bool stop = beacon_event_callback(&event);
            running = !stop;
            this_thread::sleep_for(chrono::milliseconds(10));
        }
    } catch(exception& e) {
        printf("generateTestEvents failure, %s\n", e.what());
    }
    stop_scan_frames = true;
    printf("generateTestEvents, exiting\n");
}

void HCIDumpParser::processHCI(HCIDumpCommand &parseCommand) {
    HCIDumpParser::parseCommand = parseCommand;
    eventConsumer.setParseCommand(parseCommand);
    string clientID(parseCommand.getClientID());
    if (clientID.empty())
        clientID = parseCommand.getScannerID();
    timeWindow.reset(parseCommand.getAnalyzeWindow());
    // Setup the status information
    statusInformation->setScannerID(parseCommand.getScannerID());
    statusInformation->setStatusInterval(parseCommand.getStatusInterval());
    statusInformation->setStatusQueue(parseCommand.getStatusQueue());

    if (parseCommand.isAnalyzeMode()) {
        printf("Running in analyze mode, window=%d seconds, begin=%lld\n", parseCommand.getAnalyzeWindow(),
               timeWindow.getBegin());
    }
    else if (!parseCommand.isSkipPublish()) {
        publisher.reset(MsgPublisher::create(parseCommand.getPubType(), parseCommand.getBrokerURL(), clientID, "", ""));
        publisher->setUseTopics(!parseCommand.isUseQueues());
        printf("setUseTopics: %s\n", publisher->isUseTopics() ? "true" : "false");
        publisher->setDestinationName(parseCommand.getDestinationName());
        if (batchCount > 0) {
            publisher->setUseTransactions(true);
            printf("Enabled transactions\n");
        }
        publisher->start(parseCommand.isAsyncMode());

        // Create a thread for the consumer unless running in battery test mode
        if(!parseCommand.isBatteryTestMode()) {
            eventExchanger.reset(new EventExchanger);
            eventConsumer.init(eventExchanger, publisher, statusInformation);
            consumerThread.reset(new thread(&BeaconEventConsumer::publishEvents, &eventConsumer));
            printf("Started event consumer thread\n");
        }
    }
    else {
        printf("Skipping publish of parsed beacons\n");
    }

    // If the status interval is > 0, start the health status monitor
    if(parseCommand.getStatusInterval() > 0) {
        statusMonitor.start(publisher, statusInformation);
    }

    if(parseCommand.isGenerateTestData()) {
        // Generate test data
        thread testThread(generateTestEvents, eventExchanger.get());
        testThread.detach();
    }

    // Scan
    char cdev = parseCommand.getHciDev().at(parseCommand.getHciDev().size() - 1);
    int device = cdev - '0';
    scan_frames(device, beacon_event_callback);

    // Join the consumerThread if it was
    eventConsumer.setRunning(false);
    if(consumerThread && consumerThread->joinable()) {
        printf("Joining the consumer thread...\n");
        consumerThread->join();
        printf("done\n");
    }

    // Stop the status monitor
    statusMonitor.stop();
}

void HCIDumpParser::beaconEvent(const beacon_info &info) {
    // Check for heartbeat
    bool isHeartbeat = scannerUUID.compare(info.uuid) == 0;
    if(parseCommand.isBatteryTestMode()) {
        // Send the raw unaveraged heartbeat info, or ignore non-heartbeat events
        if(isHeartbeat)
            sendRawHeartbeat(info);
        return;
    }

    // Merge the event into the current time window
    shared_ptr<EventsBucket> bucket = timeWindow.addEvent(info, isHeartbeat);
    statusInformation->addEvent(info, isHeartbeat);
    // Now handle the bucket if a new one has been created
    if (bucket) {
        if (!parseCommand.isSkipPublish()) {
            eventExchanger->putEvent(bucket);
        }
        else {
            if (parseCommand.isAnalyzeMode()) {
                printBeaconCounts(bucket);
            } else {
                Beacon beacon(parseCommand.getScannerID(), info.uuid, info.code, info.manufacturer, info.major,
                              info.minor, info.power, info.calibrated_power, info.rssi, info.time);
                const char *info = isHeartbeat ? "heartbeat" : "event";
                if (!isHeartbeat || (isHeartbeat && !parseCommand.isSkipHeartbeat()))
                    printBeaconCounts(beacon, bucket);
            }
        }
        // Display either the closest beacon or status
        if(scannerView) {
            if(scannerView->isDisplayBeaconsMode())
                displayClosestBeacon(bucket);
            else
                displayStatus();
        }
    }
}

void HCIDumpParser::cleanup() {
    if (publisher)
        publisher->stop();
}

void HCIDumpParser::printBeaconCounts(Beacon beacon, const shared_ptr<EventsBucket> &bucket) {
    printf("Window: parsed(%s):\n", beacon.toString().c_str());
    printBeaconCounts(bucket);
}

void HCIDumpParser::printBeaconCounts(const shared_ptr<EventsBucket> &bucket) {
    vector<char> tmp;
    bucket->toString(tmp);
    printf("%s\n", tmp.data());
}

static int lastRSSI[10];
static int heartbeatCount = 0;
void HCIDumpParser::sendRawHeartbeat(const beacon_info &info) {
    Beacon beacon(parseCommand.getScannerID(), info.uuid, info.code, info.manufacturer, info.major, info.minor,
                  info.power, info.calibrated_power, info.rssi, info.time);
    beacon.setMessageType(BeconEventType::SCANNER_HEARTBEAT);
    publisher->publishStatus(beacon);
    lastRSSI[heartbeatCount%10] = info.rssi;
    heartbeatCount ++;
    if(heartbeatCount % 100 == 0) {
        printf("Last[10].RSSI:");
        for(int n = 0; n < 10; n ++)
            printf("%d,", lastRSSI[n]);
        printf("\n");
    }
}

void HCIDumpParser::displayClosestBeacon(const shared_ptr<EventsBucket>& bucket) {
    map<int32_t, beacon_info>::const_iterator iter = bucket->begin();
    int32_t maxRSSI = -100;
    const beacon_info *closest = nullptr;
    const beacon_info *heartbeat = nullptr;
    while (iter != bucket->end()) {
        // Skip the heartbeast beacon...
        if(iter->second.rssi > maxRSSI) {
            if(scannerUUID.compare(iter->second.uuid) == 0)
                heartbeat = &iter->second;
            else {
                maxRSSI = iter->second.rssi;
                closest = &iter->second;
            }
        }
        iter++;
    }
    if(closest != nullptr) {
        Beacon closestBeacon(parseCommand.getScannerID(), closest->uuid, closest->code, closest->manufacturer,
                             closest->major, closest->minor, closest->power, closest->calibrated_power,
                             closest->rssi, closest->time);
        scannerView->displayBeacon(closestBeacon);
    } else if(heartbeat != nullptr) {
        // The only beacon seen was the heartbeat beacon, so display it
        Beacon heartbeatBeacon(parseCommand.getScannerID(), heartbeat->uuid, heartbeat->code, heartbeat->manufacturer,
                               heartbeat->major, heartbeat->minor, heartbeat->power, heartbeat->calibrated_power,
                               heartbeat->rssi, heartbeat->time);
        scannerView->displayHeartbeat(heartbeatBeacon);
    }

}

void HCIDumpParser::displayStatus() {
    scannerView->displayStatus(*statusInformation);
}
<|endoftext|>


<commit_before>#include "disassembler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/CommandLine.h"

#include "assert.h"

using namespace llvm;

static cl::opt<std::string>
inputFileName(cl::Positional, cl::desc("<input file>"), cl::init("-"));

int main(int argc, char **argv) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> bufferPtr =
      MemoryBuffer::getFileOrSTDIN(inputFileName);

  if (std::error_code EC = bufferPtr.getError()) {
    errs() << inputFileName << ": " << EC.message() << '\n';
    return 1;
  }

  StringRef buffer = bufferPtr->get()->getBuffer();

  Disassembler disassembler(Disassembler::Intel);

  StringRef hex = buffer.trim();
  auto y = hexToBinary(hex);
  std::string out;
  bool ok = disassembler.disassemble(y, out);
  if (!ok) {
    errs() << "Disassembly failed\n";
    return 1;
  }
  outs() << out << '\n';
  return 0;
}
<commit_msg>parametric disassembly type<commit_after>#include "disassembler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/CommandLine.h"

#include "assert.h"

using namespace llvm;

static cl::opt<std::string> inputFileName(cl::Positional, cl::desc("<input file>"), cl::init("-"));

static cl::opt<Disassembler::AsmSyntax> syntaxType(cl::desc("Choose output syntax type:"),
                                                   cl::values(clEnumValN(Disassembler::Intel, "intel", "Output Intel syntax (default)"),
                                                              clEnumValN(Disassembler::ATT, "att" , "Output AT&T ayntax")));

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv);

  ErrorOr<std::unique_ptr<MemoryBuffer>> bufferPtr =
      MemoryBuffer::getFileOrSTDIN(inputFileName);

  if (std::error_code EC = bufferPtr.getError()) {
    errs() << inputFileName << ": " << EC.message() << '\n';
    return 1;
  }

  StringRef buffer = bufferPtr->get()->getBuffer();

  Disassembler disassembler(syntaxType);

  StringRef hex = buffer.trim();
  auto y = hexToBinary(hex);
  std::string out;
  bool ok = disassembler.disassemble(y, out);
  if (!ok) {
    errs() << "Disassembly failed\n";
    return 1;
  }
  outs() << out << '\n';
  return 0;
}
<|endoftext|>


<commit_before>

#include <cstdlib>
#include <iostream>
#include <climits>
#include <algorithm>
#include <vector>
#include <utility>
#include <ctime>

#include "qset.hh"
#include "graphTypes.hh"

//Basically just a DFS
//We start at v, and search
//We expand vertices in S
//And we add to our count (without expanding) for those not in S
int sizeQ(int n, const VSet &S, Vertex v, const Graph& G)
{
    //std::cout << "Q: starting with S = " << showSet(S) << "\n";

    //int n = boost::num_vertices(G);

    Vertex* open = new Vertex[n];

    open[0] = v;
    int stackEnd = 0;

    //Uses more memory than VSet, but is faster
    bool* closed = new bool[n];
    for (int i = 0; i <n; i++)
    {
	closed[i] = false;
    }

    int numInQ = 0;

    while (stackEnd >= 0 )
    {
	Vertex w = open[stackEnd];
	stackEnd--;
	auto neighbours = boost::adjacent_vertices(w,G);
	//std::cout << "Q: expanding " << w << "\n";

	for (auto iter = neighbours.first; iter != neighbours.second; iter++ )
	{
            Vertex u = *iter;
	    //std::cout << "Q: found neighbour " << u << "\n";
	    if (!closed[u])
	    {
		//std::cout << "Q: adding " << u << " to closed\n";

                closed[u] = true;

		if (u != v && S.contains(u))
		{
		    //std::cout << "Q: adding " << u << " to queue\n";
		    stackEnd++;
		    open[stackEnd] = u;
		}
		else if (u != v)
		{
		    numInQ++;

		}
	    }
	}
    }
    delete[] closed;
    delete[] open;
    //std::cout << "|Q| = " << numInQ << "\n";
    return numInQ;

}

std::string showSet(VSet S) {
    std::ostringstream result;

    result << "{";

    std::vector<Vertex> members;
    S.members(members);

    for (auto iter = members.begin(); iter != members.end(); iter++)
        {
            result << *iter << " ; ";
        }

    result << "}";

    return result.str();

}
<commit_msg>Avoid malloc in qsize<commit_after>

#include <cstdlib>
#include <iostream>
#include <climits>
#include <algorithm>
#include <vector>
#include <utility>
#include <ctime>

#include "qset.hh"
#include "graphTypes.hh"

//Basically just a DFS
//We start at v, and search
//We expand vertices in S
//And we add to our count (without expanding) for those not in S
int sizeQ(int n, const VSet &S, Vertex v, const Graph& G)
{
    //std::cout << "Q: starting with S = " << showSet(S) << "\n";

    //int n = boost::num_vertices(G);

    Vertex open[MAX_NUM_VERTICES];

    open[0] = v;
    int stackEnd = 0;

    //Uses more memory than VSet, but is faster
    bool closed[MAX_NUM_VERTICES] = {false};

    int numInQ = 0;

    while (stackEnd >= 0 )
    {
	Vertex w = open[stackEnd];
	stackEnd--;
	auto neighbours = boost::adjacent_vertices(w,G);
	//std::cout << "Q: expanding " << w << "\n";

	for (auto iter = neighbours.first; iter != neighbours.second; iter++ )
	{
            Vertex u = *iter;
	    //std::cout << "Q: found neighbour " << u << "\n";
	    if (!closed[u])
	    {
		//std::cout << "Q: adding " << u << " to closed\n";

                closed[u] = true;

		if (u != v && S.contains(u))
		{
		    //std::cout << "Q: adding " << u << " to queue\n";
		    stackEnd++;
		    open[stackEnd] = u;
		}
		else if (u != v)
		{
		    numInQ++;

		}
	    }
	}
    }
    //delete[] closed;
    // delete[] open;
    //std::cout << "|Q| = " << numInQ << "\n";
    return numInQ;

}

std::string showSet(VSet S) {
    std::ostringstream result;

    result << "{";

    std::vector<Vertex> members;
    S.members(members);

    for (auto iter = members.begin(); iter != members.end(); iter++)
        {
            result << *iter << " ; ";
        }

    result << "}";

    return result.str();

}
<|endoftext|>


<commit_before>/**
 * Computer Graphics Assignment 3 -
 * Mitchell Anderson, Andrew Pham, Konrad Janica
 *
 * rain.cc, Simple implementation of a Rain in openGL
 *
 * This file is a simple implementation of rain in openGL
 * for more clarification read the comments describing each function
 *
 * Code tutorial - http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/
 *
 */

#include "rain.h"

Rain::Rain(const GLuint &program_id) : MAX_PARTICLES_(100000), rain_shader_(program_id)
{
  // Initialize the particle buffers
  particles_ = new Particle[MAX_PARTICLES_];
  particle_position_buffer_data_ = new GLfloat[MAX_PARTICLES_ * 3];
  particle_colour_buffer_data_ = new GLfloat[MAX_PARTICLES_ * 4];

  // Set the range in which the rain is generated
  maxx_ = 100.0f;
  maxy_ = 30.0f;
  maxz_ = 100.0f;

  // Run initialization
  rain_vao_ = CreateVao();
  Init();

}

Rain::~Rain()
{
  delete [] particles_;
  delete [] particle_position_buffer_data_;
  delete [] particle_colour_buffer_data_;

}

unsigned int Rain::CreateVao()
{
  glUseProgram(rain_shader_);

  // Initial declaration of the shape of the 'raindrop'
  // these values can be modified to change the shape of the rain
  static const GLfloat vertices[] = {
   -0.01f, -0.05f, 0.0f,
    0.01f, -0.05f, 0.0f,
   -0.01f,  0.05f, 0.0f,
    0.01f,  0.05f, 0.0f,
  };

  // Create a VAO for the rain
  GLuint vao;
  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);

  // VBO containing a single instance of a particle
  glGenBuffers(1, &particle_instance_buffer_);
  glBindBuffer(GL_ARRAY_BUFFER, particle_instance_buffer_);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  // VBO containing position of each particle instance
  glGenBuffers(1, &particle_position_buffer_);
  glBindBuffer(GL_ARRAY_BUFFER, particle_position_buffer_);

  // Initially set data to NULL
  glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES_ * 3 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);

  // VBO containing colours of each particle instance
  glGenBuffers(1, &particle_colour_buffer_);
  glBindBuffer(GL_ARRAY_BUFFER, particle_colour_buffer_);

  // Initially set data to NULL
  glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES_ * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);

  return vao;
}

void Rain::Init()
{

  // Random generation engines to generate uniform floats between a range
  std::random_device rd;
  std::mt19937 eng(rd());
  // One for each axis
  std::uniform_real_distribution<> xgen(0,maxx_);
  std::uniform_real_distribution<> ygen(0,maxy_);
  std::uniform_real_distribution<> zgen(0,maxz_);
  // Initialize the position/speed/colour for all particles

  int maxx = 50.0f;
  int maxy = 20.0f;
  int maxz = 50.0f;

  for (unsigned int i = 0; i < MAX_PARTICLES_; i++)
  {
    // Randomly generate the positions of the particle
    particles_[i].pos = glm::vec3(xgen(eng), ygen(eng), zgen(eng));
    particles_[i].speed = 0.1f;

    // Slightly randomize colours between a certain range (Blue/Blue-Grey)
    float red = (rand() % 49 + 24) / 255.0f;
    float green = (rand() % 77 + 17) / 255.0f;
    float blue = (rand() % 176 + 70) / 255.0f;
    particles_[i].colour = glm::vec4(red, green, blue, 1.0f);
  }
}

void Rain::UpdatePosition()
{
  // Updates particles and puts in data arrays
  for (unsigned int i = 0; i < MAX_PARTICLES_; i++)
  {
    // Reduce y so the rain travels towards the ground
    particles_[i].pos.y -= particles_[i].speed;

    // Reduce x so rain appears to be sweeping across the scene
    particles_[i].pos.x += particles_[i].speed;

    // Boundary cases so that the rain particles 'reset' with a smal amount of randomization
    particles_[i].pos.x += particles_[i].speed;

    if(particles_[i].pos.y < -5)
    {
      particles_[i].pos.y = maxy_ - (rand() % 5);
    }

    if (particles_[i].pos.x > maxx_)
    {
      particles_[i].pos.x = 0.0f;
    }

    // Store the particles data inside the buffer, to be put in to the VBO

    particle_position_buffer_data_[i*3 + 0] = particles_[i].pos.x;
    particle_position_buffer_data_[i*3 + 1] = particles_[i].pos.y;
    particle_position_buffer_data_[i*3 + 2] = particles_[i].pos.z;

    particle_colour_buffer_data_[i*4 + 0] = particles_[i].colour.x;
    particle_colour_buffer_data_[i*4 + 1] = particles_[i].colour.y;
    particle_colour_buffer_data_[i*4 + 2] = particles_[i].colour.z;
    particle_colour_buffer_data_[i*4 + 3] = particles_[i].colour.w;
  }
}

void Rain::Render(Camera * camera, Object * car, Skybox * skybox)
{
  glUseProgram(rain_shader_);

  // Enable blending so that rain is slightly transparent, transparency is set in the frag shader
  glEnable(GL_BLEND);
  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

  glBindVertexArray(rain_vao_);

  // Set the Buffer subdata to be the positions array that we filled in UpdatePosition()
  glBindBuffer(GL_ARRAY_BUFFER, particle_position_buffer_);
  glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES_ * 3 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);
  glBufferSubData(GL_ARRAY_BUFFER, 0, MAX_PARTICLES_ * 3 * sizeof(GLfloat), particle_position_buffer_data_);

  // Set the colour subdata to be the positions array that we filled in UpdatePosition()
  glBindBuffer(GL_ARRAY_BUFFER, particle_colour_buffer_);
  glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES_ * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);
  glBufferSubData(GL_ARRAY_BUFFER, 0, MAX_PARTICLES_ * 4 * sizeof(GLfloat), particle_colour_buffer_data_);

  // Get the handle for the Model * View Matrix
  GLint mvHandle = glGetUniformLocation(rain_shader_, "modelview_matrix");
  if (mvHandle == -1) {
    fprintf(stderr,"Could not find uniform: modelview_matrix In: Rain - Render\n");
  }

  GLuint initialVerticesHandle = glGetAttribLocation(rain_shader_, "initial_vertices");
  GLuint positionsHandle = glGetAttribLocation(rain_shader_, "displaced_vertices");
  GLuint colourHandle = glGetAttribLocation(rain_shader_, "colour");

  // Get the view matrix from the camera
  glm::mat4 view_matrix = camera->view_matrix();

  // Translate based on the car, so the rain follows the car
  glm::mat4 object_translate = glm::translate(glm::mat4(1.0f),
      glm::vec3(car->translation().x, 1.0f , car->translation().z));

  // Translate the rain so its centre is roughly around the centre of the car
  glm::mat4 rain_translate = glm::translate(glm::mat4(1.0f), glm::vec3(-maxx_ / 2.0f, 0.0f, -maxz_ / 2.0f));

  // Apply the transformations
  view_matrix = view_matrix * object_translate * rain_translate;

  glUniformMatrix4fv(mvHandle, 1, false, glm::value_ptr(view_matrix));

  // The cameras up vector is (0,1,0) transform it to world space by
  // by multiplying my camera->world (view) matrix inverse
  GLuint CamRight  = glGetUniformLocation(rain_shader_, "cam_right");
  GLuint CamUp  = glGetUniformLocation(rain_shader_, "cam_up");

  glUniform3f(CamRight, view_matrix[0][0], view_matrix[1][0], view_matrix[2][0]);
  glUniform3f(CamUp   , view_matrix[0][1], view_matrix[1][1], view_matrix[2][1]);

  glBindBuffer(GL_ARRAY_BUFFER, particle_instance_buffer_);
  glEnableVertexAttribArray(initialVerticesHandle);
  glVertexAttribPointer(initialVerticesHandle, 3, GL_FLOAT, GL_FALSE, 0, 0);

  glBindBuffer(GL_ARRAY_BUFFER, particle_position_buffer_);
  glEnableVertexAttribArray(positionsHandle);
  glVertexAttribPointer(positionsHandle, 3, GL_FLOAT, GL_FALSE, 0, 0);

  glBindBuffer(GL_ARRAY_BUFFER, particle_colour_buffer_);
  glEnableVertexAttribArray(colourHandle);
  glVertexAttribPointer(colourHandle, 4, GL_FLOAT, GL_FALSE, 0, 0);

  // Needed for instanced draws
  glVertexAttribDivisor(initialVerticesHandle, 0);    // Same every particle
  glVertexAttribDivisor(positionsHandle, 1);          // One per particle
  glVertexAttribDivisor(colourHandle, 1);             // One per particle

  // Equivalent to looping over all particles (with 4 vertices)
  glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, MAX_PARTICLES_);

  glDisable(GL_BLEND);

}

<commit_msg>made slight change<commit_after>/**
 * Computer Graphics Assignment 3 -
 * Mitchell Anderson, Andrew Pham, Konrad Janica
 *
 * rain.cc, Simple implementation of a Rain in openGL
 *
 * This file is a simple implementation of rain in openGL
 * for more clarification read the comments describing each function
 *
 * Code tutorial - http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/
 *
 */

#include "rain.h"

Rain::Rain(const GLuint &program_id) : MAX_PARTICLES_(100000), rain_shader_(program_id)
{
  // Initialize the particle buffers
  particles_ = new Particle[MAX_PARTICLES_];
  particle_position_buffer_data_ = new GLfloat[MAX_PARTICLES_ * 3];
  particle_colour_buffer_data_ = new GLfloat[MAX_PARTICLES_ * 4];

  // Set the range in which the rain is generated
  maxx_ = 100.0f;
  maxy_ = 30.0f;
  maxz_ = 100.0f;

  // Run initialization
  rain_vao_ = CreateVao();
  Init();

}

Rain::~Rain()
{
  delete [] particles_;
  delete [] particle_position_buffer_data_;
  delete [] particle_colour_buffer_data_;

}

unsigned int Rain::CreateVao()
{
  glUseProgram(rain_shader_);

  // Initial declaration of the shape of the 'raindrop'
  // these values can be modified to change the shape of the rain
  static const GLfloat vertices[] = {
   -0.01f, -0.05f, 0.0f,
    0.01f, -0.05f, 0.0f,
   -0.01f,  0.05f, 0.0f,
    0.01f,  0.05f, 0.0f,
  };

  // Create a VAO for the rain
  GLuint vao;
  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);

  // VBO containing a single instance of a particle
  glGenBuffers(1, &particle_instance_buffer_);
  glBindBuffer(GL_ARRAY_BUFFER, particle_instance_buffer_);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  // VBO containing position of each particle instance
  glGenBuffers(1, &particle_position_buffer_);
  glBindBuffer(GL_ARRAY_BUFFER, particle_position_buffer_);

  // Initially set data to NULL
  glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES_ * 3 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);

  // VBO containing colours of each particle instance
  glGenBuffers(1, &particle_colour_buffer_);
  glBindBuffer(GL_ARRAY_BUFFER, particle_colour_buffer_);

  // Initially set data to NULL
  glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES_ * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);

  return vao;
}

void Rain::Init()
{

  // Random generation engines to generate uniform floats between a range
  std::random_device rd;
  std::mt19937 eng(rd());
  // One for each axis
  std::uniform_real_distribution<> xgen(0,maxx_);
  std::uniform_real_distribution<> ygen(0,maxy_);
  std::uniform_real_distribution<> zgen(0,maxz_);
  // Initialize the position/speed/colour for all particles

  int maxx = 50.0f;
  int maxy = 20.0f;
  int maxz = 50.0f;

  for (unsigned int i = 0; i < MAX_PARTICLES_; i++)
  {
    // Randomly generate the positions of the particle
    particles_[i].pos = glm::vec3(xgen(eng), ygen(eng), zgen(eng));
    particles_[i].speed = 0.1f;

    // Slightly randomize colours between a certain range (Blue/Blue-Grey)
    float red = (rand() % 49 + 24) / 255.0f;
    float green = (rand() % 77 + 17) / 255.0f;
    float blue = (rand() % 176 + 70) / 255.0f;
    particles_[i].colour = glm::vec4(red, green, blue, 1.0f);
  }
}

void Rain::UpdatePosition()
{
  // Updates particles and puts in data arrays
  for (unsigned int i = 0; i < MAX_PARTICLES_; i++)
  {
    // Reduce y so the rain travels towards the ground
    particles_[i].pos.y -= particles_[i].speed;

    // Reduce x so rain appears to be sweeping across the scene
    particles_[i].pos.x += particles_[i].speed;

    if(particles_[i].pos.y < -5)
    {
      particles_[i].pos.y = maxy_ - (rand() % 5);
    }

    if (particles_[i].pos.x > maxx_)
    {
      particles_[i].pos.x = 0.0f;
    }

    // Store the particles data inside the buffer, to be put in to the VBO

    particle_position_buffer_data_[i*3 + 0] = particles_[i].pos.x;
    particle_position_buffer_data_[i*3 + 1] = particles_[i].pos.y;
    particle_position_buffer_data_[i*3 + 2] = particles_[i].pos.z;

    particle_colour_buffer_data_[i*4 + 0] = particles_[i].colour.x;
    particle_colour_buffer_data_[i*4 + 1] = particles_[i].colour.y;
    particle_colour_buffer_data_[i*4 + 2] = particles_[i].colour.z;
    particle_colour_buffer_data_[i*4 + 3] = particles_[i].colour.w;
  }
}

void Rain::Render(Camera * camera, Object * car, Skybox * skybox)
{
  glUseProgram(rain_shader_);

  // Enable blending so that rain is slightly transparent, transparency is set in the frag shader
  glEnable(GL_BLEND);
  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

  glBindVertexArray(rain_vao_);

  // Set the Buffer subdata to be the positions array that we filled in UpdatePosition()
  glBindBuffer(GL_ARRAY_BUFFER, particle_position_buffer_);
  glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES_ * 3 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);
  glBufferSubData(GL_ARRAY_BUFFER, 0, MAX_PARTICLES_ * 3 * sizeof(GLfloat), particle_position_buffer_data_);

  // Set the colour subdata to be the positions array that we filled in UpdatePosition()
  glBindBuffer(GL_ARRAY_BUFFER, particle_colour_buffer_);
  glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES_ * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW);
  glBufferSubData(GL_ARRAY_BUFFER, 0, MAX_PARTICLES_ * 4 * sizeof(GLfloat), particle_colour_buffer_data_);

  // Get the handle for the Model * View Matrix
  GLint mvHandle = glGetUniformLocation(rain_shader_, "modelview_matrix");
  if (mvHandle == -1) {
    fprintf(stderr,"Could not find uniform: modelview_matrix In: Rain - Render\n");
  }

  GLuint initialVerticesHandle = glGetAttribLocation(rain_shader_, "initial_vertices");
  GLuint positionsHandle = glGetAttribLocation(rain_shader_, "displaced_vertices");
  GLuint colourHandle = glGetAttribLocation(rain_shader_, "colour");

  // Get the view matrix from the camera
  glm::mat4 view_matrix = camera->view_matrix();

  // Translate based on the car, so the rain follows the car
  glm::mat4 object_translate = glm::translate(glm::mat4(1.0f),
      glm::vec3(car->translation().x, 1.0f , car->translation().z));

  // Translate the rain so its centre is roughly around the centre of the car
  glm::mat4 rain_translate = glm::translate(glm::mat4(1.0f), glm::vec3(-maxx_ / 2.0f, 0.0f, -maxz_ / 2.0f));

  // Apply the transformations
  view_matrix = view_matrix * object_translate * rain_translate;

  glUniformMatrix4fv(mvHandle, 1, false, glm::value_ptr(view_matrix));

  // The cameras up vector is (0,1,0) transform it to world space by
  // by multiplying my camera->world (view) matrix inverse
  GLuint CamRight  = glGetUniformLocation(rain_shader_, "cam_right");
  GLuint CamUp  = glGetUniformLocation(rain_shader_, "cam_up");

  glUniform3f(CamRight, view_matrix[0][0], view_matrix[1][0], view_matrix[2][0]);
  glUniform3f(CamUp   , view_matrix[0][1], view_matrix[1][1], view_matrix[2][1]);

  glBindBuffer(GL_ARRAY_BUFFER, particle_instance_buffer_);
  glEnableVertexAttribArray(initialVerticesHandle);
  glVertexAttribPointer(initialVerticesHandle, 3, GL_FLOAT, GL_FALSE, 0, 0);

  glBindBuffer(GL_ARRAY_BUFFER, particle_position_buffer_);
  glEnableVertexAttribArray(positionsHandle);
  glVertexAttribPointer(positionsHandle, 3, GL_FLOAT, GL_FALSE, 0, 0);

  glBindBuffer(GL_ARRAY_BUFFER, particle_colour_buffer_);
  glEnableVertexAttribArray(colourHandle);
  glVertexAttribPointer(colourHandle, 4, GL_FLOAT, GL_FALSE, 0, 0);

  // Needed for instanced draws
  glVertexAttribDivisor(initialVerticesHandle, 0);    // Same every particle
  glVertexAttribDivisor(positionsHandle, 1);          // One per particle
  glVertexAttribDivisor(colourHandle, 1);             // One per particle

  // Equivalent to looping over all particles (with 4 vertices)
  glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, MAX_PARTICLES_);

  glDisable(GL_BLEND);

}

<|endoftext|>