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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>

//Mitk
#include <mitkDataNode.h>
#include <mitkNodePredicateNot.h>
#include <mitkNodePredicateProperty.h>
#include <mitkIRenderingManager.h>

// Qmitk
#include "UltrasoundSupport.h"
#include <QTimer>

// Qt
#include <QMessageBox>

// Ultrasound
#include "mitkUSDevice.h"
#include "QmitkUSAbstractCustomWidget.h"

#include <usModuleContext.h>
#include <usGetModuleContext.h>
#include "usServiceReference.h"
#include "internal/org_mitk_gui_qt_ultrasound_Activator.h"

const std::string UltrasoundSupport::VIEW_ID = "org.mitk.views.ultrasoundsupport";

void UltrasoundSupport::SetFocus()
{
}

void UltrasoundSupport::CreateQtPartControl( QWidget *parent )
{
  m_Timer = new QTimer(this);

  // create GUI widgets from the Qt Designer's .ui file
  m_Controls.setupUi( parent );

  connect( m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this, SLOT(OnClickedAddNewDevice()) ); // Change Widget Visibilities
  connect( m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this->m_Controls.m_NewVideoDeviceWidget, SLOT(CreateNewDevice()) ); // Init NewDeviceWidget
  connect( m_Controls.m_NewVideoDeviceWidget, SIGNAL(Finished()), this, SLOT(OnNewDeviceWidgetDone()) ); // After NewDeviceWidget finished editing
  connect( m_Controls.m_BtnView, SIGNAL(clicked()), this, SLOT(OnClickedViewDevice()) );
  connect( m_Controls.m_FrameRate, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit(int)) );
  connect( m_Controls.m_FreezeButton, SIGNAL(clicked()), this, SLOT(OnClickedFreezeButton()) );
  connect( m_Timer, SIGNAL(timeout()), this, SLOT(DisplayImage()));

  // Initializations
  m_Controls.m_NewVideoDeviceWidget->setVisible(false);
  std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "="
      + "org.mitk.services.UltrasoundDevice)("
      + mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE + "=true))";
  m_Controls.m_ActiveVideoDevices->Initialize<mitk::USDevice>(
        mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL ,filter);

  m_Node = this->GetDataStorage()->GetNamedNode("US Image Stream");
  if (m_Node.IsNull())
  {
    // Create Node for US Stream
    m_Node = mitk::DataNode::New();
    m_Node->SetName("US Image Stream");
    this->GetDataStorage()->Add(m_Node);
  }

  m_Controls.tabWidget->setTabEnabled(1, false);
}

void UltrasoundSupport::OnClickedAddNewDevice()
{
  m_Controls.m_NewVideoDeviceWidget->setVisible(true);
  m_Controls.m_DeviceManagerWidget->setVisible(false);
  m_Controls.m_Headline->setText("Add New Video Device:");
  m_Controls.m_WidgetActiveDevices->setVisible(false);
}

void UltrasoundSupport::DisplayImage()
{
  m_Device->Modified();
  m_Device->Update();

  mitk::Image::Pointer curOutput = m_Device->GetOutput();
  if (! m_ImageAlreadySetToNode && curOutput.IsNotNull() && curOutput->IsInitialized())
  {
    m_Node->SetData(curOutput);
    m_ImageAlreadySetToNode = true;
  }

  if ( curOutput.GetPointer() != m_Node->GetData() )
  {
    MITK_INFO << "Data Node of the ultrasound image stream was changed by another plugin. Stop viewing.";
    this->StopViewing();
    return;
  }

  this->RequestRenderWindowUpdate();

  if ( curOutput->GetDimension() > 1
    && (curOutput->GetDimension(0) != m_CurrentImageWidth
    || curOutput->GetDimension(1) != m_CurrentImageHeight) )
  {
    // make a reinit on the ultrasound image
    mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
    if ( renderWindow != NULL && curOutput->GetTimeGeometry()->IsValid() )
    {
      renderWindow->GetRenderingManager()->InitializeViews(
        curOutput->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
      renderWindow->GetRenderingManager()->RequestUpdateAll();
    }

    m_CurrentImageWidth = curOutput->GetDimension(0);
    m_CurrentImageHeight = curOutput->GetDimension(1);
  }

  m_FrameCounter ++;
  if (m_FrameCounter == 10)
  {
    int nMilliseconds = m_Clock.restart();
    int fps = 10000.0f / (nMilliseconds );
    m_Controls.m_FramerateLabel->setText("Current Framerate: "+ QString::number(fps) +" FPS");
    m_FrameCounter = 0;
  }
}

void UltrasoundSupport::OnClickedViewDevice()
{
  m_FrameCounter = 0;
  // We use the activity state of the timer to determine whether we are currently viewing images
  if ( ! m_Timer->isActive() ) // Activate Imaging
  {
    this->StartViewing();
  }
  else //deactivate imaging
  {
    this->StopViewing();
  }
}

void UltrasoundSupport::OnChangedFramerateLimit(int value)
{
  m_Timer->setInterval(1000 / value);
}

void UltrasoundSupport::OnClickedFreezeButton()
{
  if ( m_Device->GetIsFreezed() )
  {
    m_Device->SetIsFreezed(false);
    m_Controls.m_FreezeButton->setText("Freeze");
  }
  else
  {
    m_Device->SetIsFreezed(true);
    m_Controls.m_FreezeButton->setText("Start Viewing Again");
  }
}

void UltrasoundSupport::OnNewDeviceWidgetDone()
{
  m_Controls.m_NewVideoDeviceWidget->setVisible(false);
  m_Controls.m_DeviceManagerWidget->setVisible(true);
  m_Controls.m_Headline->setText("Ultrasound Devices:");
  m_Controls.m_WidgetActiveDevices->setVisible(true);
}

void UltrasoundSupport::StartViewing()
{
  m_ImageAlreadySetToNode = false;

  m_Controls.tabWidget->setTabEnabled(1, true);
  m_Controls.tabWidget->setCurrentIndex(1);

  //get device & set data node
  m_Device = m_Controls.m_ActiveVideoDevices->GetSelectedService<mitk::USDevice>();
  if (m_Device.IsNull())
  {
    m_Timer->stop();
    return;
  }

  //start timer
  int interval = (1000 / m_Controls.m_FrameRate->value());
  m_Timer->setInterval(interval);
  m_Timer->start();

  //change UI elements
  m_Controls.m_BtnView->setText("Stop Viewing");

  this->CreateControlWidgets();
}

void UltrasoundSupport::StopViewing()
{
  m_Controls.tabWidget->setTabEnabled(1, false);

  this->RemoveControlWidgets();

  //stop timer & release data
  m_Timer->stop();
  m_Node->ReleaseData();
  this->RequestRenderWindowUpdate();

  //change UI elements
  m_Controls.m_BtnView->setText("Start Viewing");
}

void UltrasoundSupport::CreateControlWidgets()
{
  m_ControlProbesWidget = new QmitkUSControlsProbesWidget(m_Device->GetControlInterfaceProbes(), m_Controls.m_ToolBoxControlWidgets);
  m_Controls.probesWidgetContainer->addWidget(m_ControlProbesWidget);

  // create b mode widget for current device
  m_ControlBModeWidget = new QmitkUSControlsBModeWidget(m_Device->GetControlInterfaceBMode(), m_Controls.m_ToolBoxControlWidgets);
  m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlBModeWidget, "B Mode Controls");
  if ( ! m_Device->GetControlInterfaceBMode() )
  {
    m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false);
  }

  // create doppler widget for current device
  m_ControlDopplerWidget = new QmitkUSControlsDopplerWidget(m_Device->GetControlInterfaceDoppler(), m_Controls.m_ToolBoxControlWidgets);
  m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlDopplerWidget, "Doppler Controls");
  if ( ! m_Device->GetControlInterfaceDoppler() )
  {
    m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false);
  }

  ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
  if ( pluginContext )
  {
    std::string filter = "(ork.mitk.services.UltrasoundCustomWidget.deviceClass=" + m_Device->GetDeviceClass() + ")";

    QString interfaceName ( us_service_interface_iid<QmitkUSAbstractCustomWidget>() );
    m_CustomWidgetServiceReference = pluginContext->getServiceReferences(interfaceName, QString::fromStdString(filter));

    if (m_CustomWidgetServiceReference.size() > 0)
    {
      m_ControlCustomWidget = pluginContext->getService<QmitkUSAbstractCustomWidget>
        (m_CustomWidgetServiceReference.at(0))->CloneForQt(m_Controls.tab2);
      m_ControlCustomWidget->SetDevice(m_Device);
      m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlCustomWidget, "Custom Controls");
    }
    else
    {
      m_Controls.m_ToolBoxControlWidgets->addItem(new QWidget(m_Controls.m_ToolBoxControlWidgets), "Custom Controls");
      m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false);
    }
  }

  // select first enabled control widget
  for ( int n = 0; n < m_Controls.m_ToolBoxControlWidgets->count(); ++n)
  {
    if ( m_Controls.m_ToolBoxControlWidgets->isItemEnabled(n) )
    {
      m_Controls.m_ToolBoxControlWidgets->setCurrentIndex(n);
      break;
    }
  }
}

void UltrasoundSupport::RemoveControlWidgets()
{
  // remove all control widgets from the tool box widget
  while (m_Controls.m_ToolBoxControlWidgets->count() > 0)
  {
    m_Controls.m_ToolBoxControlWidgets->removeItem(0);
  }

  // remove probes widget (which is not part of the tool box widget)
  m_Controls.probesWidgetContainer->removeWidget(m_ControlProbesWidget);
  delete m_ControlProbesWidget;
  m_ControlProbesWidget = 0;

  delete m_ControlBModeWidget;
  m_ControlBModeWidget = 0;

  delete m_ControlDopplerWidget;
  m_ControlDopplerWidget = 0;

  // delete custom widget if it is present
  if ( m_ControlCustomWidget )
  {
    ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
    delete m_ControlCustomWidget; m_ControlCustomWidget = 0;

    if ( m_CustomWidgetServiceReference.size() > 0 )
    {
      pluginContext->ungetService(m_CustomWidgetServiceReference.at(0));
    }
  }
}

void UltrasoundSupport::OnDeciveServiceEvent(const ctkServiceEvent event)
{
  if ( m_Device.IsNull() || event.getType() != us::ServiceEvent::MODIFIED ) { return; }

  ctkServiceReference service = event.getServiceReference();

  if ( m_Device->GetDeviceManufacturer() != service.getProperty(mitk::USImageMetadata::PROP_DEV_MANUFACTURER).toString().toStdString()
    && m_Device->GetDeviceModel() != service.getProperty(mitk::USImageMetadata::PROP_DEV_MODEL).toString().toStdString() )
  {
    return;
  }

  if ( ! m_Device->GetIsActive() && m_Timer->isActive() )
  {
    this->StopViewing();
  }
}

UltrasoundSupport::UltrasoundSupport()
: m_ControlCustomWidget(0), m_ControlBModeWidget(0),
  m_ControlProbesWidget(0), m_ImageAlreadySetToNode(false),
  m_CurrentImageWidth(0), m_CurrentImageHeight(0)
{
  ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();

  if ( pluginContext )
  {
    // to be notified about service event of an USDevice
    pluginContext->connectServiceListener(this, "OnDeciveServiceEvent",
      QString::fromStdString("(" + us::ServiceConstants::OBJECTCLASS() + "=" + us_service_interface_iid<mitk::USDevice>() + ")"));
  }
}

UltrasoundSupport::~UltrasoundSupport()
{
}
<commit_msg>Commented out some code which is not working as intended and is only used by an internal navigation application.<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>

//Mitk
#include <mitkDataNode.h>
#include <mitkNodePredicateNot.h>
#include <mitkNodePredicateProperty.h>
#include <mitkIRenderingManager.h>

// Qmitk
#include "UltrasoundSupport.h"
#include <QTimer>

// Qt
#include <QMessageBox>

// Ultrasound
#include "mitkUSDevice.h"
#include "QmitkUSAbstractCustomWidget.h"

#include <usModuleContext.h>
#include <usGetModuleContext.h>
#include "usServiceReference.h"
#include "internal/org_mitk_gui_qt_ultrasound_Activator.h"

