<commit_before>/*
 * Copyright (c) 2015, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Michael X. Grey <mxgrey@gatech.edu>
 *
 * Georgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE.
 */

#include <osgGA/GUIEventAdapter>

#include "osgDart/DefaultEventHandler.h"
#include "osgDart/MouseEventHandler.h"
#include "osgDart/Viewer.h"
#include "osgDart/render/ShapeNode.h"
#include "osgDart/EntityNode.h"
#include "osgDart/utils.h"

#include "dart/dynamics/Entity.h"

#include <iostream>

namespace osgDart
{

DefaultEventHandler::DefaultEventHandler(Viewer* _viewer)
  : mViewer(_viewer),
    mLastCursorPosition(Eigen::Vector2d::Zero()),
    mLastModKeyMask(0)
{
  mViewer->addInstructionText("Spacebar:     Turn simulation on/off for any active worlds\n");
  mViewer->addInstructionText("Ctrl+H:       Turn headlights on/off\n");

  for(size_t i=0; i<NUM_MOUSE_BUTTONS; ++i)
    for(size_t j=0; j<BUTTON_NOTHING; ++j)
      mSuppressButtonPicks[i][j] = false;
  mSuppressMovePicks = false;

  clearButtonEvents();
}

//==============================================================================
DefaultEventHandler::~DefaultEventHandler()
{
  // Do nothing
}

//==============================================================================
MouseButtonEvent DefaultEventHandler::getButtonEvent(MouseButton button) const
{
  return mLastButtonEvent[button];
}

//==============================================================================
int DefaultEventHandler::getModKeyMask() const
{
  return mLastModKeyMask;
}

//==============================================================================
double DefaultEventHandler::getWindowCursorX() const
{
  return mLastCursorPosition[0];
}

//==============================================================================
double DefaultEventHandler::getWindowCursorY() const
{
  return mLastCursorPosition[1];
}

//==============================================================================
Eigen::Vector3d DefaultEventHandler::getDeltaCursor(
    const Eigen::Vector3d& _fromPosition,
    ConstraintType _constraint,
    const Eigen::Vector3d& _constraintVector) const
{
  osg::Vec3d eye, center, up;
  mViewer->getCamera()->getViewMatrixAsLookAt(eye, center, up);

  Eigen::Vector3d near, far;
  getNearAndFarPointUnderCursor(near, far);
  Eigen::Vector3d v1 = far-near;

  if(LINE_CONSTRAINT == _constraint)
  {
    const Eigen::Vector3d& b1 = near;
    const Eigen::Vector3d& v2 = _constraintVector;
    const Eigen::Vector3d& b2 = _fromPosition;

    double v1_v1 = v1.dot(v1);
    double v2_v2 = v2.dot(v2);
    double v2_v1 = v2.dot(v1);

    double denominator = v1_v1*v2_v2 - v2_v1*v2_v1;
    double s;
    if(fabs(denominator) < 1e-10)
      s = 0;
    else
      s = (v1_v1*(v2.dot(b1)-v2.dot(b2)) + v2_v1*(v1.dot(b2)-v1.dot(b1)))/denominator;

    return v2*s;
  }
  else if(PLANE_CONSTRAINT == _constraint)
  {
    const Eigen::Vector3d& n = _constraintVector;
    double s = n.dot(_fromPosition - near) / n.dot(v1);
    return near - _fromPosition + s*v1;
  }
  else
  {
    Eigen::Vector3d n = osgToEigVec3(center - eye);
    double s = n.dot(_fromPosition - near) / n.dot(v1);
    return near - _fromPosition + s*v1;
  }

  return Eigen::Vector3d::Zero();
}

//==============================================================================
void DefaultEventHandler::getNearAndFarPointUnderCursor(Eigen::Vector3d& near,
                                                        Eigen::Vector3d& far,
                                                        double distance) const
{
  osg::Camera* C = mViewer->getCamera();
  osg::Matrix VPW = C->getViewMatrix() * C->getProjectionMatrix()
      * C->getViewport()->computeWindowMatrix();
  osg::Matrix invVPW;
  invVPW.invert(VPW);

  double x = getWindowCursorX(), y = getWindowCursorY();
  osg::Vec3 osgNear = osg::Vec3(x,y,0.0) * invVPW;
  osg::Vec3 osgFar = osg::Vec3(x,y,distance) * invVPW;

  near = osgToEigVec3(osgNear);
  far = osgToEigVec3(osgFar);
}

//==============================================================================
const std::vector<PickInfo>& DefaultEventHandler::getButtonPicks(
    MouseButton button, MouseButtonEvent event) const
{
  if(BUTTON_NOTHING == event)
    return mMovePicks;

  return mButtonPicks[button][event];
}

//==============================================================================
const std::vector<PickInfo>& DefaultEventHandler::getMovePicks() const
{
  return mMovePicks;
}

//==============================================================================
void DefaultEventHandler::suppressButtonPicks(MouseButton button,
                                              MouseButtonEvent event)
{
  if(BUTTON_NOTHING == event)
    mSuppressMovePicks = true;
  else
    mSuppressButtonPicks[button][event] = true;
}

//==============================================================================
void DefaultEventHandler::suppressMovePicks()
{
  mSuppressMovePicks = true;
}

//==============================================================================
void DefaultEventHandler::activateButtonPicks(MouseButton button,
                                              MouseButtonEvent event)
{
  if(BUTTON_NOTHING == event)
    mSuppressMovePicks = false;
  else
    mSuppressButtonPicks[button][event] = false;
}

//==============================================================================
void DefaultEventHandler::activateMovePicks()
{
  mSuppressMovePicks = false;
}

//==============================================================================
void DefaultEventHandler::pick(std::vector<PickInfo>& infoVector,
                               const osgGA::GUIEventAdapter& ea)
{
  osgUtil::LineSegmentIntersector::Intersections hlist;

  infoVector.clear();
  if(mViewer->computeIntersections(ea, hlist))
  {
    infoVector.reserve(hlist.size());
    for(const osgUtil::LineSegmentIntersector::Intersection& intersect : hlist)
    {
      osg::Drawable* drawable = intersect.drawable;
      render::ShapeNode* shape =
          dynamic_cast<render::ShapeNode*>(drawable->getParent(0));
      if(shape)
      {
        PickInfo info;
        info.shape = shape->getShape();
        info.entity = shape->getParentEntityNode()->getEntity();
        info.normal = osgToEigVec3(intersect.getWorldIntersectNormal());
        info.position = osgToEigVec3(intersect.getWorldIntersectPoint());

        infoVector.push_back(info);
      }
    }
  }
}

//==============================================================================
void DefaultEventHandler::addMouseEventHandler(MouseEventHandler* handler)
{
  mMouseEventHandlers.insert(handler);
  handler->mEventHandler = this;
  handler->addSubject(this);
}

//==============================================================================
const std::set<MouseEventHandler*>&
DefaultEventHandler::getMouseEventHandlers() const
{
  return mMouseEventHandlers;
}

//==============================================================================
static bool wasActive(MouseButtonEvent event)
{
  return ( (event == BUTTON_PUSH) || (event == BUTTON_DRAG) );
}

//==============================================================================
static void assignEventToButtons(
    MouseButtonEvent (&mLastButtonEvent)[NUM_MOUSE_BUTTONS],
    const osgGA::GUIEventAdapter& ea)
{
  MouseButtonEvent event = BUTTON_NOTHING;
  if(ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
    event = BUTTON_PUSH;
  else if(ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
    event = BUTTON_DRAG;
  else if(ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
    event = BUTTON_RELEASE;

  if(BUTTON_RELEASE == event)
  {
    if( (ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) == 0
        && wasActive(mLastButtonEvent[LEFT_MOUSE]) )
      mLastButtonEvent[LEFT_MOUSE] = event;

    if( (ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) == 0
        && wasActive(mLastButtonEvent[RIGHT_MOUSE]) )
      mLastButtonEvent[RIGHT_MOUSE] = event;

    if( (ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) == 0
        && wasActive(mLastButtonEvent[MIDDLE_MOUSE]) )
      mLastButtonEvent[MIDDLE_MOUSE] = event;
  }
  else
  {
    if(ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
      mLastButtonEvent[LEFT_MOUSE] = event;

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
      mLastButtonEvent[RIGHT_MOUSE] = event;

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
      mLastButtonEvent[MIDDLE_MOUSE] = event;
  }
}

//==============================================================================
bool DefaultEventHandler::handle(const osgGA::GUIEventAdapter& ea,
                                 osgGA::GUIActionAdapter&)
{
  mLastModKeyMask = ea.getModKeyMask();

  switch(ea.getEventType())
  {
    case osgGA::GUIEventAdapter::PUSH:
    case osgGA::GUIEventAdapter::DRAG:
    case osgGA::GUIEventAdapter::RELEASE:
    case osgGA::GUIEventAdapter::MOVE:
      mLastCursorPosition[0] = ea.getX();
      mLastCursorPosition[1] = ea.getY();

      break;

    default:
      break;
  }

  switch(ea.getEventType())
  {
    case osgGA::GUIEventAdapter::KEYDOWN:
    {
      switch(ea.getKey())
      {
        case 8: // ctrl+h
        {
          mViewer->switchHeadlights(!mViewer->checkHeadlights());
          return true;
          break;
        }

        case ' ':
        {
          mViewer->simulate(!mViewer->isSimulating());
          return true;
          break;
        }
      }
    }

    case osgGA::GUIEventAdapter::MOVE:
    {
      if(!mSuppressMovePicks)
        pick(mMovePicks, ea);

      triggerMouseEventHandlers();
      break;
    }

    case osgGA::GUIEventAdapter::PUSH:
    case osgGA::GUIEventAdapter::DRAG:
    case osgGA::GUIEventAdapter::RELEASE:

      assignEventToButtons(mLastButtonEvent, ea);
      eventPick(ea);

      mViewer->updateDragAndDrops();

      triggerMouseEventHandlers();
      break;

    default:
      break;
  }

  return false;
}

//==============================================================================
void DefaultEventHandler::triggerMouseEventHandlers()
{
  for(MouseEventHandler* h : mMouseEventHandlers)
  {
    h->update();
  }
}

//==============================================================================
void DefaultEventHandler::eventPick(const osgGA::GUIEventAdapter& ea)
{
  MouseButtonEvent mbe;
  switch(ea.getEventType())
  {
    case osgGA::GUIEventAdapter::PUSH:
      mbe = BUTTON_PUSH;
      break;
    case osgGA::GUIEventAdapter::DRAG:
      mbe = BUTTON_DRAG;
      break;
    case osgGA::GUIEventAdapter::RELEASE:
      mbe = BUTTON_RELEASE;
      break;
    default:
      return;
  }

  if(   ( (ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
           && !mSuppressButtonPicks[LEFT_MOUSE][mbe])
     || ( (ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
           && !mSuppressButtonPicks[RIGHT_MOUSE][mbe])
     || ( (ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
           && !mSuppressButtonPicks[MIDDLE_MOUSE][mbe]))
  {
    pick(mTempPicks, ea);

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
      mButtonPicks[LEFT_MOUSE][mbe] = mTempPicks;

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
      mButtonPicks[RIGHT_MOUSE][mbe] = mTempPicks;

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
      mButtonPicks[MIDDLE_MOUSE][mbe] = mTempPicks;
  }
}

//==============================================================================
void DefaultEventHandler::clearButtonEvents()
{
  for(size_t i=0; i<NUM_MOUSE_BUTTONS; ++i)
    mLastButtonEvent[i] = BUTTON_NOTHING;
}

//==============================================================================
void DefaultEventHandler::handleDestructionNotification(
    const dart::common::Subject* _subject)
{
  MouseEventHandler* meh = const_cast<MouseEventHandler*>(
        dynamic_cast<const MouseEventHandler*>(_subject));
  std::set<MouseEventHandler*>::iterator it = mMouseEventHandlers.find(meh);
  if(it != mMouseEventHandlers.end())
    mMouseEventHandlers.erase(it);
}

} // namespace osgDart
<commit_msg>don't block spacebar when simulation is disabled<commit_after>/*
 * Copyright (c) 2015, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Michael X. Grey <mxgrey@gatech.edu>
 *
 * Georgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE.
 */

#include <osgGA/GUIEventAdapter>

#include "osgDart/DefaultEventHandler.h"
#include "osgDart/MouseEventHandler.h"
#include "osgDart/Viewer.h"
#include "osgDart/render/ShapeNode.h"
#include "osgDart/EntityNode.h"
#include "osgDart/utils.h"

#include "dart/dynamics/Entity.h"

#include <iostream>

namespace osgDart
{

DefaultEventHandler::DefaultEventHandler(Viewer* _viewer)
  : mViewer(_viewer),
    mLastCursorPosition(Eigen::Vector2d::Zero()),
    mLastModKeyMask(0)
{
  mViewer->addInstructionText("Spacebar:     Turn simulation on/off for any active worlds\n");
  mViewer->addInstructionText("Ctrl+H:       Turn headlights on/off\n");

  for(size_t i=0; i<NUM_MOUSE_BUTTONS; ++i)
    for(size_t j=0; j<BUTTON_NOTHING; ++j)
      mSuppressButtonPicks[i][j] = false;
  mSuppressMovePicks = false;

  clearButtonEvents();
}

//==============================================================================
DefaultEventHandler::~DefaultEventHandler()
{
  // Do nothing
}

//==============================================================================
MouseButtonEvent DefaultEventHandler::getButtonEvent(MouseButton button) const
{
  return mLastButtonEvent[button];
}

//==============================================================================
int DefaultEventHandler::getModKeyMask() const
{
  return mLastModKeyMask;
}

//==============================================================================
double DefaultEventHandler::getWindowCursorX() const
{
  return mLastCursorPosition[0];
}

//==============================================================================
double DefaultEventHandler::getWindowCursorY() const
{
  return mLastCursorPosition[1];
}

//==============================================================================
Eigen::Vector3d DefaultEventHandler::getDeltaCursor(
    const Eigen::Vector3d& _fromPosition,
    ConstraintType _constraint,
    const Eigen::Vector3d& _constraintVector) const
{
  osg::Vec3d eye, center, up;
  mViewer->getCamera()->getViewMatrixAsLookAt(eye, center, up);

  Eigen::Vector3d near, far;
  getNearAndFarPointUnderCursor(near, far);
  Eigen::Vector3d v1 = far-near;

  if(LINE_CONSTRAINT == _constraint)
  {
    const Eigen::Vector3d& b1 = near;
    const Eigen::Vector3d& v2 = _constraintVector;
    const Eigen::Vector3d& b2 = _fromPosition;

    double v1_v1 = v1.dot(v1);
    double v2_v2 = v2.dot(v2);
    double v2_v1 = v2.dot(v1);

    double denominator = v1_v1*v2_v2 - v2_v1*v2_v1;
    double s;
    if(fabs(denominator) < 1e-10)
      s = 0;
    else
      s = (v1_v1*(v2.dot(b1)-v2.dot(b2)) + v2_v1*(v1.dot(b2)-v1.dot(b1)))/denominator;

    return v2*s;
  }
  else if(PLANE_CONSTRAINT == _constraint)
  {
    const Eigen::Vector3d& n = _constraintVector;
    double s = n.dot(_fromPosition - near) / n.dot(v1);
    return near - _fromPosition + s*v1;
  }
  else
  {
    Eigen::Vector3d n = osgToEigVec3(center - eye);
    double s = n.dot(_fromPosition - near) / n.dot(v1);
    return near - _fromPosition + s*v1;
  }

  return Eigen::Vector3d::Zero();
}

//==============================================================================
void DefaultEventHandler::getNearAndFarPointUnderCursor(Eigen::Vector3d& near,
                                                        Eigen::Vector3d& far,
                                                        double distance) const
{
  osg::Camera* C = mViewer->getCamera();
  osg::Matrix VPW = C->getViewMatrix() * C->getProjectionMatrix()
      * C->getViewport()->computeWindowMatrix();
  osg::Matrix invVPW;
  invVPW.invert(VPW);

  double x = getWindowCursorX(), y = getWindowCursorY();
  osg::Vec3 osgNear = osg::Vec3(x,y,0.0) * invVPW;
  osg::Vec3 osgFar = osg::Vec3(x,y,distance) * invVPW;

  near = osgToEigVec3(osgNear);
  far = osgToEigVec3(osgFar);
}

//==============================================================================
const std::vector<PickInfo>& DefaultEventHandler::getButtonPicks(
    MouseButton button, MouseButtonEvent event) const
{
  if(BUTTON_NOTHING == event)
    return mMovePicks;

  return mButtonPicks[button][event];
}

//==============================================================================
const std::vector<PickInfo>& DefaultEventHandler::getMovePicks() const
{
  return mMovePicks;
}

//==============================================================================
void DefaultEventHandler::suppressButtonPicks(MouseButton button,
                                              MouseButtonEvent event)
{
  if(BUTTON_NOTHING == event)
    mSuppressMovePicks = true;
  else
    mSuppressButtonPicks[button][event] = true;
}

//==============================================================================
void DefaultEventHandler::suppressMovePicks()
{
  mSuppressMovePicks = true;
}

//==============================================================================
void DefaultEventHandler::activateButtonPicks(MouseButton button,
                                              MouseButtonEvent event)
{
  if(BUTTON_NOTHING == event)
    mSuppressMovePicks = false;
  else
    mSuppressButtonPicks[button][event] = false;
}

//==============================================================================
void DefaultEventHandler::activateMovePicks()
{
  mSuppressMovePicks = false;
}

//==============================================================================
void DefaultEventHandler::pick(std::vector<PickInfo>& infoVector,
                               const osgGA::GUIEventAdapter& ea)
{
  osgUtil::LineSegmentIntersector::Intersections hlist;

  infoVector.clear();
  if(mViewer->computeIntersections(ea, hlist))
  {
    infoVector.reserve(hlist.size());
    for(const osgUtil::LineSegmentIntersector::Intersection& intersect : hlist)
    {
      osg::Drawable* drawable = intersect.drawable;
      render::ShapeNode* shape =
          dynamic_cast<render::ShapeNode*>(drawable->getParent(0));
      if(shape)
      {
        PickInfo info;
        info.shape = shape->getShape();
        info.entity = shape->getParentEntityNode()->getEntity();
        info.normal = osgToEigVec3(intersect.getWorldIntersectNormal());
        info.position = osgToEigVec3(intersect.getWorldIntersectPoint());

        infoVector.push_back(info);
      }
    }
  }
}

//==============================================================================
void DefaultEventHandler::addMouseEventHandler(MouseEventHandler* handler)
{
  mMouseEventHandlers.insert(handler);
  handler->mEventHandler = this;
  handler->addSubject(this);
}

//==============================================================================
const std::set<MouseEventHandler*>&
DefaultEventHandler::getMouseEventHandlers() const
{
  return mMouseEventHandlers;
}

//==============================================================================
static bool wasActive(MouseButtonEvent event)
{
  return ( (event == BUTTON_PUSH) || (event == BUTTON_DRAG) );
}

//==============================================================================
static void assignEventToButtons(
    MouseButtonEvent (&mLastButtonEvent)[NUM_MOUSE_BUTTONS],
    const osgGA::GUIEventAdapter& ea)
{
  MouseButtonEvent event = BUTTON_NOTHING;
  if(ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
    event = BUTTON_PUSH;
  else if(ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
    event = BUTTON_DRAG;
  else if(ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
    event = BUTTON_RELEASE;

  if(BUTTON_RELEASE == event)
  {
    if( (ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) == 0
        && wasActive(mLastButtonEvent[LEFT_MOUSE]) )
      mLastButtonEvent[LEFT_MOUSE] = event;

    if( (ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) == 0
        && wasActive(mLastButtonEvent[RIGHT_MOUSE]) )
      mLastButtonEvent[RIGHT_MOUSE] = event;

    if( (ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) == 0
        && wasActive(mLastButtonEvent[MIDDLE_MOUSE]) )
      mLastButtonEvent[MIDDLE_MOUSE] = event;
  }
  else
  {
    if(ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
      mLastButtonEvent[LEFT_MOUSE] = event;

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
      mLastButtonEvent[RIGHT_MOUSE] = event;

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
      mLastButtonEvent[MIDDLE_MOUSE] = event;
  }
}

//==============================================================================
bool DefaultEventHandler::handle(const osgGA::GUIEventAdapter& ea,
                                 osgGA::GUIActionAdapter&)
{
  mLastModKeyMask = ea.getModKeyMask();

  switch(ea.getEventType())
  {
    case osgGA::GUIEventAdapter::PUSH:
    case osgGA::GUIEventAdapter::DRAG:
    case osgGA::GUIEventAdapter::RELEASE:
    case osgGA::GUIEventAdapter::MOVE:
      mLastCursorPosition[0] = ea.getX();
      mLastCursorPosition[1] = ea.getY();

      break;

    default:
      break;
  }

  switch(ea.getEventType())
  {
    case osgGA::GUIEventAdapter::KEYDOWN:
    {
      switch(ea.getKey())
      {
        case 8: // ctrl+h
        {
          mViewer->switchHeadlights(!mViewer->checkHeadlights());
          return true;
          break;
        }

        case ' ':
        {
          if(mViewer->isAllowingSimulation())
          {
            mViewer->simulate(!mViewer->isSimulating());
            return true;
          }
          break;
        }
      }
    }

    case osgGA::GUIEventAdapter::MOVE:
    {
      if(!mSuppressMovePicks)
        pick(mMovePicks, ea);

      triggerMouseEventHandlers();
      break;
    }

    case osgGA::GUIEventAdapter::PUSH:
    case osgGA::GUIEventAdapter::DRAG:
    case osgGA::GUIEventAdapter::RELEASE:

      assignEventToButtons(mLastButtonEvent, ea);
      eventPick(ea);

      mViewer->updateDragAndDrops();

      triggerMouseEventHandlers();
      break;

    default:
      break;
  }

  return false;
}

//==============================================================================
void DefaultEventHandler::triggerMouseEventHandlers()
{
  for(MouseEventHandler* h : mMouseEventHandlers)
  {
    h->update();
  }
}

//==============================================================================
void DefaultEventHandler::eventPick(const osgGA::GUIEventAdapter& ea)
{
  MouseButtonEvent mbe;
  switch(ea.getEventType())
  {
    case osgGA::GUIEventAdapter::PUSH:
      mbe = BUTTON_PUSH;
      break;
    case osgGA::GUIEventAdapter::DRAG:
      mbe = BUTTON_DRAG;
      break;
    case osgGA::GUIEventAdapter::RELEASE:
      mbe = BUTTON_RELEASE;
      break;
    default:
      return;
  }

  if(   ( (ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
           && !mSuppressButtonPicks[LEFT_MOUSE][mbe])
     || ( (ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
           && !mSuppressButtonPicks[RIGHT_MOUSE][mbe])
     || ( (ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
           && !mSuppressButtonPicks[MIDDLE_MOUSE][mbe]))
  {
    pick(mTempPicks, ea);

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
      mButtonPicks[LEFT_MOUSE][mbe] = mTempPicks;

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
      mButtonPicks[RIGHT_MOUSE][mbe] = mTempPicks;

    if(ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
      mButtonPicks[MIDDLE_MOUSE][mbe] = mTempPicks;
  }
}

//==============================================================================
void DefaultEventHandler::clearButtonEvents()
{
  for(size_t i=0; i<NUM_MOUSE_BUTTONS; ++i)
    mLastButtonEvent[i] = BUTTON_NOTHING;
}

//==============================================================================
void DefaultEventHandler::handleDestructionNotification(
    const dart::common::Subject* _subject)
{
  MouseEventHandler* meh = const_cast<MouseEventHandler*>(
        dynamic_cast<const MouseEventHandler*>(_subject));
  std::set<MouseEventHandler*>::iterator it = mMouseEventHandlers.find(meh);
  if(it != mMouseEventHandlers.end())
    mMouseEventHandlers.erase(it);
}

} // namespace osgDart
<|endoftext|>


<commit_before>#include "compiler.h"
#include "mswin.h"
#include "resources.h"
#include "glinit.h"
#include "model.h"
#include "arguments.h"
#include "polymorph.h"
#include "settings.h"
#include "dialog.h"
#include "qpc.h"
#include <tchar.h>
#include <windowsx.h>
#include <cstdint>

NOINLINE int message_loop (HWND hdlg)
{
  MSG msg;
  while (::GetMessage (& msg, NULL, 0, 0)) {
    if (! hdlg || ! ::IsDialogMessage (hdlg, & msg)) {
      ::TranslateMessage (& msg);
      ::DispatchMessage (& msg);
    }
  }
  return (int) msg.wParam;
}

int WINAPI _tWinMain (HINSTANCE hInstance, HINSTANCE, LPTSTR, int)
{
  if (! glinit (hInstance)) return 1;

  LPCTSTR display_name;
  ::LoadString (hInstance, 1, (LPTSTR) (& display_name), 0);

  ALIGNED16 window_struct_t ws;

  arguments_t arguments (::GetCommandLine ());
  ws.mode = arguments.mode;

  load_settings (ws.settings);

  // Create the screen saver window.
  // Retry once on failure (works around sporadic SetPixelFormat
  // failure observed on Intel integrated graphics on Windows 7).
  register_class (hInstance);
  HWND hwnd;
  for (unsigned retries = 0; retries != 2; ++ retries) {
    hwnd = create_window (hInstance, arguments.parent, display_name, & ws);
    if (hwnd) break;
    // Window creation failed (window will be destroyed).
    // Pump messages and throw away the WM_QUIT.
    message_loop (0);
  }

  if (! hwnd) return 1;
  if (! ws.model.initialize (qpc ())) return 1;

  // Create the configure dialog if in configure mode.
  dialog_struct_t ds = { ws.settings, hwnd, };
  HWND hdlg = arguments.mode == configure ? create_dialog (hInstance, & ds) : NULL;

  // Show the main window, or the configure dialog if in configure mode.
  ::ShowWindow (hdlg ? hdlg : hwnd, SW_SHOW);

  return message_loop (hdlg);
}

#ifdef TINY

// Tiny startup.

// No standard handles, window placement, environment variables,
// command-line transformation, global constructors and destructors,
// atexit functions, thread-local storage, runtime relocation fixups,
// 387 floating-point initialization, signal handlers and no exceptions.
extern "C"
{
  // This symbol is defined by the linker.
  extern IMAGE_DOS_HEADER __ImageBase;

  // In the linker command line, specify this function as the entry point.
  VISIBLE NORETURN ALIGN_STACK void custom_startup ()
  {
    HINSTANCE hInstance = (HINSTANCE) & __ImageBase;
    int status = _tWinMain (hInstance, NULL, NULL, 0);
    ::ExitProcess ((UINT) (status));
  }
}

#endif
<commit_msg>main.cpp: use SetWindowPos, not ShowWindow (otherwise, WM_WINDOWPOSCHANGING is not always received).<commit_after>#include "compiler.h"
#include "mswin.h"
#include "resources.h"
#include "glinit.h"
#include "model.h"
#include "arguments.h"
#include "polymorph.h"
#include "settings.h"
#include "dialog.h"
#include "qpc.h"
#include <tchar.h>
#include <windowsx.h>
#include <cstdint>

NOINLINE int message_loop (HWND hdlg)
{
  MSG msg;
  while (::GetMessage (& msg, NULL, 0, 0)) {
    if (! hdlg || ! ::IsDialogMessage (hdlg, & msg)) {
      ::TranslateMessage (& msg);
      ::DispatchMessage (& msg);
    }
  }
  return (int) msg.wParam;
}

int WINAPI _tWinMain (HINSTANCE hInstance, HINSTANCE, LPTSTR, int)
{
  if (! glinit (hInstance)) return 1;

  LPCTSTR display_name;
  ::LoadString (hInstance, 1, (LPTSTR) (& display_name), 0);

  ALIGNED16 window_struct_t ws;

  arguments_t arguments (::GetCommandLine ());
  ws.mode = arguments.mode;

  load_settings (ws.settings);

  // Create the screen saver window.
  // Retry once on failure (works around sporadic SetPixelFormat
  // failure observed on Intel integrated graphics on Windows 7).
  register_class (hInstance);
  HWND hwnd;
  for (unsigned retries = 0; retries != 2; ++ retries) {
    hwnd = create_window (hInstance, arguments.parent, display_name, & ws);
    if (hwnd) break;
    // Window creation failed (window will be destroyed).
    // Pump messages and throw away the WM_QUIT.
    message_loop (0);
  }

  if (! hwnd) return 1;
  if (! ws.model.initialize (qpc ())) return 1;

  // Create the configure dialog if in configure mode.
  dialog_struct_t ds = { ws.settings, hwnd, };
  HWND hdlg = arguments.mode == configure ? create_dialog (hInstance, & ds) : NULL;

  // Show the main window, or the configure dialog if in configure mode.
  // We use SetWindowPos because on Windows XP when the main window is
  // shown as a child of the screensaver control-panel applet windows,
  // the WM_WINDOWPOSCHANGING doesn't arrive if we use ShowWindow.
  ::SetWindowPos (hdlg ? hdlg : hwnd, NULL, 0, 0, 0, 0,
                  SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_SHOWWINDOW);

  return message_loop (hdlg);
}

#ifdef TINY

// Tiny startup.

// No standard handles, window placement, environment variables,
// command-line transformation, global constructors and destructors,
// atexit functions, thread-local storage, runtime relocation fixups,
// 387 floating-point initialization, signal handlers and no exceptions.
extern "C"
{
  // This symbol is defined by the linker.
  extern IMAGE_DOS_HEADER __ImageBase;

  // In the linker command line, specify this function as the entry point.
  VISIBLE NORETURN ALIGN_STACK void custom_startup ()
  {
    HINSTANCE hInstance = (HINSTANCE) & __ImageBase;
    int status = _tWinMain (hInstance, NULL, NULL, 0);
    ::ExitProcess ((UINT) (status));
  }
}

#endif
<|endoftext|>


<commit_before>/*=============================================================================

  Library: CppMicroServices

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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 "usServiceReference.h"
#include "usServiceReferencePrivate.h"
#include "usServiceRegistrationPrivate.h"

#include "usModule.h"
#include "usModulePrivate.h"

US_BEGIN_NAMESPACE

typedef ServiceRegistrationPrivate::MutexType MutexType;
typedef MutexLock<MutexType> MutexLocker;

ServiceReference::ServiceReference()
  : d(new ServiceReferencePrivate(0))
{

}

ServiceReference::ServiceReference(const ServiceReference& ref)
  : d(ref.d)
{
  d->ref.Ref();
}

ServiceReference::ServiceReference(ServiceRegistrationPrivate* reg)
  : d(new ServiceReferencePrivate(reg))
{

}

ServiceReference::operator bool() const
{
  return GetModule() != 0;
}

ServiceReference& ServiceReference::operator=(int null)
{
  if (null == 0)
  {
    if (!d->ref.Deref())
      delete d;
    d = new ServiceReferencePrivate(0);
  }
  return *this;
}

ServiceReference::~ServiceReference()
{
  if (!d->ref.Deref())
    delete d;
}

Any ServiceReference::GetProperty(const std::string& key) const
{
  MutexLocker lock(d->registration->propsLock);

  ServiceProperties::const_iterator iter = d->registration->properties.find(key);
  if (iter != d->registration->properties.end())
    return iter->second;
  return Any();
}

void ServiceReference::GetPropertyKeys(std::vector<std::string>& keys) const
{
  MutexLocker lock(d->registration->propsLock);

  ServiceProperties::const_iterator iterEnd = d->registration->properties.end();
  for (ServiceProperties::const_iterator iter = d->registration->properties.begin();
       iter != iterEnd; ++iter)
  {
    keys.push_back(iter->first);
  }
}

Module* ServiceReference::GetModule() const
{
  if (d->registration == 0 || d->registration->module == 0)
  {
    return 0;
  }

  return d->registration->module->q;
}

void ServiceReference::GetUsingModules(std::vector<Module*>& modules) const
{
  MutexLocker lock(d->registration->propsLock);

  ServiceRegistrationPrivate::ModuleToRefsMap::const_iterator end = d->registration->dependents.end();
  for (ServiceRegistrationPrivate::ModuleToRefsMap::const_iterator iter = d->registration->dependents.begin();
       iter != end; ++iter)
  {
    modules.push_back(iter->first);
  }
}

bool ServiceReference::operator<(const ServiceReference& reference) const
{
  int r1 = 0;
  int r2 = 0;

  Any anyR1 = GetProperty(ServiceConstants::SERVICE_RANKING());
  Any anyR2 = reference.GetProperty(ServiceConstants::SERVICE_RANKING());
  if (anyR1.Type() == typeid(int)) r1 = any_cast<int>(anyR1);
  if (anyR2.Type() == typeid(int)) r2 = any_cast<int>(anyR2);

  if (r1 != r2)
  {
    // use ranking if ranking differs
    return r1 < r2;
  }
  else
  {
    long int id1 = any_cast<long int>(GetProperty(ServiceConstants::SERVICE_ID()));
    long int id2 = any_cast<long int>(reference.GetProperty(ServiceConstants::SERVICE_ID()));

    // otherwise compare using IDs,
    // is less than if it has a higher ID.
    return id2 < id1;
  }
}

bool ServiceReference::operator==(const ServiceReference& reference) const
{
  return d->registration == reference.d->registration;
}

ServiceReference& ServiceReference::operator=(const ServiceReference& reference)
{
  ServiceReferencePrivate* curr_d = d;
  d = reference.d;
  d->ref.Ref();

  if (!curr_d->ref.Deref())
    delete curr_d;

  return *this;
}

std::size_t ServiceReference::Hash() const
{
  using namespace US_HASH_FUNCTION_NAMESPACE;
  return US_HASH_FUNCTION(ServiceRegistrationPrivate*, this->d->registration);
}

US_END_NAMESPACE

US_USE_NAMESPACE

std::ostream& operator<<(std::ostream& os, const ServiceReference& serviceRef)
{
  os << "Reference for service object registered from "
     << serviceRef.GetModule()->GetName() << " " << serviceRef.GetModule()->GetVersion()
     << " (";
  std::vector<std::string> keys;
  serviceRef.GetPropertyKeys(keys);
  int keySize = keys.size();
  for(int i = 0; i < keySize; ++i)
  {
    os << keys[i] << "=" << serviceRef.GetProperty(keys[i]);
    if (i < keySize-1) os << ",";
  }
  os << ")";

  return os;
}

<commit_msg>Fixed size_t / int issue in usServiceReference<commit_after>/*=============================================================================

  Library: CppMicroServices

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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 "usServiceReference.h"
#include "usServiceReferencePrivate.h"
#include "usServiceRegistrationPrivate.h"

#include "usModule.h"
#include "usModulePrivate.h"

US_BEGIN_NAMESPACE

typedef ServiceRegistrationPrivate::MutexType MutexType;
typedef MutexLock<MutexType> MutexLocker;

ServiceReference::ServiceReference()
  : d(new ServiceReferencePrivate(0))
{

}

ServiceReference::ServiceReference(const ServiceReference& ref)
  : d(ref.d)
{
  d->ref.Ref();
}

ServiceReference::ServiceReference(ServiceRegistrationPrivate* reg)
  : d(new ServiceReferencePrivate(reg))
{

}

ServiceReference::operator bool() const
{
  return GetModule() != 0;
}

ServiceReference& ServiceReference::operator=(int null)
{
  if (null == 0)
  {
    if (!d->ref.Deref())
      delete d;
    d = new ServiceReferencePrivate(0);
  }
  return *this;
}

ServiceReference::~ServiceReference()
{
  if (!d->ref.Deref())
    delete d;
}

Any ServiceReference::GetProperty(const std::string& key) const
{
  MutexLocker lock(d->registration->propsLock);

  ServiceProperties::const_iterator iter = d->registration->properties.find(key);
  if (iter != d->registration->properties.end())
    return iter->second;
  return Any();
}

void ServiceReference::GetPropertyKeys(std::vector<std::string>& keys) const
{
  MutexLocker lock(d->registration->propsLock);

  ServiceProperties::const_iterator iterEnd = d->registration->properties.end();
  for (ServiceProperties::const_iterator iter = d->registration->properties.begin();
       iter != iterEnd; ++iter)
  {
    keys.push_back(iter->first);
  }
}

Module* ServiceReference::GetModule() const
{
  if (d->registration == 0 || d->registration->module == 0)
  {
    return 0;
  }

  return d->registration->module->q;
}

void ServiceReference::GetUsingModules(std::vector<Module*>& modules) const
{
  MutexLocker lock(d->registration->propsLock);

  ServiceRegistrationPrivate::ModuleToRefsMap::const_iterator end = d->registration->dependents.end();
  for (ServiceRegistrationPrivate::ModuleToRefsMap::const_iterator iter = d->registration->dependents.begin();
       iter != end; ++iter)
  {
    modules.push_back(iter->first);
  }
}

bool ServiceReference::operator<(const ServiceReference& reference) const
{
  int r1 = 0;
  int r2 = 0;

  Any anyR1 = GetProperty(ServiceConstants::SERVICE_RANKING());
  Any anyR2 = reference.GetProperty(ServiceConstants::SERVICE_RANKING());
  if (anyR1.Type() == typeid(int)) r1 = any_cast<int>(anyR1);
  if (anyR2.Type() == typeid(int)) r2 = any_cast<int>(anyR2);

  if (r1 != r2)
  {
    // use ranking if ranking differs
    return r1 < r2;
  }
  else
  {
    long int id1 = any_cast<long int>(GetProperty(ServiceConstants::SERVICE_ID()));
    long int id2 = any_cast<long int>(reference.GetProperty(ServiceConstants::SERVICE_ID()));

    // otherwise compare using IDs,
    // is less than if it has a higher ID.
    return id2 < id1;
  }
}

bool ServiceReference::operator==(const ServiceReference& reference) const
{
  return d->registration == reference.d->registration;
}

ServiceReference& ServiceReference::operator=(const ServiceReference& reference)
{
  ServiceReferencePrivate* curr_d = d;
  d = reference.d;
  d->ref.Ref();

  if (!curr_d->ref.Deref())
    delete curr_d;

  return *this;
}

std::size_t ServiceReference::Hash() const
{
  using namespace US_HASH_FUNCTION_NAMESPACE;
  return US_HASH_FUNCTION(ServiceRegistrationPrivate*, this->d->registration);
}

US_END_NAMESPACE

US_USE_NAMESPACE

std::ostream& operator<<(std::ostream& os, const ServiceReference& serviceRef)
{
  os << "Reference for service object registered from "
     << serviceRef.GetModule()->GetName() << " " << serviceRef.GetModule()->GetVersion()
     << " (";
  std::vector<std::string> keys;
  serviceRef.GetPropertyKeys(keys);
  size_t keySize = keys.size();
  for(size_t i = 0; i < keySize; ++i)
  {
    os << keys[i] << "=" << serviceRef.GetProperty(keys[i]);
    if (i < keySize-1) os << ",";
  }
  os << ")";

  return os;
}

<|endoftext|>


<commit_before>/**
 * @file Event.hpp
 * @author Denis Kotov
 * @date 10 Jun 2017
 * @brief Contains abstract class for Pack Buffer
 * @copyright MIT License. Open source:
 */

#ifndef ICC_EVENT_HPP
#define ICC_EVENT_HPP

#include <vector>
#include <map>
#include <tuple>
#include <utility>
#include <algorithm>
#include "IComponent.hpp"

template <typename _T>
class Event;

template <typename _R, typename ... _Args>
class Event<_R(_Args...)> {
 public:
  using tCallback = _R(IComponent::*)(_Args...);
  using tUncheckedObjectAndCallbacks = std::pair<IComponent *, tCallback>;
  using tUncheckedListCallbacks = std::vector<tUncheckedObjectAndCallbacks>;
  using tCheckedObjectAndCallbacks = std::pair<std::weak_ptr<IComponent>, tCallback>;
  using tCheckedListCallbacks = std::vector<tCheckedObjectAndCallbacks>;
 public:
  Event() = default;
  Event(Event const&) = default;
  Event(Event &&) = default;

 public:
  /**
   * Unsafe function for connect Event to object _listener with _callback
   * User should be confident that _listener is exist at moment of calling callback
   * @tparam _Component Type of object that listen Event
   * @param _callback method in object that listen Event
   * @param _listener Object that listen Event
   */
  template <typename _Component>
  void connect(_R(_Component::*_callback)(_Args...),
               _Component * _listener) {
    static_assert(std::is_base_of<IComponent, _Component>::value,
                  "_listener is not derived from IComponent");
    if (_listener) {
      unchecked_listeners_.emplace_back(
          static_cast<IComponent*>(_listener),
          static_cast<_R(IComponent::*)(_Args...)>(_callback));
    }
  }

  /**
   * Safe function for connect Event to object _listener with _callback
   * User can check if _listener is exist at moment of calling callback
   * @tparam _Component Type of object that listen Event
   * @param _callback method in object that listen Event
   * @param _listener Object that listen Event
   */
  template <typename _Component>
  void connect(_R(_Component::*_callback)(_Args...),
               std::shared_ptr<_Component> _listener) {
    static_assert(std::is_base_of<IComponent, _Component>::value,
                  "_listener is not derived from IComponent");
    if(_listener) {
      checked_listeners_.emplace_back(
          static_cast<std::shared_ptr<IComponent>>(_listener),
          static_cast<_R(IComponent::*)(_Args...)>(_callback)
      );
    }
  }

  /**
   * Unsafe function for disconnect Event from object _listener with _callback
   * User should be confident that _listener is exist at moment of calling callback
   * @tparam _Component Type of object that listen Event
   * @param _callback method in object that listen Event
   * @param _listener Object that listen Event
   */
  template <typename _Component>
  void disconnect(_R(_Component::*_callback)(_Args...),
                  _Component * _listener) {
    static_assert(std::is_base_of<IComponent, _Component>::value,
                  "_listener is not derived from IComponent");
    if (_listener) {
      std::pair<IComponent *, tCallback> removedCallback = {
          static_cast<IComponent*>(_listener),
          static_cast<_R(IComponent::*)(_Args...)>(_callback)
        };

      auto erase = std::remove(unchecked_listeners_.begin(),
                               unchecked_listeners_.end(),
                               removedCallback);
      unchecked_listeners_.erase(erase, unchecked_listeners_.end());
    }
  }

  /**
   * Safe function for disconnect Event from object _listener with _callback
   * User can check if _listener is exist at moment of calling callback
   * @tparam _Component Type of object that listen Event
   * @param _callback method in object that listen Event
   * @param _listener Object that listen Event
   */
  template <typename _Component>
  void disconnect(_R(_Component::*_callback)(_Args...),
                  std::shared_ptr<_Component> _listener) {
    static_assert(std::is_base_of<IComponent, _Component>::value,
                  "_listener is not derived from IComponent");
    if(_listener) {
      std::pair<std::weak_ptr<IComponent>, tCallback> removedCallback = {
          static_cast<std::shared_ptr<IComponent>>(_listener),
          static_cast<_R(IComponent::*)(_Args...)>(_callback)
      };
      auto erase = std::remove_if(checked_listeners_.begin(),
                                  checked_listeners_.end(),
      [=](const std::pair<std::weak_ptr<IComponent>, tCallback> & rad) {
        bool result = false;
        if (auto _observer = rad.first.lock()) {
          result = (_callback == static_cast<void(_Component::*)(_Args...)>(rad.second));
        } else {
          result = true;
        }
        return result;
      });
      checked_listeners_.erase(erase, checked_listeners_.end());
    }
  }

  /**
   * Method for calling Event
   * @param _args Parameters for calling Event
   */
  void operator()(_Args... _args) {
    for (auto & listener : unchecked_listeners_) {
      (listener.first)->push([=]() mutable {
        ((listener.first)->*(listener.second))(std::forward<_Args>(_args)...);
      });
    }
    for (auto & listener : checked_listeners_) {
      if (auto _observer = listener.first.lock()) {
        _observer->push([=]() mutable {
          ((_observer.get())->*(listener.second))(std::forward<_Args>(_args)...);
        });
      } else {
        // TODO(redra): Delete it
      }
    }
  }

  /**
   * Method for calling const Event
   * @param _args Parameters for calling const Event
   */
  void operator()(_Args... _args) const {
    for (auto & listener : unchecked_listeners_) {
      (listener.first)->push([=]() mutable {
        ((listener.first)->*(listener.second))(std::forward<_Args>(_args)...);
      });
    }
    for (auto & listener : checked_listeners_) {
      if (auto _observer = listener.first.lock()) {
        _observer->push([=]() mutable {
          ((_observer.get())->*(listener.second))(std::forward<_Args>(_args)...);
        });
      } else {
        // TODO(redra): Delete it
      }
    }
  }

  /**
   * Convertion function is used to convert Event to std::function
   * @return std::function object
   */
  operator std::function<_R(_Args...)>() {
    return [event = *this](_Args... _args) mutable {
      for (auto & listener : event.unchecked_listeners_) {
        (listener.first)->push([=]() mutable {
          ((listener.first)->*(listener.second))(std::forward<_Args>(_args)...);
        });
      }
      for (auto & listener : event.checked_listeners_) {
        if (auto _observer = listener.first.lock()) {
          _observer->push([=]() mutable {
            ((_observer.get())->*(listener.second))(std::forward<_Args>(_args)...);
          });
        } else {
          // TODO(redra): Delete it
        }
      }
      return _R();
    };
  }

 private:
  tUncheckedListCallbacks unchecked_listeners_;
  tCheckedListCallbacks checked_listeners_;
};

#endif //ICC_EVENT_HPP
<commit_msg>Removed unsafe listeners in operator std::function<...><commit_after>/**
 * @file Event.hpp
 * @author Denis Kotov
 * @date 10 Jun 2017
 * @brief Contains abstract class for Pack Buffer
 * @copyright MIT License. Open source:
 */

#ifndef ICC_EVENT_HPP
#define ICC_EVENT_HPP

#include <vector>
#include <map>
#include <tuple>
#include <utility>
#include <algorithm>
#include "IComponent.hpp"

template <typename _T>
class Event;

template <typename _R, typename ... _Args>
class Event<_R(_Args...)> {
 public:
  using tCallback = _R(IComponent::*)(_Args...);
  using tUncheckedObjectAndCallbacks = std::pair<IComponent *, tCallback>;
  using tUncheckedListCallbacks = std::vector<tUncheckedObjectAndCallbacks>;
  using tCheckedObjectAndCallbacks = std::pair<std::weak_ptr<IComponent>, tCallback>;
  using tCheckedListCallbacks = std::vector<tCheckedObjectAndCallbacks>;
 public:
  Event() = default;
  Event(Event const&) = default;
  Event(Event &&) = default;

 public:
  /**
   * Unsafe function for connect Event to object _listener with _callback
   * User should be confident that _listener is exist at moment of calling callback
   * @tparam _Component Type of object that listen Event
   * @param _callback method in object that listen Event
   * @param _listener Object that listen Event
   */
  template <typename _Component>
  void connect(_R(_Component::*_callback)(_Args...),
               _Component * _listener) {
    static_assert(std::is_base_of<IComponent, _Component>::value,
                  "_listener is not derived from IComponent");
    if (_listener) {
      unchecked_listeners_.emplace_back(
          static_cast<IComponent*>(_listener),
          static_cast<_R(IComponent::*)(_Args...)>(_callback));
    }
  }

  /**
   * Safe function for connect Event to object _listener with _callback
   * User can check if _listener is exist at moment of calling callback
   * @tparam _Component Type of object that listen Event
   * @param _callback method in object that listen Event
   * @param _listener Object that listen Event
   */
  template <typename _Component>
  void connect(_R(_Component::*_callback)(_Args...),
               std::shared_ptr<_Component> _listener) {
    static_assert(std::is_base_of<IComponent, _Component>::value,
                  "_listener is not derived from IComponent");
    if(_listener) {
      checked_listeners_.emplace_back(
          static_cast<std::shared_ptr<IComponent>>(_listener),
          static_cast<_R(IComponent::*)(_Args...)>(_callback)
      );
    }
  }

  /**
   * Unsafe function for disconnect Event from object _listener with _callback
   * User should be confident that _listener is exist at moment of calling callback
   * @tparam _Component Type of object that listen Event
   * @param _callback method in object that listen Event
   * @param _listener Object that listen Event
   */
  template <typename _Component>
  void disconnect(_R(_Component::*_callback)(_Args...),
                  _Component * _listener) {
    static_assert(std::is_base_of<IComponent, _Component>::value,
                  "_listener is not derived from IComponent");
    if (_listener) {
      std::pair<IComponent *, tCallback> removedCallback = {
          static_cast<IComponent*>(_listener),
          static_cast<_R(IComponent::*)(_Args...)>(_callback)
        };

      auto erase = std::remove(unchecked_listeners_.begin(),
                               unchecked_listeners_.end(),
                               removedCallback);
      unchecked_listeners_.erase(erase, unchecked_listeners_.end());
    }
  }

  /**
   * Safe function for disconnect Event from object _listener with _callback
   * User can check if _listener is exist at moment of calling callback
   * @tparam _Component Type of object that listen Event
   * @param _callback method in object that listen Event
   * @param _listener Object that listen Event
   */
  template <typename _Component>
  void disconnect(_R(_Component::*_callback)(_Args...),
                  std::shared_ptr<_Component> _listener) {
    static_assert(std::is_base_of<IComponent, _Component>::value,
                  "_listener is not derived from IComponent");
    if(_listener) {
      std::pair<std::weak_ptr<IComponent>, tCallback> removedCallback = {
          static_cast<std::shared_ptr<IComponent>>(_listener),
          static_cast<_R(IComponent::*)(_Args...)>(_callback)
      };
      auto erase = std::remove_if(checked_listeners_.begin(),
                                  checked_listeners_.end(),
      [=](const std::pair<std::weak_ptr<IComponent>, tCallback> & rad) {
        bool result = false;
        if (auto _observer = rad.first.lock()) {
          result = (_callback == static_cast<void(_Component::*)(_Args...)>(rad.second));
        } else {
          result = true;
        }
        return result;
      });
      checked_listeners_.erase(erase, checked_listeners_.end());
    }
  }

  /**
   * Method for calling Event
   * @param _args Parameters for calling Event
   */
  void operator()(_Args... _args) {
    for (auto & listener : unchecked_listeners_) {
      (listener.first)->push([=]() mutable {
        ((listener.first)->*(listener.second))(std::forward<_Args>(_args)...);
      });
    }
    for (auto & listener : checked_listeners_) {
      if (auto _observer = listener.first.lock()) {
        _observer->push([=]() mutable {
          ((_observer.get())->*(listener.second))(std::forward<_Args>(_args)...);
        });
      } else {
        // TODO(redra): Delete it
      }
    }
  }

  /**
   * Method for calling const Event
   * @param _args Parameters for calling const Event
   */
  void operator()(_Args... _args) const {
    for (auto & listener : unchecked_listeners_) {
      (listener.first)->push([=]() mutable {
        ((listener.first)->*(listener.second))(std::forward<_Args>(_args)...);
      });
    }
    for (auto & listener : checked_listeners_) {
      if (auto _observer = listener.first.lock()) {
        _observer->push([=]() mutable {
          ((_observer.get())->*(listener.second))(std::forward<_Args>(_args)...);
        });
      } else {
        // TODO(redra): Delete it
      }
    }
  }

  /**
   * Convertion function is used to convert Event to std::function
   * @return std::function object
   */
  operator std::function<_R(_Args...)>() {
    return [event = *this](_Args... _args) mutable {
      for (auto & listener : event.checked_listeners_) {
        if (auto _observer = listener.first.lock()) {
          _observer->push([=]() mutable {
            ((_observer.get())->*(listener.second))(std::forward<_Args>(_args)...);
          });
        } else {
          // TODO(redra): Delete it
        }
      }
      return _R();
    };
  }

 private:
  tUncheckedListCallbacks unchecked_listeners_;
  tCheckedListCallbacks checked_listeners_;
};

#endif //ICC_EVENT_HPP
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// 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 "AMRVolume.h"
// ospray
#include "ospray/common/Model.h"
#include "ospray/common/Data.h"
#include "ospray/transferFunction/TransferFunction.h"
#include "ospcommon/tasking/parallel_for.h"
// ispc exports
#include "AMRVolume_ispc.h"
#include "finest_ispc.h"
#include "current_ispc.h"
#include "octant_ispc.h"
// stl
#include <set>
#include <map>

namespace ospray {
  namespace amr {

    AMRVolume::AMRVolume()
    {
      ispcEquivalent = ispc::AMRVolume_create(this);
    }

    std::string AMRVolume::toString() const
    {
      return "ospray::AMRVolume";
    }

    /*! Copy voxels into the volume at the given index (non-zero
      return value indicates success). */
    int AMRVolume::setRegion(const void *source,
                             const vec3i &index,
                             const vec3i &count)
    {
      FATAL("'setRegion()' doesn't make sense for AMR volumes; "
            "they can only be set from existing data");
    }

    //! Allocate storage and populate the volume.
    void AMRVolume::commit()
    {
      updateEditableParameters();

      // Make the voxel value range visible to the application.
      if (findParam("voxelRange") == nullptr)
        set("voxelRange", voxelRange);
      else
        voxelRange = getParam2f("voxelRange", voxelRange);

      auto methodStringFromEnv = getEnvVar<std::string>("OSPRAY_AMR_METHOD");
      std::string methodString = "current";

      if (methodStringFromEnv.first)
        methodString = methodStringFromEnv.second;
      else
        methodString = getParamString("amrMethod","current");

      if (methodString == "finest" || methodString == "finestLevel")
        ispc::AMR_install_finest(getIE());
      else if (methodString == "current" || methodString == "currentLevel")
        ispc::AMR_install_current(getIE());
      else if (methodString == "octant")
        ispc::AMR_install_octant(getIE());

      if (data != nullptr) //TODO: support data updates
        return;

      brickInfoData = getParamData("brickInfo");
      assert(brickInfoData);
      assert(brickInfoData->data);

      brickDataData = getParamData("brickData");
      assert(brickDataData);
      assert(brickDataData->data);

      assert(data == nullptr);
      data = new AMRData(*brickInfoData,*brickDataData);
      assert(accel == nullptr);
      accel = new AMRAccel(*data);

      Ref<TransferFunction> xf = (TransferFunction*)getParamObject("transferFunction");
      assert(xf);

      float finestLevelCellWidth = data->brick[0]->cellWidth;
      box3i rootLevelBox = empty;
      for (int i=0;i<data->numBricks;i++) {
        if (data->brick[i]->level == 0)
          rootLevelBox.extend(data->brick[i]->box);
        finestLevelCellWidth = min(finestLevelCellWidth,data->brick[i]->cellWidth);
      }
      vec3i rootGridDims = rootLevelBox.size()+vec3i(1);
      ospLogF(1) << "found root level dimensions of " << rootGridDims;

      // finding coarset cell size:
      float coarsestCellWidth = 0.f;
      for (int i=0;i<data->numBricks;i++)
        coarsestCellWidth = max(coarsestCellWidth,data->brick[i]->cellWidth);
      ospLogF(1) << "coarsest cell width is " << coarsestCellWidth << std::endl;
      float samplingStep = 0.1f*coarsestCellWidth;

      auto rateFromString = getEnvVar<std::string>("OSPRAY_AMR_SAMPLING_STEP");
      if (rateFromString.first)
        samplingStep = atof(rateFromString.second.c_str());

      box3f worldBounds = accel->worldBounds;

      ispc::AMRVolume_set(getIE(),
                          xf->getIE(),
                          (ispc::box3f&)worldBounds,
                          samplingStep);

      ispc::AMRVolume_setAMR(getIE(),
                             accel->node.size(),
                             &accel->node[0],
                             accel->leaf.size(),
                             &accel->leaf[0],
                             accel->level.size(),
                             &accel->level[0],
                             (ispc::box3f &)worldBounds);

      ospcommon::tasking::parallel_for(accel->leaf.size(),[&](int leafID) {
        ispc::AMRVolume_computeValueRangeOfLeaf(getIE(), leafID);
      });
    }

    OSP_REGISTER_VOLUME(AMRVolume, AMRVolume);
    OSP_REGISTER_VOLUME(AMRVolume, amr_volume);

  } // ::ospray::amr
} // ::ospray<commit_msg>build fix - file rename not caught locally<commit_after>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// 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 "AMRVolume.h"
// ospray
#include "ospray/common/Model.h"
#include "ospray/common/Data.h"
#include "ospray/transferFunction/TransferFunction.h"
#include "ospcommon/tasking/parallel_for.h"
// ispc exports
#include "AMRVolume_ispc.h"
#include "method_finest_ispc.h"
#include "method_current_ispc.h"
#include "method_octant_ispc.h"
// stl
#include <set>
#include <map>

namespace ospray {
  namespace amr {

    AMRVolume::AMRVolume()
    {
      ispcEquivalent = ispc::AMRVolume_create(this);
    }

    std::string AMRVolume::toString() const
    {
      return "ospray::AMRVolume";
    }

    /*! Copy voxels into the volume at the given index (non-zero
      return value indicates success). */
    int AMRVolume::setRegion(const void *source,
                             const vec3i &index,
                             const vec3i &count)
    {
      FATAL("'setRegion()' doesn't make sense for AMR volumes; "
            "they can only be set from existing data");
    }

    //! Allocate storage and populate the volume.
    void AMRVolume::commit()
    {
      updateEditableParameters();

      // Make the voxel value range visible to the application.
      if (findParam("voxelRange") == nullptr)
        set("voxelRange", voxelRange);
      else
        voxelRange = getParam2f("voxelRange", voxelRange);

      auto methodStringFromEnv = getEnvVar<std::string>("OSPRAY_AMR_METHOD");
      std::string methodString = "current";

      if (methodStringFromEnv.first)
        methodString = methodStringFromEnv.second;
      else
        methodString = getParamString("amrMethod","current");

      if (methodString == "finest" || methodString == "finestLevel")
        ispc::AMR_install_finest(getIE());
      else if (methodString == "current" || methodString == "currentLevel")
        ispc::AMR_install_current(getIE());
      else if (methodString == "octant")
        ispc::AMR_install_octant(getIE());

      if (data != nullptr) //TODO: support data updates
        return;

      brickInfoData = getParamData("brickInfo");
      assert(brickInfoData);
      assert(brickInfoData->data);

      brickDataData = getParamData("brickData");
      assert(brickDataData);
      assert(brickDataData->data);

      assert(data == nullptr);
      data = new AMRData(*brickInfoData,*brickDataData);
      assert(accel == nullptr);
      accel = new AMRAccel(*data);

      Ref<TransferFunction> xf = (TransferFunction*)getParamObject("transferFunction");
      assert(xf);

      float finestLevelCellWidth = data->brick[0]->cellWidth;
      box3i rootLevelBox = empty;
      for (int i=0;i<data->numBricks;i++) {
        if (data->brick[i]->level == 0)
          rootLevelBox.extend(data->brick[i]->box);
        finestLevelCellWidth = min(finestLevelCellWidth,data->brick[i]->cellWidth);
      }
      vec3i rootGridDims = rootLevelBox.size()+vec3i(1);
      ospLogF(1) << "found root level dimensions of " << rootGridDims;

      // finding coarset cell size:
      float coarsestCellWidth = 0.f;
      for (int i=0;i<data->numBricks;i++)
        coarsestCellWidth = max(coarsestCellWidth,data->brick[i]->cellWidth);
      ospLogF(1) << "coarsest cell width is " << coarsestCellWidth << std::endl;
      float samplingStep = 0.1f*coarsestCellWidth;

      auto rateFromString = getEnvVar<std::string>("OSPRAY_AMR_SAMPLING_STEP");
      if (rateFromString.first)
        samplingStep = atof(rateFromString.second.c_str());

      box3f worldBounds = accel->worldBounds;

      ispc::AMRVolume_set(getIE(),
                          xf->getIE(),
                          (ispc::box3f&)worldBounds,
                          samplingStep);

      ispc::AMRVolume_setAMR(getIE(),
                             accel->node.size(),
                             &accel->node[0],
                             accel->leaf.size(),
                             &accel->leaf[0],
                             accel->level.size(),
                             &accel->level[0],
                             (ispc::box3f &)worldBounds);

      ospcommon::tasking::parallel_for(accel->leaf.size(),[&](int leafID) {
        ispc::AMRVolume_computeValueRangeOfLeaf(getIE(), leafID);
      });
    }

    OSP_REGISTER_VOLUME(AMRVolume, AMRVolume);
    OSP_REGISTER_VOLUME(AMRVolume, amr_volume);

  } // ::ospray::amr
} // ::ospray<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//
// Arion
//
// Extract metadata and create beautiful thumbnails of your images.
//
// ------------
//   main.cpp
// ------------
//
// Copyright (c) 2015 Paul Filitchkin, Snapwire
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in
//      the documentation and/or other materials provided with the
//      distribution.
//
//    * Neither the name of the organization 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.
//
//------------------------------------------------------------------------------

// Local
#include "models/operation.hpp"
#include "models/resize.hpp"
#include "models/read_meta.hpp"
#include "utils/utils.hpp"
#include "arion.hpp"

// Boost
#include <boost/exception/info.hpp>
#include <boost/exception/error_info.hpp>
#include <boost/exception/all.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>
#include <boost/lexical_cast.hpp>

// Stdlib
#include <iostream>
#include <string>

using namespace boost::program_options;
using namespace std;

#define ARION_VERSION "0.3.1"

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void showHelp(options_description& desc)
{
  cerr << desc << endl;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
  try
  {
    positional_options_description p;
    p.add("input", 1);

    string description = "Arion v";
    description += ARION_VERSION;
    description += "\n\n Arguments";

    options_description desc(description);

    desc.add_options()
        ("help", "Produce this help message")
        ("version", "Print version")
        ("input", value< string >(), "The input operations to execute in JSON");

    variables_map vm;

    store(command_line_parser(argc, argv).options(desc).positional(p).run(), vm);

    notify(vm);

    string inputJson;

    if (vm.count("help"))
    {
      showHelp(desc);
      return 1;
    }

    if (vm.count("version"))
    {
      cout << "{\"version\":\"" << ARION_VERSION << "\"}" << endl;
      return 0;
    }

    if (vm.count("input"))
    {
      inputJson = vm["input"].as<string>();
    }
    else
    {
      cout << "You must provide the input operations to execute" << endl << endl;
      showHelp(desc);
      return 1;
    }

    Arion arion;

    if (!arion.setup(inputJson))
    {
      cout << arion.getJson();
      exit(-1);
    }

    bool result = arion.run();

    cout << arion.getJson();

    if (result)
    {
      exit(0);
    }
    else
    {
      exit(-1);
    }
  }
  catch (std::exception& e)
  {
    Utils::exitWithError(e.what());
  }

  return 0;
}
<commit_msg>version update<commit_after>//------------------------------------------------------------------------------
//
// Arion
//
// Extract metadata and create beautiful thumbnails of your images.
//
// ------------
//   main.cpp
// ------------
//
// Copyright (c) 2015 Paul Filitchkin, Snapwire
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in
//      the documentation and/or other materials provided with the
//      distribution.
//
//    * Neither the name of the organization 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.
//
//------------------------------------------------------------------------------

// Local
#include "models/operation.hpp"
#include "models/resize.hpp"
#include "models/read_meta.hpp"
#include "utils/utils.hpp"
#include "arion.hpp"

// Boost
#include <boost/exception/info.hpp>
#include <boost/exception/error_info.hpp>
#include <boost/exception/all.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>
#include <boost/lexical_cast.hpp>

// Stdlib
#include <iostream>
#include <string>

using namespace boost::program_options;
using namespace std;

#define ARION_VERSION "0.3.2"

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void showHelp(options_description& desc)
{
  cerr << desc << endl;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
  try
  {
    positional_options_description p;
    p.add("input", 1);

    string description = "Arion v";
    description += ARION_VERSION;
    description += "\n\n Arguments";

    options_description desc(description);

    desc.add_options()
        ("help", "Produce this help message")
        ("version", "Print version")
        ("input", value< string >(), "The input operations to execute in JSON");

    variables_map vm;

    store(command_line_parser(argc, argv).options(desc).positional(p).run(), vm);

    notify(vm);

    string inputJson;

    if (vm.count("help"))
    {
      showHelp(desc);
      return 1;
    }

    if (vm.count("version"))
    {
      cout << "{\"version\":\"" << ARION_VERSION << "\"}" << endl;
      return 0;
    }

    if (vm.count("input"))
    {
      inputJson = vm["input"].as<string>();
    }
    else
    {
      cout << "You must provide the input operations to execute" << endl << endl;
      showHelp(desc);
      return 1;
    }

    Arion arion;

    if (!arion.setup(inputJson))
    {
      cout << arion.getJson();
      exit(-1);
    }

    bool result = arion.run();

    cout << arion.getJson();

    if (result)
    {
      exit(0);
    }
    else
    {
      exit(-1);
    }
  }
  catch (std::exception& e)
  {
    Utils::exitWithError(e.what());
  }

  return 0;
}
<|endoftext|>


<commit_before>#include "vmainwindow.h"
#include <QApplication>
#include <QTranslator>
#include <QDebug>
#include <QLibraryInfo>
#include <QFile>
#include <QTextCodec>
#include <QFileInfo>
#include <QStringList>
#include <QDir>
#include "utils/vutils.h"
#include "vsingleinstanceguard.h"
#include "vconfigmanager.h"

VConfigManager *g_config;

#if defined(QT_NO_DEBUG)
QFile g_logFile;
#endif

void VLogger(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toUtf8();
    QString header;

    switch (type) {
    case QtDebugMsg:
        header = "Debug:";
        break;

    case QtInfoMsg:
        header = "Info:";
        break;

    case QtWarningMsg:
        header = "Warning:";
        break;

    case QtCriticalMsg:
        header = "Critical:";
        break;

    case QtFatalMsg:
        header = "Fatal:";
    }

#if defined(QT_NO_DEBUG)
    Q_UNUSED(context);

    QTextStream stream(&g_logFile);

#if defined(Q_OS_WIN)
    stream << header << localMsg << "\r\n";
#else
    stream << header << localMsg << "\n";
#endif

    if (type == QtFatalMsg) {
        g_logFile.close();
        abort();
    }

#else
    std::string fileStr = QFileInfo(context.file).fileName().toStdString();
    const char *file = fileStr.c_str();

    switch (type) {
    case QtDebugMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        break;
    case QtInfoMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        break;
    case QtWarningMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        break;
    case QtCriticalMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        break;
    case QtFatalMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        abort();
    }

    fflush(stderr);
#endif
}

int main(int argc, char *argv[])
{
    VSingleInstanceGuard guard;
    bool canRun = guard.tryRun();

#if defined(QT_NO_DEBUG)
    if (canRun) {
        g_logFile.setFileName(VConfigManager::getLogFilePath());
        g_logFile.open(QIODevice::WriteOnly);
    }
#endif

    if (canRun) {
        qInstallMessageHandler(VLogger);
    }

    QTextCodec *codec = QTextCodec::codecForName("UTF8");
    if (codec) {
        QTextCodec::setCodecForLocale(codec);
    }

    QApplication app(argc, argv);

    // The file path passed via command line arguments.
    QStringList filePaths = VUtils::filterFilePathsToOpen(app.arguments().mid(1));

    qDebug() << "command line arguments" << app.arguments();
    qDebug() << "files to open from arguments" << filePaths;

    if (!canRun) {
        // Ask another instance to open files passed in.
        if (!filePaths.isEmpty()) {
            guard.openExternalFiles(filePaths);
        } else {
            guard.showInstance();
        }

        return 0;
    }

    VConfigManager vconfig;
    vconfig.initialize();
    g_config = &vconfig;

    QString locale = VUtils::getLocale();
    // Set default locale.
    if (locale == "zh_CN") {
        QLocale::setDefault(QLocale(QLocale::Chinese, QLocale::China));
    }

    // load translation for Qt
    QTranslator qtTranslator;
    if (!qtTranslator.load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
        qtTranslator.load("qt_" + locale, "translations");
    }

    app.installTranslator(&qtTranslator);

    // load translation for vnote
    QTranslator translator;
    if (translator.load("vnote_" + locale, ":/translations")) {
        app.installTranslator(&translator);
    }

    VMainWindow w(&guard);
    QString style = VUtils::readFileFromDisk(":/resources/vnote.qss");
    if (!style.isEmpty()) {
        VUtils::processStyle(style, w.getPalette());
        app.setStyleSheet(style);
    }

    w.show();

    w.openStartupPages();

    w.openFiles(filePaths);

    w.promptNewNotebookIfEmpty();

    return app.exec();
}
<commit_msg>add openssl version check<commit_after>#include "vmainwindow.h"
#include <QApplication>
#include <QTranslator>
#include <QDebug>
#include <QLibraryInfo>
#include <QFile>
#include <QTextCodec>
#include <QFileInfo>
#include <QStringList>
#include <QDir>
#include <QSslSocket>
#include "utils/vutils.h"
#include "vsingleinstanceguard.h"
#include "vconfigmanager.h"

VConfigManager *g_config;

#if defined(QT_NO_DEBUG)
QFile g_logFile;
#endif

void VLogger(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toUtf8();
    QString header;

    switch (type) {
    case QtDebugMsg:
        header = "Debug:";
        break;

    case QtInfoMsg:
        header = "Info:";
        break;

    case QtWarningMsg:
        header = "Warning:";
        break;

    case QtCriticalMsg:
        header = "Critical:";
        break;

    case QtFatalMsg:
        header = "Fatal:";
    }

#if defined(QT_NO_DEBUG)
    Q_UNUSED(context);

    QTextStream stream(&g_logFile);

#if defined(Q_OS_WIN)
    stream << header << localMsg << "\r\n";
#else
    stream << header << localMsg << "\n";
#endif

    if (type == QtFatalMsg) {
        g_logFile.close();
        abort();
    }

#else
    std::string fileStr = QFileInfo(context.file).fileName().toStdString();
    const char *file = fileStr.c_str();

    switch (type) {
    case QtDebugMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        break;
    case QtInfoMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        break;
    case QtWarningMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        break;
    case QtCriticalMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        break;
    case QtFatalMsg:
        fprintf(stderr, "%s(%s:%u) %s\n",
                header.toStdString().c_str(), file, context.line, localMsg.constData());
        abort();
    }

    fflush(stderr);
#endif
}

int main(int argc, char *argv[])
{
    VSingleInstanceGuard guard;
    bool canRun = guard.tryRun();

#if defined(QT_NO_DEBUG)
    if (canRun) {
        g_logFile.setFileName(VConfigManager::getLogFilePath());
        g_logFile.open(QIODevice::WriteOnly);
    }
#endif

    if (canRun) {
        qInstallMessageHandler(VLogger);
    }

    QTextCodec *codec = QTextCodec::codecForName("UTF8");
    if (codec) {
        QTextCodec::setCodecForLocale(codec);
    }

    QApplication app(argc, argv);

    // Check the openSSL.
    qDebug() << "openSSL" << QSslSocket::sslLibraryBuildVersionString()
             << QSslSocket::sslLibraryVersionNumber();

    // The file path passed via command line arguments.
    QStringList filePaths = VUtils::filterFilePathsToOpen(app.arguments().mid(1));

    qDebug() << "command line arguments" << app.arguments();
    qDebug() << "files to open from arguments" << filePaths;

    if (!canRun) {
        // Ask another instance to open files passed in.
        if (!filePaths.isEmpty()) {
            guard.openExternalFiles(filePaths);
        } else {
            guard.showInstance();
        }

        return 0;
    }

    VConfigManager vconfig;
    vconfig.initialize();
    g_config = &vconfig;

    QString locale = VUtils::getLocale();
    // Set default locale.
    if (locale == "zh_CN") {
        QLocale::setDefault(QLocale(QLocale::Chinese, QLocale::China));
    }

    // load translation for Qt
    QTranslator qtTranslator;
    if (!qtTranslator.load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
        qtTranslator.load("qt_" + locale, "translations");
    }

    app.installTranslator(&qtTranslator);

    // load translation for vnote
    QTranslator translator;
    if (translator.load("vnote_" + locale, ":/translations")) {
        app.installTranslator(&translator);
    }

    VMainWindow w(&guard);
    QString style = VUtils::readFileFromDisk(":/resources/vnote.qss");
    if (!style.isEmpty()) {
        VUtils::processStyle(style, w.getPalette());
        app.setStyleSheet(style);
    }

    w.show();

    w.openStartupPages();

    w.openFiles(filePaths);

    w.promptNewNotebookIfEmpty();

    return app.exec();
}
<|endoftext|>


<commit_before>/*
 * File:   main.cpp
 * Author: vlad
 *
 * Created on December 12, 2013, 10:38 PM
 */

#include <iostream>

#include "qpp.h"
//#include "matlab.h" // support for MATLAB

// TODO: expandout function
// TODO: dyad function
// TODO: proj (dya) function
// TODO: ip (inner product function) function, make it general to return matrices
// TODO: Error class
// TODO: change all for(s) to column major order
// TODO: use .data() raw pointer instead of looping

using namespace std;

using namespace qpp;
using namespace qpp::types;

//int main(int argc, char **argv)
int main()
{
	_init();

	// Display formatting
	cout << std::fixed; // use fixed format for nice formatting
//	cout << std::scientific;
	cout << std::setprecision(4); // only for fixed or scientific modes

	cout << "Starting qpp..." << endl;

	size_t n = 12; // 12 qubits
	size_t N = std::pow(2, n);
	vector<size_t> dims; // local dimensions
	for (size_t i = 0; i < n; i++)
		dims.push_back(2);
	cout <<  "n = " << n << " qubits, matrix size " << N << " x " << N
			<< "." << endl;

	// TIMING
	Timer t, total;  // start the timer, automatic tic() in the constructor

	// Matrix initialization
	cout << endl << "Matrix initialization timing." << endl;
	cmat randcmat = cmat::Random(N, N);
	t.toc(); // read the time
	cout << "Took " << t.seconds() << " seconds." << endl;

	// Matrix product
	cout << endl << "Matrix product timing." << endl;
	t.tic(); // reset the chronometer
	cmat prodmat;
	prodmat = randcmat * randcmat; // need this (otherwise lazy evaluation)
	t.toc(); // read the time
	cout << "Took " << t.seconds() << " seconds." << endl;

	// ptrace SLOW SLOW SLOW
	cout << endl << "ptrace timing." << endl;
	vector<size_t> subsys_ptrace = { 0 };
	cout << "Subsytem(s): ";
	internal::_disp_container(subsys_ptrace);
	cout << endl;
	t.tic();
	ptrace(randcmat, subsys_ptrace, dims);
	t.toc();
	cout << "Took " << t.seconds() << " seconds." << endl;

	// ptranspose
	cout << endl << "ptranspose timing." << endl;
	vector<size_t> subsys_ptranspose; // partially transpose all subsystems
	for (size_t i = 0; i < n; i++)
		subsys_ptranspose.push_back(i);
	cout << "Subsytem(s): ";
	internal::_disp_container(subsys_ptranspose);
	cout << endl;
	t.tic();
	ptranspose(randcmat, subsys_ptranspose, dims);
	t.toc();
	cout << "Took " << t.seconds() << " seconds." << endl;

	// syspermute
	cout << endl << "syspermute timing." << endl;
	vector<size_t> perm; // left-shift all subsystems by 1
	for (size_t i = 0; i < n; i++)
		perm.push_back((i + 1) % n);
	cout << "Subsytem(s): ";
	internal::_disp_container(perm);
	cout << endl;
	t.tic();
	syspermute(randcmat, perm, dims);
	t.toc();
	cout << "Took " << t.seconds() << " seconds." << endl;

	total.toc(); // read the total running time
	cout << endl << "Total time: " << total.seconds() << " seconds." << endl;
	// END TIMING

	cout << "Exiting qpp..." << endl;
}
<commit_msg>commit<commit_after>/*
 * File:   main.cpp
 * Author: vlad
 *
 * Created on December 12, 2013, 10:38 PM
 */

#include <iostream>

#include "qpp.h"
//#include "matlab.h" // support for MATLAB

// TODO: expandout function
// TODO: dyad function
// TODO: proj (dya) function
// TODO: ip (inner product function) function, make it general to return matrices
// TODO: Error class
// TODO: change all for(s) to column major order
// TODO: use .data() raw pointer instead of looping

using namespace std;

using namespace qpp;
using namespace qpp::types;

//int main(int argc, char **argv)
int main()
{
	_init();

	// Display formatting
	cout << std::fixed; // use fixed format for nice formatting
//	cout << std::scientific;
	cout << std::setprecision(4); // only for fixed or scientific modes

	cout << "Starting qpp..." << endl;

	size_t n = 12; // 12 qubits
	size_t N = std::pow(2, n);
	vector<size_t> dims; // local dimensions
	for (size_t i = 0; i < n; i++)
		dims.push_back(2);
	cout <<  "n = " << n << " qubits, matrix size " << N << " x " << N
			<< "." << endl;

	// TIMING
	Timer t, total;  // start the timer, automatic tic() in the constructor

	// Matrix initialization
	cout << endl << "Matrix initialization timing." << endl;
	cmat randcmat = cmat::Random(N, N);
	t.toc(); // read the time
	cout << "Took " << t.seconds() << " seconds." << endl;

	// Matrix product
	cout << endl << "Matrix product timing." << endl;
	t.tic(); // reset the chronometer
	cmat prodmat;
	prodmat = randcmat * randcmat; // need this (otherwise lazy evaluation)
	t.toc(); // read the time
	cout << "Took " << t.seconds() << " seconds." << endl;

	// ptrace SLOW SLOW SLOW
	cout << endl << "ptrace timing." << endl;
	vector<size_t> subsys_ptrace = { 0 };
	cout << "Subsytem(s): [";
	internal::_disp_container(subsys_ptrace);
	cout<<"]"<<endl;
	t.tic();
	ptrace(randcmat, subsys_ptrace, dims);
	t.toc();
	cout << "Took " << t.seconds() << " seconds." << endl;

	// ptranspose
	cout << endl << "ptranspose timing." << endl;
	vector<size_t> subsys_ptranspose; // partially transpose all subsystems
	for (size_t i = 0; i < n; i++)
		subsys_ptranspose.push_back(i);
	cout << "Subsytem(s): [";
	internal::_disp_container(subsys_ptranspose);
	cout<<"]"<<endl;
	t.tic();
	ptranspose(randcmat, subsys_ptranspose, dims);
	t.toc();
	cout << "Took " << t.seconds() << " seconds." << endl;

	// syspermute
	cout << endl << "syspermute timing." << endl;
	vector<size_t> perm; // left-shift all subsystems by 1
	for (size_t i = 0; i < n; i++)
		perm.push_back((i + 1) % n);
	cout << "Subsytem(s): [";
	internal::_disp_container(perm);
	cout<<"]"<<endl;
	t.tic();
	syspermute(randcmat, perm, dims);
	t.toc();
	cout << "Took " << t.seconds() << " seconds." << endl;

	total.toc(); // read the total running time
	cout << endl << "Total time: " << total.seconds() << " seconds." << endl;
	// END TIMING

	cout << "Exiting qpp..." << endl;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Matthew Harvey
 *
 * 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.
 */

// TODO MEDIUM PRIORITY There is some flicker still when refreshing Report
// tabs on Windows.

// TODO MEDIUM PRIORITY Do proper "make package" instructions using CPack to
// make RPM and .deb packages.

// TODO MEDIUM PRIORITY Within "make install" and/or "make package" for
// Linux, include installation of icon and association of file extension with
// application so that .dcm files can be opened by double-clicking and so that
// application icon appears along with other applications' icons as usual for
// Gnome, KDE etc..

// TODO MEDIUM PRIORITY Under KDE (at least on Mageia) the way I have set
// up the widths of ComboBox and TextCtrl and wxButton (in various
// controls in which these feature), where they are
// supposed to be the same height, they actually turn out to be slightly
// different heights. However even if I manually set them all to the same
// hard-coded height number, they still seem to come out different heights
// on KDE. It doesn't make a lot of sense.

// TODO MEDIUM PRIORITY Tooltips aren't showing on Windows.

/// TODO MEDIUM PRIORITY The database file should perhaps have a checksum to
// guard against its contents changing other than via the application.

// TODO Facilitate automatic checking for updates from user's
// machine, or else provide an easy way for users to sign up to a mailing
// list that keeps them informed about updates.

// TODO HIGH PRIORITY Make the GUI display acceptably on smaller screen
// i.e. laptop.

// TODO MEDIUM PRIORITY Give user the option to export to CSV.

// TODO LOW PRIORITY Allow export/import to/from .qif (?) format.

// TODO MEDIUM PRIORITY Allow window borders to be dragged around, especially
// for DraftJournalListCtrl. This make it easier for users on laptops.

// TODO MEDIUM PRIORITY When the user creates a new file, ask if they want to
// create a shortcut to the file on their Desktop (assuming they didn't
// actually create the file in their desktop).

#include "app.hpp"
#include <wx/app.h>

wxIMPLEMENT_APP(dcm::App);
<commit_msg>Updated a TODO.<commit_after>/*
 * Copyright 2013 Matthew Harvey
 *
 * 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.
 */

// TODO MEDIUM PRIORITY There is some flicker still when refreshing Report
// tabs on Windows.

// TODO MEDIUM PRIORITY Do proper "make package" instructions using CPack to
// make RPM and .deb packages.

// TODO MEDIUM PRIORITY Within "make install" and/or "make package" for
// Linux, include installation of icon and association of file extension with
// application so that .dcm files can be opened by double-clicking and so that
// application icon appears along with other applications' icons as usual for
// Gnome, KDE etc..

// TODO MEDIUM PRIORITY Under KDE (at least on Mageia) the way I have set
// up the widths of ComboBox and TextCtrl and wxButton (in various
// controls in which these feature), where they are
// supposed to be the same height, they actually turn out to be slightly
// different heights. However even if I manually set them all to the same
// hard-coded height number, they still seem to come out different heights
// on KDE. It doesn't make a lot of sense.

// TODO MEDIUM PRIORITY Tooltips aren't showing on Windows.

/// TODO MEDIUM PRIORITY The database file should perhaps have a checksum to
// guard against its contents changing other than via the application.

// TODO LOW PRIORITY Facilitate automatic checking for updates from user's
// machine.

// TODO HIGH PRIORITY Make the GUI display acceptably on smaller screen
// i.e. laptop.

// TODO MEDIUM PRIORITY Give user the option to export to CSV.

// TODO LOW PRIORITY Allow export/import to/from .qif (?) format.

// TODO MEDIUM PRIORITY Allow window borders to be dragged around, especially
// for DraftJournalListCtrl. This make it easier for users on laptops.

// TODO MEDIUM PRIORITY When the user creates a new file, ask if they want to
// create a shortcut to the file on their Desktop (assuming they didn't
// actually create the file in their desktop).

#include "app.hpp"
#include <wx/app.h>

wxIMPLEMENT_APP(dcm::App);
<|endoftext|>