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

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.txx"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBSplineCenteredL2ResampleImageFilterBase.txx"
#include "itkBSplineCenteredResampleImageFilterBase.txx"
#include "itkBSplineDecompositionImageFilter.txx"
#include "itkBSplineDownsampleImageFilter.txx"
#include "itkBSplineInterpolateImageFunction.txx"
#include "itkBSplineL2ResampleImageFilterBase.txx"
#include "itkBSplineResampleImageFilterBase.txx"
#include "itkBSplineResampleImageFunction.h"
#include "itkBSplineUpsampleImageFilter.txx"
#include "itkBilateralImageFilter.txx"
#include "itkBinaryDilateImageFilter.txx"
#include "itkBinaryErodeImageFilter.txx"
#include "itkBinaryFunctorImageFilter.txx"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinaryMedianImageFilter.txx"
#include "itkBinaryThresholdImageFilter.txx"
#include "itkBinomialBlurImageFilter.txx"
#include "itkBloxBoundaryPointImageToBloxBoundaryProfileImageFilter.txx"
#include "itkBloxBoundaryPointToCoreAtomImageFilter.txx"
#include "itkCannyEdgeDetectionImageFilter.txx"
#include "itkCastImageFilter.h"
#include "itkChangeInformationImageFilter.txx"
#include "itkComposeRGBImageFilter.h"
#include "itkConfidenceConnectedImageFilter.txx"
#include "itkConnectedThresholdImageFilter.txx"
#include "itkConstantPadImageFilter.txx"
#include "itkCosImageFilter.h"
#include "itkCropImageFilter.txx"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkDanielssonDistanceMapImageFilter.txx"
#include "itkDerivativeImageFilter.txx"
#include "itkDifferenceOfGaussiansGradientImageFilter.txx"
#include "itkDilateObjectMorphologyImageFilter.txx"
#include "itkDirectedHausdorffDistanceImageFilter.txx"
#include "itkDiscreteGaussianImageFilter.txx"
#include "itkDivideImageFilter.h"
#include "itkEdgePotentialImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.txx"
#include "itkErodeObjectMorphologyImageFilter.txx"
#include "itkExpImageFilter.h"
#include "itkExpNegativeImageFilter.h"
#include "itkExpandImageFilter.txx"
#include "itkExtractImageFilter.txx"
#include "itkExtractImageFilterRegionCopier.h"
#include "itkFlipImageFilter.txx"
#include "itkGaussianImageSource.txx"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.txx"
#include "itkGradientImageToBloxBoundaryPointImageFilter.txx"
#include "itkGradientMagnitudeImageFilter.txx"
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.txx"
#include "itkGradientNDAnisotropicDiffusionFunction.txx"
#include "itkGradientRecursiveGaussianImageFilter.txx"
#include "itkGradientToMagnitudeImageFilter.h"
#include "itkGrayscaleDilateImageFilter.txx"
#include "itkGrayscaleErodeImageFilter.txx"
#include "itkGrayscaleFillholeImageFilter.txx"
#include "itkGrayscaleFunctionDilateImageFilter.txx"
#include "itkGrayscaleFunctionErodeImageFilter.txx"
#include "itkGrayscaleGeodesicDilateImageFilter.txx"
#include "itkGrayscaleGeodesicErodeImageFilter.txx"
#include "itkHardConnectedComponentImageFilter.txx"
#include "itkHausdorffDistanceImageFilter.txx"
#include "itkHoughTransform2DLinesImageFilter.txx"
#include "itkImageToMeshFilter.txx"
#include "itkImageToParametricSpaceFilter.txx"
#include "itkImportImageFilter.txx"
#include "itkIntensityWindowingImageFilter.txx"
#include "itkInteriorExteriorMeshFilter.txx"
#include "itkInterpolateImageFilter.txx"
#include "itkInterpolateImagePointsFilter.txx"
#include "itkIsolatedConnectedImageFilter.txx"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.txx"
#include "itkLaplacianRecursiveGaussianImageFilter.txx"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMaskImageFilter.h"
#include "itkMaximumImageFilter.h"
#include "itkMeanImageFilter.txx"
#include "itkMedianImageFilter.txx"
#include "itkMinimumImageFilter.h"
#include "itkMinimumMaximumImageCalculator.txx"
#include "itkMinimumMaximumImageFilter.txx"
#include "itkMirrorPadImageFilter.txx"
#include "itkMorphologyImageFilter.txx"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.txx"
#include "itkNeighborhoodConnectedImageFilter.txx"
#include "itkNeighborhoodOperatorImageFilter.txx"
#include "itkNoiseImageFilter.txx"
#include "itkNonThreadedShrinkImageFilter.txx"
#include "itkNormalizeImageFilter.txx"
#include "itkObjectMorphologyImageFilter.txx"
#include "itkPadImageFilter.txx"
#include "itkParametricSpaceToImageSpaceMeshFilter.txx"
#include "itkPasteImageFilter.txx"
#include "itkPermuteAxesImageFilter.txx"
#include "itkPlaheImageFilter.txx"
#include "itkRandomImageSource.txx"
#include "itkRecursiveGaussianImageFilter.txx"
#include "itkRecursiveSeparableImageFilter.txx"
#include "itkReflectImageFilter.txx"
#include "itkReflectiveImageRegionConstIterator.txx"
#include "itkReflectiveImageRegionIterator.txx"
#include "itkRegionOfInterestImageFilter.txx"
#include "itkResampleImageFilter.txx"
#include "itkRescaleIntensityImageFilter.txx"
#include "itkScalarAnisotropicDiffusionFunction.txx"
#include "itkScalarToArrayCastImageFilter.txx"
#include "itkShiftScaleImageFilter.txx"
#include "itkShiftScaleInPlaceImageFilter.txx"
#include "itkShrinkImageFilter.txx"
#include "itkSigmoidImageFilter.h"
#include "itkSimilarityIndexImageFilter.txx"
#include "itkSinImageFilter.h"
#include "itkSmoothingRecursiveGaussianImageFilter.txx"
#include "itkSobelEdgeDetectionImageFilter.txx"
#include "itkSparseFieldLayer.txx"
#include "itkSparseFieldLevelSetImageFilter.txx"
#include "itkSpatialFunctionImageEvaluatorFilter.txx"
#include "itkSpatialObjectToImageFilter.txx"
#include "itkSqrtImageFilter.h"
#include "itkSquareImageFilter.h"
#include "itkSquaredDifferenceImageFilter.h"
#include "itkStatisticsImageFilter.txx"
#include "itkStreamingImageFilter.txx"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.txx"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.txx"
#include "itkTobogganImageFilter.txx"
#include "itkTransformMeshFilter.txx"
#include "itkTwoOutputExampleImageFilter.txx"
#include "itkUnaryFunctorImageFilter.txx"
#include "itkVTKImageExport.txx"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.txx"
#include "itkVectorAnisotropicDiffusionFunction.txx"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkVectorExpandImageFilter.txx"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientMagnitudeImageFilter.txx"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.txx"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "itkVectorNeighborhoodOperatorImageFilter.txx"
#include "itkWarpImageFilter.txx"
#include "itkWrapPadImageFilter.txx"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.txx"
#include "itkZeroCrossingImageFilter.txx"

int main ( int , char*  )
{

  return 0;
}

<commit_msg>ENH: Updated to latest headers<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.txx"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBSplineCenteredL2ResampleImageFilterBase.txx"
#include "itkBSplineCenteredResampleImageFilterBase.txx"
#include "itkBSplineDecompositionImageFilter.txx"
#include "itkBSplineDownsampleImageFilter.txx"
#include "itkBSplineInterpolateImageFunction.txx"
#include "itkBSplineL2ResampleImageFilterBase.txx"
#include "itkBSplineResampleImageFilterBase.txx"
#include "itkBSplineResampleImageFunction.h"
#include "itkBSplineUpsampleImageFilter.txx"
#include "itkBilateralImageFilter.txx"
#include "itkBinaryDilateImageFilter.txx"
#include "itkBinaryErodeImageFilter.txx"
#include "itkBinaryFunctorImageFilter.txx"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinaryMedianImageFilter.txx"
#include "itkBinaryThresholdImageFilter.txx"
#include "itkBinomialBlurImageFilter.txx"
#include "itkBloxBoundaryPointImageToBloxBoundaryProfileImageFilter.txx"
#include "itkBloxBoundaryPointToCoreAtomImageFilter.txx"
#include "itkCannyEdgeDetectionImageFilter.txx"
#include "itkCastImageFilter.h"
#include "itkChangeInformationImageFilter.txx"
#include "itkComposeRGBImageFilter.h"
#include "itkConfidenceConnectedImageFilter.txx"
#include "itkConnectedThresholdImageFilter.txx"
#include "itkConstantPadImageFilter.txx"
#include "itkCosImageFilter.h"
#include "itkCropImageFilter.txx"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkDanielssonDistanceMapImageFilter.txx"
#include "itkDerivativeImageFilter.txx"
#include "itkDifferenceOfGaussiansGradientImageFilter.txx"
#include "itkDilateObjectMorphologyImageFilter.txx"
#include "itkDirectedHausdorffDistanceImageFilter.txx"
#include "itkDiscreteGaussianImageFilter.txx"
#include "itkDivideImageFilter.h"
#include "itkDoubleThresholdImageFilter.txx"
#include "itkEdgePotentialImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.txx"
#include "itkErodeObjectMorphologyImageFilter.txx"
#include "itkExpImageFilter.h"
#include "itkExpNegativeImageFilter.h"
#include "itkExpandImageFilter.txx"
#include "itkExtractImageFilter.txx"
#include "itkExtractImageFilterRegionCopier.h"
#include "itkFlipImageFilter.txx"
#include "itkGaussianImageSource.txx"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.txx"
#include "itkGradientImageToBloxBoundaryPointImageFilter.txx"
#include "itkGradientMagnitudeImageFilter.txx"
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.txx"
#include "itkGradientNDAnisotropicDiffusionFunction.txx"
#include "itkGradientRecursiveGaussianImageFilter.txx"
#include "itkGradientToMagnitudeImageFilter.h"
#include "itkGrayscaleDilateImageFilter.txx"
#include "itkGrayscaleErodeImageFilter.txx"
#include "itkGrayscaleFillholeImageFilter.txx"
#include "itkGrayscaleFunctionDilateImageFilter.txx"
#include "itkGrayscaleFunctionErodeImageFilter.txx"
#include "itkGrayscaleGeodesicDilateImageFilter.txx"
#include "itkGrayscaleGeodesicErodeImageFilter.txx"
#include "itkHardConnectedComponentImageFilter.txx"
#include "itkHausdorffDistanceImageFilter.txx"
#include "itkHoughTransform2DLinesImageFilter.txx"
#include "itkImageToMeshFilter.txx"
#include "itkImageToParametricSpaceFilter.txx"
#include "itkImportImageFilter.txx"
#include "itkIntensityWindowingImageFilter.txx"
#include "itkInteriorExteriorMeshFilter.txx"
#include "itkInterpolateImageFilter.txx"
#include "itkInterpolateImagePointsFilter.txx"
#include "itkIsolatedConnectedImageFilter.txx"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.txx"
#include "itkLaplacianRecursiveGaussianImageFilter.txx"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMaskImageFilter.h"
#include "itkMaximumImageFilter.h"
#include "itkMeanImageFilter.txx"
#include "itkMedianImageFilter.txx"
#include "itkMinimumImageFilter.h"
#include "itkMinimumMaximumImageCalculator.txx"
#include "itkMinimumMaximumImageFilter.txx"
#include "itkMirrorPadImageFilter.txx"
#include "itkMorphologyImageFilter.txx"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.txx"
#include "itkNeighborhoodConnectedImageFilter.txx"
#include "itkNeighborhoodOperatorImageFilter.txx"
#include "itkNoiseImageFilter.txx"
#include "itkNonThreadedShrinkImageFilter.txx"
#include "itkNormalizeImageFilter.txx"
#include "itkObjectMorphologyImageFilter.txx"
#include "itkPadImageFilter.txx"
#include "itkParametricSpaceToImageSpaceMeshFilter.txx"
#include "itkPasteImageFilter.txx"
#include "itkPermuteAxesImageFilter.txx"
#include "itkPlaheImageFilter.txx"
#include "itkRandomImageSource.txx"
#include "itkRecursiveGaussianImageFilter.txx"
#include "itkRecursiveSeparableImageFilter.txx"
#include "itkReflectImageFilter.txx"
#include "itkReflectiveImageRegionConstIterator.txx"
#include "itkReflectiveImageRegionIterator.txx"
#include "itkRegionOfInterestImageFilter.txx"
#include "itkResampleImageFilter.txx"
#include "itkRescaleIntensityImageFilter.txx"
#include "itkScalarAnisotropicDiffusionFunction.txx"
#include "itkScalarToArrayCastImageFilter.txx"
#include "itkShiftScaleImageFilter.txx"
#include "itkShiftScaleInPlaceImageFilter.txx"
#include "itkShrinkImageFilter.txx"
#include "itkSigmoidImageFilter.h"
#include "itkSimilarityIndexImageFilter.txx"
#include "itkSinImageFilter.h"
#include "itkSmoothingRecursiveGaussianImageFilter.txx"
#include "itkSobelEdgeDetectionImageFilter.txx"
#include "itkSparseFieldLayer.txx"
#include "itkSparseFieldLevelSetImageFilter.txx"
#include "itkSpatialFunctionImageEvaluatorFilter.txx"
#include "itkSpatialObjectToImageFilter.txx"
#include "itkSqrtImageFilter.h"
#include "itkSquareImageFilter.h"
#include "itkSquaredDifferenceImageFilter.h"
#include "itkStatisticsImageFilter.txx"
#include "itkStreamingImageFilter.txx"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.txx"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.txx"
#include "itkTobogganImageFilter.txx"
#include "itkTransformMeshFilter.txx"
#include "itkTwoOutputExampleImageFilter.txx"
#include "itkUnaryFunctorImageFilter.txx"
#include "itkVTKImageExport.txx"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.txx"
#include "itkVectorAnisotropicDiffusionFunction.txx"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkVectorExpandImageFilter.txx"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientMagnitudeImageFilter.txx"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.txx"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "itkVectorNeighborhoodOperatorImageFilter.txx"
#include "itkWarpImageFilter.txx"
#include "itkWrapPadImageFilter.txx"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.txx"
#include "itkZeroCrossingImageFilter.txx"

