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

  Program:   Visualization Toolkit
  Module:    vtkTriangleFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkTriangleFilter.h"
#include "vtkPolygon.h"
#include "vtkTriangleStrip.h"

void vtkTriangleFilter::Execute()
{
  vtkPolyData *input=(vtkPolyData *)this->Input;
  int numCells=input->GetNumberOfCells();
  int dim, i, j, pts[3], cellNum, numPts, numSimplices, newId, type;
  vtkIdList *ptIds=vtkIdList::New();
  vtkPoints *spts=vtkPoints::New();
  vtkPolyData *output=this->GetOutput();
  vtkCellData *inCD=input->GetCellData();
  vtkCellData *outCD=output->GetCellData();
  vtkCell *cell;
  int updateInterval;
  int numPoints=input->GetNumberOfPoints();

  output->Allocate(numPoints, numPoints);

  updateInterval = numCells/100.0;
  if (updateInterval < 1)
    {
    updateInterval = 1;
    }
  for (cellNum=0; cellNum < numCells; cellNum++)
    {
    if ( ! (cellNum % updateInterval) ) //manage progress reports / early abort
      {
      this->UpdateProgress ((float)cellNum / numCells);
      if ( this->GetAbortExecute() )
        {
        break;
        }
      }

    cell = input->GetCell(cellNum);
    dim = cell->GetCellDimension() + 1;

    cell->Triangulate(cellNum, ptIds, spts);
    numPts = ptIds->GetNumberOfIds();
    numSimplices = numPts / dim;

    if ( dim == 3 || (this->PassVerts && dim == 1) ||
    (this->PassLines && dim == 2) )
      {
      type = (dim == 3 ? VTK_TRIANGLE : (dim == 2 ? VTK_LINE : VTK_VERTEX ));
      for ( i=0; i < numSimplices; i++ )
        {
        for (j=0; j<dim; j++)
          {
          pts[j] = ptIds->GetId(dim*i+j);
          }
        // copy cell data
        newId = output->InsertNextCell(type, dim, pts);
        outCD->CopyData(inCD, cellNum, newId);

        }//for each simplex
      }//if polygon or strip or (line or verts and passed on)
    }//for all cells

  ptIds->Delete();
  spts->Delete();

  // Update output
  output->SetPoints(input->GetPoints());
  output->GetPointData()->PassData(input->GetPointData());
  output->Squeeze();

  vtkDebugMacro(<<"Converted " << input->GetNumberOfCells()
                << "input cells to "
                << output->GetNumberOfCells()
                <<" output cells");
}

void vtkTriangleFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolyDataToPolyDataFilter::PrintSelf(os,indent);

  os << indent << "Pass Verts: " << (this->PassVerts ? "On\n" : "Off\n");
  os << indent << "Pass Lines: " << (this->PassLines ? "On\n" : "Off\n");

}

<commit_msg>ERR: was not crating cell attributes on output.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkTriangleFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkTriangleFilter.h"
#include "vtkPolygon.h"
#include "vtkTriangleStrip.h"

void vtkTriangleFilter::Execute()
{
  vtkPolyData *input=(vtkPolyData *)this->Input;
  int numCells=input->GetNumberOfCells();
  int dim, i, j, pts[3], cellNum, numPts, numSimplices, newId, type;
  vtkIdList *ptIds=vtkIdList::New();
  vtkPoints *spts=vtkPoints::New();
  vtkPolyData *output=this->GetOutput();
  vtkCellData *inCD=input->GetCellData();
  vtkCellData *outCD=output->GetCellData();
  vtkCell *cell;
  int updateInterval;
  int numPoints=input->GetNumberOfPoints();

  output->Allocate(numPoints, numPoints);
  outCD->CopyAllocate(inCD,numPoints);

  updateInterval = numCells/100.0;
  if (updateInterval < 1)
    {
    updateInterval = 1;
    }
  for (cellNum=0; cellNum < numCells; cellNum++)
    {
    if ( ! (cellNum % updateInterval) ) //manage progress reports / early abort
      {
      this->UpdateProgress ((float)cellNum / numCells);
      if ( this->GetAbortExecute() )
        {
        break;
        }
      }

    cell = input->GetCell(cellNum);
    dim = cell->GetCellDimension() + 1;

    cell->Triangulate(cellNum, ptIds, spts);
    numPts = ptIds->GetNumberOfIds();
    numSimplices = numPts / dim;

    if ( dim == 3 || (this->PassVerts && dim == 1) ||
    (this->PassLines && dim == 2) )
      {
      type = (dim == 3 ? VTK_TRIANGLE : (dim == 2 ? VTK_LINE : VTK_VERTEX ));
      for ( i=0; i < numSimplices; i++ )
        {
        for (j=0; j<dim; j++)
          {
          pts[j] = ptIds->GetId(dim*i+j);
          }
        // copy cell data
        newId = output->InsertNextCell(type, dim, pts);
        outCD->CopyData(inCD, cellNum, newId);

        }//for each simplex
      }//if polygon or strip or (line or verts and passed on)
    }//for all cells

  ptIds->Delete();
  spts->Delete();

  // Update output
  output->SetPoints(input->GetPoints());
  output->GetPointData()->PassData(input->GetPointData());
  output->Squeeze();

  vtkDebugMacro(<<"Converted " << input->GetNumberOfCells()
                << "input cells to "
                << output->GetNumberOfCells()
                <<" output cells");
}

void vtkTriangleFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolyDataToPolyDataFilter::PrintSelf(os,indent);

  os << indent << "Pass Verts: " << (this->PassVerts ? "On\n" : "Off\n");
  os << indent << "Pass Lines: " << (this->PassLines ? "On\n" : "Off\n");

}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbLogger.h"
#include "itksys/SystemTools.hxx"
#include "otbConfigurationManager.h"
#include "itkStdStreamLogOutput.h"
#include <iostream>
#include "gdal.h"
#include "itkMultiThreader.h"

#include <type_traits>
#include <cassert>

namespace otb
{

namespace
{
  static bool is_logger_singleton_level_set;
}

Logger::Logger() :
  m_LogSetupInfoDone(false)
{
  m_LevelForFlushing = itk::LoggerBase::CRITICAL;
  m_TimeStampFormat = itk::LoggerBase::HUMANREADABLE;
  m_HumanReadableFormat = "%Y-%m-%d %H:%M:%S";
}

Logger * Logger::CreateInstance()
{
  Logger * logger = new Logger;

  // By default, redirect logs to std::cout
  itk::StdStreamLogOutput::Pointer defaultOutput =
    itk::StdStreamLogOutput::New();
  defaultOutput->SetStream(std::cout);

  logger->AddLogOutput(defaultOutput);
  return logger;
}

Logger * Logger::Instance()
{
  static Logger * logger_singleton = CreateInstance();
  if ( !is_logger_singleton_level_set )
  {
    is_logger_singleton_level_set = true;
    logger_singleton->SetPriorityLevel(ConfigurationManager::GetLoggerLevel());
  }
  return logger_singleton;
}

Logger::Pointer Logger::New()
{
  Pointer smartPtr = new Logger;
  smartPtr->UnRegister();
  smartPtr->SetPriorityLevel(Instance()->GetPriorityLevel());
  return smartPtr;
}

void Logger::LogSetupInformation()
{
  if (! IsLogSetupInformationDone())
    {
    std::ostringstream oss;

    oss<<"Default RAM limit for OTB is "<<
      otb::ConfigurationManager::GetMaxRAMHint()<<" MB"<<std::endl;
    this->Info(oss.str());
    oss.str("");
    oss.clear();

    oss<<"GDAL maximum cache size is "<<
      GDALGetCacheMax64()/(1024*1024)<<" MB"<<std::endl;
    this->Info(oss.str());
    oss.str("");
    oss.clear();

    oss<<"OTB will use at most "<<
      itk::MultiThreader::GetGlobalDefaultNumberOfThreads()<<
      " threads"<<std::endl;
    this->Info(oss.str());
    oss.str("");
    oss.clear();

// ensure LogSetupInformation is done once per logger, and also that it is
// skipped by the singleton when it has already been printed by an other instance
    LogSetupInformationDone();
    Instance()->LogSetupInformationDone();
    }
}

bool Logger::IsLogSetupInformationDone()
{
  return m_LogSetupInfoDone;
}

void Logger::LogSetupInformationDone()
{
  m_LogSetupInfoDone = true;
}

std::string Logger::BuildFormattedEntry(itk::Logger::PriorityLevelType level, std::string const& content)
{
  static const std::string levelString[] = {"(MUSTFLUSH)", "(FATAL)", "(CRITICAL)", "(WARNING)", "(INFO)", "(DEBUG)", "(NOTSET)"};

  assert(level <= std::extent<decltype(levelString)>::value);

  std::ostringstream s;

  switch (this->m_TimeStampFormat)
  {
  case REALVALUE:
  {
    s.precision(30);
    s << m_Clock->GetTimeInSeconds();
    break;
  }
  case HUMANREADABLE:
  {
    s << itksys::SystemTools::GetCurrentDateTime(this->m_HumanReadableFormat.c_str());
    break;
  }
  }
  s << " " << levelString[level] << ": " << content;

  return s.str();
}

} // namespace otb
<commit_msg>REFAC: refactor otb::Logger::BuildFormattedEntry<commit_after>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbLogger.h"
#include "itksys/SystemTools.hxx"
#include "otbConfigurationManager.h"
#include "itkStdStreamLogOutput.h"
#include <iostream>
#include "gdal.h"
#include "itkMultiThreader.h"

#include <type_traits>
#include <cassert>

