<commit_before>/*
    This file is part of Magnum.

    Original authors — credit is appreciated but not required:

        2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 —
            Vladimír Vondruš <mosra@centrum.cz>
        2020 — Nghia Truong <nghiatruong.vn@gmail.com>

    This is free and unencumbered software released into the public domain.

    Anyone is free to copy, modify, publish, use, compile, sell, or distribute
    this software, either in source code form or as a compiled binary, for any
    purpose, commercial or non-commercial, and by any means.

    In jurisdictions that recognize copyright laws, the author or authors of
    this software dedicate any and all copyright interest in the software to
    the public domain. We make this dedication for the benefit of the public
    at large and to the detriment of our heirs and successors. We intend this
    dedication to be an overt act of relinquishment in perpetuity of all
    present and future rights to this software under copyright law.

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

#include "ArcBall.h"

#include <Magnum/Math/Matrix3.h>

namespace Magnum { namespace Examples {

namespace {

/* Project a point in NDC onto the arcball sphere */
Quaternion ndcToArcBall(const Vector2& p) {
    const Float dist = Math::dot(p, p);

    /* Point is on sphere */
    if(dist <= 1.0f)
        return {{p.x(), p.y(), Math::sqrt(1.0f - dist)}, 0.0f};

    /* Point is outside sphere */
    else {
        const Vector2 proj = p.normalized();
        return {{proj.x(), proj.y(), 0.0f}, 0.0f};
    }
}

}

ArcBall::ArcBall(const Vector3& eye, const Vector3& viewCenter, const Vector3& upDir, Deg fov, const Vector2i& windowSize): _fov{fov}, _windowSize{windowSize} {
    setViewParameters(eye, viewCenter, upDir);
}

void ArcBall::setViewParameters(const Vector3& eye, const Vector3& viewCenter,  const Vector3& upDir) {
    const Vector3 dir = viewCenter - eye;
    Vector3 zAxis = dir.normalized();
    Vector3 xAxis = (Math::cross(zAxis, upDir.normalized())).normalized();
    Vector3 yAxis = (Math::cross(xAxis, zAxis)).normalized();
    xAxis = (Math::cross(zAxis, yAxis)).normalized();

    _targetPosition = -viewCenter;
    _targetZooming = -dir.length();
    _targetQRotation = Quaternion::fromMatrix(Matrix3x3{xAxis, yAxis, -zAxis}.transposed()).normalized();

    _positionT0  = _currentPosition = _targetPosition;
    _zoomingT0 = _currentZooming = _targetZooming;
    _qRotationT0 = _currentQRotation = _targetQRotation;

    updateMatrices();
}

void ArcBall::reset() {
    _targetPosition = _positionT0;
    _targetZooming = _zoomingT0;
    _targetQRotation = _qRotationT0;
}

void ArcBall::setLagging(const Float lagging) {
    CORRADE_INTERNAL_ASSERT(lagging >= 0.0f && lagging < 1.0f);
    _lagging = lagging;
}

void ArcBall::initTransformation(const Vector2i& mousePos) {
    _prevMousePosNDC = screenCoordToNDC(mousePos);
}

void ArcBall::rotate(const Vector2i& mousePos) {
    const Vector2 mousePosNDC = screenCoordToNDC(mousePos);
    const Quaternion currentQRotation = ndcToArcBall(mousePosNDC);
    const Quaternion prevQRotation = ndcToArcBall(_prevMousePosNDC);
    _prevMousePosNDC = mousePosNDC;
    _targetQRotation = (currentQRotation*prevQRotation*_targetQRotation).normalized();
}

void ArcBall::translate(const Vector2i& mousePos) {
    const Vector2 mousePosNDC = screenCoordToNDC(mousePos);
    const Vector2 translationNDC = mousePosNDC - _prevMousePosNDC;
    _prevMousePosNDC = mousePosNDC;
    translateDelta(translationNDC);
}

void ArcBall::translateDelta(const Vector2& translationNDC) {
    /* Half size of the screen viewport at the view center and perpendicular
       with the viewDir */
    const Float hh = Math::abs(_targetZooming)*Math::tan(_fov*0.5f);
    const Float hw = hh*Vector2{_windowSize}.aspectRatio();

    _targetPosition += (_inverseViewMatrix*Vector4{
        translationNDC.x()*hw, translationNDC.y()*hh, 0.0f, 0.0f}).xyz();
}

void ArcBall::zoom(const Float delta) {
    _targetZooming += delta;
}

bool ArcBall::updateTransformation() {
    const Vector3 diffViewCenter = _targetPosition - _currentPosition;
    const Quaternion diffRotation = _targetQRotation - _currentQRotation;
    const Float diffZooming = _targetZooming - _currentZooming;

    const Float dViewCenter = Math::dot(diffViewCenter, diffViewCenter);
    const Float dRotation = Math::dot(diffRotation, diffRotation);
    const Float dZooming = diffZooming * diffZooming;

    /* Nothing change */
    if(dViewCenter < 1.0e-10f &&
       dRotation < 1.0e-10f &&
       dZooming < 1.0e-10f) {
        return false;
    }

    /* Nearly done: just jump directly to the target */
    if(dViewCenter < 1.0e-6f &&
       dRotation < 1.0e-6f &&
       dZooming < 1.0e-6f) {
        _currentPosition  = _targetPosition;
        _currentQRotation = _targetQRotation;
        _currentZooming   = _targetZooming;

    /* Interpolate between the current transformation and the target
       transformation */
    } else {
        const Float t = 1 - _lagging;
        _currentPosition = Math::lerp(_currentPosition, _targetPosition, t);
        _currentZooming  = Math::lerp(_currentZooming, _targetZooming, t);
        _currentQRotation = Math::slerpShortestPath(_currentQRotation, _targetQRotation, t);
    }

    updateMatrices();
    return true;
}

void ArcBall::updateMatrices() {
    _viewMatrix = Matrix4::translation(Vector3::zAxis(_currentZooming))*
                  Matrix4::from(_currentQRotation.toMatrix(), {})*
                  Matrix4::translation(_currentPosition);
    _inverseViewMatrix = _viewMatrix.inverted();
}

Vector2 ArcBall::screenCoordToNDC(const Vector2i& mousePos) const {
    return {mousePos.x()*2.0f/_windowSize.x() - 1.0f,
            1.0f - 2.0f*mousePos.y()/ _windowSize.y()};
}

}}
<commit_msg>arcball: we have an API for this :)<commit_after>/*
    This file is part of Magnum.

    Original authors — credit is appreciated but not required:

        2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 —
            Vladimír Vondruš <mosra@centrum.cz>
        2020 — Nghia Truong <nghiatruong.vn@gmail.com>

    This is free and unencumbered software released into the public domain.

    Anyone is free to copy, modify, publish, use, compile, sell, or distribute
    this software, either in source code form or as a compiled binary, for any
    purpose, commercial or non-commercial, and by any means.

    In jurisdictions that recognize copyright laws, the author or authors of
    this software dedicate any and all copyright interest in the software to
    the public domain. We make this dedication for the benefit of the public
    at large and to the detriment of our heirs and successors. We intend this
    dedication to be an overt act of relinquishment in perpetuity of all
    present and future rights to this software under copyright law.

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

#include "ArcBall.h"

#include <Magnum/Math/Matrix3.h>

namespace Magnum { namespace Examples {

namespace {

/* Project a point in NDC onto the arcball sphere */
Quaternion ndcToArcBall(const Vector2& p) {
    const Float dist = Math::dot(p, p);

    /* Point is on sphere */
    if(dist <= 1.0f)
        return {{p.x(), p.y(), Math::sqrt(1.0f - dist)}, 0.0f};

    /* Point is outside sphere */
    else {
        const Vector2 proj = p.normalized();
        return {{proj.x(), proj.y(), 0.0f}, 0.0f};
    }
}

}

ArcBall::ArcBall(const Vector3& eye, const Vector3& viewCenter, const Vector3& upDir, Deg fov, const Vector2i& windowSize): _fov{fov}, _windowSize{windowSize} {
    setViewParameters(eye, viewCenter, upDir);
}

void ArcBall::setViewParameters(const Vector3& eye, const Vector3& viewCenter,  const Vector3& upDir) {
    const Vector3 dir = viewCenter - eye;
    Vector3 zAxis = dir.normalized();
    Vector3 xAxis = (Math::cross(zAxis, upDir.normalized())).normalized();
    Vector3 yAxis = (Math::cross(xAxis, zAxis)).normalized();
    xAxis = (Math::cross(zAxis, yAxis)).normalized();

    _targetPosition = -viewCenter;
    _targetZooming = -dir.length();
    _targetQRotation = Quaternion::fromMatrix(Matrix3x3{xAxis, yAxis, -zAxis}.transposed()).normalized();

    _positionT0  = _currentPosition = _targetPosition;
    _zoomingT0 = _currentZooming = _targetZooming;
    _qRotationT0 = _currentQRotation = _targetQRotation;

    updateMatrices();
}

void ArcBall::reset() {
    _targetPosition = _positionT0;
    _targetZooming = _zoomingT0;
    _targetQRotation = _qRotationT0;
}

void ArcBall::setLagging(const Float lagging) {
    CORRADE_INTERNAL_ASSERT(lagging >= 0.0f && lagging < 1.0f);
    _lagging = lagging;
}

void ArcBall::initTransformation(const Vector2i& mousePos) {
    _prevMousePosNDC = screenCoordToNDC(mousePos);
}

void ArcBall::rotate(const Vector2i& mousePos) {
    const Vector2 mousePosNDC = screenCoordToNDC(mousePos);
    const Quaternion currentQRotation = ndcToArcBall(mousePosNDC);
    const Quaternion prevQRotation = ndcToArcBall(_prevMousePosNDC);
    _prevMousePosNDC = mousePosNDC;
    _targetQRotation = (currentQRotation*prevQRotation*_targetQRotation).normalized();
}