int main ( int , char*  )
{

  return 0;
}

<|endoftext|>


<commit_before>/*
DisplayController.h - Library for Controlling a 14x28 bits FlipDot display sign using two FP2800A.
Created by Antonio Carioca, March 3, 2014.
*/

//#include "Arduino.h"

//#include <avr/pgmspace.h>
//#include "application.h"
#include "mark-iv-flip-dot-display-sign-14x28-controller.h"

/* CONSTANTS */
//const int DISPLAY_SIZE = 4;
const int DISPLAY_PIXEL_WIDTH = 28;
const int DISPLAY_PIXEL_HEIGHT = 14;
const int DISPLAY_SUBPANEL_QTY = 2;

//=== F O N T ===
// Font courtesy of aspro648
// coden taken from
// http://www.instructables.com/files/orig/FQC/A1CY/H5EW79JK/FQCA1CYH5EW79JK.txt
// The @ will display as space character.
// NOTE: MOVING ALL THE ARRAY BELOW TO PROGMEM

//DotDisplay::DotDisplay(int dataPin, int clockPin, int latchPin, int enableSubPanel1Pin, int enableSubPanel2Pin, int fontWidth, int fontHeight, prog_uchar fonteParam[][5]){
DotDisplay::DotDisplay(int dataPin, int clockPin, int latchPin,  int enableSubPanel1Pin, int enableSubPanel2Pin, int fontWidth, int fontHeight, byte fonteParam[][5]){

	pinMode(dataPin, OUTPUT);
	pinMode(clockPin, OUTPUT);
	pinMode(latchPin, OUTPUT);
	pinMode(enableSubPanel1Pin, OUTPUT);
	pinMode(enableSubPanel2Pin, OUTPUT);
	//disable FP2800A's
	digitalWrite(enableSubPanel1Pin, LOW);
	digitalWrite(enableSubPanel2Pin, LOW);

	_dataPin = dataPin;
	_clockPin = clockPin;
	_latchPin = latchPin;
	_enableSubPanel1Pin = enableSubPanel1Pin;
	_enableSubPanel2Pin = enableSubPanel2Pin;
	_fontWidth = fontWidth;
	_fontHeight = fontHeight;
	_fonteParam = fonteParam;

	//_maxNumRows = floor((DISPLAY_PIXEL_HEIGHT+1)/(_fontHeight));
	_maxNumRows = (int)((DISPLAY_PIXEL_HEIGHT+1)/(_fontHeight));
	//_maxRowLength = floor((DISPLAY_PIXEL_WIDTH * DISPLAY_SUBPANEL_QTY+1) / (_fontWidth+1));
	_maxRowLength = (int)((DISPLAY_PIXEL_WIDTH * DISPLAY_SUBPANEL_QTY+1) / (_fontWidth+1));
	_maxMessageLength = _maxRowLength * _maxNumRows;

}
/*
void DotDisplay::setSerial(HardwareSerial* hwPrint){
	printer = hwPrint; //operate on the address of print
	if(printer) {
		printer->begin(9600);
	}
}
*/

void DotDisplay::setDot(byte col, byte row, bool on){

	//accidentally reversed two data pins, so reversing back on the code here
	//on = !on;

	//2 pins - Data
	//5 pins - Column
	//4 pins - Rows

	//4 pins - Enable FP2800A (4 subpanels)
	byte subPanel = 1;
	//disable FP2800A's
	digitalWrite(_enableSubPanel1Pin, LOW);
	digitalWrite(_enableSubPanel2Pin, LOW);

	//enables next sunpanel
	if(col>=DISPLAY_PIXEL_WIDTH){
		//subPanel =  floor(col / DISPLAY_PIXEL_WIDTH)+1;
		subPanel =  (int)(col / DISPLAY_PIXEL_WIDTH)+1;
		col=col-DISPLAY_PIXEL_WIDTH;
	}

	/*
	if(printer) {
	printer->print("col: ");
	printer->print(col);
	printer->print(", ");
	printer->print("subPanel: ");
	printer->println(subPanel);
	}
	*/

	// IGNOREx4 + ROWx4 + IGNOREx1 + COLUMNx5 + DATAx2
	byte dataPins = on?1:2;
	byte colFirstThreeDigits = (col % 7)+1;
	//byte colLastTwoDigits = floor(col/7);
	byte colLastTwoDigits = (int)(col/7);
	byte colByte = colFirstThreeDigits | (colLastTwoDigits << 3);
	byte rowFirstThreeDigits = (row % 7)+1;
	byte rowLastDigit = row<7;
	byte rowByte = rowFirstThreeDigits | (rowLastDigit << 3);
	byte firstbyte = (dataPins) | (colByte << 2);
	byte secondbyte = rowByte;

	digitalWrite(_latchPin, LOW);
	shiftOut(_dataPin, _clockPin, LSBFIRST, firstbyte);
	shiftOut(_dataPin, _clockPin, LSBFIRST, secondbyte);
	digitalWrite(_latchPin, HIGH);
	//delay(1);

	//pulse the FP2800A's enable pins
	if(subPanel == 1){
		digitalWrite(_enableSubPanel1Pin, HIGH);
		delay(1);
		digitalWrite(_enableSubPanel1Pin, LOW);
	} else if (subPanel == 2) {
		digitalWrite(_enableSubPanel2Pin, HIGH);
		delay(1);
		digitalWrite(_enableSubPanel2Pin, LOW);
	}
}

//void DotDisplay::updateDisplay(char *textMessage){
void DotDisplay::updateDisplay(char textMessage[], char log[]){
	int currentColumn = 0;
	int currentRow = 0;

	strcat(log,"");

	//goes through all characters
	for (int ch = 0; ch < (_maxMessageLength);ch++){
		//get a character from the message
		int alphabetIndex = textMessage[ch] - ' '; //Subtract '@' so we get a number

		//Serial.println(alphabetIndex);
		strcat(log,"Index: ");
		//strcat(log,alphabetIndex);
		strcat(log,", Letter:");
		strcat(log,textMessage[ch]);
		strcat(log," => ");

		if ((alphabetIndex < 0) or (ch >=strlen(textMessage))) alphabetIndex=0;

		//push it to the next row if necessary
		if((currentColumn + _fontWidth) > (DISPLAY_PIXEL_WIDTH * DISPLAY_SUBPANEL_QTY)){
			currentColumn=0;
			currentRow=currentRow+_fontHeight;
		}

		//set all the bits in the next _fontWidth columns on the display
		for(byte col = currentColumn; col<(currentColumn+_fontWidth); col++){

			byte calculatedColumn = (col)%(_fontWidth+1);
			//for(byte row = 0; row < _fontHeight; row++)
			int characterRow = 0;
			for(byte row = currentRow; row < (currentRow + _fontHeight); row++){
				//bool isOn = bitRead(pgm_read_byte(&(_fonteParam[alphabetIndex][calculatedColumn])),6-characterRow);
				bool isOn = bitRead((byte)_fonteParam[alphabetIndex][calculatedColumn],6-row);//this index is needed as we are going from back to front

				setDot(col, row, isOn);
				/*
				if(printer) {
					printer->print(isOn);
				}
				*/
				char dot[2];
				if (isOn) {
					strcpy(dot,"1");
				}else {
					strcpy(dot,"0");
				}
				strcat(log,dot);

				characterRow++;
			}
			/*
			if(printer) {
				printer->println("");
			}
			*/
			strcat(log," ");
		}
		/*
		if(printer) {
			printer->println("*******");
		}
		*/
		strcat(log,"*********");

		currentColumn = currentColumn+(_fontWidth+1);
	}
}
<commit_msg>Alternative to string concatenation<commit_after>/*
DisplayController.h - Library for Controlling a 14x28 bits FlipDot display sign using two FP2800A.
Created by Antonio Carioca, March 3, 2014.
*/

//#include "Arduino.h"

//#include <avr/pgmspace.h>
//#include "application.h"
#include "mark-iv-flip-dot-display-sign-14x28-controller.h"

/* CONSTANTS */
//const int DISPLAY_SIZE = 4;
const int DISPLAY_PIXEL_WIDTH = 28;
const int DISPLAY_PIXEL_HEIGHT = 14;
const int DISPLAY_SUBPANEL_QTY = 2;

//=== F O N T ===
// Font courtesy of aspro648
// coden taken from
// http://www.instructables.com/files/orig/FQC/A1CY/H5EW79JK/FQCA1CYH5EW79JK.txt
// The @ will display as space character.
// NOTE: MOVING ALL THE ARRAY BELOW TO PROGMEM

