<commit_before>/**
*
* License: Apache License 2.0
* Author: Dario Ostuni <another.code.996@gmail.com>
*
**/

#pragma once

#include <vector>
#include <queue>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <iostream>

namespace ostuni {

template<typename T>
class scapegoat;

template<typename T>
class _scapegoat_node
{
protected:
    unsigned tree_size;
    T value;
    int left_child;
    int right_child;
    int parent;
    void reset(const T& v = T())
    {
        tree_size = 1;
        value = v;
        left_child = -1;
        right_child = -1;
        parent = -1;
    }
    _scapegoat_node(const T& v)
    {
        reset(v);
    }
public:
    friend class scapegoat<T>;
};

template<typename T>
class scapegoat
{
protected:
    double a;
    std::vector<_scapegoat_node<T>> nodes;
    std::queue<int> unused_nodes;
    int root_node;
    unsigned max_size;
    int _find(const T& v, int node)
    {
        if(nodes[node].value == v)
            return node;
        if(v < nodes[node].value)
        {
            if(nodes[node].left_child == -1)
                return -1;
            return _find(v, nodes[node].left_child);
        }
        else
        {
            if(nodes[node].right_child == -1)
                return -1;
            return _find(v, nodes[node].right_child);
        }
    }
    int _get_node_size(int node)
    {
        if(node == -1)
            return 0;
        return nodes[node].tree_size;
    }
    int _find_scapegoat(int node)
    {
        if(node == root_node)
            return node;
        bool e1 = _get_node_size(nodes[node].left_child) <= a * _get_node_size(node);
        bool e2 = _get_node_size(nodes[node].right_child) <= a * _get_node_size(node);
        if(!(e1 && e2))
            return node;
        return _find_scapegoat(nodes[node].parent);
    }
    int _get_free_node(const T& v = T())
    {
        if(!unused_nodes.empty())
        {
            int tmp = unused_nodes.front();
            unused_nodes.pop();
            nodes[tmp].reset(v);
            return tmp;
        }
        else
        {
            nodes.push_back(_scapegoat_node<T>(v));
            return nodes.size() - 1;
        }
    }
    void _inorder(int node, std::vector<int>& v)
    {
        if(node == -1)
            return;
        _inorder(nodes[node].left_child, v);
        v.push_back(node);
        _inorder(nodes[node].right_child, v);
    }
    void _rr(int s, int e, std::vector<int>& r, int parent, bool left)
    {
        if(s == e)
            return;
        int m = (s + e) / 2;
        nodes[r[m]].left_child = -1;
        nodes[r[m]].right_child = -1;
        nodes[r[m]].parent = parent;
        nodes[r[m]].tree_size = e - s;
        if(parent == -1)
            root_node = r[m];
        if(left)
        {
            if(parent != -1)
                nodes[parent].left_child = r[m];
        }
        else
        {
            if(parent != -1)
                nodes[parent].right_child = r[m];
        }
        if(s == e - 1)
            return;
        _rr(s, m, r, r[m], true);
        _rr(m + 1, e, r, r[m], false);
    }
    void _rebalance(int node)
    {
        int scp = node;
        int scp_parent = nodes[node].parent;
        std::vector<int> rebalanced;
        _inorder(node, rebalanced);
        _rr(0, rebalanced.size(), rebalanced, scp_parent, scp == nodes[scp_parent].left_child);
    }
    void _insert(const T& v)
    {
        if(!nodes.size())
        {
            root_node = _get_free_node(v);
            return;
        }
        int node = root_node;
        int depth = 1;
        while(true)
        {
            nodes[node].tree_size++;
            if(v < nodes[node].value)
            {
                if(nodes[node].left_child == -1)
                {
                    int tmp = _get_free_node(v);
                    nodes[tmp].parent = node;
                    nodes[node].left_child = tmp;
                    break;
                }
                else
                {
                    node = nodes[node].left_child;
                }
            }
            else
            {
                if(nodes[node].right_child == -1)
                {
                    int tmp = _get_free_node(v);
                    nodes[tmp].parent = node;
                    nodes[node].right_child = tmp;
                    break;
                }
                else
                {
                    node = nodes[node].right_child;
                }
            }
            depth++;
        }
        bool balanced = depth <= ((log(nodes[root_node].tree_size) / log(1.0 / a)) + 1.0);
        if(balanced)
            return;
        int scp = _find_scapegoat(node);
        _rebalance(scp);
    }
    void _decrease(int node)
    {
        if(node == -1)
            return;
        nodes[node].tree_size--;
        _decrease(nodes[node].parent);
    }
    void _erase(int node)
    {
        if(nodes[node].left_child == -1 && nodes[node].right_child == -1)
        {
            int parent = nodes[node].parent;
            if(node == nodes[parent].left_child)
            {
                nodes[parent].left_child = -1;
            }
            else
            {
                nodes[parent].right_child = -1;
            }
            _decrease(parent);
            unused_nodes.push(node);
            bool balanced = nodes[root_node].tree_size <= a * max_size;
            if(!balanced)
            {
                _rebalance(root_node);
            }
            return;
        }
        else if(nodes[node].left_child != -1)
        {
            int rnode = nodes[node].left_child;
            while(nodes[rnode].right_child != -1)
                rnode = nodes[rnode].right_child;
            std::swap(nodes[rnode].value, nodes[node].value);
            _erase(rnode);
        }
        else
        {
            int rnode = nodes[node].right_child;
            while(nodes[rnode].left_child != -1)
                rnode = nodes[rnode].left_child;
            std::swap(nodes[rnode].value, nodes[node].value);
            _erase(rnode);
        }
    }
public:
    scapegoat(double balance_factor = 0.66)
    {
        assert(balance_factor > 0.5 && balance_factor < 1.0);
        a = balance_factor;
        root_node = -1;
        max_size = 0;
    }
    bool find(const T& v)
    {
        return nodes.size() && (_find(v, root_node) != -1);
    }
    bool insert(const T& v)
    {
        if(find(v))
            return false;
        _insert(v);
        max_size = std::max(max_size, nodes[root_node].tree_size);
        return true;
    }
    bool erase(const T& v)
    {
        if(!nodes.size())
            return false;
        int node = _find(v, root_node);
        if(node == -1)
            return false;
        _erase(node);
        if(nodes.size() == unused_nodes.size())
        {
            nodes.clear();
            while(!unused_nodes.empty())
                unused_nodes.pop();
        }
        return true;
    }
    size_t size()
    {
        if(nodes.size() == 0)
            return 0;
        return nodes[root_node].tree_size;
    }
};

}
<commit_msg>Fixed things<commit_after>/**
*
* License: Apache License 2.0
* Author: Dario Ostuni <another.code.996@gmail.com>
*
**/

#pragma once

#include <vector>
#include <queue>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <iostream>

namespace ostuni {

template<typename T>
class scapegoat;

template<typename T>
class _scapegoat_node
{
protected:
    unsigned tree_size;
    T value;
    int left_child;
    int right_child;
    int parent;
    void reset(const T& v = T())
    {
        tree_size = 1;
        value = v;
        left_child = -1;
        right_child = -1;
        parent = -1;
    }
    _scapegoat_node(const T& v)
    {
        reset(v);
    }
public:
    friend class scapegoat<T>;
};

template<typename T>
class scapegoat
{
protected:
    double a;
    std::vector<_scapegoat_node<T>> nodes;
    std::queue<int> unused_nodes;
    int root_node;
    unsigned max_size;
    int _find(const T& v, int node)
    {
        if(nodes[node].value == v)
            return node;
        if(v < nodes[node].value)
        {
            if(nodes[node].left_child == -1)
                return -1;
            return _find(v, nodes[node].left_child);
        }
        else
        {
            if(nodes[node].right_child == -1)
                return -1;
            return _find(v, nodes[node].right_child);
        }
    }
    int _get_node_size(int node)
    {
        if(node == -1)
            return 0;
        return nodes[node].tree_size;
    }
    int _find_scapegoat(int node)
    {
        if(node == root_node)
            return node;
        bool e1 = _get_node_size(nodes[node].left_child) <= a * _get_node_size(node);
        bool e2 = _get_node_size(nodes[node].right_child) <= a * _get_node_size(node);
        if(!(e1 && e2))
            return node;
        return _find_scapegoat(nodes[node].parent);
    }
    int _get_free_node(const T& v = T())
    {
        if(!unused_nodes.empty())
        {
            int tmp = unused_nodes.front();
            unused_nodes.pop();
            nodes[tmp].reset(v);
            return tmp;
        }
        else
        {
            nodes.push_back(_scapegoat_node<T>(v));
            return nodes.size() - 1;
        }
    }
    void _inorder(int node, std::vector<int>& v)
    {
        if(node == -1)
            return;
        _inorder(nodes[node].left_child, v);
        v.push_back(node);
        _inorder(nodes[node].right_child, v);
    }
    void _rr(int s, int e, std::vector<int>& r, int parent, bool left)
    {
        if(s == e)
            return;
        int m = (s + e) / 2;
        nodes[r[m]].left_child = -1;
        nodes[r[m]].right_child = -1;
        nodes[r[m]].parent = parent;
        nodes[r[m]].tree_size = e - s;
        if(parent == -1)
            root_node = r[m];
        if(left)
        {
            if(parent != -1)
                nodes[parent].left_child = r[m];
        }
        else
        {
            if(parent != -1)
                nodes[parent].right_child = r[m];
        }
        if(s == e - 1)
            return;
        _rr(s, m, r, r[m], true);
        _rr(m + 1, e, r, r[m], false);
    }
    void _rebalance(int node)
    {
        int scp = node;
        int scp_parent = nodes[node].parent;
        std::vector<int> rebalanced;
        _inorder(node, rebalanced);
        _rr(0, rebalanced.size(), rebalanced, scp_parent, scp == nodes[scp_parent].left_child);
    }
    void _insert(const T& v)
    {
        if(!nodes.size())
        {
            root_node = _get_free_node(v);
            return;
        }
        int node = root_node;
        int depth = 1;
        while(true)
        {
            nodes[node].tree_size++;
            if(v < nodes[node].value)
            {
                if(nodes[node].left_child == -1)
                {
                    int tmp = _get_free_node(v);
                    nodes[tmp].parent = node;
                    nodes[node].left_child = tmp;
                    break;
                }
                else
                {
                    node = nodes[node].left_child;
                }
            }
            else
            {
                if(nodes[node].right_child == -1)
                {
                    int tmp = _get_free_node(v);
                    nodes[tmp].parent = node;
                    nodes[node].right_child = tmp;
                    break;
                }
                else
                {
                    node = nodes[node].right_child;
                }
            }
            depth++;
        }
        bool balanced = depth <= ((log(nodes[root_node].tree_size) / log(1.0 / a)) + 1.0);
        if(balanced)
            return;
        int scp = _find_scapegoat(node);
        _rebalance(scp);
    }
    void _decrease(int node)
    {
        if(node == -1)
            return;
        nodes[node].tree_size--;
        _decrease(nodes[node].parent);
    }
    void _erase(int node)
    {
        if(nodes[node].left_child == -1 && nodes[node].right_child == -1)
        {
            int parent = nodes[node].parent;
            if(node == nodes[parent].left_child)
            {
                nodes[parent].left_child = -1;
            }
            else
            {
                nodes[parent].right_child = -1;
            }
            _decrease(parent);
            unused_nodes.push(node);
            bool balanced = nodes[root_node].tree_size > a * max_size;
            if(!balanced)
            {
                _rebalance(root_node);
                max_size = nodes[root_node].tree_size;
            }
            return;
        }
        else if(nodes[node].left_child != -1)
        {
            int rnode = nodes[node].left_child;
            while(nodes[rnode].right_child != -1)
                rnode = nodes[rnode].right_child;
            std::swap(nodes[rnode].value, nodes[node].value);
            _erase(rnode);
        }
        else
        {
            int rnode = nodes[node].right_child;
            while(nodes[rnode].left_child != -1)
                rnode = nodes[rnode].left_child;
            std::swap(nodes[rnode].value, nodes[node].value);
            _erase(rnode);
        }
    }
public:
    scapegoat(double balance_factor = 0.66)
    {
        assert(balance_factor > 0.5 && balance_factor < 1.0);
        a = balance_factor;
        root_node = -1;
        max_size = 0;
    }
    bool find(const T& v)
    {
        return nodes.size() && (_find(v, root_node) != -1);
    }
    bool insert(const T& v)
    {
        if(find(v))
            return false;
        _insert(v);
        max_size = std::max(max_size, nodes[root_node].tree_size);
        return true;
    }
    bool erase(const T& v)
    {
        if(!nodes.size())
            return false;
        int node = _find(v, root_node);
        if(node == -1)
            return false;
        _erase(node);
        if(nodes.size() == unused_nodes.size())
        {
            nodes.clear();
            while(!unused_nodes.empty())
                unused_nodes.pop();
        }
        return true;
    }
    size_t size()
    {
        if(nodes.size() == 0)
            return 0;
        return nodes[root_node].tree_size;
    }
};

}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "sparse_solver.h"