void ArcBall::translate(const Vector2i& mousePos) {
    const Vector2 mousePosNDC = screenCoordToNDC(mousePos);
    const Vector2 translationNDC = mousePosNDC - _prevMousePosNDC;
    _prevMousePosNDC = mousePosNDC;
    translateDelta(translationNDC);
}

void ArcBall::translateDelta(const Vector2& translationNDC) {
    /* Half size of the screen viewport at the view center and perpendicular
       with the viewDir */
    const Float hh = Math::abs(_targetZooming)*Math::tan(_fov*0.5f);
    const Float hw = hh*Vector2{_windowSize}.aspectRatio();

    _targetPosition += _inverseViewMatrix.transformVector(
        {translationNDC.x()*hw, translationNDC.y()*hh, 0.0f});
}

void ArcBall::zoom(const Float delta) {
    _targetZooming += delta;
}

bool ArcBall::updateTransformation() {
    const Vector3 diffViewCenter = _targetPosition - _currentPosition;
    const Quaternion diffRotation = _targetQRotation - _currentQRotation;
    const Float diffZooming = _targetZooming - _currentZooming;

    const Float dViewCenter = Math::dot(diffViewCenter, diffViewCenter);
    const Float dRotation = Math::dot(diffRotation, diffRotation);
    const Float dZooming = diffZooming * diffZooming;

    /* Nothing change */
    if(dViewCenter < 1.0e-10f &&
       dRotation < 1.0e-10f &&
       dZooming < 1.0e-10f) {
        return false;
    }

    /* Nearly done: just jump directly to the target */
    if(dViewCenter < 1.0e-6f &&
       dRotation < 1.0e-6f &&
       dZooming < 1.0e-6f) {
        _currentPosition  = _targetPosition;
        _currentQRotation = _targetQRotation;
        _currentZooming   = _targetZooming;

    /* Interpolate between the current transformation and the target
       transformation */
    } else {
        const Float t = 1 - _lagging;
        _currentPosition = Math::lerp(_currentPosition, _targetPosition, t);
        _currentZooming  = Math::lerp(_currentZooming, _targetZooming, t);
        _currentQRotation = Math::slerpShortestPath(_currentQRotation, _targetQRotation, t);
    }

    updateMatrices();
    return true;
}

void ArcBall::updateMatrices() {
    _viewMatrix = Matrix4::translation(Vector3::zAxis(_currentZooming))*
                  Matrix4::from(_currentQRotation.toMatrix(), {})*
                  Matrix4::translation(_currentPosition);
    _inverseViewMatrix = _viewMatrix.inverted();
}

Vector2 ArcBall::screenCoordToNDC(const Vector2i& mousePos) const {
    return {mousePos.x()*2.0f/_windowSize.x() - 1.0f,
            1.0f - 2.0f*mousePos.y()/ _windowSize.y()};
}

}}
<|endoftext|>


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

#include "monarch/rt/DynamicObject.h"

#include <cstring>

using namespace std;
using namespace monarch::io;
using namespace monarch::rt;

FileOutputStream::FileOutputStream(File& file, bool append, int bufferMode) :
   mFile(file),
   mAppend(append),
   mHandle(NULL),
   mBufferMode(bufferMode)
{
}

FileOutputStream::FileOutputStream(StdOutput out) :
   mFile((FileImpl*)NULL),
   mAppend(false),
   mHandle((out == StdOut) ? stdout : stderr)
{
}

FileOutputStream::~FileOutputStream()
{
   // close the handle if it is open
   FileOutputStream::close();
}

bool FileOutputStream::write(const char* b, int length)
{
   bool rval = false;

   if(ensureOpen())
   {
      // do write
      if((int)fwrite(b, 1, length, mHandle) != length)
      {
         // error
         ExceptionRef e = new Exception(
            "Could not write to file.",
            "monarch.io.File.WriteError");
         e->getDetails()["path"] = mFile->getAbsolutePath();
         e->getDetails()["error"] = strerror(errno);
         Exception::set(e);
      }
      else
      {
         rval = true;
      }
   }

   return rval;
}

bool FileOutputStream::flush()
{
   bool rval = false;

   if(ensureOpen())
   {
      fflush(mHandle);
   }

   return rval;
}

void FileOutputStream::close()
{
   // (mFile is null when using stdout/stderr)
   if(mHandle != NULL && !mFile.isNull())
   {
      // close the stream
      fclose(mHandle);
      mHandle = NULL;
   }
}

bool FileOutputStream::ensureOpen()
{
   bool rval = true;

   // try to open the file (mFile is null when using stdout/stderr)
   if(mHandle == NULL && !mFile.isNull())
   {
      mHandle = fopen(mFile->getAbsolutePath(), mAppend ? "ab" : "wb");
      if(mHandle == NULL)
      {
         ExceptionRef e = new Exception(
            "Could not open file stream.",
            "monarch.io.File.OpenFailed");
         e->getDetails()["path"] = mFile->getAbsolutePath();
         e->getDetails()["error"] = strerror(errno);
         Exception::set(e);
         rval = false;
      }
      else
      {
         // set buffer mode
         if(setvbuf(mHandle, (char *) NULL, mBufferMode, 0) != 0)
         {
            ExceptionRef e = new Exception(
               "Could not set file buffer mode.",
               "monarch.io.File.BufferModeFailure");
            e->getDetails()["path"] = mFile->getAbsolutePath();
            e->getDetails()["mode"] = mBufferMode;
            e->getDetails()["error"] = strerror(errno);
            Exception::set(e);
            rval = false;
         }
      }
   }

   return rval;
}
<commit_msg>Added patch for windows file buffering.<commit_after>/*
 * Copyright (c) 2007-2009 Digital Bazaar, Inc. All rights reserved.
 */
#include "monarch/io/FileOutputStream.h"

#include "monarch/rt/DynamicObject.h"

#include <cstring>

using namespace std;
using namespace monarch::io;
using namespace monarch::rt;

FileOutputStream::FileOutputStream(File& file, bool append, int bufferMode) :
   mFile(file),
   mAppend(append),
   mHandle(NULL),
   mBufferMode(bufferMode)
{
}

FileOutputStream::FileOutputStream(StdOutput out) :
   mFile((FileImpl*)NULL),
   mAppend(false),
   mHandle((out == StdOut) ? stdout : stderr)
{
}

FileOutputStream::~FileOutputStream()
{
   // close the handle if it is open
   FileOutputStream::close();
}

bool FileOutputStream::write(const char* b, int length)
{
   bool rval = false;

   if(ensureOpen())
   {
      // do write
      if((int)fwrite(b, 1, length, mHandle) != length)
      {
         // error
         ExceptionRef e = new Exception(
            "Could not write to file.",
            "monarch.io.File.WriteError");
         e->getDetails()["path"] = mFile->getAbsolutePath();
         e->getDetails()["error"] = strerror(errno);
         Exception::set(e);
      }
      else
      {
         rval = true;
      }
   }

   return rval;
}

bool FileOutputStream::flush()
{
   bool rval = false;

   if(ensureOpen())
   {
      fflush(mHandle);
   }

   return rval;
}

void FileOutputStream::close()
{
   // (mFile is null when using stdout/stderr)
   if(mHandle != NULL && !mFile.isNull())
   {
      // close the stream
      fclose(mHandle);
      mHandle = NULL;
   }
}

bool FileOutputStream::ensureOpen()
{
   bool rval = true;

   // try to open the file (mFile is null when using stdout/stderr)
   if(mHandle == NULL && !mFile.isNull())
   {
      mHandle = fopen(mFile->getAbsolutePath(), mAppend ? "ab" : "wb");
      if(mHandle == NULL)
      {
         ExceptionRef e = new Exception(
            "Could not open file stream.",
            "monarch.io.File.OpenFailed");
         e->getDetails()["path"] = mFile->getAbsolutePath();
         e->getDetails()["error"] = strerror(errno);
         Exception::set(e);
         rval = false;
      }
      else
      {
         // set buffer mode (windows thinks 0 is an invalid argument for the
         // buffer size so we use the defined BUFSIZ minimum buffer size)
#ifdef WIN32
         if(setvbuf(mHandle, (char*)NULL, mBufferMode, BUFSIZ) != 0)
#else
         if(setvbuf(mHandle, (char*)NULL, mBufferMode, 0) != 0)
#endif
         {
            ExceptionRef e = new Exception(
               "Could not set file buffer mode.",
               "monarch.io.File.BufferModeFailure");
            e->getDetails()["path"] = mFile->getAbsolutePath();
            e->getDetails()["mode"] = mBufferMode;
            e->getDetails()["error"] = strerror(errno);
            Exception::set(e);
            rval = false;
         }
      }
   }

   return rval;
}
<|endoftext|>


<commit_before>#ifndef __ARCH_IO_NETWORK_HPP__
#define __ARCH_IO_NETWORK_HPP__

#include <vector>

#include "utils.hpp"
#include <boost/scoped_ptr.hpp>
#include "arch/runtime/event_queue.hpp"
#include "arch/io/io_utils.hpp"
#include "arch/address.hpp"
#include "concurrency/cond_var.hpp"
#include "concurrency/queue/unlimited_fifo.hpp"
#include "concurrency/semaphore.hpp"
#include "concurrency/coro_pool.hpp"
#include "perfmon_types.hpp"
#include "arch/io/event_watcher.hpp"
#include <boost/iterator/iterator_facade.hpp>
#include <stdexcept>
#include <stdarg.h>
#include <unistd.h>

class side_coro_handler_t;

/* linux_tcp_conn_t provides a nice wrapper around a TCP network connection. */