const std::string UltrasoundSupport::VIEW_ID = "org.mitk.views.ultrasoundsupport";

void UltrasoundSupport::SetFocus()
{
}

void UltrasoundSupport::CreateQtPartControl( QWidget *parent )
{
  m_Timer = new QTimer(this);

  // create GUI widgets from the Qt Designer's .ui file
  m_Controls.setupUi( parent );

  connect( m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this, SLOT(OnClickedAddNewDevice()) ); // Change Widget Visibilities
  connect( m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this->m_Controls.m_NewVideoDeviceWidget, SLOT(CreateNewDevice()) ); // Init NewDeviceWidget
  connect( m_Controls.m_NewVideoDeviceWidget, SIGNAL(Finished()), this, SLOT(OnNewDeviceWidgetDone()) ); // After NewDeviceWidget finished editing
  connect( m_Controls.m_BtnView, SIGNAL(clicked()), this, SLOT(OnClickedViewDevice()) );
  connect( m_Controls.m_FrameRate, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit(int)) );
  connect( m_Controls.m_FreezeButton, SIGNAL(clicked()), this, SLOT(OnClickedFreezeButton()) );
  connect( m_Timer, SIGNAL(timeout()), this, SLOT(DisplayImage()));

  // Initializations
  m_Controls.m_NewVideoDeviceWidget->setVisible(false);
  std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "="
      + "org.mitk.services.UltrasoundDevice)("
      + mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE + "=true))";
  m_Controls.m_ActiveVideoDevices->Initialize<mitk::USDevice>(
        mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL ,filter);

  m_Node = this->GetDataStorage()->GetNamedNode("US Image Stream");
  if (m_Node.IsNull())
  {
    // Create Node for US Stream
    m_Node = mitk::DataNode::New();
    m_Node->SetName("US Image Stream");
    this->GetDataStorage()->Add(m_Node);
  }

  m_Controls.tabWidget->setTabEnabled(1, false);
}

void UltrasoundSupport::OnClickedAddNewDevice()
{
  m_Controls.m_NewVideoDeviceWidget->setVisible(true);
  m_Controls.m_DeviceManagerWidget->setVisible(false);
  m_Controls.m_Headline->setText("Add New Video Device:");
  m_Controls.m_WidgetActiveDevices->setVisible(false);
}

void UltrasoundSupport::DisplayImage()
{
  m_Device->Modified();
  m_Device->Update();

  mitk::Image::Pointer curOutput = m_Device->GetOutput();
  if (! m_ImageAlreadySetToNode && curOutput.IsNotNull() && curOutput->IsInitialized())
  {
    m_Node->SetData(curOutput);
    m_ImageAlreadySetToNode = true;
  }

  /*if ( curOutput.GetPointer() != m_Node->GetData() )
  {
    MITK_INFO << "Data Node of the ultrasound image stream was changed by another plugin. Stop viewing.";
    this->StopViewing();
    return;
  }*/

  this->RequestRenderWindowUpdate();

  if ( curOutput->GetDimension() > 1
    && (curOutput->GetDimension(0) != m_CurrentImageWidth
    || curOutput->GetDimension(1) != m_CurrentImageHeight) )
  {
    // make a reinit on the ultrasound image
    mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
    if ( renderWindow != NULL && curOutput->GetTimeGeometry()->IsValid() )
    {
      renderWindow->GetRenderingManager()->InitializeViews(
        curOutput->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
      renderWindow->GetRenderingManager()->RequestUpdateAll();
    }

    m_CurrentImageWidth = curOutput->GetDimension(0);
    m_CurrentImageHeight = curOutput->GetDimension(1);
  }

  m_FrameCounter ++;
  if (m_FrameCounter == 10)
  {
    int nMilliseconds = m_Clock.restart();
    int fps = 10000.0f / (nMilliseconds );
    m_Controls.m_FramerateLabel->setText("Current Framerate: "+ QString::number(fps) +" FPS");
    m_FrameCounter = 0;
  }
}

void UltrasoundSupport::OnClickedViewDevice()
{
  m_FrameCounter = 0;
  // We use the activity state of the timer to determine whether we are currently viewing images
  if ( ! m_Timer->isActive() ) // Activate Imaging
  {
    this->StartViewing();
  }
  else //deactivate imaging
  {
    this->StopViewing();
  }
}

void UltrasoundSupport::OnChangedFramerateLimit(int value)
{
  m_Timer->setInterval(1000 / value);
}

void UltrasoundSupport::OnClickedFreezeButton()
{
  if ( m_Device->GetIsFreezed() )
  {
    m_Device->SetIsFreezed(false);
    m_Controls.m_FreezeButton->setText("Freeze");
  }
  else
  {
    m_Device->SetIsFreezed(true);
    m_Controls.m_FreezeButton->setText("Start Viewing Again");
  }
}

void UltrasoundSupport::OnNewDeviceWidgetDone()
{
  m_Controls.m_NewVideoDeviceWidget->setVisible(false);
  m_Controls.m_DeviceManagerWidget->setVisible(true);
  m_Controls.m_Headline->setText("Ultrasound Devices:");
  m_Controls.m_WidgetActiveDevices->setVisible(true);
}

void UltrasoundSupport::StartViewing()
{
  m_ImageAlreadySetToNode = false;

  m_Controls.tabWidget->setTabEnabled(1, true);
  m_Controls.tabWidget->setCurrentIndex(1);

  //get device & set data node
  m_Device = m_Controls.m_ActiveVideoDevices->GetSelectedService<mitk::USDevice>();
  if (m_Device.IsNull())
  {
    m_Timer->stop();
    return;
  }

  //start timer
  int interval = (1000 / m_Controls.m_FrameRate->value());
  m_Timer->setInterval(interval);
  m_Timer->start();

  //change UI elements
  m_Controls.m_BtnView->setText("Stop Viewing");

  this->CreateControlWidgets();
}

void UltrasoundSupport::StopViewing()
{
  m_Controls.tabWidget->setTabEnabled(1, false);

  this->RemoveControlWidgets();

  //stop timer & release data
  m_Timer->stop();
  m_Node->ReleaseData();
  this->RequestRenderWindowUpdate();

  //change UI elements
  m_Controls.m_BtnView->setText("Start Viewing");
}

void UltrasoundSupport::CreateControlWidgets()
{
  m_ControlProbesWidget = new QmitkUSControlsProbesWidget(m_Device->GetControlInterfaceProbes(), m_Controls.m_ToolBoxControlWidgets);
  m_Controls.probesWidgetContainer->addWidget(m_ControlProbesWidget);

  // create b mode widget for current device
  m_ControlBModeWidget = new QmitkUSControlsBModeWidget(m_Device->GetControlInterfaceBMode(), m_Controls.m_ToolBoxControlWidgets);
  m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlBModeWidget, "B Mode Controls");
  if ( ! m_Device->GetControlInterfaceBMode() )
  {
    m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false);
  }

  // create doppler widget for current device
  m_ControlDopplerWidget = new QmitkUSControlsDopplerWidget(m_Device->GetControlInterfaceDoppler(), m_Controls.m_ToolBoxControlWidgets);
  m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlDopplerWidget, "Doppler Controls");
  if ( ! m_Device->GetControlInterfaceDoppler() )
  {
    m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false);
  }

  ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
  if ( pluginContext )
  {
    std::string filter = "(ork.mitk.services.UltrasoundCustomWidget.deviceClass=" + m_Device->GetDeviceClass() + ")";

    QString interfaceName ( us_service_interface_iid<QmitkUSAbstractCustomWidget>() );
    m_CustomWidgetServiceReference = pluginContext->getServiceReferences(interfaceName, QString::fromStdString(filter));

    if (m_CustomWidgetServiceReference.size() > 0)
    {
      m_ControlCustomWidget = pluginContext->getService<QmitkUSAbstractCustomWidget>
        (m_CustomWidgetServiceReference.at(0))->CloneForQt(m_Controls.tab2);
      m_ControlCustomWidget->SetDevice(m_Device);
      m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlCustomWidget, "Custom Controls");
    }
    else
    {
      m_Controls.m_ToolBoxControlWidgets->addItem(new QWidget(m_Controls.m_ToolBoxControlWidgets), "Custom Controls");
      m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false);
    }
  }

  // select first enabled control widget
  for ( int n = 0; n < m_Controls.m_ToolBoxControlWidgets->count(); ++n)
  {
    if ( m_Controls.m_ToolBoxControlWidgets->isItemEnabled(n) )
    {
      m_Controls.m_ToolBoxControlWidgets->setCurrentIndex(n);
      break;
    }
  }
}

void UltrasoundSupport::RemoveControlWidgets()
{
  // remove all control widgets from the tool box widget
  while (m_Controls.m_ToolBoxControlWidgets->count() > 0)
  {
    m_Controls.m_ToolBoxControlWidgets->removeItem(0);
  }

  // remove probes widget (which is not part of the tool box widget)
  m_Controls.probesWidgetContainer->removeWidget(m_ControlProbesWidget);
  delete m_ControlProbesWidget;
  m_ControlProbesWidget = 0;

  delete m_ControlBModeWidget;
  m_ControlBModeWidget = 0;

  delete m_ControlDopplerWidget;
  m_ControlDopplerWidget = 0;

  // delete custom widget if it is present
  if ( m_ControlCustomWidget )
  {
    ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
    delete m_ControlCustomWidget; m_ControlCustomWidget = 0;

    if ( m_CustomWidgetServiceReference.size() > 0 )
    {
      pluginContext->ungetService(m_CustomWidgetServiceReference.at(0));
    }
  }
}

void UltrasoundSupport::OnDeciveServiceEvent(const ctkServiceEvent event)
{
  if ( m_Device.IsNull() || event.getType() != us::ServiceEvent::MODIFIED ) { return; }

  ctkServiceReference service = event.getServiceReference();

  if ( m_Device->GetDeviceManufacturer() != service.getProperty(mitk::USImageMetadata::PROP_DEV_MANUFACTURER).toString().toStdString()
    && m_Device->GetDeviceModel() != service.getProperty(mitk::USImageMetadata::PROP_DEV_MODEL).toString().toStdString() )
  {
    return;
  }

  if ( ! m_Device->GetIsActive() && m_Timer->isActive() )
  {
    this->StopViewing();
  }
}

UltrasoundSupport::UltrasoundSupport()
: m_ControlCustomWidget(0), m_ControlBModeWidget(0),
  m_ControlProbesWidget(0), m_ImageAlreadySetToNode(false),
  m_CurrentImageWidth(0), m_CurrentImageHeight(0)
{
  ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();

  if ( pluginContext )
  {
    // to be notified about service event of an USDevice
    pluginContext->connectServiceListener(this, "OnDeciveServiceEvent",
      QString::fromStdString("(" + us::ServiceConstants::OBJECTCLASS() + "=" + us_service_interface_iid<mitk::USDevice>() + ")"));
  }
}

UltrasoundSupport::~UltrasoundSupport()
{
}
<|endoftext|>


