<commit_before>/*
 * Copyright 2016 <Lennart Nachtigall> <firesurfer65@yahoo.de>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "EntityBase.h"
namespace ros2_components {

EntityBase::EntityBase(int64_t _id, bool _subscribe, std::shared_ptr<rclcpp::node::Node> _parentNode, string _className)
{
    this->id = _id;
    this->subscriber = _subscribe;
    this->parentNode = _parentNode;
    this->className = _className;
    this->active = true;
    this->name = getClassName()  + std::to_string(id);

    //TODO rework meta mechanism

    REFLECT(virtualEntity);
    REFLECT(className);
    REFLECT(active);
    qRegisterMetaType<int64_t>("int64_t");
    qRegisterMetaType<std::string>("std::string");

}

EntityBase::EntityBase(int64_t _id, bool _subscribe, std::shared_ptr<rclcpp::node::Node> _parentNode, string _className, string _componentName):EntityBase(_id,_subscribe, _parentNode,_className)
{
    this->name = _componentName + std::to_string(_id);
}

EntityBase::~EntityBase()
{
    std::cout << "Destroying: " << getName() << std::endl;
}

int64_t EntityBase::getId()
{
    return id;
}

string EntityBase::getName()
{
    return name;
}

string EntityBase::getClassName()
{
    /* const QMetaObject* metaObject = this->metaObject();

    std::string localClassName = metaObject->className();
    localClassName.erase(0, localClassName.find_last_of(":")+1);*/
    return className;
}

bool EntityBase::isVirtual()
{
    return virtualEntity;
}

bool EntityBase::isSubscriber()
{
    return subscriber;
}

rclcpp::node::Node::SharedPtr EntityBase::getParentNode()
{
    return parentNode;
}

void EntityBase::addChild(std::shared_ptr<EntityBase> child, bool remote)
{
    LOG(LogLevel::Debug) << "addChild called with: " << child->getName() << " from: " << getName()<< std::endl;
    childs.push_back(child);
    child->setParent(shared_from_this());
    emit childAdded(child,child->getParent(),remote);
}

void EntityBase::removeChild(std::shared_ptr<EntityBase> child, bool remote)
{
    auto iteratorPos = std::find(childs.begin(), childs.end(), child) ;
    if(iteratorPos != childs.end())
    {
        childs.erase(iteratorPos);
    }
    else
        throw std::runtime_error("Can't remove given child - child not found!");
    emit childRemoved(child,shared_from_this(), remote);
}

std::shared_ptr<EntityBase> EntityBase::getChildById(int64_t id)
{
    for(auto & child: childs)
    {
        if(child->getId() == id)
        {
            return child;
        }
    }
    throw std::runtime_error("Child with id: " + std::to_string(id) + " not found");
}

uint64_t EntityBase::countChilds()
{
    return childs.size();
}

std::shared_ptr<EntityBase> EntityBase::getParent()
{
    return this->parent;
}

void EntityBase::setParent(std::shared_ptr<EntityBase> par)
{
    this->parent = par;
}

string EntityBase::getTopicName()
{
    if(!isSubscriber())
        return pubBase->get_topic_name();
    else
        return subBase->get_topic_name();
}

void EntityBase::IterateThroughAllProperties(std::function<void(QMetaProperty)> func)
{
    const QMetaObject* metaObj = this->metaObject();
    while(metaObj != NULL)
    {
        for (int i = metaObj->propertyOffset(); i < metaObj->propertyCount(); ++i)
        {
            func(metaObj->property(i));
        }
        metaObj = metaObj->superClass();
    }
}

}
<commit_msg>Added reflect for description<commit_after>/*
 * Copyright 2016 <Lennart Nachtigall> <firesurfer65@yahoo.de>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "EntityBase.h"
namespace ros2_components {

EntityBase::EntityBase(int64_t _id, bool _subscribe, std::shared_ptr<rclcpp::node::Node> _parentNode, string _className)
{
    this->id = _id;
    this->subscriber = _subscribe;
    this->parentNode = _parentNode;
    this->className = _className;
    this->active = true;
    this->name = getClassName()  + std::to_string(id);

    //TODO rework meta mechanism

    REFLECT(virtualEntity);
    REFLECT(className);
    REFLECT(active);
    REFLECT(description)
    qRegisterMetaType<int64_t>("int64_t");
    qRegisterMetaType<std::string>("std::string");

}

EntityBase::EntityBase(int64_t _id, bool _subscribe, std::shared_ptr<rclcpp::node::Node> _parentNode, string _className, string _componentName):EntityBase(_id,_subscribe, _parentNode,_className)
{
    this->name = _componentName + std::to_string(_id);
}

EntityBase::~EntityBase()
{
    std::cout << "Destroying: " << getName() << std::endl;
}

int64_t EntityBase::getId()
{
    return id;
}

string EntityBase::getName()
{
    return name;
}

string EntityBase::getClassName()
{
    /* const QMetaObject* metaObject = this->metaObject();

    std::string localClassName = metaObject->className();
    localClassName.erase(0, localClassName.find_last_of(":")+1);*/
    return className;
}

bool EntityBase::isVirtual()
{
    return virtualEntity;
}

bool EntityBase::isSubscriber()
{
    return subscriber;
}

rclcpp::node::Node::SharedPtr EntityBase::getParentNode()
{
    return parentNode;
}

void EntityBase::addChild(std::shared_ptr<EntityBase> child, bool remote)
{
    LOG(LogLevel::Debug) << "addChild called with: " << child->getName() << " from: " << getName()<< std::endl;
    childs.push_back(child);
    child->setParent(shared_from_this());
    emit childAdded(child,child->getParent(),remote);
}

void EntityBase::removeChild(std::shared_ptr<EntityBase> child, bool remote)
{
    auto iteratorPos = std::find(childs.begin(), childs.end(), child) ;
    if(iteratorPos != childs.end())
    {
        childs.erase(iteratorPos);
    }
    else
        throw std::runtime_error("Can't remove given child - child not found!");
    emit childRemoved(child,shared_from_this(), remote);
}

std::shared_ptr<EntityBase> EntityBase::getChildById(int64_t id)
{
    for(auto & child: childs)
    {
        if(child->getId() == id)
        {
            return child;
        }
    }
    throw std::runtime_error("Child with id: " + std::to_string(id) + " not found");
}

uint64_t EntityBase::countChilds()
{
    return childs.size();
}

std::shared_ptr<EntityBase> EntityBase::getParent()
{
    return this->parent;
}

void EntityBase::setParent(std::shared_ptr<EntityBase> par)
{
    this->parent = par;
}

string EntityBase::getTopicName()
{
    if(!isSubscriber())
        return pubBase->get_topic_name();
    else
        return subBase->get_topic_name();
}

void EntityBase::IterateThroughAllProperties(std::function<void(QMetaProperty)> func)
{
    const QMetaObject* metaObj = this->metaObject();
    while(metaObj != NULL)
    {
        for (int i = metaObj->propertyOffset(); i < metaObj->propertyCount(); ++i)
        {
            func(metaObj->property(i));
        }
        metaObj = metaObj->superClass();
    }
}

}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <esn/network_nsli.hpp>
#include <esn/network.hpp>
#include <random>

TEST( ESN, CreateNetworkNSLI )
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 10;
    params.neuronCount = 100;
    params.outputCount = 10;
    std::unique_ptr< ESN::Network > network = CreateNetwork( params );
}

TEST(ESN, SetInputs)
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 25;
    params.neuronCount = 100;
    params.outputCount = 17;
    auto network = CreateNetwork( params );

    std::default_random_engine randomEngine;
    std::uniform_real_distribution<float > randomDist( -1.0f, 1.0f );
    std::vector< float > inputs( params.inputCount );
    for (int s = 0; s < 100; ++ s)
    {
        for (int i = 0; i < params.inputCount; ++ i)
            inputs[i] = randomDist(randomEngine);
        network->SetInputs(inputs);
    }
}

TEST( ESN, StepNSLI )
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 11;
    params.neuronCount = 100;
    params.outputCount = 15;
    std::unique_ptr< ESN::Network > network = CreateNetwork( params );
    network->Step( 0.1f );
}

TEST( ESN, TrainNSLI )
{
    const unsigned kSampleCount = 100;

    ESN::NetworkParamsNSLI params;
    params.inputCount = 1;
    params.neuronCount = 100;
    params.outputCount = 1;
    auto network = CreateNetwork( params );

    std::vector< std::vector< float > > inputs( kSampleCount );
    std::vector< std::vector< float > > outputs( kSampleCount );
    for ( int i = 0; i < kSampleCount; ++ i )
    {
        inputs[i].resize( params.inputCount );
        inputs[i][0] = 1.0f;
        outputs[i].resize( params.outputCount );
        outputs[i][0] = 1.0f;
    }

    network->Train( inputs, outputs );
}

TEST(ESN, TrainOnline)
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 32;
    params.neuronCount = 64;
    params.outputCount = 16;
    auto network = CreateNetwork(params);

    std::default_random_engine randomEngine;
    std::uniform_real_distribution<float> randomDist(-0.5f, 0.5f);
    std::vector<float> inputs(params.inputCount);
    std::vector<float> outputs(params.outputCount);
    for (int s = 0; s < 100; ++ s)
    {
        for (int i = 0; i < params.inputCount; ++ i)
            inputs[i] = randomDist(randomEngine);
        for (int i = 0; i < params.outputCount; ++ i)
            outputs[i] = randomDist(randomEngine);
        network->SetInputs(inputs);
        network->Step(1.0f);
        network->TrainOnline(outputs, false);
    }
}
<commit_msg>add test-case ESN.NoFeedback<commit_after>#include <gtest/gtest.h>
#include <esn/network_nsli.hpp>
#include <esn/network.hpp>
#include <random>

TEST( ESN, CreateNetworkNSLI )
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 10;
    params.neuronCount = 100;
    params.outputCount = 10;
    std::unique_ptr< ESN::Network > network = CreateNetwork( params );
}

TEST(ESN, SetInputs)
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 25;
    params.neuronCount = 100;
    params.outputCount = 17;
    auto network = CreateNetwork( params );

    std::default_random_engine randomEngine;
    std::uniform_real_distribution<float > randomDist( -1.0f, 1.0f );
    std::vector< float > inputs( params.inputCount );
    for (int s = 0; s < 100; ++ s)
    {
        for (int i = 0; i < params.inputCount; ++ i)
            inputs[i] = randomDist(randomEngine);
        network->SetInputs(inputs);
    }
}

TEST( ESN, StepNSLI )
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 11;
    params.neuronCount = 100;
    params.outputCount = 15;
    std::unique_ptr< ESN::Network > network = CreateNetwork( params );
    network->Step( 0.1f );
}

TEST( ESN, TrainNSLI )
{
    const unsigned kSampleCount = 100;

    ESN::NetworkParamsNSLI params;
    params.inputCount = 1;
    params.neuronCount = 100;
    params.outputCount = 1;
    auto network = CreateNetwork( params );

    std::vector< std::vector< float > > inputs( kSampleCount );
    std::vector< std::vector< float > > outputs( kSampleCount );
    for ( int i = 0; i < kSampleCount; ++ i )
    {
        inputs[i].resize( params.inputCount );
        inputs[i][0] = 1.0f;
        outputs[i].resize( params.outputCount );
        outputs[i][0] = 1.0f;
    }

    network->Train( inputs, outputs );
}

TEST(ESN, TrainOnline)
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 32;
    params.neuronCount = 64;
    params.outputCount = 16;
    auto network = CreateNetwork(params);

    std::default_random_engine randomEngine;
    std::uniform_real_distribution<float> randomDist(-0.5f, 0.5f);
    std::vector<float> inputs(params.inputCount);
    std::vector<float> outputs(params.outputCount);
    for (int s = 0; s < 100; ++ s)
    {
        for (int i = 0; i < params.inputCount; ++ i)
            inputs[i] = randomDist(randomEngine);
        for (int i = 0; i < params.outputCount; ++ i)
            outputs[i] = randomDist(randomEngine);
        network->SetInputs(inputs);
        network->Step(1.0f);
        network->TrainOnline(outputs, false);
    }
}