//DotDisplay::DotDisplay(int dataPin, int clockPin, int latchPin, int enableSubPanel1Pin, int enableSubPanel2Pin, int fontWidth, int fontHeight, prog_uchar fonteParam[][5]){
DotDisplay::DotDisplay(int dataPin, int clockPin, int latchPin,  int enableSubPanel1Pin, int enableSubPanel2Pin, int fontWidth, int fontHeight, byte fonteParam[][5]){

	pinMode(dataPin, OUTPUT);
	pinMode(clockPin, OUTPUT);
	pinMode(latchPin, OUTPUT);
	pinMode(enableSubPanel1Pin, OUTPUT);
	pinMode(enableSubPanel2Pin, OUTPUT);
	//disable FP2800A's
	digitalWrite(enableSubPanel1Pin, LOW);
	digitalWrite(enableSubPanel2Pin, LOW);

	_dataPin = dataPin;
	_clockPin = clockPin;
	_latchPin = latchPin;
	_enableSubPanel1Pin = enableSubPanel1Pin;
	_enableSubPanel2Pin = enableSubPanel2Pin;
	_fontWidth = fontWidth;
	_fontHeight = fontHeight;
	_fonteParam = fonteParam;

	//_maxNumRows = floor((DISPLAY_PIXEL_HEIGHT+1)/(_fontHeight));
	_maxNumRows = (int)((DISPLAY_PIXEL_HEIGHT+1)/(_fontHeight));
	//_maxRowLength = floor((DISPLAY_PIXEL_WIDTH * DISPLAY_SUBPANEL_QTY+1) / (_fontWidth+1));
	_maxRowLength = (int)((DISPLAY_PIXEL_WIDTH * DISPLAY_SUBPANEL_QTY+1) / (_fontWidth+1));
	_maxMessageLength = _maxRowLength * _maxNumRows;

}
/*
void DotDisplay::setSerial(HardwareSerial* hwPrint){
	printer = hwPrint; //operate on the address of print
	if(printer) {
		printer->begin(9600);
	}
}
*/

void DotDisplay::setDot(byte col, byte row, bool on){

	//accidentally reversed two data pins, so reversing back on the code here
	//on = !on;

	//2 pins - Data
	//5 pins - Column
	//4 pins - Rows

	//4 pins - Enable FP2800A (4 subpanels)
	byte subPanel = 1;
	//disable FP2800A's
	digitalWrite(_enableSubPanel1Pin, LOW);
	digitalWrite(_enableSubPanel2Pin, LOW);

	//enables next sunpanel
	if(col>=DISPLAY_PIXEL_WIDTH){
		//subPanel =  floor(col / DISPLAY_PIXEL_WIDTH)+1;
		subPanel =  (int)(col / DISPLAY_PIXEL_WIDTH)+1;
		col=col-DISPLAY_PIXEL_WIDTH;
	}

	/*
	if(printer) {
	printer->print("col: ");
	printer->print(col);
	printer->print(", ");
	printer->print("subPanel: ");
	printer->println(subPanel);
	}
	*/

	// IGNOREx4 + ROWx4 + IGNOREx1 + COLUMNx5 + DATAx2
	byte dataPins = on?1:2;
	byte colFirstThreeDigits = (col % 7)+1;
	//byte colLastTwoDigits = floor(col/7);
	byte colLastTwoDigits = (int)(col/7);
	byte colByte = colFirstThreeDigits | (colLastTwoDigits << 3);
	byte rowFirstThreeDigits = (row % 7)+1;
	byte rowLastDigit = row<7;
	byte rowByte = rowFirstThreeDigits | (rowLastDigit << 3);
	byte firstbyte = (dataPins) | (colByte << 2);
	byte secondbyte = rowByte;

	digitalWrite(_latchPin, LOW);
	shiftOut(_dataPin, _clockPin, LSBFIRST, firstbyte);
	shiftOut(_dataPin, _clockPin, LSBFIRST, secondbyte);
	digitalWrite(_latchPin, HIGH);
	//delay(1);

	//pulse the FP2800A's enable pins
	if(subPanel == 1){
		digitalWrite(_enableSubPanel1Pin, HIGH);
		delay(1);
		digitalWrite(_enableSubPanel1Pin, LOW);
	} else if (subPanel == 2) {
		digitalWrite(_enableSubPanel2Pin, HIGH);
		delay(1);
		digitalWrite(_enableSubPanel2Pin, LOW);
	}
}

//void DotDisplay::updateDisplay(char *textMessage){
void DotDisplay::updateDisplay(char textMessage[], char log[]){
	int currentColumn = 0;
	int currentRow = 0;

	strcat(log,"");

	//goes through all characters
	for (int ch = 0; ch < (_maxMessageLength);ch++){
		//get a character from the message
		int alphabetIndex = textMessage[ch] - ' '; //Subtract '@' so we get a number

		//Serial.println(alphabetIndex);
		//strcat(log,"Index: ");
		//strcat(log,alphabetIndex);
		strcat(log,"Letter: ");
		log[8]=textMessage[ch];
		log[9]='\0';

		if ((alphabetIndex < 0) or (ch >=strlen(textMessage))) alphabetIndex=0;

		//push it to the next row if necessary
		if((currentColumn + _fontWidth) > (DISPLAY_PIXEL_WIDTH * DISPLAY_SUBPANEL_QTY)){
			currentColumn=0;
			currentRow=currentRow+_fontHeight;
		}

		//set all the bits in the next _fontWidth columns on the display
		for(byte col = currentColumn; col<(currentColumn+_fontWidth); col++){

			byte calculatedColumn = (col)%(_fontWidth+1);
			//for(byte row = 0; row < _fontHeight; row++)
			int characterRow = 0;
			for(byte row = currentRow; row < (currentRow + _fontHeight); row++){
				//bool isOn = bitRead(pgm_read_byte(&(_fonteParam[alphabetIndex][calculatedColumn])),6-characterRow);
				bool isOn = bitRead((byte)_fonteParam[alphabetIndex][calculatedColumn],6-row);//this index is needed as we are going from back to front

				setDot(col, row, isOn);
				/*
				if(printer) {
					printer->print(isOn);
				}
				*/
				char dot[2];
				if (isOn) {
					strcpy(dot,"1");
				}else {
					strcpy(dot,"0");
				}
				strcat(log,dot);

				characterRow++;
			}
			/*
			if(printer) {
				printer->println("");
			}
			*/
			strcat(log," ");
		}
		/*
		if(printer) {
			printer->println("*******");
		}
		*/
		strcat(log,"*********");

		currentColumn = currentColumn+(_fontWidth+1);
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "chrome/browser/background_mode_manager.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/status_icons/status_icon.h"
#include "chrome/browser/status_icons/status_tray.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/theme_resources.h"

BackgroundModeManager::BackgroundModeManager(Profile* profile)
    : profile_(profile),
      background_app_count_(0),
      status_tray_(NULL) {
  // If background mode is disabled for unittests, just exit - don't listen for
  // any notifications.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableBackgroundMode))
    return;

  // Only need status icons on windows/linux. ChromeOS doesn't allow exiting
  // Chrome and Mac can use the dock icon instead.
#if !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
  status_tray_ = profile->GetStatusTray();
#endif

  // If the -keep-alive-for-test flag is passed, then always keep chrome running
  // in the background until the user explicitly terminates it.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kKeepAliveForTest)) {
    StartBackgroundMode();
    registrar_.Add(this, NotificationType::APP_TERMINATING,
                 NotificationService::AllSources());
  }

  // When an extension is installed, make sure launch on startup is properly
  // set if appropriate. Likewise, turn off launch on startup when the last
  // background app is uninstalled.
  registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
                 Source<Profile>(profile));
  registrar_.Add(this, NotificationType::EXTENSION_UNINSTALLED,
                 Source<Profile>(profile));
  // Listen for when extensions are loaded/unloaded so we can track the
  // number of background apps.
  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
                 Source<Profile>(profile));
  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
                 Source<Profile>(profile));

  // Check for the presence of background apps after all extensions have been
  // loaded, to handle the case where an extension has been manually removed
  // while Chrome was not running.
  registrar_.Add(this, NotificationType::EXTENSIONS_READY,
                 Source<Profile>(profile));

}

BackgroundModeManager::~BackgroundModeManager() {
}

bool BackgroundModeManager::IsBackgroundModeEnabled() {
  return profile_->GetPrefs()->GetBoolean(prefs::kBackgroundModeEnabled);
}

void BackgroundModeManager::Observe(NotificationType type,
                                    const NotificationSource& source,
                                    const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::EXTENSIONS_READY:
      EnableLaunchOnStartup(IsBackgroundModeEnabled() &&
                            background_app_count_ > 0);
      break;
    case NotificationType::EXTENSION_LOADED:
      if (IsBackgroundApp(Details<Extension>(details).ptr()))
        OnBackgroundAppLoaded();
      break;
    case NotificationType::EXTENSION_UNLOADED:
      if (IsBackgroundApp(Details<Extension>(details).ptr()))
        OnBackgroundAppUnloaded();
      break;
    case NotificationType::EXTENSION_INSTALLED:
      if (IsBackgroundApp(Details<Extension>(details).ptr()))
        OnBackgroundAppInstalled();
      break;
    case NotificationType::EXTENSION_UNINSTALLED:
      if (IsBackgroundApp(Details<Extension>(details).ptr()))
        OnBackgroundAppUninstalled();
      break;
    case NotificationType::APP_TERMINATING:
      // Performing an explicit shutdown, so allow the browser process to exit.
      // (we only listen for this notification if the keep-alive-for-test flag
      // is passed).
      DCHECK(CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kKeepAliveForTest));
      EndBackgroundMode();
      break;
    default:
      NOTREACHED();
      break;
  }
}

bool BackgroundModeManager::IsBackgroundApp(Extension* extension) {
  return extension->HasApiPermission(Extension::kBackgroundPermission);
}

void BackgroundModeManager::OnBackgroundAppLoaded() {
  // When a background app loads, increment our count and also enable
  // KeepAlive mode if the preference is set.
  background_app_count_++;
  if (background_app_count_ == 1 && IsBackgroundModeEnabled())
    StartBackgroundMode();
}

void BackgroundModeManager::StartBackgroundMode() {
  // Put ourselves in KeepAlive mode and create a status tray icon.
  BrowserList::StartKeepAlive();

  // Display a status icon to exit Chrome.
  CreateStatusTrayIcon();
}

void BackgroundModeManager::OnBackgroundAppUnloaded() {
  // When a background app unloads, decrement our count and also end
  // KeepAlive mode if appropriate.
  background_app_count_--;
  DCHECK(background_app_count_ == 0);
  if (background_app_count_ == 0 && IsBackgroundModeEnabled())
    EndBackgroundMode();
}

void BackgroundModeManager::EndBackgroundMode() {
  // End KeepAlive mode and blow away our status tray icon.
  BrowserList::EndKeepAlive();
  RemoveStatusTrayIcon();
}

void BackgroundModeManager::OnBackgroundAppInstalled() {
  // We're installing a background app. If this is the first background app
  // being installed, make sure we are set to launch on startup.
  if (IsBackgroundModeEnabled() && background_app_count_ == 0)
    EnableLaunchOnStartup(true);
}

void BackgroundModeManager::OnBackgroundAppUninstalled() {
  // When uninstalling a background app, disable launch on startup if it's the
  // last one.
  if (IsBackgroundModeEnabled() && background_app_count_ == 1)
    EnableLaunchOnStartup(false);
}

void BackgroundModeManager::EnableLaunchOnStartup(bool should_launch) {
  // TODO(atwilson): Add platform-specific code to enable/disable launch on
  // startup.
}

void BackgroundModeManager::CreateStatusTrayIcon() {
  // If the platform doesn't support status icons, or we've already created
  // our status icon, just return.
  if (!status_tray_ || status_icon_)
    return;
  status_icon_ = status_tray_->CreateStatusIcon();
  if (!status_icon_)
    return;

  // Set the image and add ourselves as a click observer on it
  SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(
      IDR_STATUS_TRAY_ICON);
  status_icon_->SetImage(*bitmap);
  status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
  status_icon_->AddObserver(this);
}

void BackgroundModeManager::RemoveStatusTrayIcon() {
  if (status_icon_)
    status_tray_->RemoveStatusIcon(status_icon_);
  status_icon_ = NULL;
}

void BackgroundModeManager::OnClicked() {
  UserMetrics::RecordAction(UserMetricsAction("Exit"), profile_);
  BrowserList::CloseAllBrowsersAndExit();
}