namespace otb
{

namespace
{
  static bool is_logger_singleton_level_set;
}

Logger::Logger() :
  m_LogSetupInfoDone(false)
{
  m_LevelForFlushing = itk::LoggerBase::CRITICAL;
  m_TimeStampFormat = itk::LoggerBase::HUMANREADABLE;
  m_HumanReadableFormat = "%Y-%m-%d %H:%M:%S";
}

Logger * Logger::CreateInstance()
{
  Logger * logger = new Logger;

  // By default, redirect logs to std::cout
  itk::StdStreamLogOutput::Pointer defaultOutput =
    itk::StdStreamLogOutput::New();
  defaultOutput->SetStream(std::cout);

  logger->AddLogOutput(defaultOutput);
  return logger;
}

Logger * Logger::Instance()
{
  static Logger * logger_singleton = CreateInstance();
  if ( !is_logger_singleton_level_set )
  {
    is_logger_singleton_level_set = true;
    logger_singleton->SetPriorityLevel(ConfigurationManager::GetLoggerLevel());
  }
  return logger_singleton;
}

Logger::Pointer Logger::New()
{
  Pointer smartPtr = new Logger;
  smartPtr->UnRegister();
  smartPtr->SetPriorityLevel(Instance()->GetPriorityLevel());
  return smartPtr;
}

void Logger::LogSetupInformation()
{
  if (! IsLogSetupInformationDone())
    {
    std::ostringstream oss;

    oss<<"Default RAM limit for OTB is "<<
      otb::ConfigurationManager::GetMaxRAMHint()<<" MB"<<std::endl;
    this->Info(oss.str());
    oss.str("");
    oss.clear();

    oss<<"GDAL maximum cache size is "<<
      GDALGetCacheMax64()/(1024*1024)<<" MB"<<std::endl;
    this->Info(oss.str());
    oss.str("");
    oss.clear();

    oss<<"OTB will use at most "<<
      itk::MultiThreader::GetGlobalDefaultNumberOfThreads()<<
      " threads"<<std::endl;
    this->Info(oss.str());
    oss.str("");
    oss.clear();

// ensure LogSetupInformation is done once per logger, and also that it is
// skipped by the singleton when it has already been printed by an other instance
    LogSetupInformationDone();
    Instance()->LogSetupInformationDone();
    }
}

bool Logger::IsLogSetupInformationDone()
{
  return m_LogSetupInfoDone;
}

void Logger::LogSetupInformationDone()
{
  m_LogSetupInfoDone = true;
}

std::string Logger::BuildFormattedEntry(itk::Logger::PriorityLevelType level, std::string const& content)
{
  static const std::string levelString[] = {"(MUSTFLUSH)", "(FATAL)", "(CRITICAL)", "(WARNING)", "(INFO)", "(DEBUG)", "(NOTSET)"};

  assert(level <= std::extent<decltype(levelString)>::value);

  return itksys::SystemTools::GetCurrentDateTime("%Y-%m-%d %H:%M:%S") + " " + levelString[level] + ": " + content;
}

} // namespace otb
<|endoftext|>


<commit_before>/// @file
/// @author  Boris Mikic
/// @version 3.0
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://www.opensource.org/licenses/bsd-license.php

#ifdef _OPENKODE
#include <KD/kd.h>

#include <gtypes/Vector2.h>
#include <hltypes/hlog.h>
#include <hltypes/hltypesUtil.h>
#include <hltypes/hmap.h>
#include <hltypes/hplatform.h>
#include <hltypes/hstring.h>

#include "april.h"

#ifdef _EGL
#include "egl.h"
#endif
#include "Platform.h"
#include "RenderSystem.h"
#include "Window.h"

#ifdef __APPLE__
	#include <TargetConditionals.h>
	#if TARGET_OS_IPHONE
		void getStaticiOSInfo(chstr name, april::SystemInfo& info);
	#endif
#endif

namespace april
{
	static SystemInfo info;
	SystemInfo getSystemInfo()
	{
		if (info.locale == "")
		{
			// RAM size
#if TARGET_IPHONE_SIMULATOR
			info.ram = 1024;
#else
			int ram;
			kdQueryAttribi(KD_ATTRIB_RAM, (KDint*)&ram);
			info.ram = ram / 1048576; // in MB
#endif

			// display resolution
			int width = 0;
			int height = 0;
			kdQueryAttribi(KD_ATTRIB_WIDTH, (KDint*)&width);
			kdQueryAttribi(KD_ATTRIB_HEIGHT, (KDint*)&height);
			info.displayResolution.set((float)width, (float)height);
			// display DPI
			kdQueryAttribi(KD_ATTRIB_DPI, (KDint*)&info.displayDpi);
			// other

			// number of CPU cores
			info.cpuCores = 1;
#if TARGET_OS_IPHONE // On iOS, april prefers to use hardcoded device info then OpenKODE's info, it's more accurate
			hstr model = kdQueryAttribcv(KD_ATTRIB_PLATFORM);
			if (model.contains("(") && model.contains(")"))
			{
				hstr a, b;
				model.split("(",a, b);
				b.split(")", model, a);
				getStaticiOSInfo(model, info);
			}
#endif

			info.locale = hstr(kdGetLocale());
			if (info.locale == "")
			{
				info.locale = "en"; // default is "en"
			}
			else if (info.locale.utf8_size() > 2)
			{
				info.locale = info.locale.utf8_substr(0, 2);
			}
		}
		if (info.maxTextureSize == 0 && april::rendersys != NULL)
		{
			info.maxTextureSize = april::rendersys->getMaxTextureSize();
		}
		return info;
	}

	DeviceType getDeviceType()
	{
		return DEVICE_OPENKODE;
	}

	hstr getPackageName()
	{
		return hstr(kdGetenv("KD_APP_ID"));
	}

	hstr getUserDataPath()
	{
		return "data";
	}

	void messageBox_platform(chstr title, chstr text, MessageBoxButton buttonMask, MessageBoxStyle style,
		hmap<MessageBoxButton, hstr> customButtonTitles, void(*callback)(MessageBoxButton))
	{
		hstr ok;
		hstr yes;
		hstr no;
		hstr cancel;
		_makeButtonLabels(&ok, &yes, &no, &cancel, buttonMask, customButtonTitles);
		const char* buttons[4] = {"", NULL, NULL, NULL};
		MessageBoxButton resultButtons[4] = {AMSGBTN_NULL, AMSGBTN_NULL, AMSGBTN_NULL, AMSGBTN_NULL};
		int indexCancel = -1;
		if ((buttonMask & AMSGBTN_OK) && (buttonMask & AMSGBTN_CANCEL))
		{
			buttons[0] = ok.c_str();
			buttons[1] = cancel.c_str();
			resultButtons[0] = AMSGBTN_OK;
			resultButtons[1] = AMSGBTN_CANCEL;
			indexCancel = 1;
		}
		else if ((buttonMask & AMSGBTN_YES) && (buttonMask & AMSGBTN_NO) && (buttonMask & AMSGBTN_CANCEL))
		{
			buttons[0] = yes.c_str();
			buttons[1] = no.c_str();
			buttons[2] = cancel.c_str();
			resultButtons[0] = AMSGBTN_YES;
			resultButtons[1] = AMSGBTN_NO;
			resultButtons[2] = AMSGBTN_CANCEL;
			indexCancel = 2;
		}
		else if (buttonMask & AMSGBTN_OK)
		{
			buttons[0] = ok.c_str();
			resultButtons[0] = AMSGBTN_OK;
			indexCancel = 0;
		}
		else if ((buttonMask & AMSGBTN_YES) && (buttonMask & AMSGBTN_NO))
		{
			buttons[0] = yes.c_str();
			buttons[1] = no.c_str();
			resultButtons[0] = AMSGBTN_YES;
			resultButtons[1] = AMSGBTN_NO;
			indexCancel = 1;
		}
		int index = kdShowMessage(title.c_str(), text.c_str(), buttons);
		if (index == -1)
		{
			index = indexCancel;
		}
		if (callback != NULL && index >= 0)
		{
			(*callback)(resultButtons[index]);
		}
	}

}
#endif
<commit_msg>OpenKODE: fixed messageBox button indexing<commit_after>/// @file
/// @author  Boris Mikic
/// @version 3.0
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://www.opensource.org/licenses/bsd-license.php

#ifdef _OPENKODE
#include <KD/kd.h>

#include <gtypes/Vector2.h>
#include <hltypes/hlog.h>
#include <hltypes/hltypesUtil.h>
#include <hltypes/hmap.h>
#include <hltypes/hplatform.h>
#include <hltypes/hstring.h>

#include "april.h"

#ifdef _EGL
#include "egl.h"
#endif
#include "Platform.h"
#include "RenderSystem.h"
#include "Window.h"

#ifdef __APPLE__
	#include <TargetConditionals.h>
	#if TARGET_OS_IPHONE
		void getStaticiOSInfo(chstr name, april::SystemInfo& info);
	#endif
#endif

namespace april
{
	static SystemInfo info;
	SystemInfo getSystemInfo()
	{
		if (info.locale == "")
		{
			// RAM size
#if TARGET_IPHONE_SIMULATOR
			info.ram = 1024;
#else
			int ram;
			kdQueryAttribi(KD_ATTRIB_RAM, (KDint*)&ram);
			info.ram = ram / 1048576; // in MB
#endif

			// display resolution
			int width = 0;
			int height = 0;
			kdQueryAttribi(KD_ATTRIB_WIDTH, (KDint*)&width);
			kdQueryAttribi(KD_ATTRIB_HEIGHT, (KDint*)&height);
			info.displayResolution.set((float)width, (float)height);
			// display DPI
			kdQueryAttribi(KD_ATTRIB_DPI, (KDint*)&info.displayDpi);
			// other

			// number of CPU cores
			info.cpuCores = 1;
#if TARGET_OS_IPHONE // On iOS, april prefers to use hardcoded device info then OpenKODE's info, it's more accurate
			hstr model = kdQueryAttribcv(KD_ATTRIB_PLATFORM);
			if (model.contains("(") && model.contains(")"))
			{
				hstr a, b;
				model.split("(",a, b);
				b.split(")", model, a);
				getStaticiOSInfo(model, info);
			}
#endif

			info.locale = hstr(kdGetLocale());
			if (info.locale == "")
			{
				info.locale = "en"; // default is "en"
			}
			else if (info.locale.utf8_size() > 2)
			{
				info.locale = info.locale.utf8_substr(0, 2);
			}
		}
		if (info.maxTextureSize == 0 && april::rendersys != NULL)
		{
			info.maxTextureSize = april::rendersys->getMaxTextureSize();
		}
		return info;
	}

	DeviceType getDeviceType()
	{
		return DEVICE_OPENKODE;
	}

	hstr getPackageName()
	{
		return hstr(kdGetenv("KD_APP_ID"));
	}

	hstr getUserDataPath()
	{
		return "data";
	}