#include <Eigen/UmfPackSupport>

void test_umfpack_support()
{
  UmfPackLU<SparseMatrix<double, ColMajor> > umfpack_double_colmajor;
  UmfPackLU<SparseMatrix<std::complex<double> > > umfpack_cplxdouble_colmajor;
  CALL_SUBTEST_1(check_sparse_square_solving(umfpack_double_colmajor));
  CALL_SUBTEST_2(check_sparse_square_solving(umfpack_cplxdouble_colmajor));
  CALL_SUBTEST_1(check_sparse_square_determinant(umfpack_double_colmajor));
  CALL_SUBTEST_2(check_sparse_square_determinant(umfpack_cplxdouble_colmajor));
}
<commit_msg>extend umfpack support<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "sparse_solver.h"

#include <Eigen/UmfPackSupport>

template<typename T> void test_umfpack_support_T()
{
  UmfPackLU<SparseMatrix<T, ColMajor> > umfpack_colmajor;
  UmfPackLU<SparseMatrix<T, RowMajor> > umfpack_rowmajor;

  check_sparse_square_solving(umfpack_colmajor);
  check_sparse_square_solving(umfpack_rowmajor);

  check_sparse_square_determinant(umfpack_colmajor);
  check_sparse_square_determinant(umfpack_rowmajor);
}

void test_umfpack_support()
{
  CALL_SUBTEST_1(test_umfpack_support_T<double>());
  CALL_SUBTEST_2(test_umfpack_support_T<std::complex<double> >());
}

<|endoftext|>


