<commit_before>/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/
#include "remoteobject_p.hpp"
#include "src/object_p.hpp"
#include "src/metasignal_p.hpp"
#include <qimessaging/message.hpp>
#include <qimessaging/transportsocket.hpp>
#include <qi/log.hpp>
#include <boost/thread/mutex.hpp>

namespace qi {

  RemoteObject::RemoteObject(unsigned int service, qi::MetaObject metaObject, TransportSocketPtr socket)
    : _socket(socket)
    , _service(service)
    , _linkMessageDispatcher(0)
  {
    setMetaObject(metaObject);
    setTransportSocket(socket);
  }

  //### RemoteObject

  void RemoteObject::setTransportSocket(qi::TransportSocketPtr socket) {
    if (_socket)
      _socket->messagePendingDisconnect(_service, _linkMessageDispatcher);
    _socket = socket;
    if (socket)
      _linkMessageDispatcher = _socket->messagePendingConnect(_service, boost::bind<void>(&RemoteObject::onMessagePending, this, _1));
  }

  RemoteObject::~RemoteObject()
  {
    //close may already have been called. (by Session_Service.close)
    close();
  }

  void RemoteObject::onMessagePending(const qi::Message &msg)
  {
    qi::Promise<MetaFunctionResult>                           promise;
    bool                                                      found = false;
    std::map<int, qi::Promise<MetaFunctionResult> >::iterator it;

    qiLogDebug("RemoteObject") << this << " msg " << msg.type() << " " << msg.buffer().size();
    {
      boost::mutex::scoped_lock lock(_mutex);
      it = _promises.find(msg.id());
      if (it != _promises.end()) {
        promise = _promises[msg.id()];
        _promises.erase(it);
        found = true;
      }
    }

    switch (msg.type()) {
      case qi::Message::Type_Reply:
        if (!found) {
          qiLogError("remoteobject") << "no promise found for req id:" << msg.id()
          << "  obj: " << msg.service() << "  func: " << msg.function();
          return;
        }
        promise.setValue(MetaFunctionResult(msg.buffer()));

        return;
      case qi::Message::Type_Error: {
        qi::IDataStream ds(msg.buffer());
        std::string    err;
        std::string    sig;
        ds >> sig;
        if (sig != "s") {
          qiLogError("qi.RemoteObject") << "Invalid error signature: " << sig;
          //houston we have an error about the error..
          promise.setError("unknown error");
          return;
        }
        ds >> err;
        promise.setError(err);
        return;
      }
      case qi::Message::Type_Event: {
        SignalBase* sb = getSignal(msg.event());
        if (sb)
          sb->trigger(MetaFunctionParameters(msg.buffer()));
        else
        {
          qiLogWarning("remoteobject") << "Event message on unknown signal " << msg.event();
          qiLogDebug("remoteobject") << metaObject().signalMap().size();
        }
        return;
      }
      default:
        qiLogError("remoteobject") << "Message (#" << msg.id() << ") type not handled: " << msg.type();
        return;
    }
  }

  qi::Future<MetaFunctionResult> RemoteObject::metaCall(unsigned int method, const qi::MetaFunctionParameters &in, MetaCallType callType)
  {
    qi::Promise<MetaFunctionResult> out;
    qi::Message msg;
    msg.setBuffer(in.getBuffer());
    msg.setType(qi::Message::Type_Call);
    msg.setService(_service);
    msg.setObject(qi::Message::GenericObject_Main);
    msg.setFunction(method);
    qiLogDebug("remoteobject") << this << " metacall " << msg.service() << " "
     << msg.function() <<" " << msg.id();
    {
      boost::mutex::scoped_lock lock(_mutex);
      if (_promises.find(msg.id()) != _promises.end())
      {
        qiLogError("remoteobject") << "There is already a pending promise with id "
                                   << msg.id();
      }
      _promises[msg.id()] = out;
    }

    //error will come back as a error message
    if (!_socket || !_socket->send(msg)) {
      qiLogError("remoteobject") << "error while sending answer";
      qi::MetaMethod*   meth = metaObject().method(method);
      std::stringstream ss;
      if (meth) {
        ss << "Network error while sending data to method: '";
        ss << meth->signature();;
        ss << "'";
      } else {
        ss << "Network error while sending data an unknown method (id=" << method << ")";
      }
      out.setError(ss.str());

      {
        boost::mutex::scoped_lock lock(_mutex);
        _promises.erase(msg.id());
      }
    }
    return out.future();
  }

  void RemoteObject::metaEmit(unsigned int event, const qi::MetaFunctionParameters &args)
  {
    // Bounce the emit request to server
    // TODO: one optimisation that could be done is to trigger the local
    // subscribers immediately.
    // But it is a bit complex, because the server will bounce the
    // event back to us.
    qi::Message msg;
    msg.setBuffer(args.getBuffer());
    msg.setType(Message::Type_Event);
    msg.setService(_service);
    msg.setObject(qi::Message::GenericObject_Main);
    msg.setFunction(event);
    if (!_socket->send(msg)) {
      qiLogError("remoteobject") << "error while emiting event";
    }
  }

  unsigned int RemoteObject::connect(unsigned int event, const SignalSubscriber& sub)
  {
    // Bind the subscriber locally.
    unsigned int uid = DynamicObject::connect(event, sub);
    // Notify the Service that we are interested in its event.
    // Provide our uid as payload
    // We send one message per connect, even on the same event: the remot
    // end is doing the refcounting
    qi::Message msg;
    qi::Buffer buf;
    qi::ODataStream ds(buf);
    ds << _service << event << uid;
    msg.setBuffer(buf);
    msg.setObject(qi::Message::GenericObject_Main);
    msg.setType(Message::Type_Event);
    msg.setService(Message::Service_Server);
    msg.setFunction(Message::ServerFunction_RegisterEvent);

    if (!_socket->send(msg)) {
      qiLogError("remoteobject") << "error while registering event";
    }
    qiLogDebug("remoteobject") <<"connect() to " << event <<" gave " << uid;
    return uid;
  }

  bool RemoteObject::disconnect(unsigned int linkId)
  {
    unsigned int event = linkId >> 16;
    //disconnect locally
    bool ok = DynamicObject::disconnect(linkId);
    if (!ok)
    {
      qiLogWarning("qi.object") << "Disconnection failure for " << linkId;
      return false;
    }
    else
    {
      // Tell the remote we are no longer interested.
      qi::Message msg;
      qi::Buffer buf;
      qi::ODataStream ds(buf);
      ds << _service << event << linkId;
      msg.setBuffer(buf);
      msg.setType(Message::Type_Event);
      msg.setService(Message::Service_Server);
      msg.setObject(Message::GenericObject_Main);
      msg.setFunction(Message::ServerFunction_UnregisterEvent);
      if (!_socket->send(msg)) {
        qiLogError("remoteobject") << "error while disconnecting signal";
      }
      return true;
    }
  }

  void RemoteObject::close() {
    if (_socket)
      _socket->messagePendingDisconnect(_service, _linkMessageDispatcher);
  }

}
<commit_msg>remoteobject: more log on error<commit_after>/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/
#include "remoteobject_p.hpp"
#include "src/object_p.hpp"
#include "src/metasignal_p.hpp"
#include <qimessaging/message.hpp>
#include <qimessaging/transportsocket.hpp>
#include <qi/log.hpp>
#include <boost/thread/mutex.hpp>

namespace qi {

  RemoteObject::RemoteObject(unsigned int service, qi::MetaObject metaObject, TransportSocketPtr socket)
    : _socket(socket)
    , _service(service)
    , _linkMessageDispatcher(0)
  {
    setMetaObject(metaObject);
    setTransportSocket(socket);
  }

  //### RemoteObject

  void RemoteObject::setTransportSocket(qi::TransportSocketPtr socket) {
    if (_socket)
      _socket->messagePendingDisconnect(_service, _linkMessageDispatcher);
    _socket = socket;
    if (socket)
      _linkMessageDispatcher = _socket->messagePendingConnect(_service, boost::bind<void>(&RemoteObject::onMessagePending, this, _1));
  }

  RemoteObject::~RemoteObject()
  {
    //close may already have been called. (by Session_Service.close)
    close();
  }

  void RemoteObject::onMessagePending(const qi::Message &msg)
  {
    qi::Promise<MetaFunctionResult>                           promise;
    bool                                                      found = false;
    std::map<int, qi::Promise<MetaFunctionResult> >::iterator it;

    qiLogDebug("RemoteObject") << this << " msg " << msg.type() << " " << msg.buffer().size();
    {
      boost::mutex::scoped_lock lock(_mutex);
      it = _promises.find(msg.id());
      if (it != _promises.end()) {
        promise = _promises[msg.id()];
        _promises.erase(it);
        found = true;
      }
    }

    switch (msg.type()) {
      case qi::Message::Type_Reply:
        if (!found) {
          qiLogError("remoteobject") << "no promise found for req id:" << msg.id()
          << "  obj: " << msg.service() << "  func: " << msg.function();
          return;
        }
        promise.setValue(MetaFunctionResult(msg.buffer()));

        return;
      case qi::Message::Type_Error: {
        qi::IDataStream ds(msg.buffer());
        std::string    err;
        std::string    sig;
        ds >> sig;
        if (sig != "s") {
          qiLogError("qi.RemoteObject") << "Invalid error signature: " << sig;
          //houston we have an error about the error..
          promise.setError("unknown error");
          return;
        }
        ds >> err;
        qiLogVerbose("remoteobject") << "Received error message"  << msg.address() << ":" << err;
        promise.setError(err);
        return;
      }
      case qi::Message::Type_Event: {
        SignalBase* sb = getSignal(msg.event());
        if (sb)
          sb->trigger(MetaFunctionParameters(msg.buffer()));
        else
        {
          qiLogWarning("remoteobject") << "Event message on unknown signal " << msg.event();
          qiLogDebug("remoteobject") << metaObject().signalMap().size();
        }
        return;
      }
      default:
        qiLogError("remoteobject") << "Message " << msg.address() << " type not handled: " << msg.type();
        return;
    }
  }

  qi::Future<MetaFunctionResult> RemoteObject::metaCall(unsigned int method, const qi::MetaFunctionParameters &in, MetaCallType callType)
  {
    qi::Promise<MetaFunctionResult> out;
    qi::Message msg;
    msg.setBuffer(in.getBuffer());
    msg.setType(qi::Message::Type_Call);
    msg.setService(_service);
    msg.setObject(qi::Message::GenericObject_Main);
    msg.setFunction(method);
    qiLogDebug("remoteobject") << this << " metacall " << msg.service() << " "
     << msg.function() <<" " << msg.id();
    {
      boost::mutex::scoped_lock lock(_mutex);
      if (_promises.find(msg.id()) != _promises.end())
      {
        qiLogError("remoteobject") << "There is already a pending promise with id "
                                   << msg.id();
      }
      _promises[msg.id()] = out;
    }

    //error will come back as a error message
    if (!_socket || !_socket->send(msg)) {
      qiLogError("remoteobject") << "error while sending answer";
      qi::MetaMethod*   meth = metaObject().method(method);
      std::stringstream ss;
      if (meth) {
        ss << "Network error while sending data to method: '";
        ss << meth->signature();;
        ss << "'";
      } else {
        ss << "Network error while sending data an unknown method (id=" << method << ")";
      }
      out.setError(ss.str());

      {
        boost::mutex::scoped_lock lock(_mutex);
        _promises.erase(msg.id());
      }
    }
    return out.future();
  }