// static
void BackgroundModeManager::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true);
}
<commit_msg>Change when we create StatusTray to avoid problem running multi-profile tests (StatusTray is effectively supposed to be a singleton, so creating multiple instances isn't truly supported currently and would require a bit of extra plumbing which I'd rather not do until we truly support multiple profiles).<commit_after>// Copyright (c) 2010 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 "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "chrome/browser/background_mode_manager.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/status_icons/status_icon.h"
#include "chrome/browser/status_icons/status_tray.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/theme_resources.h"

BackgroundModeManager::BackgroundModeManager(Profile* profile)
    : profile_(profile),
      background_app_count_(0),
      status_tray_(NULL) {
  // If background mode is disabled for unittests, just exit - don't listen for
  // any notifications.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableBackgroundMode))
    return;

  // If the -keep-alive-for-test flag is passed, then always keep chrome running
  // in the background until the user explicitly terminates it.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kKeepAliveForTest)) {
    StartBackgroundMode();
    registrar_.Add(this, NotificationType::APP_TERMINATING,
                 NotificationService::AllSources());
  }

  // When an extension is installed, make sure launch on startup is properly
  // set if appropriate. Likewise, turn off launch on startup when the last
  // background app is uninstalled.
  registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
                 Source<Profile>(profile));
  registrar_.Add(this, NotificationType::EXTENSION_UNINSTALLED,
                 Source<Profile>(profile));
  // Listen for when extensions are loaded/unloaded so we can track the
  // number of background apps.
  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
                 Source<Profile>(profile));
  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
                 Source<Profile>(profile));

  // Check for the presence of background apps after all extensions have been
  // loaded, to handle the case where an extension has been manually removed
  // while Chrome was not running.
  registrar_.Add(this, NotificationType::EXTENSIONS_READY,
                 Source<Profile>(profile));

}

BackgroundModeManager::~BackgroundModeManager() {
}

bool BackgroundModeManager::IsBackgroundModeEnabled() {
  return profile_->GetPrefs()->GetBoolean(prefs::kBackgroundModeEnabled);
}

void BackgroundModeManager::Observe(NotificationType type,
                                    const NotificationSource& source,
                                    const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::EXTENSIONS_READY:
      EnableLaunchOnStartup(IsBackgroundModeEnabled() &&
                            background_app_count_ > 0);
      break;
    case NotificationType::EXTENSION_LOADED:
      if (IsBackgroundApp(Details<Extension>(details).ptr()))
        OnBackgroundAppLoaded();
      break;
    case NotificationType::EXTENSION_UNLOADED:
      if (IsBackgroundApp(Details<Extension>(details).ptr()))
        OnBackgroundAppUnloaded();
      break;
    case NotificationType::EXTENSION_INSTALLED:
      if (IsBackgroundApp(Details<Extension>(details).ptr()))
        OnBackgroundAppInstalled();
      break;
    case NotificationType::EXTENSION_UNINSTALLED:
      if (IsBackgroundApp(Details<Extension>(details).ptr()))
        OnBackgroundAppUninstalled();
      break;
    case NotificationType::APP_TERMINATING:
      // Performing an explicit shutdown, so allow the browser process to exit.
      // (we only listen for this notification if the keep-alive-for-test flag
      // is passed).
      DCHECK(CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kKeepAliveForTest));
      EndBackgroundMode();
      break;
    default:
      NOTREACHED();
      break;
  }
}

bool BackgroundModeManager::IsBackgroundApp(Extension* extension) {
  return extension->HasApiPermission(Extension::kBackgroundPermission);
}

void BackgroundModeManager::OnBackgroundAppLoaded() {
  // When a background app loads, increment our count and also enable
  // KeepAlive mode if the preference is set.
  background_app_count_++;
  if (background_app_count_ == 1 && IsBackgroundModeEnabled())
    StartBackgroundMode();
}

void BackgroundModeManager::StartBackgroundMode() {
  // Put ourselves in KeepAlive mode and create a status tray icon.
  BrowserList::StartKeepAlive();

  // Display a status icon to exit Chrome.
  CreateStatusTrayIcon();
}

void BackgroundModeManager::OnBackgroundAppUnloaded() {
  // When a background app unloads, decrement our count and also end
  // KeepAlive mode if appropriate.
  background_app_count_--;
  DCHECK(background_app_count_ == 0);
  if (background_app_count_ == 0 && IsBackgroundModeEnabled())
    EndBackgroundMode();
}

void BackgroundModeManager::EndBackgroundMode() {
  // End KeepAlive mode and blow away our status tray icon.
  BrowserList::EndKeepAlive();
  RemoveStatusTrayIcon();
}

void BackgroundModeManager::OnBackgroundAppInstalled() {
  // We're installing a background app. If this is the first background app
  // being installed, make sure we are set to launch on startup.
  if (IsBackgroundModeEnabled() && background_app_count_ == 0)
    EnableLaunchOnStartup(true);
}

void BackgroundModeManager::OnBackgroundAppUninstalled() {
  // When uninstalling a background app, disable launch on startup if it's the
  // last one.
  if (IsBackgroundModeEnabled() && background_app_count_ == 1)
    EnableLaunchOnStartup(false);
}

void BackgroundModeManager::EnableLaunchOnStartup(bool should_launch) {
  // TODO(atwilson): Add platform-specific code to enable/disable launch on
  // startup.
}

void BackgroundModeManager::CreateStatusTrayIcon() {
  // Only need status icons on windows/linux. ChromeOS doesn't allow exiting
  // Chrome and Mac can use the dock icon instead.
#if !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
  if (!status_tray_)
    status_tray_ = profile_->GetStatusTray();
#endif

  // If the platform doesn't support status icons, or we've already created
  // our status icon, just return.
  if (!status_tray_ || status_icon_)
    return;
  status_icon_ = status_tray_->CreateStatusIcon();
  if (!status_icon_)
    return;

  // Set the image and add ourselves as a click observer on it
  SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(
      IDR_STATUS_TRAY_ICON);
  status_icon_->SetImage(*bitmap);
  status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
  status_icon_->AddObserver(this);
}

void BackgroundModeManager::RemoveStatusTrayIcon() {
  if (status_icon_)
    status_tray_->RemoveStatusIcon(status_icon_);
  status_icon_ = NULL;
}

void BackgroundModeManager::OnClicked() {
  UserMetrics::RecordAction(UserMetricsAction("Exit"), profile_);
  BrowserList::CloseAllBrowsersAndExit();
}

// static
void BackgroundModeManager::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true);
}
<|endoftext|>


<commit_before>#include "Profiling_Service.hpp"

#include "mmcore/MegaMolGraph.h"
#include "mmcore/view/AbstractView.h"

#include "LuaCallbacksCollection.h"

namespace megamol {
namespace frontend {

bool Profiling_Service::init(void* configPtr) {
    _providedResourceReferences = {{"PerformanceManager", _perf_man}};

#ifdef PROFILING
    const auto conf = static_cast<Config*>(configPtr);
    if (conf != nullptr && !conf->log_file.empty()) {
        log_file = std::ofstream(conf->log_file, std::ofstream::trunc);
        // header
        log_file << "frame;parent;name;comment;frame_index;api;type;time (ms)" << std::endl;
        _perf_man.subscribe_to_updates([&](const frontend_resources::PerformanceManager::frame_info& fi) {
            auto frame = fi.frame;
            for (auto& e : fi.entries) {
                auto conf = _perf_man.lookup_config(e.handle);
                auto name = conf.name;
                auto parent = _perf_man.lookup_parent(e.handle);
                auto comment = conf.comment;
                std::string time_string;
                const auto dur = std::chrono::duration<double, std::milli>(e.timestamp.time_since_epoch());
                time_string = std::to_string(dur.count());

                log_file << frame << ";" << parent << ";" << name << ";" << comment << ";" << e.frame_index << ";"
                         << megamol::frontend_resources::PerformanceManager::query_api_string(e.api) << ";"
                         << megamol::frontend_resources::PerformanceManager::entry_type_string(e.type) << ";"
                         << time_string << std::endl;
            }
        });
    }
#endif

    _requestedResourcesNames = {"RegisterLuaCallbacks", "MegaMolGraph", "RenderNextFrame"};

    return true;
}

void Profiling_Service::close() {
#ifdef PROFILING
    if (log_file.is_open()) {
        log_file.close();
    }
#endif
}

void Profiling_Service::updateProvidedResources() {
    _perf_man.startFrame();
}

void Profiling_Service::resetProvidedResources() {
    _perf_man.endFrame();
}

void Profiling_Service::fill_lua_callbacks() {
    frontend_resources::LuaCallbacksCollection callbacks;

    auto& graph = const_cast<core::MegaMolGraph&>(_requestedResourcesReferences[1].getResource<core::MegaMolGraph>());
    auto& render_next_frame = _requestedResourcesReferences[2].getResource<std::function<bool()>>();

    callbacks.add<frontend_resources::LuaCallbacksCollection::StringResult, std::string, std::string, int>(
        "mmGenerateCameraPositions", "(string entrypoint, string camera_path_pattern, uint num_samples)",
        {[&graph](std::string entrypoint, std::string camera_path_pattern,
             int num_samples) -> frontend_resources::LuaCallbacksCollection::StringResult {
            auto entry = graph.FindModule(entrypoint);
            if (!entry)
                return frontend_resources::LuaCallbacksCollection::Error{"could not find entrypoint"};
            auto view = std::dynamic_pointer_cast<core::view::AbstractView>(entry);
            if (!view)
                return frontend_resources::LuaCallbacksCollection::Error{"requested entrypoint is not a view"};
            auto camera_samples = view->SampleCameraScenes(num_samples);
            if (camera_samples.empty())
                return frontend_resources::LuaCallbacksCollection::Error{"could not sample camera"};
            return frontend_resources::LuaCallbacksCollection::StringResult{camera_samples};
        }});

    callbacks.add<frontend_resources::LuaCallbacksCollection::VoidResult, std::string, std::string, int>("mmProfile",
        "(string entrypoint, string cameras, unsigned int num_frames)",
        {[&graph, &render_next_frame](std::string entrypoint, std::string cameras, int num_frames) -> frontend_resources::LuaCallbacksCollection::VoidResult {
            auto entry = graph.FindModule(entrypoint);
            if (!entry)
                return frontend_resources::LuaCallbacksCollection::Error{"could not find entrypoint"};
            auto view = std::dynamic_pointer_cast<core::view::AbstractView>(entry);
            if (!view)
                return frontend_resources::LuaCallbacksCollection::Error{"requested entrypoint is not a view"};

            auto serializer = core::view::CameraSerializer();
            std::vector<core::view::Camera> cams;
            serializer.deserialize(cams, cameras);

            auto const old_cam = view->GetCamera();

            for (auto const& cam : cams) {
                view->SetCamera(cam);
                for (unsigned int f_idx = 0; f_idx < num_frames; ++f_idx) {
                    render_next_frame();
                }
            }

            view->SetCamera(old_cam);

            return frontend_resources::LuaCallbacksCollection::VoidResult{};
        }});

    auto& register_callbacks =
        _requestedResourcesReferences[0]
            .getResource<std::function<void(frontend_resources::LuaCallbacksCollection const&)>>();

    register_callbacks(callbacks);
}

} // namespace frontend
} // namespace megamol
<commit_msg>formatting<commit_after>#include "Profiling_Service.hpp"

#include "mmcore/MegaMolGraph.h"
#include "mmcore/view/AbstractView.h"

#include "LuaCallbacksCollection.h"