<commit_before>/*************************************************************************
 * This file is part of the Gluon Development Platform
 *
 * Copyright (c) 2011 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "objecttreebuilder.h"

#include <core/gluonobject.h>
#include <core/gluonobjectfactory.h>
#include <core/debughelper.h>

#include <core/gdl/gdllexer.h>
#include <core/gdl/gdlparser.h>

#include <QtCore/QSizeF>
#include <QtGui/QColor>
#include <QtGui/QVector2D>
#include <QtGui/QVector3D>
#include <QtGui/QVector4D>
#include <QtGui/QQuaternion>

using namespace GDL;
using namespace GluonCore;

class ObjectTreeBuilder::Private
{
    public:
        struct Reference
        {
            GluonObject* object;
            QString property;
            QString type;
            QString path;
        };

        Private() : currentObject(0) { }

        QString textForToken(Lexer::Token token);
        QString stripQuotes(const QString& input);

        Lexer* lexer;
        QString content;

        QList<GluonObject*> objects;
        GluonObject* currentObject;
        GluonObject* project;
        QString currentPropertyName;
        QVariant currentPropertyValue;

        QList<Reference> references;
};

ObjectTreeBuilder::ObjectTreeBuilder(Lexer* lexer, const QString& content, GluonObject* project)
    : d(new Private)
{
    d->lexer = lexer;
    d->content = content;
    d->project = project;
}

ObjectTreeBuilder::~ObjectTreeBuilder()
{

}

QList< GluonObject* > ObjectTreeBuilder::objects()
{
    return d->objects;
}

void ObjectTreeBuilder::visitStart(StartAst* node)
{
    DefaultVisitor::visitStart(node);

    //Post-process references
    foreach( const Private::Reference& ref, d->references )
    {
        GluonObject* target = 0;
        foreach( GluonObject* object, d->objects )
        {
            target = object->findItemByName( ref.path );
            if( target )
                break;
        }

        if( !target )
        {
            ref.object->debug("Warning: Invalid reference for property %1", ref.property);
            continue;
        }

        ref.object->setProperty( ref.property.toUtf8(), GluonCore::GluonObjectFactory::instance()->wrapObject( ref.type, target ) );
    }

    //Allow subclasses to do their own post-processing as well
    foreach( GluonCore::GluonObject* object, d->objects )
    {
        object->sanitize();
    }
}

void ObjectTreeBuilder::visitObject(GDL::ObjectAst* node)
{
    GluonObject* newObject = GluonObjectFactory::instance()->instantiateObjectByName(d->textForToken(d->lexer->token(node->type)));

    if( !d->project )
    {
        d->project = newObject;
    }
    else
    {
        newObject->setGameProject( d->project );
    }

    newObject->setName( d->stripQuotes( d->textForToken( d->lexer->token( node->name ) ) ) );

    if(d->currentObject)
    {
        d->currentObject->addChild(newObject);
    }
    else
    {
        d->objects.append(newObject);
    }

    GluonObject* parent = d->currentObject;
    d->currentObject = newObject;

    GDL::DefaultVisitor::visitObject(node);

    d->currentObject = parent;
}

void ObjectTreeBuilder::visitProperty(GDL::PropertyAst* node)
{
    if(!d->currentObject)
    {
        qFatal("Cannot set properties on non-existing object");
        return;
    }

    d->currentPropertyName = d->textForToken(d->lexer->token(node->propertyName));

    GDL::DefaultVisitor::visitProperty(node);

    if(!d->currentPropertyValue.isNull())
    {
        d->currentObject->setProperty(d->currentPropertyName.toUtf8(), d->currentPropertyValue);
    }
}

void ObjectTreeBuilder::visitBoolean_type(GDL::Boolean_typeAst* node)
{
    Lexer::Token boolToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<bool>(boolToken.kind == Parser::Token_TRUE_VALUE);
}

void ObjectTreeBuilder::visitInteger_type(GDL::Integer_typeAst* node)
{
    Lexer::Token intToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<int>(d->textForToken(intToken).toInt());
}

void ObjectTreeBuilder::visitUnsigned_int_type(GDL::Unsigned_int_typeAst* node)
{
    Lexer::Token uintToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<uint>(d->textForToken(uintToken).toUInt());
}

void ObjectTreeBuilder::visitLong_long_type(GDL::Long_long_typeAst* node)
{
    Lexer::Token longToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<qlonglong>(d->textForToken(longToken).toLongLong());
}

void ObjectTreeBuilder::visitFloat_type(GDL::Float_typeAst* node)
{
    Lexer::Token floatToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<float>(d->textForToken(floatToken).toFloat());
}

void ObjectTreeBuilder::visitString_type(GDL::String_typeAst* node)
{
    Lexer::Token stringToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<QString>(d->textForToken(stringToken));
}

void ObjectTreeBuilder::visitUrl_type(GDL::Url_typeAst* node)
{
    Lexer::Token urlToken = d->lexer->token(node->path);
    d->currentPropertyValue = QVariant::fromValue<QUrl>(QUrl(d->textForToken(urlToken)));
}

void ObjectTreeBuilder::visitRgba_type(GDL::Rgba_typeAst* node)
{
    QColor color;
    Lexer::Token token = d->lexer->token(node->r);
    color.setRed(d->textForToken(token).toInt());
    token = d->lexer->token(node->g);
    color.setGreen(d->textForToken(token).toInt());
    token = d->lexer->token(node->b);
    color.setBlue(d->textForToken(token).toInt());
    token = d->lexer->token(node->a);
    color.setAlpha(d->textForToken(token).toInt());

    d->currentPropertyValue = QVariant::fromValue<QColor>(color);
}

void ObjectTreeBuilder::visitVector2d_type(GDL::Vector2d_typeAst* node)
{
    QVector2D vector;
    GDL::Lexer::Token token = d->lexer->token(node->x);
    vector.setX(d->textForToken(token).toFloat());
    token = d->lexer->token(node->y);
    vector.setY(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QVector2D>(vector);
}

void ObjectTreeBuilder::visitVector3d_type(GDL::Vector3d_typeAst* node)
{
    QVector3D vector;
    GDL::Lexer::Token token = d->lexer->token(node->x);
    vector.setX(d->textForToken(token).toFloat());
    token = d->lexer->token(node->y);
    vector.setY(d->textForToken(token).toFloat());
    token = d->lexer->token(node->z);
    vector.setZ(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QVector3D>(vector);
}

void ObjectTreeBuilder::visitVector4d_type(GDL::Vector4d_typeAst* node)
{
    QVector4D vector;
    GDL::Lexer::Token token = d->lexer->token(node->x);
    vector.setX(d->textForToken(token).toFloat());
    token = d->lexer->token(node->y);
    vector.setY(d->textForToken(token).toFloat());
    token = d->lexer->token(node->z);
    vector.setZ(d->textForToken(token).toFloat());
    token = d->lexer->token(node->w);
    vector.setW(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QVector4D>(vector);
}

void ObjectTreeBuilder::visitQuaternion_type(GDL::Quaternion_typeAst* node)
{
    QQuaternion quat;
    GDL::Lexer::Token token = d->lexer->token(node->x);
    quat.setX(d->textForToken(token).toFloat());
    token = d->lexer->token(node->y);
    quat.setY(d->textForToken(token).toFloat());
    token = d->lexer->token(node->z);
    quat.setZ(d->textForToken(token).toFloat());
    token = d->lexer->token(node->w);
    quat.setScalar(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QQuaternion>(quat);
}

void ObjectTreeBuilder::visitSize2d_type(GDL::Size2d_typeAst* node)
{
    QSizeF size;
    GDL::Lexer::Token token = d->lexer->token(node->width);
    size.setWidth(d->textForToken(token).toFloat());
    token = d->lexer->token(node->height);
    size.setHeight(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QSizeF>(size);
}

void ObjectTreeBuilder::visitObject_type(GDL::Object_typeAst* node)
{
    QString type = d->textForToken( d->lexer->token( node->type ) );
    QString reference = d->stripQuotes( d->textForToken( d->lexer->token( node->value ) ) );

    Private::Reference ref = { d->currentObject, d->currentPropertyName, type, reference };
    d->references.append( ref );

    d->currentPropertyValue = QVariant();
}

void ObjectTreeBuilder::visitList_type(GDL::List_typeAst* node)
{
    qDebug("TODO: Implement list type");
}

QString ObjectTreeBuilder::Private::textForToken(KDevPG::Token token)
{
    return content.mid(token.begin, token.end - token.begin + 1);
}

QString ObjectTreeBuilder::Private::stripQuotes(const QString& input)
{
    QString retval = input;
    if(retval.at(0) == '"')
        retval = retval.remove(0, 1);
    if(retval.at(retval.size() - 1) == '"')
        retval = retval.remove(retval.size() - 1, 1);
    return retval;
}
<commit_msg>Core: Update ObjectTreeBuilder to fix several issues with creating the tree of objects<commit_after>/*************************************************************************
 * This file is part of the Gluon Development Platform
 *
 * Copyright (c) 2011 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "objecttreebuilder.h"

#include <core/gluonobject.h>
#include <core/gluonobjectfactory.h>
#include <core/debughelper.h>

#include <core/gdl/gdllexer.h>
#include <core/gdl/gdlparser.h>

#include <QtCore/QSizeF>
#include <QtGui/QColor>
#include <QtGui/QVector2D>
#include <QtGui/QVector3D>
#include <QtGui/QVector4D>
#include <QtGui/QQuaternion>

using namespace GDL;
using namespace GluonCore;

class ObjectTreeBuilder::Private
{
    public:
        struct Reference
        {
            GluonObject* object;
            QString property;
            QString type;
            QString path;
        };

        Private() : currentObject(0) { }

        QString textForToken(Lexer::Token token);
        QString stripQuotes(const QString& input);

        Lexer* lexer;
        QString content;

        QList<GluonObject*> objects;
        GluonObject* currentObject;
        GluonObject* project;
        QString currentPropertyName;
        QVariant currentPropertyValue;

        QList<Reference> references;
};

ObjectTreeBuilder::ObjectTreeBuilder(Lexer* lexer, const QString& content, GluonObject* project)
    : d(new Private)
{
    d->lexer = lexer;
    d->content = content;
    d->project = project;
}

ObjectTreeBuilder::~ObjectTreeBuilder()
{

}

QList< GluonObject* > ObjectTreeBuilder::objects()
{
    return d->objects;
}

void ObjectTreeBuilder::visitStart(StartAst* node)
{
    DefaultVisitor::visitStart(node);

    //Post-process references
    foreach( const Private::Reference& ref, d->references )
    {
        GluonObject* target = 0;
        foreach( GluonObject* object, d->objects )
        {
            target = object->findItemByName( ref.path );
            if( target )
                break;
        }

        if( !target )
        {
            target = d->project->findItemByName( ref.path );

            if( !target )
            {
                ref.object->debug("Warning: Invalid reference for property %1", ref.property);
                continue;
            }
        }

        ref.object->setProperty( ref.property.toUtf8(), GluonCore::GluonObjectFactory::instance()->wrapObject( ref.type, target ) );
    }

    //Allow subclasses to do their own post-processing as well
    foreach( GluonCore::GluonObject* object, d->objects )
    {
        object->sanitize();
    }
}

void ObjectTreeBuilder::visitObject(GDL::ObjectAst* node)
{
    QString type = d->textForToken(d->lexer->token(node->type));
    GluonObject* newObject = GluonObjectFactory::instance()->instantiateObjectByName( type );
    if( !newObject )
    {
        return;
    }

    if( !d->project )
    {
        d->project = newObject;
    }
    else
    {
        newObject->setGameProject( d->project );
    }

    newObject->setName( d->stripQuotes( d->textForToken( d->lexer->token( node->name ) ) ) );

    if(d->currentObject)
    {
        d->currentObject->addChild(newObject);
    }
    else
    {
        d->objects.append(newObject);
    }

    GluonObject* parent = d->currentObject;
    d->currentObject = newObject;

    GDL::DefaultVisitor::visitObject(node);

    d->currentObject = parent;
}

void ObjectTreeBuilder::visitProperty(GDL::PropertyAst* node)
{
    if(!d->currentObject)
    {
        qFatal("Cannot set properties on non-existing object");
        return;
    }

    d->currentPropertyName = d->textForToken(d->lexer->token(node->propertyName));

    GDL::DefaultVisitor::visitProperty(node);

    if(!d->currentPropertyValue.isNull())
    {
        d->currentObject->setProperty(d->currentPropertyName.toUtf8(), d->currentPropertyValue);
    }
}

void ObjectTreeBuilder::visitBoolean_type(GDL::Boolean_typeAst* node)
{
    Lexer::Token boolToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<bool>(boolToken.kind == Parser::Token_TRUE_VALUE);
}

void ObjectTreeBuilder::visitInteger_type(GDL::Integer_typeAst* node)
{
    Lexer::Token intToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<int>(d->textForToken(intToken).toInt());
}

void ObjectTreeBuilder::visitUnsigned_int_type(GDL::Unsigned_int_typeAst* node)
{
    Lexer::Token uintToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<uint>(d->textForToken(uintToken).toUInt());
}

void ObjectTreeBuilder::visitLong_long_type(GDL::Long_long_typeAst* node)
{
    Lexer::Token longToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<qlonglong>(d->textForToken(longToken).toLongLong());
}

void ObjectTreeBuilder::visitFloat_type(GDL::Float_typeAst* node)
{
    Lexer::Token floatToken = d->lexer->token(node->value);
    d->currentPropertyValue = QVariant::fromValue<float>(d->textForToken(floatToken).toFloat());
}

void ObjectTreeBuilder::visitString_type(GDL::String_typeAst* node)
{
    QString stringValue = d->stripQuotes( d->textForToken( d->lexer->token(node->value) ) );
    d->currentPropertyValue = QVariant::fromValue<QString>( stringValue );
}

void ObjectTreeBuilder::visitUrl_type(GDL::Url_typeAst* node)
{
    QString stringValue = d->stripQuotes( d->textForToken( d->lexer->token( node->path ) ) );
    d->currentPropertyValue = QVariant::fromValue<QUrl>(QUrl( stringValue ) );
}

void ObjectTreeBuilder::visitRgba_type(GDL::Rgba_typeAst* node)
{
    QColor color;
    Lexer::Token token = d->lexer->token(node->r);
    color.setRed(d->textForToken(token).toInt());
    token = d->lexer->token(node->g);
    color.setGreen(d->textForToken(token).toInt());
    token = d->lexer->token(node->b);
    color.setBlue(d->textForToken(token).toInt());
    token = d->lexer->token(node->a);
    color.setAlpha(d->textForToken(token).toInt());

    d->currentPropertyValue = QVariant::fromValue<QColor>(color);
}

void ObjectTreeBuilder::visitVector2d_type(GDL::Vector2d_typeAst* node)
{
    QVector2D vector;
    GDL::Lexer::Token token = d->lexer->token(node->x);
    vector.setX(d->textForToken(token).toFloat());
    token = d->lexer->token(node->y);
    vector.setY(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QVector2D>(vector);
}

void ObjectTreeBuilder::visitVector3d_type(GDL::Vector3d_typeAst* node)
{
    QVector3D vector;
    GDL::Lexer::Token token = d->lexer->token(node->x);
    vector.setX(d->textForToken(token).toFloat());
    token = d->lexer->token(node->y);
    vector.setY(d->textForToken(token).toFloat());
    token = d->lexer->token(node->z);
    vector.setZ(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QVector3D>(vector);
}

void ObjectTreeBuilder::visitVector4d_type(GDL::Vector4d_typeAst* node)
{
    QVector4D vector;
    GDL::Lexer::Token token = d->lexer->token(node->x);
    vector.setX(d->textForToken(token).toFloat());
    token = d->lexer->token(node->y);
    vector.setY(d->textForToken(token).toFloat());
    token = d->lexer->token(node->z);
    vector.setZ(d->textForToken(token).toFloat());
    token = d->lexer->token(node->w);
    vector.setW(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QVector4D>(vector);
}

void ObjectTreeBuilder::visitQuaternion_type(GDL::Quaternion_typeAst* node)
{
    QQuaternion quat;
    GDL::Lexer::Token token = d->lexer->token(node->x);
    quat.setX(d->textForToken(token).toFloat());
    token = d->lexer->token(node->y);
    quat.setY(d->textForToken(token).toFloat());
    token = d->lexer->token(node->z);
    quat.setZ(d->textForToken(token).toFloat());
    token = d->lexer->token(node->w);
    quat.setScalar(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QQuaternion>(quat);
}

void ObjectTreeBuilder::visitSize2d_type(GDL::Size2d_typeAst* node)
{
    QSizeF size;
    GDL::Lexer::Token token = d->lexer->token(node->width);
    size.setWidth(d->textForToken(token).toFloat());
    token = d->lexer->token(node->height);
    size.setHeight(d->textForToken(token).toFloat());

    d->currentPropertyValue = QVariant::fromValue<QSizeF>(size);
}

void ObjectTreeBuilder::visitObject_type(GDL::Object_typeAst* node)
{
    QString type = d->textForToken( d->lexer->token( node->type ) );
    QString reference = d->stripQuotes( d->textForToken( d->lexer->token( node->value ) ) );

    Private::Reference ref = { d->currentObject, d->currentPropertyName, type, reference };
    d->references.append( ref );

    d->currentPropertyValue = QVariant();
}

void ObjectTreeBuilder::visitList_type(GDL::List_typeAst* node)
{
    qDebug("TODO: Implement list type");
}

QString ObjectTreeBuilder::Private::textForToken(KDevPG::Token token)
{
    return content.mid(token.begin, token.end - token.begin + 1);
}

QString ObjectTreeBuilder::Private::stripQuotes(const QString& input)
{
    QString retval = input;
    if(retval.at(0) == '"')
        retval = retval.remove(0, 1);
    if(retval.at(retval.size() - 1) == '"')
        retval = retval.remove(retval.size() - 1, 1);
    return retval;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2019 - 2021 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANNTY OF ANY KIND, EXPRESS OR
IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

// Simple test for hipLaunchCooperativeKernelMultiDevice API.

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS --std=c++11 -rdc=true -gencode arch=compute_70,code=sm_70 -gencode arch=compute_80,code=sm_80
 * TEST: %t
 * HIT_END
 */

#include "hip/hip_runtime.h"
#include "hip/hip_runtime_api.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
#include <chrono>
#include "hip/hip_cooperative_groups.h"
#include "test_common.h"

using namespace std::chrono;

const static uint BufferSizeInDwords = 256 * 1024 * 1024;
const static uint numQueues = 4;
const static uint numIter = 100;
constexpr uint NumKernelArgs = 4;
constexpr uint MaxGPUs = 8;

#include <stdio.h>

__global__ void test_gws(uint* buf, uint bufSize, long* tmpBuf, long* result)
{
    extern __shared__ long tmp[];
    uint groups = gridDim.x;
    uint group_id = blockIdx.x;
    uint local_id = threadIdx.x;
    uint chunk = gridDim.x * blockDim.x;

    uint i = group_id * blockDim.x + local_id;
    long sum = 0;
    while (i < bufSize) {
      sum += buf[i];
      i += chunk;
    }
    tmp[local_id] = sum;
    __syncthreads();
    i = 0;
    if (local_id == 0) {
        sum = 0;
        while (i < blockDim.x) {
          sum += tmp[i];
          i++;
        }
        tmpBuf[group_id] = sum;
    }

    // wait
    cooperative_groups::this_grid().sync();

    if (((blockIdx.x * blockDim.x) + threadIdx.x) == 0) {
        for (uint i = 1; i < groups; ++i) {
          sum += tmpBuf[i];
       }
       //*result = sum;
       result[1 + cooperative_groups::this_multi_grid().grid_rank()] = sum;
    }
    cooperative_groups::this_multi_grid().sync();
    if (cooperative_groups::this_multi_grid().grid_rank() == 0) {
      sum = 0;
      for (uint i = 1; i <= cooperative_groups::this_multi_grid().num_grids(); ++i) {
        sum += result[i];
      }
      *result = sum;
    }
}