TEST(ESN, NoFeedback)
{
    ESN::NetworkParamsNSLI params;
    params.inputCount = 32;
    params.neuronCount = 64;
    params.outputCount = 16;
    params.hasOutputFeedback = false;
    auto network = CreateNetwork(params);

    std::default_random_engine randomEngine;
    std::uniform_real_distribution<float> randomDist(-0.5f, 0.5f);
    std::vector<float> inputs(params.inputCount);
    std::vector<float> outputs(params.outputCount);
    for (int s = 0; s < 100; ++ s)
    {
        for (int i = 0; i < params.inputCount; ++ i)
            inputs[i] = randomDist(randomEngine);
        for (int i = 0; i < params.outputCount; ++ i)
            outputs[i] = randomDist(randomEngine);
        network->SetInputs(inputs);
        network->Step(1.0f);
        network->TrainOnline(outputs, false);
    }
}
<|endoftext|>


<commit_before>/*
** Copyright 2011-2014 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <cstdlib>
#include <QMutexLocker>
#include <QWaitCondition>
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/io/events.hh"
#include "com/centreon/broker/io/exceptions/shutdown.hh"
#include "com/centreon/broker/io/raw.hh"
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/tcp/stream.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::tcp;

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Constructor.
 *
 *  @param[in] sock Socket used by this stream.
 */
stream::stream(misc::shared_ptr<QTcpSocket> sock)
  : _mutex(new QMutex),
    _process_in(true),
    _process_out(true),
    _socket(sock),
    _timeout(-1) {}

/**
 *  Constructor.
 *
 *  @param[in] sock  Socket used by this stream.
 *  @param[in] mutex Mutex used by this stream.
 */
stream::stream(
          misc::shared_ptr<QTcpSocket> sock,
          misc::shared_ptr<QMutex> mutex)
  : _mutex(mutex),
    _process_in(true),
    _process_out(true),
    _socket(sock),
    _timeout(-1) {}

/**
 *  Destructor.
 */
stream::~stream() {
  QMutexLocker lock(&*_mutex);
  if (!_socket.isNull())
    _socket->close();
}

/**
 *  Enable or disable event processing.
 *
 *  @param[in] in  Set to true to enable input event processing.
 *  @param[in] out Set to true to enable output event processing.
 */
void stream::process(bool in, bool out) {
  _process_in = in;
  _process_out = out;
  return ;
}

/**
 *  Read data from the socket.
 *
 *  @param[out] d Data read.
 */
void stream::read(misc::shared_ptr<io::data>& d) {
  d.clear();
  QMutexLocker lock(&*_mutex);

  // Check processing flags.
  if (!_process_in)
    throw (io::exceptions::shutdown(!_process_in, !_process_out)
           << "TCP stream is shutdown");

  // If data is already available, skip the waitForReadyRead() loop.
  if (_socket->bytesAvailable() <= 0) {
    while (1) {
      bool ret;
      if (!(ret = _socket->waitForReadyRead(
                             (_timeout == -1)
                             ? 200
                             : _timeout))
          // Standalone socket.
          && ((_timeout != -1)
              // Disconnected socket with no data.
              || ((_socket->state()
                   == QAbstractSocket::UnconnectedState)
                  && (_socket->bytesAvailable() <= 0))))
        throw (exceptions::msg() << "TCP stream is disconnected");
      if (ret
          || (_socket->error() != QAbstractSocket::SocketTimeoutError)
          || (_socket->bytesAvailable() > 0))
        break ;
      else {
        QWaitCondition cv;
        cv.wait(&*_mutex, 1);
      }
      if (!_process_in)
        throw (io::exceptions::shutdown(!_process_in, !_process_out)
               << "TCP stream is shutdown");
    }
  }

  char buffer[2048];
  qint64 rb(_socket->read(buffer, sizeof(buffer)));
  if (rb < 0)
    throw (exceptions::msg() << "TCP: error while reading: "
           << _socket->errorString());
  misc::shared_ptr<io::raw> data(new io::raw);
#if QT_VERSION >= 0x040500
  data->append(buffer, rb);
#else
  data->append(QByteArray(buffer, rb));
#endif // Qt version
  d = data;
  return ;
}

/**
 *  Set connection timeout.
 *
 *  @param[in] msecs Timeout in ms.
 */
void stream::set_timeout(int msecs) {
  _timeout = msecs;
  return ;
}

/**
 *  Write data to the socket.
 *
 *  @param[in] d Data to write.
 *
 *  @return Number of events acknowledged.
 */
unsigned int stream::write(misc::shared_ptr<io::data> const& d) {
  // Check that data exists and should be processed.
  if (!_process_out)
    throw (io::exceptions::shutdown(!_process_in, !_process_out)
             << "TCP stream is shutdown");
  if (d.isNull())
    return (1);

  if (d->type() == io::events::data_type<io::events::internal, 1>::value) {
    misc::shared_ptr<io::raw> r(d.staticCast<io::raw>());
    logging::debug(logging::low) << "TCP: write request of "
      << r->size() << " bytes";
    QMutexLocker lock(&*_mutex);
    qint64 wb(_socket->write(static_cast<char*>(r->QByteArray::data()),
                             r->size()));
    if ((wb < 0) || (_socket->state() == QAbstractSocket::UnconnectedState))
      throw (exceptions::msg() << "TCP: error while writing: "
             << _socket->errorString());
    _socket->waitForBytesWritten(-1);
  }
  return (1);
}
<commit_msg>TCP: check for an error return in waitForBytesWritten().<commit_after>/*
** Copyright 2011-2014 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <cstdlib>
#include <QMutexLocker>
#include <QWaitCondition>
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/io/events.hh"
#include "com/centreon/broker/io/exceptions/shutdown.hh"
#include "com/centreon/broker/io/raw.hh"
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/tcp/stream.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::tcp;

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Constructor.
 *
 *  @param[in] sock Socket used by this stream.
 */
stream::stream(misc::shared_ptr<QTcpSocket> sock)
  : _mutex(new QMutex),
    _process_in(true),
    _process_out(true),
    _socket(sock),
    _timeout(-1) {}

/**
 *  Constructor.
 *
 *  @param[in] sock  Socket used by this stream.
 *  @param[in] mutex Mutex used by this stream.
 */
stream::stream(
          misc::shared_ptr<QTcpSocket> sock,
          misc::shared_ptr<QMutex> mutex)
  : _mutex(mutex),
    _process_in(true),
    _process_out(true),
    _socket(sock),
    _timeout(-1) {}

/**
 *  Destructor.
 */
stream::~stream() {
  QMutexLocker lock(&*_mutex);
  if (!_socket.isNull())
    _socket->close();
}

/**
 *  Enable or disable event processing.
 *
 *  @param[in] in  Set to true to enable input event processing.
 *  @param[in] out Set to true to enable output event processing.
 */
void stream::process(bool in, bool out) {
  _process_in = in;
  _process_out = out;
  return ;
}

/**
 *  Read data from the socket.
 *
 *  @param[out] d Data read.
 */
void stream::read(misc::shared_ptr<io::data>& d) {
  d.clear();
  QMutexLocker lock(&*_mutex);

  // Check processing flags.
  if (!_process_in)
    throw (io::exceptions::shutdown(!_process_in, !_process_out)
           << "TCP stream is shutdown");

  // If data is already available, skip the waitForReadyRead() loop.
  if (_socket->bytesAvailable() <= 0) {
    while (1) {
      bool ret;
      if (!(ret = _socket->waitForReadyRead(
                             (_timeout == -1)
                             ? 200
                             : _timeout))
          // Standalone socket.
          && ((_timeout != -1)
              // Disconnected socket with no data.
              || ((_socket->state()
                   == QAbstractSocket::UnconnectedState)
                  && (_socket->bytesAvailable() <= 0))))
        throw (exceptions::msg() << "TCP stream is disconnected");
      if (ret
          || (_socket->error() != QAbstractSocket::SocketTimeoutError)
          || (_socket->bytesAvailable() > 0))
        break ;
      else {
        QWaitCondition cv;
        cv.wait(&*_mutex, 1);
      }
      if (!_process_in)
        throw (io::exceptions::shutdown(!_process_in, !_process_out)
               << "TCP stream is shutdown");
    }
  }

  char buffer[2048];
  qint64 rb(_socket->read(buffer, sizeof(buffer)));
  if (rb < 0)
    throw (exceptions::msg() << "TCP: error while reading: "
           << _socket->errorString());
  misc::shared_ptr<io::raw> data(new io::raw);
#if QT_VERSION >= 0x040500
  data->append(buffer, rb);
#else
  data->append(QByteArray(buffer, rb));
#endif // Qt version
  d = data;
  return ;
}

/**
 *  Set connection timeout.
 *
 *  @param[in] msecs Timeout in ms.
 */
void stream::set_timeout(int msecs) {
  _timeout = msecs;
  return ;
}

/**
 *  Write data to the socket.
 *
 *  @param[in] d Data to write.
 *
 *  @return Number of events acknowledged.
 */
unsigned int stream::write(misc::shared_ptr<io::data> const& d) {
  // Check that data exists and should be processed.
  if (!_process_out)
    throw (io::exceptions::shutdown(!_process_in, !_process_out)
             << "TCP stream is shutdown");
  if (d.isNull())
    return (1);

  if (d->type() == io::events::data_type<io::events::internal, 1>::value) {
    misc::shared_ptr<io::raw> r(d.staticCast<io::raw>());
    logging::debug(logging::low) << "TCP: write request of "
      << r->size() << " bytes";
    QMutexLocker lock(&*_mutex);
    qint64 wb(_socket->write(static_cast<char*>(r->QByteArray::data()),
                             r->size()));
    if ((wb < 0) || (_socket->state() == QAbstractSocket::UnconnectedState))
      throw (exceptions::msg() << "TCP: error while writing: "
             << _socket->errorString());
    if (_socket->waitForBytesWritten(-1) == false)
      throw (exceptions::msg() << "TCP: error while sending data: "
             << _socket->errorString());
  }
  return (1);
}
<|endoftext|>


<commit_before>#include <sailboat.h>
#include "buoy.h"
#include <stdio.h>
#include <stdlib.h>

Buoy::Buoy(int nb, double xb, double yb, double zb, double ub, double dt)
{

    this->dt = dt;

    // id
    n = nb;

    // Position
    x = xb;
    y = yb;
    z = zb;

    Xdot[0] = 0;
    Xdot[1] = 0;
    Xdot[2] = 0;

    Xdot2[0] = 0;
    Xdot2[1] = 0;
    Xdot2[2] = 0;

    // Command
    //volBal = BUOY_CONTROL;
    volBal = 0;
    S = 1;

    // Caracteristiques physiques
    m = 100;
    vol = 100;
    rho_w=1.025;
    mvol = m/(vol-volBal); //kg/m³

    // Lorentz variables
    sigma = 10.0;
    beta = 8.0/3.0;
    rho = 28;
    k = 0.0;
    delta = mvol/rho_w; //delta = rapport de la masse volumique de l'eau sur celui de la bouee
    mu = 1.0; //coefficient de resistance de Stokes
    theta = 10;

    phi_i = 1.0;
    Ri = 100.0;

    int i =0;
    //TODO : tourne a linfini
    /*
    while (Xi[i]=!NULL)
    {
        double r = rand() % 200;
        double ang = rand() % 200;
        printf("rayon : %f angle : %f\n", r, ang);
        Xi[i] = r*cos(314*ang);
        Yi[i] = r*sin(314*ang);
        i++;
        printf("valeur de i :%i\n", i);
    }
    */
   printf("appel dans le constructeur :%f\n", Xi[0]);
    Xi[0] = 100;
    Xi[1] = 100;
    Xi[2] = -100;
    Xi[3] = -100;

    Yi[0] = 100;
    Yi[1] = -100;
    Yi[2] = -100;
    Yi[3] = 100;

}

void Buoy::lorenz(void)
{
    Xdot[0] = sigma*(y-x)*dt;
    Xdot[1] = (x*(rho-z)-y)*dt;
    Xdot[2] = (k*(x*y-beta*z)+u);
}

void Buoy::sinLine(double simuTime)
{
    double depth = 40; // m
    double freq = 0.05; // Hz
    double speed = 10;  // m/s
    Xdot[0] = 0;      //X
    Xdot[1] = 0;      //Y
    Xdot[2] = speed*sin(2*M_PI*simuTime*freq); //Z
}