namespace megamol {
namespace frontend {

bool Profiling_Service::init(void* configPtr) {
    _providedResourceReferences = {{"PerformanceManager", _perf_man}};

#ifdef PROFILING
    const auto conf = static_cast<Config*>(configPtr);
    if (conf != nullptr && !conf->log_file.empty()) {
        log_file = std::ofstream(conf->log_file, std::ofstream::trunc);
        // header
        log_file << "frame;parent;name;comment;frame_index;api;type;time (ms)" << std::endl;
        _perf_man.subscribe_to_updates([&](const frontend_resources::PerformanceManager::frame_info& fi) {
            auto frame = fi.frame;
            for (auto& e : fi.entries) {
                auto conf = _perf_man.lookup_config(e.handle);
                auto name = conf.name;
                auto parent = _perf_man.lookup_parent(e.handle);
                auto comment = conf.comment;
                std::string time_string;
                const auto dur = std::chrono::duration<double, std::milli>(e.timestamp.time_since_epoch());
                time_string = std::to_string(dur.count());

                log_file << frame << ";" << parent << ";" << name << ";" << comment << ";" << e.frame_index << ";"
                         << megamol::frontend_resources::PerformanceManager::query_api_string(e.api) << ";"
                         << megamol::frontend_resources::PerformanceManager::entry_type_string(e.type) << ";"
                         << time_string << std::endl;
            }
        });
    }
#endif

    _requestedResourcesNames = {"RegisterLuaCallbacks", "MegaMolGraph", "RenderNextFrame"};

    return true;
}

void Profiling_Service::close() {
#ifdef PROFILING
    if (log_file.is_open()) {
        log_file.close();
    }
#endif
}

void Profiling_Service::updateProvidedResources() {
    _perf_man.startFrame();
}

void Profiling_Service::resetProvidedResources() {
    _perf_man.endFrame();
}

void Profiling_Service::fill_lua_callbacks() {
    frontend_resources::LuaCallbacksCollection callbacks;

    auto& graph = const_cast<core::MegaMolGraph&>(_requestedResourcesReferences[1].getResource<core::MegaMolGraph>());
    auto& render_next_frame = _requestedResourcesReferences[2].getResource<std::function<bool()>>();

    callbacks.add<frontend_resources::LuaCallbacksCollection::StringResult, std::string, std::string, int>(
        "mmGenerateCameraPositions", "(string entrypoint, string camera_path_pattern, uint num_samples)",
        {[&graph](std::string entrypoint, std::string camera_path_pattern,
             int num_samples) -> frontend_resources::LuaCallbacksCollection::StringResult {
            auto entry = graph.FindModule(entrypoint);
            if (!entry)
                return frontend_resources::LuaCallbacksCollection::Error{"could not find entrypoint"};
            auto view = std::dynamic_pointer_cast<core::view::AbstractView>(entry);
            if (!view)
                return frontend_resources::LuaCallbacksCollection::Error{"requested entrypoint is not a view"};
            auto camera_samples = view->SampleCameraScenes(num_samples);
            if (camera_samples.empty())
                return frontend_resources::LuaCallbacksCollection::Error{"could not sample camera"};
            return frontend_resources::LuaCallbacksCollection::StringResult{camera_samples};
        }});

    callbacks.add<frontend_resources::LuaCallbacksCollection::VoidResult, std::string, std::string, int>("mmProfile",
        "(string entrypoint, string cameras, unsigned int num_frames)",
        {[&graph, &render_next_frame](std::string entrypoint, std::string cameras,
             int num_frames) -> frontend_resources::LuaCallbacksCollection::VoidResult {
            auto entry = graph.FindModule(entrypoint);
            if (!entry)
                return frontend_resources::LuaCallbacksCollection::Error{"could not find entrypoint"};
            auto view = std::dynamic_pointer_cast<core::view::AbstractView>(entry);
            if (!view)
                return frontend_resources::LuaCallbacksCollection::Error{"requested entrypoint is not a view"};

            auto serializer = core::view::CameraSerializer();
            std::vector<core::view::Camera> cams;
            serializer.deserialize(cams, cameras);

            auto const old_cam = view->GetCamera();

            for (auto const& cam : cams) {
                view->SetCamera(cam);
                for (unsigned int f_idx = 0; f_idx < num_frames; ++f_idx) {
                    render_next_frame();
                }
            }

            view->SetCamera(old_cam);

            return frontend_resources::LuaCallbacksCollection::VoidResult{};
        }});

    auto& register_callbacks =
        _requestedResourcesReferences[0]
            .getResource<std::function<void(frontend_resources::LuaCallbacksCollection const&)>>();

    register_callbacks(callbacks);
}

} // namespace frontend
} // namespace megamol
<|endoftext|>


<commit_before>/*
 * This file is part of the FreeStreamer project,
 * (C)Copyright 2011-2014 Matias Muhonen <mmu@iki.fi>
 * See the file ''LICENSE'' for using the code.
 *
 * https://github.com/muhku/FreeStreamer
 */

#include "caching_stream.h"
#include "file_output.h"
#include "stream_configuration.h"
#include "file_stream.h"

//#define CS_DEBUG 1

#if !defined (CS_DEBUG)
#define CS_TRACE(...) do {} while (0)
#define CS_TRACE_CFSTRING(X) do {} while (0)
#else
#define CS_TRACE(...) printf(__VA_ARGS__)
#define CS_TRACE_CFSTRING(X) CS_TRACE("%s\n", CFStringGetCStringPtr(X, kCFStringEncodingMacRoman))
#endif

namespace astreamer {

Caching_Stream::Caching_Stream(Input_Stream *target) :
    m_target(target),
    m_fileOutput(0),
    m_fileStream(new File_Stream()),
    m_cacheable(false),
    m_writable(false),
    m_useCache(false),
    m_cacheMetaDataWritten(false),
    m_cacheIdentifier(0),
    m_fileUrl(0),
    m_metaDataUrl(0)
{
    m_target->m_delegate = this;
    m_fileStream->m_delegate = this;
}

Caching_Stream::~Caching_Stream()
{
    if (m_target) {
        delete m_target, m_target = 0;
    }
    if (m_fileOutput) {
        delete m_fileOutput, m_fileOutput = 0;
    }
    if (m_fileStream) {
        delete m_fileStream, m_fileStream = 0;
    }
    if (m_cacheIdentifier) {
        CFRelease(m_cacheIdentifier), m_cacheIdentifier = 0;
    }
    if (m_fileUrl) {
        CFRelease(m_fileUrl), m_fileUrl = 0;
    }
    if (m_metaDataUrl) {
        CFRelease(m_metaDataUrl), m_fileUrl = 0;
    }
}

CFURLRef Caching_Stream::createFileURLWithPath(CFStringRef path)
{
    CFURLRef regularUrl = CFURLCreateWithString(kCFAllocatorDefault, path, NULL);

    CFURLRef fileUrl = CFURLCreateFilePathURL(kCFAllocatorDefault, regularUrl, NULL);

    CFRelease(regularUrl);

    return fileUrl;
}

void Caching_Stream::readMetaData()
{
    if (!m_metaDataUrl) {
        return;
    }

    CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, m_metaDataUrl);

    if (readStream) {
        if (CFReadStreamOpen(readStream)) {

            UInt8 buf[1024];

            CFIndex bytesRead = CFReadStreamRead(readStream, buf, 1024);

            if (bytesRead > 0) {
                CFStringRef contentType = CFStringCreateWithBytes(kCFAllocatorDefault, buf, bytesRead, kCFStringEncodingUTF8, false);

                if (contentType) {
                    if (m_fileStream) {
                        CS_TRACE("Setting the content type of the file stream based on the meta data\n");
                        CS_TRACE_CFSTRING(contentType);

                        m_fileStream->setContentType(contentType);
                    }

                    CFRelease(contentType);
                }
            }

            CFReadStreamClose(readStream);
        }

        CFRelease(readStream);
    }
}

Input_Stream_Position Caching_Stream::position()
{
    if (m_useCache) {
        return m_fileStream->position();
    } else {
        return m_target->position();
    }
}

CFStringRef Caching_Stream::contentType()
{
    if (m_useCache) {
        return m_fileStream->contentType();
    } else {
        return m_target->contentType();
    }
}

size_t Caching_Stream::contentLength()
{
    if (m_useCache) {
        return m_fileStream->contentLength();
    } else {
        return m_target->contentLength();
    }
}

bool Caching_Stream::open()
{
    bool status;

    if (CFURLResourceIsReachable(m_metaDataUrl, NULL) &&
        CFURLResourceIsReachable(m_fileUrl, NULL)) {
        m_cacheable = false;
        m_writable  = false;
        m_useCache  = true;
        m_cacheMetaDataWritten = false;

        readMetaData();

        status = m_fileStream->open();
    } else {
        m_cacheable = true;
        m_writable  = false;
        m_useCache  = false;
        m_cacheMetaDataWritten = false;

        status = m_target->open();
    }

    return status;
}

bool Caching_Stream::open(const Input_Stream_Position& position)
{
    bool status;

    if (CFURLResourceIsReachable(m_metaDataUrl, NULL) &&
        CFURLResourceIsReachable(m_fileUrl, NULL)) {
        m_cacheable = false;
        m_writable  = false;
        m_useCache  = true;
        m_cacheMetaDataWritten = false;

        readMetaData();

        status = m_fileStream->open(position);
    } else {
        m_cacheable = false;
        m_writable  = false;
        m_useCache  = false;
        m_cacheMetaDataWritten = false;

        status = m_target->open(position);
    }

    return status;
}

void Caching_Stream::close()
{
    m_fileStream->close();
    m_target->close();
}

void Caching_Stream::setScheduledInRunLoop(bool scheduledInRunLoop)
{
    if (m_useCache) {
        m_fileStream->setScheduledInRunLoop(scheduledInRunLoop);
    } else {
        m_target->setScheduledInRunLoop(scheduledInRunLoop);
    }
}

void Caching_Stream::setUrl(CFURLRef url)
{
    m_target->setUrl(url);
}

void Caching_Stream::setCacheIdentifier(CFStringRef cacheIdentifier)
{
    m_cacheIdentifier = CFStringCreateCopy(kCFAllocatorDefault, cacheIdentifier);

    if (m_fileOutput) {
        delete m_fileOutput, m_fileOutput = 0;
    }

    Stream_Configuration *config = Stream_Configuration::configuration();

    CFStringRef filePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("file://%@/%@"), config->cacheDirectory, m_cacheIdentifier);
    CFStringRef metaDataPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("file://%@/%@.metadata"), config->cacheDirectory, m_cacheIdentifier);

    if (m_fileUrl) {
        CFRelease(m_fileUrl), m_fileUrl = 0;
    }
    if (m_metaDataUrl) {
        CFRelease(m_metaDataUrl), m_metaDataUrl = 0;
    }

    m_fileUrl = createFileURLWithPath(filePath);
    m_metaDataUrl = createFileURLWithPath(metaDataPath);

    m_fileStream->setUrl(m_fileUrl);

    CFRelease(filePath);
    CFRelease(metaDataPath);
}

bool Caching_Stream::canHandleUrl(CFURLRef url)
{
    if (!url) {
        return false;
    }

    CFStringRef scheme = CFURLCopyScheme(url);

    if (scheme) {
        if (CFStringCompare(scheme, CFSTR("http"), 0) == kCFCompareEqualTo) {
            CFRelease(scheme);
            // Using cache makes only sense for HTTP
            return true;
        }

        CFRelease(scheme);
    }

    // Nothing else to server
    return false;
}

/* ID3_Parser_Delegate */
void Caching_Stream::id3metaDataAvailable(std::map<CFStringRef,CFStringRef> metaData)
{
    if (m_delegate) {
        m_delegate->streamMetaDataAvailable(metaData);
    }
}

/* Input_Stream_Delegate */

void Caching_Stream::streamIsReadyRead()
{
    if (m_cacheable) {
        // If the stream is cacheable (not seeked from some position)
        // Check if the stream has a length. If there is no length,
        // it is a continuous stream and thus cannot be cached.
        m_cacheable = (m_target->contentLength() > 0);
    }

    if (m_delegate) {
        m_delegate->streamIsReadyRead();
    }
}