<commit_before>
/*
 *  Stream.cpp
 *  sfeMovie project
 *
 *  Copyright (C) 2010-2014 Lucas Soltic
 *  lucas.soltic@orange.fr
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <stdint.h>
}

#include "Demuxer.hpp"
#include "VideoStream.hpp"
#include "AudioStream.hpp"
#include "SubtitleStream.hpp"
#include "Log.hpp"
#include "Utilities.hpp"
#include <iostream>
#include <stdexcept>

namespace sfe
{
    std::list<Demuxer::DemuxerInfo> Demuxer::g_availableDemuxers;
    std::list<Demuxer::DecoderInfo> Demuxer::g_availableDecoders;

    static void loadFFmpeg()
    {
        ONCE(av_register_all());
        ONCE(avcodec_register_all());
        ONCE(Log::initialize());
    }

    static MediaType AVMediaTypeToMediaType(AVMediaType type)
    {
        switch (type)
        {
            case AVMEDIA_TYPE_AUDIO:    return Audio;
            case AVMEDIA_TYPE_SUBTITLE:    return Subtitle;
            case AVMEDIA_TYPE_VIDEO:    return Video;
            default:                    return Unknown;
        }
    }

    const std::list<Demuxer::DemuxerInfo>& Demuxer::getAvailableDemuxers()
    {
        AVInputFormat* demuxer = NULL;
        loadFFmpeg();

        if (g_availableDemuxers.empty())
        {
            while (NULL != (demuxer = av_iformat_next(demuxer)))
            {
                DemuxerInfo info =
                {
                    std::string(demuxer->name),
                    std::string(demuxer->long_name)
                };

                g_availableDemuxers.push_back(info);
            }
        }

        return g_availableDemuxers;
    }

    const std::list<Demuxer::DecoderInfo>& Demuxer::getAvailableDecoders()
    {
        AVCodec* codec = NULL;
        loadFFmpeg();

        if (g_availableDecoders.empty())
        {
            while (NULL != (codec = av_codec_next(codec)))
            {
                DecoderInfo info =
                {
                    avcodec_get_name(codec->id),
                    codec->long_name,
                    AVMediaTypeToMediaType(codec->type)
                };

                g_availableDecoders.push_back(info);
            }
        }

        return g_availableDecoders;
    }

    Demuxer::Demuxer(const std::string& sourceFile, Timer& timer, VideoStream::Delegate& videoDelegate, SubtitleStream::Delegate& subtitleDelegate) :
    m_formatCtx(NULL),
    m_eofReached(false),
    m_streams(),
    m_ignoredStreams(),
    m_synchronized(),
    m_timer(timer),
    m_connectedAudioStream(NULL),
    m_connectedVideoStream(NULL),
    m_duration(sf::Time::Zero)
    {
        CHECK(sourceFile.size(), "Demuxer::Demuxer() - invalid argument: sourceFile");

        int err = 0;

        // Load all the decoders
        loadFFmpeg();

        // Open the movie file
        err = avformat_open_input(&m_formatCtx, sourceFile.c_str(), NULL, NULL);
        CHECK0(err, "Demuxer::Demuxer() - error while opening media: " + sourceFile);
        CHECK(m_formatCtx, "Demuxer() - inconsistency: media context cannot be null");

        // Read the general movie informations
        err = avformat_find_stream_info(m_formatCtx, NULL);
        CHECK0(err, "Demuxer::Demuxer() - error while retreiving media information");

        // Get the media duration if possible (otherwise rely on the streams)
        if (m_formatCtx->duration != AV_NOPTS_VALUE)
        {
            long secs, us;
            secs = m_formatCtx->duration / AV_TIME_BASE;
            us = m_formatCtx->duration % AV_TIME_BASE;
            m_duration = sf::seconds(secs + (float)us / AV_TIME_BASE);
        }

        // Find all interesting streams
        for (unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
        {
            AVStream* ffstream = m_formatCtx->streams[i];

            try
            {
                switch (ffstream->codec->codec_type)
                {
                    case AVMEDIA_TYPE_VIDEO:
                        m_streams[ffstream->index] = new VideoStream(m_formatCtx, ffstream, *this, timer, videoDelegate);

                        if (m_duration == sf::Time::Zero)
                        {
                            extractDurationFromStream(ffstream);
                        }

                        sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " video stream");
                        break;

                    case AVMEDIA_TYPE_AUDIO:
                        m_streams[ffstream->index] = new AudioStream(m_formatCtx, ffstream, *this, timer);

                        if (m_duration == sf::Time::Zero)
                        {
                            extractDurationFromStream(ffstream);
                        }

                        sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " audio stream");
                        break;
                    case AVMEDIA_TYPE_SUBTITLE:
                        m_streams[ffstream->index] = new SubtitleStream(m_formatCtx, ffstream, *this, timer, subtitleDelegate);

                        if (m_duration == sf::Time::Zero)
                        {
                            extractDurationFromStream(ffstream);
                        }

                        sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " subtitle stream");
                        break;
                    default:
                        m_ignoredStreams[ffstream->index] = std::string("'" + std::string(av_get_media_type_string(ffstream->codec->codec_type)) + "/" + avcodec_get_name(ffstream->codec->codec_id));
                        sfeLogDebug(m_ignoredStreams[ffstream->index] + "' stream ignored");
                        break;
                }
            } catch (std::runtime_error& e)
            {
                std::cerr << "Demuxer::Demuxer() - " << e.what() << std::endl;
            }
        }

        if (m_duration == sf::Time::Zero)
        {
            sfeLogWarning("The media duration could not be retreived");
        }

        m_timer.addObserver(*this);
    }

    Demuxer::~Demuxer()
    {
        if (m_timer.getStatus() != Stopped)
            m_timer.stop();

        m_timer.removeObserver(*this);

        while (m_streams.size())
        {
            delete m_streams.begin()->second;
            m_streams.erase(m_streams.begin());
        }

        if (m_formatCtx)
        {
            avformat_close_input(&m_formatCtx);
        }
    }

    const std::map<int, Stream*>& Demuxer::getStreams() const
    {
        return m_streams;
    }

    std::set<Stream*> Demuxer::getStreamsOfType(MediaType type) const
    {
        std::set<Stream*> streamSet;
        std::map<int, Stream*>::const_iterator it;

        for (it = m_streams.begin(); it != m_streams.end(); it++)
        {
            if (it->second->getStreamKind() == type)
                streamSet.insert(it->second);
        }

        return streamSet;
    }

    Streams Demuxer::computeStreamDescriptors(MediaType type) const
    {
        Streams entries;
        std::set<Stream*> streamSet;
        std::map<int, Stream*>::const_iterator it;

        for (it = m_streams.begin(); it != m_streams.end(); it++)
        {
            if (it->second->getStreamKind() == type)
            {
                StreamDescriptor entry;
                entry.type = type;
                entry.identifier = it->first;
                entry.language = it->second->getLanguage();
                entries.push_back(entry);
            }
        }

        return entries;
    }

    void Demuxer::selectAudioStream(AudioStream* stream)
    {
        Status oldStatus = m_timer.getStatus();
        CHECK(oldStatus == Stopped, "Changing the selected stream after starting "
              "the movie playback isn't supported yet");

        if (oldStatus == Playing)
            m_timer.pause();

        if (stream != m_connectedAudioStream)
        {
            if (m_connectedAudioStream)
            {
                m_connectedAudioStream->disconnect();
            }

            if (stream)
                stream->connect();

            m_connectedAudioStream = stream;
        }

        if (oldStatus == Playing)
            m_timer.play();
    }

    void Demuxer::selectFirstAudioStream()
    {
        std::set<Stream*> audioStreams = getStreamsOfType(Audio);
        if (audioStreams.size())
            selectAudioStream(dynamic_cast<AudioStream*>(*audioStreams.begin()));
    }

    AudioStream* Demuxer::getSelectedAudioStream() const
    {
        return dynamic_cast<AudioStream*>(m_connectedAudioStream);
    }

    void Demuxer::selectVideoStream(VideoStream* stream)
    {
        Status oldStatus = m_timer.getStatus();
        CHECK(oldStatus == Stopped, "Changing the selected stream after starting "
              "the movie playback isn't supported yet");

        if (oldStatus == Playing)
            m_timer.pause();

        if (stream != m_connectedVideoStream)
        {
            if (m_connectedVideoStream)
            {
                m_connectedVideoStream->disconnect();
            }

            if (stream)
                stream->connect();

            m_connectedVideoStream = stream;
        }

        if (oldStatus == Playing)
            m_timer.play();
    }

    void Demuxer::selectFirstVideoStream()
    {
        std::set<Stream*> videoStreams = getStreamsOfType(Video);
        if (videoStreams.size())
            selectVideoStream(dynamic_cast<VideoStream*>(*videoStreams.begin()));
    }

    VideoStream* Demuxer::getSelectedVideoStream() const
    {
        return dynamic_cast<VideoStream*>(m_connectedVideoStream);
    }

    void Demuxer::selectSubtitleStream(SubtitleStream* stream)
    {
        Status oldStatus = m_timer.getStatus();

        if (oldStatus == Playing)
            m_timer.pause();

        if (stream != m_connectedSubtitleStream)
        {
            if (m_connectedSubtitleStream)
                m_connectedSubtitleStream->disconnect();

            if (stream)
                stream->connect();

            m_connectedSubtitleStream = stream;
        }

        if (oldStatus == Playing)
            m_timer.play();
    }

    void Demuxer::selectFirstSubtitleStream()
    {
        std::set<Stream*> subtitleStreams = getStreamsOfType(Subtitle);
        if (subtitleStreams.size())
            selectSubtitleStream(dynamic_cast<SubtitleStream*>(*subtitleStreams.begin()));
    }

    SubtitleStream* Demuxer::getSelectedSubtitleStream() const
    {
        return dynamic_cast<SubtitleStream*>(m_connectedSubtitleStream);
    }

    void Demuxer::feedStream(Stream& stream)
    {
        sf::Lock l(m_synchronized);
        sfeLogDebug("Feed " + mediaTypeToString(stream.getStreamKind()) + " stream");

        while (!didReachEndOfFile() && stream.needsMoreData())
        {
            AVPacket* pkt = readPacket();

            if (!pkt)
            {
                m_eofReached = true;
            }
            else
            {
                if (!distributePacket(pkt))
                {
                    sfeLogWarning(m_ignoredStreams[pkt->stream_index] + " packet not handled and dropped");
                    av_free_packet(pkt);
                    av_free(pkt);
                }
            }
        }
    }

    void Demuxer::update()
    {
        std::map<int, Stream*> streams = getStreams();
        std::map<int, Stream*>::iterator it;

        for (it = streams.begin();it != streams.end(); it++)
        {
            it->second->update();
        }
    }

    bool Demuxer::didReachEndOfFile() const
    {
        return m_eofReached;
    }

    sf::Time Demuxer::getDuration() const
    {
        return m_duration;
    }

    AVPacket* Demuxer::readPacket()
    {
        sf::Lock l(m_synchronized);

        AVPacket *pkt = NULL;
        int err = 0;

        pkt = (AVPacket *)av_malloc(sizeof(*pkt));
        CHECK(pkt, "Demuxer::readPacket() - out of memory");
        av_init_packet(pkt);

        err = av_read_frame(m_formatCtx, pkt);

        if (err < 0)
        {
            av_free_packet(pkt);
            av_free(pkt);
            pkt = NULL;
        }

        return pkt;
    }

    bool Demuxer::distributePacket(AVPacket* packet)
    {
        sf::Lock l(m_synchronized);
        CHECK(packet, "Demuxer::distributePacket() - invalid argument");

        bool result = false;
        std::map<int, Stream*>::iterator it = m_streams.find(packet->stream_index);

        if (it != m_streams.end())
        {
            it->second->pushEncodedData(packet);
            result = true;
        }

        return result;
    }

    void Demuxer::extractDurationFromStream(AVStream* stream)
    {
        if (m_duration != sf::Time::Zero)
            return;

        if (stream->duration != AV_NOPTS_VALUE)
        {
            long secs, us;
            secs = stream->duration / AV_TIME_BASE;
            us = stream->duration % AV_TIME_BASE;
            m_duration = sf::seconds(secs + (float)us / AV_TIME_BASE);
        }
    }

    void Demuxer::requestMoreData(Stream& starvingStream)
    {
        sf::Lock l(m_synchronized);

        feedStream(starvingStream);
    }

    void Demuxer::resetEndOfFileStatus()
    {
        m_eofReached = false;
    }

    void Demuxer::willSeek(const Timer &timer, sf::Time position)
    {
        resetEndOfFileStatus();

        if (m_formatCtx->iformat->flags & AVFMT_SEEK_TO_PTS)
        {
            int64_t timestamp = 0;

            if (m_formatCtx->start_time != AV_NOPTS_VALUE)
                timestamp += m_formatCtx->start_time;

            int err = avformat_seek_file(m_formatCtx, -1, INT64_MIN, timestamp, INT64_MAX, AVSEEK_FLAG_BACKWARD);
            sfeLogDebug("Seek by PTS at timestamp=" + s(timestamp) + " returned " + s(err));
        }
        else
        {
            int err = avformat_seek_file(m_formatCtx, -1, INT64_MIN, 0, INT64_MAX, AVSEEK_FLAG_BACKWARD);
            //            sfeLogDebug("Seek by PTS at timestamp=" + s(timestamp) + " returned " + s(err));

            //            int err = av_seek_frame(m_formatCtx, m_streamID, -999999, AVSEEK_FLAG_BACKWARD);
            sfeLogDebug("Seek by DTS at timestamp " + s(-9999) + " returned " + s(err));
        }
    }
}
<commit_msg>#7 Fixed a bug that would cause sfeMovie to crash (subtitleStream didn't get initialized, so getSelectedSubtitleStream() would crash)<commit_after>
/*
 *  Stream.cpp
 *  sfeMovie project
 *
 *  Copyright (C) 2010-2014 Lucas Soltic
 *  lucas.soltic@orange.fr
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <stdint.h>
}

#include "Demuxer.hpp"
#include "VideoStream.hpp"
#include "AudioStream.hpp"
#include "SubtitleStream.hpp"
#include "Log.hpp"
#include "Utilities.hpp"
#include <iostream>
#include <stdexcept>

namespace sfe
{
    std::list<Demuxer::DemuxerInfo> Demuxer::g_availableDemuxers;
    std::list<Demuxer::DecoderInfo> Demuxer::g_availableDecoders;

    static void loadFFmpeg()
    {
        ONCE(av_register_all());
        ONCE(avcodec_register_all());
        ONCE(Log::initialize());
    }

    static MediaType AVMediaTypeToMediaType(AVMediaType type)
    {
        switch (type)
        {
            case AVMEDIA_TYPE_AUDIO:    return Audio;
            case AVMEDIA_TYPE_SUBTITLE:    return Subtitle;
            case AVMEDIA_TYPE_VIDEO:    return Video;
            default:                    return Unknown;
        }
    }

    const std::list<Demuxer::DemuxerInfo>& Demuxer::getAvailableDemuxers()
    {
        AVInputFormat* demuxer = NULL;
        loadFFmpeg();

        if (g_availableDemuxers.empty())
        {
            while (NULL != (demuxer = av_iformat_next(demuxer)))
            {
                DemuxerInfo info =
                {
                    std::string(demuxer->name),
                    std::string(demuxer->long_name)
                };

                g_availableDemuxers.push_back(info);
            }
        }

        return g_availableDemuxers;
    }

    const std::list<Demuxer::DecoderInfo>& Demuxer::getAvailableDecoders()
    {
        AVCodec* codec = NULL;
        loadFFmpeg();

        if (g_availableDecoders.empty())
        {
            while (NULL != (codec = av_codec_next(codec)))
            {
                DecoderInfo info =
                {
                    avcodec_get_name(codec->id),
                    codec->long_name,
                    AVMediaTypeToMediaType(codec->type)
                };

                g_availableDecoders.push_back(info);
            }
        }

        return g_availableDecoders;
    }

    Demuxer::Demuxer(const std::string& sourceFile, Timer& timer, VideoStream::Delegate& videoDelegate, SubtitleStream::Delegate& subtitleDelegate) :
    m_formatCtx(NULL),
    m_eofReached(false),
    m_streams(),
    m_ignoredStreams(),
    m_synchronized(),
    m_timer(timer),
    m_connectedAudioStream(NULL),
    m_connectedVideoStream(NULL),
    m_connectedSubtitleStream(NULL),
    m_duration(sf::Time::Zero)
    {
        CHECK(sourceFile.size(), "Demuxer::Demuxer() - invalid argument: sourceFile");

        int err = 0;

        // Load all the decoders
        loadFFmpeg();

        // Open the movie file
        err = avformat_open_input(&m_formatCtx, sourceFile.c_str(), NULL, NULL);
        CHECK0(err, "Demuxer::Demuxer() - error while opening media: " + sourceFile);
        CHECK(m_formatCtx, "Demuxer() - inconsistency: media context cannot be null");

        // Read the general movie informations
        err = avformat_find_stream_info(m_formatCtx, NULL);
        CHECK0(err, "Demuxer::Demuxer() - error while retreiving media information");

        // Get the media duration if possible (otherwise rely on the streams)
        if (m_formatCtx->duration != AV_NOPTS_VALUE)
        {
            long secs, us;
            secs = m_formatCtx->duration / AV_TIME_BASE;
            us = m_formatCtx->duration % AV_TIME_BASE;
            m_duration = sf::seconds(secs + (float)us / AV_TIME_BASE);
        }

        // Find all interesting streams
        for (unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
        {
            AVStream* ffstream = m_formatCtx->streams[i];

            try
            {
                switch (ffstream->codec->codec_type)
                {
                    case AVMEDIA_TYPE_VIDEO:
                        m_streams[ffstream->index] = new VideoStream(m_formatCtx, ffstream, *this, timer, videoDelegate);

                        if (m_duration == sf::Time::Zero)
                        {
                            extractDurationFromStream(ffstream);
                        }

                        sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " video stream");
                        break;

                    case AVMEDIA_TYPE_AUDIO:
                        m_streams[ffstream->index] = new AudioStream(m_formatCtx, ffstream, *this, timer);

                        if (m_duration == sf::Time::Zero)
                        {
                            extractDurationFromStream(ffstream);
                        }

                        sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " audio stream");
                        break;
                    case AVMEDIA_TYPE_SUBTITLE:
                        m_streams[ffstream->index] = new SubtitleStream(m_formatCtx, ffstream, *this, timer, subtitleDelegate);

                        if (m_duration == sf::Time::Zero)
                        {
                            extractDurationFromStream(ffstream);
                        }

                        sfeLogDebug("Loaded " + avcodec_get_name(ffstream->codec->codec_id) + " subtitle stream");
                        break;
                    default:
                        m_ignoredStreams[ffstream->index] = std::string("'" + std::string(av_get_media_type_string(ffstream->codec->codec_type)) + "/" + avcodec_get_name(ffstream->codec->codec_id));
                        sfeLogDebug(m_ignoredStreams[ffstream->index] + "' stream ignored");
                        break;
                }
            } catch (std::runtime_error& e)
            {
                std::cerr << "Demuxer::Demuxer() - " << e.what() << std::endl;
            }
        }

        if (m_duration == sf::Time::Zero)
        {
            sfeLogWarning("The media duration could not be retreived");
        }

        m_timer.addObserver(*this);
    }

    Demuxer::~Demuxer()
    {
        if (m_timer.getStatus() != Stopped)
            m_timer.stop();

        m_timer.removeObserver(*this);

        while (m_streams.size())
        {
            delete m_streams.begin()->second;
            m_streams.erase(m_streams.begin());
        }

        if (m_formatCtx)
        {
            avformat_close_input(&m_formatCtx);
        }
    }

    const std::map<int, Stream*>& Demuxer::getStreams() const
    {
        return m_streams;
    }

    std::set<Stream*> Demuxer::getStreamsOfType(MediaType type) const
    {
        std::set<Stream*> streamSet;
        std::map<int, Stream*>::const_iterator it;

        for (it = m_streams.begin(); it != m_streams.end(); it++)
        {
            if (it->second->getStreamKind() == type)
                streamSet.insert(it->second);
        }

        return streamSet;
    }

    Streams Demuxer::computeStreamDescriptors(MediaType type) const
    {
        Streams entries;
        std::set<Stream*> streamSet;
        std::map<int, Stream*>::const_iterator it;

        for (it = m_streams.begin(); it != m_streams.end(); it++)
        {
            if (it->second->getStreamKind() == type)
            {
                StreamDescriptor entry;
                entry.type = type;
                entry.identifier = it->first;
                entry.language = it->second->getLanguage();
                entries.push_back(entry);
            }
        }

        return entries;
    }

    void Demuxer::selectAudioStream(AudioStream* stream)
    {
        Status oldStatus = m_timer.getStatus();
        CHECK(oldStatus == Stopped, "Changing the selected stream after starting "
              "the movie playback isn't supported yet");

        if (oldStatus == Playing)
            m_timer.pause();

        if (stream != m_connectedAudioStream)
        {
            if (m_connectedAudioStream)
            {
                m_connectedAudioStream->disconnect();
            }

            if (stream)
                stream->connect();

            m_connectedAudioStream = stream;
        }

        if (oldStatus == Playing)
            m_timer.play();
    }

    void Demuxer::selectFirstAudioStream()
    {
        std::set<Stream*> audioStreams = getStreamsOfType(Audio);
        if (audioStreams.size())
            selectAudioStream(dynamic_cast<AudioStream*>(*audioStreams.begin()));
    }

    AudioStream* Demuxer::getSelectedAudioStream() const
    {
        return dynamic_cast<AudioStream*>(m_connectedAudioStream);
    }

    void Demuxer::selectVideoStream(VideoStream* stream)
    {
        Status oldStatus = m_timer.getStatus();
        CHECK(oldStatus == Stopped, "Changing the selected stream after starting "
              "the movie playback isn't supported yet");

        if (oldStatus == Playing)
            m_timer.pause();

        if (stream != m_connectedVideoStream)
        {
            if (m_connectedVideoStream)
            {
                m_connectedVideoStream->disconnect();
            }

            if (stream)
                stream->connect();

            m_connectedVideoStream = stream;
        }

        if (oldStatus == Playing)
            m_timer.play();
    }

    void Demuxer::selectFirstVideoStream()
    {
        std::set<Stream*> videoStreams = getStreamsOfType(Video);
        if (videoStreams.size())
            selectVideoStream(dynamic_cast<VideoStream*>(*videoStreams.begin()));
    }

    VideoStream* Demuxer::getSelectedVideoStream() const
    {
        return dynamic_cast<VideoStream*>(m_connectedVideoStream);
    }

    void Demuxer::selectSubtitleStream(SubtitleStream* stream)
    {
        Status oldStatus = m_timer.getStatus();

        if (oldStatus == Playing)
            m_timer.pause();

        if (stream != m_connectedSubtitleStream)
        {
            if (m_connectedSubtitleStream)
                m_connectedSubtitleStream->disconnect();

            if (stream)
                stream->connect();

            m_connectedSubtitleStream = stream;
        }

        if (oldStatus == Playing)
            m_timer.play();
    }

    void Demuxer::selectFirstSubtitleStream()
    {
        std::set<Stream*> subtitleStreams = getStreamsOfType(Subtitle);
        if (subtitleStreams.size())
            selectSubtitleStream(dynamic_cast<SubtitleStream*>(*subtitleStreams.begin()));
    }

    SubtitleStream* Demuxer::getSelectedSubtitleStream() const
    {
        return dynamic_cast<SubtitleStream*>(m_connectedSubtitleStream);
    }

    void Demuxer::feedStream(Stream& stream)
    {
        sf::Lock l(m_synchronized);
        sfeLogDebug("Feed " + mediaTypeToString(stream.getStreamKind()) + " stream");

        while (!didReachEndOfFile() && stream.needsMoreData())
        {
            AVPacket* pkt = readPacket();

            if (!pkt)
            {
                m_eofReached = true;
            }
            else
            {
                if (!distributePacket(pkt))
                {
                    sfeLogWarning(m_ignoredStreams[pkt->stream_index] + " packet not handled and dropped");
                    av_free_packet(pkt);
                    av_free(pkt);
                }
            }
        }
    }

    void Demuxer::update()
    {
        std::map<int, Stream*> streams = getStreams();
        std::map<int, Stream*>::iterator it;

        for (it = streams.begin();it != streams.end(); it++)
        {
            it->second->update();
        }
    }

    bool Demuxer::didReachEndOfFile() const
    {
        return m_eofReached;
    }

    sf::Time Demuxer::getDuration() const
    {
        return m_duration;
    }

    AVPacket* Demuxer::readPacket()
    {
        sf::Lock l(m_synchronized);

        AVPacket *pkt = NULL;
        int err = 0;

        pkt = (AVPacket *)av_malloc(sizeof(*pkt));
        CHECK(pkt, "Demuxer::readPacket() - out of memory");
        av_init_packet(pkt);

        err = av_read_frame(m_formatCtx, pkt);

        if (err < 0)
        {
            av_free_packet(pkt);
            av_free(pkt);
            pkt = NULL;
        }

        return pkt;
    }

    bool Demuxer::distributePacket(AVPacket* packet)
    {
        sf::Lock l(m_synchronized);
        CHECK(packet, "Demuxer::distributePacket() - invalid argument");

        bool result = false;
        std::map<int, Stream*>::iterator it = m_streams.find(packet->stream_index);

        if (it != m_streams.end())
        {
            it->second->pushEncodedData(packet);
            result = true;
        }

        return result;
    }

    void Demuxer::extractDurationFromStream(AVStream* stream)
    {
        if (m_duration != sf::Time::Zero)
            return;

        if (stream->duration != AV_NOPTS_VALUE)
        {
            long secs, us;
            secs = stream->duration / AV_TIME_BASE;
            us = stream->duration % AV_TIME_BASE;
            m_duration = sf::seconds(secs + (float)us / AV_TIME_BASE);
        }
    }

    void Demuxer::requestMoreData(Stream& starvingStream)
    {
        sf::Lock l(m_synchronized);

        feedStream(starvingStream);
    }

    void Demuxer::resetEndOfFileStatus()
    {
        m_eofReached = false;
    }

    void Demuxer::willSeek(const Timer &timer, sf::Time position)
    {
        resetEndOfFileStatus();

        if (m_formatCtx->iformat->flags & AVFMT_SEEK_TO_PTS)
        {
            int64_t timestamp = 0;

            if (m_formatCtx->start_time != AV_NOPTS_VALUE)
                timestamp += m_formatCtx->start_time;

            int err = avformat_seek_file(m_formatCtx, -1, INT64_MIN, timestamp, INT64_MAX, AVSEEK_FLAG_BACKWARD);
            sfeLogDebug("Seek by PTS at timestamp=" + s(timestamp) + " returned " + s(err));
        }
        else
        {
            int err = avformat_seek_file(m_formatCtx, -1, INT64_MIN, 0, INT64_MAX, AVSEEK_FLAG_BACKWARD);
            //            sfeLogDebug("Seek by PTS at timestamp=" + s(timestamp) + " returned " + s(err));

            //            int err = av_seek_frame(m_formatCtx, m_streamID, -999999, AVSEEK_FLAG_BACKWARD);
            sfeLogDebug("Seek by DTS at timestamp " + s(-9999) + " returned " + s(err));
        }
    }
}
<|endoftext|>


<commit_before>#include "GraphML.h"

#include "DirectedGraph.h"
#include "UndirectedGraph.h"

#include <tinyxml2.h>
#include <Table.h>

#include <cassert>
#include <map>
#include <iostream>

using namespace std;
using namespace tinyxml2;

GraphML::GraphML() : FileTypeHandler("GraphML", true) {
  addExtension("graphml");
}

std::shared_ptr<Graph>
GraphML::openGraph(const char * filename, const std::shared_ptr<NodeArray> & initial_nodes) {
  RenderMode mode = RENDERMODE_3D;

  XMLDocument doc;
  doc.LoadFile(filename);

  XMLElement * graphml_element = doc.FirstChildElement("graphml");
  assert(graphml_element);

  XMLElement * graph_element = graphml_element->FirstChildElement("graph");
  assert(graph_element);

  map<string, int> nodes_by_id;

  const char * edgedefault = graph_element->Attribute("edgedefault");
  bool directed = true;
  if (edgedefault && strcmp(edgedefault, "undirected") == 0) {
    directed = false;
  }
  std::shared_ptr<Graph> graph;
  if (directed) {
    graph = std::make_shared<DirectedGraph>();
    graph->setNodeArray(initial_nodes);
    graph->getNodeArray().setNodeSizeMethod(SizeMethod(SizeMethod::SIZE_FROM_INDEGREE));
  } else {
    graph = std::make_shared<UndirectedGraph>();
    graph->setNodeArray(initial_nodes);
    graph->getNodeArray().setNodeSizeMethod(SizeMethod(SizeMethod::SIZE_FROM_DEGREE));
  }
  graph->getNodeArray().setFlattenHierarchy(true);

  auto & node_table = graph->getNodeArray().getTable();
  auto & edge_table = graph->getFaceData();

  XMLElement * key_element = graphml_element->FirstChildElement("key");
  for ( ; key_element ; key_element = key_element->NextSiblingElement("key") ) {
    const char * key_type = key_element->Attribute("attr.type");
    const char * key_id = key_element->Attribute("id");
    const char * for_type = key_element->Attribute("for");
    const char * name = key_element->Attribute("attr.name");

    assert(key_type && key_id && for_type);

    std::shared_ptr<table::Column> column;
    if (strcmp(key_type, "string") == 0) {
      column = std::make_shared<table::ColumnText>(key_id ? key_id : "");
    } else if (strcmp(key_type, "double") == 0 || strcmp(key_type, "float") == 0) {
      column = std::make_shared<table::ColumnDouble>(key_id ? key_id : "");
    } else if (strcmp(key_type, "int") == 0) {
      column = std::make_shared<table::ColumnInt>(key_id ? key_id : "");
    } else {
      assert(0);
    }

    if (strcmp(for_type, "node") == 0) {
      node_table.addColumn(column);
    } else if (strcmp(for_type, "edge") == 0) {
      edge_table.addColumn(column);
    } else {
      assert(0);
    }
  }

  createGraphFromElement(*graph, *graphml_element, *graph_element, nodes_by_id, directed);

  graph->updateAppearance();
  graph->randomizeGeometry();
  // graph->setComplexGraph(is_complex);
  // graph->setHasSubGraphs(is_complex);

  return graph;
}

void
GraphML::createGraphFromElement(Graph & graph, XMLElement & graphml_element, XMLElement & graph_element, map<string, int> & nodes_by_id, bool is_directed, int parent_node_id) const {
  auto & node_table = graph.getNodeArray().getTable();
  auto & edge_table = graph.getFaceData();

  auto & node_id_column = node_table.addTextColumn("id");
  auto & edge_id_column = edge_table.addTextColumn("id");

  XMLElement * node_element = graph_element.FirstChildElement("node");
  for ( ; node_element ; node_element = node_element->NextSiblingElement("node") ) {
    const char * node_id_text = node_element->Attribute("id");
    assert(node_id_text);

    int node_id = graph.addNode();
    node_id_column.setValue(node_id, node_id_text);
    nodes_by_id[node_id_text] = node_id + 1;

    if (parent_node_id != -1) graph.addChild(parent_node_id, node_id);

    XMLElement * data_element = node_element->FirstChildElement("data");
    for ( ; data_element ; data_element = data_element->NextSiblingElement("data") ) {
      const char * key = data_element->Attribute("key");
      assert(key);
      const char * text = data_element->GetText();
      if (text) {
	node_table[key].setValue(node_id, text);
      }
    }

    XMLElement * nested_graph_element = node_element->FirstChildElement("graph");
    if (nested_graph_element) {
      createGraphFromElement(graph, graphml_element, *nested_graph_element, nodes_by_id, is_directed, node_id);
    }
  }

  XMLElement * edge_element = graph_element.FirstChildElement("edge");
  for ( ; edge_element ; edge_element = edge_element->NextSiblingElement("edge") ) {
    const char * edge_id_text = edge_element->Attribute("id");
    const char * source = edge_element->Attribute("source");
    const char * target = edge_element->Attribute("target");
    assert(source && target);

    if (strcmp(source, target) == 0) {
      cerr << "GraphML: skipping self link for " << source << endl;
      continue;
    }

    int source_node = nodes_by_id[source];
    int target_node = nodes_by_id[target];

    if (source_node && target_node) {
      int face_id = graph.addFace(-1);
      int edge_id1 = graph.addEdge(source_node - 1, target_node - 1, face_id);
      if (!is_directed) {
	int edge_id2 = graph.addEdge(target_node - 1, source_node - 1, face_id);
	graph.connectEdgePair(edge_id1, edge_id2);
      }

      if (edge_id_text && strlen(edge_id_text) != 0) {
	edge_id_column.setValue(face_id, edge_id_text);
      }

      XMLElement * data_element = edge_element->FirstChildElement("data");

      for ( ; data_element ; data_element = data_element->NextSiblingElement("data") ) {
	const char * key = data_element->Attribute("key");
	assert(key);
	const char * text = data_element->GetText();
	if (text) {
	  edge_table[key].setValue(face_id, text);
	}
      }
    } else {
      if (!source_node) {
	// cerr << "cannot find node " << source << endl;
      }
      if (!target_node) {
	// cerr << "cannot find node " << target << endl;
      }
    }
  }
}

bool
GraphML::saveGraph(const Graph & graph, const std::string & filename) {
  XMLDocument doc;
  doc.LinkEndChild(doc.NewDeclaration());

  XMLElement * graphml_element = doc.NewElement("graphml");
  graphml_element->SetAttribute("xmlns", "http://graphml.graphdrawing.org/xmlns");

  bool directed = graph.isDirected();
  auto & node_table = graph.getNodeArray().getTable();
  auto & edge_table = graph.getFaceData();

  for (auto & col : node_table.getColumns()) {
    XMLElement * key_element = doc.NewElement("key");
    key_element->SetAttribute("attr.name", col.first.c_str());
    key_element->SetAttribute("id", col.first.c_str());
    key_element->SetAttribute("attr.type", col.second->getTypeText());
    key_element->SetAttribute("for", "node");
    graphml_element->LinkEndChild(key_element);
  }

  for (auto & col : edge_table.getColumns()) {
    XMLElement * key_element = doc.NewElement("key");
    key_element->SetAttribute("attr.name", col.first.c_str());
    key_element->SetAttribute("id", col.first.c_str());
    key_element->SetAttribute("attr.type", col.second->getTypeText());
    key_element->SetAttribute("for", "edge");
    graphml_element->LinkEndChild(key_element);
  }

  XMLElement * graph_element = doc.NewElement("graph");
  graphml_element->LinkEndChild(graph_element);

  if (!directed) {
    graph_element->SetAttribute("edgedefault", "undirected");
  }

  for (unsigned int i = 0; i < graph.getNodeArray().size(); i++) {
    XMLElement * node_element = doc.NewElement("node");
    string node_id = "n" + to_string(i);
    node_element->SetAttribute("id", node_id.c_str());

    for (auto & col : node_table.getColumns()) {
      XMLElement * data_element = doc.NewElement("data");
      data_element->SetAttribute("key", col.first.c_str());
      data_element->LinkEndChild(doc.NewText(col.second->getText(i).c_str()));
      node_element->LinkEndChild(data_element);
    }

    graph_element->LinkEndChild(node_element);
  }

  for (unsigned int i = 0; i < graph.getFaceCount(); i++) {
    XMLElement * edge_element = doc.NewElement("edge");

#if 0
    auto edge = graph.getEdgeAttributes(i);
    string node_id1 = "n" + to_string(edge.tail);
    string node_id2 = "n" + to_string(edge.head);

    // timestamp, sentiment

    edge_element->SetAttribute("source", node_id1.c_str());
    edge_element->SetAttribute("target", node_id2.c_str());
#endif

    for (auto & col : edge_table.getColumns()) {
      XMLElement * data_element = doc.NewElement("data");
      data_element->SetAttribute("key", col.first.c_str());
      data_element->LinkEndChild(doc.NewText(col.second->getText(i).c_str()));
      edge_element->LinkEndChild(data_element);
    }

    graph_element->LinkEndChild(edge_element);
  }

  doc.LinkEndChild(graphml_element);
  doc.SaveFile(filename.c_str());

  return true;
}
<commit_msg>rename method call<commit_after>#include "GraphML.h"

#include "DirectedGraph.h"
#include "UndirectedGraph.h"

#include <tinyxml2.h>
#include <Table.h>

#include <cassert>
#include <map>
#include <iostream>

using namespace std;
using namespace tinyxml2;

GraphML::GraphML() : FileTypeHandler("GraphML", true) {
  addExtension("graphml");
}

std::shared_ptr<Graph>
GraphML::openGraph(const char * filename, const std::shared_ptr<NodeArray> & initial_nodes) {
  RenderMode mode = RENDERMODE_3D;

  XMLDocument doc;
  doc.LoadFile(filename);

  XMLElement * graphml_element = doc.FirstChildElement("graphml");
  assert(graphml_element);

  XMLElement * graph_element = graphml_element->FirstChildElement("graph");
  assert(graph_element);

  map<string, int> nodes_by_id;

  const char * edgedefault = graph_element->Attribute("edgedefault");
  bool directed = true;
  if (edgedefault && strcmp(edgedefault, "undirected") == 0) {
    directed = false;
  }
  std::shared_ptr<Graph> graph;
  if (directed) {
    graph = std::make_shared<DirectedGraph>();
    graph->setNodeArray(initial_nodes);
    graph->getNodeArray().setNodeSizeMethod(SizeMethod(SizeMethod::SIZE_FROM_INDEGREE));
  } else {
    graph = std::make_shared<UndirectedGraph>();
    graph->setNodeArray(initial_nodes);
    graph->getNodeArray().setNodeSizeMethod(SizeMethod(SizeMethod::SIZE_FROM_DEGREE));
  }
  graph->getNodeArray().setFlattenHierarchy(true);

  auto & node_table = graph->getNodeArray().getTable();
  auto & edge_table = graph->getFaceData();

  XMLElement * key_element = graphml_element->FirstChildElement("key");
  for ( ; key_element ; key_element = key_element->NextSiblingElement("key") ) {
    const char * key_type = key_element->Attribute("attr.type");
    const char * key_id = key_element->Attribute("id");
    const char * for_type = key_element->Attribute("for");
    const char * name = key_element->Attribute("attr.name");

    assert(key_type && key_id && for_type);

    std::shared_ptr<table::Column> column;
    if (strcmp(key_type, "string") == 0) {
      column = std::make_shared<table::ColumnText>(key_id ? key_id : "");
    } else if (strcmp(key_type, "double") == 0 || strcmp(key_type, "float") == 0) {
      column = std::make_shared<table::ColumnDouble>(key_id ? key_id : "");
    } else if (strcmp(key_type, "int") == 0) {
      column = std::make_shared<table::ColumnInt>(key_id ? key_id : "");
    } else {
      assert(0);
    }

    if (strcmp(for_type, "node") == 0) {
      node_table.addColumn(column);
    } else if (strcmp(for_type, "edge") == 0) {
      edge_table.addColumn(column);
    } else {
      assert(0);
    }
  }

  createGraphFromElement(*graph, *graphml_element, *graph_element, nodes_by_id, directed);

  graph->updateFaceAppearance();
  graph->randomizeGeometry();
  // graph->setComplexGraph(is_complex);
  // graph->setHasSubGraphs(is_complex);

  return graph;
}

void
GraphML::createGraphFromElement(Graph & graph, XMLElement & graphml_element, XMLElement & graph_element, map<string, int> & nodes_by_id, bool is_directed, int parent_node_id) const {
  auto & node_table = graph.getNodeArray().getTable();
  auto & edge_table = graph.getFaceData();

  auto & node_id_column = node_table.addTextColumn("id");
  auto & edge_id_column = edge_table.addTextColumn("id");

  XMLElement * node_element = graph_element.FirstChildElement("node");
  for ( ; node_element ; node_element = node_element->NextSiblingElement("node") ) {
    const char * node_id_text = node_element->Attribute("id");
    assert(node_id_text);

    int node_id = graph.addNode();
    node_id_column.setValue(node_id, node_id_text);
    nodes_by_id[node_id_text] = node_id + 1;

    if (parent_node_id != -1) graph.addChild(parent_node_id, node_id);

    XMLElement * data_element = node_element->FirstChildElement("data");
    for ( ; data_element ; data_element = data_element->NextSiblingElement("data") ) {
      const char * key = data_element->Attribute("key");
      assert(key);
      const char * text = data_element->GetText();
      if (text) {
	node_table[key].setValue(node_id, text);
      }
    }

    XMLElement * nested_graph_element = node_element->FirstChildElement("graph");
    if (nested_graph_element) {
      createGraphFromElement(graph, graphml_element, *nested_graph_element, nodes_by_id, is_directed, node_id);
    }
  }

  XMLElement * edge_element = graph_element.FirstChildElement("edge");
  for ( ; edge_element ; edge_element = edge_element->NextSiblingElement("edge") ) {
    const char * edge_id_text = edge_element->Attribute("id");
    const char * source = edge_element->Attribute("source");
    const char * target = edge_element->Attribute("target");
    assert(source && target);

    if (strcmp(source, target) == 0) {
      cerr << "GraphML: skipping self link for " << source << endl;
      continue;
    }

    int source_node = nodes_by_id[source];
    int target_node = nodes_by_id[target];

    if (source_node && target_node) {
      int face_id = graph.addFace(-1);
      int edge_id1 = graph.addEdge(source_node - 1, target_node - 1, face_id);
      if (!is_directed) {
	int edge_id2 = graph.addEdge(target_node - 1, source_node - 1, face_id);
	graph.connectEdgePair(edge_id1, edge_id2);
      }

      if (edge_id_text && strlen(edge_id_text) != 0) {
	edge_id_column.setValue(face_id, edge_id_text);
      }

      XMLElement * data_element = edge_element->FirstChildElement("data");

      for ( ; data_element ; data_element = data_element->NextSiblingElement("data") ) {
	const char * key = data_element->Attribute("key");
	assert(key);
	const char * text = data_element->GetText();
	if (text) {
	  edge_table[key].setValue(face_id, text);
	}
      }
    } else {
      if (!source_node) {
	// cerr << "cannot find node " << source << endl;
      }
      if (!target_node) {
	// cerr << "cannot find node " << target << endl;
      }
    }
  }
}

bool
GraphML::saveGraph(const Graph & graph, const std::string & filename) {
  XMLDocument doc;
  doc.LinkEndChild(doc.NewDeclaration());

  XMLElement * graphml_element = doc.NewElement("graphml");
  graphml_element->SetAttribute("xmlns", "http://graphml.graphdrawing.org/xmlns");

  bool directed = graph.isDirected();
  auto & node_table = graph.getNodeArray().getTable();
  auto & edge_table = graph.getFaceData();

  for (auto & col : node_table.getColumns()) {
    XMLElement * key_element = doc.NewElement("key");
    key_element->SetAttribute("attr.name", col.first.c_str());
    key_element->SetAttribute("id", col.first.c_str());
    key_element->SetAttribute("attr.type", col.second->getTypeText());
    key_element->SetAttribute("for", "node");
    graphml_element->LinkEndChild(key_element);
  }

  for (auto & col : edge_table.getColumns()) {
    XMLElement * key_element = doc.NewElement("key");
    key_element->SetAttribute("attr.name", col.first.c_str());
    key_element->SetAttribute("id", col.first.c_str());
    key_element->SetAttribute("attr.type", col.second->getTypeText());
    key_element->SetAttribute("for", "edge");
    graphml_element->LinkEndChild(key_element);
  }

  XMLElement * graph_element = doc.NewElement("graph");
  graphml_element->LinkEndChild(graph_element);

  if (!directed) {
    graph_element->SetAttribute("edgedefault", "undirected");
  }

  for (unsigned int i = 0; i < graph.getNodeArray().size(); i++) {
    XMLElement * node_element = doc.NewElement("node");
    string node_id = "n" + to_string(i);
    node_element->SetAttribute("id", node_id.c_str());

    for (auto & col : node_table.getColumns()) {
      XMLElement * data_element = doc.NewElement("data");
      data_element->SetAttribute("key", col.first.c_str());
      data_element->LinkEndChild(doc.NewText(col.second->getText(i).c_str()));
      node_element->LinkEndChild(data_element);
    }

    graph_element->LinkEndChild(node_element);
  }

  for (unsigned int i = 0; i < graph.getFaceCount(); i++) {
    XMLElement * edge_element = doc.NewElement("edge");

#if 0
    auto edge = graph.getEdgeAttributes(i);
    string node_id1 = "n" + to_string(edge.tail);
    string node_id2 = "n" + to_string(edge.head);

    // timestamp, sentiment

    edge_element->SetAttribute("source", node_id1.c_str());
    edge_element->SetAttribute("target", node_id2.c_str());
#endif

    for (auto & col : edge_table.getColumns()) {
      XMLElement * data_element = doc.NewElement("data");
      data_element->SetAttribute("key", col.first.c_str());
      data_element->LinkEndChild(doc.NewText(col.second->getText(i).c_str()));
      edge_element->LinkEndChild(data_element);
    }

    graph_element->LinkEndChild(edge_element);
  }

  doc.LinkEndChild(graphml_element);
  doc.SaveFile(filename.c_str());

  return true;
}
<|endoftext|>


<commit_before>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sstream>

#include "liblogger.h"

namespace liblogger
{

LogFile::LogFile(const std::string fname) :
	m_fname(fname)
{
	m_fp = fopen(m_fname.c_str(), "a");
	if (m_fp == NULL)
	{
		std::stringstream ss;
		ss << "Cannot open file: '" << m_fname << "' error: " << strerror(errno);
		throw(LogException(ss.str()));
	}
}

LogFile::~LogFile()
{
	if (m_fp != NULL)
	{
		if (fclose(m_fp) < 0)
		{
			std::stringstream ss;
			ss << "Cannot close file: '" << m_fname << "' error: " << strerror(errno);
			throw(LogException(ss.str()));
		}
	}
}

void LogFile::GetName(std::string *str)
{
	*str = "File";
}

void LogFile::GetDesc(std::string *str)
{
	*str = "Logs to a File";
}

void LogFile::Log(const LogType Type, const std::string &str)
{
	if (m_fp == NULL)
		return;

	time_t current = time(NULL);
	struct tm timeinfo;
	char buf[128];

	localtime_r(&current, &timeinfo);
	strftime(buf, sizeof(buf), "%F %T", &timeinfo);

	if (fprintf(m_fp, "%s - %s [PID: %d] - %s\n", buf, LogTypeToStr(Type).c_str(), getpid(), str.c_str()) < 0)
	{
		std::stringstream ss;
		ss << "failed to write to file '" << m_fname.c_str() << "' error:" << strerror(errno);
		throw(LogException(ss.str()));
	}
	if (fflush(m_fp) < 0)
	{
		std::stringstream ss;
		ss << "failed to fflush to file '" << m_fname.c_str() << "' error:" << strerror(errno);
		throw(LogException(ss.str()));
	}
}

void LogFile::Rotate()
{
	if (m_fp != NULL)
	{
		if (fclose(m_fp) < 0)
		{
			std::stringstream ss;
			ss << "failed to close to file '" << m_fname.c_str() << "' error:" << strerror(errno);
			throw(LogException(ss.str()));
		}
	}

	m_fp = fopen(m_fname.c_str(), "a");
	if (m_fp == NULL)
	{
		std::stringstream ss;
		ss << "Cannot open file: '" << m_fname << "'";
		throw(LogException(ss.str()));
	}
}

};

<commit_msg>Added missing error check to strftime<commit_after>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sstream>

#include "liblogger.h"

namespace liblogger
{

LogFile::LogFile(const std::string fname) :
	m_fname(fname)
{
	m_fp = fopen(m_fname.c_str(), "a");
	if (m_fp == NULL)
	{
		std::stringstream ss;
		ss << "Cannot open file: '" << m_fname << "' error: " << strerror(errno);
		throw(LogException(ss.str()));
	}
}

LogFile::~LogFile()
{
	if (m_fp != NULL)
	{
		if (fclose(m_fp) < 0)
		{
			std::stringstream ss;
			ss << "Cannot close file: '" << m_fname << "' error: " << strerror(errno);
			throw(LogException(ss.str()));
		}
	}
}

void LogFile::GetName(std::string *str)
{
	*str = "File";
}

void LogFile::GetDesc(std::string *str)
{
	*str = "Logs to a File";
}

void LogFile::Log(const LogType Type, const std::string &str)
{
	if (m_fp == NULL)
		return;

	time_t current = time(NULL);
	struct tm timeinfo;
	char buf[128];

	localtime_r(&current, &timeinfo);
	if (strftime(buf, sizeof(buf), "%F %T", &timeinfo) == 0)
	{
		std::stringstream ss;
		ss << "strftime failed: '" << "' error: " << strerror(errno);
		throw(LogException(ss.str()));
	}

	if (fprintf(m_fp, "%s - %s [PID: %d] - %s\n", buf, LogTypeToStr(Type).c_str(), getpid(), str.c_str()) < 0)
	{
		std::stringstream ss;
		ss << "failed to write to file '" << m_fname.c_str() << "' error:" << strerror(errno);
		throw(LogException(ss.str()));
	}
	if (fflush(m_fp) < 0)
	{
		std::stringstream ss;
		ss << "failed to fflush to file '" << m_fname.c_str() << "' error:" << strerror(errno);
		throw(LogException(ss.str()));
	}
}

void LogFile::Rotate()
{
	if (m_fp != NULL)
	{
		if (fclose(m_fp) < 0)
		{
			std::stringstream ss;
			ss << "failed to close to file '" << m_fname.c_str() << "' error:" << strerror(errno);
			throw(LogException(ss.str()));
		}
	}

	m_fp = fopen(m_fname.c_str(), "a");
	if (m_fp == NULL)
	{
		std::stringstream ss;
		ss << "Cannot open file: '" << m_fname << "'";
		throw(LogException(ss.str()));
	}
}

};

<|endoftext|>


<commit_before>#include "Louvain.h"

#include <Graph.h>

#include <iostream>
#include <cassert>
#include <unordered_set>

using namespace std;

Louvain::Louvain(Graph * _g, int _max_num_passes, double _min_modularity,
		 bool _create_node_clusters, bool _create_edge_clusters)
  : g(_g),
    max_num_passes(_max_num_passes),
    min_modularity(_min_modularity),
    create_node_clusters(_create_node_clusters),
    create_edge_clusters(_create_edge_clusters)
{
}

int
Louvain::getNodeCommunity(int node) const {
  while ( 1 ) {
    auto & td = getGraph().getNodeTertiaryData(node);
    if (td.parent_node == -1) break;
    node = td.parent_node;
  }
  return node;
}

unordered_map<int, float>
Louvain::neighboringCommunities(int node) const {
  unordered_map<int, float> comms;

  comms[getNodeCommunity(node)] = 0.0f;

  auto nd = g->getAllNeighbors(node);
  for (auto n : nd) {
    unsigned int neigh = n.first;
    unsigned int neigh_comm = getNodeCommunity(neigh);
    float neigh_w = n.second;
    if (neigh != node) {
      auto it = comms.find(neigh_comm);
      if (it == comms.end()) {
	comms[neigh_comm] = neigh_w;
      } else {
	it->second += neigh_w;
      }
    }
  }

  return comms;
}

bool
Louvain::oneLevel() {
  std::vector<int> nodes, edges;

  if (create_node_clusters) {
    auto end = g->end_visible_nodes();
    for (auto it = g->begin_visible_nodes(); it != end; ++it) {
      // if (getNodeCommunity(*it) == -1) {
      if (getGraph().getNodeTertiaryData(*it).parent_node == -1) {
	nodes.push_back(*it);
      }
    }
    for (auto & n : nodes) {
      int community_id = g->getNodeArray().createCommunity(n);
      // g->getNodeArray().setPosition(community_id, g->getNodePosition(n));
      g->addChild(community_id, n, 0);
      // g->getNodeArray().setPosition(n, glm::vec3());
    }
  } else {
    assert(0);
  }
#if 0
  if (create_edge_clusters) {
    auto end = g->end_edges();
    for (auto it = g->begin_edges(); it != end; ++it) {
      if (getEdgeCommunity(*it) == -1) {
	edges.push_back(*it);
	int community_id = g->getNodeArray().createCommunity(*it);
	g->addEdgeChild(community_id, *it, 0);
      }
    }
  }
#endif

  bool is_improved = false;
  double initial_modularity = getGraph().modularity();
  double modularity = initial_modularity;

#if 0
  // shuffle nodes
  for (int i = 0; i < nodes.size()-1; i++) {
    int rand_pos = rand() % (nodes.size()-i)+i;
    int tmp = nodes[i];
    nodes[i] = nodes[rand_pos];
    nodes[rand_pos] = tmp;
  }
#endif

  // cerr << "max_num_passes = " << max_num_passes << endl;

  // repeat until there is no improvement in modularity, or the improvement is smaller than epsilon, or maximum number of passes have been done
  for (int num_passes = 0; max_num_passes == -1 || num_passes < max_num_passes; num_passes++) {
    int num_moves = 0;

    // for each node: remove the node from its community and insert it in the best community
    for (int node : nodes) {
      int node_comm = getNodeCommunity(node);
      float weighted_degree = g->weightedDegree(node);

      // get the neighboring communities of the node
      auto neighboring_comms = neighboringCommunities(node);

      // remove the node from its community
      g->removeChild(node, neighboring_comms[node_comm]);

      // find the best community for node
      int best_comm = node_comm;
      double best_num_edges = 0.0, best_increase = 0.0;
      for (auto & ncd : neighboring_comms) {
        double increase = getGraph().modularityGain(node, ncd.first, ncd.second, weighted_degree);
        if (increase > best_increase) {
          best_comm = ncd.first;
          best_num_edges = ncd.second;
          best_increase = increase;
        }
      }

      // insert node in the best community
      g->addChild(best_comm, node, best_num_edges);

      if (best_comm != node_comm) {
        num_moves++;
      }
    }

    double prev_modularity = modularity;
    modularity = getGraph().modularity();
    if (num_moves > 0) {
      is_improved = true;
    }

    if (!num_moves) {
      cerr << "Louvain: stopping due to no moves\n";
      break;
    } if (modularity - prev_modularity < min_modularity) {
      cerr << "Louvain: modularity diff too small, min = " << min_modularity << "\n";
      break;
    }
  }

  cerr << "level done, modularity increase: " << initial_modularity << " to " << modularity << endl;

  std::unordered_set<int> clusters;

  if (is_improved) {
    for (int node : nodes) {
      clusters.insert(getNodeCommunity(node));
    }

    current_clusters.clear();
    current_clusters.reserve(clusters.size());
    for (auto id : clusters) {
      current_clusters.push_back(id);
    }
  } else {
    for (int node : nodes) {
      getGraph().removeChild(node);
    }
  }

  return is_improved;
}
<commit_msg>add safety check<commit_after>#include "Louvain.h"

#include <Graph.h>

#include <iostream>
#include <cassert>
#include <unordered_set>

using namespace std;

Louvain::Louvain(Graph * _g, int _max_num_passes, double _min_modularity,
		 bool _create_node_clusters, bool _create_edge_clusters)
  : g(_g),
    max_num_passes(_max_num_passes),
    min_modularity(_min_modularity),
    create_node_clusters(_create_node_clusters),
    create_edge_clusters(_create_edge_clusters)
{
}

int
Louvain::getNodeCommunity(int node) const {
  while ( 1 ) {
    auto & td = getGraph().getNodeTertiaryData(node);
    if (td.parent_node == -1) break;
    node = td.parent_node;
  }
  return node;
}

unordered_map<int, float>
Louvain::neighboringCommunities(int node) const {
  unordered_map<int, float> comms;

  comms[getNodeCommunity(node)] = 0.0f;

  auto nd = g->getAllNeighbors(node);
  for (auto n : nd) {
    unsigned int neigh = n.first;
    unsigned int neigh_comm = getNodeCommunity(neigh);
    float neigh_w = n.second;
    if (neigh != node) {
      auto it = comms.find(neigh_comm);
      if (it == comms.end()) {
	comms[neigh_comm] = neigh_w;
      } else {
	it->second += neigh_w;
      }
    }
  }

  return comms;
}

bool
Louvain::oneLevel() {
  std::vector<int> nodes, edges;

  if (create_node_clusters) {
    auto end = g->end_visible_nodes();
    for (auto it = g->begin_visible_nodes(); it != end; ++it) {
      // if (getNodeCommunity(*it) == -1) {
      if (getGraph().getNodeTertiaryData(*it).parent_node == -1) {
	nodes.push_back(*it);
      }
    }
    for (auto & n : nodes) {
      int community_id = g->getNodeArray().createCommunity(n);
      assert(getGraph().getNodeTertiaryData(community_id).parent_node == -1);
      // g->getNodeArray().setPosition(community_id, g->getNodePosition(n));
      g->addChild(community_id, n, 0);
      // g->getNodeArray().setPosition(n, glm::vec3());
    }
  } else {
    assert(0);
  }
#if 0
  if (create_edge_clusters) {
    auto end = g->end_edges();
    for (auto it = g->begin_edges(); it != end; ++it) {
      if (getEdgeCommunity(*it) == -1) {
	edges.push_back(*it);
	int community_id = g->getNodeArray().createCommunity(*it);
	g->addEdgeChild(community_id, *it, 0);
      }
    }
  }
#endif

  bool is_improved = false;
  double initial_modularity = getGraph().modularity();
  double modularity = initial_modularity;

#if 0
  // shuffle nodes
  for (int i = 0; i < nodes.size()-1; i++) {
    int rand_pos = rand() % (nodes.size()-i)+i;
    int tmp = nodes[i];
    nodes[i] = nodes[rand_pos];
    nodes[rand_pos] = tmp;
  }
#endif

  // cerr << "max_num_passes = " << max_num_passes << endl;

  // repeat until there is no improvement in modularity, or the improvement is smaller than epsilon, or maximum number of passes have been done
  for (int num_passes = 0; max_num_passes == -1 || num_passes < max_num_passes; num_passes++) {
    int num_moves = 0;

    // for each node: remove the node from its community and insert it in the best community
    for (int node : nodes) {
      int node_comm = getNodeCommunity(node);
      float weighted_degree = g->weightedDegree(node);

      // get the neighboring communities of the node
      auto neighboring_comms = neighboringCommunities(node);

      // remove the node from its community
      g->removeChild(node, neighboring_comms[node_comm]);

      // find the best community for node
      int best_comm = node_comm;
      double best_num_edges = 0.0, best_increase = 0.0;
      for (auto & ncd : neighboring_comms) {
        double increase = getGraph().modularityGain(node, ncd.first, ncd.second, weighted_degree);
        if (increase > best_increase) {
          best_comm = ncd.first;
          best_num_edges = ncd.second;
          best_increase = increase;
        }
      }

      // insert node in the best community
      g->addChild(best_comm, node, best_num_edges);

      if (best_comm != node_comm) {
        num_moves++;
      }
    }

    double prev_modularity = modularity;
    modularity = getGraph().modularity();
    if (num_moves > 0) {
      is_improved = true;
    }

    if (!num_moves) {
      cerr << "Louvain: stopping due to no moves\n";
      break;
    } if (modularity - prev_modularity < min_modularity) {
      cerr << "Louvain: modularity diff too small, min = " << min_modularity << "\n";
      break;
    }
  }

  cerr << "level done, modularity increase: " << initial_modularity << " to " << modularity << endl;

  std::unordered_set<int> clusters;

  if (is_improved) {
    for (int node : nodes) {
      clusters.insert(getNodeCommunity(node));
    }

    current_clusters.clear();
    current_clusters.reserve(clusters.size());
    for (auto id : clusters) {
      current_clusters.push_back(id);
    }
  } else {
    for (int node : nodes) {
      getGraph().removeChild(node);
    }
  }

  return is_improved;
}
<|endoftext|>


<commit_before>// Copyright (c) M5Stack. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "M5Stack.h"

M5Stack::M5Stack() : isInited(0) {
}

void M5Stack::begin(bool LCDEnable, bool SDEnable, bool SerialEnable, bool I2CEnable) {
  // Correct init once
  if (isInited == true) {
    return;
  } else {
    isInited = true;
  }

  // UART
  if (SerialEnable == true) {
    Serial.begin(115200);
    Serial.flush();
    delay(50);
    Serial.print("M5Stack initializing...");
  }

  // TF Card
  if (SDEnable == true) {
    SD.begin(TFCARD_CS_PIN, SPI, 40000000);
  }

  // LCD INIT
  if (LCDEnable == true) {
    Lcd.begin();
  }

  // TONE
  // Speaker.begin();

  // Set wakeup button
  Power.setWakeupButton(BUTTON_A_PIN);

  // I2C init
  if (I2CEnable == true) {
    Wire.begin(21, 22);
  }

  if (SerialEnable == true) {
    Serial.println("OK");
  }

  // if use M5GO button, need set gpio15 OD or PP mode to avoid affecting the wifi signal
  pinMode(15, OUTPUT_OPEN_DRAIN);
}

void M5Stack::update() {
  //Button update
  BtnA.read();
  BtnB.read();
  BtnC.read();

  //Speaker update
  Speaker.update();
}

/**
  * Function has been move to Power class.(for compatibility)
  * This name will be removed in a future release.
  */