class linux_tcp_conn_t :
    public home_thread_mixin_t,
    private linux_event_callback_t {
public:
    friend class linux_tcp_listener_t;

    struct connect_failed_exc_t : public std::exception {
        const char *what() throw () {
            return "Could not make connection";
        }
    };

    /* TODO: One of these forms should be replaced by the other. */
    linux_tcp_conn_t(const char *host, int port);
    linux_tcp_conn_t(const ip_address_t &host, int port);

    /* Reading */

    struct read_closed_exc_t : public std::exception {
        const char *what() throw () {
            return "Network connection read end closed";
        }
    };

    /* If you know beforehand how many bytes you want to read, use read() with a byte buffer.
    Returns when the buffer is full, or throws read_closed_exc_t. */
    void read(void *buf, size_t size);

    // If you don't know how many bytes you want to read, but still
    // masochistically want to handle buffering yourself.  Makes at
    // most one call to ::read(), reads some data or throws
    // read_closed_exc_t. read_some() is guaranteed to return at least
    // one byte of data unless it throws read_closed_exc_t.
    size_t read_some(void *buf, size_t size);

    // If you don't know how many bytes you want to read, use peek()
    // and then, if you're satisfied, pop what you've read, or if
    // you're unsatisfied, read_more_buffered() and then try again.
    // Note that you should always call peek() before calling
    // read_more_buffered(), because there might be leftover data in
    // the peek buffer that might be enough for you.
    const_charslice peek() const;

    //you can also peek with a specific size (this is really just convenient
    //for some things and can in some cases avoid an unneeded copy
    const_charslice peek(size_t size);

    void pop(size_t len);

    //pop to the position the iterator has been incremented to
    class iterator;
    void pop(iterator &);

    void read_more_buffered();

    /* Call shutdown_read() to close the half of the pipe that goes from the peer to us. If there
    is an outstanding read() or peek_until() operation, it will throw read_closed_exc_t. */
    void shutdown_read();

    /* Returns false if the half of the pipe that goes from the peer to us has been closed. */
    bool is_read_open();

    /* Writing */

    struct write_closed_exc_t : public std::exception {
        const char *what() throw () {
            return "Network connection write end closed";
        }
    };

    /* write() writes 'size' bytes from 'buf' to the socket and blocks until it is done. Throws
    write_closed_exc_t if the write end of the pipe is closed before we can finish. */
    void write(const void *buf, size_t size);

    /* write_buffered() is like write(), but it might not send the data until flush_buffer*() or
    write() is called. Internally, it bundles together the buffered writes; this may improve
    performance. */
    void write_buffered(const void *buf, size_t size);

    void vwritef(const char *format, va_list args) {
        char buffer[1000];
        size_t bytes = vsnprintf(buffer, sizeof(buffer), format, args);
        rassert(bytes < sizeof(buffer));
        write(buffer, bytes);
    }

    void writef(const char *format, ...)
        __attribute__ ((format (printf, 2, 3))) {
        va_list args;
        va_start(args, format);
        vwritef(format, args);
        va_end(args);
    }

    void flush_buffer();   // Blocks until flush is done
    void flush_buffer_eventually();   // Blocks only if the queue is backed up

    /* Call shutdown_write() to close the half of the pipe that goes from us to the peer. If there
    is a write currently happening, it will get write_closed_exc_t. */
    void shutdown_write();

    /* Returns false if the half of the pipe that goes from us to the peer has been closed. */
    bool is_write_open();

    /* Put a `perfmon_rate_monitor_t` here if you want to record stats on how fast data is being
    transmitted over the network. */
    perfmon_rate_monitor_t *write_perfmon;

    /* Note that is_read_open() and is_write_open() must both be false1 before the socket is
    destroyed. */
    ~linux_tcp_conn_t();

public:
    /* iterator always you to handle the stream of data off the
     * socket with iterators, the iterator handles all of the buffering itself. The
     * impetus for this class comes from wanting to use network connection's with
     * Boost's spirit parser */

    class iterator
        : public boost::iterator_facade<iterator, const char, boost::forward_traversal_tag>
    {
    friend class linux_tcp_conn_t;
    private:
        linux_tcp_conn_t *source;
        bool end;
        size_t pos;
    private:
        int compare(iterator const& other) const;
    private:
    // boost iterator interface
        void increment();
        bool equal(iterator const& other);
        const char &dereference();
    public:
        iterator();
        iterator(linux_tcp_conn_t *, size_t);
        iterator(linux_tcp_conn_t *, bool);
        iterator(const iterator&);
        ~iterator();
        char operator*();
        void operator++();
        void operator++(int);
        bool operator==(const iterator&);
        bool operator!=(const iterator&);
        bool operator<(const iterator&);
    };

public:
    iterator begin();
    iterator end();

    // Changes the home_thread_mixin_t superclass's real_home_thread.
    void rethread(int);

private:
    explicit linux_tcp_conn_t(fd_t sock);   // Used by tcp_listener_t

    /* Note that this only gets called to handle error-events. Read and write
    events are handled through the linux_event_watcher_t. */
    void on_event(int events);

    void on_shutdown_read();
    void on_shutdown_write();

    scoped_fd_t sock;

    /* Object that we use to watch for events. It's NULL when we are not registered on any
    thread, and otherwise is an object that's valid for the current thread. */
    linux_event_watcher_t *event_watcher;

    /* True if there is a pending read or write */
    bool read_in_progress, write_in_progress;

    /* These are pulsed if and only if the read/write end of the connection has been closed. */
    cond_t read_closed, write_closed;

    /* Holds data that we read from the socket but hasn't been consumed yet */
    std::vector<char> read_buffer;

    /* Reads up to the given number of bytes, but not necessarily that many. Simple wrapper around
    ::read(). Returns the number of bytes read or throws read_closed_exc_t. Bypasses read_buffer. */
    size_t read_internal(void *buffer, size_t size);

    /* Buffer we are currently filling up with data that we want to write. When it reaches a
    certain size, we push it onto `write_queue`. */
    std::vector<char> write_buffer;

    /* Schedules old write buffer's contents to be flushed and swaps in a fresh write buffer.
    Blocks until it can acquire the `write_queue_limiter` semaphore, but doesn't wait for
    data to be completely written. */
    void internal_flush_write_buffer();

    /* Used to queue up buffers to write. The functions in `write_queue` will all be
    `boost::bind()`s of the `perform_write()` function below. */
    unlimited_fifo_queue_t<boost::function<void()> > write_queue;

    /* This semaphore prevents the write queue from getting arbitrarily big. */
    semaphore_t write_queue_limiter;

    /* Used to actually perform the writes. Only has one coroutine in it. */
    coro_pool_t write_coro_pool;

    /* Used to actually perform a write. If the write end of the connection is open, then writes
    `size` bytes from `buffer` to the socket. */
    void perform_write(const void *buffer, size_t size);
};

/* The linux_tcp_listener_t is used to listen on a network port for incoming
connections. Create a linux_tcp_listener_t with some port and then call set_callback();
the provided callback will be called in a new coroutine every time something connects. */

class linux_tcp_listener_t : public linux_event_callback_t {
public:
    linux_tcp_listener_t(
        int port,
        boost::function<void(boost::scoped_ptr<linux_tcp_conn_t>&)> callback
        );
    ~linux_tcp_listener_t();

    // The constructor can throw this exception
    struct address_in_use_exc_t :
        public std::exception
    {
        const char *what() throw () {
            return "The requested port is already in use.";
        }
    };

private:
    // The socket to listen for connections on
    scoped_fd_t sock;

    // Sentry representing our registration with event loop
    linux_event_watcher_t event_watcher;

    // The callback to call when we get a connection
    boost::function<void(boost::scoped_ptr<linux_tcp_conn_t>&)> callback;

    /* accept_loop() runs in a separate coroutine. It repeatedly tries to accept
    new connections; when accept() blocks, then it waits for events from the
    event loop. When accept_loop_handler's destructor is called, accept_loop_handler
    stops accept_loop() by pulsing the signal. */
    boost::scoped_ptr<side_coro_handler_t> accept_loop_handler;
    void accept_loop(signal_t *);

    void handle(fd_t sock);

    /* event_watcher sends any error conditions to here */
    void on_event(int events);
    bool log_next_error;
};

#endif // __ARCH_IO_NETWORK_HPP__
<commit_msg>Fixed out-of-date documentation.<commit_after>#ifndef __ARCH_IO_NETWORK_HPP__
#define __ARCH_IO_NETWORK_HPP__

#include <vector>

#include "utils.hpp"
#include <boost/scoped_ptr.hpp>
#include "arch/runtime/event_queue.hpp"
#include "arch/io/io_utils.hpp"
#include "arch/address.hpp"
#include "concurrency/cond_var.hpp"
#include "concurrency/queue/unlimited_fifo.hpp"
#include "concurrency/semaphore.hpp"
#include "concurrency/coro_pool.hpp"
#include "perfmon_types.hpp"
#include "arch/io/event_watcher.hpp"
#include <boost/iterator/iterator_facade.hpp>
#include <stdexcept>
#include <stdarg.h>
#include <unistd.h>

class side_coro_handler_t;

/* linux_tcp_conn_t provides a disgusting wrapper around a TCP network connection. */