void Caching_Stream::streamHasBytesAvailable(UInt8 *data, UInt32 numBytes)
{
    if (m_cacheable) {
        if (numBytes > 0) {
            if (!m_fileOutput) {
                if (m_fileUrl) {
                    m_fileOutput = new File_Output(m_fileUrl);

                    m_writable = true;
                }
            }

            if (m_writable) {
                m_writable &= (m_fileOutput->write(data, numBytes) > 0);
            }
        }
    }
    if (m_delegate) {
        m_delegate->streamHasBytesAvailable(data, numBytes);
    }
}

void Caching_Stream::streamEndEncountered()
{
    if (m_fileOutput) {
        delete m_fileOutput, m_fileOutput = 0;
    }

    if (m_cacheable) {
        if (m_writable) {
            CS_TRACE("Successfully cached the stream\n");

            // We only write the meta data if the stream was successfully streamed.
            // In that way we can use the meta data as an indicator that there is a file to stream.

            if (!m_cacheMetaDataWritten) {
                CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault, m_metaDataUrl);

                if (writeStream) {
                    if (CFWriteStreamOpen(writeStream)) {
                        CFStringRef contentType = m_target->contentType();

                        UInt8 buf[1024];
                        CFIndex usedBytes = 0;

                        CFStringGetBytes(contentType,
                                         CFRangeMake(0, CFStringGetLength(contentType)),
                                         kCFStringEncodingUTF8,
                                         '?',
                                         false,
                                         buf,
                                         1024,
                                         &usedBytes);

                        if (usedBytes > 0) {
                            CS_TRACE("Writing the meta data\n");
                            CS_TRACE_CFSTRING(contentType);

                            CFWriteStreamWrite(writeStream, buf, usedBytes);
                        }

                        CFWriteStreamClose(writeStream);
                    }

                    CFRelease(writeStream);
                }

                m_cacheMetaDataWritten = true;
            }
        }
    }
    if (m_delegate) {
        m_delegate->streamEndEncountered();
    }
}

void Caching_Stream::streamErrorOccurred()
{
    if (m_delegate) {
        m_delegate->streamErrorOccurred();
    }
}

void Caching_Stream::streamMetaDataAvailable(std::map<CFStringRef,CFStringRef> metaData)
{
    if (m_delegate) {
        m_delegate->streamMetaDataAvailable(metaData);
    }
}

} // namespace astreamer<commit_msg>Fix analyzer warning<commit_after>/*
 * This file is part of the FreeStreamer project,
 * (C)Copyright 2011-2014 Matias Muhonen <mmu@iki.fi>
 * See the file ''LICENSE'' for using the code.
 *
 * https://github.com/muhku/FreeStreamer
 */

#include "caching_stream.h"
#include "file_output.h"
#include "stream_configuration.h"
#include "file_stream.h"

//#define CS_DEBUG 1

#if !defined (CS_DEBUG)
#define CS_TRACE(...) do {} while (0)
#define CS_TRACE_CFSTRING(X) do {} while (0)
#else
#define CS_TRACE(...) printf(__VA_ARGS__)
#define CS_TRACE_CFSTRING(X) CS_TRACE("%s\n", CFStringGetCStringPtr(X, kCFStringEncodingMacRoman))
#endif

namespace astreamer {

Caching_Stream::Caching_Stream(Input_Stream *target) :
    m_target(target),
    m_fileOutput(0),
    m_fileStream(new File_Stream()),
    m_cacheable(false),
    m_writable(false),
    m_useCache(false),
    m_cacheMetaDataWritten(false),
    m_cacheIdentifier(0),
    m_fileUrl(0),
    m_metaDataUrl(0)
{
    m_target->m_delegate = this;
    m_fileStream->m_delegate = this;
}

Caching_Stream::~Caching_Stream()
{
    if (m_target) {
        delete m_target, m_target = 0;
    }
    if (m_fileOutput) {
        delete m_fileOutput, m_fileOutput = 0;
    }
    if (m_fileStream) {
        delete m_fileStream, m_fileStream = 0;
    }
    if (m_cacheIdentifier) {
        CFRelease(m_cacheIdentifier), m_cacheIdentifier = 0;
    }
    if (m_fileUrl) {
        CFRelease(m_fileUrl), m_fileUrl = 0;
    }
    if (m_metaDataUrl) {
        CFRelease(m_metaDataUrl), m_fileUrl = 0;
    }
}

CFURLRef Caching_Stream::createFileURLWithPath(CFStringRef path)
{
    CFURLRef regularUrl = CFURLCreateWithString(kCFAllocatorDefault, path, NULL);

    CFURLRef fileUrl = CFURLCreateFilePathURL(kCFAllocatorDefault, regularUrl, NULL);

    CFRelease(regularUrl);

    return fileUrl;
}

void Caching_Stream::readMetaData()
{
    if (!m_metaDataUrl) {
        return;
    }

    CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, m_metaDataUrl);

    if (readStream) {
        if (CFReadStreamOpen(readStream)) {

            UInt8 buf[1024];

            CFIndex bytesRead = CFReadStreamRead(readStream, buf, 1024);

            if (bytesRead > 0) {
                CFStringRef contentType = CFStringCreateWithBytes(kCFAllocatorDefault, buf, bytesRead, kCFStringEncodingUTF8, false);

                if (contentType) {
                    if (m_fileStream) {
                        CS_TRACE("Setting the content type of the file stream based on the meta data\n");
                        CS_TRACE_CFSTRING(contentType);

                        m_fileStream->setContentType(contentType);
                    }

                    CFRelease(contentType);
                }
            }

            CFReadStreamClose(readStream);
        }

        CFRelease(readStream);
    }
}

Input_Stream_Position Caching_Stream::position()
{
    if (m_useCache) {
        return m_fileStream->position();
    } else {
        return m_target->position();
    }
}

CFStringRef Caching_Stream::contentType()
{
    if (m_useCache) {
        return m_fileStream->contentType();
    } else {
        return m_target->contentType();
    }
}

size_t Caching_Stream::contentLength()
{
    if (m_useCache) {
        return m_fileStream->contentLength();
    } else {
        return m_target->contentLength();
    }
}

bool Caching_Stream::open()
{
    bool status;

    if (CFURLResourceIsReachable(m_metaDataUrl, NULL) &&
        CFURLResourceIsReachable(m_fileUrl, NULL)) {
        m_cacheable = false;
        m_writable  = false;
        m_useCache  = true;
        m_cacheMetaDataWritten = false;

        readMetaData();

        status = m_fileStream->open();
    } else {
        m_cacheable = true;
        m_writable  = false;
        m_useCache  = false;
        m_cacheMetaDataWritten = false;

        status = m_target->open();
    }

    return status;
}

bool Caching_Stream::open(const Input_Stream_Position& position)
{
    bool status;

    if (CFURLResourceIsReachable(m_metaDataUrl, NULL) &&
        CFURLResourceIsReachable(m_fileUrl, NULL)) {
        m_cacheable = false;
        m_writable  = false;
        m_useCache  = true;
        m_cacheMetaDataWritten = false;

        readMetaData();

        status = m_fileStream->open(position);
    } else {
        m_cacheable = false;
        m_writable  = false;
        m_useCache  = false;
        m_cacheMetaDataWritten = false;

        status = m_target->open(position);
    }

    return status;
}

void Caching_Stream::close()
{
    m_fileStream->close();
    m_target->close();
}

void Caching_Stream::setScheduledInRunLoop(bool scheduledInRunLoop)
{
    if (m_useCache) {
        m_fileStream->setScheduledInRunLoop(scheduledInRunLoop);
    } else {
        m_target->setScheduledInRunLoop(scheduledInRunLoop);
    }
}

void Caching_Stream::setUrl(CFURLRef url)
{
    m_target->setUrl(url);
}

void Caching_Stream::setCacheIdentifier(CFStringRef cacheIdentifier)
{
    m_cacheIdentifier = CFStringCreateCopy(kCFAllocatorDefault, cacheIdentifier);

    if (m_fileOutput) {
        delete m_fileOutput, m_fileOutput = 0;
    }

    Stream_Configuration *config = Stream_Configuration::configuration();

    CFStringRef filePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("file://%@/%@"), config->cacheDirectory, m_cacheIdentifier);
    CFStringRef metaDataPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("file://%@/%@.metadata"), config->cacheDirectory, m_cacheIdentifier);

    if (m_fileUrl) {
        CFRelease(m_fileUrl), m_fileUrl = 0;
    }
    if (m_metaDataUrl) {
        CFRelease(m_metaDataUrl), m_metaDataUrl = 0;
    }

    m_fileUrl = createFileURLWithPath(filePath);
    m_metaDataUrl = createFileURLWithPath(metaDataPath);

    m_fileStream->setUrl(m_fileUrl);

    CFRelease(filePath);
    CFRelease(metaDataPath);
}

bool Caching_Stream::canHandleUrl(CFURLRef url)
{
    if (!url) {
        return false;
    }

    CFStringRef scheme = CFURLCopyScheme(url);

    if (scheme) {
        if (CFStringCompare(scheme, CFSTR("http"), 0) == kCFCompareEqualTo) {
            CFRelease(scheme);
            // Using cache makes only sense for HTTP
            return true;
        }

        CFRelease(scheme);
    }

    // Nothing else to server
    return false;
}

/* ID3_Parser_Delegate */
void Caching_Stream::id3metaDataAvailable(std::map<CFStringRef,CFStringRef> metaData)
{
    if (m_delegate) {
        m_delegate->streamMetaDataAvailable(metaData);
    }
}

/* Input_Stream_Delegate */

void Caching_Stream::streamIsReadyRead()
{
    if (m_cacheable) {
        // If the stream is cacheable (not seeked from some position)
        // Check if the stream has a length. If there is no length,
        // it is a continuous stream and thus cannot be cached.
        m_cacheable = (m_target->contentLength() > 0);
    }

    if (m_delegate) {
        m_delegate->streamIsReadyRead();
    }
}

void Caching_Stream::streamHasBytesAvailable(UInt8 *data, UInt32 numBytes)
{
    if (m_cacheable) {
        if (numBytes > 0) {
            if (!m_fileOutput) {
                if (m_fileUrl) {
                    m_fileOutput = new File_Output(m_fileUrl);

                    m_writable = true;
                }
            }

            if (m_writable && m_fileOutput) {
                m_writable &= (m_fileOutput->write(data, numBytes) > 0);
            }
        }
    }
    if (m_delegate) {
        m_delegate->streamHasBytesAvailable(data, numBytes);
    }
}

void Caching_Stream::streamEndEncountered()
{
    if (m_fileOutput) {
        delete m_fileOutput, m_fileOutput = 0;
    }

    if (m_cacheable) {
        if (m_writable) {
            CS_TRACE("Successfully cached the stream\n");

            // We only write the meta data if the stream was successfully streamed.
            // In that way we can use the meta data as an indicator that there is a file to stream.

            if (!m_cacheMetaDataWritten) {
                CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault, m_metaDataUrl);

                if (writeStream) {
                    if (CFWriteStreamOpen(writeStream)) {
                        CFStringRef contentType = m_target->contentType();

                        UInt8 buf[1024];
                        CFIndex usedBytes = 0;

                        CFStringGetBytes(contentType,
                                         CFRangeMake(0, CFStringGetLength(contentType)),
                                         kCFStringEncodingUTF8,
                                         '?',
                                         false,
                                         buf,
                                         1024,
                                         &usedBytes);

                        if (usedBytes > 0) {
                            CS_TRACE("Writing the meta data\n");
                            CS_TRACE_CFSTRING(contentType);

                            CFWriteStreamWrite(writeStream, buf, usedBytes);
                        }

                        CFWriteStreamClose(writeStream);
                    }

                    CFRelease(writeStream);
                }

                m_cacheMetaDataWritten = true;
            }
        }
    }
    if (m_delegate) {
        m_delegate->streamEndEncountered();
    }
}

void Caching_Stream::streamErrorOccurred()
{
    if (m_delegate) {
        m_delegate->streamErrorOccurred();
    }
}