void M5Stack::setPowerBoostKeepOn(bool en) {
  M5.Power.setPowerBoostKeepOn(en);
}
/**
  * Function has been move to Power class.(for compatibility)
  * This name will be removed in a future release.
  */
void M5Stack::setWakeupButton(uint8_t button) {
  M5.Power.setWakeupButton(button);
}
/**
  * Function has been move to Power class.(for compatibility)
  * This name will be removed in a future release.
  */
void M5Stack::powerOFF() {
  M5.Power.deepSleep();
}

M5Stack M5;
<commit_msg>Print init text on own line, neatens Serial output<commit_after>// Copyright (c) M5Stack. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "M5Stack.h"

M5Stack::M5Stack() : isInited(0) {
}

void M5Stack::begin(bool LCDEnable, bool SDEnable, bool SerialEnable, bool I2CEnable) {
  // Correct init once
  if (isInited == true) {
    return;
  } else {
    isInited = true;
  }

  // UART
  if (SerialEnable == true) {
    Serial.begin(115200);
    Serial.flush();
    delay(50);
    Serial.println("M5Stack initializing...");
  }

  // TF Card
  if (SDEnable == true) {
    SD.begin(TFCARD_CS_PIN, SPI, 40000000);
  }

  // LCD INIT
  if (LCDEnable == true) {
    Lcd.begin();
  }

  // TONE
  // Speaker.begin();

  // Set wakeup button
  Power.setWakeupButton(BUTTON_A_PIN);

  // I2C init
  if (I2CEnable == true) {
    Wire.begin(21, 22);
  }

  if (SerialEnable == true) {
    Serial.println("OK");
  }

  // if use M5GO button, need set gpio15 OD or PP mode to avoid affecting the wifi signal
  pinMode(15, OUTPUT_OPEN_DRAIN);
}