  void RemoteObject::metaEmit(unsigned int event, const qi::MetaFunctionParameters &args)
  {
    // Bounce the emit request to server
    // TODO: one optimisation that could be done is to trigger the local
    // subscribers immediately.
    // But it is a bit complex, because the server will bounce the
    // event back to us.
    qi::Message msg;
    msg.setBuffer(args.getBuffer());
    msg.setType(Message::Type_Event);
    msg.setService(_service);
    msg.setObject(qi::Message::GenericObject_Main);
    msg.setFunction(event);
    if (!_socket->send(msg)) {
      qiLogError("remoteobject") << "error while emiting event";
    }
  }

  unsigned int RemoteObject::connect(unsigned int event, const SignalSubscriber& sub)
  {
    // Bind the subscriber locally.
    unsigned int uid = DynamicObject::connect(event, sub);
    // Notify the Service that we are interested in its event.
    // Provide our uid as payload
    // We send one message per connect, even on the same event: the remot
    // end is doing the refcounting
    qi::Message msg;
    qi::Buffer buf;
    qi::ODataStream ds(buf);
    ds << _service << event << uid;
    msg.setBuffer(buf);
    msg.setObject(qi::Message::GenericObject_Main);
    msg.setType(Message::Type_Event);
    msg.setService(Message::Service_Server);
    msg.setFunction(Message::ServerFunction_RegisterEvent);

    if (!_socket->send(msg)) {
      qiLogError("remoteobject") << "error while registering event";
    }
    qiLogDebug("remoteobject") <<"connect() to " << event <<" gave " << uid;
    return uid;
  }

  bool RemoteObject::disconnect(unsigned int linkId)
  {
    unsigned int event = linkId >> 16;
    //disconnect locally
    bool ok = DynamicObject::disconnect(linkId);
    if (!ok)
    {
      qiLogWarning("qi.object") << "Disconnection failure for " << linkId;
      return false;
    }
    else
    {
      // Tell the remote we are no longer interested.
      qi::Message msg;
      qi::Buffer buf;
      qi::ODataStream ds(buf);
      ds << _service << event << linkId;
      msg.setBuffer(buf);
      msg.setType(Message::Type_Event);
      msg.setService(Message::Service_Server);
      msg.setObject(Message::GenericObject_Main);
      msg.setFunction(Message::ServerFunction_UnregisterEvent);
      if (!_socket->send(msg)) {
        qiLogError("remoteobject") << "error while disconnecting signal";
      }
      return true;
    }
  }

  void RemoteObject::close() {
    if (_socket)
      _socket->messagePendingDisconnect(_service, _linkMessageDispatcher);
  }

}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes functions for debugging.
 */

#ifndef DEBUG_HPP_
#define DEBUG_HPP_

#include <openthread-core-config.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#if defined(OPENTHREAD_TARGET_DARWIN) || defined(OPENTHREAD_TARGET_LINUX)

#include <assert.h>

#elif defined(_KERNEL_MODE)

#include <wdm.h>