void Buoy::pendulum(void)
{
    Xdot[0] = y;
    Xdot[1] = -sin(x);
    Xdot[2] = u;
}

void Buoy::stateEq(void)
{
    Xdot[0] = sin(0.001*(y+0.9*z));
    Xdot[1] = -sin(0.001*(x+z));
    Xdot[2] = u;

}

void Buoy::setCommand(double ub)
{
    u = ub;
}

int Buoy::getNumber(void)
{
    return n;
}

double* Buoy::getPos(void)
{
    double* xd = new double[4];
    xd[0] = sqrt(pow(Xdot[0],2.0)+pow(Xdot[1],2.0)+pow(Xdot[2],2.0));
    xd[1] = x;
    xd[2] = y;
    xd[3] = z;
    return xd;
}

void Buoy::eqParticuleSimple(void)
{
    vx = -2*sin(y);
    vy = 2*sin(x);

    Dx = -4*sin(x)*cos(y);
    Dy = 4*sin(y)*cos(x);
}

void Buoy::eqParticule(void)
{
    double d2;
    double dvxx, dvyx, dvxy, dvyy;
    vx = 0;
    vy = 0;
    dvxx = 0;
    dvyx = 0;
    dvxy = 0;
    dvyy = 0;

    for (int i=0;i<4;i++)
    {
        d2 = (x-Xi[i])*(x-Xi[i])+(y-Yi[i])*(y-Yi[i]);

        vx   += phi_i*2*y*(y-Yi[i])*exp(-1*d2/(Ri*Ri))/(Ri*Ri);
        vy   -= phi_i*2*x*(x-Xi[i])*exp(-1*d2/(Ri*Ri))/(Ri*Ri);

        dvxx -= phi_i*4*y*(y-Yi[i])*(x-Xi[i])*exp(-1*d2/(Ri*Ri))/(Ri*Ri*Ri*Ri);
        dvxy += 2*phi_i*exp(-1*d2/(Ri*Ri))/(Ri*Ri)*((2*y-Yi[i])-2*y*(y-Yi[i])*(y-Yi[i]));
        dvyx -= 2*phi_i*exp(-1*d2/(Ri*Ri))/(Ri*Ri)*((2*x-Xi[i])-2*x*(x-Xi[i])*(x-Xi[i]));
        dvyy += phi_i*4*x*(y-Yi[i])*(x-Xi[i])*exp(-1*d2/(Ri*Ri))/(Ri*Ri*Ri*Ri);
    }

    Dx = vx*dvxx+vy*dvxy;
    Dy = vx*dvyx+vy*dvyy;
}

void Buoy::vortex(void)
{
    //Dx = vy*0.5*(1+sin(theta*z))*2*cos(y);
    //Dy = vx*0.5*(1+sin(theta*z))*2*cos(x);
    eqParticule();
    mvol = m/(vol-volBal);
    delta = mvol/rho_w;
    Xdot2[0] = delta * Dx - mu * (Xdot[0] - vx);
    Xdot2[1] = Dy - mu * (Xdot[1] - vy);
    Xdot2[2] = (m - (vol - volBal) * rho_w) * 9.81 - mu * Xdot[2];
    printf("Buoy  mass : %f : vol : %f, volbal : %f, accel : %f \n",m,vol,volBal,Xdot2[2]);

}

void Buoy::rotation(void)
{
    double xd;
    double yd;
    xd = cos(theta*z)*vx-sin(theta*z)*vy;
    yd = cos(theta*z)*vy+sin(theta*z)*vx;
    vx = xd;
    vy = yd;
}

void Buoy::clock(void)  // The model is described in "L. Jaulin Modélisation et commande d'un bateau à voile, CIFA2004, Douz (Tunisie)"
{
    // On met à jour la position de la bouee
    // On travaille en dynamique donc pfd m*a = Somme(Forces)
    vortex();
    rotation();
    Xdot[0] = Xdot[0]+dt*Xdot2[0];
    Xdot[1] = Xdot[1]+dt*Xdot2[1];
    Xdot[2] = Xdot[2]+dt*Xdot2[2];
    x = x+dt*Xdot[0];
    y = y+dt*Xdot[1];
    z = z+dt*Xdot[2];
    if (z<0)
    {
        z = 0;
        Xdot[2] = 0;
    }
    //TODO : mettre un min et un max
    volBal = volBal+u*S*dt;
    if(volBal<0){volBal = 0;}
    else if(volBal>50){volBal = 50;}
    printf("Buoy State %d : x : %f, y : %f, z : %f \n",n,x,y,z);
    fflush(stdout);
}

<commit_msg>modification du volume de balast pour eviter de vouler trop vite: a corriger ulterieurement<commit_after>#include <sailboat.h>
#include "buoy.h"
#include <stdio.h>
#include <stdlib.h>

Buoy::Buoy(int nb, double xb, double yb, double zb, double ub, double dt)
{

    this->dt = dt;

    // id
    n = nb;

    // Position
    x = xb;
    y = yb;
    z = zb;

    Xdot[0] = 0;
    Xdot[1] = 0;
    Xdot[2] = 0;

    Xdot2[0] = 0;
    Xdot2[1] = 0;
    Xdot2[2] = 0;

    // Command
    //volBal = BUOY_CONTROL;
    volBal = 0;
    S = 1;

    // Caracteristiques physiques
    m = 100;
    vol = 100;
    rho_w=1.025;
    mvol = m/(vol-volBal); //kg/m³

    // Lorentz variables
    sigma = 10.0;
    beta = 8.0/3.0;
    rho = 28;
    k = 0.0;
    delta = mvol/rho_w; //delta = rapport de la masse volumique de l'eau sur celui de la bouee
    mu = 1.0; //coefficient de resistance de Stokes
    theta = 10;

    phi_i = 1.0;
    Ri = 100.0;

    int i =0;
    //TODO : tourne a linfini
    /*
    while (Xi[i]=!NULL)
    {
        double r = rand() % 200;
        double ang = rand() % 200;
        printf("rayon : %f angle : %f\n", r, ang);
        Xi[i] = r*cos(314*ang);
        Yi[i] = r*sin(314*ang);
        i++;
        printf("valeur de i :%i\n", i);
    }
    */
   printf("appel dans le constructeur :%f\n", Xi[0]);
    Xi[0] = 100;
    Xi[1] = 100;
    Xi[2] = -100;
    Xi[3] = -100;

    Yi[0] = 100;
    Yi[1] = -100;
    Yi[2] = -100;
    Yi[3] = 100;

}

void Buoy::lorenz(void)
{
    Xdot[0] = sigma*(y-x)*dt;
    Xdot[1] = (x*(rho-z)-y)*dt;
    Xdot[2] = (k*(x*y-beta*z)+u);
}

void Buoy::sinLine(double simuTime)
{
    double depth = 40; // m
    double freq = 0.05; // Hz
    double speed = 10;  // m/s
    Xdot[0] = 0;      //X
    Xdot[1] = 0;      //Y
    Xdot[2] = speed*sin(2*M_PI*simuTime*freq); //Z
}

void Buoy::pendulum(void)
{
    Xdot[0] = y;
    Xdot[1] = -sin(x);
    Xdot[2] = u;
}

void Buoy::stateEq(void)
{
    Xdot[0] = sin(0.001*(y+0.9*z));
    Xdot[1] = -sin(0.001*(x+z));
    Xdot[2] = u;

}

void Buoy::setCommand(double ub)
{
    u = ub;
}

int Buoy::getNumber(void)
{
    return n;
}

double* Buoy::getPos(void)
{
    double* xd = new double[4];
    xd[0] = sqrt(pow(Xdot[0],2.0)+pow(Xdot[1],2.0)+pow(Xdot[2],2.0));
    xd[1] = x;
    xd[2] = y;
    xd[3] = z;
    return xd;
}

void Buoy::eqParticuleSimple(void)
{
    vx = -2*sin(y);
    vy = 2*sin(x);

    Dx = -4*sin(x)*cos(y);
    Dy = 4*sin(y)*cos(x);
}

void Buoy::eqParticule(void)
{
    double d2;
    double dvxx, dvyx, dvxy, dvyy;
    vx = 0;
    vy = 0;
    dvxx = 0;
    dvyx = 0;
    dvxy = 0;
    dvyy = 0;

    for (int i=0;i<4;i++)
    {
        d2 = (x-Xi[i])*(x-Xi[i])+(y-Yi[i])*(y-Yi[i]);

        vx   += phi_i*2*y*(y-Yi[i])*exp(-1*d2/(Ri*Ri))/(Ri*Ri);
        vy   -= phi_i*2*x*(x-Xi[i])*exp(-1*d2/(Ri*Ri))/(Ri*Ri);

        dvxx -= phi_i*4*y*(y-Yi[i])*(x-Xi[i])*exp(-1*d2/(Ri*Ri))/(Ri*Ri*Ri*Ri);
        dvxy += 2*phi_i*exp(-1*d2/(Ri*Ri))/(Ri*Ri)*((2*y-Yi[i])-2*y*(y-Yi[i])*(y-Yi[i]));
        dvyx -= 2*phi_i*exp(-1*d2/(Ri*Ri))/(Ri*Ri)*((2*x-Xi[i])-2*x*(x-Xi[i])*(x-Xi[i]));
        dvyy += phi_i*4*x*(y-Yi[i])*(x-Xi[i])*exp(-1*d2/(Ri*Ri))/(Ri*Ri*Ri*Ri);
    }

    Dx = vx*dvxx+vy*dvxy;
    Dy = vx*dvyx+vy*dvyy;
}

void Buoy::vortex(void)
{
    //Dx = vy*0.5*(1+sin(theta*z))*2*cos(y);
    //Dy = vx*0.5*(1+sin(theta*z))*2*cos(x);
    eqParticule();
    mvol = m/(vol-volBal);
    delta = mvol/rho_w;
    Xdot2[0] = delta * Dx - mu * (Xdot[0] - vx);
    Xdot2[1] = Dy - mu * (Xdot[1] - vy);
    Xdot2[2] = (m - (vol - volBal) * rho_w) * 9.81 - mu * Xdot[2];
    // printf("Buoy  mass : %f : vol : %f, volbal : %f, accel : %f \n",m,vol,volBal,Xdot2[2]);

}

void Buoy::rotation(void)
{
    double xd;
    double yd;
    xd = cos(theta*z)*vx-sin(theta*z)*vy;
    yd = cos(theta*z)*vy+sin(theta*z)*vx;
    vx = xd;
    vy = yd;
}

void Buoy::clock(void)  // The model is described in "L. Jaulin Modélisation et commande d'un bateau à voile, CIFA2004, Douz (Tunisie)"
{
    // On met à jour la position de la bouee
    // On travaille en dynamique donc pfd m*a = Somme(Forces)
    vortex();
    rotation();
    Xdot[0] = Xdot[0]+dt*Xdot2[0];
    Xdot[1] = Xdot[1]+dt*Xdot2[1];
    Xdot[2] = Xdot[2]+dt*Xdot2[2];
    x = x+dt*Xdot[0];
    y = y+dt*Xdot[1];
    z = z+dt*Xdot[2];
    if (z<0)
    {
        z = 0;
        Xdot[2] = 0;
    }
    //TODO : mettre un min et un max
    volBal = volBal+u*S*dt;
    if(volBal<0){volBal = 0;}
    else if(volBal>5){volBal = 5;}
    // printf("Buoy State %d : x : %f, y : %f, z : %f \n",n,x,y,z);
    // fflush(stdout);
}

<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  Copyright (C) 2019  The Symbiflow Authors
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *  ---
 *
 *   XDC commands
 *
 *   This plugin operates on the existing design and modifies its structure
 *   based on the content of the XDC (Xilinx Design Constraints) file.
 *   Since the XDC file consists of Tcl commands it is read using Yosys's
 *   Tcl interpreter and processed by the new XDC commands imported to the
 *   Tcl interpreter.
 */
#include <cassert>
#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
#include "libs/json11/json11.hpp"
#include "../bank_tiles.h"

USING_YOSYS_NAMESPACE