void M5Stack::update() {
  //Button update
  BtnA.read();
  BtnB.read();
  BtnC.read();

  //Speaker update
  Speaker.update();
}

/**
  * Function has been move to Power class.(for compatibility)
  * This name will be removed in a future release.
  */
void M5Stack::setPowerBoostKeepOn(bool en) {
  M5.Power.setPowerBoostKeepOn(en);
}
/**
  * Function has been move to Power class.(for compatibility)
  * This name will be removed in a future release.
  */
void M5Stack::setWakeupButton(uint8_t button) {
  M5.Power.setWakeupButton(button);
}
/**
  * Function has been move to Power class.(for compatibility)
  * This name will be removed in a future release.
  */
void M5Stack::powerOFF() {
  M5.Power.deepSleep();
}

M5Stack M5;
<|endoftext|>


<commit_before>#include "MyServo.h"

#include <Arduino.h>

MyServo::MyServo(int pin): pin(pin), servo() {}

void MyServo::setUp() {
	this->servo.attach(this->pin);
}

void MyServo::updateFromAnalog(AnalogInput& input) {
  int rawVal = input.read(-100, 100);
  int finalVal = rawVal / 10;
  this->servo.write(this->servo.read() + finalVal);
}
<commit_msg>Small change in MyServo<commit_after>#include "MyServo.h"