	void messageBox_platform(chstr title, chstr text, MessageBoxButton buttonMask, MessageBoxStyle style,
		hmap<MessageBoxButton, hstr> customButtonTitles, void(*callback)(MessageBoxButton))
	{
		hstr ok;
		hstr yes;
		hstr no;
		hstr cancel;
		_makeButtonLabels(&ok, &yes, &no, &cancel, buttonMask, customButtonTitles);
		const char* buttons[4] = {"", NULL, NULL, NULL};
		MessageBoxButton resultButtons[4] = {AMSGBTN_NULL, AMSGBTN_NULL, AMSGBTN_NULL, AMSGBTN_NULL};
		int indexCancel = -1;
		if ((buttonMask & AMSGBTN_OK) && (buttonMask & AMSGBTN_CANCEL))
		{
			// order is reversed because libKD prefers the colored button to be at place [1], at least on iOS
			// if this is going to be changed for a new platform, ifdef the button order for iOS
			buttons[1] = ok.c_str();
			buttons[0] = cancel.c_str();
			resultButtons[1] = AMSGBTN_OK;
			resultButtons[0] = AMSGBTN_CANCEL;
			indexCancel = 0;
		}
		else if ((buttonMask & AMSGBTN_YES) && (buttonMask & AMSGBTN_NO) && (buttonMask & AMSGBTN_CANCEL))
		{
			buttons[1] = yes.c_str();
			buttons[0] = no.c_str();
			buttons[2] = cancel.c_str();
			resultButtons[1] = AMSGBTN_YES;
			resultButtons[0] = AMSGBTN_NO;
			resultButtons[2] = AMSGBTN_CANCEL;
			indexCancel = 2;
		}
		else if (buttonMask & AMSGBTN_OK)
		{
			buttons[0] = ok.c_str();
			resultButtons[0] = AMSGBTN_OK;
			indexCancel = 0;
		}
		else if ((buttonMask & AMSGBTN_YES) && (buttonMask & AMSGBTN_NO))
		{
			buttons[1] = yes.c_str();
			buttons[0] = no.c_str();
			resultButtons[1] = AMSGBTN_YES;
			resultButtons[0] = AMSGBTN_NO;
			indexCancel = 1;
		}
		int index = kdShowMessage(title.c_str(), text.c_str(), buttons);
		if (index == -1)
		{
			index = indexCancel;
		}
		if (callback != NULL && index >= 0)
		{
			(*callback)(resultButtons[index]);
		}
	}

}
#endif
<|endoftext|>