PRIVATE_NAMESPACE_BEGIN

static bool isInputPort(RTLIL::Wire* wire) {
	return wire->port_input;
}
static bool isOutputPort(RTLIL::Wire* wire) {
	return wire->port_output;
}

enum class SetPropertyOptions { INTERNAL_VREF, IOSTANDARD, SLEW, IN_TERM };

const std::unordered_map<std::string, SetPropertyOptions> set_property_options_map  = {
	{"INTERNAL_VREF", SetPropertyOptions::INTERNAL_VREF},
	{"IOSTANDARD", SetPropertyOptions::IOSTANDARD},
	{"SLEW", SetPropertyOptions::SLEW},
	{"IN_TERM", SetPropertyOptions::IN_TERM}
};

void register_in_tcl_interpreter(const std::string& command) {
	Tcl_Interp* interp = yosys_get_tcl_interp();
	std::string tcl_script = stringf("proc %s args { return [yosys %s {*}$args] }", command.c_str(), command.c_str());
	Tcl_Eval(interp, tcl_script.c_str());
}

struct GetPorts : public Pass {
	GetPorts() : Pass("get_ports", "Print matching ports") {
		register_in_tcl_interpreter(pass_name);
	}

	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("   get_ports <port_name> \n");
		log("\n");
		log("Get matching ports\n");
		log("\n");
		log("Print the output to stdout too. This is useful when all Yosys is executed\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design* design) YS_OVERRIDE
	{
		if (args.size() < 2) {
			log_cmd_error("No port specified.\n");
		}
		RTLIL::Module* top_module = design->top_module();
		if (top_module == nullptr) {
			log_cmd_error("No top module detected\n");
		}
		// TODO handle more than one port
		port_name = args.at(1);
		RTLIL::IdString port_id(RTLIL::escape_id(port_name));
		if (auto wire = top_module->wire(port_id)) {
			if (isInputPort(wire) || isOutputPort(wire)) {
				Tcl_Interp *interp = yosys_get_tcl_interp();
				Tcl_SetResult(interp, const_cast<char*>(port_name.c_str()), NULL);
				return;
			}
		}
		log_warning("Couldn't find port %s\n", port_name.c_str());
	}
	std::string port_name;
};

struct GetIOBanks : public Pass {
	GetIOBanks(std::function<const BankTilesMap&()> get_bank_tiles)
		: Pass("get_iobanks", "Set IO Bank number")
		, get_bank_tiles(get_bank_tiles) {
		register_in_tcl_interpreter(pass_name);
	}

	void help() YS_OVERRIDE	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("   get_iobanks <bank_number>\n");
		log("\n");
		log("Get IO Bank number\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design* ) YS_OVERRIDE {
		if (args.size() < 2) {
			log_cmd_error("%s: Missing bank number.\n", pass_name.c_str());
		}
		auto bank_tiles = get_bank_tiles();
		if (bank_tiles.count(std::atoi(args[1].c_str())) == 0) {
			log_cmd_error("%s:Bank number %s is not present in the target device.\n", args[1].c_str(), pass_name.c_str());
		}

                Tcl_Interp *interp = yosys_get_tcl_interp();
		Tcl_SetResult(interp, const_cast<char*>(args[1].c_str()), NULL);
		log("%s\n", args[1].c_str());
	}

	std::function<const BankTilesMap&()> get_bank_tiles;
};

struct SetProperty : public Pass {
	SetProperty(std::function<const BankTilesMap&()> get_bank_tiles)
		: Pass("set_property", "Set a given property")
		, get_bank_tiles(get_bank_tiles) {
		register_in_tcl_interpreter(pass_name);
	}

	void help() YS_OVERRIDE	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    set_property PROPERTY VALUE OBJECT\n");
		log("\n");
		log("Set the given property to the specified value on an object\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design* design) YS_OVERRIDE {
		if (design->top_module() == nullptr) {
			log_cmd_error("No top module detected\n");
		}

		std::string option(args[1]);
		if (set_property_options_map.count(option) == 0) {
			log_warning("set_property: %s option is currently not supported\n", option.c_str());
			return;
		}

		switch (set_property_options_map.at(option)) {
			case SetPropertyOptions::INTERNAL_VREF:
				process_vref(std::vector<std::string>(args.begin() + 2, args.end()), design);
				break;
			case SetPropertyOptions::IOSTANDARD:
			case SetPropertyOptions::SLEW:
			case SetPropertyOptions::IN_TERM:
				process_port_parameter(std::vector<std::string>(args.begin() + 1, args.end()), design);
				break;
			default:
				assert(false);
		}
	}

	void process_vref(std::vector<std::string> args, RTLIL::Design* design) {
		if (args.size() < 2) {
			log_error("set_property INTERNAL_VREF: Incorrect number of arguments.\n");
		}
		int iobank = std::atoi(args[1].c_str());
		auto bank_tiles = get_bank_tiles();
		if (bank_tiles.count(iobank) == 0) {
			log_cmd_error("set_property INTERNAL_VREF: Invalid IO bank.\n");
		}

		int internal_vref = 1000 * std::atof(args[0].c_str());
		if (internal_vref != 600 &&
				internal_vref != 675 &&
				internal_vref != 750 &&
				internal_vref != 900) {
			log("set_property INTERNAL_VREF: Incorrect INTERNAL_VREF value\n");
			return;
		}

		// Create a new BANK module if it hasn't been created so far
		RTLIL::Module* top_module = design->top_module();
		if (!design->has(ID(BANK))) {
			std::string fasm_extra_modules_dir(proc_share_dirname() + "/plugins/fasm_extra_modules");
			Pass::call(design, "read_verilog " + fasm_extra_modules_dir + "/BANK.v");
		}

		// Set parameters on a new bank instance or update an existing one
		char bank_cell_name[16];
		snprintf(bank_cell_name, 16, "\\bank_cell_%d", iobank);
		RTLIL::Cell* bank_cell = top_module->cell(RTLIL::IdString(bank_cell_name));
		if (!bank_cell) {
			bank_cell = top_module->addCell(RTLIL::IdString(bank_cell_name), ID(BANK));
		}
		bank_cell->setParam(ID(FASM_EXTRA), RTLIL::Const("INTERNAL_VREF"));
		bank_cell->setParam(ID(NUMBER), RTLIL::Const(iobank));
		bank_cell->setParam(ID(INTERNAL_VREF), RTLIL::Const(internal_vref));
	}

	void process_port_parameter(std::vector<std::string> args, RTLIL::Design* design) {
		if (args.size() < 1) {
			log_error("set_property: Incorrect number of arguments.\n");
		}
		std::string parameter(args.at(0));
		if (args.size() < 3) {
			log_error("set_property %s: Incorrect number of arguments.\n", parameter.c_str());
		}
		std::string port(args.at(2));
		std::string value(args.at(1));
		RTLIL::Module* top_module = design->top_module();
		RTLIL::IdString port_id(RTLIL::escape_id(port));
		for (auto cell_obj : top_module->cells_) {
			RTLIL::Cell* cell = cell_obj.second;
			RTLIL::IdString cell_id = cell_obj.first;
			for (auto connection : cell->connections_) {
				if (connection.second.is_wire()) {
					RTLIL::Wire* cell_wire = connection.second.as_wire();
					if (cell_wire == nullptr) {
						continue;
					}
					if (cell_wire->name == port_id) {
						cell->setParam(RTLIL::IdString(RTLIL::escape_id(parameter)), RTLIL::Const(value));
						log("Setting parameter %s to value %s on cell %s \n", parameter.c_str(), value.c_str(), cell_id.c_str());
					}
				}
			}
		}
	}

	std::function<const BankTilesMap&()> get_bank_tiles;
};

struct ReadXdc : public Frontend {
	ReadXdc()
	       	: Frontend("xdc", "Read XDC file")
		, GetIOBanks(std::bind(&ReadXdc::get_bank_tiles, this))
		, SetProperty(std::bind(&ReadXdc::get_bank_tiles, this)) {}

	void help() YS_OVERRIDE {
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    read_xdc -part_json <part_json_filename> <filename>\n");
		log("\n");
		log("Read XDC file.\n");
		log("\n");
	}

	void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE {
                if (args.size() < 2) {
                        log_cmd_error("Missing script file.\n");
		}
                Tcl_Interp *interp = yosys_get_tcl_interp();
		size_t argidx = 1;
		bank_tiles.clear();
		if (args[argidx] == "-part_json" && argidx + 1 < args.size()) {
			bank_tiles = ::get_bank_tiles(args[++argidx]);
			argidx++;
		}
		extra_args(f, filename, args, argidx);
		std::string content{std::istreambuf_iterator<char>(*f), std::istreambuf_iterator<char>()};
		log("%s\n", content.c_str());
                if (Tcl_EvalFile(interp, args[argidx].c_str()) != TCL_OK) {
                        log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp));
		}
	}
	const BankTilesMap& get_bank_tiles() {
		return bank_tiles;
	}

	BankTilesMap bank_tiles;
	struct GetPorts GetPorts;
	struct GetIOBanks GetIOBanks;
	struct SetProperty SetProperty;
} ReadXdc;

struct GetBankTiles : public Pass {
	GetBankTiles()
	       	: Pass("get_bank_tiles", "Inspect IO Bank tiles") {
		register_in_tcl_interpreter(pass_name);
	}

	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("   get_bank_tiles <part_json_file>\n");
		log("\n");
		log("Inspect IO Bank tiles for the specified part based on the provided JSON file.\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design* ) YS_OVERRIDE {
                if (args.size() < 2) {
                        log_cmd_error("Missing JSON file.\n");
		}
		// Check if the part has the specified bank
		auto bank_tiles = get_bank_tiles(args[1]);
		if (bank_tiles.size()) {
			log("Available bank tiles:\n");
			for (auto bank : bank_tiles) {
				log("Bank: %d, Tile: %s\n", bank.first, bank.second.c_str());
			}
			log("\n");
		} else {
			log("No bank tiles available.\n");
		}
	}
} GetBankTiles;

PRIVATE_NAMESPACE_END
<commit_msg>XDC: Add support for bus ports<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  Copyright (C) 2019  The Symbiflow Authors
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *  ---
 *
 *   XDC commands
 *
 *   This plugin operates on the existing design and modifies its structure
 *   based on the content of the XDC (Xilinx Design Constraints) file.
 *   Since the XDC file consists of Tcl commands it is read using Yosys's
 *   Tcl interpreter and processed by the new XDC commands imported to the
 *   Tcl interpreter.
 */
#include <cassert>
#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
#include "libs/json11/json11.hpp"
#include "../bank_tiles.h"

USING_YOSYS_NAMESPACE

PRIVATE_NAMESPACE_BEGIN

static bool isInputPort(RTLIL::Wire* wire) {
	return wire->port_input;
}
static bool isOutputPort(RTLIL::Wire* wire) {
	return wire->port_output;
}

enum class SetPropertyOptions { INTERNAL_VREF, IOSTANDARD, SLEW, IN_TERM };

const std::unordered_map<std::string, SetPropertyOptions> set_property_options_map  = {
	{"INTERNAL_VREF", SetPropertyOptions::INTERNAL_VREF},
	{"IOSTANDARD", SetPropertyOptions::IOSTANDARD},
	{"SLEW", SetPropertyOptions::SLEW},
	{"IN_TERM", SetPropertyOptions::IN_TERM}
};

void register_in_tcl_interpreter(const std::string& command) {
	Tcl_Interp* interp = yosys_get_tcl_interp();
	std::string tcl_script = stringf("proc %s args { return [yosys %s {*}$args] }", command.c_str(), command.c_str());
	Tcl_Eval(interp, tcl_script.c_str());
}