#define assert(exp) \
    ((!(exp)) ? \
        (RtlAssert( #exp, __FILE__, __LINE__, NULL ),FALSE) : \
        TRUE)

#elif defined(_WIN32)

#include <assert.h>

#elif OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT

#include <platform/misc.h>

#define assert(cond)                            \
  do {                                          \
    if (!(cond)) {                              \
      otPlatAssertFail(__FILE__, __LINE__);     \
      while (1) {}                              \
    }                                           \
  } while (0)

#else

#define assert(cond)                            \
  do {                                          \
    if (!(cond)) {                              \
      while (1) {}                              \
    }                                           \
  } while (0)

#endif

#endif  // DEBUG_HPP_
<commit_msg>Update the include path for "misc.h" in "debug.hpp" (#1419)<commit_after>/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes functions for debugging.
 */

#ifndef DEBUG_HPP_
#define DEBUG_HPP_

#include <openthread-core-config.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#if defined(OPENTHREAD_TARGET_DARWIN) || defined(OPENTHREAD_TARGET_LINUX)

#include <assert.h>

#elif defined(_KERNEL_MODE)

#include <wdm.h>

#define assert(exp) \
    ((!(exp)) ? \
        (RtlAssert( #exp, __FILE__, __LINE__, NULL ),FALSE) : \
        TRUE)

#elif defined(_WIN32)

#include <assert.h>

#elif OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT

#include "openthread/platform/misc.h"

#define assert(cond)                            \
  do {                                          \
    if (!(cond)) {                              \
      otPlatAssertFail(__FILE__, __LINE__);     \
      while (1) {}                              \
    }                                           \
  } while (0)

#else

#define assert(cond)                            \
  do {                                          \
    if (!(cond)) {                              \
      while (1) {}                              \
    }                                           \
  } while (0)

#endif

#endif  // DEBUG_HPP_
<|endoftext|>


<commit_before>#ifndef ENTT_ENTITY_ACTOR_HPP
#define ENTT_ENTITY_ACTOR_HPP

#include <utility>
#include <type_traits>
#include "../config/config.h"
#include "registry.hpp"
#include "entity.hpp"
#include "fwd.hpp"

namespace entt {

/**
 * @brief Dedicated to those who aren't confident with the
 * entity-component-system architecture.
 *
 * Tiny wrapper around a registry, for all those users that aren't confident
 * with entity-component-system architecture and prefer to iterate objects
 * directly.
 *
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
struct basic_actor {
    /*! @brief Type of registry used internally. */
    using registry_type = basic_registry<Entity>;
    /*! @brief Underlying entity identifier. */
    using entity_type = Entity;

    basic_actor() ENTT_NOEXCEPT
        : entt{entt::null}, reg{nullptr}
    {}

    /**
     * @brief Move constructor.
     *
     * After actor move construction, instances that have been moved from are
     * placed in a valid but unspecified state. It's highly discouraged to
     * continue using them.
     *
     * @param other The instance to move from.
     */
    basic_actor(basic_actor &&other) ENTT_NOEXCEPT
        : entt{other.entt}, reg{other.reg}
    {
        other.entt = null;
    }

    /**
     * @brief Constructs an actor from a given registry.
     * @param ref An instance of the registry class.
     */
    explicit basic_actor(registry_type &ref)
        : entt{ref.create()}, reg{&ref}
    {}

    /**
     * @brief Constructs an actor from a given entity.
     * @param entity A valid entity identifier.
     * @param ref An instance of the registry class.
     */
    explicit basic_actor(entity_type entity, registry_type &ref) ENTT_NOEXCEPT
        : entt{entity}, reg{&ref}
    {
        ENTT_ASSERT(ref.valid(entity));
    }

    /*! @brief Default destructor. */
    virtual ~basic_actor() {
        if(*this) {
            reg->destroy(entt);
        }
    }

    /**
     * @brief Move assignment operator.
     *
     * After actor move assignment, instances that have been moved from are
     * placed in a valid but unspecified state. It's highly discouraged to
     * continue using them.
     *
     * @param other The instance to move from.
     * @return This actor.
     */
    basic_actor & operator=(basic_actor &&other) ENTT_NOEXCEPT {
        if(this != &other) {
            auto tmp{std::move(other)};
            std::swap(reg, tmp.reg);
            std::swap(entt, tmp.entt);
        }

        return *this;
    }

    /**
     * @brief Assigns the given component to an actor.
     *
     * A new instance of the given component is created and initialized with the
     * arguments provided (the component must have a proper constructor or be of
     * aggregate type). Then the component is assigned to the actor.

     * In case the actor already has a component of the given type, it's
     * replaced with the new one.
     *
     * @tparam Component Type of the component to create.
     * @tparam Args Types of arguments to use to construct the component.
     * @param args Parameters to use to initialize the component.
     * @return A reference to the newly created component.
     */
    template<typename Component, typename... Args>
    decltype(auto) assign(Args &&... args) {
        return reg->template assign_or_replace<Component>(entt, std::forward<Args>(args)...);
    }

    /**
     * @brief Removes the given component from an actor.
     * @tparam Component Type of the component to remove.
     */
    template<typename Component>
    void remove() {
        reg->template remove<Component>(entt);
    }

    /**
     * @brief Checks if an actor has the given components.
     * @tparam Component Components for which to perform the check.
     * @return True if the actor has all the components, false otherwise.
     */
    template<typename... Component>
    bool has() const {
        return (reg->template has<Component>(entt) && ...);
    }

    /**
     * @brief Returns references to the given components for an actor.
     * @tparam Component Types of components to get.
     * @return References to the components owned by the actor.
     */
    template<typename... Component>
    decltype(auto) get() const {
        return std::as_const(*reg).template get<Component...>(entt);
    }

    /*! @copydoc get */
    template<typename... Component>
    decltype(auto) get() {
        return reg->template get<Component...>(entt);
    }

    /**
     * @brief Returns pointers to the given components for an actor.
     * @tparam Component Types of components to get.
     * @return Pointers to the components owned by the actor.
     */
    template<typename... Component>
    auto try_get() const {
        return std::as_const(*reg).template try_get<Component...>(entt);
    }

    /*! @copydoc try_get */
    template<typename... Component>
    auto try_get() {
        return reg->template try_get<Component...>(entt);
    }

    /**
     * @brief Returns a reference to the underlying registry.
     * @return A reference to the underlying registry.
     */
    const registry_type & backend() const ENTT_NOEXCEPT {
        return *reg;
    }

    /*! @copydoc backend */
    registry_type & backend() ENTT_NOEXCEPT {
        return const_cast<registry_type &>(std::as_const(*this).backend());
    }

    /**
     * @brief Returns the entity associated with an actor.
     * @return The entity associated with the actor.
     */
    entity_type entity() const ENTT_NOEXCEPT {
        return entt;
    }

    /**
     * @brief Checks if an actor refers to a valid entity or not.
     * @return True if the actor refers to a valid entity, false otherwise.
     */
    explicit operator bool() const {
        return reg && reg->valid(entt);
    }

private:
    entity_type entt;
    registry_type *reg;
};

}

#endif
<commit_msg>actor: (has<T>(e) && ...) -> has<T...>(e)<commit_after>#ifndef ENTT_ENTITY_ACTOR_HPP
#define ENTT_ENTITY_ACTOR_HPP

#include <utility>
#include <type_traits>
#include "../config/config.h"
#include "registry.hpp"
#include "entity.hpp"
#include "fwd.hpp"

namespace entt {

/**
 * @brief Dedicated to those who aren't confident with the
 * entity-component-system architecture.
 *
 * Tiny wrapper around a registry, for all those users that aren't confident
 * with entity-component-system architecture and prefer to iterate objects
 * directly.
 *
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
struct basic_actor {
    /*! @brief Type of registry used internally. */
    using registry_type = basic_registry<Entity>;
    /*! @brief Underlying entity identifier. */
    using entity_type = Entity;

    basic_actor() ENTT_NOEXCEPT
        : entt{entt::null}, reg{nullptr}
    {}

    /**
     * @brief Move constructor.
     *
     * After actor move construction, instances that have been moved from are
     * placed in a valid but unspecified state. It's highly discouraged to
     * continue using them.
     *
     * @param other The instance to move from.
     */
    basic_actor(basic_actor &&other) ENTT_NOEXCEPT
        : entt{other.entt}, reg{other.reg}
    {
        other.entt = null;
    }

    /**
     * @brief Constructs an actor from a given registry.
     * @param ref An instance of the registry class.
     */
    explicit basic_actor(registry_type &ref)
        : entt{ref.create()}, reg{&ref}
    {}

    /**
     * @brief Constructs an actor from a given entity.
     * @param entity A valid entity identifier.
     * @param ref An instance of the registry class.
     */
    explicit basic_actor(entity_type entity, registry_type &ref) ENTT_NOEXCEPT
        : entt{entity}, reg{&ref}
    {
        ENTT_ASSERT(ref.valid(entity));
    }

    /*! @brief Default destructor. */
    virtual ~basic_actor() {
        if(*this) {
            reg->destroy(entt);
        }
    }

    /**
     * @brief Move assignment operator.
     *
     * After actor move assignment, instances that have been moved from are
     * placed in a valid but unspecified state. It's highly discouraged to
     * continue using them.
     *
     * @param other The instance to move from.
     * @return This actor.
     */
    basic_actor & operator=(basic_actor &&other) ENTT_NOEXCEPT {
        if(this != &other) {
            auto tmp{std::move(other)};
            std::swap(reg, tmp.reg);
            std::swap(entt, tmp.entt);
        }

        return *this;
    }

    /**
     * @brief Assigns the given component to an actor.
     *
     * A new instance of the given component is created and initialized with the
     * arguments provided (the component must have a proper constructor or be of
     * aggregate type). Then the component is assigned to the actor.

     * In case the actor already has a component of the given type, it's
     * replaced with the new one.
     *
     * @tparam Component Type of the component to create.
     * @tparam Args Types of arguments to use to construct the component.
     * @param args Parameters to use to initialize the component.
     * @return A reference to the newly created component.
     */
    template<typename Component, typename... Args>
    decltype(auto) assign(Args &&... args) {
        return reg->template assign_or_replace<Component>(entt, std::forward<Args>(args)...);
    }

    /**
     * @brief Removes the given component from an actor.
     * @tparam Component Type of the component to remove.
     */
    template<typename Component>
    void remove() {
        reg->template remove<Component>(entt);
    }

    /**
     * @brief Checks if an actor has the given components.
     * @tparam Component Components for which to perform the check.
     * @return True if the actor has all the components, false otherwise.
     */
    template<typename... Component>
    bool has() const {
        return reg->template has<Component...>(entt);
    }

    /**
     * @brief Returns references to the given components for an actor.
     * @tparam Component Types of components to get.
     * @return References to the components owned by the actor.
     */
    template<typename... Component>
    decltype(auto) get() const {
        return std::as_const(*reg).template get<Component...>(entt);
    }

    /*! @copydoc get */
    template<typename... Component>
    decltype(auto) get() {
        return reg->template get<Component...>(entt);
    }

    /**
     * @brief Returns pointers to the given components for an actor.
     * @tparam Component Types of components to get.
     * @return Pointers to the components owned by the actor.
     */
    template<typename... Component>
    auto try_get() const {
        return std::as_const(*reg).template try_get<Component...>(entt);
    }

    /*! @copydoc try_get */
    template<typename... Component>
    auto try_get() {
        return reg->template try_get<Component...>(entt);
    }

    /**
     * @brief Returns a reference to the underlying registry.
     * @return A reference to the underlying registry.
     */
    const registry_type & backend() const ENTT_NOEXCEPT {
        return *reg;
    }

    /*! @copydoc backend */
    registry_type & backend() ENTT_NOEXCEPT {
        return const_cast<registry_type &>(std::as_const(*this).backend());
    }

    /**
     * @brief Returns the entity associated with an actor.
     * @return The entity associated with the actor.
     */
    entity_type entity() const ENTT_NOEXCEPT {
        return entt;
    }

    /**
     * @brief Checks if an actor refers to a valid entity or not.
     * @return True if the actor refers to a valid entity, false otherwise.
     */
    explicit operator bool() const {
        return reg && reg->valid(entt);
    }

private:
    entity_type entt;
    registry_type *reg;
};

}

#endif
<|endoftext|>


<commit_before><commit_msg>pxt test<commit_after><|endoftext|>


<commit_before>// ImGui Allegro 5 bindings
// https://github.com/ocornut/imgui
// by @birthggd, public domain

#include <stdint.h>     // uint64_t
#include <cstring>      // memcpy
#include <imgui.h>
#include "imgui_impl_a5.h"
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>

#ifdef _WIN32
#include <allegro5/allegro_windows.h>
#endif

// Data
static ALLEGRO_DISPLAY* g_Display = NULL;
static ALLEGRO_BITMAP*  g_Surface = NULL;
static double           g_Time = 0.0;

static void ImGui_ImplA5_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
    const float width = ImGui::GetIO().DisplaySize.x;
    const float height = ImGui::GetIO().DisplaySize.y;

    const float bw = al_get_bitmap_width(g_Surface);
    const float bh = al_get_bitmap_height(g_Surface);

    int op, src, dst;
    al_get_blender(&op, &src, &dst);
    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

    #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->Element))
    for (int n=0; n < cmd_lists_count; ++n)
    {
        const ImDrawList* cmd_list = cmd_lists[n];
        static ImVector<ALLEGRO_VERTEX> vertices;
        vertices.reserve(cmd_list->vtx_buffer.size());
        vertices.clear();
        for (int i = 0; i < cmd_list->vtx_buffer.size(); ++i)
        {
            ALLEGRO_VERTEX v;
            const ImDrawVert &dv = cmd_list->vtx_buffer[i];
            v.x = dv.pos.x;
            v.y = dv.pos.y;
            v.z = 0;
            v.u = dv.uv.x * bw;
            v.v = dv.uv.y * bh;
            unsigned char *c = (unsigned char*)&dv.col;
            v.color = al_map_rgba(c[0], c[1], c[2], c[3]);
            vertices.push_back(v);
        }
        int vtx_offset = 0;
        for (size_t cmd_i=0; cmd_i < cmd_list->commands.size(); ++cmd_i)
        {
            const ImDrawCmd *pcmd = &cmd_list->commands[cmd_i];
            if (pcmd->user_callback)
            {
                pcmd->user_callback(cmd_list, pcmd);
            }
            else
            {
                ALLEGRO_BITMAP *tex = (ALLEGRO_BITMAP*)pcmd->texture_id;
                al_set_clipping_rectangle(pcmd->clip_rect.x, pcmd->clip_rect.y, pcmd->clip_rect.z, pcmd->clip_rect.w);
                al_draw_prim(&vertices[0], NULL, tex, vtx_offset, vtx_offset+pcmd->vtx_count, ALLEGRO_PRIM_TRIANGLE_LIST);
            }
            vtx_offset += pcmd->vtx_count;
        }
    }
    #undef OFFSETOF

    // restore state
    al_set_blender(op, src, dst);
    al_set_clipping_rectangle(0, 0, al_get_display_width(g_Display), al_get_display_height(g_Display));
}

bool Imgui_ImplA5_CreateDeviceObjects()
{
    ImGuiIO &io = ImGui::GetIO();

    // Build texture
    unsigned char *pixels;
    int width, height;
    io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);

    // Create texture
    int flags = al_get_new_bitmap_flags();
    int fmt = al_get_new_bitmap_format();
    al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP|ALLEGRO_MIN_LINEAR|ALLEGRO_MAG_LINEAR);
    al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
    ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
    al_set_new_bitmap_flags(flags);
    al_set_new_bitmap_format(fmt);
    if (!img)
        return false;

    ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
    if (!locked_img)
    {
        al_destroy_bitmap(img);
        return false;
    }
    memcpy(locked_img->data, pixels, sizeof(int)*width*height);
    al_unlock_bitmap(img);

    // Convert software texture to hardware texture.
    ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
    al_destroy_bitmap(img);
    if (!cloned_img)
        return false;

    // Store our identifier
    io.Fonts->TexID = (void*)cloned_img;
    g_Surface = cloned_img;

    // Cleanup (don't clear the input data if you want to append new fonts later)
    io.Fonts->ClearInputData();
    io.Fonts->ClearTexData();

    return true;
}

void ImGui_ImplA5_InvalidateDeviceObjects()
{
    if (g_Surface)
    {
        al_destroy_bitmap(g_Surface);
        ImGui::GetIO().Fonts->TexID = NULL;
        g_Surface = NULL;
    }
}

bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
    g_Display = display;

    ImGuiIO& io = ImGui::GetIO();
    io.KeyMap[ImGuiKey_Tab] = ALLEGRO_KEY_TAB;
    io.KeyMap[ImGuiKey_LeftArrow] = ALLEGRO_KEY_LEFT;
    io.KeyMap[ImGuiKey_RightArrow] = ALLEGRO_KEY_RIGHT;
    io.KeyMap[ImGuiKey_UpArrow] = ALLEGRO_KEY_UP;
    io.KeyMap[ImGuiKey_DownArrow] = ALLEGRO_KEY_DOWN;
    io.KeyMap[ImGuiKey_Home] = ALLEGRO_KEY_HOME;
    io.KeyMap[ImGuiKey_End] = ALLEGRO_KEY_END;
    io.KeyMap[ImGuiKey_Delete] = ALLEGRO_KEY_DELETE;
    io.KeyMap[ImGuiKey_Backspace] = ALLEGRO_KEY_BACKSPACE;
    io.KeyMap[ImGuiKey_Enter] = ALLEGRO_KEY_ENTER;
    io.KeyMap[ImGuiKey_Escape] = ALLEGRO_KEY_ESCAPE;
    io.KeyMap[ImGuiKey_A] = ALLEGRO_KEY_A;
    io.KeyMap[ImGuiKey_C] = ALLEGRO_KEY_C;
    io.KeyMap[ImGuiKey_V] = ALLEGRO_KEY_V;
    io.KeyMap[ImGuiKey_X] = ALLEGRO_KEY_X;
    io.KeyMap[ImGuiKey_Y] = ALLEGRO_KEY_Y;
    io.KeyMap[ImGuiKey_Z] = ALLEGRO_KEY_Z;

    io.RenderDrawListsFn = ImGui_ImplA5_RenderDrawLists;
#ifdef _WIN32
    io.ImeWindowHandle = al_get_win_window_handle(g_Display);
#endif

    return true;
}

void ImGui_ImplA5_Shutdown()
{
    ImGui_ImplA5_InvalidateDeviceObjects();
    ImGui::Shutdown();
}