class linux_tcp_conn_t :
    public home_thread_mixin_t,
    private linux_event_callback_t {
public:
    friend class linux_tcp_listener_t;

    struct connect_failed_exc_t : public std::exception {
        const char *what() throw () {
            return "Could not make connection";
        }
    };

    /* TODO: One of these forms should be replaced by the other. */
    linux_tcp_conn_t(const char *host, int port);
    linux_tcp_conn_t(const ip_address_t &host, int port);

    /* Reading */

    struct read_closed_exc_t : public std::exception {
        const char *what() throw () {
            return "Network connection read end closed";
        }
    };

    /* If you know beforehand how many bytes you want to read, use read() with a byte buffer.
    Returns when the buffer is full, or throws read_closed_exc_t. */
    void read(void *buf, size_t size);

    // If you don't know how many bytes you want to read, but still
    // masochistically want to handle buffering yourself.  Makes at
    // most one call to ::read(), reads some data or throws
    // read_closed_exc_t. read_some() is guaranteed to return at least
    // one byte of data unless it throws read_closed_exc_t.
    size_t read_some(void *buf, size_t size);

    // If you don't know how many bytes you want to read, use peek()
    // and then, if you're satisfied, pop what you've read, or if
    // you're unsatisfied, read_more_buffered() and then try again.
    // Note that you should always call peek() before calling
    // read_more_buffered(), because there might be leftover data in
    // the peek buffer that might be enough for you.
    const_charslice peek() const;

    //you can also peek with a specific size (this is really just convenient
    //for some things and can in some cases avoid an unneeded copy
    const_charslice peek(size_t size);

    void pop(size_t len);

    //pop to the position the iterator has been incremented to
    class iterator;
    void pop(iterator &);

    void read_more_buffered();

    /* Call shutdown_read() to close the half of the pipe that goes from the peer to us. If there
    is an outstanding read() or peek_until() operation, it will throw read_closed_exc_t. */
    void shutdown_read();

    /* Returns false if the half of the pipe that goes from the peer to us has been closed. */
    bool is_read_open();

    /* Writing */

    struct write_closed_exc_t : public std::exception {
        const char *what() throw () {
            return "Network connection write end closed";
        }
    };

    /* write() writes 'size' bytes from 'buf' to the socket and blocks until it is done. Throws
    write_closed_exc_t if the write end of the pipe is closed before we can finish. */
    void write(const void *buf, size_t size);

    /* write_buffered() is like write(), but it might not send the data until flush_buffer*() or
    write() is called. Internally, it bundles together the buffered writes; this may improve
    performance. */
    void write_buffered(const void *buf, size_t size);

    void vwritef(const char *format, va_list args) {
        char buffer[1000];
        size_t bytes = vsnprintf(buffer, sizeof(buffer), format, args);
        rassert(bytes < sizeof(buffer));
        write(buffer, bytes);
    }

    void writef(const char *format, ...)
        __attribute__ ((format (printf, 2, 3))) {
        va_list args;
        va_start(args, format);
        vwritef(format, args);
        va_end(args);
    }

    void flush_buffer();   // Blocks until flush is done
    void flush_buffer_eventually();   // Blocks only if the queue is backed up

    /* Call shutdown_write() to close the half of the pipe that goes from us to the peer. If there
    is a write currently happening, it will get write_closed_exc_t. */
    void shutdown_write();

    /* Returns false if the half of the pipe that goes from us to the peer has been closed. */
    bool is_write_open();

    /* Put a `perfmon_rate_monitor_t` here if you want to record stats on how fast data is being
    transmitted over the network. */
    perfmon_rate_monitor_t *write_perfmon;

    /* Note that is_read_open() and is_write_open() must both be false1 before the socket is
    destroyed. */
    ~linux_tcp_conn_t();

public:
    /* iterator always you to handle the stream of data off the
     * socket with iterators, the iterator handles all of the buffering itself. The
     * impetus for this class comes from wanting to use network connection's with
     * Boost's spirit parser */

    class iterator
        : public boost::iterator_facade<iterator, const char, boost::forward_traversal_tag>
    {
    friend class linux_tcp_conn_t;
    private:
        linux_tcp_conn_t *source;
        bool end;
        size_t pos;
    private:
        int compare(iterator const& other) const;
    private:
    // boost iterator interface
        void increment();
        bool equal(iterator const& other);
        const char &dereference();
    public:
        iterator();
        iterator(linux_tcp_conn_t *, size_t);
        iterator(linux_tcp_conn_t *, bool);
        iterator(const iterator&);
        ~iterator();
        char operator*();
        void operator++();
        void operator++(int);
        bool operator==(const iterator&);
        bool operator!=(const iterator&);
        bool operator<(const iterator&);
    };

public:
    iterator begin();
    iterator end();

    // Changes the home_thread_mixin_t superclass's real_home_thread.
    void rethread(int);

private:
    explicit linux_tcp_conn_t(fd_t sock);   // Used by tcp_listener_t

    /* Note that this only gets called to handle error-events. Read and write
    events are handled through the linux_event_watcher_t. */
    void on_event(int events);

    void on_shutdown_read();
    void on_shutdown_write();

    scoped_fd_t sock;

    /* Object that we use to watch for events. It's NULL when we are not registered on any
    thread, and otherwise is an object that's valid for the current thread. */
    linux_event_watcher_t *event_watcher;

    /* True if there is a pending read or write */
    bool read_in_progress, write_in_progress;

    /* These are pulsed if and only if the read/write end of the connection has been closed. */
    cond_t read_closed, write_closed;

    /* Holds data that we read from the socket but hasn't been consumed yet */
    std::vector<char> read_buffer;

    /* Reads up to the given number of bytes, but not necessarily that many. Simple wrapper around
    ::read(). Returns the number of bytes read or throws read_closed_exc_t. Bypasses read_buffer. */
    size_t read_internal(void *buffer, size_t size);

    /* Buffer we are currently filling up with data that we want to write. When it reaches a
    certain size, we push it onto `write_queue`. */
    std::vector<char> write_buffer;

    /* Schedules old write buffer's contents to be flushed and swaps in a fresh write buffer.
    Blocks until it can acquire the `write_queue_limiter` semaphore, but doesn't wait for
    data to be completely written. */
    void internal_flush_write_buffer();

    /* Used to queue up buffers to write. The functions in `write_queue` will all be
    `boost::bind()`s of the `perform_write()` function below. */
    unlimited_fifo_queue_t<boost::function<void()> > write_queue;

    /* This semaphore prevents the write queue from getting arbitrarily big. */
    semaphore_t write_queue_limiter;

    /* Used to actually perform the writes. Only has one coroutine in it. */
    coro_pool_t write_coro_pool;

    /* Used to actually perform a write. If the write end of the connection is open, then writes
    `size` bytes from `buffer` to the socket. */
    void perform_write(const void *buffer, size_t size);
};

/* The linux_tcp_listener_t is used to listen on a network port for incoming
connections. Create a linux_tcp_listener_t with some port and then call set_callback();
the provided callback will be called in a new coroutine every time something connects. */

class linux_tcp_listener_t : public linux_event_callback_t {
public:
    linux_tcp_listener_t(
        int port,
        boost::function<void(boost::scoped_ptr<linux_tcp_conn_t>&)> callback
        );
    ~linux_tcp_listener_t();

    // The constructor can throw this exception
    struct address_in_use_exc_t :
        public std::exception
    {
        const char *what() throw () {
            return "The requested port is already in use.";
        }
    };

private:
    // The socket to listen for connections on
    scoped_fd_t sock;

    // Sentry representing our registration with event loop
    linux_event_watcher_t event_watcher;

    // The callback to call when we get a connection
    boost::function<void(boost::scoped_ptr<linux_tcp_conn_t>&)> callback;

    /* accept_loop() runs in a separate coroutine. It repeatedly tries to accept
    new connections; when accept() blocks, then it waits for events from the
    event loop. When accept_loop_handler's destructor is called, accept_loop_handler
    stops accept_loop() by pulsing the signal. */
    boost::scoped_ptr<side_coro_handler_t> accept_loop_handler;
    void accept_loop(signal_t *);

    void handle(fd_t sock);

    /* event_watcher sends any error conditions to here */
    void on_event(int events);
    bool log_next_error;
};

#endif // __ARCH_IO_NETWORK_HPP__
<|endoftext|>


<commit_before>#include "mesh_def.h"
#include <vcg/complex/algorithms/smooth.h>
#include <vcg/complex/algorithms/update/position.h>
#include <vcg/complex/algorithms/local_optimization/tri_edge_flip.h>

using namespace vcg;
using namespace std;

void LaplacianSmooth(uintptr_t _meshPtr, int step, bool useLaplacianWeights)
{
  MyMesh &m = * ((MyMesh*) _meshPtr);
  tri::UpdateTopology<MyMesh>::VertexFace(m);
  tri::Smooth<MyMesh>::VertexCoordLaplacian(m, step, false, useLaplacianWeights);
  m.UpdateBoxAndNormals();
}

void TaubinSmooth(uintptr_t _meshPtr, int step, float lambda, float mu)
{
  MyMesh &m = * ((MyMesh*) _meshPtr);
  tri::UpdateTopology<MyMesh>::VertexFace(m);
  tri::Smooth<MyMesh>::VertexCoordTaubin(m,step,lambda,mu,false);
  m.UpdateBoxAndNormals();
}

void RandomDisplacement(uintptr_t _m, float max_displacement, const bool normalDirected)
{
  MyMesh &m = *((MyMesh*) _m);
  math::MarsenneTwisterRNG rnd;
  tri::UpdateNormal<MyMesh>::NormalizePerVertex(m);
  rnd.initialize(time(NULL));
  for(unsigned int i = 0; i< m.vert.size(); i++){
    if(normalDirected)
      m.vert[i].P() +=  m.vert[i].N()* rnd.generateRange(-1.0f,1.0f)*max_displacement;
    else
      m.vert[i].P() +=  math::GeneratePointInUnitBallUniform<float,math::MarsenneTwisterRNG>(rnd)*max_displacement;
  }
  m.UpdateBoxAndNormals();
}

