<commit_before>#include <nan.h>
#include "addon.h"
#include "dvbtee-parser.h"

TableData::TableData(const uint8_t &tableId, const std::string &decoderName, const std::string &json)
: tableId(tableId)
, decoderName(decoderName)
, json(json)
{}

////////////////////////////////////////

uv_async_t TableReceiver::m_async;

TableReceiver::TableReceiver(dvbteeParser *dvbteeParser)
: m_dvbteeParser(dvbteeParser)
{
  uv_mutex_init(&m_mutex);
  uv_async_init(uv_default_loop(), &m_async, completeCb);
  m_async.data = this;
}

TableReceiver::~TableReceiver()
{
  uv_mutex_destroy(&m_mutex);
}

void TableReceiver::updateTable(uint8_t tId, dvbtee::decode::Table *table)
{
  uv_mutex_lock(&m_mutex);
  v.push_back(new TableData(table->getTableid(), table->getDecoderName(), table->toJson()));
  uv_mutex_unlock(&m_mutex);

  uv_async_send(&m_async);
}

void TableReceiver::notify()
{
  Nan::HandleScope scope;
  uv_mutex_lock(&m_mutex);
  for (std::vector<TableData*>::const_iterator it = v.begin(); it != v.end(); ++it)
  {
    TableData *data = *it;
    v8::Local<v8::String> jsonStr = Nan::New(data->json).ToLocalChecked();

    v8::Local<v8::Value> argv[] = {
      Nan::New(data->tableId),
      Nan::New(data->decoderName).ToLocalChecked(),
      v8::JSON::Parse(jsonStr)
    };
    m_dvbteeParser->m_cb_tableReceiver.Call(3, argv);

    delete data;
  }
  v.clear();
  uv_mutex_unlock(&m_mutex);
}

void TableReceiver::completeCb(uv_async_t *handle
#if NODE_MODULE_VERSION<=11
                              , int status /*UNUSED*/
#endif
                              )
{
  TableReceiver* rcvr = static_cast<TableReceiver*>(handle->data);
  rcvr->notify();
}

////////////////////////////////////////

Nan::Persistent<v8::Function> dvbteeParser::constructor;

dvbteeParser::dvbteeParser(double value)
: m_tableReceiver(this)
, value_(value) {
}

dvbteeParser::~dvbteeParser() {
}

void dvbteeParser::Init(v8::Local<v8::Object> exports) {
  Nan::HandleScope scope;

  // Prepare constructor template
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("Parser").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  Nan::SetPrototypeMethod(tpl, "reset", reset);
  Nan::SetPrototypeMethod(tpl, "push", push);
  Nan::SetPrototypeMethod(tpl, "listenTables", listenTables);
  Nan::SetPrototypeMethod(tpl, "logLevel", logLevel);

  constructor.Reset(tpl->GetFunction());
  exports->Set(Nan::New("Parser").ToLocalChecked(), tpl->GetFunction());
}