bool ImGui_ImplA5_ProcessEvent(ALLEGRO_EVENT *ev)
{
    ImGuiIO &io = ImGui::GetIO();

    switch (ev->type)
    {
    case ALLEGRO_EVENT_MOUSE_AXES:
        io.MouseWheel += ev->mouse.dz;
        return true;
    case ALLEGRO_EVENT_KEY_CHAR:
        if (ev->keyboard.display == g_Display)
        {
            io.KeysDown[ev->keyboard.keycode] = true;
            if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
                io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
        }
        return true;
    case ALLEGRO_EVENT_KEY_UP:
        if (ev->keyboard.display == g_Display)
            io.KeysDown[ev->keyboard.keycode] = false;
        return true;
    }
    return false;
}

void ImGui_ImplA5_NewFrame()
{
    if (!g_Surface)
        Imgui_ImplA5_CreateDeviceObjects();

    ImGuiIO &io = ImGui::GetIO();

    // Setup display size (every frame to accommodate for window resizing)
    int w, h;
    w = al_get_display_width(g_Display);
    h = al_get_display_height(g_Display);
    io.DisplaySize = ImVec2((float)w, (float)h);

    // Setup time step
    double current_time = al_get_time();
    io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f);
    g_Time = current_time;

    // Setup inputs
    ALLEGRO_KEYBOARD_STATE keys;
    al_get_keyboard_state(&keys);
    io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEYMOD_CTRL);
    io.KeyShift = al_key_down(&keys, ALLEGRO_KEYMOD_SHIFT);
    io.KeyAlt = al_key_down(&keys, ALLEGRO_KEYMOD_ALT);

    ALLEGRO_MOUSE_STATE mouse;
    if (keys.display == g_Display)
    {
        al_get_mouse_state(&mouse);
        io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
    }
    else
    {
        io.MousePos = ImVec2(-1, -1);
    }

    al_get_mouse_state(&mouse);
    io.MouseDown[0] = mouse.buttons & (1 << 0);
    io.MouseDown[1] = mouse.buttons & (1 << 1);
    io.MouseDown[2] = mouse.buttons & (1 << 2);

    // Start the frame
    ImGui::NewFrame();
}
<commit_msg>Allegro 5 example: fixed key modifiers, keyboard input, clipping, added pagedown/pageup.<commit_after>// ImGui Allegro 5 bindings
// https://github.com/ocornut/imgui
// by @birthggd, public domain

#include <stdint.h>     // uint64_t
#include <cstring>      // memcpy
#include <imgui.h>
#include "imgui_impl_a5.h"
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>

#ifdef _WIN32
#include <allegro5/allegro_windows.h>
#endif

// Data
static ALLEGRO_DISPLAY* g_Display = NULL;
static ALLEGRO_BITMAP*  g_Surface = NULL;
static double           g_Time = 0.0;

static void ImGui_ImplA5_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
    const float width = ImGui::GetIO().DisplaySize.x;
    const float height = ImGui::GetIO().DisplaySize.y;

    const float bw = al_get_bitmap_width(g_Surface);
    const float bh = al_get_bitmap_height(g_Surface);

    int op, src, dst;
    al_get_blender(&op, &src, &dst);
    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

    #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->Element))
    for (int n=0; n < cmd_lists_count; ++n)
    {
        const ImDrawList* cmd_list = cmd_lists[n];
        static ImVector<ALLEGRO_VERTEX> vertices;
        vertices.reserve(cmd_list->vtx_buffer.size());
        vertices.clear();
        for (int i = 0; i < cmd_list->vtx_buffer.size(); ++i)
        {
            ALLEGRO_VERTEX v;
            const ImDrawVert &dv = cmd_list->vtx_buffer[i];
            v.x = dv.pos.x;
            v.y = dv.pos.y;
            v.z = 0;
            v.u = dv.uv.x * bw;
            v.v = dv.uv.y * bh;
            unsigned char *c = (unsigned char*)&dv.col;
            v.color = al_map_rgba(c[0], c[1], c[2], c[3]);
            vertices.push_back(v);
        }
        int vtx_offset = 0;
        for (size_t cmd_i=0; cmd_i < cmd_list->commands.size(); ++cmd_i)
        {
            const ImDrawCmd *pcmd = &cmd_list->commands[cmd_i];
            if (pcmd->user_callback)
            {
                pcmd->user_callback(cmd_list, pcmd);
            }
            else
            {
                ALLEGRO_BITMAP *tex = (ALLEGRO_BITMAP*)pcmd->texture_id;
                al_set_clipping_rectangle(pcmd->clip_rect.x, pcmd->clip_rect.y, pcmd->clip_rect.z-pcmd->clip_rect.x, pcmd->clip_rect.w-pcmd->clip_rect.y);
                al_draw_prim(&vertices[0], NULL, tex, vtx_offset, vtx_offset+pcmd->vtx_count, ALLEGRO_PRIM_TRIANGLE_LIST);
            }
            vtx_offset += pcmd->vtx_count;
        }
    }
    #undef OFFSETOF

    // restore state
    al_set_blender(op, src, dst);
    al_set_clipping_rectangle(0, 0, al_get_display_width(g_Display), al_get_display_height(g_Display));
}

bool Imgui_ImplA5_CreateDeviceObjects()
{
    ImGuiIO &io = ImGui::GetIO();

    // Build texture
    unsigned char *pixels;
    int width, height;
    io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);

    // Create texture
    int flags = al_get_new_bitmap_flags();
    int fmt = al_get_new_bitmap_format();
    al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP|ALLEGRO_MIN_LINEAR|ALLEGRO_MAG_LINEAR);
    al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
    ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
    al_set_new_bitmap_flags(flags);
    al_set_new_bitmap_format(fmt);
    if (!img)
        return false;

    ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
    if (!locked_img)
    {
        al_destroy_bitmap(img);
        return false;
    }
    memcpy(locked_img->data, pixels, sizeof(int)*width*height);
    al_unlock_bitmap(img);

    // Convert software texture to hardware texture.
    ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
    al_destroy_bitmap(img);
    if (!cloned_img)
        return false;

    // Store our identifier
    io.Fonts->TexID = (void*)cloned_img;
    g_Surface = cloned_img;

    // Cleanup (don't clear the input data if you want to append new fonts later)
    io.Fonts->ClearInputData();
    io.Fonts->ClearTexData();

    return true;
}

void ImGui_ImplA5_InvalidateDeviceObjects()
{
    if (g_Surface)
    {
        al_destroy_bitmap(g_Surface);
        ImGui::GetIO().Fonts->TexID = NULL;
        g_Surface = NULL;
    }
}

bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
    g_Display = display;

    ImGuiIO& io = ImGui::GetIO();
    io.KeyMap[ImGuiKey_Tab] = ALLEGRO_KEY_TAB;
    io.KeyMap[ImGuiKey_LeftArrow] = ALLEGRO_KEY_LEFT;
    io.KeyMap[ImGuiKey_RightArrow] = ALLEGRO_KEY_RIGHT;
    io.KeyMap[ImGuiKey_UpArrow] = ALLEGRO_KEY_UP;
    io.KeyMap[ImGuiKey_DownArrow] = ALLEGRO_KEY_DOWN;
    io.KeyMap[ImGuiKey_PageUp] = ALLEGRO_KEY_PGUP;
    io.KeyMap[ImGuiKey_PageDown] = ALLEGRO_KEY_PGDN;
    io.KeyMap[ImGuiKey_Home] = ALLEGRO_KEY_HOME;
    io.KeyMap[ImGuiKey_End] = ALLEGRO_KEY_END;
    io.KeyMap[ImGuiKey_Delete] = ALLEGRO_KEY_DELETE;
    io.KeyMap[ImGuiKey_Backspace] = ALLEGRO_KEY_BACKSPACE;
    io.KeyMap[ImGuiKey_Enter] = ALLEGRO_KEY_ENTER;
    io.KeyMap[ImGuiKey_Escape] = ALLEGRO_KEY_ESCAPE;
    io.KeyMap[ImGuiKey_A] = ALLEGRO_KEY_A;
    io.KeyMap[ImGuiKey_C] = ALLEGRO_KEY_C;
    io.KeyMap[ImGuiKey_V] = ALLEGRO_KEY_V;
    io.KeyMap[ImGuiKey_X] = ALLEGRO_KEY_X;
    io.KeyMap[ImGuiKey_Y] = ALLEGRO_KEY_Y;
    io.KeyMap[ImGuiKey_Z] = ALLEGRO_KEY_Z;

    io.RenderDrawListsFn = ImGui_ImplA5_RenderDrawLists;
#ifdef _WIN32
    io.ImeWindowHandle = al_get_win_window_handle(g_Display);
#endif

    return true;
}

void ImGui_ImplA5_Shutdown()
{
    ImGui_ImplA5_InvalidateDeviceObjects();
    ImGui::Shutdown();
}

bool ImGui_ImplA5_ProcessEvent(ALLEGRO_EVENT *ev)
{
    ImGuiIO &io = ImGui::GetIO();

    switch (ev->type)
    {
    case ALLEGRO_EVENT_MOUSE_AXES:
        io.MouseWheel += ev->mouse.dz;
        return true;
    case ALLEGRO_EVENT_KEY_CHAR:
        if (ev->keyboard.display == g_Display)
            if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
                io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
        return true;
    case ALLEGRO_EVENT_KEY_DOWN:
    case ALLEGRO_EVENT_KEY_UP:
        if (ev->keyboard.display == g_Display)
            io.KeysDown[ev->keyboard.keycode] = (ev->type == ALLEGRO_EVENT_KEY_DOWN);
        return true;
    }
    return false;
}

void ImGui_ImplA5_NewFrame()
{
    if (!g_Surface)
        Imgui_ImplA5_CreateDeviceObjects();

    ImGuiIO &io = ImGui::GetIO();

    // Setup display size (every frame to accommodate for window resizing)
    int w, h;
    w = al_get_display_width(g_Display);
    h = al_get_display_height(g_Display);
    io.DisplaySize = ImVec2((float)w, (float)h);

    // Setup time step
    double current_time = al_get_time();
    io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f);
    g_Time = current_time;

    // Setup inputs
    ALLEGRO_KEYBOARD_STATE keys;
    al_get_keyboard_state(&keys);
    io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
    io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
    io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);

    ALLEGRO_MOUSE_STATE mouse;
    if (keys.display == g_Display)
    {
        al_get_mouse_state(&mouse);
        io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
    }
    else
    {
        io.MousePos = ImVec2(-1, -1);
    }

    al_get_mouse_state(&mouse);
    io.MouseDown[0] = mouse.buttons & (1 << 0);
    io.MouseDown[1] = mouse.buttons & (1 << 1);
    io.MouseDown[2] = mouse.buttons & (1 << 2);

    // Start the frame
    ImGui::NewFrame();
}
<|endoftext|>


<commit_before>#ifndef DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_DEFAULT_HH
#define DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_DEFAULT_HH

#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>
#include <dune/common/shared_ptr.hh>

#include <dune/grid/io/file/vtk/function.hh>

#include "local.hh"