void Scale(uintptr_t _m, float x,float y, float z,bool uniformFlag, bool unitboxFlag)
{
  MyMesh &m = *((MyMesh*) _m);
  if(uniformFlag) z=y=x;
  if(unitboxFlag)
  {
    float maxdim=math::Max(m.bbox.DimX(),m.bbox.DimY(),m.bbox.DimZ());
    z=y=x=1.0f/maxdim;
  }
  tri::UpdatePosition<MyMesh>::Scale(m, MyMesh::CoordType(x,y,z));
  m.UpdateBoxAndNormals();
}

void Rotate(uintptr_t _m)
{
    MyMesh &m = *((MyMesh*) _m);
}

void Translate(uintptr_t _m,float x,float y, float z, bool centerToOriginFlag)
{
  MyMesh &m = *((MyMesh*) _m);
  if(centerToOriginFlag)
    tri::UpdatePosition<MyMesh>::Translate(m,-m.bbox.Center());
  else
    tri::UpdatePosition<MyMesh>::Translate(m,MyMesh::CoordType(x,y,z));
  m.UpdateBoxAndNormals();
}

class QRadiiEFlip :
public vcg::tri::PlanarEdgeFlip<MyMesh, QRadiiEFlip, QualityRadii>
{
public:
  QRadiiEFlip(PosType pos, int mark,BaseParameterClass *pp) :
    vcg::tri::PlanarEdgeFlip<MyMesh, QRadiiEFlip, QualityRadii>(pos, mark,pp) {}
};

void FlipRelaxOptimize(uintptr_t _m, int iterNum, float CoplanarAngleThresholdDeg)
{
  MyMesh &m = *((MyMesh*) _m);
  tri::Allocator<MyMesh>::CompactEveryVector(m);
  tri::UpdateTopology<MyMesh>::FaceFace(m);
  tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
  tri::PlanarEdgeFlipParameter pp;
  pp.CoplanarAngleThresholdDeg = CoplanarAngleThresholdDeg;
  for(int i=0;i<iterNum;++i)
  {
    LocalOptimization<MyMesh> optimiz(m,&pp);
    float limit = -std::numeric_limits<float>::epsilon();
    optimiz.Init<QRadiiEFlip>();
    optimiz.SetTargetMetric(limit);
    optimiz.DoOptimization();
    printf("Completed optimization; performed ops %i\n",optimiz.nPerfmormedOps);
    optimiz.h.clear();
    tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
    tri::Smooth<MyMesh>::VertexCoordLaplacianBlend(m, 1, 0.3f,false);
  }
  m.UpdateBoxAndNormals();
}

void TransformPluginTEST()
{
    MyMesh m0,m1,m2,m3,m4,m5;
    tri::Sphere(m0,3);
    LaplacianSmooth(uintptr_t(&m0),3,true);
    tri::Sphere(m1,3);
    TaubinSmooth(uintptr_t(&m1),5,0.33f,-0.34f);
    tri::Sphere(m2,3);
    RandomDisplacement(uintptr_t(&m2),0.01f,false);
    tri::Sphere(m3,3);
    Scale(uintptr_t(&m3),2,3,4,false,false); //normal scaling with factor for x,y,z
    tri::Sphere(m4,3);
    Scale(uintptr_t(&m4),2,3,4,true,false); //uniform scaling
    tri::Sphere(m5,3);
    Scale(uintptr_t(&m5),2,3,4,false,true); //scale to unit box
}

#ifdef __EMSCRIPTEN__
EMSCRIPTEN_BINDINGS(MLSmoothPlugin) {
    emscripten::function("LaplacianSmooth", &LaplacianSmooth);
    emscripten::function("TaubinSmooth", &TaubinSmooth);
    emscripten::function("RandomDisplacement", &RandomDisplacement);
    emscripten::function("Scale", &Scale);
    emscripten::function("Translate", &Translate);
    emscripten::function("FlipRelaxOptimize", &FlipRelaxOptimize);
}
#endif
<commit_msg>updated to the last change in the vcg<commit_after>#include "mesh_def.h"
#include <vcg/complex/algorithms/smooth.h>
#include <vcg/complex/algorithms/update/position.h>
#include <vcg/complex/algorithms/local_optimization/tri_edge_flip.h>

using namespace vcg;
using namespace std;

void LaplacianSmooth(uintptr_t _meshPtr, int step, bool useLaplacianWeights)
{
  MyMesh &m = * ((MyMesh*) _meshPtr);
  tri::UpdateTopology<MyMesh>::VertexFace(m);
  tri::Smooth<MyMesh>::VertexCoordLaplacian(m, step, false, useLaplacianWeights);
  m.UpdateBoxAndNormals();
}

void TaubinSmooth(uintptr_t _meshPtr, int step, float lambda, float mu)
{
  MyMesh &m = * ((MyMesh*) _meshPtr);
  tri::UpdateTopology<MyMesh>::VertexFace(m);
  tri::Smooth<MyMesh>::VertexCoordTaubin(m,step,lambda,mu,false);
  m.UpdateBoxAndNormals();
}

void RandomDisplacement(uintptr_t _m, float max_displacement, const bool normalDirected)
{
  MyMesh &m = *((MyMesh*) _m);
  math::MarsenneTwisterRNG rnd;
  tri::UpdateNormal<MyMesh>::NormalizePerVertex(m);
  rnd.initialize(time(NULL));
  for(unsigned int i = 0; i< m.vert.size(); i++){
    if(normalDirected)
      m.vert[i].P() +=  m.vert[i].N()* rnd.generateRange(-1.0f,1.0f)*max_displacement;
    else
      m.vert[i].P() +=  math::GeneratePointInUnitBallUniform<float,math::MarsenneTwisterRNG>(rnd)*max_displacement;
  }
  m.UpdateBoxAndNormals();
}

void Scale(uintptr_t _m, float x,float y, float z,bool uniformFlag, bool unitboxFlag)
{
  MyMesh &m = *((MyMesh*) _m);
  if(uniformFlag) z=y=x;
  if(unitboxFlag)
  {
    float maxdim=math::Max(m.bbox.DimX(),m.bbox.DimY(),m.bbox.DimZ());
    z=y=x=1.0f/maxdim;
  }
  tri::UpdatePosition<MyMesh>::Scale(m, MyMesh::CoordType(x,y,z));
  m.UpdateBoxAndNormals();
}

void Rotate(uintptr_t _m)
{
    MyMesh &m = *((MyMesh*) _m);
}

void Translate(uintptr_t _m,float x,float y, float z, bool centerToOriginFlag)
{
  MyMesh &m = *((MyMesh*) _m);
  if(centerToOriginFlag)
    tri::UpdatePosition<MyMesh>::Translate(m,-m.bbox.Center());
  else
    tri::UpdatePosition<MyMesh>::Translate(m,MyMesh::CoordType(x,y,z));
  m.UpdateBoxAndNormals();
}

class QRadiiEFlip :
public vcg::tri::PlanarEdgeFlip<MyMesh, QRadiiEFlip, QualityRadii>
{
public:
  QRadiiEFlip(PosType pos, int mark,BaseParameterClass *pp) :
    vcg::tri::PlanarEdgeFlip<MyMesh, QRadiiEFlip, QualityRadii>(pos, mark,pp) {}
};

void FlipRelaxOptimize(uintptr_t _m, int iterNum, float CoplanarAngleThresholdDeg)
{
  MyMesh &m = *((MyMesh*) _m);
  tri::Allocator<MyMesh>::CompactEveryVector(m);
  tri::UpdateTopology<MyMesh>::FaceFace(m);
  tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
  tri::PlanarEdgeFlipParameter pp;
  pp.CoplanarAngleThresholdDeg = CoplanarAngleThresholdDeg;
  for(int i=0;i<iterNum;++i)
  {
    LocalOptimization<MyMesh> optimiz(m,&pp);
    float limit = -std::numeric_limits<float>::epsilon();
    optimiz.Init<QRadiiEFlip>();
    optimiz.SetTargetMetric(limit);
    optimiz.DoOptimization();
    printf("Completed optimization; performed ops %i\n",optimiz.nPerformedOps);
    optimiz.h.clear();
    tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
    tri::Smooth<MyMesh>::VertexCoordLaplacianBlend(m, 1, 0.3f,false);
  }
  m.UpdateBoxAndNormals();
}

void TransformPluginTEST()
{
    MyMesh m0,m1,m2,m3,m4,m5;
    tri::Sphere(m0,3);
    LaplacianSmooth(uintptr_t(&m0),3,true);
    tri::Sphere(m1,3);
    TaubinSmooth(uintptr_t(&m1),5,0.33f,-0.34f);
    tri::Sphere(m2,3);
    RandomDisplacement(uintptr_t(&m2),0.01f,false);
    tri::Sphere(m3,3);
    Scale(uintptr_t(&m3),2,3,4,false,false); //normal scaling with factor for x,y,z
    tri::Sphere(m4,3);
    Scale(uintptr_t(&m4),2,3,4,true,false); //uniform scaling
    tri::Sphere(m5,3);
    Scale(uintptr_t(&m5),2,3,4,false,true); //scale to unit box
}

#ifdef __EMSCRIPTEN__
EMSCRIPTEN_BINDINGS(MLSmoothPlugin) {
    emscripten::function("LaplacianSmooth", &LaplacianSmooth);
    emscripten::function("TaubinSmooth", &TaubinSmooth);
    emscripten::function("RandomDisplacement", &RandomDisplacement);
    emscripten::function("Scale", &Scale);
    emscripten::function("Translate", &Translate);
    emscripten::function("FlipRelaxOptimize", &FlipRelaxOptimize);
}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_X86_INTREGS_HH__
#define __ARCH_X86_INTREGS_HH__