void dvbteeParser::New(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  if (info.IsConstructCall()) {
    // Invoked as constructor: `new dvbteeParser(...)`
    double value = info[0]->IsUndefined() ? 0 : info[0]->NumberValue();
    dvbteeParser* obj = new dvbteeParser(value);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    // Invoked as plain function `dvbteeParser(...)`, turn into construct call.
    const int argc = 1;
    v8::Local<v8::Value> argv[argc] = { info[0] };
    v8::Local<v8::Function> cons = Nan::New<v8::Function>(constructor);
    info.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void dvbteeParser::listenTables(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  dvbteeParser* obj = ObjectWrap::Unwrap<dvbteeParser>(info.Holder());

  int lastArg = info.Length() - 1;

  if ((lastArg >= 0) && (info[lastArg]->IsFunction())) {
    obj->m_cb_tableReceiver.SetFunction(info[lastArg].As<v8::Function>());
    obj->m_parser.subscribeTables(&obj->m_tableReceiver);
  }

  info.GetReturnValue().Set(info.Holder());
}

////////////////////////////////////////

class ResetWorker : public Nan::AsyncWorker {
public:
  ResetWorker(Nan::Callback *callback, const Nan::FunctionCallbackInfo<v8::Value>& info)
    : Nan::AsyncWorker(callback)
    {
      m_obj = Nan::ObjectWrap::Unwrap<dvbteeParser>(info.Holder());
    }
  ~ResetWorker()
    {
    }

  // Executed inside the worker-thread.
  // It is not safe to access V8, or V8 data structures
  // here, so everything we need for input and output
  // should go on `this`.
  void Execute () {
    m_obj->m_parser.cleanup();
    m_obj->m_parser.reset();
  }

  // Executed when the async work is complete
  // this function will be run inside the main event loop
  // so it is safe to use V8 again
  void HandleOKCallback () {
    Nan::HandleScope scope;

    v8::Local<v8::Value> argv[] = {
        Nan::Null()
      , Nan::New<v8::Number>(0)
    };

    callback->Call(2, argv);
  }

private:
  dvbteeParser* m_obj;
};

void dvbteeParser::reset(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  int lastArg = info.Length() - 1;

  if ((lastArg >= 0) && (info[lastArg]->IsFunction())) {

    Nan::Callback *callback = new Nan::Callback(info[lastArg].As<v8::Function>());
    Nan::AsyncQueueWorker(new ResetWorker(callback, info));

  } else {
    dvbteeParser* obj = ObjectWrap::Unwrap<dvbteeParser>(info.Holder());

    obj->m_parser.cleanup();
    obj->m_parser.reset();

    info.GetReturnValue().Set(Nan::New(0));
  }
}

////////////////////////////////////////

class PushWorker : public Nan::AsyncWorker {
public:
  PushWorker(Nan::Callback *callback, const Nan::FunctionCallbackInfo<v8::Value>& info)
    : Nan::AsyncWorker(callback)
    {
      m_obj = Nan::ObjectWrap::Unwrap<dvbteeParser>(info.Holder());

      if ((info[0]->IsObject()) && (info[1]->IsNumber())) {

        v8::Local<v8::Object> bufferObj = info[0]->ToObject();
        m_buf_len = info[1]->Uint32Value();
        m_buf = (char*) malloc(m_buf_len);

        memcpy(m_buf, node::Buffer::Data(bufferObj), m_buf_len);
      }
    }
  ~PushWorker()
    {
      if (m_buf) free(m_buf);
    }

  // Executed inside the worker-thread.
  // It is not safe to access V8, or V8 data structures
  // here, so everything we need for input and output
  // should go on `this`.
  void Execute () {
    m_ret = m_obj->m_parser.feed(m_buf_len, (uint8_t*)m_buf);
    free(m_buf);
    m_buf = NULL;
  }

  // Executed when the async work is complete
  // this function will be run inside the main event loop
  // so it is safe to use V8 again
  void HandleOKCallback () {
    Nan::HandleScope scope;

    v8::Local<v8::Value> argv[] = {
        Nan::Null()
      , Nan::New<v8::Number>(m_ret)
    };

    callback->Call(2, argv);
  }

private:
  dvbteeParser* m_obj;
  char* m_buf;
  unsigned int m_buf_len;
  int m_ret;
};

void dvbteeParser::push(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  int lastArg = info.Length() - 1;

  if ((lastArg >= 0) && (info[lastArg]->IsFunction())) {

    Nan::Callback *callback = new Nan::Callback(info[lastArg].As<v8::Function>());
    Nan::AsyncQueueWorker(new PushWorker(callback, info));

  } else {
    dvbteeParser* obj = ObjectWrap::Unwrap<dvbteeParser>(info.Holder());
    int ret = -1;

    if ((info[0]->IsObject()) && (info[1]->IsNumber())) {

      v8::Local<v8::Object> bufferObj = info[0]->ToObject();
      unsigned int len = info[1]->Uint32Value();
      const char* buf = node::Buffer::Data(bufferObj);

      ret = obj->m_parser.feed(len, (uint8_t*)buf);
    }

    info.GetReturnValue().Set(Nan::New(ret));
  }
}
<commit_msg>dvbtee-parser: add comments documenting the sync / async nature of push & reset<commit_after>#include <nan.h>
#include "addon.h"
#include "dvbtee-parser.h"

TableData::TableData(const uint8_t &tableId, const std::string &decoderName, const std::string &json)
: tableId(tableId)
, decoderName(decoderName)
, json(json)
{}

////////////////////////////////////////

uv_async_t TableReceiver::m_async;

TableReceiver::TableReceiver(dvbteeParser *dvbteeParser)
: m_dvbteeParser(dvbteeParser)
{
  uv_mutex_init(&m_mutex);
  uv_async_init(uv_default_loop(), &m_async, completeCb);
  m_async.data = this;
}

TableReceiver::~TableReceiver()
{
  uv_mutex_destroy(&m_mutex);
}

void TableReceiver::updateTable(uint8_t tId, dvbtee::decode::Table *table)
{
  uv_mutex_lock(&m_mutex);
  v.push_back(new TableData(table->getTableid(), table->getDecoderName(), table->toJson()));
  uv_mutex_unlock(&m_mutex);

  uv_async_send(&m_async);
}

void TableReceiver::notify()
{
  Nan::HandleScope scope;
  uv_mutex_lock(&m_mutex);
  for (std::vector<TableData*>::const_iterator it = v.begin(); it != v.end(); ++it)
  {
    TableData *data = *it;
    v8::Local<v8::String> jsonStr = Nan::New(data->json).ToLocalChecked();

    v8::Local<v8::Value> argv[] = {
      Nan::New(data->tableId),
      Nan::New(data->decoderName).ToLocalChecked(),
      v8::JSON::Parse(jsonStr)
    };
    m_dvbteeParser->m_cb_tableReceiver.Call(3, argv);

    delete data;
  }
  v.clear();
  uv_mutex_unlock(&m_mutex);
}

void TableReceiver::completeCb(uv_async_t *handle
#if NODE_MODULE_VERSION<=11
                              , int status /*UNUSED*/
#endif
                              )
{
  TableReceiver* rcvr = static_cast<TableReceiver*>(handle->data);
  rcvr->notify();
}

////////////////////////////////////////

Nan::Persistent<v8::Function> dvbteeParser::constructor;

dvbteeParser::dvbteeParser(double value)
: m_tableReceiver(this)
, value_(value) {
}

dvbteeParser::~dvbteeParser() {
}

void dvbteeParser::Init(v8::Local<v8::Object> exports) {
  Nan::HandleScope scope;

  // Prepare constructor template
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("Parser").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  Nan::SetPrototypeMethod(tpl, "reset", reset);
  Nan::SetPrototypeMethod(tpl, "push", push);
  Nan::SetPrototypeMethod(tpl, "listenTables", listenTables);
  Nan::SetPrototypeMethod(tpl, "logLevel", logLevel);

  constructor.Reset(tpl->GetFunction());
  exports->Set(Nan::New("Parser").ToLocalChecked(), tpl->GetFunction());
}

void dvbteeParser::New(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  if (info.IsConstructCall()) {
    // Invoked as constructor: `new dvbteeParser(...)`
    double value = info[0]->IsUndefined() ? 0 : info[0]->NumberValue();
    dvbteeParser* obj = new dvbteeParser(value);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    // Invoked as plain function `dvbteeParser(...)`, turn into construct call.
    const int argc = 1;
    v8::Local<v8::Value> argv[argc] = { info[0] };
    v8::Local<v8::Function> cons = Nan::New<v8::Function>(constructor);
    info.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void dvbteeParser::listenTables(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  dvbteeParser* obj = ObjectWrap::Unwrap<dvbteeParser>(info.Holder());

  int lastArg = info.Length() - 1;

  if ((lastArg >= 0) && (info[lastArg]->IsFunction())) {
    obj->m_cb_tableReceiver.SetFunction(info[lastArg].As<v8::Function>());
    obj->m_parser.subscribeTables(&obj->m_tableReceiver);
  }

  info.GetReturnValue().Set(info.Holder());
}

////////////////////////////////////////

class ResetWorker : public Nan::AsyncWorker {
public:
  ResetWorker(Nan::Callback *callback, const Nan::FunctionCallbackInfo<v8::Value>& info)
    : Nan::AsyncWorker(callback)
    {
      m_obj = Nan::ObjectWrap::Unwrap<dvbteeParser>(info.Holder());
    }
  ~ResetWorker()
    {
    }

  // Executed inside the worker-thread.
  // It is not safe to access V8, or V8 data structures
  // here, so everything we need for input and output
  // should go on `this`.
  void Execute () {
    m_obj->m_parser.cleanup();
    m_obj->m_parser.reset();
  }

  // Executed when the async work is complete
  // this function will be run inside the main event loop
  // so it is safe to use V8 again
  void HandleOKCallback () {
    Nan::HandleScope scope;

    v8::Local<v8::Value> argv[] = {
        Nan::Null()
      , Nan::New<v8::Number>(0)
    };

    callback->Call(2, argv);
  }

private:
  dvbteeParser* m_obj;
};

void dvbteeParser::reset(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  // If a callback function is supplied, this method will run async
  // otherwise, it will run synchronous

  int lastArg = info.Length() - 1;

  if ((lastArg >= 0) && (info[lastArg]->IsFunction())) {

    Nan::Callback *callback = new Nan::Callback(info[lastArg].As<v8::Function>());
    Nan::AsyncQueueWorker(new ResetWorker(callback, info));

  } else {
    dvbteeParser* obj = ObjectWrap::Unwrap<dvbteeParser>(info.Holder());

    obj->m_parser.cleanup();
    obj->m_parser.reset();

    info.GetReturnValue().Set(Nan::New(0));
  }
}

////////////////////////////////////////

class PushWorker : public Nan::AsyncWorker {
public:
  PushWorker(Nan::Callback *callback, const Nan::FunctionCallbackInfo<v8::Value>& info)
    : Nan::AsyncWorker(callback)
    {
      m_obj = Nan::ObjectWrap::Unwrap<dvbteeParser>(info.Holder());

      if ((info[0]->IsObject()) && (info[1]->IsNumber())) {

        v8::Local<v8::Object> bufferObj = info[0]->ToObject();
        m_buf_len = info[1]->Uint32Value();
        m_buf = (char*) malloc(m_buf_len);

        memcpy(m_buf, node::Buffer::Data(bufferObj), m_buf_len);
      }
    }
  ~PushWorker()
    {
      if (m_buf) free(m_buf);
    }

  // Executed inside the worker-thread.
  // It is not safe to access V8, or V8 data structures
  // here, so everything we need for input and output
  // should go on `this`.
  void Execute () {
    m_ret = m_obj->m_parser.feed(m_buf_len, (uint8_t*)m_buf);
    free(m_buf);
    m_buf = NULL;
  }

  // Executed when the async work is complete
  // this function will be run inside the main event loop
  // so it is safe to use V8 again
  void HandleOKCallback () {
    Nan::HandleScope scope;

    v8::Local<v8::Value> argv[] = {
        Nan::Null()
      , Nan::New<v8::Number>(m_ret)
    };

    callback->Call(2, argv);
  }

private:
  dvbteeParser* m_obj;
  char* m_buf;
  unsigned int m_buf_len;
  int m_ret;
};

void dvbteeParser::push(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  // If a callback function is supplied, this method will run async
  // otherwise, it will run synchronous
  //
  // Note: when packets are pushed to the parser, the parser will start
  // generating async events containing PSIP table data regardless of
  // whether this function was called synchronously or not

  int lastArg = info.Length() - 1;

  if ((lastArg >= 0) && (info[lastArg]->IsFunction())) {

    Nan::Callback *callback = new Nan::Callback(info[lastArg].As<v8::Function>());
    Nan::AsyncQueueWorker(new PushWorker(callback, info));

  } else {
    dvbteeParser* obj = ObjectWrap::Unwrap<dvbteeParser>(info.Holder());
    int ret = -1;

    if ((info[0]->IsObject()) && (info[1]->IsNumber())) {

      v8::Local<v8::Object> bufferObj = info[0]->ToObject();
      unsigned int len = info[1]->Uint32Value();
      const char* buf = node::Buffer::Data(bufferObj);

      ret = obj->m_parser.feed(len, (uint8_t*)buf);
    }

    info.GetReturnValue().Set(Nan::New(ret));
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */
#include <libport/debug.hh>
#include <jni.h>
#include "urbi_Log.h"

GD_INIT();

JNIEXPORT void JNICALL
Java_urbi_Log_info (JNIEnv *env,jobject, jstring category, jstring msg, jstring functionname, jstring filename, jint linenumber)
{
  const char* msg_ = env->GetStringUTFChars(msg, 0);
  const char* functionname_ = env->GetStringUTFChars(functionname, 0);
  const char* filename_ = env->GetStringUTFChars(filename, 0);
  const char*category_ = env->GetStringUTFChars(category, 0);
  libport::debug::category_type _libport_gd_category = ::libport::debug::add_category(::libport::debug::category_type(category_));
  if (libport::debugger()->enabled(::libport::Debug::levels::debug, _libport_gd_category))
    libport::debugger()->debug(msg_, ::libport::Debug::types::info, _libport_gd_category, functionname_, filename_, (int) linenumber);
  env->ReleaseStringUTFChars(msg, msg_);
  env->ReleaseStringUTFChars(functionname, functionname_);
  env->ReleaseStringUTFChars(filename, filename_);
  env->ReleaseStringUTFChars(category, category_);
}

JNIEXPORT void JNICALL
Java_urbi_Log_error (JNIEnv *env,jobject, jstring category, jstring msg, jstring functionname, jstring filename, jint linenumber)
{
  const char* msg_ = env->GetStringUTFChars(msg, 0);
  const char* functionname_ = env->GetStringUTFChars(functionname, 0);
  const char* filename_ = env->GetStringUTFChars(filename, 0);
  const char*category_ = env->GetStringUTFChars(category, 0);
  ::libport::debug::category_type _libport_gd_category = ::libport::debug::add_category(::libport::debug::category_type(category_));
  if (libport::debugger()->enabled(::libport::Debug::levels::log, _libport_gd_category))
    libport::debugger()->debug(msg_, ::libport::Debug::types::error, _libport_gd_category, functionname_, filename_, (int) linenumber);
  env->ReleaseStringUTFChars(msg, msg_);
  env->ReleaseStringUTFChars(functionname, functionname_);
  env->ReleaseStringUTFChars(filename, filename_);
  env->ReleaseStringUTFChars(category, category_);
}
<commit_msg>UObject java: fix GD usage.<commit_after>/*
 * Copyright (C) 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */
#include <libport/debug.hh>
#include <jni.h>
#include "urbi_Log.h"

GD_INIT();

JNIEXPORT void JNICALL
Java_urbi_Log_info (JNIEnv *env,jobject, jstring category, jstring msg, jstring functionname, jstring filename, jint linenumber)
{
  const char* msg_ = env->GetStringUTFChars(msg, 0);
  const char* functionname_ = env->GetStringUTFChars(functionname, 0);
  const char* filename_ = env->GetStringUTFChars(filename, 0);
  const char*category_ = env->GetStringUTFChars(category, 0);
  libport::debug::category_type _libport_gd_category = ::libport::debug::add_category(::libport::debug::category_type(category_));
  if (GD_DEBUGGER->enabled(::libport::Debug::levels::debug, _libport_gd_category))
    GD_DEBUGGER->debug(msg_, ::libport::Debug::types::info, _libport_gd_category, functionname_, filename_, (int) linenumber);
  env->ReleaseStringUTFChars(msg, msg_);
  env->ReleaseStringUTFChars(functionname, functionname_);
  env->ReleaseStringUTFChars(filename, filename_);
  env->ReleaseStringUTFChars(category, category_);
}

JNIEXPORT void JNICALL
Java_urbi_Log_error (JNIEnv *env,jobject, jstring category, jstring msg, jstring functionname, jstring filename, jint linenumber)
{
  const char* msg_ = env->GetStringUTFChars(msg, 0);
  const char* functionname_ = env->GetStringUTFChars(functionname, 0);
  const char* filename_ = env->GetStringUTFChars(filename, 0);
  const char*category_ = env->GetStringUTFChars(category, 0);
  ::libport::debug::category_type _libport_gd_category = ::libport::debug::add_category(::libport::debug::category_type(category_));
  if (GD_DEBUGGER->enabled(::libport::Debug::levels::log, _libport_gd_category))
    GD_DEBUGGER->debug(msg_, ::libport::Debug::types::error, _libport_gd_category, functionname_, filename_, (int) linenumber);
  env->ReleaseStringUTFChars(msg, msg_);
  env->ReleaseStringUTFChars(functionname, functionname_);
  env->ReleaseStringUTFChars(filename, filename_);
  env->ReleaseStringUTFChars(category, category_);
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * common.hpp: Basic shared types & helpers
 *****************************************************************************
 * Copyright © 2015 libvlcpp authors & VideoLAN
 *
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
 *          Jonathan Calmels <exxo@videolabs.io>
 *
 * This program 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 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifndef LIBVLC_CXX_COMMON_H
#define LIBVLC_CXX_COMMON_H

#include <vlc/vlc.h>
#include <array>
#include <cassert>
#include <memory>

namespace VLC
{
    class Media;
    using MediaPtr = std::shared_ptr<Media>;

    // Work around cross class dependencies
    // Class A needs to access B's internal pointer
    // Class B needs to access A's internal pointer
    // By using a template function to do this, we're delegating
    // the access to both classes' guts to a later point, when the compiler
    // already knows everything it needs.
    // The only drawback is that we can't return decltype(ptr->get()), since when
    // the compiler checks for the prototype, it hasn't parsed all the declarations yet.
    template <typename TYPE, typename REF>
    TYPE* getInternalPtr(const REF& ref)
    {
        return ref.get();
    }

    inline std::unique_ptr<char, void (*)(void*)> wrapCStr(char* str)
    {
        return std::unique_ptr<char, void(*)(void*)>( str, [](void* ptr) { libvlc_free(ptr); } );
    }

#if !defined(_MSC_VER)
    // Kudos to 3xxO for the signature_match helper
    template <typename, typename, typename = void>
    struct signature_match : std::false_type {};

    template <typename Func, typename Ret, typename... Args>
    struct signature_match<Func, Ret(Args...),
        typename std::enable_if<
            std::is_convertible<
                decltype(std::declval<Func>()(std::declval<Args>()...)),
                Ret
            >::value // true or false
        >::type // void or SFINAE
    > : std::true_type {};
#else
    template <typename... Args>
    struct signature_match : std::false_type {};

    template <typename Func, typename Ret, class... Args>
    struct signature_match<Func, Ret(Args...)>
        : std::integral_constant < bool,
            std::is_convertible < decltype(std::declval<Func>()(std::declval<Args>()...)), Ret
        > ::value
    > {};
#endif

    template <typename Func, typename Ret, typename... Args>
    struct signature_match_or_nullptr : std::integral_constant<bool,
            signature_match<Func, Ret, Args...>::value ||
            std::is_same<Func, std::nullptr_t>::value
        >
    {
    };

    struct CallbackHandlerBase
    {
        virtual ~CallbackHandlerBase() = default;
    };

    template <typename Func>
    struct CallbackHandler : public CallbackHandlerBase
    {
        CallbackHandler(Func&& f) : func( std::forward<Func>( f ) ) {}
        Func func;
    };

    template <int NbEvent>
    struct EventOwner
    {
        std::array<std::shared_ptr<CallbackHandlerBase>, NbEvent> callbacks;

    protected:
        EventOwner() = default;
    };

    template <int, typename>
    struct FromOpaque;

    template <int NbEvents>
    struct FromOpaque<NbEvents, void*>
    {
        static EventOwner<NbEvents>* get(void* opaque)
        {
            return reinterpret_cast<EventOwner<NbEvents>*>( opaque );
        }
    };

    template <int NbEvents>
    struct FromOpaque<NbEvents, void**>
    {
        static EventOwner<NbEvents>* get(void** opaque)
        {
            return reinterpret_cast<EventOwner<NbEvents>*>( *opaque );
        }
    };

    template <int Idx, typename... Args>
    struct CallbackWrapper;

    // We assume that any callback will take a void*/void** opaque as its first parameter.
    // We intercept this parameter, and use it to fetch the list of user provided
    // functions. Once we know what function to call, we forward the rest of the
    // parameters.
    // Using partial specialization also allows us to get the list of the expected
    // callback parameters automatically, rather than having to specify them.
    template <int Idx, typename Ret, typename Opaque, typename... Args>
    struct CallbackWrapper<Idx, Ret(*)(Opaque, Args...)>
    {
        using Wrapped = Ret(Opaque, Args...);

        template <int NbEvents, typename Func>
        static Wrapped* wrap(EventOwner<NbEvents>* owner, Func&& func)
        {
            owner->callbacks[Idx] = std::shared_ptr<CallbackHandlerBase>( new CallbackHandler<Func>( std::forward<Func>( func ) ) );
            return [](Opaque opaque, Args... args) -> Ret {
                auto self = FromOpaque<NbEvents, Opaque>::get( opaque );
                assert(self->callbacks[Idx].get());
                auto cbHandler = static_cast<CallbackHandler<Func>*>( self->callbacks[Idx].get() );
                return cbHandler->func( std::forward<Args>(args)... );
            };
        }

        // Overload to handle null callbacks at build time.
        // We could try to compare any "Func" against nullptr at runtime, though
        // since Func is a template type, which roughly has to satisfy the "Callable" concept,
        // it could be an instance of a function object, which doesn't compare nicely against nullptr.
        // Using the specialization at build time is easier and performs better.
        template <int NbEvents>
        static std::nullptr_t wrap(EventOwner<NbEvents>*, std::nullptr_t)
        {
            return nullptr;
        }
    };
}

#endif
<commit_msg>Common.hpp: Use make_shared<commit_after>/*****************************************************************************
 * common.hpp: Basic shared types & helpers
 *****************************************************************************
 * Copyright © 2015 libvlcpp authors & VideoLAN
 *
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
 *          Jonathan Calmels <exxo@videolabs.io>
 *
 * This program 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 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifndef LIBVLC_CXX_COMMON_H
#define LIBVLC_CXX_COMMON_H

#include <vlc/vlc.h>
#include <array>
#include <cassert>
#include <memory>

namespace VLC
{
    class Media;
    using MediaPtr = std::shared_ptr<Media>;

    // Work around cross class dependencies
    // Class A needs to access B's internal pointer
    // Class B needs to access A's internal pointer
    // By using a template function to do this, we're delegating
    // the access to both classes' guts to a later point, when the compiler
    // already knows everything it needs.
    // The only drawback is that we can't return decltype(ptr->get()), since when
    // the compiler checks for the prototype, it hasn't parsed all the declarations yet.
    template <typename TYPE, typename REF>
    TYPE* getInternalPtr(const REF& ref)
    {
        return ref.get();
    }

    inline std::unique_ptr<char, void (*)(void*)> wrapCStr(char* str)
    {
        return std::unique_ptr<char, void(*)(void*)>( str, [](void* ptr) { libvlc_free(ptr); } );
    }

#if !defined(_MSC_VER)
    // Kudos to 3xxO for the signature_match helper
    template <typename, typename, typename = void>
    struct signature_match : std::false_type {};

    template <typename Func, typename Ret, typename... Args>
    struct signature_match<Func, Ret(Args...),
        typename std::enable_if<
            std::is_convertible<
                decltype(std::declval<Func>()(std::declval<Args>()...)),
                Ret
            >::value // true or false
        >::type // void or SFINAE
    > : std::true_type {};
#else
    template <typename... Args>
    struct signature_match : std::false_type {};

    template <typename Func, typename Ret, class... Args>
    struct signature_match<Func, Ret(Args...)>
        : std::integral_constant < bool,
            std::is_convertible < decltype(std::declval<Func>()(std::declval<Args>()...)), Ret
        > ::value
    > {};
#endif

    template <typename Func, typename Ret, typename... Args>
    struct signature_match_or_nullptr : std::integral_constant<bool,
            signature_match<Func, Ret, Args...>::value ||
            std::is_same<Func, std::nullptr_t>::value
        >
    {
    };

    struct CallbackHandlerBase
    {
        virtual ~CallbackHandlerBase() = default;
    };

    template <typename Func>
    struct CallbackHandler : public CallbackHandlerBase
    {
        CallbackHandler(Func&& f) : func( std::forward<Func>( f ) ) {}
        Func func;
    };

    template <int NbEvent>
    struct EventOwner
    {
        std::array<std::shared_ptr<CallbackHandlerBase>, NbEvent> callbacks;

    protected:
        EventOwner() = default;
    };

    template <int, typename>
    struct FromOpaque;

    template <int NbEvents>
    struct FromOpaque<NbEvents, void*>
    {
        static EventOwner<NbEvents>* get(void* opaque)
        {
            return reinterpret_cast<EventOwner<NbEvents>*>( opaque );
        }
    };

    template <int NbEvents>
    struct FromOpaque<NbEvents, void**>
    {
        static EventOwner<NbEvents>* get(void** opaque)
        {
            return reinterpret_cast<EventOwner<NbEvents>*>( *opaque );
        }
    };

    template <int Idx, typename... Args>
    struct CallbackWrapper;

    // We assume that any callback will take a void*/void** opaque as its first parameter.
    // We intercept this parameter, and use it to fetch the list of user provided
    // functions. Once we know what function to call, we forward the rest of the
    // parameters.
    // Using partial specialization also allows us to get the list of the expected
    // callback parameters automatically, rather than having to specify them.
    template <int Idx, typename Ret, typename Opaque, typename... Args>
    struct CallbackWrapper<Idx, Ret(*)(Opaque, Args...)>
    {
        using Wrapped = Ret(Opaque, Args...);

        template <int NbEvents, typename Func>
        static Wrapped* wrap(EventOwner<NbEvents>* owner, Func&& func)
        {
            owner->callbacks[Idx] = std::make_shared<CallbackHandler<Func>>( std::forward<Func>( func ) );
            return [](Opaque opaque, Args... args) -> Ret {
                auto self = FromOpaque<NbEvents, Opaque>::get( opaque );
                assert(self->callbacks[Idx].get());
                auto cbHandler = static_cast<CallbackHandler<Func>*>( self->callbacks[Idx].get() );
                return cbHandler->func( std::forward<Args>(args)... );
            };
        }

        // Overload to handle null callbacks at build time.
        // We could try to compare any "Func" against nullptr at runtime, though
        // since Func is a template type, which roughly has to satisfy the "Callable" concept,
        // it could be an instance of a function object, which doesn't compare nicely against nullptr.
        // Using the specialization at build time is easier and performs better.
        template <int NbEvents>
        static std::nullptr_t wrap(EventOwner<NbEvents>*, std::nullptr_t)
        {
            return nullptr;
        }
    };
}

#endif
<|endoftext|>


<commit_before>#include "objectmemory.hpp"

#include "builtin/class.hpp"
#include "builtin/data.hpp"

#include "capi/capi.hpp"
#include "capi/ruby.h"

using namespace rubinius;
using namespace rubinius::capi;

namespace rubinius {
  namespace capi {

    void flush_cached_rdata(NativeMethodEnvironment* env, Handle* handle) {
      if(handle->is_rdata()) {
        Data* data = c_as<Data>(handle->object());
        RData* rdata = handle->as_rdata(env);

        data->mark(env->state(), rdata->dmark);
        data->free(env->state(), rdata->dfree);
        data->data(env->state(), rdata->data);
      }
    }

    RData* Handle::as_rdata(NativeMethodEnvironment* env) {
      if(type_ != cRData) {
        Data* data = c_as<Data>(object());
        type_ = cRData;

        as_.rdata = reinterpret_cast<RData*>(data->exposed());
      }

      env->state()->om->remember_object(object());

      return as_.rdata;
    }
  }
}

extern "C" {
  struct RData* capi_rdata_struct(VALUE data_handle) {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    Handle* handle = Handle::from(data_handle);
    return handle->as_rdata(env);
  }

  VALUE rb_data_object_alloc(VALUE klass, void* ptr,
      RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free) {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    Class* data_klass = c_as<Class>(env->get_object(klass));

    Data* data = Data::create(env->state(), ptr, mark, free);

    data->klass(env->state(), data_klass);

    return env->get_handle(data);
  }
}
<commit_msg>Remember new Data objects<commit_after>#include "objectmemory.hpp"

#include "builtin/class.hpp"
#include "builtin/data.hpp"

#include "capi/capi.hpp"
#include "capi/ruby.h"

using namespace rubinius;
using namespace rubinius::capi;

namespace rubinius {
  namespace capi {

    void flush_cached_rdata(NativeMethodEnvironment* env, Handle* handle) {
      if(handle->is_rdata()) {
        Data* data = c_as<Data>(handle->object());
        RData* rdata = handle->as_rdata(env);

        data->mark(env->state(), rdata->dmark);
        data->free(env->state(), rdata->dfree);
        data->data(env->state(), rdata->data);
      }
    }

    RData* Handle::as_rdata(NativeMethodEnvironment* env) {
      if(type_ != cRData) {
        Data* data = c_as<Data>(object());
        type_ = cRData;

        as_.rdata = reinterpret_cast<RData*>(data->exposed());
      }

      env->state()->om->remember_object(object());

      return as_.rdata;
    }
  }
}

extern "C" {
  struct RData* capi_rdata_struct(VALUE data_handle) {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    Handle* handle = Handle::from(data_handle);
    return handle->as_rdata(env);
  }

  VALUE rb_data_object_alloc(VALUE klass, void* ptr,
      RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free) {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    Class* data_klass = c_as<Class>(env->get_object(klass));

    Data* data = Data::create(env->state(), ptr, mark, free);

    data->klass(env->state(), data_klass);

    // Data objects are directly manipulated, so we have to always
    // track them.
    env->state()->om->remember_object(data);

    return env->get_handle(data);
  }
}
<|endoftext|>


<commit_before>// Copyright © 2012, Université catholique de Louvain
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// *  Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// *  Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 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 HOLDER 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.

#ifndef __UTILS_H
#define __UTILS_H

#include "mozart.hh"

#include <type_traits>

#ifndef MOZART_GENERATOR

namespace mozart {

// getArgument -----------------------------------------------------------------

template <class T>
T getArgument(VM vm, RichNode argValue, const nchar* expectedType) {
  using namespace patternmatching;

  T result;

  if (!matches(vm, argValue, capture(result)))
    raiseTypeError(vm, expectedType, argValue);

  return result;
}

// requireFeature --------------------------------------------------------------

void requireFeature(VM vm, RichNode feature) {
  if (!feature.isFeature())
    PotentialFeature(feature).makeFeature(vm);
}

// ozListForEach ---------------------------------------------------------------

template <class F, class G>
void ozListForEach(VM vm, RichNode cons, const F& onHead, const G& onTail) {
  while (true) {
    using namespace patternmatching;

    typename std::remove_reference<
      typename function_traits<F>::template arg<0>::type>::type head;
    UnstableNode tail;

    if (matchesCons(vm, cons, capture(head), capture(tail))) {
      onHead(head);
      cons = tail;
    } else if (matches(vm, cons, vm->coreatoms.nil)) {
      return;
    } else {
      return onTail(cons);
    }
  }
}

template <class F>
void ozListForEach(VM vm, RichNode cons, const F& onHead,
                   const nchar* expectedType) {
  return ozListForEach(vm, cons, onHead, [=](RichNode node) {
    return raiseTypeError(vm, expectedType, node);
  });
}

size_t ozListLength(VM vm, RichNode list) {
  size_t result = 0;

  UnstableNode nextList;

  while (true) {
    using namespace patternmatching;

    UnstableNode tail;

    if (matchesCons(vm, list, wildcard(), capture(tail))) {
      result++;
      nextList = std::move(tail);
      list = nextList;
    } else if (matches(vm, list, vm->coreatoms.nil)) {
      return result;
    } else {
      raiseTypeError(vm, MOZART_STR("list"), list);
    }
  }
}

namespace internal {
  template <class C>
  struct VSToStringHelper {
    inline
    static std::basic_string<C> call(VM vm, RichNode vs);
  };

  template <>
  struct VSToStringHelper<nchar> {
    static std::basic_string<nchar> call(VM vm, RichNode vs) {
      std::basic_stringstream<nchar> buffer;
      VirtualString(vs).toString(vm, buffer);
      return buffer.str();
    }
  };

  template <class C>
  std::basic_string<C> VSToStringHelper<C>::call(VM vm, RichNode vs) {
    auto nresult = VSToStringHelper<nchar>::call(vm, vs);
    auto str = toUTF<C>(makeLString(nresult.c_str(), nresult.size()));
    return std::basic_string<C>(str.string, str.length);
  }
}

template <class C>
std::basic_string<C> vsToString(VM vm, RichNode vs) {
  return internal::VSToStringHelper<C>::call(vm, vs);
}

}

#endif

#endif // __UTILS_H
<commit_msg>Fixed a bug in ozListForEach().<commit_after>// Copyright © 2012, Université catholique de Louvain
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// *  Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// *  Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 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 HOLDER 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.

#ifndef __UTILS_H
#define __UTILS_H

#include "mozart.hh"

#include <type_traits>

#ifndef MOZART_GENERATOR

namespace mozart {

// getArgument -----------------------------------------------------------------

template <class T>
T getArgument(VM vm, RichNode argValue, const nchar* expectedType) {
  using namespace patternmatching;

  T result;

  if (!matches(vm, argValue, capture(result)))
    raiseTypeError(vm, expectedType, argValue);

  return result;
}

// requireFeature --------------------------------------------------------------

void requireFeature(VM vm, RichNode feature) {
  if (!feature.isFeature())
    PotentialFeature(feature).makeFeature(vm);
}

// ozListForEach ---------------------------------------------------------------

template <class F, class G>
void ozListForEach(VM vm, RichNode cons, const F& onHead, const G& onTail) {
  using namespace patternmatching;

  typename std::remove_reference<
    typename function_traits<F>::template arg<0>::type>::type head;

  UnstableNode tail;

  while (true) {
    if (matchesCons(vm, cons, capture(head), capture(tail))) {
      onHead(head);
      cons = tail;
    } else if (matches(vm, cons, vm->coreatoms.nil)) {
      return;
    } else {
      return onTail(cons);
    }
  }
}

template <class F>
void ozListForEach(VM vm, RichNode cons, const F& onHead,
                   const nchar* expectedType) {
  return ozListForEach(vm, cons, onHead, [=](RichNode node) {
    return raiseTypeError(vm, expectedType, node);
  });
}

size_t ozListLength(VM vm, RichNode list) {
  size_t result = 0;

  UnstableNode nextList;

  while (true) {
    using namespace patternmatching;

    UnstableNode tail;

    if (matchesCons(vm, list, wildcard(), capture(tail))) {
      result++;
      nextList = std::move(tail);
      list = nextList;
    } else if (matches(vm, list, vm->coreatoms.nil)) {
      return result;
    } else {
      raiseTypeError(vm, MOZART_STR("list"), list);
    }
  }
}

namespace internal {
  template <class C>
  struct VSToStringHelper {
    inline
    static std::basic_string<C> call(VM vm, RichNode vs);
  };

  template <>
  struct VSToStringHelper<nchar> {
    static std::basic_string<nchar> call(VM vm, RichNode vs) {
      std::basic_stringstream<nchar> buffer;
      VirtualString(vs).toString(vm, buffer);
      return buffer.str();
    }
  };

  template <class C>
  std::basic_string<C> VSToStringHelper<C>::call(VM vm, RichNode vs) {
    auto nresult = VSToStringHelper<nchar>::call(vm, vs);
    auto str = toUTF<C>(makeLString(nresult.c_str(), nresult.size()));
    return std::basic_string<C>(str.string, str.length);
  }
}

template <class C>
std::basic_string<C> vsToString(VM vm, RichNode vs) {
  return internal::VSToStringHelper<C>::call(vm, vs);
}

}

#endif

#endif // __UTILS_H
<|endoftext|>


<commit_before>#ifndef RBX_VM_TYPE_INFO_HPP
#define RBX_VM_TYPE_INFO_HPP

#include <map>
#include <stdexcept>
#include <vector>

#include "object_types.hpp"
#include "prelude.hpp"
#include "executor.hpp"

namespace rubinius {

  class Class;
  class Object;
  class ObjectMark;
  class ObjectMemory;
  class ObjectHeader;

  class GCTokenImpl {};

  typedef GCTokenImpl& GCToken;

  /**
   *  Static type information for the VM.
   *
   *  Due to memory layout restrictions, virtual methods cannot exist
   *  on builtin types. This class abstracts those operations out of
   *  the classes themselves. Using virtual dispatch here allows the
   *  correct method implementation to be invoked, based on the object's
   *  obj_type field.
   *
   *  @see  doc/builtin_internal_resource_releasing.txt
   *  @see  vm/object_types.hpp
   *  @see  builtin/object.hpp
   */
  class TypeInfo {
  public: // Types

    typedef std::map<native_int, long> Slots;
    typedef std::vector<object_type> SlotTypes;
    typedef std::vector<executor> AccessorPrimitives;
    typedef std::vector<uintptr_t> SlotLocations;

  private: /* Instance vars */
    VM*         state_;

  public:

    size_t      instance_size;
    static size_t instance_sizes[(int)LastObjectType];
    Slots       slots;
    SlotTypes   slot_types;
    AccessorPrimitives slot_accessors;
    SlotLocations slot_locations;
    std::string type_name;
    object_type type;
    bool        allow_user_allocate;

  public: /* Class initializers */

    static void init(ObjectMemory* om);
    static void auto_init(ObjectMemory* om);
    static void auto_learn_fields(STATE);
    virtual void auto_mark(Object* obj, ObjectMark& mark) = 0;

  public:   /* Ctors */

    /**
     *  Make a new TypeInfo.
     *
     *  To support TypeInfo hierarchies where some classes may
     *  and some may not need e.g. a cleanup, the instantiation
     *  will set the cleanup flag if _any_ of the classes in
     *  the chain request it.
     */
    TypeInfo(object_type type);

    virtual ~TypeInfo();

  public:   /* Interface */

    void set_state(STATE);

    VM* state() {
      return state_;
    }

    virtual void mark(Object* obj, ObjectMark& mark);

    virtual void set_field(STATE, Object* target, size_t index, Object* val);
    virtual Object* get_field(STATE, Object* target, size_t index);

    virtual void populate_slot_locations() { }

    /**
     * Slow case, should be called only if instance_size is zero
     */
    virtual size_t object_size(const ObjectHeader * obj);

    /**
     * Currently prints the same output as show_simple. Is specialized by
     * complex classes to e.g. limit the recursion into nested
     * objects to make the output more manageable. See e.g. Tuple
     * and CompiledCode. Immediates and numeric classes print
     * their value for both show and show_simple.
     */
    virtual void show(STATE, Object* self, int level);

    /**
     * Default output for any object. Prints just the class name
     * and address. It is expected that classes will define their own
     * show output.
     */
    virtual void show_simple(STATE, Object* self, int level);

    /**
     * Prints spaces to indent the following text to the requested
     * level. Levels are specified as 0, 1, 2, ... and the multiplier
     * is 2. So, text at level 2 will have 2 * 2 = 4 spaces in front.
     */
    virtual void indent(int level);

    /**
     * Indents the attribute name to the requested level. @see indent.
     */
    virtual void indent_attribute(int level, const char* name);

    /**
     * Prints out the class name and address. Used for simple classes
     * that may append other info on the same line.
     *
     *   #<SomeClass:0x346882
     */
    virtual void class_info(STATE, const Object* self, bool newline = false);

    /**
     * Prints out the class name and address followed by a newline. Used
     * for complex classes that will print additional member info.
     *
     *   #<SomeClass:0x3287648\n
     */
    virtual void class_header(STATE, const Object* self);

    /**
     * Prints "..." + endl at the requested indent level.
     */
    virtual void ellipsis(int level);

    /**
     * Indents to level-1 and prints ">" + endl.
     */
    virtual void close_body(int level);

  };

}

#define BASIC_TYPEINFO(super) \
  Info(object_type type) : super(type) { } \
  virtual void auto_mark(Object* obj, ObjectMark& mark); \
  virtual void set_field(STATE, Object* target, size_t index, Object* val); \
  virtual Object* get_field(STATE, Object* target, size_t index); \
  virtual void populate_slot_locations();

#endif
<commit_msg>Added missing #include for OS X 10.9 cc.<commit_after>#ifndef RBX_VM_TYPE_INFO_HPP
#define RBX_VM_TYPE_INFO_HPP

#include <map>
#include <stdexcept>
#include <vector>
#include <string>

#include "object_types.hpp"
#include "prelude.hpp"
#include "executor.hpp"

namespace rubinius {

  class Class;
  class Object;
  class ObjectMark;
  class ObjectMemory;
  class ObjectHeader;

  class GCTokenImpl {};

  typedef GCTokenImpl& GCToken;

  /**
   *  Static type information for the VM.
   *
   *  Due to memory layout restrictions, virtual methods cannot exist
   *  on builtin types. This class abstracts those operations out of
   *  the classes themselves. Using virtual dispatch here allows the
   *  correct method implementation to be invoked, based on the object's
   *  obj_type field.
   *
   *  @see  doc/builtin_internal_resource_releasing.txt
   *  @see  vm/object_types.hpp
   *  @see  builtin/object.hpp
   */
  class TypeInfo {
  public: // Types

    typedef std::map<native_int, long> Slots;
    typedef std::vector<object_type> SlotTypes;
    typedef std::vector<executor> AccessorPrimitives;
    typedef std::vector<uintptr_t> SlotLocations;

  private: /* Instance vars */
    VM*         state_;

  public:

    size_t      instance_size;
    static size_t instance_sizes[(int)LastObjectType];
    Slots       slots;
    SlotTypes   slot_types;
    AccessorPrimitives slot_accessors;
    SlotLocations slot_locations;
    std::string type_name;
    object_type type;
    bool        allow_user_allocate;

  public: /* Class initializers */

    static void init(ObjectMemory* om);
    static void auto_init(ObjectMemory* om);
    static void auto_learn_fields(STATE);
    virtual void auto_mark(Object* obj, ObjectMark& mark) = 0;

  public:   /* Ctors */

    /**
     *  Make a new TypeInfo.
     *
     *  To support TypeInfo hierarchies where some classes may
     *  and some may not need e.g. a cleanup, the instantiation
     *  will set the cleanup flag if _any_ of the classes in
     *  the chain request it.
     */
    TypeInfo(object_type type);

    virtual ~TypeInfo();

  public:   /* Interface */

    void set_state(STATE);

    VM* state() {
      return state_;
    }

    virtual void mark(Object* obj, ObjectMark& mark);

    virtual void set_field(STATE, Object* target, size_t index, Object* val);
    virtual Object* get_field(STATE, Object* target, size_t index);

    virtual void populate_slot_locations() { }

    /**
     * Slow case, should be called only if instance_size is zero
     */
    virtual size_t object_size(const ObjectHeader * obj);

    /**
     * Currently prints the same output as show_simple. Is specialized by
     * complex classes to e.g. limit the recursion into nested
     * objects to make the output more manageable. See e.g. Tuple
     * and CompiledCode. Immediates and numeric classes print
     * their value for both show and show_simple.
     */
    virtual void show(STATE, Object* self, int level);

    /**
     * Default output for any object. Prints just the class name
     * and address. It is expected that classes will define their own
     * show output.
     */
    virtual void show_simple(STATE, Object* self, int level);

    /**
     * Prints spaces to indent the following text to the requested
     * level. Levels are specified as 0, 1, 2, ... and the multiplier
     * is 2. So, text at level 2 will have 2 * 2 = 4 spaces in front.
     */
    virtual void indent(int level);

    /**
     * Indents the attribute name to the requested level. @see indent.
     */
    virtual void indent_attribute(int level, const char* name);

    /**
     * Prints out the class name and address. Used for simple classes
     * that may append other info on the same line.
     *
     *   #<SomeClass:0x346882
     */
    virtual void class_info(STATE, const Object* self, bool newline = false);

    /**
     * Prints out the class name and address followed by a newline. Used
     * for complex classes that will print additional member info.
     *
     *   #<SomeClass:0x3287648\n
     */
    virtual void class_header(STATE, const Object* self);

    /**
     * Prints "..." + endl at the requested indent level.
     */
    virtual void ellipsis(int level);

    /**
     * Indents to level-1 and prints ">" + endl.
     */
    virtual void close_body(int level);

  };

}

#define BASIC_TYPEINFO(super) \
  Info(object_type type) : super(type) { } \
  virtual void auto_mark(Object* obj, ObjectMark& mark); \
  virtual void set_field(STATE, Object* target, size_t index, Object* val); \
  virtual Object* get_field(STATE, Object* target, size_t index); \
  virtual void populate_slot_locations();

#endif
<|endoftext|>


<commit_before>#include <world/terrain/PerlinTerrainGenerator.h>
#include <world/terrain.h>
#include "FlatWorld.h"

#include "world/core/GridChunkSystem.h"
#include "world/core/InstancePool.h"
#include "world/terrain/HeightmapGround.h"
#include "world/tree/ForestLayer.h"
#include "world/nature/Grass.h"
#include "world/tree/SimpleTreeDecorator.h"
#include "world/nature/Rocks.h"
#include "world/core/Profiler.h"
#include "world/core/SeedDistribution.h"
#include "world/terrain/MultilayerGroundTexture.h"
#include "world/terrain/CachedTextureProvider.h"
#include "world/core/WorldFile.h"
#include "world/terrain/GroundBiomes.h"

namespace world {

class PFlatWorld {
public:
    std::unique_ptr<GroundNode> _ground;

    PFlatWorld() {}
};

FlatWorld *FlatWorld::createDemoFlatWorld() {
    FlatWorld *world = new FlatWorld();

    HeightmapGround &ground = world->setGround<HeightmapGround>();

    ground.addWorker<PerlinTerrainGenerator>(3, 4., 0.35).setMaxOctaveCount(6);

    auto &map = ground.addWorker<CustomWorldRMModifier>();
    map.setRegion({0, 0}, 10000, 3, 0.1, 0.3);
    map.setRegion({0, 0}, 6000, 0.7, 1.6, 0.8);

    ground.addWorker<GroundBiomes>();
    // TODO add color configuration to the texturer (just as before)
    ground.addWorker<AltitudeTexturer>();

    /*auto &multilayer = ground.addWorker<MultilayerGroundTexture>();
    multilayer.setTextureProvider<CachedTextureProvider>("multilayer/");
    // rock
    multilayer.addLayer(DistributionParams{-1, 0, 1, 2, // h
                                           -1, 0, 1, 2, // dh
                                           0, 1, 0, 1, 0.05});
    // sand
    multilayer.addLayer(DistributionParams{-1, 0, 0.4, 0.45, // h
                                           -1, 0, 0.4, 0.6,  // dh
                                           0, 1, 0, 1, 0.05});
    // soil
    multilayer.addLayer(DistributionParams{0.33, 0.4, 0.6, 0.75, // h
                                           -1, 0, 0.45, 0.65,    // dh
                                           0, 0.85, 0.25, 0.85, 0.05});
    // grass
    multilayer.addLayer(DistributionParams{0.33, 0.4, 0.6, 0.7, // h
                                           -1, 0, 0.4, 0.6,     // dh
                                           0., 1., 0.25, 0.6, 0.05});
    // snow
    multilayer.addLayer(DistributionParams{0.65, 0.8, 1, 2, // h
                                           -1, 0, 0.5, 0.7, // dh
                                           0.0, 1.0, 0, 1., 0.05});*/

    auto &chunkSystem = world->addPrimaryNode<GridChunkSystem>({0, 0, 0});
    chunkSystem.addDecorator<ForestLayer>();

    // auto &treePool = chunkSystem.addDecorator<InstancePool<Tree>>(world);
    // treePool.setResolution(1);
    // treePool.distribution().setDensity(0.0008);

    // Grass with seed distribution
    auto &grassPool = chunkSystem.addDecorator<InstancePool>();
    grassPool.setDistribution<SeedDistribution>();
    grassPool.setTemplateGenerator<Grass>();

    // Rocks
    auto &rocksPool = chunkSystem.addDecorator<InstancePool>();
    rocksPool.setDistribution<RandomDistribution>().setDensity(0.02);
    rocksPool.setTemplateGenerator<Rocks>();

    auto &rocks = rocksPool.addGenerator<Rocks>();
    rocks.setRadius(0.7);

    for (int i = 0; i < 10; ++i) {
        rocks.addRock({0, 0, 0});
    }

    return world;
}

FlatWorld::FlatWorld() : _internal(new PFlatWorld()) {
    auto &ground = setGround<HeightmapGround>();
}

FlatWorld::~FlatWorld() { delete _internal; }

IGround &FlatWorld::ground() { return *_internal->_ground; }

void FlatWorld::collect(ICollector &collector,
                        const IResolutionModel &resolutionModel) {
    // TODO remove this hack when we can deserialize references
    auto *hg = dynamic_cast<HeightmapGround *>(_internal->_ground.get());
    if (hg != nullptr) {
        _atmosphericProvider = hg->getAtmosphericProvider();
    }
    // end of hack

    _internal->_ground->collect(collector, resolutionModel);
    World::collect(collector, resolutionModel);
}

vec3d FlatWorld::findNearestFreePoint(const vec3d &origin,
                                      const vec3d &direction, double resolution,
                                      const ExplorationContext &ctx) const {
    auto pos = origin + ctx.getOffset();
    double z =
        _internal->_ground->observeAltitudeAt(pos.x, pos.y, resolution, ctx);
    // std::cout << z - ctx.getOffset().z << " <> " << origin.z << std::endl;
    return {origin.x, origin.y, z - ctx.getOffset().z};
}

void FlatWorld::write(WorldFile &wf) const {
    wf.addChild("ground", _internal->_ground->serializeSubclass());
    World::write(wf);
}

void FlatWorld::read(const WorldFile &wf) {
    _internal->_ground.reset(readSubclass<GroundNode>(wf.readChild("ground")));
    World::read(wf);
}

IEnvironment *FlatWorld::getInitialEnvironment() { return this; }

void FlatWorld::setGroundInternal(GroundNode *ground) {
    _internal->_ground = std::unique_ptr<GroundNode>(ground);
}

} // namespace world
<commit_msg>Add color map configuration to demo flat world<commit_after>#include <world/terrain/PerlinTerrainGenerator.h>
#include <world/terrain.h>
#include "FlatWorld.h"

#include "world/core/GridChunkSystem.h"
#include "world/core/InstancePool.h"
#include "world/terrain/HeightmapGround.h"
#include "world/tree/ForestLayer.h"
#include "world/nature/Grass.h"
#include "world/tree/SimpleTreeDecorator.h"
#include "world/nature/Rocks.h"
#include "world/core/Profiler.h"
#include "world/core/SeedDistribution.h"
#include "world/terrain/MultilayerGroundTexture.h"
#include "world/terrain/CachedTextureProvider.h"
#include "world/core/WorldFile.h"
#include "world/terrain/GroundBiomes.h"

namespace world {

class PFlatWorld {
public:
    std::unique_ptr<GroundNode> _ground;

    PFlatWorld() {}
};

FlatWorld *FlatWorld::createDemoFlatWorld() {
    FlatWorld *world = new FlatWorld();

    HeightmapGround &ground = world->setGround<HeightmapGround>();

    ground.addWorker<PerlinTerrainGenerator>(3, 4., 0.35).setMaxOctaveCount(6);

    auto &map = ground.addWorker<CustomWorldRMModifier>();
    map.setRegion({0, 0}, 10000, 3, 0.1, 0.3);
    map.setRegion({0, 0}, 6000, 0.7, 1.6, 0.8);

    auto &texturer = ground.addWorker<AltitudeTexturer>();
    ColorMap &colorMap = texturer.getColorMap();

    colorMap.addPoint({0.15, 0.5}, Color4u(209, 207, 153)); // Sand
    colorMap.addPoint({0.31, 0}, Color4u(209, 207, 153));   // Sand
    colorMap.addPoint({0.31, 1}, Color4u(209, 207, 153));   // Sand
    colorMap.addPoint({0.35, 0}, Color4u(144, 183, 92));    // Light grass
    colorMap.addPoint({0.35, 1}, Color4u(72, 132, 65));     // Dark grass
    colorMap.addPoint({0.5, 0}, Color4u(144, 183, 100));    // Light grass
    colorMap.addPoint({0.5, 1}, Color4u(96, 76, 40));       // Dark dirt
    colorMap.addPoint({0.75, 0}, Color4u(96, 76, 40));      // Dark dirt
    colorMap.addPoint({0.75, 1}, Color4u(160, 160, 160));   // Rock
    colorMap.addPoint({1, 0}, Color4u(244, 252, 250));      // Snow
    colorMap.addPoint({1, 1}, Color4u(160, 160, 160));      // Rock
    colorMap.setOrder(3);

    // ground.addWorker<GroundBiomes>();
    /*auto &multilayer = ground.addWorker<MultilayerGroundTexture>();
    multilayer.setTextureProvider<CachedTextureProvider>("multilayer/");
    // rock
    multilayer.addLayer(DistributionParams{-1, 0, 1, 2, // h
                                           -1, 0, 1, 2, // dh
                                           0, 1, 0, 1, 0.05});
    // sand
    multilayer.addLayer(DistributionParams{-1, 0, 0.4, 0.45, // h
                                           -1, 0, 0.4, 0.6,  // dh
                                           0, 1, 0, 1, 0.05});
    // soil
    multilayer.addLayer(DistributionParams{0.33, 0.4, 0.6, 0.75, // h
                                           -1, 0, 0.45, 0.65,    // dh
                                           0, 0.85, 0.25, 0.85, 0.05});
    // grass
    multilayer.addLayer(DistributionParams{0.33, 0.4, 0.6, 0.7, // h
                                           -1, 0, 0.4, 0.6,     // dh
                                           0., 1., 0.25, 0.6, 0.05});
    // snow
    multilayer.addLayer(DistributionParams{0.65, 0.8, 1, 2, // h
                                           -1, 0, 0.5, 0.7, // dh
                                           0.0, 1.0, 0, 1., 0.05});*/

    auto &chunkSystem = world->addPrimaryNode<GridChunkSystem>({0, 0, 0});
    chunkSystem.addDecorator<ForestLayer>();

    // auto &treePool = chunkSystem.addDecorator<InstancePool<Tree>>(world);
    // treePool.setResolution(1);
    // treePool.distribution().setDensity(0.0008);

    // Grass with seed distribution
    auto &grassPool = chunkSystem.addDecorator<InstancePool>();
    grassPool.setDistribution<SeedDistribution>();
    grassPool.setTemplateGenerator<Grass>();

    // Rocks
    auto &rocksPool = chunkSystem.addDecorator<InstancePool>();
    rocksPool.setDistribution<RandomDistribution>().setDensity(0.02);
    rocksPool.setTemplateGenerator<Rocks>();

    auto &rocks = rocksPool.addGenerator<Rocks>();
    rocks.setRadius(0.7);

    for (int i = 0; i < 10; ++i) {
        rocks.addRock({0, 0, 0});
    }

    return world;
}

FlatWorld::FlatWorld() : _internal(new PFlatWorld()) {
    auto &ground = setGround<HeightmapGround>();
}

FlatWorld::~FlatWorld() { delete _internal; }

IGround &FlatWorld::ground() { return *_internal->_ground; }

void FlatWorld::collect(ICollector &collector,
                        const IResolutionModel &resolutionModel) {
    // TODO remove this hack when we can deserialize references
    auto *hg = dynamic_cast<HeightmapGround *>(_internal->_ground.get());
    if (hg != nullptr) {
        _atmosphericProvider = hg->getAtmosphericProvider();
    }
    // end of hack

    _internal->_ground->collect(collector, resolutionModel);
    World::collect(collector, resolutionModel);
}

vec3d FlatWorld::findNearestFreePoint(const vec3d &origin,
                                      const vec3d &direction, double resolution,
                                      const ExplorationContext &ctx) const {
    auto pos = origin + ctx.getOffset();
    double z =
        _internal->_ground->observeAltitudeAt(pos.x, pos.y, resolution, ctx);
    // std::cout << z - ctx.getOffset().z << " <> " << origin.z << std::endl;
    return {origin.x, origin.y, z - ctx.getOffset().z};
}

void FlatWorld::write(WorldFile &wf) const {
    wf.addChild("ground", _internal->_ground->serializeSubclass());
    World::write(wf);
}

void FlatWorld::read(const WorldFile &wf) {
    _internal->_ground.reset(readSubclass<GroundNode>(wf.readChild("ground")));
    World::read(wf);
}

IEnvironment *FlatWorld::getInitialEnvironment() { return this; }

void FlatWorld::setGroundInternal(GroundNode *ground) {
    _internal->_ground = std::unique_ptr<GroundNode>(ground);
}

} // namespace world
<|endoftext|>


<commit_before>/*
 *
 * Copyright (C) 2001  Frank Dabek (fdabek@lcs.mit.edu),
 *   		       Massachusetts Institute of Technology
 *
 *
 *  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 OR COPYRIGHT HOLDERS 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 <async.h>
#include <sfsmisc.h>
#include <dhash_common.h>
#include <dhash_prot.h>
#include <dhashclient.h>
#include <verify.h>
#include <dbfe.h>
#include <crypt.h>
#include <sys/time.h>

static bigint *IDs;
static void **data;
str control_socket;
static FILE *outfile;
static FILE *bwfile;
unsigned int datasize;

ptr<axprt_stream> xprt;
int fconnected = 0;
int out = 0;
int MAX_OPS_OUT = 1024;

int bps = 0;
int sec = 0;
timecb_t *measurer = NULL;

u_int64_t
getusec ()
{
  timeval tv;
  gettimeofday (&tv, NULL);
  return tv.tv_sec * INT64(1000000) + tv.tv_usec;
}

void
measure_bw (void)
{
  float bw = datasize * bps; // we get called every second
  bw /= 1024; // convert to K.
  sec++;
  unsigned long long usecs = (getusec ()/1000);
  fprintf (bwfile, "%llu\t%6.2f KB/s\n", usecs, bw);
  bps = 0;
  measurer = delaycb (1, wrap (&measure_bw));
}

chordID
make_block (void *data, int g)
{
  // size must be word sized
  //  assert (datasize % sizeof (long) == 0);

  char *rd = (char *)data;
  for (unsigned int i = 0; i < datasize; i++)
        rd[i] = random();
    //rd[i] = (char)('a' + g);
  rd[datasize - 1] = 0;

  return compute_hash (rd, datasize);
}

void
prepare_test_data (int num)
{
  IDs = New chordID[num];
  data = (void **)malloc(sizeof(void *)*num);
  for (int i = 0; i < num; i++) {
    data[i] = malloc(datasize);
    IDs[i] = make_block(data[i], i);
  }
}

void
store_cb (dhash_stat status, ptr<insert_info> i)
{
  out--;

  if (status != DHASH_OK) {
    warn << "store_cb: " << i->key << " " << status << "\n";
    fprintf (outfile, "store error\n");
  } else {
    bps++;
    str buf = strbuf () << "stored " << i->key << " at " << i->path.back () << "\n";
    fprintf (outfile, "%s", buf.cstr ());
  }
}

int
store (dhashclient *dhash, int num)
{
  for (int i = 0; i < num; i++) {
    out++;
    dhash->insert ((char *)data[i], datasize, wrap (store_cb));
    while (out > MAX_OPS_OUT)
      acheck ();
  }

  while (out > 0)
    acheck ();

  return 0;
}

void
fetch_cb (int i, struct timeval start, dhash_stat stat, ptr<dhash_block> blk, vec<chordID> path)
{
  out--;

  if (!blk) {
    strbuf buf;
    buf << "Error: " << IDs[i] << "\n";
    fprintf (outfile, str (buf).cstr ());
  }
  else if (datasize != blk->len || memcmp (data[i], blk->data, datasize) != 0)
    fatal << "verification failed";
  else {
    struct timeval end;
    gettimeofday(&end, NULL);
    strbuf buf;
    float elapsed = (end.tv_sec - start.tv_sec)*1000.0 + (end.tv_usec - start.tv_usec)/1000.0;
    char estr[128];
    sprintf (estr, "%f", elapsed);

    bps++;
    buf << IDs[i] << " " << estr;
    buf << " /";
    for (u_int i = 0; i < blk->times.size (); i++)
      buf << " " << blk->times[i];
    buf << " /";

    buf << " " << blk->hops << " " <<  blk->errors
	<< " " << blk->retries << " ";
    for (u_int i=0; i < path.size (); i++) {
      buf << path[i] << " ";
    }

    buf << "\n";
    fprintf (outfile, str (buf).cstr ());
    if (outfile != stdout)
      warnx << buf;
  }
}

void
fetch (dhashclient &dhash, int num)
{
  for (int i = 0; i < num; i++) {
    out++;
    struct timeval start;
    gettimeofday (&start, NULL);

    dhash.retrieve (IDs[i], DHASH_CONTENTHASH, wrap (fetch_cb, i, start));
    while (out > MAX_OPS_OUT)
      acheck ();
  }

  while (out > 0)
    acheck();
}

void
usage (char *progname)
{
  warn << "vnode_num control_socket num_trials data_size file <f or s> nops seed [bw-file]\n";
  exit(0);
}

void
connected (dhashclient *dhash, int argc, char **argv)
{

  fconnected = 1;
  int num = atoi(argv[3]);
  datasize = atoi(argv[4]);

  char *output = argv[5];
  if (strcmp(output, "-") == 0)
    outfile = stdout;
  else
    outfile = fopen(output, "w");

  char *bwoutput;
  if (argc > 9) {
    bwoutput = argv[9];
    if (strcmp (bwoutput, "-") == 0)
      bwfile = stdout;
    else
      bwfile = fopen (bwoutput, "w");

    fflush (bwfile);
    measurer = delaycb (1, wrap (&measure_bw));
  }

  if (!outfile) {
    printf ("could not open %s\n", output);
    exit(1);
  }

  unsigned int seed = strtoul (argv[8], NULL, 10);
  srandom (seed);
  prepare_test_data (num);

  MAX_OPS_OUT = atoi(argv[7]);

  struct timeval start;
  gettimeofday (&start, NULL);

  if (argv[6][0] == 's')
    store (dhash, num);
  else
    fetch (*dhash, num);

  struct timeval end;
  gettimeofday (&end, NULL);
  float elapsed = (end.tv_sec - start.tv_sec)*1000.0 + (end.tv_usec - start.tv_usec)/1000.0;
  fprintf(outfile, "Total Elapsed: %f\n", elapsed);

  if (bwfile && measurer) {
    timecb_remove (measurer);
    measurer = NULL;
    measure_bw ();
    fclose (bwfile);
  }

  fclose (outfile);

  delete dhash;
}

void
tcp_connect_cb (int argc, char **argv, int fd)
{
  if (fd < 0)
    fatal << "connect failed\n";
  warnx << "... connected!\n";
  xprt = axprt_stream::alloc (fd);
  dhashclient *dhash = New dhashclient (xprt);
  connected (dhash, argc, argv);
}

int
main (int argc, char **argv)
{
  setprogname (argv[0]);

  if (argc < 9) {
    usage (argv[0]);
    exit (1);
  }

  control_socket = argv[2];
  char *cstr = (char *)control_socket.cstr ();
  if (strchr (cstr, ':')) {
    char *port = strchr (cstr, ':');
    *port = 0; //isolate host
    port++; // point at port
    char *host = cstr;
    short i_port = atoi (port);
    warn << "Hi Russ, I'm connecting to " << host << ":" << i_port << "...";
    tcpconnect (host, i_port, wrap (&tcp_connect_cb, argc, argv));
    while (!fconnected) acheck ();
  } else {
    dhashclient *dhash = New dhashclient (control_socket);
    connected (dhash, argc, argv);
  }
}

<commit_msg>Don't say hi to Russ.<commit_after>/*
 *
 * Copyright (C) 2001  Frank Dabek (fdabek@lcs.mit.edu),
 *   		       Massachusetts Institute of Technology
 *
 *
 *  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 OR COPYRIGHT HOLDERS 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 <async.h>
#include <sfsmisc.h>
#include <dhash_common.h>
#include <dhash_prot.h>
#include <dhashclient.h>
#include <verify.h>
#include <dbfe.h>
#include <crypt.h>
#include <sys/time.h>

static bigint *IDs;
static void **data;
str control_socket;
static FILE *outfile;
static FILE *bwfile;
unsigned int datasize;

ptr<axprt_stream> xprt;
int fconnected = 0;
int out = 0;
int MAX_OPS_OUT = 1024;

int bps = 0;
int sec = 0;
timecb_t *measurer = NULL;

u_int64_t
getusec ()
{
  timeval tv;
  gettimeofday (&tv, NULL);
  return tv.tv_sec * INT64(1000000) + tv.tv_usec;
}

void
measure_bw (void)
{
  float bw = datasize * bps; // we get called every second
  bw /= 1024; // convert to K.
  sec++;
  unsigned long long usecs = (getusec ()/1000);
  fprintf (bwfile, "%llu\t%6.2f KB/s\n", usecs, bw);
  bps = 0;
  measurer = delaycb (1, wrap (&measure_bw));
}

chordID
make_block (void *data, int g)
{
  // size must be word sized
  //  assert (datasize % sizeof (long) == 0);

  char *rd = (char *)data;
  for (unsigned int i = 0; i < datasize; i++)
        rd[i] = random();
    //rd[i] = (char)('a' + g);
  rd[datasize - 1] = 0;

  return compute_hash (rd, datasize);
}

void
prepare_test_data (int num)
{
  IDs = New chordID[num];
  data = (void **)malloc(sizeof(void *)*num);
  for (int i = 0; i < num; i++) {
    data[i] = malloc(datasize);
    IDs[i] = make_block(data[i], i);
  }
}

void
store_cb (dhash_stat status, ptr<insert_info> i)
{
  out--;

  if (status != DHASH_OK) {
    warn << "store_cb: " << i->key << " " << status << "\n";
    fprintf (outfile, "store error\n");
  } else {
    bps++;
    str buf = strbuf () << "stored " << i->key << " at " << i->path.back () << "\n";
    fprintf (outfile, "%s", buf.cstr ());
  }
}

int
store (dhashclient *dhash, int num)
{
  for (int i = 0; i < num; i++) {
    out++;
    dhash->insert ((char *)data[i], datasize, wrap (store_cb));
    while (out > MAX_OPS_OUT)
      acheck ();
  }

  while (out > 0)
    acheck ();

  return 0;
}

void
fetch_cb (int i, struct timeval start, dhash_stat stat, ptr<dhash_block> blk, vec<chordID> path)
{
  out--;

  if (!blk) {
    strbuf buf;
    buf << "Error: " << IDs[i] << "\n";
    fprintf (outfile, str (buf).cstr ());
  }
  else if (datasize != blk->len || memcmp (data[i], blk->data, datasize) != 0)
    fatal << "verification failed";
  else {
    struct timeval end;
    gettimeofday(&end, NULL);
    strbuf buf;
    float elapsed = (end.tv_sec - start.tv_sec)*1000.0 + (end.tv_usec - start.tv_usec)/1000.0;
    char estr[128];
    sprintf (estr, "%f", elapsed);

    bps++;
    buf << IDs[i] << " " << estr;
    buf << " /";
    for (u_int i = 0; i < blk->times.size (); i++)
      buf << " " << blk->times[i];
    buf << " /";

    buf << " " << blk->hops << " " <<  blk->errors
	<< " " << blk->retries << " ";
    for (u_int i=0; i < path.size (); i++) {
      buf << path[i] << " ";
    }

    buf << "\n";
    fprintf (outfile, str (buf).cstr ());
    if (outfile != stdout)
      warnx << buf;
  }
}

void
fetch (dhashclient &dhash, int num)
{
  for (int i = 0; i < num; i++) {
    out++;
    struct timeval start;
    gettimeofday (&start, NULL);

    dhash.retrieve (IDs[i], DHASH_CONTENTHASH, wrap (fetch_cb, i, start));
    while (out > MAX_OPS_OUT)
      acheck ();
  }

  while (out > 0)
    acheck();
}

void
usage (char *progname)
{
  warn << "vnode_num control_socket num_trials data_size file <f or s> nops seed [bw-file]\n";
  exit(0);
}

void
connected (dhashclient *dhash, int argc, char **argv)
{

  fconnected = 1;
  int num = atoi(argv[3]);
  datasize = atoi(argv[4]);

  char *output = argv[5];
  if (strcmp(output, "-") == 0)
    outfile = stdout;
  else
    outfile = fopen(output, "w");

  char *bwoutput;
  if (argc > 9) {
    bwoutput = argv[9];
    if (strcmp (bwoutput, "-") == 0)
      bwfile = stdout;
    else
      bwfile = fopen (bwoutput, "w");

    fflush (bwfile);
    measurer = delaycb (1, wrap (&measure_bw));
  }

  if (!outfile) {
    printf ("could not open %s\n", output);
    exit(1);
  }

  unsigned int seed = strtoul (argv[8], NULL, 10);
  srandom (seed);
  prepare_test_data (num);

  MAX_OPS_OUT = atoi(argv[7]);

  struct timeval start;
  gettimeofday (&start, NULL);

  if (argv[6][0] == 's')
    store (dhash, num);
  else
    fetch (*dhash, num);

  struct timeval end;
  gettimeofday (&end, NULL);
  float elapsed = (end.tv_sec - start.tv_sec)*1000.0 + (end.tv_usec - start.tv_usec)/1000.0;
  fprintf(outfile, "Total Elapsed: %f\n", elapsed);

  if (bwfile && measurer) {
    timecb_remove (measurer);
    measurer = NULL;
    measure_bw ();
    fclose (bwfile);
  }

  fclose (outfile);

  delete dhash;
}

void
tcp_connect_cb (int argc, char **argv, int fd)
{
  if (fd < 0)
    fatal << "connect failed\n";
  warnx << "... connected!\n";
  xprt = axprt_stream::alloc (fd);
  dhashclient *dhash = New dhashclient (xprt);
  connected (dhash, argc, argv);
}

int
main (int argc, char **argv)
{
  setprogname (argv[0]);

  if (argc < 9) {
    usage (argv[0]);
    exit (1);
  }

  control_socket = argv[2];
  char *cstr = (char *)control_socket.cstr ();
  if (strchr (cstr, ':')) {
    char *port = strchr (cstr, ':');
    *port = 0; //isolate host
    port++; // point at port
    char *host = cstr;
    short i_port = atoi (port);
    warn << "Connecting to " << host << ":" << i_port << " via TCP...";
    tcpconnect (host, i_port, wrap (&tcp_connect_cb, argc, argv));
    while (!fconnected) acheck ();
  } else {
    dhashclient *dhash = New dhashclient (control_socket);
    connected (dhash, argc, argv);
  }
}

<|endoftext|>


<commit_before><commit_msg>Dynamically reduce precision when rendering "high-precision" values, to keep within ~4 digits (plus decimal point) and make the best use of the limited display real estate.<commit_after><|endoftext|>


<commit_before>#include "photoeffects.hpp"

using namespace cv;

int warmify(cv::InputArray src, cv::OutputArray dst, uchar delta)
{
    CV_Assert(src.type() == CV_8UC3);
    Mat imgSrc = src.getMat();
    CV_Assert(imgSrc.data);
    Mat imgDst(imgSrc.size(), CV_8UC3);
    Vec3b intensity, intensityNew;

    for (int i = 0; i < imgSrc.rows; i++)
    {
        for (int j = 0; j < imgSrc.cols; j++)
        {
            intensity = imgSrc.at<Vec3b>(i, j);
            intensityNew[0] = intensity[0];
            intensityNew[1] = (intensity[1] + delta < 255) ? (uchar)(intensity[1] + delta) : 255;
            intensityNew[2] = (intensity[2] + delta < 255) ? (uchar)(intensity[2] + delta) : 255;
            imgDst.at<Vec3b>(i, j) = intensityNew;
        }
    }
    imgDst.copyTo(dst);
    return 0;
}

<commit_msg>warmify.cpp was correct<commit_after>#include "photoeffects.hpp"

using namespace cv;

int warmify(cv::InputArray src, cv::OutputArray dst, uchar delta)
{
    CV_Assert(src.type() == CV_8UC3);

    Mat imgSrc = src.getMat();
    CV_Assert(imgSrc.data);

    dst.create(imgSrc.size(), CV_8UC3);
    Mat imgDst = dst.getMat();
    Vec3b intensityNew;

    for (int i = 0; i < imgSrc.rows; i++)
    {
        for (int j = 0; j < imgSrc.cols; j++)
        {
            intensityNew = imgSrc.at<Vec3b>(i, j);
            intensityNew[1] = (intensityNew[1] + delta < 255) ? (uchar)(intensityNew[1] + delta) : 255;
            intensityNew[2] = (intensityNew[2] + delta < 255) ? (uchar)(intensityNew[2] + delta) : 255;
            imgDst.at<Vec3b>(i, j) = intensityNew;
        }
    }
    return 0;
}

<|endoftext|>


<commit_before>// @(#)root/proofplayer:$Id$
// Author: Maarten Ballintijn   7/06/2004

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TStatus                                                              //
//                                                                      //
// This class holds the status of an ongoing operation and collects     //
// error messages. It provides a Merge() operation allowing it to       //
// be used in PROOF to monitor status in the slaves.                    //
// No messages indicates success.                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStatus.h"
#include "Riostream.h"
#include "TClass.h"
#include "TList.h"

ClassImp(TStatus)

//______________________________________________________________________________
TStatus::TStatus() : fVirtMemMax(-1), fResMemMax(-1)
{
   // Deafult constructor.

   SetName("PROOF_Status");
   fIter = fMsgs.begin();
}

//______________________________________________________________________________
void TStatus::Add(const char *mesg)
{
   // Add an error message.

   fMsgs.insert(mesg);
   Reset();
}

//______________________________________________________________________________
Int_t TStatus::Merge(TCollection *li)
{
   // PROOF Merge() function.

   TIter stats(li);
   Info("Merge", "Start: Max virtual memory: %.2f MB \tMax resident memory: %.2f MB ",
          GetVirtMemMax()/1024., GetResMemMax()/1024.);
   while (TObject *obj = stats()) {
      TStatus *s = dynamic_cast<TStatus*>(obj);
      if (s == 0) continue;

      MsgIter_t i = s->fMsgs.begin();
      MsgIter_t end = s->fMsgs.end();
      for (; i != end; i++)
         Add(i->c_str());

      SetMemValues(s->GetVirtMemMax(), s->GetResMemMax());
   Info("Merge", "During: Max virtual memory: %.2f MB \tMax resident memory: %.2f MB ",
          GetVirtMemMax()/1024., GetResMemMax()/1024.);
   }
   Info("Merge", "End: Max virtual memory: %.2f MB \tMax resident memory: %.2f MB ",
          GetVirtMemMax()/1024., GetResMemMax()/1024.);

   return fMsgs.size();
}

//______________________________________________________________________________
void TStatus::Print(Option_t * /*option*/) const
{
   // Standard print function.

   Printf("OBJ: %s\t%s\t%s", IsA()->GetName(), GetName(), (IsOk() ? "OK" : "ERROR"));

   MsgIter_t i = fMsgs.begin();
   for (; i != fMsgs.end(); i++)
      Printf("\t%s", (*i).c_str());

   Printf(" Max virtual memory: %.2f MB \tMax resident memory: %.2f MB ",
          GetVirtMemMax()/1024., GetResMemMax()/1024.);
}

//______________________________________________________________________________
void TStatus::Reset()
{
   // Reset the iterator on the messages.

   fIter = fMsgs.begin();
}

//______________________________________________________________________________
const char *TStatus::NextMesg()
{
   // Return the next message or 0.

   if (fIter != fMsgs.end()) {
      return (*fIter++).c_str();
   } else {
      return 0;
   }
}

//______________________________________________________________________________
void TStatus::SetMemValues(Long_t vmem, Long_t rmem)
{
   // Set max memory values

   if (vmem > 0. && (fVirtMemMax < 0. || vmem > fVirtMemMax)) fVirtMemMax = vmem;
   if (rmem > 0. && (fResMemMax < 0. || rmem > fResMemMax)) fResMemMax = rmem;
}

<commit_msg>Remove debug statements<commit_after>// @(#)root/proofplayer:$Id$
// Author: Maarten Ballintijn   7/06/2004

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TStatus                                                              //
//                                                                      //
// This class holds the status of an ongoing operation and collects     //
// error messages. It provides a Merge() operation allowing it to       //
// be used in PROOF to monitor status in the slaves.                    //
// No messages indicates success.                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStatus.h"
#include "Riostream.h"
#include "TClass.h"
#include "TList.h"
#include "TProofDebug.h"

ClassImp(TStatus)

//______________________________________________________________________________
TStatus::TStatus() : fVirtMemMax(-1), fResMemMax(-1)
{
   // Deafult constructor.

   SetName("PROOF_Status");
   fIter = fMsgs.begin();
}

//______________________________________________________________________________
void TStatus::Add(const char *mesg)
{
   // Add an error message.

   fMsgs.insert(mesg);
   Reset();
}

//______________________________________________________________________________
Int_t TStatus::Merge(TCollection *li)
{
   // PROOF Merge() function.

   TIter stats(li);
   PDB(kOutput,1)
      Info("Merge", "start: max virtual memory: %.2f MB \tmax resident memory: %.2f MB ",
                    GetVirtMemMax()/1024., GetResMemMax()/1024.);
   while (TObject *obj = stats()) {
      TStatus *s = dynamic_cast<TStatus*>(obj);
      if (s == 0) continue;

      MsgIter_t i = s->fMsgs.begin();
      MsgIter_t end = s->fMsgs.end();
      for (; i != end; i++)
         Add(i->c_str());

      SetMemValues(s->GetVirtMemMax(), s->GetResMemMax());
      PDB(kOutput,1)
         Info("Merge", "during: max virtual memory: %.2f MB \t"
                       "max resident memory: %.2f MB ",
                       GetVirtMemMax()/1024., GetResMemMax()/1024.);
   }

   return fMsgs.size();
}

//______________________________________________________________________________
void TStatus::Print(Option_t * /*option*/) const
{
   // Standard print function.

   Printf("OBJ: %s\t%s\t%s", IsA()->GetName(), GetName(), (IsOk() ? "OK" : "ERROR"));

   MsgIter_t i = fMsgs.begin();
   for (; i != fMsgs.end(); i++)
      Printf("\t%s", (*i).c_str());

   Printf(" Max virtual memory: %.2f MB \tMax resident memory: %.2f MB ",
          GetVirtMemMax()/1024., GetResMemMax()/1024.);
}

//______________________________________________________________________________
void TStatus::Reset()
{
   // Reset the iterator on the messages.

   fIter = fMsgs.begin();
}

//______________________________________________________________________________
const char *TStatus::NextMesg()
{
   // Return the next message or 0.

   if (fIter != fMsgs.end()) {
      return (*fIter++).c_str();
   } else {
      return 0;
   }
}

//______________________________________________________________________________
void TStatus::SetMemValues(Long_t vmem, Long_t rmem)
{
   // Set max memory values

   if (vmem > 0. && (fVirtMemMax < 0. || vmem > fVirtMemMax)) fVirtMemMax = vmem;
   if (rmem > 0. && (fResMemMax < 0. || rmem > fResMemMax)) fResMemMax = rmem;
}

<|endoftext|>