namespace Dune {
namespace Detailed {
namespace Discretizations {
namespace DiscreteFunction {

template< class DiscreteFunctionSpaceImp, class VectorImp >
class DefaultConst;

template< class DiscreteFunctionSpaceImp, class VectorImp >
class Default
  : public Dune::VTKFunction< typename DiscreteFunctionSpaceImp::GridViewType >
{
private:
  typedef Dune::VTKFunction< typename DiscreteFunctionSpaceImp::GridViewType > BaseType;

public:
  typedef DiscreteFunctionSpaceImp DiscreteFunctionSpaceType;

  typedef VectorImp VectorType;

  typedef Default< DiscreteFunctionSpaceType, VectorType > ThisType;

  typedef DefaultConst< DiscreteFunctionSpaceType, VectorType > ConstType;

  typedef typename DiscreteFunctionSpaceType::GridViewType::template Codim< 0 >::Iterator::Entity EntityType;

  static const int polOrder = DiscreteFunctionSpaceType::polynomialOrder;

  typedef Dune::Detailed::Discretizations::DiscreteFunction::LocalConst< ThisType > ConstLocalFunctionType;

  typedef Dune::Detailed::Discretizations::DiscreteFunction::Local< ThisType > LocalFunctionType;

  typedef typename DiscreteFunctionSpaceType::FunctionSpaceType FunctionSpaceType;

  typedef typename FunctionSpaceType::DomainType DomainType;

  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;

  typedef typename FunctionSpaceType::RangeType RangeType;

  static const int dimDomain = DiscreteFunctionSpaceType::dimDomain;

  static const int dimRange = DiscreteFunctionSpaceType::dimRange;

  typedef typename VectorType::size_type size_type;

  Default(const DiscreteFunctionSpaceType& _space,
          Dune::shared_ptr< VectorType > _vector,
          const std::string _name = "discrete_function")
    : BaseType(),
      space_(_space)
    , vector_(_vector)
    , name_(_name)
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
  }

  Default(const DiscreteFunctionSpaceType& _space,
          const std::string _name = "discrete_function")
    : BaseType(),
      space_(_space)
    , vector_(new VectorType(space_.map().size()))
    , name_(_name)
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
  }

  operator ConstType() const
  {
    return ConstType(space_, vector_, name_);
  }

private:
  Default(const ThisType&);
  ThisType& operator=(const ThisType&);

public:
  const DiscreteFunctionSpaceType& space() const
  {
    return space_;
  }

  virtual std::string name() const
  {
    return name_;
  }

  ConstLocalFunctionType localFunction(const EntityType& entity) const
  {
    return ConstLocalFunctionType(*this, entity);
  }

  LocalFunctionType localFunction(const EntityType& entity)
  {
    return LocalFunctionType(*this, entity);
  }

  Dune::shared_ptr< VectorType > vector()
  {
    return vector_;
  }

  const Dune::shared_ptr< const VectorType > vector() const
  {
    return vector_;
  }

  /**
      @name Convenience methods
      @{
   **/
  size_type size() const
  {
    return vector_->size();
  }
  /**
      @}
   **/

  void clear()
  {
    const RangeFieldType zero(0);
    for (size_type ii = 0; ii < vector_->size(); ++ii)
      vector_->set(ii, zero);
  }

  /**
      @name Methods to comply with the Dune::VTKFunction interface
      @{
   **/
  virtual int ncomps() const
  {
    return dimRange;
  }

  virtual RangeFieldType evaluate(int component, const EntityType& entity, const DomainType& x) const
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
    RangeType ret(0.0);
    localFunction(entity).evaluate(x, ret);
    return ret[component];
  }
  /**
      @}
     **/

private:
  const DiscreteFunctionSpaceType& space_;
  Dune::shared_ptr< VectorType > vector_;
  const std::string name_;
}; // class Defaul

template< class DiscreteFunctionSpaceImp, class VectorImp >
class DefaultConst
  : public Dune::VTKFunction< typename DiscreteFunctionSpaceImp::GridViewType >
{
private:
  typedef Dune::VTKFunction< typename DiscreteFunctionSpaceImp::GridViewType > BaseType;

public:
  typedef DiscreteFunctionSpaceImp DiscreteFunctionSpaceType;

  typedef VectorImp VectorType;

  typedef DefaultConst< DiscreteFunctionSpaceType, VectorType > ThisType;

  typedef Default< DiscreteFunctionSpaceType, VectorType > NonConstType;

  typedef typename DiscreteFunctionSpaceType::GridViewType::template Codim< 0 >::Iterator::Entity EntityType;

  static const int polOrder = DiscreteFunctionSpaceType::polynomialOrder;

  typedef Dune::Detailed::Discretizations::DiscreteFunction::LocalConst< ThisType > ConstLocalFunctionType;

  typedef typename DiscreteFunctionSpaceType::FunctionSpaceType FunctionSpaceType;

  typedef typename FunctionSpaceType::DomainType DomainType;

  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;

  typedef typename FunctionSpaceType::RangeType RangeType;

  static const int dimDomain = DiscreteFunctionSpaceType::dimDomain;

  static const int dimRange = DiscreteFunctionSpaceType::dimRange;

  typedef typename VectorType::size_type size_type;

  DefaultConst(const DiscreteFunctionSpaceType& _space,
               const Dune::shared_ptr< const VectorType > _vector,
               const std::string _name = "discrete_function")
    : BaseType()
    , space_(_space)
    , name_(_name)
    , vector_(_vector)
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
  }

  DefaultConst(const NonConstType& _nonConstOther)
    : BaseType()
    , space_(_nonConstOther.space())
    , name_(_nonConstOther.name())
    , vector_(_nonConstOther.vector())
  {}

private:
  DefaultConst(const ThisType&);
  ThisType& operator=(const ThisType&);

public:
  const DiscreteFunctionSpaceType& space() const
  {
    return space_;
  }

  virtual std::string name() const
  {
    return name_;
  }

  ConstLocalFunctionType localFunction(const EntityType& entity) const
  {
    return ConstLocalFunctionType(*this, entity);
  }

  const Dune::shared_ptr< const VectorType > vector() const
  {
    return vector_;
  }

  /**
      @name Convenience methods
      @{
   **/
  size_type size() const
  {
    return vector_->size();
  }
  /**
      @}
   **/

  /**
      @name Methods to comply with the Dune::VTKFunction interface
      @{
   **/
  virtual int ncomps() const
  {
    return dimRange;
  }

  virtual RangeFieldType evaluate(int component, const EntityType& entity, const DomainType& x) const
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
    RangeType ret(0.0);
    localFunction(entity).evaluate(x, ret);
    return ret[component];
  }
  /**
      @}
     **/

private:
  const DiscreteFunctionSpaceType& space_;
  const std::string name_;
  const Dune::shared_ptr< const VectorType > vector_;
}; // class DefaulConst

} // namespace DiscreteFunction
} // namespace Discretizations
} // namespace Detailed
} // namespace Dune

#endif // DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_DEFAULT_HH
<commit_msg>[discretefunction.default] added createConst()<commit_after>#ifndef DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_DEFAULT_HH
#define DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_DEFAULT_HH

#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>
#include <dune/common/shared_ptr.hh>

#include <dune/grid/io/file/vtk/function.hh>

#include "local.hh"

namespace Dune {
namespace Detailed {
namespace Discretizations {
namespace DiscreteFunction {

template< class DiscreteFunctionSpaceImp, class VectorImp >
class DefaultConst;

template< class DiscreteFunctionSpaceImp, class VectorImp >
class Default
  : public Dune::VTKFunction< typename DiscreteFunctionSpaceImp::GridViewType >
{
private:
  typedef Dune::VTKFunction< typename DiscreteFunctionSpaceImp::GridViewType > BaseType;

public:
  typedef DiscreteFunctionSpaceImp DiscreteFunctionSpaceType;

  typedef VectorImp VectorType;

  typedef Default< DiscreteFunctionSpaceType, VectorType > ThisType;

  typedef DefaultConst< DiscreteFunctionSpaceType, VectorType > ConstType;

  typedef typename DiscreteFunctionSpaceType::GridViewType::template Codim< 0 >::Iterator::Entity EntityType;

  static const int polOrder = DiscreteFunctionSpaceType::polynomialOrder;

  typedef Dune::Detailed::Discretizations::DiscreteFunction::LocalConst< ThisType > ConstLocalFunctionType;

  typedef Dune::Detailed::Discretizations::DiscreteFunction::Local< ThisType > LocalFunctionType;

  typedef typename DiscreteFunctionSpaceType::FunctionSpaceType FunctionSpaceType;

  typedef typename FunctionSpaceType::DomainType DomainType;

  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;

  typedef typename FunctionSpaceType::RangeType RangeType;

  static const int dimDomain = DiscreteFunctionSpaceType::dimDomain;

  static const int dimRange = DiscreteFunctionSpaceType::dimRange;

  typedef typename VectorType::size_type size_type;

  Default(const DiscreteFunctionSpaceType& _space,
          Dune::shared_ptr< VectorType > _vector,
          const std::string _name = "discrete_function")
    : BaseType(),
      space_(_space)
    , vector_(_vector)
    , name_(_name)
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
  }

  Default(const DiscreteFunctionSpaceType& _space,
          const std::string _name = "discrete_function")
    : BaseType(),
      space_(_space)
    , vector_(new VectorType(space_.map().size()))
    , name_(_name)
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
  }

  Dune::shared_ptr< const ConstType > createConst() const
  {
    Dune::shared_ptr< const ConstType > ret(new ConstType(*this));
    return ret;
  }

private:
  Default(const ThisType&);
  ThisType& operator=(const ThisType&);

public:
  const DiscreteFunctionSpaceType& space() const
  {
    return space_;
  }

  virtual std::string name() const
  {
    return name_;
  }

  ConstLocalFunctionType localFunction(const EntityType& entity) const
  {
    return ConstLocalFunctionType(*this, entity);
  }

  LocalFunctionType localFunction(const EntityType& entity)
  {
    return LocalFunctionType(*this, entity);
  }

  Dune::shared_ptr< VectorType > vector()
  {
    return vector_;
  }

  const Dune::shared_ptr< const VectorType > vector() const
  {
    return vector_;
  }

  /**
      @name Convenience methods
      @{
   **/
  size_type size() const
  {
    return vector_->size();
  }
  /**
      @}
   **/

  void clear()
  {
    const RangeFieldType zero(0);
    for (size_type ii = 0; ii < vector_->size(); ++ii)
      vector_->set(ii, zero);
  }

  /**
      @name Methods to comply with the Dune::VTKFunction interface
      @{
   **/
  virtual int ncomps() const
  {
    return dimRange;
  }