namespace X86ISA
{
    enum IntRegIndex
    {
        INTREG_RAX,
        INTREG_RCX,
        INTREG_RDX,
        INTREG_RBX,
        INTREG_RSP,
        INTREG_RBP,
        INTREG_RSI,
        INTREG_RDI,
        INTREG_R8W,
        INTREG_R9W,
        INTREG_R10W,
        INTREG_R11W,
        INTREG_R12W,
        INTREG_R13W,
        INTREG_R14W,
        INTREG_R15W,
        NUM_INTREGS
    };
};

#endif // __ARCH_X86_INTERRUPTS_HH__
<commit_msg>Added all the different variations of the register names.<commit_after>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_X86_INTREGS_HH__
#define __ARCH_X86_INTREGS_HH__

namespace X86ISA
{
    enum IntRegIndex
    {
        INTREG_RAX,
        INTREG_EAX = INTREG_RAX,
        INTREG_AX = INTREG_RAX,
        INTREG_AL = INTREG_RAX,
        INTREG_AH = INTREG_RAX,

        INTREG_RCX,
        INTREG_ECX = INTREG_RCX,
        INTREG_CX = INTREG_RCX,
        INTREG_CL = INTREG_RCX,
        INTREG_CH = INTREG_RCX,

        INTREG_RDX,
        INTREG_EDX = INTREG_RDX,
        INTREG_DX = INTREG_RDX,
        INTREG_DL = INTREG_RDX,
        INTREG_DH = INTREG_RDX,

        INTREG_RBX,
        INTREG_EBX = INTREG_RBX,
        INTREG_BX = INTREG_RBX,
        INTREG_BL = INTREG_RBX,
        INTREG_BH = INTREG_RBX,

        INTREG_RSP,
        INTREG_ESP = INTREG_RSP,
        INTREG_SP = INTREG_RSP,
        INTREG_SPL = INTREG_RSP,

        INTREG_RBP,
        INTREG_EBP = INTREG_RBP,
        INTREG_BP = INTREG_RBP,
        INTREG_BPL = INTREG_RBP,

        INTREG_RSI,
        INTREG_ESI = INTREG_RSI,
        INTREG_SI = INTREG_RSI,
        INTREG_SIL = INTREG_RSI,

        INTREG_RDI,
        INTREG_EDI = INTREG_RDI,
        INTREG_DI = INTREG_RDI,
        INTREG_DIL = INTREG_RDI,

        INTREG_R8,
        INTREG_R8D = INTREG_R8,
        INTREG_R8W = INTREG_R8,
        INTREG_R8B = INTREG_R8,

        INTREG_R9,
        INTREG_R9D = INTREG_R9,
        INTREG_R9W = INTREG_R9,
        INTREG_R9B = INTREG_R9,

        INTREG_R10,
        INTREG_R10D = INTREG_R10,
        INTREG_R10W = INTREG_R10,
        INTREG_R10B = INTREG_R10,

        INTREG_R11,
        INTREG_R11D = INTREG_R11,
        INTREG_R11W = INTREG_R11,
        INTREG_R11B = INTREG_R11,

        INTREG_R12,
        INTREG_R12D = INTREG_R12,
        INTREG_R12W = INTREG_R12,
        INTREG_R12B = INTREG_R12,

        INTREG_R13,
        INTREG_R13D = INTREG_R13,
        INTREG_R13W = INTREG_R13,
        INTREG_R13B = INTREG_R13,

        INTREG_R14,
        INTREG_R14D = INTREG_R14,
        INTREG_R14W = INTREG_R14,
        INTREG_R14B = INTREG_R14,

        INTREG_R15,
        INTREG_R15D = INTREG_R15,
        INTREG_R15W = INTREG_R15,
        INTREG_R15B = INTREG_R15,

        NUM_INTREGS
    };
};

#endif // __ARCH_X86_INTERRUPTS_HH__
<|endoftext|>


<commit_before>
#include <utility>
#include <set>

#include <tapas/common.h>
#include <tapas/test.h>
#include <tapas/distance.h>

SETUP_TEST;

using V = tapas::Vec<1, double>;

bool Close(double a, double b) {
  return fabs(a - b) < 1e-6;
}

bool Close(double a, V b) {
  return fabs(a - b[0]) < 1e-6;
}

bool Close(V a, double b) {
  return fabs(a[0] - b) < 1e-6;
}

bool Close(V a, V b) {
  return fabs(a[0] - b[0]) < 1e-10;
}

void Test_Center() {
  V tmax = {1}, tmin = {-1};
  V smax, smin, dist, dist_ans;
  V sctr, tctr;
  const V R = 0.5;

  // Case 1
  // |---+---|                 src
  //   |---+-----------------| trg
  //  -1                     1
  sctr = -0.8;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = -0.75; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0.05 * 0.05;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 2
  //     |---+---|             src
  //   |-----+---------------| trg
  //  -1                     1
  sctr = -0.7;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = sctr; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0 * 0;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 3
  //               |---+---|   src
  //   |---------------+-----| trg
  //  -1                     1
  sctr = 0.4;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = sctr; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0 * 0;
  std::cout << "dist = " << sqrt(dist[0]) << std::endl;
  std::cout << "ditt_ans = " << sqrt(dist_ans[0]) << std::endl;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 4
  //                   |---+---| src
  //   |-----------------+---|   trg
  //  -1                     1
  sctr = 0.4;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = sctr; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0 * 0;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 5
  //                           |---+---| src
  //   |-----------------+---|           trg
  //  -1                     1
  sctr = 0.4;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = sctr; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0 * 0;
  ASSERT_TRUE(Close(dist, dist_ans));
}

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);

  Test_Center();

  TEST_REPORT_RESULT();

  MPI_Finalize();
  return (TEST_SUCCESS() ? 0 : 1);
}
<commit_msg>added distance test<commit_after>
#include <utility>
#include <set>

#include <tapas/common.h>
#include <tapas/test.h>
#include <tapas/distance.h>

SETUP_TEST;

using V = tapas::Vec<1, double>;

bool Close(double a, double b) {
  return fabs(a - b) < 1e-6;
}

bool Close(double a, V b) {
  return fabs(a - b[0]) < 1e-6;
}

bool Close(V a, double b) {
  return fabs(a[0] - b) < 1e-6;
}

bool Close(V a, V b) {
  return fabs(a[0] - b[0]) < 1e-10;
}

void Test_Center() {
  V tmax = {1}, tmin = {-1};
  V smax, smin, dist, dist_ans;
  V sctr, tctr;
  V R = 0.5;

  // Case 1
  // |---+---|                 src
  //   |---+-----------------| trg
  //  -1                     1
  sctr = -0.8;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = -0.75; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0.05 * 0.05;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 2
  //     |---+---|             src
  //   |-----+---------------| trg
  //  -1                     1
  sctr = -0.7;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = sctr; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0 * 0;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 3
  //               |---+---|   src
  //   |---------------+-----| trg
  //  -1                     1
  sctr = 0.4;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = sctr; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0 * 0;
  std::cout << "dist = " << sqrt(dist[0]) << std::endl;
  std::cout << "ditt_ans = " << sqrt(dist_ans[0]) << std::endl;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 4
  //                   |---+---| src
  //   |-----------------+---|   trg
  //  -1                     1
  sctr = 0.4;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = sctr; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0 * 0;
  //std::cout << "dist = " << sqrt(dist[0]) << std::endl;
  //std::cout << "ditt_ans = " << sqrt(dist_ans[0]) << std::endl;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 5
  //                           |---+---| src
  //   |-----------------+---|           trg
  //  -1                     1
  sctr = 0.4;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = sctr; // answer
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0 * 0;
  ASSERT_TRUE(Close(dist, dist_ans));

  // Case 6
  // |-------------+-------------| src
  //   |----------+----------|   trg
  //  -1                     1
  R = 2.5;
  sctr = 0.1;
  smin = sctr - R/2;
  smax = sctr + R/2;
  tctr = 0.0;
  dist = tapas::Distance<tapas::CenterClass, double>::CalcApprox(tmax, tmin, smax, smin);
  dist_ans = 0.1 * 0.1;
  //std::cout << "dist = " << sqrt(dist[0]) << std::endl;
  //std::cout << "ditt_ans = " << sqrt(dist_ans[0]) << std::endl;
  ASSERT_TRUE(Close(dist, dist_ans));

}

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);

  Test_Center();

  TEST_REPORT_RESULT();

  MPI_Finalize();
  return (TEST_SUCCESS() ? 0 : 1);
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#ifdef __APPLE__
#  include <libkern/OSByteOrder.h>
#  define htobe32(x) OSSwapHostToBigInt32(x)
#  define htobe64(x) OSSwapHostToBigInt64(x)
#else
#  include <endian.h>
#endif

#include "receiver.h"
#include "stream.h"

#include <cstdio>
#include <inttypes.h>

//////////////////////////////////////////////////////////////////////
// Test utility functions.
//////////////////////////////////////////////////////////////////////

static struct Receiver* create_test_receiver()
{
    const int num_buffers_max = 1;
    const int num_times_in_buffer = 4;
    const int num_threads_recv = 1;
    const int num_threads_write = 1;
    const int num_streams = 1;
    const unsigned short int port_start = 41000;
    const int num_channels_per_file = 1;
    const char* output_root = "";
    struct Receiver* receiver = receiver_create(num_buffers_max,
            num_times_in_buffer, num_threads_recv, num_threads_write,
            num_streams, port_start, num_channels_per_file, output_root);
    return receiver;
}

//////////////////////////////////////////////////////////////////////
// Tests.
//////////////////////////////////////////////////////////////////////

TEST(Receiver, test_create)
{
    struct Receiver* receiver = create_test_receiver();
    ASSERT_TRUE(receiver != NULL);
    receiver_free(receiver);
}