struct GetPorts : public Pass {
	GetPorts() : Pass("get_ports", "Print matching ports") {
		register_in_tcl_interpreter(pass_name);
	}

	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("   get_ports <port_name> \n");
		log("\n");
		log("Get matching ports\n");
		log("\n");
		log("Print the output to stdout too. This is useful when all Yosys is executed\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design* design) YS_OVERRIDE
	{
		if (args.size() < 2) {
			log_cmd_error("No port specified.\n");
		}
		RTLIL::Module* top_module = design->top_module();
		if (top_module == nullptr) {
			log_cmd_error("No top module detected\n");
		}
		// TODO handle more than one port
		port_name = args.at(1);
		char port[128];
		int bit(0);
		std::string port_signal(port_name);
		if (sscanf(port_name.c_str(), "%[^[][%d]", port, &bit) == 2) {
			port_signal = std::string(port);
		}

		RTLIL::IdString port_id(RTLIL::escape_id(port_signal.c_str()));
		if (auto wire = top_module->wire(port_id)) {
			if (isInputPort(wire) || isOutputPort(wire)) {
				Tcl_Interp *interp = yosys_get_tcl_interp();
				Tcl_SetResult(interp, const_cast<char*>(port_name.c_str()), NULL);
				log("Found port %s\n", port_name.c_str());
				return;
			}
		}
		log_warning("Couldn't find port %s\n", port_name.c_str());
	}
	std::string port_name;
};

struct GetIOBanks : public Pass {
	GetIOBanks(std::function<const BankTilesMap&()> get_bank_tiles)
		: Pass("get_iobanks", "Set IO Bank number")
		, get_bank_tiles(get_bank_tiles) {
		register_in_tcl_interpreter(pass_name);
	}

	void help() YS_OVERRIDE	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("   get_iobanks <bank_number>\n");
		log("\n");
		log("Get IO Bank number\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design* ) YS_OVERRIDE {
		if (args.size() < 2) {
			log_cmd_error("%s: Missing bank number.\n", pass_name.c_str());
		}
		auto bank_tiles = get_bank_tiles();
		if (bank_tiles.count(std::atoi(args[1].c_str())) == 0) {
			log_cmd_error("%s:Bank number %s is not present in the target device.\n", args[1].c_str(), pass_name.c_str());
		}

                Tcl_Interp *interp = yosys_get_tcl_interp();
		Tcl_SetResult(interp, const_cast<char*>(args[1].c_str()), NULL);
		log("%s\n", args[1].c_str());
	}

	std::function<const BankTilesMap&()> get_bank_tiles;
};

struct SetProperty : public Pass {
	SetProperty(std::function<const BankTilesMap&()> get_bank_tiles)
		: Pass("set_property", "Set a given property")
		, get_bank_tiles(get_bank_tiles) {
		register_in_tcl_interpreter(pass_name);
	}

	void help() YS_OVERRIDE	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    set_property PROPERTY VALUE OBJECT\n");
		log("\n");
		log("Set the given property to the specified value on an object\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design* design) YS_OVERRIDE {
		if (design->top_module() == nullptr) {
			log_cmd_error("No top module detected\n");
		}

		std::string option(args[1]);
		if (set_property_options_map.count(option) == 0) {
			log_warning("set_property: %s option is currently not supported\n", option.c_str());
			return;
		}

		switch (set_property_options_map.at(option)) {
			case SetPropertyOptions::INTERNAL_VREF:
				process_vref(std::vector<std::string>(args.begin() + 2, args.end()), design);
				break;
			case SetPropertyOptions::IOSTANDARD:
			case SetPropertyOptions::SLEW:
			case SetPropertyOptions::IN_TERM:
				process_port_parameter(std::vector<std::string>(args.begin() + 1, args.end()), design);
				break;
			default:
				assert(false);
		}
	}

	void process_vref(std::vector<std::string> args, RTLIL::Design* design) {
		if (args.size() < 2) {
			log_error("set_property INTERNAL_VREF: Incorrect number of arguments.\n");
		}
		int iobank = std::atoi(args[1].c_str());
		auto bank_tiles = get_bank_tiles();
		if (bank_tiles.count(iobank) == 0) {
			log_cmd_error("set_property INTERNAL_VREF: Invalid IO bank.\n");
		}

		int internal_vref = 1000 * std::atof(args[0].c_str());
		if (internal_vref != 600 &&
				internal_vref != 675 &&
				internal_vref != 750 &&
				internal_vref != 900) {
			log("set_property INTERNAL_VREF: Incorrect INTERNAL_VREF value\n");
			return;
		}

		// Create a new BANK module if it hasn't been created so far
		RTLIL::Module* top_module = design->top_module();
		if (!design->has(ID(BANK))) {
			std::string fasm_extra_modules_dir(proc_share_dirname() + "/plugins/fasm_extra_modules");
			Pass::call(design, "read_verilog " + fasm_extra_modules_dir + "/BANK.v");
		}

		// Set parameters on a new bank instance or update an existing one
		char bank_cell_name[16];
		snprintf(bank_cell_name, 16, "\\bank_cell_%d", iobank);
		RTLIL::Cell* bank_cell = top_module->cell(RTLIL::IdString(bank_cell_name));
		if (!bank_cell) {
			bank_cell = top_module->addCell(RTLIL::IdString(bank_cell_name), ID(BANK));
		}
		bank_cell->setParam(ID(FASM_EXTRA), RTLIL::Const("INTERNAL_VREF"));
		bank_cell->setParam(ID(NUMBER), RTLIL::Const(iobank));
		bank_cell->setParam(ID(INTERNAL_VREF), RTLIL::Const(internal_vref));
	}

	void process_port_parameter(std::vector<std::string> args, RTLIL::Design* design) {
		if (args.size() < 1) {
			log_error("set_property: Incorrect number of arguments.\n");
		}
		std::string parameter(args.at(0));
		if (args.size() < 3) {
			log_error("set_property %s: Incorrect number of arguments.\n", parameter.c_str());
		}
		std::string port_name(args.at(2));
		std::string value(args.at(1));
		char port[128];
		char bit[64];
		if (sscanf(port_name.c_str(), "%[^[]%s", port, bit) == 2) {
			port_name = std::string(port) + " " + std::string(bit);
		}
		RTLIL::Module* top_module = design->top_module();
		RTLIL::IdString port_id(RTLIL::escape_id(port_name.c_str()));
		for (auto cell_obj : top_module->cells_) {
			RTLIL::Cell* cell = cell_obj.second;
			RTLIL::IdString cell_id = cell_obj.first;
			for (auto connection : cell->connections_) {
				RTLIL::SigSpec cell_signals = connection.second;
				if (!strcmp(log_signal(cell_signals),port_id.c_str())) {
					cell->setParam(RTLIL::IdString(RTLIL::escape_id(parameter)), RTLIL::Const(value));
					log("Setting parameter %s to value %s on cell %s \n", parameter.c_str(), value.c_str(), cell_id.c_str());
				}
			}
		}
	}

	std::function<const BankTilesMap&()> get_bank_tiles;
};

struct ReadXdc : public Frontend {
	ReadXdc()
	       	: Frontend("xdc", "Read XDC file")
		, GetIOBanks(std::bind(&ReadXdc::get_bank_tiles, this))
		, SetProperty(std::bind(&ReadXdc::get_bank_tiles, this)) {}

	void help() YS_OVERRIDE {
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    read_xdc -part_json <part_json_filename> <filename>\n");
		log("\n");
		log("Read XDC file.\n");
		log("\n");
	}

	void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE {
                if (args.size() < 2) {
                        log_cmd_error("Missing script file.\n");
		}
                Tcl_Interp *interp = yosys_get_tcl_interp();
		size_t argidx = 1;
		bank_tiles.clear();
		if (args[argidx] == "-part_json" && argidx + 1 < args.size()) {
			bank_tiles = ::get_bank_tiles(args[++argidx]);
			argidx++;
		}
		extra_args(f, filename, args, argidx);
		std::string content{std::istreambuf_iterator<char>(*f), std::istreambuf_iterator<char>()};
		log("%s\n", content.c_str());
                if (Tcl_EvalFile(interp, args[argidx].c_str()) != TCL_OK) {
                        log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp));
		}
	}
	const BankTilesMap& get_bank_tiles() {
		return bank_tiles;
	}

	BankTilesMap bank_tiles;
	struct GetPorts GetPorts;
	struct GetIOBanks GetIOBanks;
	struct SetProperty SetProperty;
} ReadXdc;

struct GetBankTiles : public Pass {
	GetBankTiles()
	       	: Pass("get_bank_tiles", "Inspect IO Bank tiles") {
		register_in_tcl_interpreter(pass_name);
	}

	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("   get_bank_tiles <part_json_file>\n");
		log("\n");
		log("Inspect IO Bank tiles for the specified part based on the provided JSON file.\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design* ) YS_OVERRIDE {
                if (args.size() < 2) {
                        log_cmd_error("Missing JSON file.\n");
		}
		// Check if the part has the specified bank
		auto bank_tiles = get_bank_tiles(args[1]);
		if (bank_tiles.size()) {
			log("Available bank tiles:\n");
			for (auto bank : bank_tiles) {
				log("Bank: %d, Tile: %s\n", bank.first, bank.second.c_str());
			}
			log("\n");
		} else {
			log("No bank tiles available.\n");
		}
	}
} GetBankTiles;

PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>#include "translator.hpp"
#include "decl.hpp"
#include "type.hpp"
#include "context.hpp"
#include "expr.hpp"
#include "action.hpp"
#include "dumper.hpp"

#include <string>

// for testing only
#include <iostream>
#include <sstream>

namespace pip
{
  translator::translator(context& cxt)
    : cxt(cxt), field_decoder(cxt)
  {
  }