<commit_before>/* medDropSite.cpp ---
 *
 * Author: Julien Wintz
 * Copyright (C) 2008 - Julien Wintz, Inria.
 * Created: Fri Feb 19 17:41:43 2010 (+0100)
 * Version: $Id$
 * Last-Updated: Mon Feb 22 21:15:03 2010 (+0100)
 *           By: Julien Wintz
 *     Update #: 18
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "medViewPool.h"
#include <medCore/medMessageController.h>
#include <medCore/medAbstractView.h>

#include <dtkCore/dtkAbstractData.h>
#include <dtkCore/dtkAbstractProcess.h>
#include <dtkCore/dtkAbstractProcessFactory.h>

#include "medCore/medMessageController.h"

class medViewPoolPrivate
{
public:
    QList<medAbstractView *>                 views;
    QMap<medAbstractView*, dtkAbstractData*> viewData;
    QHash<QString, QString>                  propertySet;
};

medViewPool::medViewPool(void) : d (new medViewPoolPrivate)
{
    connect(this,SIGNAL(showInfo(QObject*,const QString&,unsigned int)),
            medMessageController::instance(),SLOT(showInfo(QObject*,const QString&,unsigned int)));
    connect(this,SIGNAL(showError(QObject*,const QString&,unsigned int)),
            medMessageController::instance(),SLOT(showError(QObject*,const QString&,unsigned int)));
}

medViewPool::~medViewPool(void)
{
    delete d;
    d = NULL;
}

void medViewPool::appendView (medAbstractView *view)
{
    if (!view || d->views.contains (view))
        return;

    if (d->views.count()==0) { // view will become daddy
        view->setProperty ("Daddy", "true");
    }

    d->views.append (view);

    connect (view, SIGNAL (propertySet(const QString&, const QString&)), this, SLOT (onViewPropertySet(const QString&, const QString &)));
    connect (view, SIGNAL (becomeDaddy(bool)),             this, SLOT (onViewDaddy(bool)));
    connect (view, SIGNAL (reg(bool)),                     this, SLOT (onViewReg(bool)));

    connect (view, SIGNAL (positionChanged  (const QVector3D  &)), this, SLOT (onViewPositionChanged  (const QVector3D  &)));
    connect (view, SIGNAL (zoomChanged      (double)),             this, SLOT (onViewZoomChanged      (double)));
    connect (view, SIGNAL (panChanged       (const QVector2D &)),  this, SLOT (onViewPanChanged       (const QVector2D  &)));
    connect (view, SIGNAL (windowingChanged (double, double)),     this, SLOT (onViewWindowingChanged (double, double)));

    connect (view, SIGNAL (cameraChanged     (const QVector3D &, const QVector3D &, const QVector3D &, double)),
             this, SLOT (onViewCameraChanged (const QVector3D &, const QVector3D &, const QVector3D &, double)));

    // set properties
    QHashIterator<QString, QString> it(d->propertySet);
    while (it.hasNext()) {
        it.next();
        view->setProperty (it.key(), it.value());
    }

}

void medViewPool::removeView (medAbstractView *view)
{
    if (!view || !d->views.contains (view))
        return;

    // look if a view is a daddy
    medAbstractView *refView = this->daddy();

    if (refView) {
        if (refView==view) { // we are daddy, we need to find a new daddy
            // change daddy
            QList<medAbstractView *>::iterator it = d->views.begin();
            for( ; it!=d->views.end(); it++)
                if ((*it)!=refView && (*it)->property ("Daddy")=="false") {
                    (*it)->setProperty ("Daddy", "true");
                    break;
                }

            medAbstractView *oldDaddy = refView;
            oldDaddy->setProperty ("Daddy", "false"); // not necessary
        }
    }

    disconnect (view, SIGNAL (propertySet(const QString&, const QString&)), this, SLOT (onViewPropertySet(const QString&, const QString &)));
    disconnect (view, SIGNAL (becomeDaddy(bool)),             this, SLOT (onViewDaddy(bool)));
    disconnect (view, SIGNAL (reg(bool)),                     this, SLOT (onViewReg(bool)));

    disconnect (view, SIGNAL (positionChanged  (const QVector3D  &)), this, SLOT (onViewPositionChanged  (const QVector3D  &)));
    disconnect (view, SIGNAL (zoomChanged      (double)),             this, SLOT (onViewZoomChanged      (double)));
    disconnect (view, SIGNAL (panChanged       (const QVector2D &)),  this, SLOT (onViewPanChanged       (const QVector2D  &)));
    disconnect (view, SIGNAL (windowingChanged (double, double)),     this, SLOT (onViewWindowingChanged (double, double)));

    disconnect (view, SIGNAL (cameraChanged     (const QVector3D &, const QVector3D &, const QVector3D &, double)),
             this, SLOT (onViewCameraChanged (const QVector3D &, const QVector3D &, const QVector3D &, double)));

    d->views.removeOne (view);
}

medAbstractView *medViewPool::daddy (void)
{
    QList<medAbstractView *>::iterator it = d->views.begin();
    for( ; it!=d->views.end(); it++) {
        if ((*it)->property ("Daddy")=="true")
            return (*it);
    }
    return NULL;
}

void medViewPool::onViewDaddy (bool daddy)
{
    if (medAbstractView *view = dynamic_cast<medAbstractView *>(this->sender())) {

        if (daddy) { // view wants to become daddy

            medAbstractView *refView = this->daddy();

            // tell all views that they are not daddys
            QList<medAbstractView *>::iterator it = d->views.begin();
            for( ; it!=d->views.end(); it++)
                (*it)->setProperty ("Daddy", "false");

            // tell the sender it is now daddy
            view->setProperty ("Daddy", "true");

            // restore the previous data (if any)
            if ( d->viewData[view] ) {
                view->setData (d->viewData[view]);
                d->viewData[view] = NULL;
		if (view->widget()->isVisible())
		    view->update();
            }
        }
        else { // view does not want to become daddy
            view->setProperty ("Daddy", "false");
        }
    }
}

void medViewPool::onViewReg(bool value)
{
	if (medAbstractView *view = dynamic_cast<medAbstractView *>(this->sender())) {

        if (value) {
            medAbstractView *refView = this->daddy();

            if (refView==view) // do not register the view with itself
                return;

            if (refView) {

                dtkAbstractData *data1 = static_cast<dtkAbstractData *>(refView->data());
                dtkAbstractData *data2 = static_cast<dtkAbstractData *>(view->data());

                if (data1!=data2) {// do not register the same data

                    dtkAbstractProcess *process = dtkAbstractProcessFactory::instance()->create("itkProcessRegistration");
                    if (!process)
                        return;

                    process->setInput (data1, 0);
                    process->setInput (data2, 1);

                    if (process->run()==0) {
                        dtkAbstractData *output = process->output();
                        d->viewData[view] = data2;
                        view->setData (output);
			if (view->widget()->isVisible())
			    view->update();
                        emit showInfo (this, tr ("Automatic registration successful"),3000);
                    }
                    else {
                        emit showError(this, tr  ("Automatic registration failed"),3000);
                    }
                    delete process;
                }

            }
        }
        else { // restore the previous data (if any)
            if ( d->viewData[view] ) {
                dtkAbstractData *oldData = static_cast<dtkAbstractData*>( view->data() );
                view->setData (d->viewData[view]);
                d->viewData[view] = NULL;
                if (oldData)
                    delete oldData;
		if (view->widget()->isVisible())
		    view->update();
            }
        }
    }
}

void medViewPool::onViewPropertySet (const QString &key, const QString &value)
{
    // property that we do not want to synchronize
    if (key=="Daddy" ||
        key=="PositionLinked" ||
        key=="CameraLinked" ||
        key=="WindowingLinked" ||
        key=="Orientation")
        return;

    d->propertySet[key] = value;

    // first, block all signals
    foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

    // second, propagate properties
    foreach (medAbstractView *lview, d->views) {
        if (lview!=this->sender()) {
            lview->setProperty (key, value);
	    if (lview->widget()->isVisible())
	        lview->update();
        }
    }

    // third, restore signals
    foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
}

void medViewPool::onViewPositionChanged (const QVector3D &position)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->positionLinked()) {
        // first, block all signals
        foreach (medAbstractView *lview, d->views)
	    lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->positionLinked()) {
                lview->setPosition (position);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

void medViewPool::onViewCameraChanged (const QVector3D &position, const QVector3D &viewup, const QVector3D &focal, double parallelScale)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->cameraLinked()) {
      // first, block all signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->cameraLinked()) {
                lview->setCamera (position, viewup, focal, parallelScale);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

void medViewPool::onViewZoomChanged (double zoom)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->cameraLinked()) {
        // first, block all signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->cameraLinked()) {
                lview->setZoom (zoom);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

void medViewPool::onViewPanChanged (const QVector2D &pan)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->cameraLinked()) {
        // first, block all signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->cameraLinked()) {
                lview->setPan (pan);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

void medViewPool::onViewWindowingChanged (double level, double window)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->windowingLinked()) {
        // first, block all signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->windowingLinked()) {
                lview->setWindowLevel (level, window);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

int medViewPool::count (void)
{
    return d->views.count();
}
<commit_msg>Do not propagate LookupTable property<commit_after>/* medDropSite.cpp ---
 *
 * Author: Julien Wintz
 * Copyright (C) 2008 - Julien Wintz, Inria.
 * Created: Fri Feb 19 17:41:43 2010 (+0100)
 * Version: $Id$
 * Last-Updated: Mon Feb 22 21:15:03 2010 (+0100)
 *           By: Julien Wintz
 *     Update #: 18
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "medViewPool.h"
#include <medCore/medMessageController.h>
#include <medCore/medAbstractView.h>

#include <dtkCore/dtkAbstractData.h>
#include <dtkCore/dtkAbstractProcess.h>
#include <dtkCore/dtkAbstractProcessFactory.h>

#include "medCore/medMessageController.h"

class medViewPoolPrivate
{
public:
    QList<medAbstractView *>                 views;
    QMap<medAbstractView*, dtkAbstractData*> viewData;
    QHash<QString, QString>                  propertySet;
};

medViewPool::medViewPool(void) : d (new medViewPoolPrivate)
{
    connect(this,SIGNAL(showInfo(QObject*,const QString&,unsigned int)),
            medMessageController::instance(),SLOT(showInfo(QObject*,const QString&,unsigned int)));
    connect(this,SIGNAL(showError(QObject*,const QString&,unsigned int)),
            medMessageController::instance(),SLOT(showError(QObject*,const QString&,unsigned int)));
}

medViewPool::~medViewPool(void)
{
    delete d;
    d = NULL;
}

void medViewPool::appendView (medAbstractView *view)
{
    if (!view || d->views.contains (view))
        return;

    if (d->views.count()==0) { // view will become daddy
        view->setProperty ("Daddy", "true");
    }

    d->views.append (view);

    connect (view, SIGNAL (propertySet(const QString&, const QString&)), this, SLOT (onViewPropertySet(const QString&, const QString &)));
    connect (view, SIGNAL (becomeDaddy(bool)),             this, SLOT (onViewDaddy(bool)));
    connect (view, SIGNAL (reg(bool)),                     this, SLOT (onViewReg(bool)));

    connect (view, SIGNAL (positionChanged  (const QVector3D  &)), this, SLOT (onViewPositionChanged  (const QVector3D  &)));
    connect (view, SIGNAL (zoomChanged      (double)),             this, SLOT (onViewZoomChanged      (double)));
    connect (view, SIGNAL (panChanged       (const QVector2D &)),  this, SLOT (onViewPanChanged       (const QVector2D  &)));
    connect (view, SIGNAL (windowingChanged (double, double)),     this, SLOT (onViewWindowingChanged (double, double)));

    connect (view, SIGNAL (cameraChanged     (const QVector3D &, const QVector3D &, const QVector3D &, double)),
             this, SLOT (onViewCameraChanged (const QVector3D &, const QVector3D &, const QVector3D &, double)));

    // set properties
    QHashIterator<QString, QString> it(d->propertySet);
    while (it.hasNext()) {
        it.next();
        view->setProperty (it.key(), it.value());
    }

}

void medViewPool::removeView (medAbstractView *view)
{
    if (!view || !d->views.contains (view))
        return;

    // look if a view is a daddy
    medAbstractView *refView = this->daddy();

    if (refView) {
        if (refView==view) { // we are daddy, we need to find a new daddy
            // change daddy
            QList<medAbstractView *>::iterator it = d->views.begin();
            for( ; it!=d->views.end(); it++)
                if ((*it)!=refView && (*it)->property ("Daddy")=="false") {
                    (*it)->setProperty ("Daddy", "true");
                    break;
                }

            medAbstractView *oldDaddy = refView;
            oldDaddy->setProperty ("Daddy", "false"); // not necessary
        }
    }

    disconnect (view, SIGNAL (propertySet(const QString&, const QString&)), this, SLOT (onViewPropertySet(const QString&, const QString &)));
    disconnect (view, SIGNAL (becomeDaddy(bool)),             this, SLOT (onViewDaddy(bool)));
    disconnect (view, SIGNAL (reg(bool)),                     this, SLOT (onViewReg(bool)));

    disconnect (view, SIGNAL (positionChanged  (const QVector3D  &)), this, SLOT (onViewPositionChanged  (const QVector3D  &)));
    disconnect (view, SIGNAL (zoomChanged      (double)),             this, SLOT (onViewZoomChanged      (double)));
    disconnect (view, SIGNAL (panChanged       (const QVector2D &)),  this, SLOT (onViewPanChanged       (const QVector2D  &)));
    disconnect (view, SIGNAL (windowingChanged (double, double)),     this, SLOT (onViewWindowingChanged (double, double)));

    disconnect (view, SIGNAL (cameraChanged     (const QVector3D &, const QVector3D &, const QVector3D &, double)),
             this, SLOT (onViewCameraChanged (const QVector3D &, const QVector3D &, const QVector3D &, double)));

    d->views.removeOne (view);
}

medAbstractView *medViewPool::daddy (void)
{
    QList<medAbstractView *>::iterator it = d->views.begin();
    for( ; it!=d->views.end(); it++) {
        if ((*it)->property ("Daddy")=="true")
            return (*it);
    }
    return NULL;
}

void medViewPool::onViewDaddy (bool daddy)
{
    if (medAbstractView *view = dynamic_cast<medAbstractView *>(this->sender())) {

        if (daddy) { // view wants to become daddy

            medAbstractView *refView = this->daddy();

            // tell all views that they are not daddys
            QList<medAbstractView *>::iterator it = d->views.begin();
            for( ; it!=d->views.end(); it++)
                (*it)->setProperty ("Daddy", "false");

            // tell the sender it is now daddy
            view->setProperty ("Daddy", "true");

            // restore the previous data (if any)
            if ( d->viewData[view] ) {
                view->setData (d->viewData[view]);
                d->viewData[view] = NULL;
		if (view->widget()->isVisible())
		    view->update();
            }
        }
        else { // view does not want to become daddy
            view->setProperty ("Daddy", "false");
        }
    }
}

void medViewPool::onViewReg(bool value)
{
	if (medAbstractView *view = dynamic_cast<medAbstractView *>(this->sender())) {

        if (value) {
            medAbstractView *refView = this->daddy();

            if (refView==view) // do not register the view with itself
                return;

            if (refView) {

                dtkAbstractData *data1 = static_cast<dtkAbstractData *>(refView->data());
                dtkAbstractData *data2 = static_cast<dtkAbstractData *>(view->data());

                if (data1!=data2) {// do not register the same data

                    dtkAbstractProcess *process = dtkAbstractProcessFactory::instance()->create("itkProcessRegistration");
                    if (!process)
                        return;

                    process->setInput (data1, 0);
                    process->setInput (data2, 1);

                    if (process->run()==0) {
                        dtkAbstractData *output = process->output();
                        d->viewData[view] = data2;
                        view->setData (output);
			if (view->widget()->isVisible())
			    view->update();
                        emit showInfo (this, tr ("Automatic registration successful"),3000);
                    }
                    else {
                        emit showError(this, tr  ("Automatic registration failed"),3000);
                    }
                    delete process;
                }

            }
        }
        else { // restore the previous data (if any)
            if ( d->viewData[view] ) {
                dtkAbstractData *oldData = static_cast<dtkAbstractData*>( view->data() );
                view->setData (d->viewData[view]);
                d->viewData[view] = NULL;
                if (oldData)
                    delete oldData;
		if (view->widget()->isVisible())
		    view->update();
            }
        }
    }
}

void medViewPool::onViewPropertySet (const QString &key, const QString &value)
{
    // property that we do not want to synchronize
    if (key=="Daddy" ||
        key=="PositionLinked" ||
        key=="CameraLinked" ||
        key=="WindowingLinked" ||
        key=="Orientation" ||
        key=="LookupTable")
        return;

    d->propertySet[key] = value;

    // first, block all signals
    foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

    // second, propagate properties
    foreach (medAbstractView *lview, d->views) {
        if (lview!=this->sender()) {
            lview->setProperty (key, value);
	    if (lview->widget()->isVisible())
	        lview->update();
        }
    }

    // third, restore signals
    foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
}

void medViewPool::onViewPositionChanged (const QVector3D &position)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->positionLinked()) {
        // first, block all signals
        foreach (medAbstractView *lview, d->views)
	    lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->positionLinked()) {
                lview->setPosition (position);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

void medViewPool::onViewCameraChanged (const QVector3D &position, const QVector3D &viewup, const QVector3D &focal, double parallelScale)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->cameraLinked()) {
      // first, block all signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->cameraLinked()) {
                lview->setCamera (position, viewup, focal, parallelScale);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

void medViewPool::onViewZoomChanged (double zoom)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->cameraLinked()) {
        // first, block all signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->cameraLinked()) {
                lview->setZoom (zoom);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

void medViewPool::onViewPanChanged (const QVector2D &pan)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->cameraLinked()) {
        // first, block all signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->cameraLinked()) {
                lview->setPan (pan);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

void medViewPool::onViewWindowingChanged (double level, double window)
{
    medAbstractView *vsender = dynamic_cast<medAbstractView*>(this->sender());

    if (!vsender) {
        qDebug() << "Sender seems not to be a medAbstractView";
        return;
    }

    if (vsender->windowingLinked()) {
        // first, block all signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (true);

        // second, propagate properties
        foreach (medAbstractView *lview, d->views) {
            if (lview!=this->sender() && lview->windowingLinked()) {
                lview->setWindowLevel (level, window);
		if (lview->widget()->isVisible())
		    lview->update();
            }
        }

        // third, restore signals
        foreach (medAbstractView *lview, d->views)
        lview->blockSignals (false);
    }
}

int medViewPool::count (void)
{
    return d->views.count();
}
<|endoftext|>


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

#include "chrome/browser/ui/webui/hung_renderer_dialog_ui.h"

#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h"
#include "chrome/common/url_constants.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "chrome/browser/profiles/profile.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"

HungRendererDialogUI::HungRendererDialogUI(TabContents* contents)
    : HtmlDialogUI(contents) {
  ChromeWebUIDataSource* source =
      new ChromeWebUIDataSource(chrome::kChromeUIHungRendererDialogHost);

  source->AddLocalizedString("title", IDS_BROWSER_HANGMONITOR_RENDERER_TITLE);
  source->AddLocalizedString("explanation", IDS_BROWSER_HANGMONITOR_RENDERER);
  source->AddLocalizedString("kill", IDS_BROWSER_HANGMONITOR_RENDERER_END);
  source->AddLocalizedString("wait", IDS_BROWSER_HANGMONITOR_RENDERER_WAIT);

  // Set the json path.
  source->set_json_path("strings.js");

  // Add required resources.
  source->add_resource_path("hung_renderer_dialog.js",
                            IDR_HUNG_RENDERER_DIALOG_JS);
  source->add_resource_path("hung_renderer_dialog.css",
                            IDR_HUNG_RENDERER_DIALOG_CSS);

  // Set default resource.
  source->set_default_resource(IDR_HUNG_RENDERER_DIALOG_HTML);

  Profile* profile = Profile::FromBrowserContext(contents->browser_context());
  profile->GetChromeURLDataManager()->AddDataSource(source);
}

HungRendererDialogUI::~HungRendererDialogUI() {
}
<commit_msg>Add a theme source for the WebUI hung renderer dialog.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/hung_renderer_dialog_ui.h"

#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h"
#include "chrome/browser/ui/webui/theme_source.h"
#include "chrome/common/url_constants.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "chrome/browser/profiles/profile.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"

HungRendererDialogUI::HungRendererDialogUI(TabContents* contents)
    : HtmlDialogUI(contents) {
  ChromeWebUIDataSource* source =
      new ChromeWebUIDataSource(chrome::kChromeUIHungRendererDialogHost);

  source->AddLocalizedString("title", IDS_BROWSER_HANGMONITOR_RENDERER_TITLE);
  source->AddLocalizedString("explanation", IDS_BROWSER_HANGMONITOR_RENDERER);
  source->AddLocalizedString("kill", IDS_BROWSER_HANGMONITOR_RENDERER_END);
  source->AddLocalizedString("wait", IDS_BROWSER_HANGMONITOR_RENDERER_WAIT);

  // Set the json path.
  source->set_json_path("strings.js");

  // Add required resources.
  source->add_resource_path("hung_renderer_dialog.js",
                            IDR_HUNG_RENDERER_DIALOG_JS);
  source->add_resource_path("hung_renderer_dialog.css",
                            IDR_HUNG_RENDERER_DIALOG_CSS);

  // Set default resource.
  source->set_default_resource(IDR_HUNG_RENDERER_DIALOG_HTML);

  Profile* profile = Profile::FromBrowserContext(contents->browser_context());
  profile->GetChromeURLDataManager()->AddDataSource(source);

  // Set up the chrome://theme/ source.
  ThemeSource* theme = new ThemeSource(profile);
  profile->GetChromeURLDataManager()->AddDataSource(theme);
}

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


<commit_before>#include <chrono>

class Timer {

public:
  using clock = std::chrono::steady_clock;

  template <typename T>
  std::size_t time() const {
    return std::chrono::duration_cast<T>(clock::now() - start).count();
  }

  std::size_t nanoseconds() const { return time<std::chrono::nanoseconds>(); }
  std::size_t microseconds() const { return time<std::chrono::microseconds>(); }
  std::size_t milliseconds() const { return time<std::chrono::milliseconds>(); }
  std::size_t seconds() const { return time<std::chrono::seconds>(); }
  std::size_t minutes() const { return time<std::chrono::minutes>(); }
  std::size_t hours() const { return time<std::chrono::hours>(); }

private:

  clock::time_point start = clock::now();

};

#include <QApplication>
#include <QDockWidget>
#include <QHBoxLayout>
#include <QImage>
#include <QLabel>
#include <QMainWindow>
#include <QObjectCleanupHandler>
#include <QPixmap>
#include <QResource>
#include <QSplitter>
#include <QVBoxLayout>
#include <QWebFrame>
#include <QWebPage>
#include <QWebSettings>
#include <QWebView>
#include <QWebPluginFactory>

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>

auto convertToMat(const QImage& source) {

  return cv::Mat(source.height(),source.width(),CV_8UC4,(uchar*)source.bits(),source.bytesPerLine());
  // cv::Mat result; // deep copy just in case (my lack of knowledge with open cv)
  // cv::cvtColor(tmp, result, CV_RGBA2BGR);
  // return result;
}

auto convertToQImage(const cv::Mat& source) {

  auto color_table = [] {
    static auto table = [] {
      QVector<QRgb> table;
      for (int i = 0;i < 256;++i) table.push_back( qRgb(i,i,i) );
      return table;
    }();
    return table;
  };
  int step = source.step;
  switch (source.type()) {
  case CV_8UC4: return QImage{source.data, source.cols, source.rows, step, QImage::Format_RGB32};
  case CV_8UC3: return QImage{source.data, source.cols, source.rows, step, QImage::Format_RGB888};
  case CV_8UC1: {
    QImage image{source.data, source.cols, source.rows, step, QImage::Format_Indexed8};
    image.setColorTable(color_table());
    return image;
  }
  default:
    qWarning() << "Cannot convert OpenCV Mat to QImage";
    return QImage();
  }
}

class ImageViewer : public QLabel {
  Q_OBJECT
public:

  template <typename T> T get(const QVariant& value, T default_value) {
    if (value.isValid()) return value.value<T>();
    return default_value;
  }

  ImageViewer(QUrl url, QVariantMap params, QWidget* parent = 0) : QLabel(parent) {

    QNetworkRequest request(url);
    auto reply = network_access_manager.get(request);

    req_width = get(params["width"], 0);
    req_height = get(params["height"], 0);

    connect(reply, &QNetworkReply::finished, [=] {
      raw_image.loadFromData( reply->readAll() );
      reply->deleteLater();

      scaleImage(raw_image);
    });

  }

public slots:

  void threshold() {
    qDebug() << "threshold";
    Timer t;
    auto tmp = convertToMat(raw_image);
    cv::cvtColor(tmp, tmp, cv::RBG2GRAY);
    tmp = tmp > 128;
    cv::resize(tmp, tmp, {500, 500});
    auto img = convertToQImage(tmp);
    qDebug() << "time:" << t.milliseconds() << "ms";
    scaleImage( img );

  }

  void blur() {
    Timer t;
    auto tmp = convertToMat(raw_image);
    cv::GaussianBlur(tmp, tmp, cv::Size(3,3), 0, 0);
//    cv::resize(tmp, tmp, {500, 500});
    auto img = convertToQImage(tmp);
    qDebug() << "time:" << t.milliseconds() << "ms";
    scaleImage( img );

  }

  void grayscale() {
    Timer t;
    auto tmp = convertToMat(raw_image);
    cv::cvtColor(tmp, tmp, cv::RGB2GRAY);
//    cv::resize(tmp, tmp, {500, 500});
    auto img = convertToQImage(tmp);
    qDebug() << "time:" << t.milliseconds() << "ms";
    scaleImage( img );
  }

  void sharpen() {
    Timer t;
    auto tmp = convertToMat(raw_image);
    cv::Mat mask;
    cv::GaussianBlur(tmp, mask, cv::Size(0, 0), 3);
    cv::addWeighted(tmp, 1.5, mask, -0.5, 0, tmp);
//    cv::resize(tmp, tmp, {500, 500});
    auto img = convertToQImage(tmp);
    qDebug() << "time:" << t.milliseconds() << "ms";
    scaleImage( img );
  }

  void scaleImage(const QImage& input) {

      if (req_width > 0 && req_height == 0)      cur_image = input.scaledToWidth(req_width, Qt::SmoothTransformation);
      else if (req_width == 0 && req_height > 0) cur_image = input.scaledToHeight(req_height, Qt::SmoothTransformation);
      else if (req_width > 0 && req_height > 0)  cur_image = input.scaled(req_width, req_height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
      else cur_image = input;

//      setFixedSize(std::min(req_width, cur_image.width()),
//                   std::min(req_height, cur_image.height()));

      qDebug() << input.width() << input.height() << width() << height() << cur_image.width() << cur_image.height();
      setPixmap(QPixmap::fromImage(cur_image));
      setScaledContents(true);
//      updateGeometry();
  }
private:

  QImage raw_image, cur_image;
  cv::Mat cv_image;

  int req_width, req_height;
  QNetworkAccessManager network_access_manager;
};

class WebPage : public QWebPage {
  Q_OBJECT
public:

  WebPage(QObject* parent = 0) : QWebPage(parent) {
    setLinkDelegationPolicy(DelegateAllLinks);
  }

  QObject* createPlugin(
      const QString & classid,
      const QUrl & url,
      const QStringList & paramNames,
      const QStringList & paramValues) {

    qDebug() << url;

    QVariantMap params;

    for (int i = 0;i < paramNames.size();++i) {
      params.insert(paramNames[i], paramValues[i]);
    }

    if (classid == "se.susi.Filter") {
      auto result = new ImageViewer(url, std::move(params));
//      cleanup_handler.add(result);
      return result;
    }

    return QWebPage::createPlugin(classid, url, paramNames, paramValues);
  }
private:

  QObjectCleanupHandler cleanup_handler;

};

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

  QApplication app(argc, argv);

  QResource::registerResource("assets.rcc");
  auto settings = QWebSettings::globalSettings();
  settings->setAttribute(QWebSettings::DnsPrefetchEnabled, true);
  settings->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
  settings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
  settings->setAttribute(QWebSettings::LocalStorageEnabled, true);
  settings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, true);

  QMainWindow main_window;
  auto view = new QWebView();
  auto page = new WebPage(view);
  view->setPage(page);
//  view->setFixedWidth(1024);

  auto navigate = [=](auto url) {
    qDebug() << "url: " << url;
    page->mainFrame()->evaluateJavaScript( QString("navigate('%1');").arg(url.toString()) );
  };

  auto header = new QWebView();
  header->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
  QObject::connect(header->page(), &QWebPage::linkClicked, navigate);
  header->setFixedHeight(50);
  header->load(QUrl("qrc:///contents/header.html"));

  auto sidebar = new QWebView();
  sidebar->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
  QObject::connect(sidebar->page(), &QWebPage::linkClicked, navigate);
  sidebar->setFixedWidth(150);

  sidebar->load(QUrl("qrc:///contents/sidebar.html"));

  auto header_dock = new QDockWidget();
  header_dock->setWidget(header);
  header_dock->setFeatures(
    QDockWidget::DockWidgetVerticalTitleBar
  );
  header_dock->setTitleBarWidget(new QWidget(&main_window));
  main_window.addDockWidget(Qt::DockWidgetArea::TopDockWidgetArea, header_dock);

  auto sidebar_dock = new QDockWidget();
  sidebar_dock->setWidget(sidebar);
  sidebar_dock->setTitleBarWidget(new QWidget(&main_window));

  main_window.addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, sidebar_dock);

  auto main_dock = new QDockWidget();
  main_dock->setWidget(view);
  main_dock->setTitleBarWidget(new QWidget(&main_window));

  main_window.setCentralWidget(main_dock);
  main_window.resize(800, 600);
  main_window.show();
  view->load(QUrl("qrc:///contents/main.html"));

  return app.exec();
}

#include "main.moc"
<commit_msg>OpenCV 3.0 syntax change<commit_after>#include <chrono>

class Timer {

public:
  using clock = std::chrono::steady_clock;

  template <typename T>
  std::size_t time() const {
    return std::chrono::duration_cast<T>(clock::now() - start).count();
  }

  std::size_t nanoseconds() const { return time<std::chrono::nanoseconds>(); }
  std::size_t microseconds() const { return time<std::chrono::microseconds>(); }
  std::size_t milliseconds() const { return time<std::chrono::milliseconds>(); }
  std::size_t seconds() const { return time<std::chrono::seconds>(); }
  std::size_t minutes() const { return time<std::chrono::minutes>(); }
  std::size_t hours() const { return time<std::chrono::hours>(); }

private:

  clock::time_point start = clock::now();

};

#include <QApplication>
#include <QDockWidget>
#include <QHBoxLayout>
#include <QImage>
#include <QLabel>
#include <QMainWindow>
#include <QObjectCleanupHandler>
#include <QPixmap>
#include <QResource>
#include <QSplitter>
#include <QVBoxLayout>
#include <QWebFrame>
#include <QWebPage>
#include <QWebSettings>
#include <QWebView>
#include <QWebPluginFactory>

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>

auto convertToMat(const QImage& source) {

  return cv::Mat(source.height(),source.width(),CV_8UC4,(uchar*)source.bits(),source.bytesPerLine());
  // cv::Mat result; // deep copy just in case (my lack of knowledge with open cv)
  // cv::cvtColor(tmp, result, CV_RGBA2BGR);
  // return result;
}

auto convertToQImage(const cv::Mat& source) {

  auto color_table = [] {
    static auto table = [] {
      QVector<QRgb> table;
      for (int i = 0;i < 256;++i) table.push_back( qRgb(i,i,i) );
      return table;
    }();
    return table;
  };
  int step = source.step;
  switch (source.type()) {
  case CV_8UC4: return QImage{source.data, source.cols, source.rows, step, QImage::Format_RGB32};
  case CV_8UC3: return QImage{source.data, source.cols, source.rows, step, QImage::Format_RGB888};
  case CV_8UC1: {
    QImage image{source.data, source.cols, source.rows, step, QImage::Format_Indexed8};
    image.setColorTable(color_table());
    return image;
  }
  default:
    qWarning() << "Cannot convert OpenCV Mat to QImage";
    return QImage();
  }
}

class ImageViewer : public QLabel {
  Q_OBJECT
public:

  template <typename T> T get(const QVariant& value, T default_value) {
    if (value.isValid()) return value.value<T>();
    return default_value;
  }

  ImageViewer(QUrl url, QVariantMap params, QWidget* parent = 0) : QLabel(parent) {

    QNetworkRequest request(url);
    auto reply = network_access_manager.get(request);

    req_width = get(params["width"], 0);
    req_height = get(params["height"], 0);

    connect(reply, &QNetworkReply::finished, [=] {
      raw_image.loadFromData( reply->readAll() );
      reply->deleteLater();

      scaleImage(raw_image);
    });

  }

public slots:

  void threshold() {
    qDebug() << "threshold";
    Timer t;
    auto tmp = convertToMat(raw_image);
    cv::cvtColor(tmp, tmp, cv::BGR2GRAY);
    tmp = tmp > 128;
    cv::resize(tmp, tmp, {500, 500});
    auto img = convertToQImage(tmp);
    qDebug() << "time:" << t.milliseconds() << "ms";
    scaleImage( img );

  }

  void blur() {
    Timer t;
    auto tmp = convertToMat(raw_image);
    cv::GaussianBlur(tmp, tmp, cv::Size(3,3), 0, 0);
//    cv::resize(tmp, tmp, {500, 500});
    auto img = convertToQImage(tmp);
    qDebug() << "time:" << t.milliseconds() << "ms";
    scaleImage( img );

  }

  void grayscale() {
    Timer t;
    auto tmp = convertToMat(raw_image);
    cv::cvtColor(tmp, tmp, cv::BGR2GRAY);
//    cv::resize(tmp, tmp, {500, 500});
    auto img = convertToQImage(tmp);
    qDebug() << "time:" << t.milliseconds() << "ms";
    scaleImage( img );
  }

  void sharpen() {
    Timer t;
    auto tmp = convertToMat(raw_image);
    cv::Mat mask;
    cv::GaussianBlur(tmp, mask, cv::Size(0, 0), 3);
    cv::addWeighted(tmp, 1.5, mask, -0.5, 0, tmp);
//    cv::resize(tmp, tmp, {500, 500});
    auto img = convertToQImage(tmp);
    qDebug() << "time:" << t.milliseconds() << "ms";
    scaleImage( img );
  }

  void scaleImage(const QImage& input) {

      if (req_width > 0 && req_height == 0)      cur_image = input.scaledToWidth(req_width, Qt::SmoothTransformation);
      else if (req_width == 0 && req_height > 0) cur_image = input.scaledToHeight(req_height, Qt::SmoothTransformation);
      else if (req_width > 0 && req_height > 0)  cur_image = input.scaled(req_width, req_height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
      else cur_image = input;

//      setFixedSize(std::min(req_width, cur_image.width()),
//                   std::min(req_height, cur_image.height()));

      qDebug() << input.width() << input.height() << width() << height() << cur_image.width() << cur_image.height();
      setPixmap(QPixmap::fromImage(cur_image));
      setScaledContents(true);
//      updateGeometry();
  }
private:

  QImage raw_image, cur_image;
  cv::Mat cv_image;

  int req_width, req_height;
  QNetworkAccessManager network_access_manager;
};

class WebPage : public QWebPage {
  Q_OBJECT
public:

  WebPage(QObject* parent = 0) : QWebPage(parent) {
    setLinkDelegationPolicy(DelegateAllLinks);
  }

  QObject* createPlugin(
      const QString & classid,
      const QUrl & url,
      const QStringList & paramNames,
      const QStringList & paramValues) {

    qDebug() << url;

    QVariantMap params;

    for (int i = 0;i < paramNames.size();++i) {
      params.insert(paramNames[i], paramValues[i]);
    }

    if (classid == "se.susi.Filter") {
      auto result = new ImageViewer(url, std::move(params));
//      cleanup_handler.add(result);
      return result;
    }

    return QWebPage::createPlugin(classid, url, paramNames, paramValues);
  }
private:

  QObjectCleanupHandler cleanup_handler;

};

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

  QApplication app(argc, argv);

  QResource::registerResource("assets.rcc");
  auto settings = QWebSettings::globalSettings();
  settings->setAttribute(QWebSettings::DnsPrefetchEnabled, true);
  settings->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
  settings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
  settings->setAttribute(QWebSettings::LocalStorageEnabled, true);
  settings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, true);

  QMainWindow main_window;
  auto view = new QWebView();
  auto page = new WebPage(view);
  view->setPage(page);
//  view->setFixedWidth(1024);

  auto navigate = [=](auto url) {
    qDebug() << "url: " << url;
    page->mainFrame()->evaluateJavaScript( QString("navigate('%1');").arg(url.toString()) );
  };

  auto header = new QWebView();
  header->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
  QObject::connect(header->page(), &QWebPage::linkClicked, navigate);
  header->setFixedHeight(50);
  header->load(QUrl("qrc:///contents/header.html"));

  auto sidebar = new QWebView();
  sidebar->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
  QObject::connect(sidebar->page(), &QWebPage::linkClicked, navigate);
  sidebar->setFixedWidth(150);

  sidebar->load(QUrl("qrc:///contents/sidebar.html"));

  auto header_dock = new QDockWidget();
  header_dock->setWidget(header);
  header_dock->setFeatures(
    QDockWidget::DockWidgetVerticalTitleBar
  );
  header_dock->setTitleBarWidget(new QWidget(&main_window));
  main_window.addDockWidget(Qt::DockWidgetArea::TopDockWidgetArea, header_dock);

  auto sidebar_dock = new QDockWidget();
  sidebar_dock->setWidget(sidebar);
  sidebar_dock->setTitleBarWidget(new QWidget(&main_window));

  main_window.addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, sidebar_dock);

  auto main_dock = new QDockWidget();
  main_dock->setWidget(view);
  main_dock->setTitleBarWidget(new QWidget(&main_window));

  main_window.setCentralWidget(main_dock);
  main_window.resize(800, 600);
  main_window.show();
  view->load(QUrl("qrc:///contents/main.html"));

  return app.exec();
}

#include "main.moc"
<|endoftext|>


<commit_before>/*
 *  This dmxgram is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This dmxgram 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this dmxgram; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * UsbDmxPlugin.cpp
 * The UsbDmx plugin for ola
 * Copyright (C) 2006-2007 Simon Newton
 */

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <libusb.h>