TEST(Stream, test_stream_decode)
{
    // Verify stream_decode() function can handle a simple SPEAD packet.

    // SPEAD packet item IDs.
    const unsigned int item_ids[] = {
        0x1,    // Heap counter.
        0x2,    // Heap size.
        0x3     // Heap offset.
    };

    // Dummy values for items.
    const int item_val[] = {
        4,
        10,
        55
    };
    const unsigned int num_items = sizeof(item_ids) / sizeof(unsigned int);

    // Allocate memory for a SPEAD packet.
    unsigned char* buf = (unsigned char*) malloc(8 + num_items * 8);
    ASSERT_TRUE(buf != NULL);

    // Define SPEAD flavour.
    const unsigned char heap_address_bits = 48;
    const unsigned char item_id_bits = 64 - heap_address_bits - 1;

    // Construct SPEAD packet header.
    buf[0] = 'S';
    buf[1] = 4;
    buf[2] = (item_id_bits + 1) / 8;
    buf[3] = heap_address_bits / 8;
    buf[4] = 0;
    buf[5] = 0;
    buf[6] = 0;
    buf[7] = (unsigned char) num_items;

    // Construct SPEAD packet payload containing items in
    // "immediate addressing mode".
    uint64_t* items = (uint64_t*) &buf[8];
    for (unsigned int i = 0; i < num_items; i++)
    {
        const uint64_t item_id = (uint64_t) item_ids[i];
        const uint64_t item_addr_or_val = (uint64_t) item_val[i];
        const uint64_t item =
                (1ull << 63) |
                (item_id << heap_address_bits) |
                item_addr_or_val;
        items[i] = htobe64(item);
    }

    // Create a test receiver.
    struct Receiver* receiver = create_test_receiver();
    ASSERT_TRUE(receiver != NULL);

    // Call stream_decode().
    stream_decode(receiver->streams[0], buf, 0);

    // Clean up.
    receiver_free(receiver);
    free(buf);
}
<commit_msg>Initial commit of the feature/recv_unit_test branch<commit_after>#include <gtest/gtest.h>

#ifdef __APPLE__
#  include <libkern/OSByteOrder.h>
#  define htobe32(x) OSSwapHostToBigInt32(x)
#  define htobe64(x) OSSwapHostToBigInt64(x)
#else
#  include <endian.h>
#endif

#include "receiver.h"
#include "stream.h"

#include <cstdio>
#include <inttypes.h>

//////////////////////////////////////////////////////////////////////
// Test utility functions.
//////////////////////////////////////////////////////////////////////

static struct Receiver* create_test_receiver()
{
    const int num_buffers_max = 1;
    const int num_times_in_buffer = 4;
    const int num_threads_recv = 1;
    const int num_threads_write = 1;
    const int num_streams = 1;
    const unsigned short int port_start = 41000;
    const int num_channels_per_file = 1;
    const char* output_root = "";
    struct Receiver* receiver = receiver_create(num_buffers_max,
            num_times_in_buffer, num_threads_recv, num_threads_write,
            num_streams, port_start, num_channels_per_file, output_root);
    return receiver;
}

//////////////////////////////////////////////////////////////////////
// Tests.
//////////////////////////////////////////////////////////////////////

TEST(Receiver, test_create)
{
    struct Receiver* receiver = create_test_receiver();
    ASSERT_TRUE(receiver != NULL);
    receiver_free(receiver);
}

TEST(Stream, test_stream_decode)
{
    // Verify stream_decode() function can handle a simple SPEAD packet.

    // SPEAD packet item IDs.
    const unsigned int item_ids[] = {
        0x1,    // Heap counter.
        0x2,    // Heap size.
        0x3     // Heap offset.
    };

    // Dummy values for items.
    const int item_val[] = {
        4,
        10,
        55
    };
    const unsigned int num_items = sizeof(item_ids) / sizeof(unsigned int);

    // Allocate memory for a SPEAD packet.
    unsigned char* buf = (unsigned char*) malloc(8 + num_items * 8);
    ASSERT_TRUE(buf != NULL);

    // Define SPEAD flavour.
    const unsigned char heap_address_bits = 48;
    const unsigned char item_id_bits = 64 - heap_address_bits - 1;

    // Construct SPEAD packet header.
    buf[0] = 'S';
    buf[1] = 4;
    buf[2] = (item_id_bits + 1) / 8;
    buf[3] = heap_address_bits / 8;
    buf[4] = 0;
    buf[5] = 0;
    buf[6] = 0;
    buf[7] = (unsigned char) num_items;

    // Construct SPEAD packet payload containing items in
    // "immediate addressing mode".
    uint64_t* items = (uint64_t*) &buf[8];
    for (unsigned int i = 0; i < num_items; i++)
    {
        const uint64_t item_id = (uint64_t) item_ids[i];
        const uint64_t item_addr_or_val = (uint64_t) item_val[i];
        const uint64_t item =
                (1ull << 63) |
                (item_id << heap_address_bits) |
                item_addr_or_val;
        items[i] = htobe64(item);
    }

    // Create a test receiver.
    struct Receiver* receiver = create_test_receiver();
    ASSERT_TRUE(receiver != NULL);

    // Call stream_decode().
    stream_decode(receiver->streams[0], buf, 0);

    // Clean up.
    receiver_free(receiver);
    free(buf);
}

TEST(Stream, test_stream_receive)
{
    /* Verify stream_decode() function and verify if correct
    data is received */

    // ADD DESCRIPTOR AND OTHER IDS
    // SPEAD packet item IDs.
    const unsigned int item_ids[] = {
        0x1,    // Heap counter.
        0x2,    // Heap size.
        0x3,    // Heap offset.
        0x6000,
        0x6001
        // 0x6005,
        // 0x6008,
        // 0x600A
    };

    // NEED TO FIGURE OUT HOW TO DO FLOOR IN C
    // ADD DESCRIPTOR AND OTHER VALUES
    //num_baselines = (512 * 513) // 2
    // Dummy values for items.
    const int item_val[] = {
        4,
        10,
        55,
        1,
        0

    };
    const unsigned int num_items = sizeof(item_ids) / sizeof(unsigned int);

    // Allocate memory for a SPEAD packet.
    unsigned char* buf = (unsigned char*) malloc(8 + num_items * 8);
    ASSERT_TRUE(buf != NULL);

    // Define SPEAD flavour.
    const unsigned char heap_address_bits = 48;
    const unsigned char item_id_bits = 64 - heap_address_bits - 1;

    // Construct SPEAD packet header.
    buf[0] = 'S';
    buf[1] = 4;
    buf[2] = (item_id_bits + 1) / 8;
    buf[3] = heap_address_bits / 8;
    buf[4] = 0;
    buf[5] = 0;
    buf[6] = 0;
    buf[7] = (unsigned char) num_items;

    // Construct SPEAD packet payload containing items in
    // "immediate addressing mode".
    uint64_t* items = (uint64_t*) &buf[8];
    for (unsigned int i = 0; i < num_items; i++)
    {
        const uint64_t item_id = (uint64_t) item_ids[i];
        const uint64_t item_addr_or_val = (uint64_t) item_val[i];
        //printf("Item Value: %i\n", item_val[i]);
        const uint64_t item =
                (1ull << 63) |
                (item_id << heap_address_bits) |
                item_addr_or_val;
        items[i] = htobe64(item);
    }

    // Create a test receiver.
    struct Receiver* receiver = create_test_receiver();
    ASSERT_TRUE(receiver != NULL);

    // Call stream_decode().
    stream_decode(receiver->streams[0], buf, 0);
    printf("Heap count - %i\n", receiver->streams[0]->heap_count);
    printf("BUffer Len - %i\n", receiver->streams[0]->buffer_len);
    printf("Num buffers - %i\n", receiver->num_buffers);
    printf("completed_streams - %i\n", receiver->completed_streams);
    printf("max_num_buffers - %i\n", receiver->max_num_buffers);
    printf("num_baselines - %i\n", receiver->num_baselines);
    // printf("buffer_id - %i\n", receiver->buffers[0]->buffer_id);
    // struct Buffer* buff = receiver->buffers[0];
    // printf("Buf %i", buff->buffer_id);

    // Clean up.
    receiver_free(receiver);
    free(buf);
}<|endoftext|>


<commit_before>/***********************************************************************
    filename:   Sample_FirstWindow.cpp
    created:    10/3/2005
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "Sample_FirstWindow.h"
#include "CEGUI.h"

int main(int /*argc*/, char* /*argv*/[])
{
    // This is a basic start-up for the sample application which is
    // object orientated in nature, so we just need an instance of
    // the CEGuiSample based object and then tell that sample application
    // to run.  All of the samples will use code similar to this in the
    // main/WinMain function.
    FirstWindowSample app;
    return app.run();
}