  virtual RangeFieldType evaluate(int component, const EntityType& entity, const DomainType& x) const
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
    RangeType ret(0.0);
    localFunction(entity).evaluate(x, ret);
    return ret[component];
  }
  /**
      @}
     **/

private:
  const DiscreteFunctionSpaceType& space_;
  Dune::shared_ptr< VectorType > vector_;
  const std::string name_;
}; // class Defaul

template< class DiscreteFunctionSpaceImp, class VectorImp >
class DefaultConst
  : public Dune::VTKFunction< typename DiscreteFunctionSpaceImp::GridViewType >
{
private:
  typedef Dune::VTKFunction< typename DiscreteFunctionSpaceImp::GridViewType > BaseType;

public:
  typedef DiscreteFunctionSpaceImp DiscreteFunctionSpaceType;

  typedef VectorImp VectorType;

  typedef DefaultConst< DiscreteFunctionSpaceType, VectorType > ThisType;

  typedef Default< DiscreteFunctionSpaceType, VectorType > NonConstType;

  typedef typename DiscreteFunctionSpaceType::GridViewType::template Codim< 0 >::Iterator::Entity EntityType;

  static const int polOrder = DiscreteFunctionSpaceType::polynomialOrder;

  typedef Dune::Detailed::Discretizations::DiscreteFunction::LocalConst< ThisType > ConstLocalFunctionType;

  typedef typename DiscreteFunctionSpaceType::FunctionSpaceType FunctionSpaceType;

  typedef typename FunctionSpaceType::DomainType DomainType;

  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;

  typedef typename FunctionSpaceType::RangeType RangeType;

  static const int dimDomain = DiscreteFunctionSpaceType::dimDomain;

  static const int dimRange = DiscreteFunctionSpaceType::dimRange;

  typedef typename VectorType::size_type size_type;

  DefaultConst(const DiscreteFunctionSpaceType& _space,
               const Dune::shared_ptr< const VectorType > _vector,
               const std::string _name = "discrete_function")
    : BaseType()
    , space_(_space)
    , name_(_name)
    , vector_(_vector)
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
  }

  DefaultConst(const NonConstType& _nonConstOther)
    : BaseType()
    , space_(_nonConstOther.space())
    , name_(_nonConstOther.name())
    , vector_(_nonConstOther.vector())
  {}

private:
  DefaultConst(const ThisType&);
  ThisType& operator=(const ThisType&);

public:
  const DiscreteFunctionSpaceType& space() const
  {
    return space_;
  }

  virtual std::string name() const
  {
    return name_;
  }

  ConstLocalFunctionType localFunction(const EntityType& entity) const
  {
    return ConstLocalFunctionType(*this, entity);
  }

  const Dune::shared_ptr< const VectorType > vector() const
  {
    return vector_;
  }

  /**
      @name Convenience methods
      @{
   **/
  size_type size() const
  {
    return vector_->size();
  }
  /**
      @}
   **/

  /**
      @name Methods to comply with the Dune::VTKFunction interface
      @{
   **/
  virtual int ncomps() const
  {
    return dimRange;
  }

  virtual RangeFieldType evaluate(int component, const EntityType& entity, const DomainType& x) const
  {
    assert(vector_->size() == space_.map().size() && "Given vector has wrong size!");
    RangeType ret(0.0);
    localFunction(entity).evaluate(x, ret);
    return ret[component];
  }
  /**
      @}
     **/

private:
  const DiscreteFunctionSpaceType& space_;
  const std::string name_;
  const Dune::shared_ptr< const VectorType > vector_;
}; // class DefaulConst

} // namespace DiscreteFunction
} // namespace Discretizations
} // namespace Detailed
} // namespace Dune

#endif // DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_DEFAULT_HH
<|endoftext|>


<commit_before>// This may look like C code, but it is really -*- C++ -*-
//
// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
//
// Pixels Implementation
//

#define MAGICKCORE_IMPLEMENTATION  1
#define MAGICK_PLUSPLUS_IMPLEMENTATION 1

#include <cstring>
#include "Magick++/Include.h"
#include <string> // This is here to compile with Visual C++
#include "Magick++/Thread.h"
#include "Magick++/Exception.h"
#include "Magick++/Pixels.h"

Magick::Pixels::Pixels(Magick::Image &image_)
  : _image(image_),
    _view(AcquireVirtualCacheView(_image.image(),&_exception)),
    _x(0),
    _y(0),
    _columns(0),
    _rows(0)
{
  GetExceptionInfo(&_exception);

  if (!_view)
    throwExceptionExplicit(OptionError,"Empty view detected.");
}

Magick::Pixels::~Pixels(void)
{
  if (_view)
    _view=DestroyCacheView(_view);

  (void) DestroyExceptionInfo(&_exception);
}

Magick::Quantum* Magick::Pixels::get(const ssize_t x_,const ssize_t y_,
  const size_t columns_,const size_t rows_)
{
  _x=x_;
  _y=y_;
  _columns=columns_;
  _rows=rows_;

  Quantum* pixels=GetCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
    &_exception);

  if (!pixels)
    throwException(_exception);

  return pixels;
}

const Magick::Quantum* Magick::Pixels::getConst(const ssize_t x_,
  const ssize_t y_,const size_t columns_,const size_t rows_)
{
  _x=x_;
  _y=y_;
  _columns=columns_;
  _rows=rows_;

  const Quantum* pixels=GetCacheViewVirtualPixels(_view,x_,y_,columns_,rows_,
    &_exception);

  if (!pixels)
    throwException(_exception);

  return pixels;
}

ssize_t Magick::Pixels::offset(PixelChannel channel) const
{
  if (_image.constImage()->channel_map[channel].traits == UndefinedPixelTrait)
    return -1;
  return _image.constImage()->channel_map[channel].offset;
}

Magick::Quantum* Magick::Pixels::set(const ssize_t x_,const ssize_t y_,
  const size_t columns_,const size_t rows_)
{
  _x=x_;
  _y=y_;
  _columns=columns_;
  _rows=rows_;

  Quantum* pixels=QueueCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
    &_exception);

  if (!pixels)
    throwException(_exception);

  return pixels;
}

void Magick::Pixels::sync(void)
{
  if(!SyncCacheViewAuthenticPixels(_view,&_exception))
    throwException(_exception);
}

// Return pixel colormap index array
/*
Magick::void* Magick::Pixels::metacontent(void)
{
  void* pixel_metacontent=GetCacheViewAuthenticMetacontent(_view);

  if (!pixel_metacontent)
    _image.throwImageException();

  return pixel_metacontent;
}
*/

Magick::PixelData::PixelData(Magick::Image &image_,std::string map_,
  const StorageType type_)
{
  init(image_,0,0,image_.columns(),image_.rows(),map_,type_);
}

Magick::PixelData::PixelData(Magick::Image &image_,const ::ssize_t x_,
  const ::ssize_t y_,const size_t width_,const size_t height_,std::string map_,
  const StorageType type_)
{
  init(image_,x_,y_,width_,height_,map_,type_);
}

Magick::PixelData::~PixelData(void)
{
  relinquish();
}

const void *Magick::PixelData::data(void) const
{
  return(_data);
}

const ::ssize_t Magick::PixelData::length(void) const
{
  return(_length);
}

const ::ssize_t Magick::PixelData::size(void) const
{
  return(_size);
}

void Magick::PixelData::init(Magick::Image &image_,const ::ssize_t x_,
  const ::ssize_t y_,const size_t width_,const size_t height_,
  std::string map_,const StorageType type_)
{
  size_t
    size;

  _data=(void *) NULL;
  _length=0;
  _size=0;
  if ((x_ < 0) || (width_ < 0) || (y_ < 0) || (height_ < 0) ||
      (x_ > image_.columns()) || (width_ + x_ > image_.columns()) ||
      (y_ > image_.rows()) || (height_ + y_ > image_.rows()) ||
      (map_.length() == 0))
    return;

  switch(type_)
  {
    case CharPixel:
      size=sizeof(unsigned char);
      break;
    case DoublePixel:
      size=sizeof(double);
      break;
    case FloatPixel:
      size=sizeof(float);
      break;
    case LongPixel:
      size=sizeof(unsigned int);
      break;
    case LongLongPixel:
      size=sizeof(MagickSizeType);
      break;
    case QuantumPixel:
      size=sizeof(Quantum);
      break;
    case ShortPixel:
      size=sizeof(unsigned short);
      break;
    default:
      throwExceptionExplicit(OptionError,"Invalid type");
      return;
  }

  _length=width_*height_*map_.length();
  _size=_length*size;
  _data=AcquireMagickMemory(_size);

  GetPPException;
  MagickCore::ExportImagePixels(image_.constImage(),x_,y_,width_,height_,
    map_.c_str(),type_,_data,&exceptionInfo);
  if (exceptionInfo.severity != UndefinedException)
    relinquish();
  ThrowPPException;
}

void Magick::PixelData::relinquish(void) throw()
{
  if (_data != (void *)NULL)
    _data=RelinquishMagickMemory(_data);
  _length=0;
  _size=0;
}<commit_msg>Build fix.<commit_after>// This may look like C code, but it is really -*- C++ -*-
//
// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
//
// Pixels Implementation
//

#define MAGICKCORE_IMPLEMENTATION  1
#define MAGICK_PLUSPLUS_IMPLEMENTATION 1

#include <cstring>
#include "Magick++/Include.h"
#include <string> // This is here to compile with Visual C++
#include "Magick++/Thread.h"
#include "Magick++/Exception.h"
#include "Magick++/Pixels.h"

Magick::Pixels::Pixels(Magick::Image &image_)
  : _image(image_),
    _view(AcquireVirtualCacheView(_image.image(),&_exception)),
    _x(0),
    _y(0),
    _columns(0),
    _rows(0)
{
  GetExceptionInfo(&_exception);

  if (!_view)
    throwExceptionExplicit(OptionError,"Empty view detected.");
}

Magick::Pixels::~Pixels(void)
{
  if (_view)
    _view=DestroyCacheView(_view);

  (void) DestroyExceptionInfo(&_exception);
}

Magick::Quantum* Magick::Pixels::get(const ssize_t x_,const ssize_t y_,
  const size_t columns_,const size_t rows_)
{
  _x=x_;
  _y=y_;
  _columns=columns_;
  _rows=rows_;

  Quantum* pixels=GetCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
    &_exception);

  if (!pixels)
    throwException(_exception);

  return pixels;
}

const Magick::Quantum* Magick::Pixels::getConst(const ssize_t x_,
  const ssize_t y_,const size_t columns_,const size_t rows_)
{
  _x=x_;
  _y=y_;
  _columns=columns_;
  _rows=rows_;

  const Quantum* pixels=GetCacheViewVirtualPixels(_view,x_,y_,columns_,rows_,
    &_exception);

  if (!pixels)
    throwException(_exception);

  return pixels;
}

ssize_t Magick::Pixels::offset(PixelChannel channel) const
{
  if (_image.constImage()->channel_map[channel].traits == UndefinedPixelTrait)
    return -1;
  return _image.constImage()->channel_map[channel].offset;
}

Magick::Quantum* Magick::Pixels::set(const ssize_t x_,const ssize_t y_,
  const size_t columns_,const size_t rows_)
{
  _x=x_;
  _y=y_;
  _columns=columns_;
  _rows=rows_;

  Quantum* pixels=QueueCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
    &_exception);

  if (!pixels)
    throwException(_exception);

  return pixels;
}

void Magick::Pixels::sync(void)
{
  if(!SyncCacheViewAuthenticPixels(_view,&_exception))
    throwException(_exception);
}