int main() {
  float *A, *B;
  uint* dA[MaxGPUs];
  long* dB[MaxGPUs];
  long* dC;
  hipStream_t stream[MaxGPUs];

  uint32_t* init = new uint32_t[BufferSizeInDwords];
  for (uint32_t i = 0; i < BufferSizeInDwords; ++i) {
    init[i] = i;
  }

  int nGpu = 0;
  HIPCHECK(hipGetDeviceCount(&nGpu));
  size_t copySizeInDwords = BufferSizeInDwords / nGpu;
  hipDeviceProp_t deviceProp[MaxGPUs];

  for (int i = 0; i < nGpu; i++) {
    HIPCHECK(hipSetDevice(i));

    // Calculate the device occupancy to know how many blocks can be run concurrently
    hipGetDeviceProperties(&deviceProp[i], 0);
    if (!deviceProp[i].cooperativeMultiDeviceLaunch) {
      printf("Device doesn't support cooperative launch!");
      passed();
      return 0;
    }
    size_t SIZE = copySizeInDwords * sizeof(uint);

    HIPCHECK(hipMalloc((void**)&dA[i], SIZE));
    HIPCHECK(hipMalloc((void**)&dB[i], 64 * deviceProp[i].multiProcessorCount * sizeof(long)));
    if (i == 0) {
      HIPCHECK(hipHostMalloc((void**)&dC, (nGpu + 1) * sizeof(long)));
    }
    HIPCHECK(hipMemcpy(dA[i], &init[i * copySizeInDwords] , SIZE, hipMemcpyHostToDevice));
    HIPCHECK(hipStreamCreate(&stream[i]));
    hipDeviceSynchronize();
  }

  dim3 dimBlock;
  dim3 dimGrid;
  dimGrid.x = 1;
  dimGrid.y = 1;
  dimGrid.z = 1;
  dimBlock.x = 64;
  dimBlock.y = 1;
  dimBlock.z = 1;

  int numBlocks = 0;
  uint workgroups[3] = {64, 128, 256};

  hipLaunchParams* launchParamsList = new hipLaunchParams[nGpu];
  std::time_t end_time;
  double time = 0;
  for (uint set = 0; set < 3; ++set) {
    void* args[MaxGPUs * NumKernelArgs];
    std::cout << "---------- Test#" << set << ", size: "<< BufferSizeInDwords <<
      " dwords ---------------\n";
    for (int i = 0; i < nGpu; i++) {
      HIPCHECK(hipSetDevice(i));
      dimBlock.x = workgroups[set];
      HIPCHECK(hipOccupancyMaxActiveBlocksPerMultiprocessor(&numBlocks,
      test_gws, dimBlock.x * dimBlock.y * dimBlock.z, dimBlock.x * sizeof(long)));

      std::cout << "GPU(" << i << ") Block size: " << dimBlock.x <<
        " Num blocks per CU: " << numBlocks << "\n";

      dimGrid.x = deviceProp[i].multiProcessorCount * std::min(numBlocks, 32);

      args[i * NumKernelArgs]     = (void*)&dA[i];
      args[i * NumKernelArgs + 1] = (void*)&copySizeInDwords;
      args[i * NumKernelArgs + 2] = (void*)&dB[i];
      args[i * NumKernelArgs + 3] = (void*)&dC;

      launchParamsList[i].func = reinterpret_cast<void*>(test_gws);
      launchParamsList[i].gridDim = dimGrid;
      launchParamsList[i].blockDim = dimBlock;
      launchParamsList[i].sharedMem = dimBlock.x * sizeof(long);
      launchParamsList[i].stream = stream[i];
      launchParamsList[i].args = &args[i * NumKernelArgs];
    }

    system_clock::time_point start = system_clock::now();
    hipLaunchCooperativeKernelMultiDevice(launchParamsList, nGpu, 0);
    for (int i = 0; i < nGpu; i++) {
      hipStreamSynchronize(stream[i]);
    }
    system_clock::time_point end = system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end - start;
    end_time = std::chrono::system_clock::to_time_t(end);

    time += elapsed_seconds.count();

    size_t processedDwords = copySizeInDwords * nGpu;
    if (*dC != (((long)(processedDwords) * (processedDwords - 1)) / 2)) {
      std::cout << "Data validation failed ("<< *dC << " != " <<
        (((long)(BufferSizeInDwords) * (BufferSizeInDwords - 1)) / 2) <<
        ") for grid size = " << dimGrid.x << " and block size = " << dimBlock.x << "\n";
      std::cout << "Test failed! \n";
    }
  }

  delete [] launchParamsList;

  std::cout << "finished computation at " << std::ctime(&end_time) <<
    "elapsed time: " << time << "s\n";

  hipSetDevice(0);
  hipFree(dC);
  for (int i = 0; i < nGpu; i++) {
    hipFree(dA[i]);
    hipFree(dB[i]);
    HIPCHECK(hipStreamDestroy(stream[i]));
  }
  delete [] init;
  passed();
  return 0;
}
<commit_msg>SWDEV-312700 - Fixing memory corruption at the test. (#3026)<commit_after>/*
Copyright (c) 2019 - 2021 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANNTY OF ANY KIND, EXPRESS OR
IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

// Simple test for hipLaunchCooperativeKernelMultiDevice API.

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS --std=c++11 -rdc=true -gencode arch=compute_70,code=sm_70 -gencode arch=compute_80,code=sm_80
 * TEST: %t
 * HIT_END
 */

#include "hip/hip_runtime.h"
#include "hip/hip_runtime_api.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
#include <chrono>
#include "hip/hip_cooperative_groups.h"
#include "test_common.h"

using namespace std::chrono;

const static uint BufferSizeInDwords = 256 * 1024 * 1024;
const static uint numQueues = 4;
const static uint numIter = 100;
constexpr uint NumKernelArgs = 4;

#include <stdio.h>

__global__ void test_gws(uint* buf, uint bufSize, long* tmpBuf, long* result)
{
    extern __shared__ long tmp[];
    uint groups = gridDim.x;
    uint group_id = blockIdx.x;
    uint local_id = threadIdx.x;
    uint chunk = gridDim.x * blockDim.x;

    uint i = group_id * blockDim.x + local_id;
    long sum = 0;
    while (i < bufSize) {
      sum += buf[i];
      i += chunk;
    }
    tmp[local_id] = sum;
    __syncthreads();
    i = 0;
    if (local_id == 0) {
        sum = 0;
        while (i < blockDim.x) {
          sum += tmp[i];
          i++;
        }
        tmpBuf[group_id] = sum;
    }

    // wait
    cooperative_groups::this_grid().sync();

    if (((blockIdx.x * blockDim.x) + threadIdx.x) == 0) {
        for (uint i = 1; i < groups; ++i) {
          sum += tmpBuf[i];
       }
       //*result = sum;
       result[1 + cooperative_groups::this_multi_grid().grid_rank()] = sum;
    }
    cooperative_groups::this_multi_grid().sync();
    if (cooperative_groups::this_multi_grid().grid_rank() == 0) {
      sum = 0;
      for (uint i = 1; i <= cooperative_groups::this_multi_grid().num_grids(); ++i) {
        sum += result[i];
      }
      *result = sum;
    }
}

int main() {
  float *A, *B;
  long* dC;

  uint32_t* init = new uint32_t[BufferSizeInDwords];
  for (uint32_t i = 0; i < BufferSizeInDwords; ++i) {
    init[i] = i;
  }

  int nGpu = 0;
  HIPCHECK(hipGetDeviceCount(&nGpu));
  size_t copySizeInDwords = BufferSizeInDwords / nGpu;

  uint* dA[nGpu];
  long* dB[nGpu];
  hipStream_t stream[nGpu];
  hipDeviceProp_t deviceProp[nGpu];

  for (int i = 0; i < nGpu; i++) {
    HIPCHECK(hipSetDevice(i));

    // Calculate the device occupancy to know how many blocks can be run concurrently
    hipGetDeviceProperties(&deviceProp[i], 0);
    if (!deviceProp[i].cooperativeMultiDeviceLaunch) {
      printf("Device doesn't support cooperative launch!");
      passed();
      return 0;
    }
    size_t SIZE = copySizeInDwords * sizeof(uint);

    HIPCHECK(hipMalloc((void**)&dA[i], SIZE));
    HIPCHECK(hipMalloc((void**)&dB[i], 64 * deviceProp[i].multiProcessorCount * sizeof(long)));
    if (i == 0) {
      HIPCHECK(hipHostMalloc((void**)&dC, (nGpu + 1) * sizeof(long)));
    }
    HIPCHECK(hipMemcpy(dA[i], &init[i * copySizeInDwords] , SIZE, hipMemcpyHostToDevice));
    HIPCHECK(hipStreamCreate(&stream[i]));
    hipDeviceSynchronize();
  }

  dim3 dimBlock;
  dim3 dimGrid;
  dimGrid.x = 1;
  dimGrid.y = 1;
  dimGrid.z = 1;
  dimBlock.x = 64;
  dimBlock.y = 1;
  dimBlock.z = 1;

  int numBlocks = 0;
  uint workgroups[3] = {64, 128, 256};

  hipLaunchParams* launchParamsList = new hipLaunchParams[nGpu];
  std::time_t end_time;
  double time = 0;
  for (uint set = 0; set < 3; ++set) {
    void* args[nGpu * NumKernelArgs];
    std::cout << "---------- Test#" << set << ", size: "<< BufferSizeInDwords <<
      " dwords ---------------\n";
    for (int i = 0; i < nGpu; i++) {
      HIPCHECK(hipSetDevice(i));
      dimBlock.x = workgroups[set];
      HIPCHECK(hipOccupancyMaxActiveBlocksPerMultiprocessor(&numBlocks,
      test_gws, dimBlock.x * dimBlock.y * dimBlock.z, dimBlock.x * sizeof(long)));

      std::cout << "GPU(" << i << ") Block size: " << dimBlock.x <<
        " Num blocks per CU: " << numBlocks << "\n";

      dimGrid.x = deviceProp[i].multiProcessorCount * std::min(numBlocks, 32);

      args[i * NumKernelArgs]     = (void*)&dA[i];
      args[i * NumKernelArgs + 1] = (void*)&copySizeInDwords;
      args[i * NumKernelArgs + 2] = (void*)&dB[i];
      args[i * NumKernelArgs + 3] = (void*)&dC;

      launchParamsList[i].func = reinterpret_cast<void*>(test_gws);
      launchParamsList[i].gridDim = dimGrid;
      launchParamsList[i].blockDim = dimBlock;
      launchParamsList[i].sharedMem = dimBlock.x * sizeof(long);
      launchParamsList[i].stream = stream[i];
      launchParamsList[i].args = &args[i * NumKernelArgs];
    }

    system_clock::time_point start = system_clock::now();
    hipLaunchCooperativeKernelMultiDevice(launchParamsList, nGpu, 0);
    for (int i = 0; i < nGpu; i++) {
      hipStreamSynchronize(stream[i]);
    }
    system_clock::time_point end = system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end - start;
    end_time = std::chrono::system_clock::to_time_t(end);

    time += elapsed_seconds.count();

    size_t processedDwords = copySizeInDwords * nGpu;
    if (*dC != (((long)(processedDwords) * (processedDwords - 1)) / 2)) {
      std::cout << "Data validation failed ("<< *dC << " != " <<
        (((long)(BufferSizeInDwords) * (BufferSizeInDwords - 1)) / 2) <<
        ") for grid size = " << dimGrid.x << " and block size = " << dimBlock.x << "\n";
      std::cout << "Test failed! \n";
    }
  }

  delete [] launchParamsList;

  std::cout << "finished computation at " << std::ctime(&end_time) <<
    "elapsed time: " << time << "s\n";

  hipSetDevice(0);
  hipFree(dC);
  for (int i = 0; i < nGpu; i++) {
    hipFree(dA[i]);
    hipFree(dB[i]);
    HIPCHECK(hipStreamDestroy(stream[i]));
  }

  delete [] init;
  passed();
  return 0;
}
<|endoftext|>


<commit_before>
#include "../MultiTokenizer.h"
#include "../Stemmer.h"

#include <phpcpp.h>

using namespace std;

enum {
	DISKERROR_STEM_RETURN_ARRAY = 1,
	DISKERROR_STEM_RETURN_BIGRAM
};

Php::Value stem(Php::Parameters &params)
{
    static MultiTokenizer tokenizer;

    string p = params[0];
	tokenizer.SetText(p);
	int prefs = 0;

	if ( params.size() > 1 ) {
		prefs = (long) params[1];
	}

	string outputText, token, thisOne, lastOne;
	Php::Array outputArray;
	int i = 0;
	Php::Value outputData;

    switch ( prefs ) {
    	case 0:
		while( (token = tokenizer.Get()) != "" ) {
			outputText += Stemmer::StemWord(token) + " ";
		}

		if ( outputText.size() ) {
			outputText.pop_back();	//	remove extra space at end if not empty
		}

		outputData = outputText;
    	break;

    	case DISKERROR_STEM_RETURN_ARRAY:
		while( (token = tokenizer.Get()) != "" ) {
			outputArray[i++] = Stemmer::StemWord(token);
		}
		outputData = outputArray;
    	break;

    	case DISKERROR_STEM_RETURN_BIGRAM:
		while( (token = tokenizer.Get()) != "" ) {
			thisOne = Stemmer::StemWord(token);
			outputText += (lastOne + thisOne + " ");
			lastOne = thisOne;
		}
		outputText += lastOne;
		outputData = outputText;
    	break;

    	case DISKERROR_STEM_RETURN_ARRAY|DISKERROR_STEM_RETURN_BIGRAM:
		while( (token = tokenizer.Get()) != "" ) {
			thisOne = Stemmer::StemWord(token);
			outputArray[i++] = (lastOne + thisOne);
			lastOne = thisOne;
		}
		outputArray[i] = lastOne;
		outputData = outputArray;
    	break;
    }

    return outputData;
}

extern "C" {

    /**
     *  Function that is called by PHP right after the PHP process
     *  has started, and that returns an address of an internal PHP
     *  strucure with all the details and features of your extension
     *
     *  @return void*   a pointer to an address that is understood by PHP
     */
    PHPCPP_EXPORT void *get_module()
    {
        // static(!) Php::Extension object that should stay in memory
        // for the entire duration of the process (that's why it's static)
        static Php::Extension extension("diskerror_stem", "0.3");

        extension.add(Php::Constant("DISKERROR_STEM_RETURN_ARRAY", DISKERROR_STEM_RETURN_ARRAY));
        extension.add(Php::Constant("DISKERROR_STEM_RETURN_BIGRAM", DISKERROR_STEM_RETURN_BIGRAM));

//        extension.add( "Diskerror\\Stem", stem, {
//        	Php::ByVal("subject", Php::Type::String),
//        	Php::ByVal("options", Php::Type::Numeric, false)
//        } );
		extension.add<stem>( "Diskerror\\Stem" );

        // return the extension
        return extension;
    }
}
<commit_msg>version bump<commit_after>
#include "../MultiTokenizer.h"
#include "../Stemmer.h"

#include <phpcpp.h>

using namespace std;

enum {
	DISKERROR_STEM_RETURN_ARRAY = 1,
	DISKERROR_STEM_RETURN_BIGRAM
};

Php::Value stem(Php::Parameters &params)
{
    static MultiTokenizer tokenizer;

    string p = params[0];
	tokenizer.SetText(p);
	int prefs = 0;

	if ( params.size() > 1 ) {
		prefs = (long) params[1];
	}

	string outputText, token, thisOne, lastOne;
	Php::Array outputArray;
	int i = 0;
	Php::Value outputData;

    switch ( prefs ) {
    	case 0:
		while( (token = tokenizer.Get()) != "" ) {
			outputText += Stemmer::StemWord(token) + " ";
		}

		if ( outputText.size() ) {
			outputText.pop_back();	//	remove extra space at end if not empty
		}

		outputData = outputText;
    	break;

    	case DISKERROR_STEM_RETURN_ARRAY:
		while( (token = tokenizer.Get()) != "" ) {
			outputArray[i++] = Stemmer::StemWord(token);
		}
		outputData = outputArray;
    	break;

    	case DISKERROR_STEM_RETURN_BIGRAM:
		while( (token = tokenizer.Get()) != "" ) {
			thisOne = Stemmer::StemWord(token);
			outputText += (lastOne + thisOne + " ");
			lastOne = thisOne;
		}
		outputText += lastOne;
		outputData = outputText;
    	break;

    	case DISKERROR_STEM_RETURN_ARRAY|DISKERROR_STEM_RETURN_BIGRAM:
		while( (token = tokenizer.Get()) != "" ) {
			thisOne = Stemmer::StemWord(token);
			outputArray[i++] = (lastOne + thisOne);
			lastOne = thisOne;
		}
		outputArray[i] = lastOne;
		outputData = outputArray;
    	break;
    }

    return outputData;
}

extern "C" {

    /**
     *  Function that is called by PHP right after the PHP process
     *  has started, and that returns an address of an internal PHP
     *  strucure with all the details and features of your extension
     *
     *  @return void*   a pointer to an address that is understood by PHP
     */
    PHPCPP_EXPORT void *get_module()
    {
        // static(!) Php::Extension object that should stay in memory
        // for the entire duration of the process (that's why it's static)
        static Php::Extension extension("diskerror_stem", "0.4");

        extension.add(Php::Constant("DISKERROR_STEM_RETURN_ARRAY", DISKERROR_STEM_RETURN_ARRAY));
        extension.add(Php::Constant("DISKERROR_STEM_RETURN_BIGRAM", DISKERROR_STEM_RETURN_BIGRAM));

//        extension.add( "Diskerror\\Stem", stem, {
//        	Php::ByVal("subject", Php::Type::String),
//        	Php::ByVal("options", Php::Type::Numeric, false)
//        } );
		extension.add<stem>( "Diskerror\\Stem" );

        // return the extension
        return extension;
    }
}
<|endoftext|>


<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Base class for a tire.
// A tire subsystem is a force element. It is passed position and velocity
// information of the wheel body and it produces ground reaction forces and
// moments to be applied to the wheel body.
//
// =============================================================================

#include "core/ChMatrix33.h"

#include "subsys/ChTire.h"

namespace chrono {

ChTire::ChTire(const ChTerrain& terrain)
: m_terrain(terrain)
{
}

// -----------------------------------------------------------------------------
// Utility function for characterizing the geometric contact between a disc with
// specified center location, normal direction, and radius and the terrain,
// assumed to be specified as a height field (over the x-y domain).
// This function returns false if no contact occurs. Otherwise, it sets the
// contact points on the disc (ptD) and on the terrain (ptT), the normal contact
// direction, and the resulting penetration depth (a positive value).
// -----------------------------------------------------------------------------
bool ChTire::disc_terrain_contact(const ChVector<>& disc_center,
                                  const ChVector<>& disc_normal,
                                  double            disc_radius,
                                  ChCoordsys<>&     contact,
                                  double&           depth)
{
  // Find terrain height below disc center. There is no contact if the disc
  // center is below the terrain or farther away by more than its radius.
  double hc = m_terrain.GetHeight(disc_center.x, disc_center.y);
  if (disc_center.z <= hc || disc_center.z >= hc + disc_radius)
    return false;

  // Find the lowest point on the disc. There is no contact if the disc is
  // (almost) horizontal.
  ChVector<> dir1 = Vcross(disc_normal, ChVector<>(0, 0, 1));
  double sinTilt2 = dir1.Length2();

  if (sinTilt2 < 1e-3)
    return false;

  // Contact point (lowest point on disc).
  ChVector<> ptD = disc_center + disc_radius * Vcross(disc_normal, dir1 / sqrt(sinTilt2));

  // Find terrain height at lowest point. No contact if lowest point is above
  // the terrain.
  double hp = m_terrain.GetHeight(ptD.x, ptD.y);

  if (ptD.z > hp)
    return false;

  // Approximate the terrain with a plane. Define the projection of the lowest
  // point onto this plane as the contact point on the terrain.
  ChVector<> normal = m_terrain.GetNormal(ptD.x, ptD.y);
  ChVector<> longitudinal = Vcross(disc_normal, normal);
  longitudinal.Normalize();
  ChVector<> lateral = Vcross(normal, longitudinal);
  ChMatrix33<> rot;
  rot.Set_A_axis(longitudinal, lateral, normal);

  contact.pos = ptD;
  contact.rot = rot.Get_A_quaternion();

  depth = Vdot(ChVector<>(0, 0, hp - ptD.z), normal);
  assert(depth > 0);

  return true;
}

}  // end namespace chrono
<commit_msg>fixes a linking error for compiling with VS 2012<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Base class for a tire.
// A tire subsystem is a force element. It is passed position and velocity
// information of the wheel body and it produces ground reaction forces and
// moments to be applied to the wheel body.
//
// =============================================================================

#include "physics/ChSystem.h"

#include "subsys/ChTire.h"

namespace chrono {

ChTire::ChTire(const ChTerrain& terrain)
: m_terrain(terrain)
{
}

// -----------------------------------------------------------------------------
// Utility function for characterizing the geometric contact between a disc with
// specified center location, normal direction, and radius and the terrain,
// assumed to be specified as a height field (over the x-y domain).
// This function returns false if no contact occurs. Otherwise, it sets the
// contact points on the disc (ptD) and on the terrain (ptT), the normal contact
// direction, and the resulting penetration depth (a positive value).
// -----------------------------------------------------------------------------
bool ChTire::disc_terrain_contact(const ChVector<>& disc_center,
                                  const ChVector<>& disc_normal,
                                  double            disc_radius,
                                  ChCoordsys<>&     contact,
                                  double&           depth)
{
  // Find terrain height below disc center. There is no contact if the disc
  // center is below the terrain or farther away by more than its radius.
  double hc = m_terrain.GetHeight(disc_center.x, disc_center.y);
  if (disc_center.z <= hc || disc_center.z >= hc + disc_radius)
    return false;

  // Find the lowest point on the disc. There is no contact if the disc is
  // (almost) horizontal.
  ChVector<> dir1 = Vcross(disc_normal, ChVector<>(0, 0, 1));
  double sinTilt2 = dir1.Length2();

  if (sinTilt2 < 1e-3)
    return false;

  // Contact point (lowest point on disc).
  ChVector<> ptD = disc_center + disc_radius * Vcross(disc_normal, dir1 / sqrt(sinTilt2));

  // Find terrain height at lowest point. No contact if lowest point is above
  // the terrain.
  double hp = m_terrain.GetHeight(ptD.x, ptD.y);

  if (ptD.z > hp)
    return false;

  // Approximate the terrain with a plane. Define the projection of the lowest
  // point onto this plane as the contact point on the terrain.
  ChVector<> normal = m_terrain.GetNormal(ptD.x, ptD.y);
  ChVector<> longitudinal = Vcross(disc_normal, normal);
  longitudinal.Normalize();
  ChVector<> lateral = Vcross(normal, longitudinal);
  ChMatrix33<> rot;
  rot.Set_A_axis(longitudinal, lateral, normal);

  contact.pos = ptD;
  contact.rot = rot.Get_A_quaternion();

  depth = Vdot(ChVector<>(0, 0, hp - ptD.z), normal);
  assert(depth > 0);

  return true;
}

}  // end namespace chrono
<|endoftext|>


<commit_before>// Copyright (c) 2014 The Caroline authors. All rights reserved.
// Use of this source file is governed by a MIT license that can be found in the
// LICENSE file.
// Author: Aleksandr Derbenev <13alexac@gmail.com>

#include "core/optical_flow_processor.h"

#include <string>

#include "base/values.h"
#include "core/config.h"

namespace core {

namespace {

const char kOpticalFlowNode[] = "optical-flow";
const char kAlgorithmNameNode[] = "algorithm";
const char kLucasKanadeAlgorithmName[] = "lucas-kanade";
const char kFarnebackAlgorithmName[] = "farneback";

}  // namespace

// static
std::unique_ptr<OpticalFlowProcessor>
OpticalFlowProcessor::Create(const Config* config) {
  if (!config)
    return std::unique_ptr<OpticalFlowProcessor>();

  auto dictionary = config->dictionary();
  if (!dictionary)
    return std::unique_ptr<OpticalFlowProcessor>();

  auto settings =
      base::ToDictionary(dictionary->GetValue(kOpticalFlowNode));
  if (!settings)
    return std::unique_ptr<OpticalFlowProcessor>();

  auto algorithm_node = base::ToString(settings->GetValue(kAlgorithmNameNode));
  if (algorithm_node) {
    std::string algorithm_name = algorithm_node->value();

    if (kLucasKanadeAlgorithmName == algorithm_name) {
      // return LucasKanadeOpticalFrowProcessor::Create(settings);
    }

    if (kFarnebackAlgorithmName == algorithm_name) {
      // return FarnebackOpticalFlowProcessor::Create(settings);
    }
  }

  // There is no matched algorithm. Return empty pointer.
  return std::unique_ptr<OpticalFlowProcessor>();
}

}  // namespace core
<commit_msg>#46: Enabled FarnebackOpticalFlowProcessor<commit_after>// Copyright (c) 2014 The Caroline authors. All rights reserved.
// Use of this source file is governed by a MIT license that can be found in the
// LICENSE file.
// Author: Aleksandr Derbenev <13alexac@gmail.com>

#include "core/optical_flow_processor.h"

#include <string>

#include "core/farneback_optical_flow_processor.h"

#include "base/values.h"
#include "core/config.h"

namespace core {

namespace {

const char kOpticalFlowNode[] = "optical-flow";
const char kAlgorithmNameNode[] = "algorithm";
const char kLucasKanadeAlgorithmName[] = "lucas-kanade";
const char kFarnebackAlgorithmName[] = "farneback";

}  // namespace

// static
std::unique_ptr<OpticalFlowProcessor>
OpticalFlowProcessor::Create(const Config* config) {
  if (!config)
    return std::unique_ptr<OpticalFlowProcessor>();

  auto dictionary = config->dictionary();
  if (!dictionary)
    return std::unique_ptr<OpticalFlowProcessor>();

  auto settings =
      base::ToDictionary(dictionary->GetValue(kOpticalFlowNode));
  if (!settings)
    return std::unique_ptr<OpticalFlowProcessor>();

  auto algorithm_node = base::ToString(settings->GetValue(kAlgorithmNameNode));
  if (algorithm_node) {
    std::string algorithm_name = algorithm_node->value();

    if (kLucasKanadeAlgorithmName == algorithm_name) {
      // return LucasKanadeOpticalFrowProcessor::Create(settings);
    }

    if (kFarnebackAlgorithmName == algorithm_name) {
      return FarnebackOpticalFlowProcessor::Create(settings);
    }
  }

  // There is no matched algorithm. Return empty pointer.
  return std::unique_ptr<OpticalFlowProcessor>();
}

}  // namespace core
<|endoftext|>


<commit_before>/*! \file Mesh.cpp
 *  \author Jared Hoberock
 *  \brief Implementation of Mesh class.
 */

#include "Mesh.h"
#include "../geometry/Normal.h"
#include <2dmapping/UnitSquareToTriangle.h>

Mesh
  ::Mesh(const std::vector<Point> &vertices,
         const std::vector<Triangle> &triangles)
     :Parent0(vertices,triangles),Parent1()
{
  buildWaldBikkerData();
  buildTree();
  buildTriangleTable();
  mSurfaceArea = computeSurfaceArea();
  mOneOverSurfaceArea = 1.0f / mSurfaceArea;
} // end Mesh::Mesh()

Mesh
  ::Mesh(const std::vector<Point> &vertices,
         const std::vector<ParametricCoordinates> &parametrics,
         const std::vector<Triangle> &triangles)
    :Parent0(vertices,parametrics,triangles),Parent1()
{
  buildWaldBikkerData();
  buildTree();
  buildTriangleTable();
  mSurfaceArea = computeSurfaceArea();
  mOneOverSurfaceArea = 1.0f / mSurfaceArea;
} // end Mesh::Mesh()

Mesh
  ::~Mesh(void)
{
  ;
} // end Mesh::~Mesh()

bool Mesh
  ::intersect(const Ray &r) const
{
  // create a TriangleShadower
  TriangleShadower shadower = {this};
  return mTree.shadow(r.getAnchor(), r.getDirection(), r.getInterval()[0], r.getInterval()[1], shadower);
} // end Mesh::intersect()

bool Mesh
  ::intersect(const Ray &r, float &t, DifferentialGeometry &dg) const
{
  // create a TriangleIntersector
  TriangleIntersector intersector;
  intersector.init();
  intersector.mMesh = this;

  if(mTree.intersect(r.getAnchor(), r.getDirection(),
                     r.getInterval()[0], r.getInterval()[1],
                     intersector))
  {
    t = intersector.mT;
    const Triangle &tri = *intersector.mHitFace;

    // fill out DifferentialGeometry details
    Vector3 e1 = mPoints[tri[1]] - mPoints[tri[0]];
    Vector3 e2 = mPoints[tri[2]] - mPoints[tri[0]];
    getDifferentialGeometry(tri, r(t), e1.cross(e2).normalize(),
                            intersector.mBarycentricCoordinates[0],
                            intersector.mBarycentricCoordinates[1],
                            dg);
    return true;
  } // end if

  return false;
} // end Mesh::intersect()

float Mesh::TriangleBounder
  ::operator()(unsigned int axis, bool min, const Triangle *t)
{
  float result = std::numeric_limits<float>::infinity();
  if(!min) result = -result;

  // iterate through each adjacent vertex & pick the minimal/maximal
  const PointList &points = mMesh->getPoints();

  for(unsigned int i = 0; i < 3; ++i)
  {
    const Point &pos = points[(*t)[i]];

    if(min)
    {
      if(pos[axis] < result) result = pos[axis];
    } // end if
    else
    {
      if(pos[axis] > result) result = pos[axis];
    } // end else
  } // end for i

  return result;
} // end Mesh::TriangleBounder::operator()()

void Mesh
  ::getBoundingBox(BoundingBox &b) const
{
  b.setEmpty();

  // iterate over positions
  for(PointList::const_iterator p = getPoints().begin();
      p != getPoints().end();
      ++p)
  {
    b.addPoint(*p);
  } // end for p
} // end Mesh::getBoundingBox()

void Mesh
  ::buildTree(void)
{
  TriangleBounder bounder;
  bounder.mMesh = this;

  std::vector<const Triangle*> trianglePointers;
  for(TriangleList::const_iterator t = getTriangles().begin();
      t != getTriangles().end();
      ++t)
  {
    trianglePointers.push_back(&(*t));
  } // end for t

  mTree.buildTree(trianglePointers.begin(), trianglePointers.end(), bounder);
} // end Mesh::buildTree()

void Mesh
  ::getDifferentialGeometry(const Triangle &tri,
                            const Point &p,
                            const Normal &ng,
                            const float b1,
                            const float b2,
                            DifferentialGeometry &dg) const
{
  // shorthand
  const Point &p1 = mPoints[tri[0]];
  const Point &p2 = mPoints[tri[1]];
  const Point &p3 = mPoints[tri[2]];

  Vector e1 = p2 - p1;
  Vector e2 = p3 - p1;

  // compute the last barycentric coordinate
  float b0 = 1.0f - b1 - b2;

  // interpolate normal?
  //if(f[0].mNormalIndex == -1 ||
  //   f[1].mNormalIndex == -1 ||
  //   f[2].mNormalIndex == -1)
  //{
  //} // end if
  //else
  //{
  //  // get each vertex's Normals
  //  const Mesh::NormalList &norms = m.getNormals();
  //  const Normal &n1 = norms[f[0].mNormalIndex];
  //  const Normal &n2 = norms[f[1].mNormalIndex];
  //  const Normal &n3 = norms[f[2].mNormalIndex];
  //  n = b0 * n1 + b1 * n2 + b2 * n3;
  //} // end else

  // normalize it
  //dg.getNormal() = dg.getNormal().normalize();

  ParametricCoordinates uv0;
  ParametricCoordinates uv1;
  ParametricCoordinates uv2;
  getParametricCoordinates(tri, uv0, uv1, uv2);

  // compute deltas for partial derivatives
  float du1 = uv0[0] - uv2[0];
  float du2 = uv1[0] - uv2[0];
  float dv1 = uv0[1] - uv2[1];
  float dv2 = uv1[1] - uv2[1];
  Vector dp1 = p1 - p3, dp2 = p2 - p3;
  float determinant = du1 * dv2 - dv1 * du2;
  if(determinant == 0.0)
  {
    // handle zero determinant case
    dg.getPointPartials()[0] = ng.orthogonalVector();
    dg.getPointPartials()[1] = ng.cross(dg.getPointPartials()[0]).normalize();
  } // end if
  else
  {
    float invDet = 1.0f / determinant;
    dg.getPointPartials()[0] = ( dv2*dp1 - dv1*dp2) * invDet;
    dg.getPointPartials()[1] = (-du2*dp1 + du1*dp2) * invDet;
  } // end else

  // interpolate uv using barycentric coordinates
  ParametricCoordinates uv;
  uv[0] = b0*uv0[0] + b1*uv1[0] + b2*uv2[0];
  uv[1] = b0*uv0[1] + b1*uv1[1] + b2*uv2[1];

  dg.setPoint(p);
  dg.setNormal(ng);
  dg.setParametricCoordinates(uv);
  dg.setTangent(dg.getPointPartials()[0].normalize());

  // force an orthonormal basis
  dg.setBinormal(ng.cross(dg.getTangent()));
} // end Mesh::getDifferentialGeometry()

void Mesh::TriangleIntersector
  ::init(void)
{
  mT = std::numeric_limits<float>::infinity();
  mHitFace = 0;
  mMesh = 0;
} // end TriangleIntersector::init()

void Mesh
  ::buildTriangleTable(void)
{
  std::vector<const Triangle*> pointers;
  std::vector<float> area;
  for(TriangleList::const_iterator t = mTriangles.begin();
      t != mTriangles.end();
      ++t)
  {
    pointers.push_back(&(*t));
    area.push_back(Parent0::computeSurfaceArea(*t));
  } // end for t

  mTriangleTable.build(pointers.begin(), pointers.end(),
                       area.begin(), area.end());
} // end Mesh::buildTriangleTable()

float Mesh
  ::computeSurfaceArea(void) const
{
  float result = 0;

  for(TriangleList::const_iterator t = mTriangles.begin();
      t != mTriangles.end();
      ++t)
  {
    result += Parent0::computeSurfaceArea(*t);
  } // end for t

  return result;
} // end Mesh::computeSurfaceArea()

void Mesh
  ::sampleSurfaceArea(const float u1,
                      const float u2,
                      const float u3,
                      DifferentialGeometry &dg,
                      float &pdf) const
{
  const Triangle &t = *mTriangleTable(u1);
  const Point &v0 = mPoints[t[0]];
  const Point &v1 = mPoints[t[1]];
  const Point &v2 = mPoints[t[2]];

  Point p;
  UnitSquareToTriangle::evaluate(u2,u3, v0, v1, v2, p);

  // XXX implement shading normals
  // XXX implement derivatives
  Normal ng = (v1 - v0).cross(v2 - v0).normalize();

  getDifferentialGeometry(t, p, ng, u2, u3, dg);

  // evaluate the pdf
  pdf = evaluateSurfaceAreaPdf(dg);
} // end Mesh::sampleSurfaceArea()

float Mesh
  ::evaluateSurfaceAreaPdf(const DifferentialGeometry &dg) const
{
  // we assume dg is actually on the surface of this Mesh
  return mOneOverSurfaceArea;
} // end Mesh::evaluateSurfaceAreaPdf()

float Mesh
  ::getSurfaceArea(void) const
{
  return mSurfaceArea;
} // end Mesh::getSurfaceArea()

float Mesh
  ::getInverseSurfaceArea(void) const
{
  return mOneOverSurfaceArea;
} // end Mesh::getInverseSurfaceArea()

void Mesh
  ::buildWaldBikkerData(void)
{
  mWaldBikkerTriangleData.clear();

  // see http://www.devmaster.net/articles/raytracing_series/part7.php for details
  for(size_t i = 0; i < mTriangles.size(); ++i)
  {
    const Triangle &tri = mTriangles[i];

    // compute the triangle's normal
    Vector b = mPoints[tri[2]] - mPoints[tri[0]];
    Vector c = mPoints[tri[1]] - mPoints[tri[0]];
    Normal n = c.cross(b).normalize();

    WaldBikkerData data;

    // determine dominant axis
    if(fabsf(n[0]) > fabsf(n[1]))
    {
      if(fabsf(n[0]) > fabsf(n[2])) data.mDominantAxis = 0;
      else data.mDominantAxis = 2;
    } // end if
    else
    {
      if(fabsf(n[1]) > fabsf(n[2])) data.mDominantAxis = 1;
      else data.mDominantAxis = 2;
    } // end else

    int u = (data.mDominantAxis + 1) % 3;
    int v = (data.mDominantAxis + 2) % 3;

    data.mUAxis = u;
    data.mVAxis = v;

    data.mN[0] = n.dot(mPoints[tri[0]]) / n[data.mDominantAxis];
    data.mN[1] = n[u] / n[data.mDominantAxis];
    data.mN[2] = n[v] / n[data.mDominantAxis];

    float bnu =  b[u] / (b[u] * c[v] - b[v] * c[u]);
    float bnv = -b[v] / (b[u] * c[v] - b[v] * c[u]);
    data.mBn = gpcpu::float2(bnu, bnv);

    float cnu =  c[v] / (b[u] * c[v] - b[v] * c[u]);
    float cnv = -c[u] / (b[u] * c[v] - b[v] * c[u]);
    data.mCn = gpcpu::float2(cnu, cnv);

    mWaldBikkerTriangleData.push_back(data);
  } // end for i
} // end Mesh::buildWaldBikkerData()

<commit_msg>Fix bug where we need to send barycentrics rather than unit square coordinates.<commit_after>/*! \file Mesh.cpp
 *  \author Jared Hoberock
 *  \brief Implementation of Mesh class.
 */

#include "Mesh.h"
#include "../geometry/Normal.h"
#include <2dmapping/UnitSquareToTriangle.h>

Mesh
  ::Mesh(const std::vector<Point> &vertices,
         const std::vector<Triangle> &triangles)
     :Parent0(vertices,triangles),Parent1()
{
  buildWaldBikkerData();
  buildTree();
  buildTriangleTable();
  mSurfaceArea = computeSurfaceArea();
  mOneOverSurfaceArea = 1.0f / mSurfaceArea;
} // end Mesh::Mesh()

Mesh
  ::Mesh(const std::vector<Point> &vertices,
         const std::vector<ParametricCoordinates> &parametrics,
         const std::vector<Triangle> &triangles)
    :Parent0(vertices,parametrics,triangles),Parent1()
{
  buildWaldBikkerData();
  buildTree();
  buildTriangleTable();
  mSurfaceArea = computeSurfaceArea();
  mOneOverSurfaceArea = 1.0f / mSurfaceArea;
} // end Mesh::Mesh()

Mesh
  ::~Mesh(void)
{
  ;
} // end Mesh::~Mesh()

bool Mesh
  ::intersect(const Ray &r) const
{
  // create a TriangleShadower
  TriangleShadower shadower = {this};
  return mTree.shadow(r.getAnchor(), r.getDirection(), r.getInterval()[0], r.getInterval()[1], shadower);
} // end Mesh::intersect()

bool Mesh
  ::intersect(const Ray &r, float &t, DifferentialGeometry &dg) const
{
  // create a TriangleIntersector
  TriangleIntersector intersector;
  intersector.init();
  intersector.mMesh = this;

  if(mTree.intersect(r.getAnchor(), r.getDirection(),
                     r.getInterval()[0], r.getInterval()[1],
                     intersector))
  {
    t = intersector.mT;
    const Triangle &tri = *intersector.mHitFace;

    // fill out DifferentialGeometry details
    Vector3 e1 = mPoints[tri[1]] - mPoints[tri[0]];
    Vector3 e2 = mPoints[tri[2]] - mPoints[tri[0]];
    getDifferentialGeometry(tri, r(t), e1.cross(e2).normalize(),
                            intersector.mBarycentricCoordinates[0],
                            intersector.mBarycentricCoordinates[1],
                            dg);
    return true;
  } // end if

  return false;
} // end Mesh::intersect()

float Mesh::TriangleBounder
  ::operator()(unsigned int axis, bool min, const Triangle *t)
{
  float result = std::numeric_limits<float>::infinity();
  if(!min) result = -result;

  // iterate through each adjacent vertex & pick the minimal/maximal
  const PointList &points = mMesh->getPoints();

  for(unsigned int i = 0; i < 3; ++i)
  {
    const Point &pos = points[(*t)[i]];

    if(min)
    {
      if(pos[axis] < result) result = pos[axis];
    } // end if
    else
    {
      if(pos[axis] > result) result = pos[axis];
    } // end else
  } // end for i

  return result;
} // end Mesh::TriangleBounder::operator()()

void Mesh
  ::getBoundingBox(BoundingBox &b) const
{
  b.setEmpty();

  // iterate over positions
  for(PointList::const_iterator p = getPoints().begin();
      p != getPoints().end();
      ++p)
  {
    b.addPoint(*p);
  } // end for p
} // end Mesh::getBoundingBox()

void Mesh
  ::buildTree(void)
{
  TriangleBounder bounder;
  bounder.mMesh = this;

  std::vector<const Triangle*> trianglePointers;
  for(TriangleList::const_iterator t = getTriangles().begin();
      t != getTriangles().end();
      ++t)
  {
    trianglePointers.push_back(&(*t));
  } // end for t

  mTree.buildTree(trianglePointers.begin(), trianglePointers.end(), bounder);
} // end Mesh::buildTree()

void Mesh
  ::getDifferentialGeometry(const Triangle &tri,
                            const Point &p,
                            const Normal &ng,
                            const float b1,
                            const float b2,
                            DifferentialGeometry &dg) const
{
  // shorthand
  const Point &p1 = mPoints[tri[0]];
  const Point &p2 = mPoints[tri[1]];
  const Point &p3 = mPoints[tri[2]];

  Vector e1 = p2 - p1;
  Vector e2 = p3 - p1;

  // compute the last barycentric coordinate
  float b0 = 1.0f - b1 - b2;

  // interpolate normal?
  //if(f[0].mNormalIndex == -1 ||
  //   f[1].mNormalIndex == -1 ||
  //   f[2].mNormalIndex == -1)
  //{
  //} // end if
  //else
  //{
  //  // get each vertex's Normals
  //  const Mesh::NormalList &norms = m.getNormals();
  //  const Normal &n1 = norms[f[0].mNormalIndex];
  //  const Normal &n2 = norms[f[1].mNormalIndex];
  //  const Normal &n3 = norms[f[2].mNormalIndex];
  //  n = b0 * n1 + b1 * n2 + b2 * n3;
  //} // end else

  // normalize it
  //dg.getNormal() = dg.getNormal().normalize();

  ParametricCoordinates uv0;
  ParametricCoordinates uv1;
  ParametricCoordinates uv2;
  getParametricCoordinates(tri, uv0, uv1, uv2);

  // compute deltas for partial derivatives
  float du1 = uv0[0] - uv2[0];
  float du2 = uv1[0] - uv2[0];
  float dv1 = uv0[1] - uv2[1];
  float dv2 = uv1[1] - uv2[1];
  Vector dp1 = p1 - p3, dp2 = p2 - p3;
  float determinant = du1 * dv2 - dv1 * du2;
  if(determinant == 0.0)
  {
    // handle zero determinant case
    dg.getPointPartials()[0] = ng.orthogonalVector();
    dg.getPointPartials()[1] = ng.cross(dg.getPointPartials()[0]).normalize();
  } // end if
  else
  {
    float invDet = 1.0f / determinant;
    dg.getPointPartials()[0] = ( dv2*dp1 - dv1*dp2) * invDet;
    dg.getPointPartials()[1] = (-du2*dp1 + du1*dp2) * invDet;
  } // end else

  // interpolate uv using barycentric coordinates
  ParametricCoordinates uv;
  uv[0] = b0*uv0[0] + b1*uv1[0] + b2*uv2[0];
  uv[1] = b0*uv0[1] + b1*uv1[1] + b2*uv2[1];

  dg.setPoint(p);
  dg.setNormal(ng);
  dg.setParametricCoordinates(uv);
  dg.setTangent(dg.getPointPartials()[0].normalize());

  // force an orthonormal basis
  dg.setBinormal(ng.cross(dg.getTangent()));
} // end Mesh::getDifferentialGeometry()

void Mesh::TriangleIntersector
  ::init(void)
{
  mT = std::numeric_limits<float>::infinity();
  mHitFace = 0;
  mMesh = 0;
} // end TriangleIntersector::init()

void Mesh
  ::buildTriangleTable(void)
{
  std::vector<const Triangle*> pointers;
  std::vector<float> area;
  for(TriangleList::const_iterator t = mTriangles.begin();
      t != mTriangles.end();
      ++t)
  {
    pointers.push_back(&(*t));
    area.push_back(Parent0::computeSurfaceArea(*t));
  } // end for t

  mTriangleTable.build(pointers.begin(), pointers.end(),
                       area.begin(), area.end());
} // end Mesh::buildTriangleTable()

float Mesh
  ::computeSurfaceArea(void) const
{
  float result = 0;

  for(TriangleList::const_iterator t = mTriangles.begin();
      t != mTriangles.end();
      ++t)
  {
    result += Parent0::computeSurfaceArea(*t);
  } // end for t

  return result;
} // end Mesh::computeSurfaceArea()

void Mesh
  ::sampleSurfaceArea(const float u1,
                      const float u2,
                      const float u3,
                      DifferentialGeometry &dg,
                      float &pdf) const
{
  const Triangle &t = *mTriangleTable(u1);
  const Point &v0 = mPoints[t[0]];
  const Point &v1 = mPoints[t[1]];
  const Point &v2 = mPoints[t[2]];

  Point p;
  ParametricCoordinates b;
  UnitSquareToTriangle::evaluate(u2,u3, v0, v1, v2, p, b);

  // XXX implement shading normals
  Normal ng = (v1 - v0).cross(v2 - v0).normalize();

  // we need to send barycentrics here, not u2 and u3
  // as they are NOT the same thing
  getDifferentialGeometry(t, p, ng, b[0], b[1], dg);

  // evaluate the pdf
  pdf = evaluateSurfaceAreaPdf(dg);
} // end Mesh::sampleSurfaceArea()

float Mesh
  ::evaluateSurfaceAreaPdf(const DifferentialGeometry &dg) const
{
  // we assume dg is actually on the surface of this Mesh
  return mOneOverSurfaceArea;
} // end Mesh::evaluateSurfaceAreaPdf()

float Mesh
  ::getSurfaceArea(void) const
{
  return mSurfaceArea;
} // end Mesh::getSurfaceArea()

float Mesh
  ::getInverseSurfaceArea(void) const
{
  return mOneOverSurfaceArea;
} // end Mesh::getInverseSurfaceArea()

void Mesh
  ::buildWaldBikkerData(void)
{
  mWaldBikkerTriangleData.clear();

  // see http://www.devmaster.net/articles/raytracing_series/part7.php for details
  for(size_t i = 0; i < mTriangles.size(); ++i)
  {
    const Triangle &tri = mTriangles[i];

    // compute the triangle's normal
    Vector b = mPoints[tri[2]] - mPoints[tri[0]];
    Vector c = mPoints[tri[1]] - mPoints[tri[0]];
    Normal n = c.cross(b).normalize();

    WaldBikkerData data;

    // determine dominant axis
    if(fabsf(n[0]) > fabsf(n[1]))
    {
      if(fabsf(n[0]) > fabsf(n[2])) data.mDominantAxis = 0;
      else data.mDominantAxis = 2;
    } // end if
    else
    {
      if(fabsf(n[1]) > fabsf(n[2])) data.mDominantAxis = 1;
      else data.mDominantAxis = 2;
    } // end else

    int u = (data.mDominantAxis + 1) % 3;
    int v = (data.mDominantAxis + 2) % 3;

    data.mUAxis = u;
    data.mVAxis = v;

    data.mN[0] = n.dot(mPoints[tri[0]]) / n[data.mDominantAxis];
    data.mN[1] = n[u] / n[data.mDominantAxis];
    data.mN[2] = n[v] / n[data.mDominantAxis];

    float bnu =  b[u] / (b[u] * c[v] - b[v] * c[u]);
    float bnv = -b[v] / (b[u] * c[v] - b[v] * c[u]);
    data.mBn = gpcpu::float2(bnu, bnv);

    float cnu =  c[v] / (b[u] * c[v] - b[v] * c[u]);
    float cnv = -c[u] / (b[u] * c[v] - b[v] * c[u]);
    data.mCn = gpcpu::float2(cnu, cnv);

    mWaldBikkerTriangleData.push_back(data);
  } // end for i
} // end Mesh::buildWaldBikkerData()

<|endoftext|>


<commit_before><commit_msg>make SwClientIter::GoStart/GoEnd private<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: mdiexp.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 02:00:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/
#ifndef _MDIEXP_HXX
#define _MDIEXP_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

class UniString;
class SwRect;
class Size;
class Dialog;
class ViewShell;
class SwDoc;
class SwDocShell;
class SfxObjectShell;
class SfxFrame;

extern void ScrollMDI(ViewShell* pVwSh, const SwRect &, USHORT nRangeX, USHORT nRangeY);
extern BOOL IsScrollMDI(ViewShell* pVwSh, const SwRect &);
extern void SizeNotify(ViewShell* pVwSh, const Size &);

//Update der Statusleiste, waehrend einer Action.
extern void PageNumNotify( ViewShell* pVwSh,
                            USHORT nPhyNum,
                            USHORT nVirtNum,
                           const UniString& rPg );

enum FlyMode { FLY_DRAG_START, FLY_DRAG, FLY_DRAG_END };
extern void FrameNotify( ViewShell* pVwSh, FlyMode eMode = FLY_DRAG );

void StartProgress     ( USHORT nMessId, long nStartVal, long nEndVal, SwDocShell *pDocSh = 0 );
void EndProgress       ( SwDocShell *pDocSh = 0 );
void SetProgressState  ( long nPosition, SwDocShell *pDocShell );
void SetProgressText   ( USHORT nMessId, SwDocShell *pDocShell );
void RescheduleProgress( SwDocShell *pDocShell );

void EnableCmdInterface(BOOL bEnable = TRUE);

Dialog* GetSearchDialog();

void RepaintPagePreview( ViewShell* pVwSh, const SwRect& rRect );

// ndgrf.cxx
// alle QuickDraw-Bitmaps des speziellen Docs loeschen
void DelAllGrfCacheEntries( SwDoc* pDoc );

// ChgMode fuer Tabellen aus der Konfiguration lesen
USHORT GetTblChgDefaultMode();

BOOL JumpToSwMark( ViewShell* pVwSh, const UniString& rMark );

#endif
<commit_msg>INTEGRATION: CWS writercorehandoff (1.3.466); FILE MERGED 2005/09/13 11:41:47 tra 1.3.466.2: RESYNC: (1.3-1.4); FILE MERGED 2005/06/07 14:10:04 fme 1.3.466.1: #i50348# General cleanup - removed unused header files, functions, members, declarations etc.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: mdiexp.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-14 15:26:31 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/
#ifndef _MDIEXP_HXX
#define _MDIEXP_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

class UniString;
class SwRect;
class Size;
class Dialog;
class ViewShell;
class SwDoc;
class SwDocShell;

extern void ScrollMDI(ViewShell* pVwSh, const SwRect &, USHORT nRangeX, USHORT nRangeY);
extern BOOL IsScrollMDI(ViewShell* pVwSh, const SwRect &);
extern void SizeNotify(ViewShell* pVwSh, const Size &);

//Update der Statusleiste, waehrend einer Action.
extern void PageNumNotify( ViewShell* pVwSh,
                            USHORT nPhyNum,
                            USHORT nVirtNum,
                           const UniString& rPg );

enum FlyMode { FLY_DRAG_START, FLY_DRAG, FLY_DRAG_END };
extern void FrameNotify( ViewShell* pVwSh, FlyMode eMode = FLY_DRAG );

void StartProgress     ( USHORT nMessId, long nStartVal, long nEndVal, SwDocShell *pDocSh = 0 );
void EndProgress       ( SwDocShell *pDocSh = 0 );
void SetProgressState  ( long nPosition, SwDocShell *pDocShell );
void SetProgressText   ( USHORT nMessId, SwDocShell *pDocShell );
void RescheduleProgress( SwDocShell *pDocShell );

void EnableCmdInterface(BOOL bEnable = TRUE);

Dialog* GetSearchDialog();

void RepaintPagePreview( ViewShell* pVwSh, const SwRect& rRect );

// ndgrf.cxx
// alle QuickDraw-Bitmaps des speziellen Docs loeschen
void DelAllGrfCacheEntries( SwDoc* pDoc );

// ChgMode fuer Tabellen aus der Konfiguration lesen
USHORT GetTblChgDefaultMode();

BOOL JumpToSwMark( ViewShell* pVwSh, const UniString& rMark );

#endif
<|endoftext|>


<commit_before>#include "../TCPSocket.h"

#include <cstring>
#include <iostream>

using namespace NET;

int main()
{
	static char send_msg[] = "The quick brown fox jumps over the lazy dog";
	static char recv_msg[sizeof(send_msg)];
	static size_t len = sizeof(send_msg);

	try {

	// Test peer status on a TCP socket
	TCPSocket server_socket;
	TCPSocket client_socket;
	server_socket.bind( "127.0.0.1", 47777);
	server_socket.listen();
	if( server_socket.peerDisconnected()) return 1;

	client_socket.connect( "127.0.0.1", 47777);

	const TCPSocket::Handle& handle = server_socket.accept();
	if(!handle) return 1;
	TCPSocket session_socket(handle);
	if( session_socket.peerDisconnected()) return 1;

	session_socket.send( send_msg, len);
	if( client_socket.receive( recv_msg, len) != len) return 1;
	if( std::memcmp( send_msg, recv_msg, len) < 0) return 1;

	client_socket.disconnect();
	session_socket.send( send_msg, len);
	if( !session_socket.peerDisconnected()) return 1;

	// no errors in this testcase
	} catch( const SocketException& e)
	{
		std::cerr << e.what() << std::endl;
		std::cerr << e.errorCode() << std::endl;
	}
}
<commit_msg>fix bug in TCPSocket test, where an exception is ignored<commit_after>#include "../TCPSocket.h"

#include <cstring>
#include <iostream>

using namespace NET;

int main()
{
	static char send_msg[] = "The quick brown fox jumps over the lazy dog";
	static char recv_msg[sizeof(send_msg)];
	static size_t len = sizeof(send_msg);

	try {

	// Test peer status on a TCP socket
	TCPSocket server_socket;
	TCPSocket client_socket;
	server_socket.bind( "127.0.0.1", 47777);
	server_socket.listen();
	if( server_socket.peerDisconnected()) return 1;

	client_socket.connect( "127.0.0.1", 47777);

	const TCPSocket::Handle& handle = server_socket.accept();
	if(!handle) return 1;
	TCPSocket session_socket(handle);
	if( session_socket.peerDisconnected()) return 1;

	session_socket.send( send_msg, len);
	if( client_socket.receive( recv_msg, len) != len) return 1;
	if( std::memcmp( send_msg, recv_msg, len) < 0) return 1;

	client_socket.disconnect();
	session_socket.send( send_msg, len);
	if( !session_socket.peerDisconnected()) return 1;

	// no errors in this testcase
	} catch( const SocketException& e)
	{
		std::cerr << e.what() << std::endl;
		std::cerr << e.errorCode() << std::endl;
		return 1;
	}
}
<|endoftext|>


<commit_before>/* This file is part of QJson
 *
 * Copyright (C) 2009 Flavio Castelli <flavio.castelli@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QStringList>
#include <QVariant>

#include <json_driver.hh>

int main(int argc, char *argv[]) {
  QCoreApplication app (argc, argv);

  if (app.arguments().size() != 2) {
    qFatal("You have to specify the file containing the json code");
    exit (1);
  }

  QString filename = app.arguments()[1];
  if (!QFile::exists ( filename )) {
    qFatal ("The file you specified doesn't exist!");
    exit (1);
  }

  JSonDriver driver;
  bool status;

  QVariant data = driver.parse (new QFile(filename), &status);
  if (status) {
    qFatal("An error occured during parsing");
    exit (1);
  }
  else {
    qDebug() << "json object successfully converted to:";
    qDebug() << data;
  }

  return 0;
}<commit_msg>take advantage of error localization<commit_after>/* This file is part of QJson
 *
 * Copyright (C) 2009 Flavio Castelli <flavio.castelli@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QStringList>
#include <QVariant>

#include <json_driver.hh>

int main(int argc, char *argv[]) {
  QCoreApplication app (argc, argv);

  if (app.arguments().size() != 2) {
    qFatal("You have to specify the file containing the json code");
    exit (1);
  }

  QString filename = app.arguments()[1];
  if (!QFile::exists ( filename )) {
    qFatal ("The file you specified doesn't exist!");
    exit (1);
  }

  JSonDriver driver;
  bool status;

  QVariant data = driver.parse (new QFile(filename), &status);
  if (status) {
    QString message;
    message.sprintf("%s:%i - Error: %s", filename.toLatin1().data(), driver.errorLine(), driver.error().toLatin1().data());
    qFatal(message.toLatin1().data());
    exit (1);
  }
  else {
    qDebug() << "json object successfully converted to:";
    qDebug() << data;
  }

  return 0;
}<|endoftext|>