void Caching_Stream::streamMetaDataAvailable(std::map<CFStringRef,CFStringRef> metaData)
{
    if (m_delegate) {
        m_delegate->streamMetaDataAvailable(metaData);
    }
}

} // namespace astreamer<|endoftext|>


<commit_before><commit_msg>Slightly improve readability<commit_after><|endoftext|>


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

// Realm inter-node networking abstractions

#include "realm/network.h"

namespace Realm {

  namespace Network {
    NodeID my_node_id = 0;
    NodeID max_node_id = 0;
    NodeSet all_peers;
    NetworkModule *single_network = 0;
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class NetworkModule
  //

  NetworkModule::NetworkModule(const std::string& _name)
    : Module(_name)
  {}

  void NetworkModule::parse_command_line(RuntimeImpl *runtime,
					 std::vector<std::string>& cmdline)
  {}

  ////////////////////////////////////////////////////////////////////////
  //
  // class LoopbackNetworkModule
  //

  // used when there are no other networks

  class LoopbackNetworkModule : public NetworkModule {
  protected:
    LoopbackNetworkModule();

  public:
    static NetworkModule *create_network_module(RuntimeImpl *runtime,
						int *argc, const char ***argv);

    // actual parsing of the command line should wait until here if at all
    //  possible
    virtual void parse_command_line(RuntimeImpl *runtime,
				    std::vector<std::string>& cmdline);

    // "attaches" to the network, if that is meaningful - attempts to
    //  bind/register/(pick your network-specific verb) the requested memory
    //  segments with the network
    virtual void attach(RuntimeImpl *runtime,
			std::vector<NetworkSegment *>& segments);

    // detaches from the network
    virtual void detach(RuntimeImpl *runtime,
			std::vector<NetworkSegment *>& segments);

    // collective communication within this network
    virtual void barrier(void);
    virtual void broadcast(NodeID root,
			   const void *val_in, void *val_out, size_t bytes);
    virtual void gather(NodeID root,
			const void *val_in, void *vals_out, size_t bytes);

    // used to create a remote proxy for a memory
    virtual MemoryImpl *create_remote_memory(Memory m, size_t size, Memory::Kind kind,
					     const ByteArray& rdma_info);

    virtual ActiveMessageImpl *create_active_message_impl(NodeID target,
							  unsigned short msgid,
							  size_t header_size,
							  size_t max_payload_size,
							  void *dest_payload_addr,
							  void *storage_base,
							  size_t storage_size);

    virtual ActiveMessageImpl *create_active_message_impl(const NodeSet& targets,
							  unsigned short msgid,
							  size_t header_size,
							  size_t max_payload_size,
							  void *storage_base,
							  size_t storage_size);
  };

  LoopbackNetworkModule::LoopbackNetworkModule()
    : NetworkModule("loopback")
  {}

  /*static*/ NetworkModule *LoopbackNetworkModule::create_network_module(RuntimeImpl *runtime,
									 int *argc, const char ***argv)
  {
    return new LoopbackNetworkModule;
  }

  // actual parsing of the command line should wait until here if at all
  //  possible
  void LoopbackNetworkModule::parse_command_line(RuntimeImpl *runtime,
						 std::vector<std::string>& cmdline)
  {
    NetworkModule::parse_command_line(runtime, cmdline);
  }

  // "attaches" to the network, if that is meaningful - attempts to
  //  bind/register/(pick your network-specific verb) the requested memory
  //  segments with the network
  void LoopbackNetworkModule::attach(RuntimeImpl *runtime,
				     std::vector<NetworkSegment *>& segments)
  {
    // service any still-unbound request by doing a malloc
    for(std::vector<NetworkSegment *>::iterator it = segments.begin();
	it != segments.end();
	++it) {
      if(((*it)->bytes > 0) && ((*it)->base == 0)) {
	void *memptr;
	int ret = posix_memalign(&memptr,
				 std::max((*it)->alignment, sizeof(void *)),
				 (*it)->bytes);
	assert(ret == 0);
	(*it)->base = memptr;
	(*it)->add_rdma_info(this, &memptr, sizeof(void *));
      }
    }
  }

  // detaches from the network
  void LoopbackNetworkModule::detach(RuntimeImpl *runtime,
				     std::vector<NetworkSegment *>& segments)
  {
    // free any segment memory we allocated
    for(std::vector<NetworkSegment *>::iterator it = segments.begin();
	it != segments.end();
	++it) {
      const ByteArray *rdma_info = (*it)->get_rdma_info(this);
      if(rdma_info) {
	free((*it)->base);
	(*it)->base = 0;
      }
    }
  }

  // collective communication within this network
  void LoopbackNetworkModule::barrier(void)
  {
    // nothing to do
  }

  void LoopbackNetworkModule::broadcast(NodeID root,
					const void *val_in, void *val_out,
					size_t bytes)
  {
    memcpy(val_out, val_in, bytes);
  }

  void LoopbackNetworkModule::gather(NodeID root,
				     const void *val_in, void *vals_out,
				     size_t bytes)
  {
    memcpy(vals_out, val_in, bytes);
  }

  // used to create a remote proxy for a memory
  MemoryImpl *LoopbackNetworkModule::create_remote_memory(Memory m, size_t size, Memory::Kind kind,
							  const ByteArray& rdma_info)
  {
    // should never be called
    abort();
  }

  ActiveMessageImpl *LoopbackNetworkModule::create_active_message_impl(NodeID target,
								       unsigned short msgid,
								       size_t header_size,
								       size_t max_payload_size,
								       void *dest_payload_addr,
								       void *storage_base,
								       size_t storage_size)
  {
    // should never be called
    abort();
  }