  /// program ::= (pip <decl-seq>)
  decl*
  translator::trans_program(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      decl_seq decls;
      match_list(list, "pip", &decls);

      return new program_decl(std::move(decls));
    }
    sexpr::throw_unexpected_term(e);
  }

  /// decl-seq ::= (<decl*>)
  decl_seq
  translator::trans_decls(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      decl_seq decls;

      decl* d = trans_decl(list);
      decls.push_back(d);

      return decls;
    }
    sexpr::throw_unexpected_term(e);
  }

  /// decl ::= table-decl | meter-decl
  decl*
  translator::trans_decl(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      symbol* sym;
      match_list(list, &sym);
      if (*sym == "table")
	return trans_table(list);
      sexpr::throw_unexpected_id(cast<sexpr::id_expr>(list->exprs[0]));
    }
    sexpr::throw_unexpected_term(e);
  }

  /// table-decl ::= (table id <match-kind> <action-seq> <rule-seq>)
  ///
  /// rule-kind ::= exact | prefix | wildcard | range
  ///
  /// FIXME: We actually need parse the key extraction program. This
  /// would be a sequence of actions that bits from the current offset
  /// into a "key register".
  decl*
  translator::trans_table(const sexpr::list_expr* e)
  {
    symbol* id;
    symbol* kind;
    action_seq actions;
    rule_seq rules;
    match_list(e, "table", &id, &kind, &actions, &rules);

    // TODO: Actually parse the kind of match. For now, we can simply
    // assume that all tables are exact. Hint: use the match_list framework
    // to return a match kind.

    return new table_decl(id, rk_exact, std::move(actions), std::move(rules));
  }

  /// rule_seq ::= (<rule*>)
  rule_seq
  translator::trans_rules(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      match_list(list, "rules");
      rule_seq rules;

      // Match each element in turn.
      for(const sexpr::expr* el : list->exprs) {
        // We are only interested in the entire sublists contained within list,
        // not its individual expressions.
	if(const sexpr::list_expr* r = as<sexpr::list_expr>(el)) {
	  rule* r1 = trans_rule(r);
	  rules.push_back(r1);
	}
      }
      return rules;
    }
    sexpr::throw_unexpected_term(e);
  }

  rule*
  translator::trans_rule(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      expr_seq exprs;
      expr* key;
      action_seq actions;

      match_list(list, &key, &actions);

      auto r = new rule(rk_exact, key, std::move(actions));
      return r;
    }

    sexpr::throw_unexpected_term(e);
  }

  rule*
  translator::trans_rule(const sexpr::list_expr* e)
  {
    expr_seq exprs;
    expr* key;
    action_seq actions;

    match_list(e, "rule", &key, &actions);

    auto r = new rule(rk_exact, key, std::move(actions));

    dumper d(std::cout);
    d(r);
    return r;
  }

  action_seq
  translator::trans_actions(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      match_list(list, "actions");
      action_seq actions;
      for(const sexpr::expr* el : list->exprs) {
	// We are only interested in the entire sublists contained within list,
	// not its individual expressions.
	if(const sexpr::list_expr* a = as<sexpr::list_expr>(el)) {
	  action* a1 = trans_action(a);
	  actions.push_back(a1);
	}
      }

      return actions;
    }
    sexpr::throw_unexpected_term(e);
  }

  action*
  translator::trans_action(const sexpr::list_expr* e)
  {
    symbol* action_name;
    expr_seq exprs;
    int i;

    match_list(e, &action_name);

    if(*action_name == "advance") {
      expr* amount;
      match_list(e, "advance", &amount);
      return cxt.make_advance_action(amount);
    }

    if(*action_name == "copy") {
      expr* src;
      expr* dst;
      expr* n;
      match_list(e, "copy", &src, &dst, &n);

      // TODO: Use libcc diagnostics.
      if(!dynamic_cast<bitfield_expr*>(src))
	throw std::runtime_error("Source in copy action does not have location type.\n");
      if(!dynamic_cast<bitfield_expr*>(dst))
	throw std::runtime_error("Destination in copy action does not have location type.\n");
      if(!(dynamic_cast<int_expr*>(n)))
	throw std::runtime_error("Length of copy must be of type int.\n");

      return cxt.make_copy_action(src, dst, n);
    }

    if(*action_name == "set") {
      expr* f;
      expr* v;
      match_list(e, "set", &f, &v);
      return cxt.make_set_action(f, v);
    }

    if(*action_name == "write") {
      action* a;
      match_list(e, "write", &a);

      return cxt.make_write_action(a);
    }

    if(*action_name == "clear") {
      return cxt.make_clear_action();
    }

    if(*action_name == "drop") {
      return cxt.make_drop_action();
    }

    if(*action_name == "match") {
      return cxt.make_match_action();
    }

    if(*action_name == "goto") {
      expr* dst;
      match_list(e, "goto", &dst);

      return cxt.make_goto_action(dst);
    }

    if(*action_name == "output") {
      expr* dst;
      match_list(e, "output", &dst);

      return cxt.make_output_action(dst);
    }

    sexpr::throw_unexpected_term(e);
  }

  expr*
  translator::trans_expr(const sexpr::expr* e)
  {
    // Match phrases.
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      symbol* sym;
      match_list(list, &sym);

      auto it = expression_symbols.find(sym);

      if(it == expression_symbols.end())
	throw std::logic_error("Invalid expression.");

      switch(it->second) {
      case es_int:
	return trans_int_expr(list);

      case es_wildcard:
	return trans_wild_expr(list);
      case es_range:
	return trans_range_expr(list);
      case es_port:
	return trans_port_expr(list);
      case es_bitfield:
	return trans_bitfield_expr(list);
      case es_miss:
	return trans_miss_expr();
      case es_named_field:
	return trans_named_field_expr(list);
      }
    }
  }

  expr_seq
  translator::trans_exprs(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      expr_seq exprs;
      for (const sexpr::expr* elem : list->exprs) {
	expr* e = trans_expr(elem);
	exprs.push_back(e);
      }
      return exprs;
    }
    sexpr::throw_unexpected_term(e);
  }

  expr*
  translator::trans_range_expr(const sexpr::list_expr* e)
  {
    expr* lo;
    expr* hi;
    match_list(e, "range", &lo, &hi);

    auto lo_expr = as<int_expr>(lo);
    auto hi_expr = as<int_expr>(hi);

    auto lo_val = lo_expr->val;
    auto hi_val = hi_expr->val;

    auto lo_ty = static_cast<int_type*>(lo_expr->ty);
    auto hi_ty = static_cast<int_type*>(hi_expr->ty);

    if(lo_ty->width == hi_ty->width)
      return cxt.make_range_expr(new range_type(
				   new int_type(lo_ty->width)), lo_val, hi_val);
    //TODO: proper diagnostic
    std::stringstream ss;
    ss << "Width of range arguments not equal: " << lo_ty->width << ", and "
       << hi_ty->width << "\n";
    throw std::runtime_error(ss.str().c_str());
  }

  expr*
  translator::trans_wild_expr(const sexpr::list_expr* e)
  {
  }

  expr*
  translator::trans_miss_expr()
  {
    return cxt.make_miss_expr(new int_type(64));
  }

  expr*
  translator::trans_ref_expr(const sexpr::id_expr* e)
  {
  }

  expr*
  translator::trans_named_field_expr(const sexpr::list_expr* e)
  {
    symbol* field;
    match_list(e, "named_field", &field);

    return field_decoder.decode_named_field(
      static_cast<named_field_expr*>(cxt.make_named_field_expr(new loc_type, field)));
  }

  expr*
  translator::trans_port_expr(const sexpr::list_expr* e)
  {
    expr* port;
    match_list(e, "port", &port);

    if(get_kind(port) != ek_int && get_kind(port) != ek_bitfield) {
      throw std::logic_error("Invalid type for port value.\n");
    }

    return cxt.make_port_expr(new port_type, port);
  }

  expr*
  translator::trans_bitfield_expr(const sexpr::list_expr* e)
  {
    symbol* space;
    expr* pos;
    expr* len;

    match_list(e, "bitfield", &space, &pos, &len);

    address_space as;
    auto it = address_spaces.find(space);
    if(it != address_spaces.end())
      as = it->second;
    else
      throw std::logic_error("Invalid address space.");

    return cxt.make_bitfield_expr(as, pos, len);
  }

  // When given an integer width specifier, such as i32,
  // return the integer after the i. In this case, 32.
  static int
  deduce_int_type_width(const symbol* ty)
  {
    std::string spec = *ty;

    if(spec.front() == 'i') {
      spec.erase(0, 1);

      std::size_t it;
      auto width = std::stoi(spec.c_str(), &it);

      if(spec.size() == it)
	return width;
    }

    std::stringstream ss;
    ss << "Invalid integer width specifier: " << *ty <<
      ". Specifier should be of form i[integer].\n";
    throw std::runtime_error(ss.str().c_str());
  }

  expr*
  translator::trans_int_expr(const sexpr::list_expr* e)
  {
    symbol* width_specifier;
    int value;
    match_list(e, "int", &width_specifier, &value);

    int w = deduce_int_type_width(width_specifier);

    return cxt.make_int_expr( new int_type(w), value );
  }

  // -------------------------------------------------------------------------- //
  // Matching

  void
  translator::match(const sexpr::list_expr* list, int n, decl_seq* decls)
  {
    *decls = trans_decls(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, rule_seq* rules)
  {
    *rules = trans_rules(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, expr_seq* exprs)
  {
    *exprs = trans_exprs(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, expr** out)
  {
    *out = trans_expr(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, action_seq* actions)
  {
    *actions = trans_actions(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, action** a)
  {
    *a = trans_action(list);
  }
} // namespace pip
<commit_msg>Remove FIXME about parsing key extraction program.<commit_after>#include "translator.hpp"
#include "decl.hpp"
#include "type.hpp"
#include "context.hpp"
#include "expr.hpp"
#include "action.hpp"
#include "dumper.hpp"

#include <string>

// for testing only
#include <iostream>
#include <sstream>

namespace pip
{
  translator::translator(context& cxt)
    : cxt(cxt), field_decoder(cxt)
  {
  }

  /// program ::= (pip <decl-seq>)
  decl*
  translator::trans_program(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      decl_seq decls;
      match_list(list, "pip", &decls);

      return new program_decl(std::move(decls));
    }
    sexpr::throw_unexpected_term(e);
  }

  /// decl-seq ::= (<decl*>)
  decl_seq
  translator::trans_decls(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      decl_seq decls;

      decl* d = trans_decl(list);
      decls.push_back(d);

      return decls;
    }
    sexpr::throw_unexpected_term(e);
  }

  /// decl ::= table-decl | meter-decl
  decl*
  translator::trans_decl(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      symbol* sym;
      match_list(list, &sym);
      if (*sym == "table")
	return trans_table(list);
      sexpr::throw_unexpected_id(cast<sexpr::id_expr>(list->exprs[0]));
    }
    sexpr::throw_unexpected_term(e);
  }

  /// table-decl ::= (table id <match-kind> <action-seq> <rule-seq>)
  ///
  /// rule-kind ::= exact | prefix | wildcard | range
  decl*
  translator::trans_table(const sexpr::list_expr* e)
  {
    symbol* id;
    symbol* kind;
    action_seq actions;
    rule_seq rules;
    match_list(e, "table", &id, &kind, &actions, &rules);

    // TODO: Actually parse the kind of match. For now, we can simply
    // assume that all tables are exact. Hint: use the match_list framework
    // to return a match kind.

    return new table_decl(id, rk_exact, std::move(actions), std::move(rules));
  }

  /// rule_seq ::= (<rule*>)
  rule_seq
  translator::trans_rules(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      match_list(list, "rules");
      rule_seq rules;

      // Match each element in turn.
      for(const sexpr::expr* el : list->exprs) {
        // We are only interested in the entire sublists contained within list,
        // not its individual expressions.
	if(const sexpr::list_expr* r = as<sexpr::list_expr>(el)) {
	  rule* r1 = trans_rule(r);
	  rules.push_back(r1);
	}
      }
      return rules;
    }
    sexpr::throw_unexpected_term(e);
  }

  rule*
  translator::trans_rule(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      expr_seq exprs;
      expr* key;
      action_seq actions;

      match_list(list, &key, &actions);

      auto r = new rule(rk_exact, key, std::move(actions));
      return r;
    }

    sexpr::throw_unexpected_term(e);
  }

  rule*
  translator::trans_rule(const sexpr::list_expr* e)
  {
    expr_seq exprs;
    expr* key;
    action_seq actions;

    match_list(e, "rule", &key, &actions);

    auto r = new rule(rk_exact, key, std::move(actions));

    dumper d(std::cout);
    d(r);
    return r;
  }

  action_seq
  translator::trans_actions(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      match_list(list, "actions");
      action_seq actions;
      for(const sexpr::expr* el : list->exprs) {
	// We are only interested in the entire sublists contained within list,
	// not its individual expressions.
	if(const sexpr::list_expr* a = as<sexpr::list_expr>(el)) {
	  action* a1 = trans_action(a);
	  actions.push_back(a1);
	}
      }

      return actions;
    }
    sexpr::throw_unexpected_term(e);
  }

  action*
  translator::trans_action(const sexpr::list_expr* e)
  {
    symbol* action_name;
    expr_seq exprs;
    int i;

    match_list(e, &action_name);

    if(*action_name == "advance") {
      expr* amount;
      match_list(e, "advance", &amount);
      return cxt.make_advance_action(amount);
    }

    if(*action_name == "copy") {
      expr* src;
      expr* dst;
      expr* n;
      match_list(e, "copy", &src, &dst, &n);

      // TODO: Use libcc diagnostics.
      if(!dynamic_cast<bitfield_expr*>(src))
	throw std::runtime_error("Source in copy action does not have location type.\n");
      if(!dynamic_cast<bitfield_expr*>(dst))
	throw std::runtime_error("Destination in copy action does not have location type.\n");
      if(!(dynamic_cast<int_expr*>(n)))
	throw std::runtime_error("Length of copy must be of type int.\n");

      return cxt.make_copy_action(src, dst, n);
    }

    if(*action_name == "set") {
      expr* f;
      expr* v;
      match_list(e, "set", &f, &v);
      return cxt.make_set_action(f, v);
    }

    if(*action_name == "write") {
      action* a;
      match_list(e, "write", &a);

      return cxt.make_write_action(a);
    }

    if(*action_name == "clear") {
      return cxt.make_clear_action();
    }

    if(*action_name == "drop") {
      return cxt.make_drop_action();
    }

    if(*action_name == "match") {
      return cxt.make_match_action();
    }

    if(*action_name == "goto") {
      expr* dst;
      match_list(e, "goto", &dst);

      return cxt.make_goto_action(dst);
    }

    if(*action_name == "output") {
      expr* dst;
      match_list(e, "output", &dst);

      return cxt.make_output_action(dst);
    }

    sexpr::throw_unexpected_term(e);
  }

  expr*
  translator::trans_expr(const sexpr::expr* e)
  {
    // Match phrases.
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      symbol* sym;
      match_list(list, &sym);

      auto it = expression_symbols.find(sym);

      if(it == expression_symbols.end())
	throw std::logic_error("Invalid expression.");

      switch(it->second) {
      case es_int:
	return trans_int_expr(list);

      case es_wildcard:
	return trans_wild_expr(list);
      case es_range:
	return trans_range_expr(list);
      case es_port:
	return trans_port_expr(list);
      case es_bitfield:
	return trans_bitfield_expr(list);
      case es_miss:
	return trans_miss_expr();
      case es_named_field:
	return trans_named_field_expr(list);
      }
    }
  }

  expr_seq
  translator::trans_exprs(const sexpr::expr* e)
  {
    if (const sexpr::list_expr* list = as<sexpr::list_expr>(e)) {
      expr_seq exprs;
      for (const sexpr::expr* elem : list->exprs) {
	expr* e = trans_expr(elem);
	exprs.push_back(e);
      }
      return exprs;
    }
    sexpr::throw_unexpected_term(e);
  }

  expr*
  translator::trans_range_expr(const sexpr::list_expr* e)
  {
    expr* lo;
    expr* hi;
    match_list(e, "range", &lo, &hi);

    auto lo_expr = as<int_expr>(lo);
    auto hi_expr = as<int_expr>(hi);

    auto lo_val = lo_expr->val;
    auto hi_val = hi_expr->val;

    auto lo_ty = static_cast<int_type*>(lo_expr->ty);
    auto hi_ty = static_cast<int_type*>(hi_expr->ty);

    if(lo_ty->width == hi_ty->width)
      return cxt.make_range_expr(new range_type(
				   new int_type(lo_ty->width)), lo_val, hi_val);
    //TODO: proper diagnostic
    std::stringstream ss;
    ss << "Width of range arguments not equal: " << lo_ty->width << ", and "
       << hi_ty->width << "\n";
    throw std::runtime_error(ss.str().c_str());
  }

  expr*
  translator::trans_wild_expr(const sexpr::list_expr* e)
  {
  }

  expr*
  translator::trans_miss_expr()
  {
    return cxt.make_miss_expr(new int_type(64));
  }

  expr*
  translator::trans_ref_expr(const sexpr::id_expr* e)
  {
  }

  expr*
  translator::trans_named_field_expr(const sexpr::list_expr* e)
  {
    symbol* field;
    match_list(e, "named_field", &field);

    return field_decoder.decode_named_field(
      static_cast<named_field_expr*>(cxt.make_named_field_expr(new loc_type, field)));
  }

  expr*
  translator::trans_port_expr(const sexpr::list_expr* e)
  {
    expr* port;
    match_list(e, "port", &port);

    if(get_kind(port) != ek_int && get_kind(port) != ek_bitfield) {
      throw std::logic_error("Invalid type for port value.\n");
    }

    return cxt.make_port_expr(new port_type, port);
  }

  expr*
  translator::trans_bitfield_expr(const sexpr::list_expr* e)
  {
    symbol* space;
    expr* pos;
    expr* len;

    match_list(e, "bitfield", &space, &pos, &len);

    address_space as;
    auto it = address_spaces.find(space);
    if(it != address_spaces.end())
      as = it->second;
    else
      throw std::logic_error("Invalid address space.");

    return cxt.make_bitfield_expr(as, pos, len);
  }

  // When given an integer width specifier, such as i32,
  // return the integer after the i. In this case, 32.
  static int
  deduce_int_type_width(const symbol* ty)
  {
    std::string spec = *ty;

    if(spec.front() == 'i') {
      spec.erase(0, 1);

      std::size_t it;
      auto width = std::stoi(spec.c_str(), &it);

      if(spec.size() == it)
	return width;
    }

    std::stringstream ss;
    ss << "Invalid integer width specifier: " << *ty <<
      ". Specifier should be of form i[integer].\n";
    throw std::runtime_error(ss.str().c_str());
  }

  expr*
  translator::trans_int_expr(const sexpr::list_expr* e)
  {
    symbol* width_specifier;
    int value;
    match_list(e, "int", &width_specifier, &value);

    int w = deduce_int_type_width(width_specifier);

    return cxt.make_int_expr( new int_type(w), value );
  }

  // -------------------------------------------------------------------------- //
  // Matching

  void
  translator::match(const sexpr::list_expr* list, int n, decl_seq* decls)
  {
    *decls = trans_decls(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, rule_seq* rules)
  {
    *rules = trans_rules(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, expr_seq* exprs)
  {
    *exprs = trans_exprs(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, expr** out)
  {
    *out = trans_expr(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, action_seq* actions)
  {
    *actions = trans_actions(get(list, n));
  }

  void
  translator::match(const sexpr::list_expr* list, int n, action** a)
  {
    *a = trans_action(list);
  }
} // namespace pip
<|endoftext|>


<commit_before>// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.

#include "browser/views/views_delegate.h"

#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"

#if defined(OS_LINUX)
#include "ui/views/linux_ui/linux_ui.h"
#endif

namespace brightray {

ViewsDelegate::ViewsDelegate() {
  DCHECK(!views::ViewsDelegate::views_delegate);
  views::ViewsDelegate::views_delegate = this;
}

ViewsDelegate::~ViewsDelegate() {
  DCHECK_EQ(views::ViewsDelegate::views_delegate, this);
  views::ViewsDelegate::views_delegate = NULL;
}

void ViewsDelegate::SaveWindowPlacement(const views::Widget* window,
                                        const std::string& window_name,
                                        const gfx::Rect& bounds,
                                        ui::WindowShowState show_state) {
}

bool ViewsDelegate::GetSavedWindowPlacement(
    const views::Widget* widget,
    const std::string& window_name,
    gfx::Rect* bounds,
    ui::WindowShowState* show_state) const {
  return false;
}

void ViewsDelegate::NotifyAccessibilityEvent(
    views::View* view, ui::AXEvent event_type) {
}

void ViewsDelegate::NotifyMenuItemFocused(
    const base::string16& menu_name,
    const base::string16& menu_item_name,
    int item_index,
    int item_count,
    bool has_submenu) {
}

#if defined(OS_WIN)
HICON ViewsDelegate::GetDefaultWindowIcon() const {
  // Use current exe's icon as default window icon.
  return LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(1  /* IDR_MAINFRAME */));
}

HICON ViewsDelegate::GetSmallWindowIcon() const {
  return GetDefaultWindowIcon();
}

bool ViewsDelegate::IsWindowInMetro(gfx::NativeWindow window) const {
  return false;
}

#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
gfx::ImageSkia* ViewsDelegate::GetDefaultWindowIcon() const {
  return NULL;
}
#endif

views::NonClientFrameView* ViewsDelegate::CreateDefaultNonClientFrameView(
    views::Widget* widget) {
  return NULL;
}

void ViewsDelegate::AddRef() {
}

void ViewsDelegate::ReleaseRef() {
}

content::WebContents* ViewsDelegate::CreateWebContents(
    content::BrowserContext* browser_context,
    content::SiteInstance* site_instance) {
  return NULL;
}

void ViewsDelegate::OnBeforeWidgetInit(
    views::Widget::InitParams* params,
    views::internal::NativeWidgetDelegate* delegate) {
  // If we already have a native_widget, we don't have to try to come
  // up with one.
  if (params->native_widget)
    return;

  // The native_widget is required when using aura.
  if (params->type == views::Widget::InitParams::TYPE_MENU ||
      (params->parent == NULL && params->context == NULL && !params->child))
    params->native_widget = new views::DesktopNativeWidgetAura(delegate);
}

base::TimeDelta ViewsDelegate::GetDefaultTextfieldObscuredRevealDuration() {
  return base::TimeDelta();
}

bool ViewsDelegate::WindowManagerProvidesTitleBar(bool maximized) {
#if defined(OS_LINUX)
  // On Ubuntu Unity, the system always provides a title bar for maximized
  // windows.
  views::LinuxUI* ui = views::LinuxUI::instance();
  return maximized && ui && ui->UnityIsRunning();
#else
  return false;
#endif
}

}  // namespace brightray
<commit_msg>Fix API changes on Linux<commit_after>// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.

#include "browser/views/views_delegate.h"

#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"

#if defined(OS_LINUX)
#include "ui/views/linux_ui/linux_ui.h"
#endif

namespace brightray {

ViewsDelegate::ViewsDelegate() {
}

ViewsDelegate::~ViewsDelegate() {
}

void ViewsDelegate::SaveWindowPlacement(const views::Widget* window,
                                        const std::string& window_name,
                                        const gfx::Rect& bounds,
                                        ui::WindowShowState show_state) {
}

bool ViewsDelegate::GetSavedWindowPlacement(
    const views::Widget* widget,
    const std::string& window_name,
    gfx::Rect* bounds,
    ui::WindowShowState* show_state) const {
  return false;
}

void ViewsDelegate::NotifyAccessibilityEvent(
    views::View* view, ui::AXEvent event_type) {
}

void ViewsDelegate::NotifyMenuItemFocused(
    const base::string16& menu_name,
    const base::string16& menu_item_name,
    int item_index,
    int item_count,
    bool has_submenu) {
}

#if defined(OS_WIN)
HICON ViewsDelegate::GetDefaultWindowIcon() const {
  // Use current exe's icon as default window icon.
  return LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(1  /* IDR_MAINFRAME */));
}

HICON ViewsDelegate::GetSmallWindowIcon() const {
  return GetDefaultWindowIcon();
}

bool ViewsDelegate::IsWindowInMetro(gfx::NativeWindow window) const {
  return false;
}

#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
gfx::ImageSkia* ViewsDelegate::GetDefaultWindowIcon() const {
  return NULL;
}
#endif

views::NonClientFrameView* ViewsDelegate::CreateDefaultNonClientFrameView(
    views::Widget* widget) {
  return NULL;
}

void ViewsDelegate::AddRef() {
}

void ViewsDelegate::ReleaseRef() {
}

content::WebContents* ViewsDelegate::CreateWebContents(
    content::BrowserContext* browser_context,
    content::SiteInstance* site_instance) {
  return NULL;
}

void ViewsDelegate::OnBeforeWidgetInit(
    views::Widget::InitParams* params,
    views::internal::NativeWidgetDelegate* delegate) {
  // If we already have a native_widget, we don't have to try to come
  // up with one.
  if (params->native_widget)
    return;

  // The native_widget is required when using aura.
  if (params->type == views::Widget::InitParams::TYPE_MENU ||
      (params->parent == NULL && params->context == NULL && !params->child))
    params->native_widget = new views::DesktopNativeWidgetAura(delegate);
}

base::TimeDelta ViewsDelegate::GetDefaultTextfieldObscuredRevealDuration() {
  return base::TimeDelta();
}

bool ViewsDelegate::WindowManagerProvidesTitleBar(bool maximized) {
#if defined(OS_LINUX)
  // On Ubuntu Unity, the system always provides a title bar for maximized
  // windows.
  views::LinuxUI* ui = views::LinuxUI::instance();
  return maximized && ui && ui->UnityIsRunning();
#else
  return false;
#endif
}

}  // namespace brightray
<|endoftext|>


<commit_before>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   ScriptMetaTypeDefines.cpp
 *  @brief  Registration of Naali Core API to Javascript.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "ScriptMetaTypeDefines.h"

#include "Entity.h"
#include "KeyEvent.h"
#include "MouseEvent.h"
#include "UiProxyWidget.h"
#include "Frame.h"
#include "Console.h"
#include "ISoundService.h"

#include "EntityAction.h"

#include <QUiLoader>
#include <QFile>
#include "MemoryLeakCheck.h"

//! Qt defines
Q_SCRIPT_DECLARE_QMETAOBJECT(QPushButton, QWidget*)
Q_SCRIPT_DECLARE_QMETAOBJECT(QWidget, QWidget*)

///\todo Remove these two and move to Input API once NaaliCore is merged.
//! Naali input defines
Q_DECLARE_METATYPE(MouseEvent*)
Q_DECLARE_METATYPE(KeyEvent*)

//! Naali Ui defines
Q_DECLARE_METATYPE(UiProxyWidget*);
Q_SCRIPT_DECLARE_QMETAOBJECT(UiProxyWidget, QWidget*)

//! Naali Scene defines.
Q_DECLARE_METATYPE(Scene::Entity*);
Q_DECLARE_METATYPE(EntityAction*);
Q_DECLARE_METATYPE(AttributeChange*);
Q_DECLARE_METATYPE(IComponent*);
Q_DECLARE_METATYPE(AttributeChange::Type);

//! Naali core API object defines.
Q_DECLARE_METATYPE(Frame*);
Q_DECLARE_METATYPE(ScriptConsole*);
Q_DECLARE_METATYPE(Command*);
Q_DECLARE_METATYPE(DelayedSignal*);

void ExposeQtMetaTypes(QScriptEngine *engine)
{
    QScriptValue object = engine->scriptValueFromQMetaObject<QPushButton>();
    engine->globalObject().setProperty("QPushButton", object);
    object = engine->scriptValueFromQMetaObject<QWidget>();
    engine->globalObject().setProperty("QWidget", object);
}

void ExposeCoreApiMetaTypes(QScriptEngine *engine)
{
    // Input metatypes.
    qScriptRegisterQObjectMetaType<MouseEvent*>(engine);
    qScriptRegisterQObjectMetaType<KeyEvent*>(engine);
    qRegisterMetaType<KeyEvent::EventType>("KeyEvent::EventType");
    qRegisterMetaType<MouseEvent::EventType>("MouseEvent::EventType");
    qRegisterMetaType<MouseEvent::MouseButton>("MouseEvent::MouseButton");

    // Scene metatypes.
    qScriptRegisterQObjectMetaType<Scene::Entity*>(engine);
    qScriptRegisterQObjectMetaType<EntityAction*>(engine);
    qScriptRegisterQObjectMetaType<AttributeChange*>(engine);
    qScriptRegisterQObjectMetaType<IComponent*>(engine);
    //qRegisterMetaType<AttributeChange::Type>("AttributeChange::Type");
    qScriptRegisterMetaType(engine, toScriptValueEnum<AttributeChange::Type>, fromScriptValueEnum<AttributeChange::Type>);
    qRegisterMetaType<EntityAction::ExecutionType>("EntityAction::ExecutionType");

    // Console metatypes.
    qScriptRegisterQObjectMetaType<ScriptConsole*>(engine);
    qScriptRegisterQObjectMetaType<Command*>(engine);

    // Frame metatypes.
    qScriptRegisterQObjectMetaType<Frame*>(engine);
    qScriptRegisterQObjectMetaType<DelayedSignal*>(engine);

    // Ui metatypes.
    qScriptRegisterQObjectMetaType<UiProxyWidget*>(engine);
    qScriptRegisterQObjectMetaType<QGraphicsScene*>(engine);
    //Add support to create proxy widgets in javascript side.
    QScriptValue object = engine->scriptValueFromQMetaObject<UiProxyWidget>();
    engine->globalObject().setProperty("UiProxyWidget", object);

    // Sound metatypes.
    qRegisterMetaType<sound_id_t>("sound_id_t");
    qRegisterMetaType<ISoundService::SoundState>("SoundState");
    qRegisterMetaType<ISoundService::SoundState>("ISoundService::SoundState");
    qRegisterMetaType<ISoundService::SoundType>("SoundType");
    qRegisterMetaType<ISoundService::SoundType>("ISoundService::SoundType");
}

<commit_msg>Expose/register EntityAction::ExecutionType enum to js.<commit_after>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   ScriptMetaTypeDefines.cpp
 *  @brief  Registration of Naali Core API to Javascript.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "ScriptMetaTypeDefines.h"

#include "Entity.h"
#include "KeyEvent.h"
#include "MouseEvent.h"
#include "UiProxyWidget.h"
#include "Frame.h"
#include "Console.h"
#include "ISoundService.h"

#include "EntityAction.h"

#include <QUiLoader>
#include <QFile>
#include "MemoryLeakCheck.h"

//! Qt defines
Q_SCRIPT_DECLARE_QMETAOBJECT(QPushButton, QWidget*)
Q_SCRIPT_DECLARE_QMETAOBJECT(QWidget, QWidget*)

///\todo Remove these two and move to Input API once NaaliCore is merged.
//! Naali input defines
Q_DECLARE_METATYPE(MouseEvent*)
Q_DECLARE_METATYPE(KeyEvent*)

//! Naali Ui defines
Q_DECLARE_METATYPE(UiProxyWidget*);
Q_SCRIPT_DECLARE_QMETAOBJECT(UiProxyWidget, QWidget*)

//! Naali Scene defines.
Q_DECLARE_METATYPE(Scene::Entity*);
Q_DECLARE_METATYPE(EntityAction*);
Q_DECLARE_METATYPE(EntityAction::ExecutionType);
Q_DECLARE_METATYPE(AttributeChange*);
Q_DECLARE_METATYPE(IComponent*);
Q_DECLARE_METATYPE(AttributeChange::Type);

//! Naali core API object defines.
Q_DECLARE_METATYPE(Frame*);
Q_DECLARE_METATYPE(ScriptConsole*);
Q_DECLARE_METATYPE(Command*);
Q_DECLARE_METATYPE(DelayedSignal*);

void ExposeQtMetaTypes(QScriptEngine *engine)
{
    QScriptValue object = engine->scriptValueFromQMetaObject<QPushButton>();
    engine->globalObject().setProperty("QPushButton", object);
    object = engine->scriptValueFromQMetaObject<QWidget>();
    engine->globalObject().setProperty("QWidget", object);
}

void ExposeCoreApiMetaTypes(QScriptEngine *engine)
{
    // Input metatypes.
    qScriptRegisterQObjectMetaType<MouseEvent*>(engine);
    qScriptRegisterQObjectMetaType<KeyEvent*>(engine);
    qRegisterMetaType<KeyEvent::EventType>("KeyEvent::EventType");
    qRegisterMetaType<MouseEvent::EventType>("MouseEvent::EventType");
    qRegisterMetaType<MouseEvent::MouseButton>("MouseEvent::MouseButton");

    // Scene metatypes.
    qScriptRegisterQObjectMetaType<Scene::Entity*>(engine);
    qScriptRegisterQObjectMetaType<EntityAction*>(engine);
    qScriptRegisterQObjectMetaType<AttributeChange*>(engine);
    qScriptRegisterQObjectMetaType<IComponent*>(engine);
    //qRegisterMetaType<AttributeChange::Type>("AttributeChange::Type");
    qScriptRegisterMetaType(engine, toScriptValueEnum<AttributeChange::Type>, fromScriptValueEnum<AttributeChange::Type>);
    //qRegisterMetaType<EntityAction::ExecutionType>("EntityAction::ExecutionType");
    qScriptRegisterMetaType(engine, toScriptValueEnum<EntityAction::ExecutionType>, fromScriptValueEnum<EntityAction::ExecutionType>);

    // Console metatypes.
    qScriptRegisterQObjectMetaType<ScriptConsole*>(engine);
    qScriptRegisterQObjectMetaType<Command*>(engine);

    // Frame metatypes.
    qScriptRegisterQObjectMetaType<Frame*>(engine);
    qScriptRegisterQObjectMetaType<DelayedSignal*>(engine);

    // Ui metatypes.
    qScriptRegisterQObjectMetaType<UiProxyWidget*>(engine);
    qScriptRegisterQObjectMetaType<QGraphicsScene*>(engine);
    //Add support to create proxy widgets in javascript side.
    QScriptValue object = engine->scriptValueFromQMetaObject<UiProxyWidget>();
    engine->globalObject().setProperty("UiProxyWidget", object);

    // Sound metatypes.
    qRegisterMetaType<sound_id_t>("sound_id_t");
    qRegisterMetaType<ISoundService::SoundState>("SoundState");
    qRegisterMetaType<ISoundService::SoundState>("ISoundService::SoundState");
    qRegisterMetaType<ISoundService::SoundType>("SoundType");
    qRegisterMetaType<ISoundService::SoundType>("ISoundService::SoundType");
}

<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_SCAL_FUN_LGAMMA_HPP
#define STAN_MATH_PRIM_SCAL_FUN_LGAMMA_HPP

#if _POSIX_C_SOURCE >= 199506L
#include <cmath>
#else
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/scal/fun/boost_policy.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <limits>
#endif

namespace stan {
namespace math {

/**
 * Return the natural logarithm of the gamma function applied to
 * the specified argument.
 *
   \f[
   \mbox{lgamma}(x) =
   \begin{cases}
     \textrm{error} & \mbox{if } x\in \{\dots, -3, -2, -1, 0\}\\
     \ln\Gamma(x) & \mbox{if } x\not\in \{\dots, -3, -2, -1, 0\}\\[6pt]
     \textrm{NaN} & \mbox{if } x = \textrm{NaN}
   \end{cases}
   \f]

   \f[
   \frac{\partial\, \mbox{lgamma}(x)}{\partial x} =
   \begin{cases}
     \textrm{error} & \mbox{if } x\in \{\dots, -3, -2, -1, 0\}\\
     \Psi(x) & \mbox{if } x\not\in \{\dots, -3, -2, -1, 0\}\\[6pt]
     \textrm{NaN} & \mbox{if } x = \textrm{NaN}
   \end{cases}
\f]
*
* @param x argument
* @return natural logarithm of the gamma function applied to
* argument
*/
inline double lgamma(double x) {
#if _POSIX_C_SOURCE >= 199506L
  int sign = 0;
  return lgamma_r(x, &sign);
#else
  if (unlikely(x == 0.0))
    return std::numeric_limits<double>::infinity();
  return boost::math::lgamma(x, boost_policy_t());
#endif
}

/**
 * Return the natural logarithm of the gamma function applied
 * to the specified argument.
 *
 * @param x argument
 * @return natural logarithm of the gamma function applied to
 * argument
 */
inline double lgamma(int x) {
#if _POSIX_C_SOURCE >= 199506L
  int sign = 0;
  return lgamma_r(x, &sign);
#else
  if (unlikely(x == 0.0))
    return std::numeric_limits<double>::infinity();
  return boost::math::lgamma(x, boost_policy_t());
#endif
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/stable/2017-11-14)<commit_after>#ifndef STAN_MATH_PRIM_SCAL_FUN_LGAMMA_HPP
#define STAN_MATH_PRIM_SCAL_FUN_LGAMMA_HPP

#if _POSIX_C_SOURCE >= 199506L
#include <cmath>
#else
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/scal/fun/boost_policy.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <limits>
#endif

namespace stan {
namespace math {

/**
 * Return the natural logarithm of the gamma function applied to
 * the specified argument.
 *
   \f[
   \mbox{lgamma}(x) =
   \begin{cases}
     \textrm{error} & \mbox{if } x\in \{\dots, -3, -2, -1, 0\}\\
     \ln\Gamma(x) & \mbox{if } x\not\in \{\dots, -3, -2, -1, 0\}\\[6pt]
     \textrm{NaN} & \mbox{if } x = \textrm{NaN}
   \end{cases}
   \f]

   \f[
   \frac{\partial\, \mbox{lgamma}(x)}{\partial x} =
   \begin{cases}
     \textrm{error} & \mbox{if } x\in \{\dots, -3, -2, -1, 0\}\\
     \Psi(x) & \mbox{if } x\not\in \{\dots, -3, -2, -1, 0\}\\[6pt]
     \textrm{NaN} & \mbox{if } x = \textrm{NaN}
   \end{cases}
\f]
*
* @param x argument
* @return natural logarithm of the gamma function applied to
* argument
*/
inline double lgamma(double x) {
#if _POSIX_C_SOURCE >= 199506L
  int sign = 0;
  return lgamma_r(x, &sign);
#else
  if (unlikely(x == 0.0))
    return std::numeric_limits<double>::infinity();
  return boost::math::lgamma(x, boost_policy_t());
#endif
}

/**
 * Return the natural logarithm of the gamma function applied
 * to the specified argument.
 *
 * @param x argument
 * @return natural logarithm of the gamma function applied to
 * argument
 */
inline double lgamma(int x) {
#if _POSIX_C_SOURCE >= 199506L
  int sign = 0;
  return lgamma_r(x, &sign);
#else
  if (unlikely(x == 0.0))
    return std::numeric_limits<double>::infinity();
  return boost::math::lgamma(x, boost_policy_t());
#endif
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>