#include <string>
#include <utility>
#include <vector>

#include "ola/Callback.h"
#include "ola/Logging.h"
#include "olad/PluginAdaptor.h"
#include "olad/Preferences.h"
#include "ola/network/Socket.h"

#include "plugins/usbdmx/AnymaDevice.h"
#include "plugins/usbdmx/FirmwareLoader.h"
#include "plugins/usbdmx/SunliteDevice.h"
#include "plugins/usbdmx/SunliteFirmwareLoader.h"
#include "plugins/usbdmx/UsbDevice.h"
#include "plugins/usbdmx/UsbDmxPlugin.h"
#include "plugins/usbdmx/VellemanDevice.h"

namespace ola {
namespace plugin {
namespace usbdmx {

using ola::network::DeviceSocket;

const char UsbDmxPlugin::PLUGIN_NAME[] = "USB";
const char UsbDmxPlugin::PLUGIN_PREFIX[] = "usbdmx";
const char UsbDmxPlugin::LIBUSB_DEBUG_LEVEL_KEY[] = "libusb_debug_level";
int UsbDmxPlugin::LIBUSB_DEFAULT_DEBUG_LEVEL = 0;
int UsbDmxPlugin::LIBUSB_MAX_DEBUG_LEVEL = 3;

/*
 * Called by libusb when a new socket is created.
 */
void libusb_fd_added(int fd, short events, void *data) {
  UsbDmxPlugin *plugin = reinterpret_cast<UsbDmxPlugin*>(data);

  OLA_INFO << "USB new FD: " << fd;
  plugin->AddDeviceSocket(fd);
}

/*
 * Called by libusb when a socket is no longer needed.
 */
void libusb_fd_removed(int fd, void *data) {
  UsbDmxPlugin *plugin = reinterpret_cast<UsbDmxPlugin*>(data);
  OLA_INFO << "USB rm FD: " << fd;
  plugin->RemoveDeviceSocket(fd);
}

/*
 * Start the plugin
 */
bool UsbDmxPlugin::StartHook() {
  if (libusb_init(NULL)) {
    OLA_WARN << "Failed to init libusb";
    return false;
  }

  unsigned int debug_level;
  if (!StringToUInt(m_preferences->GetValue(LIBUSB_DEBUG_LEVEL_KEY) ,
                    &debug_level))
    debug_level = LIBUSB_DEFAULT_DEBUG_LEVEL;

  libusb_set_debug(NULL, debug_level);

  if (LoadFirmware()) {
    // we loaded firmware for at least one device, set up a callback to run in
    // a couple of seconds to re-scan for devices
    m_plugin_adaptor->RegisterSingleTimeout(
        3500,
        NewSingleCallback(this, &UsbDmxPlugin::FindDevices));
  }
  FindDevices();

  /*
  if (!libusb_pollfds_handle_timeouts(m_usb_context)) {
    OLA_FATAL << "libusb doesn't have timeout support, BAD";
    return false;
  }

  libusb_set_pollfd_notifiers(m_usb_context,
                              &libusb_fd_added,
                              &libusb_fd_removed,
                              this);

  const libusb_pollfd **pollfds = libusb_get_pollfds(m_usb_context);
  while (*pollfds) {
    OLA_WARN << "poll fd " << (*pollfds)->fd;
    AddDeviceSocket((*pollfds)->fd);
    pollfds++;
  }
  */

  return true;
}

/*
 * Load firmware onto devices if required.
 * @returns true if we loaded firmware for one or more devices
 */
bool UsbDmxPlugin::LoadFirmware() {
  libusb_device **device_list;
  size_t device_count = libusb_get_device_list(NULL, &device_list);
  FirmwareLoader *loader;
  bool loaded = false;

  for (unsigned int i = 0; i < device_count; i++) {
    libusb_device *usb_device = device_list[i];
    loader = NULL;
    struct libusb_device_descriptor device_descriptor;
    libusb_get_device_descriptor(usb_device, &device_descriptor);

    if (device_descriptor.idVendor == 0x0962 &&
        device_descriptor.idProduct == 0x2000) {
      loader = new SunliteFirmwareLoader(usb_device);
    }

    if (loader) {
      loader->LoadFirmware();
      loaded = true;
      delete loader;
    }
  }
  libusb_free_device_list(device_list, 1);  // unref devices
  return loaded;
}

/*
 * Find known devices & register them
 */
void UsbDmxPlugin::FindDevices() {
  libusb_device **device_list;
  libusb_device *found = NULL;
  size_t device_count = libusb_get_device_list(NULL, &device_list);

  for (unsigned int i = 0; i < device_count; i++) {
    libusb_device *usb_device = device_list[i];
    struct libusb_device_descriptor device_descriptor;
    libusb_get_device_descriptor(usb_device, &device_descriptor);
    UsbDevice *device = NULL;

    pair<uint8_t, uint8_t> bus_dev_id(libusb_get_bus_number(usb_device),
                                      libusb_get_device_address(usb_device));

    if ((m_registered_devices.find(bus_dev_id) != m_registered_devices.end()))
      continue;

    if (device_descriptor.idVendor == 0x10cf &&
        device_descriptor.idProduct == 0x8062) {
      OLA_INFO << "Found a Velleman USB device";
      device = new VellemanDevice(this, usb_device);
    } else if (device_descriptor.idVendor == 0x0962 &&
        device_descriptor.idProduct == 0x2001) {
      OLA_INFO << "found a sunlite device";
      device = new SunliteDevice(this, usb_device);
    } else if (device_descriptor.idVendor == 0x16C0 &&
        device_descriptor.idProduct == 0x05DC) {
      OLA_INFO << "found a anyma device";
      device = new AnymaDevice(this, usb_device);
    }

    if (device) {
      if (!device->Start()) {
        delete device;
        continue;
      }
      m_registered_devices.insert(bus_dev_id);
      m_devices.push_back(device);
      m_plugin_adaptor->RegisterDevice(device);
    }
  }
  libusb_free_device_list(device_list, 1);  // unref devices
}

/*
 * Stop the plugin
 * @return true on success, false on failure
 */
bool UsbDmxPlugin::StopHook() {
  vector<UsbDevice*>::iterator iter;
  for (iter = m_devices.begin(); iter != m_devices.end(); ++iter) {
    m_plugin_adaptor->UnregisterDevice(*iter);
    (*iter)->Stop();
    delete *iter;
  }
  m_devices.clear();
  m_registered_devices.clear();

  libusb_exit(NULL);

  if (m_sockets.size()) {
    OLA_WARN << "libusb is still using sockets, this is a bug";
  }
  return true;
}

/*
 * Return the description for this plugin
 */
string UsbDmxPlugin::Description() const {
    return
"USB DMX Plugin\n"
"----------------------------\n"
"\n"
"This plugin supports various USB DMX devices including the \n"
"Anyma uDMX, Sunlite USBDMX2 & Velleman K8062.\n"
"\n"
"--- Config file : ola-usbdmx.conf ---\n"
"\n"
"libusb_debug_level = {0,1,2,3}\n"
"The debug level for libusb. 0 = No logging, 3 = Verbose.\n";
}

/*
 * Default to sensible values
 */
bool UsbDmxPlugin::SetDefaultPreferences() {
  if (!m_preferences)
    return false;

  bool save = m_preferences->SetDefaultValue(
      LIBUSB_DEBUG_LEVEL_KEY,
      IntValidator(LIBUSB_DEFAULT_DEBUG_LEVEL, LIBUSB_MAX_DEBUG_LEVEL),
      IntToString(LIBUSB_DEFAULT_DEBUG_LEVEL));

  if (save)
    m_preferences->Save();

  return true;
}

bool UsbDmxPlugin::AddDeviceSocket(int fd) {
  vector<DeviceSocket*>::const_iterator iter = m_sockets.begin();
  for (; iter != m_sockets.end(); ++iter) {
    if ((*iter)->ReadDescriptor() == fd)
      return true;
  }
  DeviceSocket *socket = new DeviceSocket(fd);
  socket->SetOnData(NewCallback(this, &UsbDmxPlugin::SocketReady));
  m_plugin_adaptor->AddSocket(socket);
  m_sockets.push_back(socket);
}

bool UsbDmxPlugin::RemoveDeviceSocket(int fd) {
  vector<DeviceSocket*>::iterator iter = m_sockets.begin();
  for (; iter != m_sockets.end(); ++iter) {
    if ((*iter)->ReadDescriptor() == fd) {
      m_plugin_adaptor->RemoveSocket(*iter);
      delete *iter;
      m_sockets.erase(iter);
      return true;
    }
  }
  return false;
}

/*
 * Called when there is activity on one of our sockets.
 */
void UsbDmxPlugin::SocketReady() {
  struct timeval tv;
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  libusb_handle_events_timeout(NULL, &tv);
}
}  // usbdmx
}  // plugin
}  // ola
<commit_msg> * add a link to the libusb api page<commit_after>/*
 *  This dmxgram is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This dmxgram 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this dmxgram; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * UsbDmxPlugin.cpp
 * The UsbDmx plugin for ola
 * Copyright (C) 2006-2007 Simon Newton
 */

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <libusb.h>