// Return pixel colormap index array
/*
Magick::void* Magick::Pixels::metacontent(void)
{
  void* pixel_metacontent=GetCacheViewAuthenticMetacontent(_view);

  if (!pixel_metacontent)
    _image.throwImageException();

  return pixel_metacontent;
}
*/

Magick::PixelData::PixelData(Magick::Image &image_,std::string map_,
  const StorageType type_)
{
  init(image_,0,0,image_.columns(),image_.rows(),map_,type_);
}

Magick::PixelData::PixelData(Magick::Image &image_,const ::ssize_t x_,
  const ::ssize_t y_,const size_t width_,const size_t height_,std::string map_,
  const StorageType type_)
{
  init(image_,x_,y_,width_,height_,map_,type_);
}

Magick::PixelData::~PixelData(void)
{
  relinquish();
}

const void *Magick::PixelData::data(void) const
{
  return(_data);
}

const ::ssize_t Magick::PixelData::length(void) const
{
  return(_length);
}

const ::ssize_t Magick::PixelData::size(void) const
{
  return(_size);
}

void Magick::PixelData::init(Magick::Image &image_,const ::ssize_t x_,
  const ::ssize_t y_,const size_t width_,const size_t height_,
  std::string map_,const StorageType type_)
{
  size_t
    size;

  _data=(void *) NULL;
  _length=0;
  _size=0;
  if ((x_ < 0) || (width_ < 0) || (y_ < 0) || (height_ < 0) ||
      (x_ > image_.columns()) || (width_ + x_ > image_.columns()) ||
      (y_ > image_.rows()) || (height_ + y_ > image_.rows()) ||
      (map_.length() == 0))
    return;

  switch(type_)
  {
    case CharPixel:
      size=sizeof(unsigned char);
      break;
    case DoublePixel:
      size=sizeof(double);
      break;
    case FloatPixel:
      size=sizeof(float);
      break;
    case LongPixel:
      size=sizeof(unsigned int);
      break;
    case LongLongPixel:
      size=sizeof(MagickSizeType);
      break;
    case QuantumPixel:
      size=sizeof(Quantum);
      break;
    case ShortPixel:
      size=sizeof(unsigned short);
      break;
    default:
      throwExceptionExplicit(OptionError,"Invalid type");
      return;
  }

  _length=width_*height_*map_.length();
  _size=_length*size;
  _data=AcquireMagickMemory(_size);

  GetPPException;
  MagickCore::ExportImagePixels(image_.image(),x_,y_,width_,height_,
    map_.c_str(),type_,_data,&exceptionInfo);
  if (exceptionInfo.severity != UndefinedException)
    relinquish();
  ThrowPPException;
}