/*************************************************************************
    Sample specific initialisation goes here.
*************************************************************************/
bool FirstWindowSample::initialiseSample()
{
    using namespace CEGUI;

    // CEGUI relies on various systems being set-up, so this is what we do
    // here first.
    //
    // Note that is is possible, and even usual, for most of these steps to
    // be done automatically via a "scheme" definition, or even from the
    // cegui.conf configuration file, however for completeness, and as an
    // example, virtually everything is being done manually in this example
    // code.

    // Imagesets area a collection of named areas within a texture or image
    // file.  Each area becomes an Image, and has a unique name by which it
    // can be referenced.  This sample is using the TaharezLook widgets, and
    // these rely upon the TaharezLook Imageset; so we must load this in
    // before doing anything else.  Note that the Imageset would normally be
    // specified as part of a scheme file, although as this example is
    // demonstrating, it is not a requirement.
    //
    // Load TaharezLook imageset by making use of the ImagesetManager singleton.
    Imageset& taharezImages = ImagesetManager::getSingleton().create("TaharezLook.imageset");

    // The next thing we do is to set a default mouse cursor image.  This is
    // not strictly essential, although it is nice to always have a visible
    // cursor if a window or widget does not explicitly set one of its own.
    //
    // The TaharezLook Imageset contains an Image named "MouseArrow" which is
    // the ideal thing to have as a defult mouse cursor image.
    System::getSingleton().setDefaultMouseCursor(&taharezImages.getImage("MouseArrow"));

    // Now we have the gui imagery side of thigs set up, we should load in a font.
    // You should always load in at least one font, this is to ensure that there
    // is a default available for any gui element which needs to draw text.
    // The first font you load is automatically set as the initial default font,
    // although you can change the default later on if so desired.  Again, it is
    // possible to list fonts to be automatically loaded as part of a scheme, so
    // this step may not usually be performed explicitly.
    //
    // Fonts are loaded via the FontManager singleton.
    FontManager::getSingleton().create("Commonwealth-10.font");

    // The widgets that we will be using for this sample are the TaharezLook widgets,
    // and to enable us to use this 'skin' we must load the xml specification - which
    // within cegui is known as a "looknfeel" file.
    //
    // We load the looknfeel via the WidgetLookManager singleton.
    WidgetLookManager::getSingleton().parseLookNFeelSpecification("TaharezLook.looknfeel");

    // The final step of basic initialisation that is usually peformed is
    // registering some widgets with the system via a scheme file.  The scheme
    // basically states the name of a dynamically loaded module that contains the
    // widget classes that we wish to use.  As stated previously, a scheme can actually
    // conatin much more information, though for the sake of this first example, we
    // load a scheme which only contains what is required to register some widgets.
    //
    // Use the SchemeManager singleton to load in a scheme that registers widgets
    // for TaharezLook.
    SchemeManager::getSingleton().create("TaharezLookWidgets.scheme");

    // Now the system is initialised, we can actually create some UI elements, for
    // this first example, a full-screen 'root' window is set as the active GUI
    // sheet, and then a simple frame window will be created and attached to it.

    // All windows and widgets are created via the WindowManager singleton.
    WindowManager& winMgr = WindowManager::getSingleton();

    // Here we create a "DeafultWindow".  This is a native type, that is, it does
    // not have to be loaded via a scheme, it is always available.  One common use
    // for the DefaultWindow is as a generic container for other windows.  Its
    // size defaults to 1.0f x 1.0f using the Relative metrics mode, which means
    // when it is set as the root GUI sheet window, it will cover the entire display.
    // The DefaultWindow does not perform any rendering of its own, so is invisible.
    //
    // Create a DefaultWindow called 'Root'.
    DefaultWindow* root = (DefaultWindow*)winMgr.createWindow("DefaultWindow", "Root");

    // set the GUI root window (also known as the GUI "sheet"), so the gui we set up
    // will be visible.
    System::getSingleton().setGUISheet(root);

    // A FrameWindow is a window with a frame and a titlebar which may be moved around
    // and resized.
    //
    // Create a FrameWindow in the TaharezLook style, and name it 'Demo Window'
    FrameWindow* wnd = (FrameWindow*)winMgr.createWindow("TaharezLook/FrameWindow", "Demo Window");

    // Here we attach the newly created FrameWindow to the previously created
    // DefaultWindow which we will be using as the root of the displayed gui.
    root->addChildWindow(wnd);

    // Windows are in Relative metrics mode by default.  This means that we can
    // specify sizes and positions without having to know the exact pixel size
    // of the elements in advance.  The relative metrics mode co-ordinates are
    // relative to the parent of the window where the co-ordinates are being set.
    // This means that if 0.5f is specified as the width for a window, that window
    // will be half as its parent window.
    //
    // Here we set the FrameWindow so that it is half the size of the display,
    // and centered within the display.
    wnd->setPosition(UVector2(cegui_reldim(0.25f), cegui_reldim( 0.25f)));
    wnd->setSize(UVector2(cegui_reldim(0.5f), cegui_reldim( 0.5f)));

    // now we set the maximum and minum sizes for the new window.  These are
    // specified using relative co-ordinates, but the important thing to note
    // is that these settings are aways relative to the display rather than the
    // parent window.
    //
    // here we set a maximum size for the FrameWindow which is equal to the size
    // of the display, and a minimum size of one tenth of the display.
    wnd->setMaxSize(UVector2(cegui_reldim(1.0f), cegui_reldim( 1.0f)));
    wnd->setMinSize(UVector2(cegui_reldim(0.1f), cegui_reldim( 0.1f)));

    // As a final step in the initialisation of our sample window, we set the window's
    // text to "Hello World!", so that this text will appear as the caption in the
    // FrameWindow's titlebar.
    wnd->setText("Hello World!");

    // return true so that the samples framework knows that initialisation was a
    // success, and that it should now run the sample.
    return true;
}

/*************************************************************************
    Cleans up resources allocated in the initialiseSample call.
*************************************************************************/
void FirstWindowSample::cleanupSample()
{
    // nothing to do here!
}
<commit_msg>Modify FirstWindow sample so it's a more realistic example of the way things are done (as opposed to loading all that stuff manually, that nobody does).<commit_after>/***********************************************************************
    filename:   Sample_FirstWindow.cpp
    created:    10/3/2005
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "Sample_FirstWindow.h"
#include "CEGUI.h"

int main(int /*argc*/, char* /*argv*/[])
{
    // This is a basic start-up for the sample application which is
    // object orientated in nature, so we just need an instance of
    // the CEGuiSample based object and then tell that sample application
    // to run.  All of the samples will use code similar to this in the
    // main/WinMain function.
    FirstWindowSample app;
    return app.run();
}

/*************************************************************************
    Sample specific initialisation goes here.
*************************************************************************/
bool FirstWindowSample::initialiseSample()
{
    using namespace CEGUI;

    // CEGUI relies on various systems being set-up, so this is what we do
    // here first.
    //
    // The first thing to do is load a CEGUI 'scheme' this is basically a file
    // that groups all the required resources and definitions for a particular
    // skin so they can be loaded / initialised easily
    //
    // So, we use the SchemeManager singleton to load in a scheme that loads the
    // imagery and registers widgets for the TaharezLook skin.  This scheme also
    // loads in a font that gets used as the system default.
    SchemeManager::getSingleton().create("TaharezLook.scheme");

    // The next thing we do is to set a default mouse cursor image.  This is
    // not strictly essential, although it is nice to always have a visible
    // cursor if a window or widget does not explicitly set one of its own.
    //
    // The TaharezLook Imageset contains an Image named "MouseArrow" which is
    // the ideal thing to have as a defult mouse cursor image.
    System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");

    // Now the system is initialised, we can actually create some UI elements, for
    // this first example, a full-screen 'root' window is set as the active GUI
    // sheet, and then a simple frame window will be created and attached to it.

    // All windows and widgets are created via the WindowManager singleton.
    WindowManager& winMgr = WindowManager::getSingleton();

    // Here we create a "DeafultWindow".  This is a native type, that is, it does
    // not have to be loaded via a scheme, it is always available.  One common use
    // for the DefaultWindow is as a generic container for other windows.  Its
    // size defaults to 1.0f x 1.0f using the Relative metrics mode, which means
    // when it is set as the root GUI sheet window, it will cover the entire display.
    // The DefaultWindow does not perform any rendering of its own, so is invisible.
    //
    // Create a DefaultWindow called 'Root'.
    DefaultWindow* root = (DefaultWindow*)winMgr.createWindow("DefaultWindow", "Root");

    // set the GUI root window (also known as the GUI "sheet"), so the gui we set up
    // will be visible.
    System::getSingleton().setGUISheet(root);

    // A FrameWindow is a window with a frame and a titlebar which may be moved around
    // and resized.
    //
    // Create a FrameWindow in the TaharezLook style, and name it 'Demo Window'
    FrameWindow* wnd = (FrameWindow*)winMgr.createWindow("TaharezLook/FrameWindow", "Demo Window");

    // Here we attach the newly created FrameWindow to the previously created
    // DefaultWindow which we will be using as the root of the displayed gui.
    root->addChildWindow(wnd);

    // Windows are in Relative metrics mode by default.  This means that we can
    // specify sizes and positions without having to know the exact pixel size
    // of the elements in advance.  The relative metrics mode co-ordinates are
    // relative to the parent of the window where the co-ordinates are being set.
    // This means that if 0.5f is specified as the width for a window, that window
    // will be half as its parent window.
    //
    // Here we set the FrameWindow so that it is half the size of the display,
    // and centered within the display.
    wnd->setPosition(UVector2(cegui_reldim(0.25f), cegui_reldim( 0.25f)));
    wnd->setSize(UVector2(cegui_reldim(0.5f), cegui_reldim( 0.5f)));

    // now we set the maximum and minum sizes for the new window.  These are
    // specified using relative co-ordinates, but the important thing to note
    // is that these settings are aways relative to the display rather than the
    // parent window.
    //
    // here we set a maximum size for the FrameWindow which is equal to the size
    // of the display, and a minimum size of one tenth of the display.
    wnd->setMaxSize(UVector2(cegui_reldim(1.0f), cegui_reldim( 1.0f)));
    wnd->setMinSize(UVector2(cegui_reldim(0.1f), cegui_reldim( 0.1f)));

    // As a final step in the initialisation of our sample window, we set the window's
    // text to "Hello World!", so that this text will appear as the caption in the
    // FrameWindow's titlebar.
    wnd->setText("Hello World!");

    // return true so that the samples framework knows that initialisation was a
    // success, and that it should now run the sample.
    return true;
}

/*************************************************************************
    Cleans up resources allocated in the initialiseSample call.
*************************************************************************/
void FirstWindowSample::cleanupSample()
{
    // nothing to do here!
}
<|endoftext|>