#include <string>
#include <utility>
#include <vector>

#include "ola/Callback.h"
#include "ola/Logging.h"
#include "olad/PluginAdaptor.h"
#include "olad/Preferences.h"
#include "ola/network/Socket.h"

#include "plugins/usbdmx/AnymaDevice.h"
#include "plugins/usbdmx/FirmwareLoader.h"
#include "plugins/usbdmx/SunliteDevice.h"
#include "plugins/usbdmx/SunliteFirmwareLoader.h"
#include "plugins/usbdmx/UsbDevice.h"
#include "plugins/usbdmx/UsbDmxPlugin.h"
#include "plugins/usbdmx/VellemanDevice.h"

namespace ola {
namespace plugin {
namespace usbdmx {

using ola::network::DeviceSocket;

const char UsbDmxPlugin::PLUGIN_NAME[] = "USB";
const char UsbDmxPlugin::PLUGIN_PREFIX[] = "usbdmx";
const char UsbDmxPlugin::LIBUSB_DEBUG_LEVEL_KEY[] = "libusb_debug_level";
int UsbDmxPlugin::LIBUSB_DEFAULT_DEBUG_LEVEL = 0;
int UsbDmxPlugin::LIBUSB_MAX_DEBUG_LEVEL = 3;

/*
 * Called by libusb when a new socket is created.
 */
void libusb_fd_added(int fd, short events, void *data) {
  UsbDmxPlugin *plugin = reinterpret_cast<UsbDmxPlugin*>(data);

  OLA_INFO << "USB new FD: " << fd;
  plugin->AddDeviceSocket(fd);
}

/*
 * Called by libusb when a socket is no longer needed.
 */
void libusb_fd_removed(int fd, void *data) {
  UsbDmxPlugin *plugin = reinterpret_cast<UsbDmxPlugin*>(data);
  OLA_INFO << "USB rm FD: " << fd;
  plugin->RemoveDeviceSocket(fd);
}

/*
 * Start the plugin
 */
bool UsbDmxPlugin::StartHook() {
  if (libusb_init(NULL)) {
    OLA_WARN << "Failed to init libusb";
    return false;
  }

  unsigned int debug_level;
  if (!StringToUInt(m_preferences->GetValue(LIBUSB_DEBUG_LEVEL_KEY) ,
                    &debug_level))
    debug_level = LIBUSB_DEFAULT_DEBUG_LEVEL;

  libusb_set_debug(NULL, debug_level);

  if (LoadFirmware()) {
    // we loaded firmware for at least one device, set up a callback to run in
    // a couple of seconds to re-scan for devices
    m_plugin_adaptor->RegisterSingleTimeout(
        3500,
        NewSingleCallback(this, &UsbDmxPlugin::FindDevices));
  }
  FindDevices();

  /*
  if (!libusb_pollfds_handle_timeouts(m_usb_context)) {
    OLA_FATAL << "libusb doesn't have timeout support, BAD";
    return false;
  }

  libusb_set_pollfd_notifiers(m_usb_context,
                              &libusb_fd_added,
                              &libusb_fd_removed,
                              this);

  const libusb_pollfd **pollfds = libusb_get_pollfds(m_usb_context);
  while (*pollfds) {
    OLA_WARN << "poll fd " << (*pollfds)->fd;
    AddDeviceSocket((*pollfds)->fd);
    pollfds++;
  }
  */

  return true;
}

/*
 * Load firmware onto devices if required.
 * @returns true if we loaded firmware for one or more devices
 */
bool UsbDmxPlugin::LoadFirmware() {
  libusb_device **device_list;
  size_t device_count = libusb_get_device_list(NULL, &device_list);
  FirmwareLoader *loader;
  bool loaded = false;

  for (unsigned int i = 0; i < device_count; i++) {
    libusb_device *usb_device = device_list[i];
    loader = NULL;
    struct libusb_device_descriptor device_descriptor;
    libusb_get_device_descriptor(usb_device, &device_descriptor);

    if (device_descriptor.idVendor == 0x0962 &&
        device_descriptor.idProduct == 0x2000) {
      loader = new SunliteFirmwareLoader(usb_device);
    }

    if (loader) {
      loader->LoadFirmware();
      loaded = true;
      delete loader;
    }
  }
  libusb_free_device_list(device_list, 1);  // unref devices
  return loaded;
}

/*
 * Find known devices & register them
 */
void UsbDmxPlugin::FindDevices() {
  libusb_device **device_list;
  libusb_device *found = NULL;
  size_t device_count = libusb_get_device_list(NULL, &device_list);

  for (unsigned int i = 0; i < device_count; i++) {
    libusb_device *usb_device = device_list[i];
    struct libusb_device_descriptor device_descriptor;
    libusb_get_device_descriptor(usb_device, &device_descriptor);
    UsbDevice *device = NULL;

    pair<uint8_t, uint8_t> bus_dev_id(libusb_get_bus_number(usb_device),
                                      libusb_get_device_address(usb_device));

    if ((m_registered_devices.find(bus_dev_id) != m_registered_devices.end()))
      continue;

    if (device_descriptor.idVendor == 0x10cf &&
        device_descriptor.idProduct == 0x8062) {
      OLA_INFO << "Found a Velleman USB device";
      device = new VellemanDevice(this, usb_device);
    } else if (device_descriptor.idVendor == 0x0962 &&
        device_descriptor.idProduct == 0x2001) {
      OLA_INFO << "found a sunlite device";
      device = new SunliteDevice(this, usb_device);
    } else if (device_descriptor.idVendor == 0x16C0 &&
        device_descriptor.idProduct == 0x05DC) {
      OLA_INFO << "found a anyma device";
      device = new AnymaDevice(this, usb_device);
    }

    if (device) {
      if (!device->Start()) {
        delete device;
        continue;
      }
      m_registered_devices.insert(bus_dev_id);
      m_devices.push_back(device);
      m_plugin_adaptor->RegisterDevice(device);
    }
  }
  libusb_free_device_list(device_list, 1);  // unref devices
}

/*
 * Stop the plugin
 * @return true on success, false on failure
 */
bool UsbDmxPlugin::StopHook() {
  vector<UsbDevice*>::iterator iter;
  for (iter = m_devices.begin(); iter != m_devices.end(); ++iter) {
    m_plugin_adaptor->UnregisterDevice(*iter);
    (*iter)->Stop();
    delete *iter;
  }
  m_devices.clear();
  m_registered_devices.clear();

  libusb_exit(NULL);

  if (m_sockets.size()) {
    OLA_WARN << "libusb is still using sockets, this is a bug";
  }
  return true;
}

/*
 * Return the description for this plugin
 */
string UsbDmxPlugin::Description() const {
    return
"USB DMX Plugin\n"
"----------------------------\n"
"\n"
"This plugin supports various USB DMX devices including the \n"
"Anyma uDMX, Sunlite USBDMX2 & Velleman K8062.\n"
"\n"
"--- Config file : ola-usbdmx.conf ---\n"
"\n"
"libusb_debug_level = {0,1,2,3}\n"
"The debug level for libusb, see http://libusb.sourceforge.net/api-1.0/ .\n"
"0 = No logging, 3 = Verbose.\n";
}

/*
 * Default to sensible values
 */
bool UsbDmxPlugin::SetDefaultPreferences() {
  if (!m_preferences)
    return false;

  bool save = m_preferences->SetDefaultValue(
      LIBUSB_DEBUG_LEVEL_KEY,
      IntValidator(LIBUSB_DEFAULT_DEBUG_LEVEL, LIBUSB_MAX_DEBUG_LEVEL),
      IntToString(LIBUSB_DEFAULT_DEBUG_LEVEL));

  if (save)
    m_preferences->Save();

  return true;
}

bool UsbDmxPlugin::AddDeviceSocket(int fd) {
  vector<DeviceSocket*>::const_iterator iter = m_sockets.begin();
  for (; iter != m_sockets.end(); ++iter) {
    if ((*iter)->ReadDescriptor() == fd)
      return true;
  }
  DeviceSocket *socket = new DeviceSocket(fd);
  socket->SetOnData(NewCallback(this, &UsbDmxPlugin::SocketReady));
  m_plugin_adaptor->AddSocket(socket);
  m_sockets.push_back(socket);
}

bool UsbDmxPlugin::RemoveDeviceSocket(int fd) {
  vector<DeviceSocket*>::iterator iter = m_sockets.begin();
  for (; iter != m_sockets.end(); ++iter) {
    if ((*iter)->ReadDescriptor() == fd) {
      m_plugin_adaptor->RemoveSocket(*iter);
      delete *iter;
      m_sockets.erase(iter);
      return true;
    }
  }
  return false;
}

/*
 * Called when there is activity on one of our sockets.
 */
void UsbDmxPlugin::SocketReady() {
  struct timeval tv;
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  libusb_handle_events_timeout(NULL, &tv);
}
}  // usbdmx
}  // plugin
}  // ola
<|endoftext|>