MyServo::MyServo(int pin): pin(pin), servo() {}

void MyServo::setUp() {
	this->servo.attach(this->pin);
}

void MyServo::updateFromAnalog(AnalogInput& input) {
  int rawVal = input.read(-100, 100);
  int finalVal = rawVal / 10;
  this->servo.write(this->servo.read() + finalVal);
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>

#include "Options.hpp"

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>

using namespace eddic;

bool eddic::OptimizeStrings;
bool eddic::OptimizeUnused;

bool eddic::WarningUnused;

po::variables_map eddic::options;

po::options_description desc("Usage : eddic [options] source.eddi");

std::pair<std::string, std::string> numeric_parser(const std::string& s){
    if (s.find("-32") == 0) {
        return make_pair("32", std::string("true"));
    } else if (s.find("-64") == 0) {
        return make_pair("64", std::string("true"));
    } else {
        return make_pair(std::string(), std::string());
    }
}

bool eddic::parseOptions(int argc, const char* argv[]) {
    try {
        desc.add_options()
            ("help,h", "Generate this help message")
            ("assembly,S", "Generate only the assembly")
            ("keep,k", "Keep the assembly file")
            ("version", "Print the version of eddic")
            ("output,o", po::value<std::string>()->default_value("a.out"), "Set the name of the executable")

            ("ast", "Print the Abstract Syntax Tree representation of the source")
            ("tac", "Print the Three Address Code representation of the source")

            ("ast-only", "Only print the Abstract Syntax Tree representation of the source (do not continue compilation after printing)")
            ("tac-only", "Only print the Three Address Code representation of the source (do not continue compilation after printing)")

            ("optimize-all", "Enable all optimizations")
            ("optimize-strings", po::bool_switch(&OptimizeStrings), "Enable the optimizations on strings")
            ("optimize-unused", po::bool_switch(&OptimizeUnused), "Enable the removal of unused variables and functions")

            ("debug,g", "Add debugging symbols")

            ("warning-all", "Enable all the warnings")
            ("warning-unused", po::bool_switch(&WarningUnused), "Enable warnings for unused variables, parameters and functions")

            ("32", po::value<std::string>(), "Force the compilation for 32 bits platform")
            ("64", po::value<std::string>(), "Force the compilation for 64 bits platform")

            ("input", po::value<std::string>(), "Input file");

        po::positional_options_description p;
        p.add("input", -1);

        po::store(po::command_line_parser(argc, argv).options(desc).extra_parser(numeric_parser).positional(p).run(), options);
        po::notify(options);

        if(options.count("optimize-all")){
            OptimizeStrings = OptimizeUnused = true;
        }

        if(options.count("warning-all")){
            WarningUnused = true;
        }

        if(options.count("64") && options.count("32")){
            std::cout << "Invalid command line options : a compilation cannot be both 32 and 64 bits" << std::endl;

            return false;
        }
    } catch (const po::ambiguous_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return false;
    } catch (const po::unknown_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return false;
    } catch (const po::multiple_occurrences& e) {
        std::cout << "Only one file can be compiled" << std::endl;

        return false;
    }

    return true;
}

void eddic::printHelp(){
    std::cout << desc << std::endl;
}

void eddic::printVersion(){
    std::cout << "eddic version 0.8.1" << std::endl;
}
<commit_msg>Fix the description of command line swithches<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>

#include "Options.hpp"

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>

using namespace eddic;

bool eddic::OptimizeStrings;
bool eddic::OptimizeUnused;

bool eddic::WarningUnused;

po::variables_map eddic::options;

po::options_description desc("Usage : eddic [options] source.eddi");

std::pair<std::string, std::string> numeric_parser(const std::string& s){
    if (s.find("-32") == 0) {
        return make_pair("32", std::string("true"));
    } else if (s.find("-64") == 0) {
        return make_pair("64", std::string("true"));
    } else {
        return make_pair(std::string(), std::string());
    }
}

bool eddic::parseOptions(int argc, const char* argv[]) {
    try {
        desc.add_options()
            ("help,h", "Generate this help message")
            ("assembly,S", "Generate only the assembly")
            ("keep,k", "Keep the assembly file")
            ("version", "Print the version of eddic")
            ("output,o", po::value<std::string>()->default_value("a.out"), "Set the name of the executable")

            ("ast", "Print the Abstract Syntax Tree representation of the source")
            ("tac", "Print the Three Address Code representation of the source")

            ("ast-only", "Only print the Abstract Syntax Tree representation of the source (do not continue compilation after printing)")
            ("tac-only", "Only print the Three Address Code representation of the source (do not continue compilation after printing)")

            ("optimize-all", "Enable all optimizations")
            ("optimize-strings", po::bool_switch(&OptimizeStrings), "Enable the optimizations on strings")
            ("optimize-unused", po::bool_switch(&OptimizeUnused), "Enable the removal of unused variables and functions")

            ("debug,g", "Add debugging symbols")

            ("warning-all", "Enable all the warnings")
            ("warning-unused", po::bool_switch(&WarningUnused), "Enable warnings for unused variables, parameters and functions")

            ("32", "Force the compilation for 32 bits platform")
            ("64", "Force the compilation for 64 bits platform")

            ("input", po::value<std::string>(), "Input file");

        po::positional_options_description p;
        p.add("input", -1);

        po::store(po::command_line_parser(argc, argv).options(desc).extra_parser(numeric_parser).positional(p).run(), options);
        po::notify(options);

        if(options.count("optimize-all")){
            OptimizeStrings = OptimizeUnused = true;
        }

        if(options.count("warning-all")){
            WarningUnused = true;
        }

        if(options.count("64") && options.count("32")){
            std::cout << "Invalid command line options : a compilation cannot be both 32 and 64 bits" << std::endl;

            return false;
        }
    } catch (const po::ambiguous_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return false;
    } catch (const po::unknown_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return false;
    } catch (const po::multiple_occurrences& e) {
        std::cout << "Only one file can be compiled" << std::endl;

        return false;
    }

    return true;
}

void eddic::printHelp(){
    std::cout << desc << std::endl;
}

void eddic::printVersion(){
    std::cout << "eddic version 0.8.1" << std::endl;
}
<|endoftext|>


<commit_before>#ifndef RADIAL_PAIRED_COORDINATES_VISUALIZATION_METHOD_HPP
#define RADIAL_PAIRED_COORDINATES_VISUALIZATION_METHOD_HPP
#include "LotsOfLines/IVisualizationMethod.hpp"

namespace LotsOfLines
{
	class RadialPairedCoordinatesVisualizationMethod : public IVisualizationMethod
	{
	public:

		VISUALIZATION_METHOD("Radial Paired Coordinates", EVT_RADIAL_PAIRED_COORDINATES)

		const char* DRAW_SEQUENTIALLY = "Draw lines sequentially";

		void getNavigationOptions(NavigationOptions& optionsOut)
		{
			optionsOut = NavigationOptions();
		}

		void getDefaultOptions(VisualizationOptions& options)
		{
			options.setBool(DRAW_SEQUENTIALLY, true);
		}

		bool generateVBO(const std::shared_ptr<const DataSet> dataSet, std::vector<Vertex>& verticesOut, std::vector<unsigned int>& indicesOut, const VisualizationOptions& options);
	};
}

#endif<commit_msg>Change radial paired name<commit_after>#ifndef RADIAL_PAIRED_COORDINATES_VISUALIZATION_METHOD_HPP
#define RADIAL_PAIRED_COORDINATES_VISUALIZATION_METHOD_HPP
#include "LotsOfLines/IVisualizationMethod.hpp"

namespace LotsOfLines
{
	class RadialPairedCoordinatesVisualizationMethod : public IVisualizationMethod
	{
	public:

		VISUALIZATION_METHOD("Radial (Anchored) Paired Coordinates", EVT_RADIAL_PAIRED_COORDINATES)

		const char* DRAW_SEQUENTIALLY = "Draw lines sequentially";

		void getNavigationOptions(NavigationOptions& optionsOut)
		{
			optionsOut = NavigationOptions();
		}

		void getDefaultOptions(VisualizationOptions& options)
		{
			options.setBool(DRAW_SEQUENTIALLY, true);
		}

		bool generateVBO(const std::shared_ptr<const DataSet> dataSet, std::vector<Vertex>& verticesOut, std::vector<unsigned int>& indicesOut, const VisualizationOptions& options);
	};
}

#endif<|endoftext|>