void Magick::PixelData::relinquish(void) throw()
{
  if (_data != (void *)NULL)
    _data=RelinquishMagickMemory(_data);
  _length=0;
  _size=0;
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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 "CellularTests.h"
#ifdef CELLULAR_DEVICE

using namespace mbed;

static bool wait_register()
{
    tr_info("Try registering to network...");
    if (network->set_registration() != NSAPI_ERROR_OK) {
        tr_error("Network registration request failed.");
        return false;
    }

    CellularNetwork::RegistrationStatus status;
    for (int i=0; i<180; i++) {
        tr_info("Register to network %d...", i);
        for (int type = 0; type < CellularNetwork::C_MAX; type++) {
            if (network->get_registration_status((CellularNetwork::RegistrationType)type, status) ==  NSAPI_ERROR_OK) {
                tr_info("status %d...", status);
                switch (status) {
                    case CellularNetwork::RegisteredRoaming:
                    // fall-through
                    case CellularNetwork::RegisteredHomeNetwork:
                        tr_info("Registered to network.");
                        return true;
                    case CellularNetwork::RegisteredSMSOnlyRoaming:
                    // fall-through
                    case CellularNetwork::RegisteredSMSOnlyHome:
                        tr_warn("SMS only network registration!");
                        return true;
                    case CellularNetwork::RegisteredCSFBNotPreferredRoaming:
                    // fall-through
                    case CellularNetwork::RegisteredCSFBNotPreferredHome:
                        tr_warn("Not preferred network registration!");
                        return true;
                    case CellularNetwork::AttachedEmergencyOnly:
                        tr_warn("Emergency only network registration!");
                        return true;
                    case CellularNetwork::RegistrationDenied:
                        tr_warn("Network registration denied!");
                        wait(i);
                        break;
                    case CellularNetwork::NotRegistered:
                    case CellularNetwork::Unknown:
                    case CellularNetwork::SearchingNetwork:
                    default:
                        break;
                }
            }
        }
        wait(1);
    }
    return false;
}

void test_attach()
{
    tr_info("Register to network.");
    TEST_ASSERT(wait_register());
    tr_info("Attach to network.");
    nsapi_error_t err = network->set_attach();
    TEST_ASSERT(!err);
    CellularNetwork::AttachStatus status;
    err = network->get_attach(status);
    TEST_ASSERT(!err);
}

void test_connect()
{
    nsapi_error_t err = network->connect();
    TEST_ASSERT(!err);
}

void test_get_ip_address()
{
    const char *ip = network->get_ip_address();
    TEST_ASSERT(ip && ip[0]);
    tr_info("IP: %s\r\n", ip);
}

void test_disconnect()
{
    nsapi_error_t err = network->disconnect();
    TEST_ASSERT(!err);
}

#endif // CELLULAR_DEVICE
<commit_msg>Cellular tests: fixed cellular greentea tests by adding timeout as it may take time to register, attach and connect to network.<commit_after>/*
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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 "CellularTests.h"
#ifdef CELLULAR_DEVICE

using namespace mbed;

static bool wait_register()
{
    tr_info("Try registering to network...");
    if (network->set_registration() != NSAPI_ERROR_OK) {
        tr_error("Network registration request failed.");
        return false;
    }

    CellularNetwork::RegistrationStatus status;
    for (int i=0; i<180; i++) {
        tr_info("Register to network %d...", i);
        for (int type = 0; type < CellularNetwork::C_MAX; type++) {
            if (network->get_registration_status((CellularNetwork::RegistrationType)type, status) ==  NSAPI_ERROR_OK) {
                tr_info("status %d...", status);
                switch (status) {
                    case CellularNetwork::RegisteredRoaming:
                    // fall-through
                    case CellularNetwork::RegisteredHomeNetwork:
                        tr_info("Registered to network.");
                        return true;
                    case CellularNetwork::RegisteredSMSOnlyRoaming:
                    // fall-through
                    case CellularNetwork::RegisteredSMSOnlyHome:
                        tr_warn("SMS only network registration!");
                        return true;
                    case CellularNetwork::RegisteredCSFBNotPreferredRoaming:
                    // fall-through
                    case CellularNetwork::RegisteredCSFBNotPreferredHome:
                        tr_warn("Not preferred network registration!");
                        return true;
                    case CellularNetwork::AttachedEmergencyOnly:
                        tr_warn("Emergency only network registration!");
                        return true;
                    case CellularNetwork::RegistrationDenied:
                        tr_warn("Network registration denied!");
                        wait(i);
                        break;
                    case CellularNetwork::NotRegistered:
                    case CellularNetwork::Unknown:
                    case CellularNetwork::SearchingNetwork:
                    default:
                        break;
                }
            }
        }
        wait(1);
    }
    return false;
}

void test_attach()
{
    cellularDevice.set_timeout(120*1000); // 120 second timeout for at commands after power is up. It might take time to register, attach and connect
    tr_info("Register to network.");
    TEST_ASSERT(wait_register());
    tr_info("Attach to network.");
    nsapi_error_t err = network->set_attach();
    TEST_ASSERT(!err);
    CellularNetwork::AttachStatus status;
    err = network->get_attach(status);
    TEST_ASSERT(!err);
}

void test_connect()
{
    nsapi_error_t err = network->connect();
    TEST_ASSERT(!err);
}

void test_get_ip_address()
{
    const char *ip = network->get_ip_address();
    TEST_ASSERT(ip && ip[0]);
    tr_info("IP: %s\r\n", ip);
}

void test_disconnect()
{
    nsapi_error_t err = network->disconnect();
    TEST_ASSERT(!err);
}

#endif // CELLULAR_DEVICE
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */

#include <deque>
#include <cassert>
#include "halWiggleLiftover.h"
#include "halBlockMapper.h"

using namespace std;
using namespace hal;

const double WiggleLiftover::DefaultValue = 0.0;
const hal_size_t WiggleLiftover::DefaultTileSize = 10000;

WiggleLiftover::WiggleLiftover()
{

}

WiggleLiftover::~WiggleLiftover()
{

}

void WiggleLiftover::convert(AlignmentConstPtr alignment,
                             const Genome* srcGenome,
                             istream* inputFile,
                             const Genome* tgtGenome,
                             ostream* outputFile,
                             bool traverseDupes,
                             bool unique)
{
  _alignment = alignment;
  _srcGenome = srcGenome;
  _tgtGenome = tgtGenome;
  _outStream = outputFile;
  _traverseDupes = traverseDupes;
  _unique = unique;
  _srcSequence = NULL;

  if (_srcGenome->getNumTopSegments() > 0)
  {
    _segment = _srcGenome->getTopSegmentIterator();
    _lastIndex = (hal_index_t)_srcGenome->getNumTopSegments();
  }
  else
  {
    _segment = _srcGenome->getBottomSegmentIterator();
    _lastIndex = (hal_index_t)_srcGenome->getNumBottomSegments();
  }

  set<const Genome*> inputSet;
  inputSet.insert(_srcGenome);
  inputSet.insert(_tgtGenome);
  getGenomesInSpanningTree(inputSet, _tgtSet);
  _outVals.init(srcGenome->getSequenceLength(), DefaultValue, DefaultTileSize);
  scan(inputFile);
  write();
  _outVals.clear();
}

void WiggleLiftover::visitHeader()
{
  mapSegment();
  _srcSequence = _srcGenome->getSequence(_sequenceName);
  if (_srcSequence == NULL)
  {
    stringstream ss;
    ss << "Sequence " << _sequenceName << " not found in genome "
       << _srcGenome->getName();
    throw hal_exception(ss.str());
  }
}

void WiggleLiftover::visitLine()
{
  if (_srcSequence == NULL)
  {
    throw hal_exception("Missing Wig header");
  }
  hal_index_t absFirst = _first + _srcSequence->getStartPosition();
  hal_index_t absLast = _last + _srcSequence->getStartPosition();
  if (absFirst < _segment->getStartPosition() ||
      absLast > _segment->getStartPosition())
  {
    mapSegment();
  }
  CoordVal cv = {absFirst, absLast, _value};
  if (_cvals.size() > 0 && _cvals.back()._last >= absFirst)
  {
    throw hal_exception("Coordinate out of order");
  }
  _cvals.push_back(cv);
  cout << "pushing cv " << cv._first << "," <<cv._last << "," << cv._val
       << endl;
}

void WiggleLiftover::visitEOF()
{
  mapSegment();
}

void WiggleLiftover::mapSegment()
{
  if (_cvals.empty())
  {
    return;
  }
  if (_segment->getArrayIndex() == 0)
  {
    _segment->toSite(_cvals[0]._first, false);
  }
  while (_segment->getStartPosition() < _cvals[0]._first)
  {
    _segment->toRight();
  }

  while (_cvals[0]._first < _segment->getStartPosition())
  {
    assert(_segment->getArrayIndex() > 0);
    assert(_segment->getReversed() == false);
    _segment->toLeft(_cvals[0]._first);
  }
  assert(_cvals[0]._first <= _segment->getEndPosition());
  if (_cvals[0]._first > _segment->getStartPosition())
  {
    hal_offset_t so = _cvals[0]._first - _segment->getStartPosition();
    _segment->slice(so, _segment->getEndOffset());
  }
  if (_cvals.back()._last > _segment->getEndPosition())
  {
    hal_offset_t eo = _segment->getEndPosition() - _cvals.back()._last;
    _segment->slice(_segment->getStartOffset(), eo);
  }

  while (_segment->getArrayIndex() < _lastIndex &&
         _segment->getStartPosition() <= (_cvals.back()._last))
  {
    _segment->getMappedSegments(_mappedSegments, _tgtGenome, &_tgtSet,
                                _traverseDupes);
    _segment->toRight(_cvals.back()._last);
  }

  vector<MappedSegmentConstPtr> fragments;
  BlockMapper::MSSet emptySet;
  set<hal_index_t> queryCutSet;
  set<hal_index_t> targetCutSet;

  _cvIdx = 0;
  for (std::set<MappedSegmentConstPtr>::iterator i = _mappedSegments.begin();
       i != _mappedSegments.end(); ++i)
  {
    BlockMapper::extractSegment(i, emptySet, fragments, &_mappedSegments,
                                targetCutSet, queryCutSet);
    mapFragments(fragments);
  }
}

void WiggleLiftover::mapFragments(vector<MappedSegmentConstPtr>& fragments)
{
  sort(fragments.begin(), fragments.end(), MappedSegment::LessSource());

  for (size_t i = 0; i < fragments.size() && _cvIdx < _cvals.size(); ++i)
  {
    MappedSegmentConstPtr& seg = fragments[i];
    for (size_t j = 0; j < seg->getLength() && _cvIdx < _cvals.size(); ++j)
    {
      hal_index_t pos = seg->getSource()->getStartPosition() + j;
      hal_index_t mpos;
      if (seg->getReversed() == false)
      {
        mpos = seg->getStartPosition() + j;
      }
      else
      {
        mpos = seg->getEndPosition() - j;
      }
      assert(_cvals[_cvIdx]._first <= pos);
      while (_cvIdx < _cvals.size() && _cvals[_cvIdx]._last < pos)
      {
        ++_cvIdx;
      }
      if (_cvIdx < _cvals.size() && _cvals[_cvIdx]._first <= pos &&
          _cvals[_cvIdx]._last >= pos)
      {
        double val = std::max(_cvals[_cvIdx]._val, _outVals.get(mpos));
        _outVals.set(mpos, val);
      }
    }
  }
}

void WiggleLiftover::write()
{
  const Sequence* outSequence = NULL;
  hal_size_t ogSize = _tgtGenome->getSequenceLength();
  for (hal_size_t i = 0; i < _outVals.getNumTiles(); ++i)
  {
    if (_outVals.isTileEmpty(i) == false)
    {
      hal_index_t pos = i * _outVals.getTileSize();
      for (hal_size_t j = 0; pos < ogSize && j < _outVals.getTileSize(); ++j,
              ++pos)
      {
        if (outSequence == NULL || pos < outSequence->getStartPosition() ||
            pos > outSequence->getEndPosition())
        {
          outSequence = _tgtGenome->getSequenceBySite(pos);
          assert(outSequence != NULL);
          *_outStream << "fixedStep"
                      << "\tchrom=" << outSequence->getName()
                      << "\tstart=" << (pos - outSequence->getStartPosition())
                      << "\tstep=1\n";
        }
        *_outStream << _outVals.get(pos) << '\n';
      }
    }
  }
}
<commit_msg>try to fix a few bugs in the segment traversal<commit_after>/*
 * Copyright (C) 2013 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */

#include <deque>
#include <cassert>
#include "halWiggleLiftover.h"
#include "halBlockMapper.h"

using namespace std;
using namespace hal;

const double WiggleLiftover::DefaultValue = 0.0;
const hal_size_t WiggleLiftover::DefaultTileSize = 10000;

WiggleLiftover::WiggleLiftover()
{

}

WiggleLiftover::~WiggleLiftover()
{

}

void WiggleLiftover::convert(AlignmentConstPtr alignment,
                             const Genome* srcGenome,
                             istream* inputFile,
                             const Genome* tgtGenome,
                             ostream* outputFile,
                             bool traverseDupes,
                             bool unique)
{
  _alignment = alignment;
  _srcGenome = srcGenome;
  _tgtGenome = tgtGenome;
  _outStream = outputFile;
  _traverseDupes = traverseDupes;
  _unique = unique;
  _srcSequence = NULL;

  if (_srcGenome->getNumTopSegments() > 0)
  {
    _segment = _srcGenome->getTopSegmentIterator();
    _lastIndex = (hal_index_t)_srcGenome->getNumTopSegments();
  }
  else
  {
    _segment = _srcGenome->getBottomSegmentIterator();
    _lastIndex = (hal_index_t)_srcGenome->getNumBottomSegments();
  }

  set<const Genome*> inputSet;
  inputSet.insert(_srcGenome);
  inputSet.insert(_tgtGenome);
  getGenomesInSpanningTree(inputSet, _tgtSet);
  _outVals.init(srcGenome->getSequenceLength(), DefaultValue, DefaultTileSize);
  scan(inputFile);
  write();
  _outVals.clear();
}

void WiggleLiftover::visitHeader()
{
  mapSegment();
  _srcSequence = _srcGenome->getSequence(_sequenceName);
  if (_srcSequence == NULL)
  {
    stringstream ss;
    ss << "Sequence " << _sequenceName << " not found in genome "
       << _srcGenome->getName();
    throw hal_exception(ss.str());
  }
}

void WiggleLiftover::visitLine()
{
  if (_srcSequence == NULL)
  {
    throw hal_exception("Missing Wig header");
  }
  hal_index_t absFirst = _first + _srcSequence->getStartPosition();
  hal_index_t absLast = _last + _srcSequence->getStartPosition();
  _segment->slice(0,0);
  if (absFirst < _segment->getStartPosition() ||
      absLast > _segment->getStartPosition())
  {
    mapSegment();
    _cvals.clear();
  }
  if (_cvals.size() > 0 && _cvals.back()._last >= absFirst)
  {
    throw hal_exception("Coordinate out of order");
  }
  if (_value != DefaultValue)
  {
    CoordVal cv = {absFirst, absLast, _value};
    _cvals.push_back(cv);
  }
}

void WiggleLiftover::visitEOF()
{
  mapSegment();
}

void WiggleLiftover::mapSegment()
{
  if (_cvals.empty())
  {
    return;
  }
  if (_segment->getArrayIndex() == 0)
  {
    _segment->toSite(_cvals[0]._first, false);
  }
  while (_segment->getEndPosition() < _cvals[0]._first)
  {
    _segment->toRight();
  }

  while (_cvals[0]._first < _segment->getStartPosition())
  {
    assert(_segment->getArrayIndex() > 0);
    assert(_segment->getReversed() == false);
    _segment->toLeft(_cvals[0]._first);
  }

  assert(_cvals[0]._first <= _segment->getEndPosition());
  if (_cvals[0]._first > _segment->getStartPosition())
  {
    hal_offset_t so = _cvals[0]._first - _segment->getStartPosition();
    _segment->slice(so, _segment->getEndOffset());
  }
  if (_segment->getEndPosition() > _cvals.back()._last)
  {
    hal_offset_t eo = _segment->getEndPosition() - _cvals.back()._last;
    _segment->slice(_segment->getStartOffset(), eo);
  }

  _mappedSegments.clear();
  while (_segment->getArrayIndex() < _lastIndex &&
         _segment->getStartPosition() <= (_cvals.back()._last))
  {
    _segment->getMappedSegments(_mappedSegments, _tgtGenome, &_tgtSet,
                                _traverseDupes);
    _segment->toRight(_cvals.back()._last);
  }

  vector<MappedSegmentConstPtr> fragments;
  BlockMapper::MSSet emptySet;
  set<hal_index_t> queryCutSet;
  set<hal_index_t> targetCutSet;

  for (std::set<MappedSegmentConstPtr>::iterator i = _mappedSegments.begin();
       i != _mappedSegments.end(); ++i)
  {
    BlockMapper::extractSegment(i, emptySet, fragments, &_mappedSegments,
                                targetCutSet, queryCutSet);
    mapFragments(fragments);
  }
}

void WiggleLiftover::mapFragments(vector<MappedSegmentConstPtr>& fragments)
{
  sort(fragments.begin(), fragments.end(), MappedSegment::LessSource());
  _cvIdx = 0;

  for (size_t i = 0; i < fragments.size() && _cvIdx < _cvals.size(); ++i)
  {
    MappedSegmentConstPtr& seg = fragments[i];
    for (size_t j = 0; j < seg->getLength() && _cvIdx < _cvals.size(); ++j)
    {
      hal_index_t pos = seg->getSource()->getStartPosition() + j;
      while (_cvIdx < _cvals.size() && _cvals[_cvIdx]._last < pos)
      {
        ++_cvIdx;
      }
      assert(_cvals[_cvIdx]._first <= pos);
      hal_index_t mpos;

      if (seg->getReversed() == false)
      {
        mpos = seg->getStartPosition() + j;
      }
      else
      {
        mpos = seg->getEndPosition() - j;
      }
      if (_cvIdx < _cvals.size() && _cvals[_cvIdx]._first <= pos &&
          _cvals[_cvIdx]._last >= pos)
      {
        double val = std::max(_cvals[_cvIdx]._val, _outVals.get(mpos));
        _outVals.set(mpos, val);
      }
    }
  }
}

void WiggleLiftover::write()
{
  const Sequence* outSequence = NULL;
  hal_size_t ogSize = _tgtGenome->getSequenceLength();
  for (hal_size_t i = 0; i < _outVals.getNumTiles(); ++i)
  {
    if (_outVals.isTileEmpty(i) == false)
    {
      hal_index_t pos = i * _outVals.getTileSize();
      for (hal_size_t j = 0; pos < ogSize && j < _outVals.getTileSize(); ++j,
              ++pos)
      {
        if (outSequence == NULL || pos < outSequence->getStartPosition() ||
            pos > outSequence->getEndPosition())
        {
          outSequence = _tgtGenome->getSequenceBySite(pos);
          assert(outSequence != NULL);
          *_outStream << "fixedStep"
                      << "\tchrom=" << outSequence->getName()
                      << "\tstart=" << (pos - outSequence->getStartPosition())
                      << "\tstep=1\n";
        }
        *_outStream << _outVals.get(pos) << '\n';
      }
    }
  }
}
<|endoftext|>