<commit_before>/*
    Copyright (C) 2014-2016 Leosac

    This file is part of Leosac.

    Leosac is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Leosac 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "AsioModule.hpp"
#include "core/GetServiceRegistry.hpp"

namespace Leosac
{
namespace Module
{

AsioModule::AsioModule(zmqpp::context &ctx, zmqpp::socket *pipe,
                       const boost::property_tree::ptree &cfg, CoreUtilsPtr utils)
    : BaseModule(ctx, pipe, cfg, utils)
{
}

AsioModule::~AsioModule()
{
}

void AsioModule::run()
{
    service_event_listener_ = get_service_registry().register_event_listener(
        [this](const service_event::Event &e) { on_service_event(e); });

    work_ = std::make_unique<boost::asio::io_service::work>(io_service_);
    install_async_handlers();
    io_service_.run();

    service_event_listener_.disconnect();
}

void AsioModule::install_async_handlers()
{
    auto stop_watcher(std::make_shared<StopWatcher>(*this));
    stop_watcher->schedule_wait();

    auto reactor_poller(std::make_shared<AsyncReactorPoller>(*this));
    reactor_poller->schedule_wait();
}

void AsioModule::StopWatcher::wait(const boost::system::error_code &ec)
{
    if (ec)
    {
        WARN("AsioModule StopWatcher timer has errored: " << ec.message());
        ASSERT_LOG(0, "Failed.");
    }
    if (!self_.is_running_)
        self_.work_.reset();
    else
        schedule_wait();
}

void AsioModule::StopWatcher::schedule_wait()
{
    timer_.expires_from_now(std::chrono::milliseconds(1000));
    timer_.async_wait(std::bind(&AsioModule::StopWatcher::wait, shared_from_this(),
                                std::placeholders::_1));
}

void AsioModule::AsyncReactorPoller::schedule_wait()
{
    timer_.expires_from_now(std::chrono::milliseconds(25));
    timer_.async_wait(std::bind(&AsioModule::AsyncReactorPoller::wait_handler,
                                shared_from_this(), std::placeholders::_1));
}

void AsioModule::AsyncReactorPoller::wait_handler(
    const boost::system::error_code &ec)
{
    ASSERT_LOG(ec == 0, "Error while processing wait_handler: " << ec.message());
    self_.reactor_.poll(0);
    if (self_.is_running_)
        schedule_wait();
}
}
}
<commit_msg>Explicitly check for boost::system::errc::success<commit_after>/*
    Copyright (C) 2014-2016 Leosac

    This file is part of Leosac.

    Leosac is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Leosac 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "AsioModule.hpp"
#include "core/GetServiceRegistry.hpp"

namespace Leosac
{
namespace Module
{

AsioModule::AsioModule(zmqpp::context &ctx, zmqpp::socket *pipe,
                       const boost::property_tree::ptree &cfg, CoreUtilsPtr utils)
    : BaseModule(ctx, pipe, cfg, utils)
{
}

AsioModule::~AsioModule()
{
}

void AsioModule::run()
{
    service_event_listener_ = get_service_registry().register_event_listener(
        [this](const service_event::Event &e) { on_service_event(e); });

    work_ = std::make_unique<boost::asio::io_service::work>(io_service_);
    install_async_handlers();
    io_service_.run();

    service_event_listener_.disconnect();
}

void AsioModule::install_async_handlers()
{
    auto stop_watcher(std::make_shared<StopWatcher>(*this));
    stop_watcher->schedule_wait();

    auto reactor_poller(std::make_shared<AsyncReactorPoller>(*this));
    reactor_poller->schedule_wait();
}

void AsioModule::StopWatcher::wait(const boost::system::error_code &ec)
{
    if (ec)
    {
        WARN("AsioModule StopWatcher timer has errored: " << ec.message());
        ASSERT_LOG(0, "Failed.");
    }
    if (!self_.is_running_)
        self_.work_.reset();
    else
        schedule_wait();
}

void AsioModule::StopWatcher::schedule_wait()
{
    timer_.expires_from_now(std::chrono::milliseconds(1000));
    timer_.async_wait(std::bind(&AsioModule::StopWatcher::wait, shared_from_this(),
                                std::placeholders::_1));
}

void AsioModule::AsyncReactorPoller::schedule_wait()
{
    timer_.expires_from_now(std::chrono::milliseconds(25));
    timer_.async_wait(std::bind(&AsioModule::AsyncReactorPoller::wait_handler,
                                shared_from_this(), std::placeholders::_1));
}

void AsioModule::AsyncReactorPoller::wait_handler(
    const boost::system::error_code &ec)
{
    ASSERT_LOG(ec == boost::system::errc::success, "Error while processing wait_handler: " << ec.message());
    self_.reactor_.poll(0);
    if (self_.is_running_)
        schedule_wait();
}
}
}
<|endoftext|>