  ActiveMessageImpl *LoopbackNetworkModule::create_active_message_impl(const NodeSet& targets,
								       unsigned short msgid,
								       size_t header_size,
								       size_t max_payload_size,
								       void *storage_base,
								       size_t storage_size)
  {
    // should never be called
    abort();
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class NetworkSegment
  //

  void NetworkSegment::add_rdma_info(NetworkModule *network,
				     const void *data, size_t len)
  {
    ByteArray& ba = networks[network];
    ba.set(data, len);
#ifdef REALM_USE_MULTIPLE_NETWORKS
#else
    assert(single_network == 0);
    single_network = network;
    single_network_data = &ba;
#endif
  }

  const ByteArray *NetworkSegment::get_rdma_info(NetworkModule *network) const
  {
    if(single_network == network) {
      return single_network_data;
    } else {
#ifdef REALM_USE_MULTIPLE_NETWORKS
      std::map<NetworkModule *, ByteArray>::iterator it = networks.find(network);
      if(it != networks.end())
	return &(it->second);
#endif
      return 0;
    }
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class ModuleRegistrar
  //

  namespace {
    ModuleRegistrar::NetworkRegistrationBase *network_modules_head = 0;
    ModuleRegistrar::NetworkRegistrationBase **network_modules_tail = &network_modules_head;
  };

  // called by the runtime during init - these may change the command line!
  void ModuleRegistrar::create_network_modules(std::vector<NetworkModule *>& modules,
					       int *argc, const char ***argv)
  {
    // iterate over the network module list, trying to create each module
    bool need_loopback = true;
    for(const NetworkRegistrationBase *nreg = network_modules_head;
	nreg;
	nreg = nreg->next) {
      NetworkModule *m = nreg->create_network_module(runtime, argc, argv);
      if(m) {
	modules.push_back(m);
#ifndef REALM_USE_MULTIPLE_NETWORKS
	assert(Network::single_network == 0);
#endif
	Network::single_network = m;
	need_loopback = false;
      }
    }

    if(need_loopback) {
      NetworkModule *m = LoopbackNetworkModule::create_network_module(runtime, argc, argv);
      assert(m != 0);
      modules.push_back(m);
      assert(Network::single_network == 0);
      Network::single_network = m;
    }
  }

  /*static*/ void ModuleRegistrar::add_network_registration(NetworkRegistrationBase *reg)
  {
    // done during init, so single-threaded
    *network_modules_tail = reg;
    network_modules_tail = &(reg->next);
  }

};
<commit_msg>realm: handle -ll:gsize in dummy network module<commit_after>/* Copyright 2019 Stanford University, NVIDIA Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Realm inter-node networking abstractions

#include "realm/network.h"
#include "realm/cmdline.h"

namespace Realm {

  namespace Network {
    NodeID my_node_id = 0;
    NodeID max_node_id = 0;
    NodeSet all_peers;
    NetworkModule *single_network = 0;
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class NetworkModule
  //

  NetworkModule::NetworkModule(const std::string& _name)
    : Module(_name)
  {}

  void NetworkModule::parse_command_line(RuntimeImpl *runtime,
					 std::vector<std::string>& cmdline)
  {}

  ////////////////////////////////////////////////////////////////////////
  //
  // class LoopbackNetworkModule
  //

  // used when there are no other networks

  class LoopbackNetworkModule : public NetworkModule {
  protected:
    LoopbackNetworkModule();

  public:
    static NetworkModule *create_network_module(RuntimeImpl *runtime,
						int *argc, const char ***argv);

    // actual parsing of the command line should wait until here if at all
    //  possible
    virtual void parse_command_line(RuntimeImpl *runtime,
				    std::vector<std::string>& cmdline);

    // "attaches" to the network, if that is meaningful - attempts to
    //  bind/register/(pick your network-specific verb) the requested memory
    //  segments with the network
    virtual void attach(RuntimeImpl *runtime,
			std::vector<NetworkSegment *>& segments);

    // detaches from the network
    virtual void detach(RuntimeImpl *runtime,
			std::vector<NetworkSegment *>& segments);

    // collective communication within this network
    virtual void barrier(void);
    virtual void broadcast(NodeID root,
			   const void *val_in, void *val_out, size_t bytes);
    virtual void gather(NodeID root,
			const void *val_in, void *vals_out, size_t bytes);

    // used to create a remote proxy for a memory
    virtual MemoryImpl *create_remote_memory(Memory m, size_t size, Memory::Kind kind,
					     const ByteArray& rdma_info);

    virtual ActiveMessageImpl *create_active_message_impl(NodeID target,
							  unsigned short msgid,
							  size_t header_size,
							  size_t max_payload_size,
							  void *dest_payload_addr,
							  void *storage_base,
							  size_t storage_size);

    virtual ActiveMessageImpl *create_active_message_impl(const NodeSet& targets,
							  unsigned short msgid,
							  size_t header_size,
							  size_t max_payload_size,
							  void *storage_base,
							  size_t storage_size);
  };

  LoopbackNetworkModule::LoopbackNetworkModule()
    : NetworkModule("loopback")
  {}

  /*static*/ NetworkModule *LoopbackNetworkModule::create_network_module(RuntimeImpl *runtime,
									 int *argc, const char ***argv)
  {
    return new LoopbackNetworkModule;
  }

  // actual parsing of the command line should wait until here if at all
  //  possible
  void LoopbackNetworkModule::parse_command_line(RuntimeImpl *runtime,
						 std::vector<std::string>& cmdline)
  {
    NetworkModule::parse_command_line(runtime, cmdline);

    size_t global_size = 0;
    CommandLineParser cp;
    cp.add_option_int_units("-ll:gsize", global_size, 'm');
    bool ok = cp.parse_command_line(cmdline);
    assert(ok);
    assert((global_size == 0) && "no global mem support in dummy network yet");
  }

  // "attaches" to the network, if that is meaningful - attempts to
  //  bind/register/(pick your network-specific verb) the requested memory
  //  segments with the network
  void LoopbackNetworkModule::attach(RuntimeImpl *runtime,
				     std::vector<NetworkSegment *>& segments)
  {
    // service any still-unbound request by doing a malloc
    for(std::vector<NetworkSegment *>::iterator it = segments.begin();
	it != segments.end();
	++it) {
      if(((*it)->bytes > 0) && ((*it)->base == 0)) {
	void *memptr;
	int ret = posix_memalign(&memptr,
				 std::max((*it)->alignment, sizeof(void *)),
				 (*it)->bytes);
	assert(ret == 0);
	(*it)->base = memptr;
	(*it)->add_rdma_info(this, &memptr, sizeof(void *));
      }
    }
  }

  // detaches from the network
  void LoopbackNetworkModule::detach(RuntimeImpl *runtime,
				     std::vector<NetworkSegment *>& segments)
  {
    // free any segment memory we allocated
    for(std::vector<NetworkSegment *>::iterator it = segments.begin();
	it != segments.end();
	++it) {
      const ByteArray *rdma_info = (*it)->get_rdma_info(this);
      if(rdma_info) {
	free((*it)->base);
	(*it)->base = 0;
      }
    }
  }

  // collective communication within this network
  void LoopbackNetworkModule::barrier(void)
  {
    // nothing to do
  }

  void LoopbackNetworkModule::broadcast(NodeID root,
					const void *val_in, void *val_out,
					size_t bytes)
  {
    memcpy(val_out, val_in, bytes);
  }

  void LoopbackNetworkModule::gather(NodeID root,
				     const void *val_in, void *vals_out,
				     size_t bytes)
  {
    memcpy(vals_out, val_in, bytes);
  }

  // used to create a remote proxy for a memory
  MemoryImpl *LoopbackNetworkModule::create_remote_memory(Memory m, size_t size, Memory::Kind kind,
							  const ByteArray& rdma_info)
  {
    // should never be called
    abort();
  }

  ActiveMessageImpl *LoopbackNetworkModule::create_active_message_impl(NodeID target,
								       unsigned short msgid,
								       size_t header_size,
								       size_t max_payload_size,
								       void *dest_payload_addr,
								       void *storage_base,
								       size_t storage_size)
  {
    // should never be called
    abort();
  }

  ActiveMessageImpl *LoopbackNetworkModule::create_active_message_impl(const NodeSet& targets,
								       unsigned short msgid,
								       size_t header_size,
								       size_t max_payload_size,
								       void *storage_base,
								       size_t storage_size)
  {
    // should never be called
    abort();
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class NetworkSegment
  //

  void NetworkSegment::add_rdma_info(NetworkModule *network,
				     const void *data, size_t len)
  {
    ByteArray& ba = networks[network];
    ba.set(data, len);
#ifdef REALM_USE_MULTIPLE_NETWORKS
#else
    assert(single_network == 0);
    single_network = network;
    single_network_data = &ba;
#endif
  }

  const ByteArray *NetworkSegment::get_rdma_info(NetworkModule *network) const
  {
    if(single_network == network) {
      return single_network_data;
    } else {
#ifdef REALM_USE_MULTIPLE_NETWORKS
      std::map<NetworkModule *, ByteArray>::iterator it = networks.find(network);
      if(it != networks.end())
	return &(it->second);
#endif
      return 0;
    }
  }

  ////////////////////////////////////////////////////////////////////////
  //
  // class ModuleRegistrar
  //

  namespace {
    ModuleRegistrar::NetworkRegistrationBase *network_modules_head = 0;
    ModuleRegistrar::NetworkRegistrationBase **network_modules_tail = &network_modules_head;
  };

  // called by the runtime during init - these may change the command line!
  void ModuleRegistrar::create_network_modules(std::vector<NetworkModule *>& modules,
					       int *argc, const char ***argv)
  {
    // iterate over the network module list, trying to create each module
    bool need_loopback = true;
    for(const NetworkRegistrationBase *nreg = network_modules_head;
	nreg;
	nreg = nreg->next) {
      NetworkModule *m = nreg->create_network_module(runtime, argc, argv);
      if(m) {
	modules.push_back(m);
#ifndef REALM_USE_MULTIPLE_NETWORKS
	assert(Network::single_network == 0);
#endif
	Network::single_network = m;
	need_loopback = false;
      }
    }

    if(need_loopback) {
      NetworkModule *m = LoopbackNetworkModule::create_network_module(runtime, argc, argv);
      assert(m != 0);
      modules.push_back(m);
      assert(Network::single_network == 0);
      Network::single_network = m;
    }
  }

  /*static*/ void ModuleRegistrar::add_network_registration(NetworkRegistrationBase *reg)
  {
    // done during init, so single-threaded
    *network_modules_tail = reg;
    network_modules_tail = &(reg->next);
  }

};
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Networks and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library 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 library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "kmeans_clustering_method.hpp"

#include <iostream>
#include <utility>
#include <vector>
#include "../common/exception.hpp"
#include "util.hpp"

using std::pair;
using std::vector;

namespace jubatus {
namespace core {
namespace clustering {

kmeans_clustering_method::kmeans_clustering_method(size_t k, uint32_t seed)
    : k_(k),
      seed_(seed),
      rand_(seed) {
}

kmeans_clustering_method::~kmeans_clustering_method() {
}

void kmeans_clustering_method::batch_update(wplist points) {
  if (points.empty()) {
    kcenters_.clear();
    return;
  }
  initialize_centers(points);
  do_batch_update(points);
}

void kmeans_clustering_method::initialize_centers(wplist& points) {
  if (points.size() < k_) {
    return;
  }
  kcenters_.clear();
  kcenters_.push_back(points[0].data);
  vector<double> weights;
  while (kcenters_.size() < k_) {
    weights.clear();
    for (wplist::iterator it = points.begin(); it != points.end(); ++it) {
      pair<int64_t, double> m = min_dist((*it).data, kcenters_);
      weights.push_back(m.second * it->weight);
    }
    discrete_distribution d(weights.begin(), weights.end(), rand_.next_int());
    kcenters_.push_back(points[d()].data);
  }
}

void kmeans_clustering_method::do_batch_update(wplist& points) {
  bool terminated = false;
  if (points.size() < k_) {
    return;
  }
  while (!terminated) {
    vector<common::sfv_t> kcenters_new(k_);
    vector<double> center_count(k_, 0);
    for (wplist::iterator it = points.begin(); it != points.end(); ++it) {
      pair<int64_t, double> m = min_dist((*it).data, kcenters_);
      scalar_mul_and_add(it->data, it->weight, kcenters_new[m.first]);
      center_count[m.first] += it->weight;
    }
    terminated = true;
    for (size_t i = 0; i < k_; ++i) {
      if (center_count[i] == 0) {
        kcenters_new[i] = kcenters_[i];
        continue;
      }
      kcenters_new[i] = scalar_dot(kcenters_new[i], 1.0 / center_count[i]);
      double d = dist(kcenters_new[i], kcenters_[i]);
      if (d > 1e-9) {
        terminated = false;
      }
    }
    kcenters_ = kcenters_new;
  }
}

void kmeans_clustering_method::online_update(wplist points) {
}

vector<common::sfv_t> kmeans_clustering_method::get_k_center() const {
  if (kcenters_.empty()) {
    throw JUBATUS_EXCEPTION(common::exception::runtime_error(
        "clustering is not performed yet"));
  }

  return kcenters_;
}

int64_t kmeans_clustering_method::get_nearest_center_index(
    const common::sfv_t& point) const {
  if (kcenters_.empty()) {
    throw JUBATUS_EXCEPTION(common::exception::runtime_error(
        "clustering is not performed yet"));
  }

  return min_dist(point, kcenters_).first;
}

common::sfv_t kmeans_clustering_method::get_nearest_center(
    const common::sfv_t& point) const {
  return kcenters_[get_nearest_center_index(point)];
}

wplist kmeans_clustering_method::get_cluster(
    size_t cluster_id,
    const wplist& points) const {
  if (cluster_id >= k_) {
    return wplist();
  }
  return get_clusters(points)[cluster_id];
}

vector<wplist> kmeans_clustering_method::get_clusters(
    const wplist& points) const {
  vector<wplist> ret(k_);
  for (wplist::const_iterator it = points.begin(); it != points.end(); ++it) {
    pair<int64_t, double> m = min_dist(it->data, kcenters_);
    ret[m.first].push_back(*it);
  }
  return ret;
}

}  // namespace clustering
}  // namespace core
}  // namespace jubatus
<commit_msg>Fix k-means to throw exception in get_core_members when clustering is not performed<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Networks and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library 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 library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "kmeans_clustering_method.hpp"

#include <iostream>
#include <utility>
#include <vector>
#include "../common/exception.hpp"
#include "util.hpp"

using std::pair;
using std::vector;

namespace jubatus {
namespace core {
namespace clustering {

kmeans_clustering_method::kmeans_clustering_method(size_t k, uint32_t seed)
    : k_(k),
      seed_(seed),
      rand_(seed) {
}

kmeans_clustering_method::~kmeans_clustering_method() {
}

void kmeans_clustering_method::batch_update(wplist points) {
  if (points.empty()) {
    kcenters_.clear();
    return;
  }
  initialize_centers(points);
  do_batch_update(points);
}

void kmeans_clustering_method::initialize_centers(wplist& points) {
  if (points.size() < k_) {
    return;
  }
  kcenters_.clear();
  kcenters_.push_back(points[0].data);
  vector<double> weights;
  while (kcenters_.size() < k_) {
    weights.clear();
    for (wplist::iterator it = points.begin(); it != points.end(); ++it) {
      pair<int64_t, double> m = min_dist((*it).data, kcenters_);
      weights.push_back(m.second * it->weight);
    }
    discrete_distribution d(weights.begin(), weights.end(), rand_.next_int());
    kcenters_.push_back(points[d()].data);
  }
}

void kmeans_clustering_method::do_batch_update(wplist& points) {
  bool terminated = false;
  if (points.size() < k_) {
    return;
  }
  while (!terminated) {
    vector<common::sfv_t> kcenters_new(k_);
    vector<double> center_count(k_, 0);
    for (wplist::iterator it = points.begin(); it != points.end(); ++it) {
      pair<int64_t, double> m = min_dist((*it).data, kcenters_);
      scalar_mul_and_add(it->data, it->weight, kcenters_new[m.first]);
      center_count[m.first] += it->weight;
    }
    terminated = true;
    for (size_t i = 0; i < k_; ++i) {
      if (center_count[i] == 0) {
        kcenters_new[i] = kcenters_[i];
        continue;
      }
      kcenters_new[i] = scalar_dot(kcenters_new[i], 1.0 / center_count[i]);
      double d = dist(kcenters_new[i], kcenters_[i]);
      if (d > 1e-9) {
        terminated = false;
      }
    }
    kcenters_ = kcenters_new;
  }
}

void kmeans_clustering_method::online_update(wplist points) {
}

vector<common::sfv_t> kmeans_clustering_method::get_k_center() const {
  if (kcenters_.empty()) {
    throw JUBATUS_EXCEPTION(common::exception::runtime_error(
        "clustering is not performed yet"));
  }

  return kcenters_;
}

int64_t kmeans_clustering_method::get_nearest_center_index(
    const common::sfv_t& point) const {
  if (kcenters_.empty()) {
    throw JUBATUS_EXCEPTION(common::exception::runtime_error(
        "clustering is not performed yet"));
  }

  return min_dist(point, kcenters_).first;
}

common::sfv_t kmeans_clustering_method::get_nearest_center(
    const common::sfv_t& point) const {
  return kcenters_[get_nearest_center_index(point)];
}

wplist kmeans_clustering_method::get_cluster(
    size_t cluster_id,
    const wplist& points) const {
  if (cluster_id >= k_) {
    return wplist();
  }
  return get_clusters(points)[cluster_id];
}

vector<wplist> kmeans_clustering_method::get_clusters(
    const wplist& points) const {
  if (kcenters_.empty()) {
    throw JUBATUS_EXCEPTION(common::exception::runtime_error(
        "clustering is not performed yet"));
  }

  vector<wplist> ret(k_);
  for (wplist::const_iterator it = points.begin(); it != points.end(); ++it) {
    pair<int64_t, double> m = min_dist(it->data, kcenters_);
    ret[m.first].push_back(*it);
  }
  return ret;
}

}  // namespace clustering
}  // namespace core
}  // namespace jubatus
<|endoftext|>