<commit_before>#include "ofApp.h"

//--------------------------------------------------------------

void ofApp::setup() {

    // Screen
    ofSetWindowTitle("beeeeeeeer");
    ofBackground(255);

    // Font
    mainFont.loadFont("font/Ostrich.ttf", 40);
    subFont.loadFont("font/Ostrich.ttf", 25);

    // Misc
    verbose = false;
    cellWidth  = 480;
    cellHeight = 360;

    // Camera
    camWidth = 640;
    camHeight = 480;
    cropWidth = camWidth/2;
    cropOffset = camWidth/4;
    nearBeer = 160;
    farBeer = 320;
    lineCounter = 0;

    tmpR = 0;
    tmpG = 0;
    tmpB = 0;

    vector<ofVideoDevice> devices = camera.listDevices();
    if(verbose) {
        for(int i = 0; i < devices.size(); i++){
            cout << devices[i].id << ": " << devices[i].deviceName;
            if( devices[i].bAvailable ){
                cout << endl;
            }
            else {
                cout << " - unavailable " << endl;
            }
        }
    }

	camera.setDeviceID(0);
	camera.setDesiredFrameRate(60);
    camera.setVerbose(true);
    camera.initGrabber(camWidth, camHeight);

    croppedCamera.allocate(cropWidth, camHeight, OF_IMAGE_COLOR_ALPHA);

    // Audio
    int bufferSize = 256;
	left.assign(bufferSize, 0.0);
	right.assign(bufferSize, 0.0);
	volHistory.assign(camWidth, 0.0);
	bufferCounter	= 0;
	drawCounter		= 0;
	smoothedVol     = 0.0;
	scaledVol		= 0.0;
	soundStream.setup(this, 0, 2, 44100, bufferSize, 4);
    soundStream.start();

    // FBOs
    averageLines.allocate(camWidth, camHeight, GL_RGBA);
    averageLines.begin();
        ofClear(255,255,255, 0);
    averageLines.end();

    sortedLines.allocate(camWidth, camHeight, GL_RGBA);
    sortedLines.begin();
        ofClear(255,255,255, 0);
    sortedLines.end();

    dataSet.allocate(camWidth, camHeight, GL_RGBA);
    dataSet.begin();
        ofClear(255,255,255, 0);
    dataSet.end();

    interpretivePanel.allocate(camWidth, camHeight, GL_RGBA);
    interpretivePanel.begin();
        ofClear(255,255,255, 0);
    interpretivePanel.end();

    audioFbo.allocate(camWidth, camHeight, GL_RGBA);
    audioFbo.begin();
        ofClear(255,255,255, 0);
    audioFbo.end();

    drawAvgLines = true;

    // Syphon
	mainOutputSyphonServer.setName("Screen Output");
	individualTextureSyphonServer.setName("Texture Output");
	mClient.setup();
    mClient.set("","Simple Server");

    tex.allocate(camWidth, camHeight, GL_RGBA);
    pixelArray.allocate(camWidth, camHeight, OF_PIXELS_RGBA);
    colorPixels = new unsigned char[640*480*4];

    cout << " -- END OF SETUP -- " << endl;
}

//--------------------------------------------------------------

void ofApp::update() {

    // Camera
    camera.update();
    if (camera.isFrameNew()){

        // Get Camera Pixels
        cameraPixels = camera.getPixels();

        // Pull Cam Pix & Crop
        tmpCamera.setFromPixels(cameraPixels, camWidth, camHeight, OF_IMAGE_COLOR);
        croppedCamera.setFromPixels(tmpCamera);
        croppedCamera.crop(cropOffset, 0, camWidth - cropWidth, camHeight);
        croppedCamera.resize(camWidth, camHeight);

        // Set CameraPix from Cropped Image
        cameraPixels = croppedCamera.getPixels();

        int totalPixels = camWidth * camHeight;
        lineCounter = 0;
        bool startAdding = false;

        // Get Average Colours
        for (int i = 0; i < totalPixels; i++) {

            // Adding Colors
            tmpR += cameraPixels[i*3];
            tmpG += cameraPixels[i*3+1];
            tmpB += cameraPixels[i*3+2];

            // Store Color
            if(i % camWidth == 0) {
                // get the average value
                tmpR = tmpR / camWidth;
                tmpG = tmpG / camWidth;
                tmpB = tmpB / camWidth;

                // Set Avg Colours To Color Array
                lineColors[lineCounter].r = tmpR;
                lineColors[lineCounter].g = tmpG;
                lineColors[lineCounter].b = tmpB;

                // Add Averages
                tmpR += tmpR;
                tmpG += tmpG;
                tmpB += tmpB;

                // Set Block Averages
                if(lineCounter % 10 == 0) {
                    blockColors[lineCounter/10].r = tmpR;
                    blockColors[lineCounter/10].g = tmpG;
                    blockColors[lineCounter/10].b = tmpB;
                }

                // Reset Temp Colors
                tmpR = 0;
                tmpG = 0;
                tmpB = 0;

                // Iterate
                lineCounter++;
            }
        }

        // Audio
        scaledVol = ofMap(smoothedVol, 0.0, 0.17, 0.0, 1.0, true);
        volHistory.push_back( scaledVol );
        if( volHistory.size() >= 400 ){
            volHistory.erase(volHistory.begin(), volHistory.begin()+1);
        }

        // Draw FBOs
        averageLines.begin();
            ofClear(128, 128, 128, 255);
            for(int i = 0; i < camHeight; i++) {
                ofSetColor(lineColors[i]);
                ofLine(0, i, camWidth, i);
            }
        averageLines.end();

        sortedLines.begin();
            ofClear(128, 128, 128, 255);
            for(int i = 0; i < camHeight/10; i++) {
                ofSetColor(blockColors[i]);
                ofRect(0, -10 + i*10, camWidth, -10 + i*10);
            }
        sortedLines.end();

        dataSet.begin();
            ofClear(0, 0, 0, 5);
            ofSetBackgroundColor(0);
            for(int i = 0; i < camHeight; i++) {
                if(i % 10 == 0) {
                    ofSetColor(lineColors[i].r, 0, 0);
                    char r = lineColors[i].r;
                    mainFont.drawString(ofToString(r), (i*2) + 15, lineCounter/5);

                    ofSetColor(0, lineColors[i].g, 0);
                    char g = lineColors[i].g;
                    mainFont.drawString(ofToString(g), (i*2) + 15, 150 + lineCounter/5);

                    ofSetColor(0, 0, lineColors[i].b);
                    char b = lineColors[i].b;
                    mainFont.drawString(ofToString(b), (i*2) + 15, 300 + lineCounter/5);
                }
            }
        dataSet.end();

        interpretivePanel.begin();
            ofClear(0, 0, 0, 255);
            ofSetBackgroundColor(0);

            ofSetColor(255);
            string title = "DECANTER";
            mainFont.drawString(title, camWidth/2 - 85, camHeight/2 - 50);

            ofSetColor(200);
            string subtitle = "- a generative audio alcoholic experience -";
            subFont.drawString(subtitle, camWidth/4 - 75, camHeight/2);
        interpretivePanel.end();

        audioFbo.begin();
            ofClear(0, 0, 0, 255);
            ofSetLineWidth(3);
            ofSetColor(245, 58, 135);

            ofBeginShape();
                for (unsigned int i = 0; i < left.size(); i++){
                    ofVertex(i*3, 100 -left[i]*180.0f);
                }
            ofEndShape(false);

            ofBeginShape();
                for (unsigned int i = 0; i < right.size(); i++){
                    ofVertex(i*3, 200 -right[i]*180.0f);
                }
            ofEndShape(false);

            ofBeginShape();
            for (unsigned int i = 0; i < volHistory.size(); i++){
                if( i == 0 ) ofVertex(i, camHeight);
                ofVertex(i, camHeight - volHistory[i] * 150);
                if( i == volHistory.size() -1 ) ofVertex(i, camHeight);
            }
            ofEndShape(false);

        audioFbo.end();

        // Texture For Syphon
        if(drawAvgLines) {
            averageLines.readToPixels(pixelArray);
        }
        else {
            sortedLines.readToPixels(pixelArray);
        }
        colorPixels =  pixelArray.getPixels();
        tex.loadData(colorPixels, 640, 480, GL_RGBA);

	}

}

//--------------------------------------------------------------

void ofApp::draw() {

    // Raw Camera
    ofSetColor(255);
    camera.draw(0, 0, cellWidth, cellHeight); // 0, 0  || TL

    // Average Colour Lines
    ofSetColor(255);
    averageLines.draw(cellWidth, 0, cellWidth, cellHeight); // 0, 0    || TC

    // Sorted Colour Lines
    ofSetColor(255);
    sortedLines.draw(cellWidth*2, 0, cellWidth, cellHeight); // 960, 0    || TR

    // Data Set
    ofSetColor(255);
    dataSet.draw(0, cellHeight, cellWidth, cellHeight); // 0, 360   || ML

    // Interpretive Text
    ofSetColor(255);
    interpretivePanel.draw(cellWidth, cellHeight, cellWidth, cellHeight); // 360, 360   || MC

    // Audio Waverform
    audioFbo.draw(cellWidth*2, cellHeight, cellWidth, cellHeight);

    // Cropped Camera
    //croppedCamera.draw(0, cellHeight, cellWidth, cellHeight); // 0, 360    || ML

    // Texture
    //tex.draw(cellWidth, cellHeight, cellWidth, cellHeight); // 480, 360    || MC

//    ofSetColor(255, 0, 0);
//    ofLine(ofGetWidth()/2, 0, ofGetWidth()/2, 720);

    // Syphon
	mainOutputSyphonServer.publishScreen();
    individualTextureSyphonServer.publishTexture(&tex);

    // Debug
    if(verbose) {
        ofSetColor(0);
        char fpsStr[255];
        sprintf(fpsStr, "frame rate: %f", ofGetFrameRate());
        ofDrawBitmapString(fpsStr, 50, ofGetWindowHeight() - 50);
    }

}

//--------------------------------------------------------------
void ofApp::audioIn(float * input, int bufferSize, int nChannels){

	float curVol = 0.0;
	int numCounted = 0;

	for (int i = 0; i < bufferSize; i++){
		left[i]		= input[i*2]*0.5;
		right[i]	= input[i*2+1]*0.5;

		curVol += left[i] * left[i];
		curVol += right[i] * right[i];
		numCounted+=2;
	}

	curVol /= (float)numCounted;
	curVol = sqrt( curVol );

	smoothedVol *= 0.93;
	smoothedVol += 0.07 * curVol;

	bufferCounter++;

}

//--------------------------------------------------------------

void ofApp::exit() {
    ofLogNotice("Exiting App");

    // Close Camera
    camera.close();

    // Close Audio
    soundStream.stop();
}

//--------------------------------------------------------------

void ofApp::keyPressed(int key){

    // Camera Settings
    if (key == 's' || key == 'S') {
		camera.videoSettings();
        //ofSaveFrame();
	}

    // FBO -> Syphon
    if (key == 'f' || key == 'F') {
		drawAvgLines = !drawAvgLines;
        cout << "DAL = " << ofToString(drawAvgLines) << endl;
    }

}

//--------------------------------------------------------------

void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------

void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------

void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------

void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------

void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------

void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------

void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------

void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>Exhibition State<commit_after>#include "ofApp.h"

//--------------------------------------------------------------

void ofApp::setup() {

    // Screen
    ofSetWindowTitle("beeeeeeeer");
    ofBackground(255);

    // Font
    mainFont.loadFont("font/Ostrich.ttf", 40);
    subFont.loadFont("font/Ostrich.ttf", 25);

    // Misc
    verbose = false;
    cellWidth  = 480;
    cellHeight = 360;

    // Camera
    camWidth = 640;
    camHeight = 480;

    nearBeer = 160;
    farBeer = 320;
    cropWidth = camWidth/2;
    cropOffset = nearBeer;
    lineCounter = 0;

    tmpR = 0;
    tmpG = 0;
    tmpB = 0;

    vector<ofVideoDevice> devices = camera.listDevices();
    if(verbose) {
        for(int i = 0; i < devices.size(); i++){
            cout << devices[i].id << ": " << devices[i].deviceName;
            if( devices[i].bAvailable ){
                cout << endl;
            }
            else {
                cout << " - unavailable " << endl;
            }
        }
    }

	camera.setDeviceID(0);
	camera.setDesiredFrameRate(60);
    camera.setVerbose(true);
    camera.initGrabber(camWidth, camHeight);

    croppedCamera.allocate(cropWidth, camHeight, OF_IMAGE_COLOR_ALPHA);

    // Audio
    int bufferSize = 256;
	left.assign(bufferSize, 0.0);
	right.assign(bufferSize, 0.0);
	volHistory.assign(camWidth, 0.0);
	bufferCounter	= 0;
	drawCounter		= 0;
	smoothedVol     = 0.0;
	scaledVol		= 0.0;
	soundStream.setup(this, 0, 2, 44100, bufferSize, 4);
    soundStream.start();

    // FBOs
    averageLines.allocate(camWidth, camHeight, GL_RGBA);
    averageLines.begin();
        ofClear(255,255,255, 0);
    averageLines.end();

    sortedLines.allocate(camWidth, camHeight, GL_RGBA);
    sortedLines.begin();
        ofClear(255,255,255, 0);
    sortedLines.end();

    dataSet.allocate(camWidth, camHeight, GL_RGBA);
    dataSet.begin();
        ofClear(255,255,255, 0);
    dataSet.end();

    interpretivePanel.allocate(camWidth, camHeight, GL_RGBA);
    interpretivePanel.begin();
        ofClear(255,255,255, 0);
    interpretivePanel.end();

    audioFbo.allocate(camWidth, camHeight, GL_RGBA);
    audioFbo.begin();
        ofClear(255,255,255, 0);
    audioFbo.end();

    drawAvgLines = true;

    // Syphon
	mainOutputSyphonServer.setName("Screen Output");
	individualTextureSyphonServer.setName("Texture Output");
	mClient.setup();
    mClient.set("","Simple Server");

    tex.allocate(camWidth, camHeight, GL_RGBA);
    pixelArray.allocate(camWidth, camHeight, OF_PIXELS_RGBA);
    colorPixels = new unsigned char[640*480*4];

    cout << " -- END OF SETUP -- " << endl;
}

//--------------------------------------------------------------

void ofApp::update() {

    // Camera
    camera.update();
    if (camera.isFrameNew()){

        // Get Camera Pixels
        cameraPixels = camera.getPixels();

        // Pull Cam Pix & Crop
        tmpCamera.setFromPixels(cameraPixels, camWidth, camHeight, OF_IMAGE_COLOR);
        croppedCamera.setFromPixels(tmpCamera);
        croppedCamera.crop(cropOffset, 0, camWidth - cropWidth, camHeight);
        croppedCamera.resize(camWidth, camHeight);

        // Set CameraPix from Cropped Image
        cameraPixels = croppedCamera.getPixels();

        int totalPixels = camWidth * camHeight;
        lineCounter = 0;
        bool startAdding = false;

        // Get Average Colours
        for (int i = 0; i < totalPixels; i++) {

            // Adding Colors
            tmpR += cameraPixels[i*3];
            tmpG += cameraPixels[i*3+1];
            tmpB += cameraPixels[i*3+2];

            // Store Color
            if(i % camWidth == 0) {
                // get the average value
                tmpR = tmpR / camWidth;
                tmpG = tmpG / camWidth;
                tmpB = tmpB / camWidth;

                // Set Avg Colours To Color Array
                lineColors[lineCounter].r = tmpR;
                lineColors[lineCounter].g = tmpG;
                lineColors[lineCounter].b = tmpB;

                // Add Averages
                tmpR += tmpR;
                tmpG += tmpG;
                tmpB += tmpB;

                // Set Block Averages
                if(lineCounter % 10 == 0) {
                    blockColors[lineCounter/10].r = tmpR;
                    blockColors[lineCounter/10].g = tmpG;
                    blockColors[lineCounter/10].b = tmpB;
                }

                // Reset Temp Colors
                tmpR = 0;
                tmpG = 0;
                tmpB = 0;

                // Iterate
                lineCounter++;
            }
        }

        // Audio
        scaledVol = ofMap(smoothedVol, 0.0, 0.17, 0.0, 1.0, true);
        volHistory.push_back( scaledVol );
        if( volHistory.size() >= 400 ){
            volHistory.erase(volHistory.begin(), volHistory.begin()+1);
        }

        // Draw FBOs
        averageLines.begin();
            ofClear(128, 128, 128, 255);
            for(int i = 0; i < camHeight; i++) {
                ofSetColor(lineColors[i]);
                ofLine(0, i, camWidth, i);
            }
        averageLines.end();

        sortedLines.begin();
            ofClear(128, 128, 128, 255);
            for(int i = 0; i < camHeight/10; i++) {
                ofSetColor(blockColors[i]);
                ofRect(0, -10 + i*10, camWidth, -10 + i*10);
            }
        sortedLines.end();

        dataSet.begin();
            ofClear(0, 0, 0, 5);
            ofSetBackgroundColor(0);
            for(int i = 0; i < camHeight; i++) {
                if(i % 10 == 0) {
                    ofSetColor(lineColors[i].r, 0, 0);
                    char r = lineColors[i].r;
                    mainFont.drawString(ofToString(r), (i*2) + 15, lineCounter/5);

                    ofSetColor(0, lineColors[i].g, 0);
                    char g = lineColors[i].g;
                    mainFont.drawString(ofToString(g), (i*2) + 15, 150 + lineCounter/5);

                    ofSetColor(0, 0, lineColors[i].b);
                    char b = lineColors[i].b;
                    mainFont.drawString(ofToString(b), (i*2) + 15, 300 + lineCounter/5);
                }
            }
        dataSet.end();

        interpretivePanel.begin();
            ofClear(0, 0, 0, 255);
            ofSetBackgroundColor(0);

            ofSetColor(255);
            string title = "DECANTER";
            mainFont.drawString(title, camWidth/2 - 85, camHeight/2 - 50);

            ofSetColor(200);
            string subtitle = "- a generative audio alcoholic experience -";
            subFont.drawString(subtitle, camWidth/4 - 75, camHeight/2);
        interpretivePanel.end();

        audioFbo.begin();
            ofClear(0, 0, 0, 255);
            ofSetLineWidth(3);
            ofSetColor(245, 58, 135);

            ofBeginShape();
                for (unsigned int i = 0; i < left.size(); i++){
                    ofVertex(i*3, 100 -left[i]*180.0f);
                }
            ofEndShape(false);

            ofBeginShape();
                for (unsigned int i = 0; i < right.size(); i++){
                    ofVertex(i*3, 200 -right[i]*180.0f);
                }
            ofEndShape(false);

            ofBeginShape();
            for (unsigned int i = 0; i < volHistory.size(); i++){
                if( i == 0 ) ofVertex(i, camHeight);
                ofVertex(i, camHeight - volHistory[i] * 150);
                if( i == volHistory.size() -1 ) ofVertex(i, camHeight);
            }
            ofEndShape(false);

        audioFbo.end();

        // Texture For Syphon
        if(drawAvgLines) {
            averageLines.readToPixels(pixelArray);
        }
        else {
            sortedLines.readToPixels(pixelArray);
        }
        colorPixels =  pixelArray.getPixels();
        tex.loadData(colorPixels, 640, 480, GL_RGBA);

	}

}

//--------------------------------------------------------------

void ofApp::draw() {

    // Raw Camera
    ofSetColor(255);
    camera.draw(0, 0, cellWidth, cellHeight); // 0, 0  || TL

    // Average Colour Lines
    ofSetColor(255);
    averageLines.draw(cellWidth, 0, cellWidth, cellHeight); // 0, 0    || TC

    // Sorted Colour Lines
    ofSetColor(255);
    sortedLines.draw(cellWidth*2, 0, cellWidth, cellHeight); // 960, 0    || TR

    // Data Set
    ofSetColor(255);
    //dataSet.draw(0, cellHeight, cellWidth, cellHeight); // 0, 360   || ML

    // Interpretive Text
    ofSetColor(255);
    interpretivePanel.draw(cellWidth, cellHeight, cellWidth, cellHeight); // 360, 360   || MC

    // Audio Waverform
    audioFbo.draw(cellWidth*2, cellHeight, cellWidth, cellHeight);

    // Cropped Camera
    croppedCamera.draw(0, cellHeight, cellWidth, cellHeight); // 0, 360    || ML

    // Texture
    //tex.draw(cellWidth, cellHeight, cellWidth, cellHeight); // 480, 360    || MC

//    ofSetColor(255, 0, 0);
//    ofLine(ofGetWidth()/2, 0, ofGetWidth()/2, 720);

    // Syphon
	mainOutputSyphonServer.publishScreen();
    individualTextureSyphonServer.publishTexture(&tex);

    // Debug
    if(verbose) {
        ofSetColor(0);
        char fpsStr[255];
        sprintf(fpsStr, "frame rate: %f", ofGetFrameRate());
        ofDrawBitmapString(fpsStr, 50, ofGetWindowHeight() - 50);
    }

}

//--------------------------------------------------------------
void ofApp::audioIn(float * input, int bufferSize, int nChannels){

	float curVol = 0.0;
	int numCounted = 0;

	for (int i = 0; i < bufferSize; i++){
		left[i]		= input[i*2]*0.5;
		right[i]	= input[i*2+1]*0.5;

		curVol += left[i] * left[i];
		curVol += right[i] * right[i];
		numCounted+=2;
	}

	curVol /= (float)numCounted;
	curVol = sqrt( curVol );

	smoothedVol *= 0.93;
	smoothedVol += 0.07 * curVol;

	bufferCounter++;

}

//--------------------------------------------------------------

void ofApp::exit() {
    ofLogNotice("Exiting App");

    // Close Camera
    camera.close();

    // Close Audio
    soundStream.stop();
}

//--------------------------------------------------------------

void ofApp::keyPressed(int key){

    // Camera Settings
    if (key == 's' || key == 'S') {
		camera.videoSettings();
        //ofSaveFrame();
	}

    // FBO -> Syphon
    if (key == 'f' || key == 'F') {
		drawAvgLines = !drawAvgLines;
        cout << "DAL = " << ofToString(drawAvgLines) << endl;
    }

}

//--------------------------------------------------------------

void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------

void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------

void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------

void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------

void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------

void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------

void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------

void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>


<commit_before>#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup()
{
	ofSetLogLevel(OF_LOG_VERBOSE);
	ofSetLogLevel("ofThread", OF_LOG_ERROR);
	ofSetVerticalSync(false);
	ofEnableAlphaBlending();

	doDrawInfo	= true;

	consoleListener.setup(this);

	omxCameraSettings.width = 640;
	omxCameraSettings.height = 480;
	omxCameraSettings.framerate = 15;
	omxCameraSettings.enableTexture = true;

	videoGrabber.setup(omxCameraSettings);
	filterCollection.setup();

	doShader = true;
	shader.load("shaderExample");

	//fbo.allocate(omxCameraSettings.width, omxCameraSettings.height);
	fbo.allocate(omxCameraSettings.width, omxCameraSettings.height);
	fbo.begin();
		ofClear(0, 0, 0, 0);
	fbo.end();
	// selfberry
	videoTexture.allocate(omxCameraSettings.width, omxCameraSettings.height, GL_RGB);

	bufferDir = "buffer";
	//uiBackground.init("ui.png");
	timeZero = ofGetElapsedTimeMicros();
	frameNumber = 0;
	slotRecording = 255;
	slotAmount = 4;
	if (dirSRC.doesDirectoryExist(bufferDir)) {
		dirSRC.removeDirectory(bufferDir, true);
	}
	if (!dirSRC.doesDirectoryExist("slot1")) {
		dirSRC.createDirectory("slot1");
	}
	if (!dirSRC.doesDirectoryExist("slot2")) {
		dirSRC.createDirectory("slot2");
	}
	if (!dirSRC.doesDirectoryExist("slot3")) {
		dirSRC.createDirectory("slot3");
	}
	if (!dirSRC.doesDirectoryExist("slot4")) {
		dirSRC.createDirectory("slot4");
	}
	if (!dirSRC.doesDirectoryExist("tmp")) {
		dirSRC.createDirectory("tmp");
	}
	dirSRC.createDirectory(bufferDir);
	indexSavedPhoto = 0;
	isRecording = false;
	amountOfFrames = 10;
	maxFrames = 10;

}

//--------------------------------------------------------------
void ofApp::update()
{
	if (!doShader || !videoGrabber.isFrameNew())
	{
		return;
	}
	fbo.begin();
		ofClear(0, 0, 0, 0);
		shader.begin();
			shader.setUniformTexture("tex0", videoGrabber.getTextureReference(), videoGrabber.getTextureID());
			shader.setUniform1f("time", ofGetElapsedTimef());
			shader.setUniform2f("resolution", ofGetWidth(), ofGetHeight());
			videoGrabber.draw();
		shader.end();
	fbo.end();
	if (isRecording == true) {
		dirSRC.createDirectory(bufferDir);
		dirSRC.listDir(bufferDir);
		recordedFramesAmount = dirSRC.size();
		ofLogNotice("AMOUNT OF FILES: "+ofToString(recordedFramesAmount)+"/"+ofToString(maxFrames));
		if (recordedFramesAmount == maxFrames) {
			isRecording = false;
			indexSavedPhoto = 0;
		}
		else {
			if (videoGrabber.isFrameNew()) {
				string filename;
				if (indexSavedPhoto < 10) filename = "seq00" + ofToString(indexSavedPhoto);
				if (indexSavedPhoto >= 10 && indexSavedPhoto < 100) filename = "seq0" + ofToString(indexSavedPhoto);
				if (indexSavedPhoto >= 100 && indexSavedPhoto < 1000) filename = "seq" + ofToString(indexSavedPhoto);
				// FBO TODO GETTEXTURE? videoTexture = videoGrabber.getTextureReference();
				fbo.readToPixels(pix);
				fbo.draw(0,0, omxCameraSettings.width, omxCameraSettings.height);
				//pix.resize(targetWidth, targetHeight, OF_INTERPOLATE_NEAREST_NEIGHBOR);
				savedImage.setFromPixels(pix);
				savedImage.setImageType(OF_IMAGE_COLOR);
				savedImage.saveImage("buffer//" + filename + ".tga");
				//omxCameraSettings.width, omxCameraSettings.height
				// add frame to gif encoder
				colorGifEncoder.addFrame(
					pix.getPixels(),
					640,
					480,
					pix.getBitsPerPixel()/*,
										 .1f duration */
				);
				/*colorGifEncoder.addFrame(
					pix.getPixels(),
					pix.getWidth(),
					pix.getHeight(),
					pix.getBitsPerPixel()
				);*/

				pix.clear();
				savedImage.clear();
				indexSavedPhoto++;
				if (indexSavedPhoto == (amountOfFrames + 1)) {
					isRecording = false;
					indexSavedPhoto = 0;
					saveGif();
				}
			}

		}
	}
}
void ofApp::saveGif()
{

	string fileName = ofToString(ofGetMonth()) + "-" + ofToString(ofGetDay()) + "-" + ofToString(ofGetHours()) + "-" + ofToString(ofGetMinutes()) + "-" + ofToString(ofGetSeconds());
	colorGifEncoder.save("gif//" + fileName + ".gif");
}

//--------------------------------------------------------------
void ofApp::draw(){

	if (doShader)
	{
		fbo.draw(0, 0);
	}else
	{
		videoGrabber.draw();
	}

	stringstream info;
	info << "APP FPS: " << ofGetFrameRate() << "\n";
	info << "Camera Resolution: " << videoGrabber.getWidth() << "x" << videoGrabber.getHeight()	<< " @ "<< videoGrabber.getFrameRate() <<"FPS"<< "\n";
	info << "CURRENT FILTER: " << filterCollection.getCurrentFilterName() << "\n";
	info << "SHADER ENABLED: " << doShader << "\n";
	//info <<	filterCollection.filterList << "\n";

	info << "\n";
	info << "Press e to increment filter" << "\n";
	info << "Press g to Toggle info" << "\n";
	info << "Press s to Toggle Shader" << "\n";

	if (doDrawInfo)
	{
		ofDrawBitmapStringHighlight(info.str(), 100, 100, ofColor::black, ofColor::yellow);
	}

	//
}

//--------------------------------------------------------------
void ofApp::keyPressed  (int key)
{
	ofLog(OF_LOG_VERBOSE, "%c keyPressed", key);
	ofLogNotice("PRESSED KEY: " + ofToString(key));
		/*RED 13 10
			WHITE 127 126
			YELLOW 54
			GREEN 357 65
			BLUE 50*/
	switch (key) {
		case 65:
			videoGrabber.setImageFilter(filterCollection.getNextFilter());
		break;
		case 10:
		case 13:
			if (!isRecording) {
				isRecording = true;
				indexSavedPhoto = 0;
				bufferDir = ofToString(ofGetMonth()) + "-" + ofToString(ofGetDay()) + "-" + ofToString(ofGetHours()) + "-" + ofToString(ofGetMinutes()) + "-" + ofToString(ofGetSeconds());
			}
		break;
		case 126:
			doDrawInfo = !doDrawInfo;
		break;
	}

	/*
	if (key == 's')
	{
		doShader = !doShader;
	}*/

}

void ofApp::onCharacterReceived(KeyListenerEventData& e)
{
	keyPressed((int)e.character);
}

<commit_msg>works!<commit_after>#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup()
{
	ofSetLogLevel(OF_LOG_VERBOSE);
	ofSetLogLevel("ofThread", OF_LOG_ERROR);
	ofSetVerticalSync(false);
	ofEnableAlphaBlending();

	doDrawInfo	= true;

	consoleListener.setup(this);

	omxCameraSettings.width = 640;
	omxCameraSettings.height = 480;
	omxCameraSettings.framerate = 15;
	omxCameraSettings.enableTexture = true;

	videoGrabber.setup(omxCameraSettings);
	filterCollection.setup();

	doShader = true;
	shader.load("shaderExample");

	//fbo.allocate(omxCameraSettings.width, omxCameraSettings.height);
	fbo.allocate(omxCameraSettings.width, omxCameraSettings.height);
	fbo.begin();
		ofClear(0, 0, 0, 0);
	fbo.end();
	// selfberry
	colorGifEncoder.setup(omxCameraSettings.width, omxCameraSettings.height, .2, 256);
	videoTexture.allocate(omxCameraSettings.width, omxCameraSettings.height, GL_RGB);

	bufferDir = "buffer";
	//uiBackground.init("ui.png");
	timeZero = ofGetElapsedTimeMicros();
	frameNumber = 0;
	slotRecording = 255;
	slotAmount = 4;
	if (dirSRC.doesDirectoryExist(bufferDir)) {
		dirSRC.removeDirectory(bufferDir, true);
	}
	if (!dirSRC.doesDirectoryExist("slot1")) {
		dirSRC.createDirectory("slot1");
	}
	if (!dirSRC.doesDirectoryExist("slot2")) {
		dirSRC.createDirectory("slot2");
	}
	if (!dirSRC.doesDirectoryExist("slot3")) {
		dirSRC.createDirectory("slot3");
	}
	if (!dirSRC.doesDirectoryExist("slot4")) {
		dirSRC.createDirectory("slot4");
	}
	if (!dirSRC.doesDirectoryExist("tmp")) {
		dirSRC.createDirectory("tmp");
	}
	dirSRC.createDirectory(bufferDir);
	indexSavedPhoto = 0;
	isRecording = false;
	amountOfFrames = 10;
	maxFrames = 10;

}

//--------------------------------------------------------------
void ofApp::update()
{
	if (!doShader || !videoGrabber.isFrameNew())
	{
		return;
	}
	fbo.begin();
		ofClear(0, 0, 0, 0);
		shader.begin();
			shader.setUniformTexture("tex0", videoGrabber.getTextureReference(), videoGrabber.getTextureID());
			shader.setUniform1f("time", ofGetElapsedTimef());
			shader.setUniform2f("resolution", ofGetWidth(), ofGetHeight());
			videoGrabber.draw();
		shader.end();
	fbo.end();
	if (isRecording == true) {
		dirSRC.createDirectory(bufferDir);
		dirSRC.listDir(bufferDir);
		recordedFramesAmount = dirSRC.size();
		ofLogNotice("AMOUNT OF FILES: "+ofToString(recordedFramesAmount)+"/"+ofToString(maxFrames));
		if (recordedFramesAmount == maxFrames) {
			isRecording = false;
			indexSavedPhoto = 0;
		}
		else {
			if (videoGrabber.isFrameNew()) {
				string filename;
				if (indexSavedPhoto < 10) filename = "seq00" + ofToString(indexSavedPhoto);
				if (indexSavedPhoto >= 10 && indexSavedPhoto < 100) filename = "seq0" + ofToString(indexSavedPhoto);
				if (indexSavedPhoto >= 100 && indexSavedPhoto < 1000) filename = "seq" + ofToString(indexSavedPhoto);
				// FBO TODO GETTEXTURE? videoTexture = videoGrabber.getTextureReference();
				fbo.readToPixels(pix);
				fbo.draw(0,0, omxCameraSettings.width, omxCameraSettings.height);
						ofLogNotice("AMOUNT OF FILES: "+ofToString(recordedFramesAmount)+"/"+ofToString(maxFrames));

				//pix.resize(targetWidth, targetHeight, OF_INTERPOLATE_NEAREST_NEIGHBOR);
				savedImage.setFromPixels(pix);
				savedImage.setImageType(OF_IMAGE_COLOR);
				savedImage.saveImage("buffer//" + filename + ".tga");
				//omxCameraSettings.width, omxCameraSettings.height
				// add frame to gif encoder
				colorGifEncoder.addFrame(
					pix.getPixels(),
					omxCameraSettings.width,
					omxCameraSettings.height,
					pix.getBitsPerPixel()/*,
										 .1f duration */
				);
				/*colorGifEncoder.addFrame(
					pix.getPixels(),
					pix.getWidth(),
					pix.getHeight(),
					pix.getBitsPerPixel()
				);*/
				recordedFramesAmount++;
				pix.clear();
				savedImage.clear();
				indexSavedPhoto++;
				if (indexSavedPhoto == (amountOfFrames + 1)) {
					isRecording = false;
					indexSavedPhoto = 0;
					saveGif();
				}
			}

		}
	}
}
void ofApp::saveGif()
{

	string fileName = ofToString(ofGetMonth()) + "-" + ofToString(ofGetDay()) + "-" + ofToString(ofGetHours()) + "-" + ofToString(ofGetMinutes()) + "-" + ofToString(ofGetSeconds());
	colorGifEncoder.save("gif//" + fileName + ".gif");
}

//--------------------------------------------------------------
void ofApp::draw(){

	if (doShader)
	{
		fbo.draw(0, 0);
	}else
	{
		videoGrabber.draw();
	}

	stringstream info;
	info << "APP FPS: " << ofGetFrameRate() << "\n";
	info << "Camera Resolution: " << videoGrabber.getWidth() << "x" << videoGrabber.getHeight()	<< " @ "<< videoGrabber.getFrameRate() <<"FPS"<< "\n";
	info << "CURRENT FILTER: " << filterCollection.getCurrentFilterName() << "\n";
	info << "SHADER ENABLED: " << doShader << "\n";
	//info <<	filterCollection.filterList << "\n";

	info << "\n";
	info << "Press e to increment filter" << "\n";
	info << "Press g to Toggle info" << "\n";
	info << "Press s to Toggle Shader" << "\n";

	if (doDrawInfo)
	{
		ofDrawBitmapStringHighlight(info.str(), 100, 100, ofColor::black, ofColor::yellow);
	}

	//
}

//--------------------------------------------------------------
void ofApp::keyPressed  (int key)
{
	ofLog(OF_LOG_VERBOSE, "%c keyPressed", key);
	ofLogNotice("PRESSED KEY: " + ofToString(key));
		/*RED 13 10
			WHITE 127 126
			YELLOW 54
			GREEN 357 65
			BLUE 50*/
	switch (key) {
		case 65:
			videoGrabber.setImageFilter(filterCollection.getNextFilter());
		break;
		case 10:
		case 13:
			if (!isRecording) {
				isRecording = true;
				indexSavedPhoto = 0;
				bufferDir = ofToString(ofGetMonth()) + "-" + ofToString(ofGetDay()) + "-" + ofToString(ofGetHours()) + "-" + ofToString(ofGetMinutes()) + "-" + ofToString(ofGetSeconds());
			}
		break;
		case 126:
			doDrawInfo = !doDrawInfo;
		break;
	}

	/*
	if (key == 's')
	{
		doShader = !doShader;
	}*/

}

void ofApp::onCharacterReceived(KeyListenerEventData& e)
{
	keyPressed((int)e.character);
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: filenotation.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2004-03-19 12:26:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SVTOOLS_FILENOTATION_HXX
#define SVTOOLS_FILENOTATION_HXX

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

//.........................................................................
namespace svt
{
//.........................................................................

    //=====================================================================
    //= OFileNotation
    //=====================================================================
    class OFileNotation
    {
    protected:
        ::rtl::OUString     m_sSystem;
        ::rtl::OUString     m_sFileURL;

    public:
        enum NOTATION
        {
            N_SYSTEM,
            N_URL
        };

        OFileNotation( const ::rtl::OUString& _rUrlOrPath );
        OFileNotation( const ::rtl::OUString& _rUrlOrPath, NOTATION _eInputNotation );

        ::rtl::OUString get(NOTATION _eOutputNotation);

    private:
        void    construct( const ::rtl::OUString& _rUrlOrPath );
        bool    implInitWithSystemNotation( const ::rtl::OUString& _rSystemPath );
        bool    implInitWithURLNotation( const ::rtl::OUString& _rURL );
    };

//.........................................................................
}   // namespace svt
//.........................................................................

#endif // SVTOOLS_FILENOTATION_HXX

<commit_msg>INTEGRATION: CWS visibility03 (1.2.406); FILE MERGED 2005/03/24 14:13:39 mhu 1.2.406.1: #i45006# Include svtools/(svl|svt)dllapi.h, declare symbol visibility with (SVL|SVT)_DLL(PUBLIC|PRIVATE) as appropriate; partial cleanup.<commit_after>/*************************************************************************
 *
 *  $RCSfile: filenotation.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2005-04-13 10:07:51 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SVTOOLS_FILENOTATION_HXX
#define SVTOOLS_FILENOTATION_HXX

#ifndef INCLUDED_SVLDLLAPI_H
#include "svtools/svldllapi.h"
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

//.........................................................................
namespace svt
{
//.........................................................................

    //=====================================================================
    //= OFileNotation
    //=====================================================================
    class SVL_DLLPUBLIC OFileNotation
    {
    protected:
        ::rtl::OUString     m_sSystem;
        ::rtl::OUString     m_sFileURL;

    public:
        enum NOTATION
        {
            N_SYSTEM,
            N_URL
        };

        OFileNotation( const ::rtl::OUString& _rUrlOrPath );
        OFileNotation( const ::rtl::OUString& _rUrlOrPath, NOTATION _eInputNotation );

        ::rtl::OUString get(NOTATION _eOutputNotation);

    private:
        SVL_DLLPRIVATE void construct( const ::rtl::OUString& _rUrlOrPath );
        SVL_DLLPRIVATE bool    implInitWithSystemNotation( const ::rtl::OUString& _rSystemPath );
        SVL_DLLPRIVATE bool    implInitWithURLNotation( const ::rtl::OUString& _rURL );
    };

//.........................................................................
}   // namespace svt
//.........................................................................

#endif // SVTOOLS_FILENOTATION_HXX

<|endoftext|>


<commit_before>/*
 * (C) Copyright 2015 ETH Zurich Systems Group (http://www.systems.ethz.ch/) and others.
 *
 * 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.
 *
 * Contributors:
 *     Markus Pilman <mpilman@inf.ethz.ch>
 *     Simon Loesing <sloesing@inf.ethz.ch>
 *     Thomas Etter <etterth@gmail.com>
 *     Kevin Bocksrocker <kevin.bocksrocker@gmail.com>
 *     Lucas Braun <braunl@inf.ethz.ch>
 */
#include <crossbow/program_options.hpp>
#include <crossbow/logger.hpp>

#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#include <string>
#include <iostream>
#include <cassert>
#include <fstream>

#include "Client.hpp"

using namespace crossbow::program_options;
using namespace boost::asio;
using err_code = boost::system::error_code;

std::vector<std::string> split(const std::string str, const char delim) {
    std::stringstream ss(str);
    std::string item;
    std::vector<std::string> result;
    while (std::getline(ss, item, delim)) {
        if (item.empty()) continue;
        result.push_back(std::move(item));
    }
    return result;
}

int main(int argc, const char** argv) {
    bool help = false;
    bool populate = false;
    int16_t numWarehouses = 1;
    std::string host;
    std::string port("8713");
    std::string logLevel("DEBUG");
    std::string outFile("out.csv");
    size_t numClients = 1;
    unsigned time = 5*60;
    auto opts = create_options("tpcc_server",
            value<'h'>("help", &help, tag::description{"print help"})
            , value<'H'>("host", &host, tag::description{"Comma-separated list of hosts"})
            , value<'l'>("log-level", &logLevel, tag::description{"The log level"})
            , value<'c'>("num-clients", &numClients, tag::description{"Number of Clients to run per host"})
            , value<'P'>("populate", &populate, tag::description{"Populate the database"})
            , value<'W'>("num-warehouses", &numWarehouses, tag::description{"Number of warehouses"})
            , value<'t'>("time", &time, tag::description{"Duration of the benchmark in seconds"})
            , value<'o'>("out", &outFile, tag::description{"Path to the output file"})
            );
    try {
        parse(opts, argc, argv);
    } catch (argument_not_found& e) {
        std::cerr << e.what() << std::endl << std::endl;
        print_help(std::cout, opts);
        return 1;
    }
    if (help) {
        print_help(std::cout, opts);
        return 0;
    }
    if (host.empty()) {
        std::cerr << "No host\n";
        return 1;
    }
    auto startTime = tpcc::Clock::now();
    auto endTime = startTime + std::chrono::seconds(time);
    crossbow::logger::logger->config.level = crossbow::logger::logLevelFromString(logLevel);
    try {
        auto hosts = split(host, ',');
        io_service service;
        auto sumClients = hosts.size() * numClients;
        std::vector<tpcc::Client> clients;
        clients.reserve(sumClients);
        auto wareHousesPerClient = numWarehouses / sumClients;
        for (decltype(sumClients) i = 0; i < sumClients; ++i) {
            if (i >= unsigned(numWarehouses)) break;
            clients.emplace_back(service, numWarehouses, int16_t(wareHousesPerClient * i + 1), int16_t(wareHousesPerClient * (i + 1)), endTime);
        }
        for (size_t i = 0; i < hosts.size(); ++i) {
            auto h = hosts[i];
            auto addr = split(h, ':');
            assert(addr.size() <= 2);
            auto p = addr.size() == 2 ? addr[1] : port;
            ip::tcp::resolver resolver(service);
            ip::tcp::resolver::iterator iter;
            if (host == "") {
                iter = resolver.resolve(ip::tcp::resolver::query(port));
            } else {
                iter = resolver.resolve(ip::tcp::resolver::query(host, port));
            }
            for (unsigned j = 0; j < numClients; ++j) {
                LOG_INFO("Connected to client " + crossbow::to_string(i*numClients + j));
                boost::asio::connect(clients[i*numClients + j].socket(), iter);
            }
        }
        if (populate) {
            auto& cmds = clients[0].commands();
            cmds.execute<tpcc::Command::CREATE_SCHEMA>(
                    [&clients, numClients, wareHousesPerClient, numWarehouses](const err_code& ec,
                        const std::tuple<bool, crossbow::string>& res){
                if (ec) {
                    LOG_ERROR(ec.message());
                    return;
                }
                if (!std::get<0>(res)) {
                    LOG_ERROR(std::get<1>(res));
                    return;
                }
                for (auto& client : clients) {
                    client.populate();
                }
            });
        } else {
            for (decltype(clients.size()) i = 0; i < clients.size(); ++i) {
                auto& client = clients[i];
                client.run();
            }
        }
        service.run();
        LOG_INFO("Done, writing results");
        std::ofstream out(outFile.c_str());
        out << "start,end,transaction,success,error\n";
        for (const auto& client : clients) {
            const auto& queue = client.log();
            for (const auto& e : queue) {
                crossbow::string tName;
                switch (e.transaction) {
                case tpcc::Command::POPULATE_WAREHOUSE:
                    tName = "Populate";
                    break;
                case tpcc::Command::POPULATE_ITEMS:
                    tName = "Populate";
                    break;
                case tpcc::Command::CREATE_SCHEMA:
                    tName = "Schema Create";
                    break;
                case tpcc::Command::STOCK_LEVEL:
                    tName = "Stock Level";
                    break;
                case tpcc::Command::DELIVERY:
                    tName = "Delivery";
                    break;
                case tpcc::Command::NEW_ORDER:
                    tName = "New Order";
                    break;
                case tpcc::Command::ORDER_STATUS:
                    tName = "Order Status";
                    break;
                case tpcc::Command::PAYMENT:
                    tName = "Payment";
                    break;
                }
                out << std::chrono::duration_cast<std::chrono::seconds>(e.start - startTime).count()
                    << std::chrono::duration_cast<std::chrono::seconds>(e.end - startTime).count()
                    << tName
                    << (e.success ? "true" : "false")
                    << e.error
                    << std::endl;
            }
        }
    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
    }
}
<commit_msg>Fix printing of out file<commit_after>/*
 * (C) Copyright 2015 ETH Zurich Systems Group (http://www.systems.ethz.ch/) and others.
 *
 * 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.
 *
 * Contributors:
 *     Markus Pilman <mpilman@inf.ethz.ch>
 *     Simon Loesing <sloesing@inf.ethz.ch>
 *     Thomas Etter <etterth@gmail.com>
 *     Kevin Bocksrocker <kevin.bocksrocker@gmail.com>
 *     Lucas Braun <braunl@inf.ethz.ch>
 */
#include <crossbow/program_options.hpp>
#include <crossbow/logger.hpp>

#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#include <string>
#include <iostream>
#include <cassert>
#include <fstream>

#include "Client.hpp"

using namespace crossbow::program_options;
using namespace boost::asio;
using err_code = boost::system::error_code;

std::vector<std::string> split(const std::string str, const char delim) {
    std::stringstream ss(str);
    std::string item;
    std::vector<std::string> result;
    while (std::getline(ss, item, delim)) {
        if (item.empty()) continue;
        result.push_back(std::move(item));
    }
    return result;
}

int main(int argc, const char** argv) {
    bool help = false;
    bool populate = false;
    int16_t numWarehouses = 1;
    std::string host;
    std::string port("8713");
    std::string logLevel("DEBUG");
    std::string outFile("out.csv");
    size_t numClients = 1;
    unsigned time = 5*60;
    auto opts = create_options("tpcc_server",
            value<'h'>("help", &help, tag::description{"print help"})
            , value<'H'>("host", &host, tag::description{"Comma-separated list of hosts"})
            , value<'l'>("log-level", &logLevel, tag::description{"The log level"})
            , value<'c'>("num-clients", &numClients, tag::description{"Number of Clients to run per host"})
            , value<'P'>("populate", &populate, tag::description{"Populate the database"})
            , value<'W'>("num-warehouses", &numWarehouses, tag::description{"Number of warehouses"})
            , value<'t'>("time", &time, tag::description{"Duration of the benchmark in seconds"})
            , value<'o'>("out", &outFile, tag::description{"Path to the output file"})
            );
    try {
        parse(opts, argc, argv);
    } catch (argument_not_found& e) {
        std::cerr << e.what() << std::endl << std::endl;
        print_help(std::cout, opts);
        return 1;
    }
    if (help) {
        print_help(std::cout, opts);
        return 0;
    }
    if (host.empty()) {
        std::cerr << "No host\n";
        return 1;
    }
    auto startTime = tpcc::Clock::now();
    auto endTime = startTime + std::chrono::seconds(time);
    crossbow::logger::logger->config.level = crossbow::logger::logLevelFromString(logLevel);
    try {
        auto hosts = split(host, ',');
        io_service service;
        auto sumClients = hosts.size() * numClients;
        std::vector<tpcc::Client> clients;
        clients.reserve(sumClients);
        auto wareHousesPerClient = numWarehouses / sumClients;
        for (decltype(sumClients) i = 0; i < sumClients; ++i) {
            if (i >= unsigned(numWarehouses)) break;
            clients.emplace_back(service, numWarehouses, int16_t(wareHousesPerClient * i + 1), int16_t(wareHousesPerClient * (i + 1)), endTime);
        }
        for (size_t i = 0; i < hosts.size(); ++i) {
            auto h = hosts[i];
            auto addr = split(h, ':');
            assert(addr.size() <= 2);
            auto p = addr.size() == 2 ? addr[1] : port;
            ip::tcp::resolver resolver(service);
            ip::tcp::resolver::iterator iter;
            if (host == "") {
                iter = resolver.resolve(ip::tcp::resolver::query(port));
            } else {
                iter = resolver.resolve(ip::tcp::resolver::query(host, port));
            }
            for (unsigned j = 0; j < numClients; ++j) {
                LOG_INFO("Connected to client " + crossbow::to_string(i*numClients + j));
                boost::asio::connect(clients[i*numClients + j].socket(), iter);
            }
        }
        if (populate) {
            auto& cmds = clients[0].commands();
            cmds.execute<tpcc::Command::CREATE_SCHEMA>(
                    [&clients, numClients, wareHousesPerClient, numWarehouses](const err_code& ec,
                        const std::tuple<bool, crossbow::string>& res){
                if (ec) {
                    LOG_ERROR(ec.message());
                    return;
                }
                if (!std::get<0>(res)) {
                    LOG_ERROR(std::get<1>(res));
                    return;
                }
                for (auto& client : clients) {
                    client.populate();
                }
            });
        } else {
            for (decltype(clients.size()) i = 0; i < clients.size(); ++i) {
                auto& client = clients[i];
                client.run();
            }
        }
        service.run();
        LOG_INFO("Done, writing results");
        std::ofstream out(outFile.c_str());
        out << "start,end,transaction,success,error\n";
        for (const auto& client : clients) {
            const auto& queue = client.log();
            for (const auto& e : queue) {
                crossbow::string tName;
                switch (e.transaction) {
                case tpcc::Command::POPULATE_WAREHOUSE:
                    tName = "Populate";
                    break;
                case tpcc::Command::POPULATE_ITEMS:
                    tName = "Populate";
                    break;
                case tpcc::Command::CREATE_SCHEMA:
                    tName = "Schema Create";
                    break;
                case tpcc::Command::STOCK_LEVEL:
                    tName = "Stock Level";
                    break;
                case tpcc::Command::DELIVERY:
                    tName = "Delivery";
                    break;
                case tpcc::Command::NEW_ORDER:
                    tName = "New Order";
                    break;
                case tpcc::Command::ORDER_STATUS:
                    tName = "Order Status";
                    break;
                case tpcc::Command::PAYMENT:
                    tName = "Payment";
                    break;
                }
                out << std::chrono::duration_cast<std::chrono::seconds>(e.start - startTime).count() << ','
                    << std::chrono::duration_cast<std::chrono::seconds>(e.end - startTime).count() << ','
                    << tName << ','
                    << (e.success ? "true" : "false") << ','
                    << e.error << std::endl;
            }
        }
    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/message_box.h"

#include <windows.h>
#include <commctrl.h>

#include <map>
#include <vector>

#include "atom/browser/browser.h"
#include "atom/browser/native_window_views.h"
#include "base/callback.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/win/scoped_gdi_object.h"
#include "content/public/browser/browser_thread.h"
#include "ui/gfx/icon_util.h"

namespace atom {

namespace {

// Small command ID values are already taken by Windows, we have to start from
// a large number to avoid conflicts with Windows.
const int kIDStart = 100;

// Get the common ID from button's name.
struct CommonButtonID {
  int button;
  int id;
};
CommonButtonID GetCommonID(const base::string16& button) {
  base::string16 lower = base::StringToLowerASCII(button);
  if (lower == L"ok")
    return { TDCBF_OK_BUTTON, IDOK };
  else if (lower == L"yes")
    return { TDCBF_YES_BUTTON, IDYES };
  else if (lower == L"no")
    return { TDCBF_NO_BUTTON, IDNO };
  else if (lower == L"cancel")
    return { TDCBF_CANCEL_BUTTON, IDCANCEL };
  else if (lower == L"retry")
    return { TDCBF_RETRY_BUTTON, IDRETRY };
  else if (lower == L"close")
    return { TDCBF_CLOSE_BUTTON, IDCLOSE };
  return { -1, -1 };
}

// Determine whether the buttons are common buttons, if so map common ID
// to button ID.
void MapToCommonID(const std::vector<base::string16>& buttons,
                   std::map<int, int>* id_map,
                   TASKDIALOG_COMMON_BUTTON_FLAGS* button_flags,
                   std::vector<TASKDIALOG_BUTTON>* dialog_buttons) {
  for (size_t i = 0; i < buttons.size(); ++i) {
    auto common = GetCommonID(buttons[i]);
    if (common.button != -1) {
      // It is a common button.
      (*id_map)[common.id] = i;
      (*button_flags) |= common.button;
    } else {
      // It is a custom button.
      dialog_buttons->push_back({i + kIDStart, buttons[i].c_str()});
    }
  }
}

int ShowMessageBoxUTF16(HWND parent,
                        MessageBoxType type,
                        const std::vector<base::string16>& buttons,
                        int cancel_id,
                        int options,
                        const base::string16& title,
                        const base::string16& message,
                        const base::string16& detail,
                        const gfx::ImageSkia& icon) {
  TASKDIALOG_FLAGS flags =
      TDF_SIZE_TO_CONTENT | // Show all content.
      TDF_ALLOW_DIALOG_CANCELLATION; // Allow canceling the dialog.

  TASKDIALOGCONFIG config = { 0 };
  config.cbSize     = sizeof(config);
  config.hwndParent = parent;
  config.hInstance  = GetModuleHandle(NULL);
  config.dwFlags    = flags;

  // TaskDialogIndirect doesn't allow empty name, if we set empty title it
  // will show "electron.exe" in title.
  base::string16 app_name = base::UTF8ToUTF16(Browser::Get()->GetName());
  if (title.empty())
    config.pszWindowTitle = app_name.c_str();
  else
    config.pszWindowTitle = title.c_str();

  base::win::ScopedHICON hicon;
  if (!icon.isNull()) {
    hicon.Set(IconUtil::CreateHICONFromSkBitmap(*icon.bitmap()));
    config.dwFlags |= TDF_USE_HICON_MAIN;
    config.hMainIcon = hicon.Get();
  } else {
    // Show icon according to dialog's type.
    switch (type) {
      case MESSAGE_BOX_TYPE_INFORMATION:
      case MESSAGE_BOX_TYPE_QUESTION:
        config.pszMainIcon = TD_INFORMATION_ICON;
        break;
      case MESSAGE_BOX_TYPE_WARNING:
        config.pszMainIcon = TD_WARNING_ICON;
        break;
      case MESSAGE_BOX_TYPE_ERROR:
        config.pszMainIcon = TD_ERROR_ICON;
        break;
    }
  }

  // If "detail" is empty then don't make message hilighted.
  if (detail.empty()) {
    config.pszContent = message.c_str();
  } else {
    config.pszMainInstruction = message.c_str();
    config.pszContent = detail.c_str();
  }

  // Iterate through the buttons, put common buttons in dwCommonButtons
  // and custom buttons in pButtons.
  std::map<int, int> id_map;
  std::vector<TASKDIALOG_BUTTON> dialog_buttons;
  if (options & MESSAGE_BOX_NO_LINK) {
    for (size_t i = 0; i < buttons.size(); ++i)
      dialog_buttons.push_back({i + kIDStart, buttons[i].c_str()});
  } else {
    MapToCommonID(buttons, &id_map, &config.dwCommonButtons, &dialog_buttons);
  }
  if (dialog_buttons.size() > 0) {
    config.pButtons = &dialog_buttons.front();
    config.cButtons = dialog_buttons.size();
    if (!(options & MESSAGE_BOX_NO_LINK))
      config.dwFlags |= TDF_USE_COMMAND_LINKS;  // custom buttons as links.
  }

  int id = 0;
  TaskDialogIndirect(&config, &id, NULL, NULL);
  if (id_map.find(id) != id_map.end())  // common button.
    return id_map[id];
  else if (id >= kIDStart)  // custom button.
    return id - kIDStart;
  else
    return cancel_id;
}

void RunMessageBoxInNewThread(base::Thread* thread,
                              NativeWindow* parent,
                              MessageBoxType type,
                              const std::vector<std::string>& buttons,
                              int cancel_id,
                              int options,
                              const std::string& title,
                              const std::string& message,
                              const std::string& detail,
                              const gfx::ImageSkia& icon,
                              const MessageBoxCallback& callback) {
  int result = ShowMessageBox(parent, type, buttons, cancel_id, options, title,
                              message, detail, icon);
  content::BrowserThread::PostTask(
      content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
  content::BrowserThread::DeleteSoon(
      content::BrowserThread::UI, FROM_HERE, thread);
}

}  // namespace

int ShowMessageBox(NativeWindow* parent,
                   MessageBoxType type,
                   const std::vector<std::string>& buttons,
                   int cancel_id,
                   int options,
                   const std::string& title,
                   const std::string& message,
                   const std::string& detail,
                   const gfx::ImageSkia& icon) {
  std::vector<base::string16> utf16_buttons;
  for (const auto& button : buttons)
    utf16_buttons.push_back(base::UTF8ToUTF16(button));

  HWND hwnd_parent = parent ?
      static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() :
      NULL;

  NativeWindow::DialogScope dialog_scope(parent);
  return ShowMessageBoxUTF16(hwnd_parent,
                             type,
                             utf16_buttons,
                             cancel_id,
                             options,
                             base::UTF8ToUTF16(title),
                             base::UTF8ToUTF16(message),
                             base::UTF8ToUTF16(detail),
                             icon);
}

void ShowMessageBox(NativeWindow* parent,
                    MessageBoxType type,
                    const std::vector<std::string>& buttons,
                    int cancel_id,
                    int options,
                    const std::string& title,
                    const std::string& message,
                    const std::string& detail,
                    const gfx::ImageSkia& icon,
                    const MessageBoxCallback& callback) {
  scoped_ptr<base::Thread> thread(
      new base::Thread(ATOM_PRODUCT_NAME "MessageBoxThread"));
  thread->init_com_with_mta(false);
  if (!thread->Start()) {
    callback.Run(cancel_id);
    return;
  }

  base::Thread* unretained = thread.release();
  unretained->message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained),
                 parent, type, buttons, cancel_id, options, title, message,
                 detail, icon, callback));
}

void ShowErrorBox(const base::string16& title, const base::string16& content) {
  ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, 0, 0, L"Error", title,
                      content, gfx::ImageSkia());
}

}  // namespace atom
<commit_msg>Fixed comment spacing<commit_after>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/message_box.h"

#include <windows.h>
#include <commctrl.h>

#include <map>
#include <vector>

#include "atom/browser/browser.h"
#include "atom/browser/native_window_views.h"
#include "base/callback.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/win/scoped_gdi_object.h"
#include "content/public/browser/browser_thread.h"
#include "ui/gfx/icon_util.h"

namespace atom {

namespace {

// Small command ID values are already taken by Windows, we have to start from
// a large number to avoid conflicts with Windows.
const int kIDStart = 100;

// Get the common ID from button's name.
struct CommonButtonID {
  int button;
  int id;
};
CommonButtonID GetCommonID(const base::string16& button) {
  base::string16 lower = base::StringToLowerASCII(button);
  if (lower == L"ok")
    return { TDCBF_OK_BUTTON, IDOK };
  else if (lower == L"yes")
    return { TDCBF_YES_BUTTON, IDYES };
  else if (lower == L"no")
    return { TDCBF_NO_BUTTON, IDNO };
  else if (lower == L"cancel")
    return { TDCBF_CANCEL_BUTTON, IDCANCEL };
  else if (lower == L"retry")
    return { TDCBF_RETRY_BUTTON, IDRETRY };
  else if (lower == L"close")
    return { TDCBF_CLOSE_BUTTON, IDCLOSE };
  return { -1, -1 };
}

// Determine whether the buttons are common buttons, if so map common ID
// to button ID.
void MapToCommonID(const std::vector<base::string16>& buttons,
                   std::map<int, int>* id_map,
                   TASKDIALOG_COMMON_BUTTON_FLAGS* button_flags,
                   std::vector<TASKDIALOG_BUTTON>* dialog_buttons) {
  for (size_t i = 0; i < buttons.size(); ++i) {
    auto common = GetCommonID(buttons[i]);
    if (common.button != -1) {
      // It is a common button.
      (*id_map)[common.id] = i;
      (*button_flags) |= common.button;
    } else {
      // It is a custom button.
      dialog_buttons->push_back({i + kIDStart, buttons[i].c_str()});
    }
  }
}

int ShowMessageBoxUTF16(HWND parent,
                        MessageBoxType type,
                        const std::vector<base::string16>& buttons,
                        int cancel_id,
                        int options,
                        const base::string16& title,
                        const base::string16& message,
                        const base::string16& detail,
                        const gfx::ImageSkia& icon) {
  TASKDIALOG_FLAGS flags =
      TDF_SIZE_TO_CONTENT |  // Show all content.
      TDF_ALLOW_DIALOG_CANCELLATION;  // Allow canceling the dialog.

  TASKDIALOGCONFIG config = { 0 };
  config.cbSize     = sizeof(config);
  config.hwndParent = parent;
  config.hInstance  = GetModuleHandle(NULL);
  config.dwFlags    = flags;

  // TaskDialogIndirect doesn't allow empty name, if we set empty title it
  // will show "electron.exe" in title.
  base::string16 app_name = base::UTF8ToUTF16(Browser::Get()->GetName());
  if (title.empty())
    config.pszWindowTitle = app_name.c_str();
  else
    config.pszWindowTitle = title.c_str();

  base::win::ScopedHICON hicon;
  if (!icon.isNull()) {
    hicon.Set(IconUtil::CreateHICONFromSkBitmap(*icon.bitmap()));
    config.dwFlags |= TDF_USE_HICON_MAIN;
    config.hMainIcon = hicon.Get();
  } else {
    // Show icon according to dialog's type.
    switch (type) {
      case MESSAGE_BOX_TYPE_INFORMATION:
      case MESSAGE_BOX_TYPE_QUESTION:
        config.pszMainIcon = TD_INFORMATION_ICON;
        break;
      case MESSAGE_BOX_TYPE_WARNING:
        config.pszMainIcon = TD_WARNING_ICON;
        break;
      case MESSAGE_BOX_TYPE_ERROR:
        config.pszMainIcon = TD_ERROR_ICON;
        break;
    }
  }

  // If "detail" is empty then don't make message hilighted.
  if (detail.empty()) {
    config.pszContent = message.c_str();
  } else {
    config.pszMainInstruction = message.c_str();
    config.pszContent = detail.c_str();
  }

  // Iterate through the buttons, put common buttons in dwCommonButtons
  // and custom buttons in pButtons.
  std::map<int, int> id_map;
  std::vector<TASKDIALOG_BUTTON> dialog_buttons;
  if (options & MESSAGE_BOX_NO_LINK) {
    for (size_t i = 0; i < buttons.size(); ++i)
      dialog_buttons.push_back({i + kIDStart, buttons[i].c_str()});
  } else {
    MapToCommonID(buttons, &id_map, &config.dwCommonButtons, &dialog_buttons);
  }
  if (dialog_buttons.size() > 0) {
    config.pButtons = &dialog_buttons.front();
    config.cButtons = dialog_buttons.size();
    if (!(options & MESSAGE_BOX_NO_LINK))
      config.dwFlags |= TDF_USE_COMMAND_LINKS;  // custom buttons as links.
  }

  int id = 0;
  TaskDialogIndirect(&config, &id, NULL, NULL);
  if (id_map.find(id) != id_map.end())  // common button.
    return id_map[id];
  else if (id >= kIDStart)  // custom button.
    return id - kIDStart;
  else
    return cancel_id;
}

void RunMessageBoxInNewThread(base::Thread* thread,
                              NativeWindow* parent,
                              MessageBoxType type,
                              const std::vector<std::string>& buttons,
                              int cancel_id,
                              int options,
                              const std::string& title,
                              const std::string& message,
                              const std::string& detail,
                              const gfx::ImageSkia& icon,
                              const MessageBoxCallback& callback) {
  int result = ShowMessageBox(parent, type, buttons, cancel_id, options, title,
                              message, detail, icon);
  content::BrowserThread::PostTask(
      content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
  content::BrowserThread::DeleteSoon(
      content::BrowserThread::UI, FROM_HERE, thread);
}

}  // namespace

int ShowMessageBox(NativeWindow* parent,
                   MessageBoxType type,
                   const std::vector<std::string>& buttons,
                   int cancel_id,
                   int options,
                   const std::string& title,
                   const std::string& message,
                   const std::string& detail,
                   const gfx::ImageSkia& icon) {
  std::vector<base::string16> utf16_buttons;
  for (const auto& button : buttons)
    utf16_buttons.push_back(base::UTF8ToUTF16(button));

  HWND hwnd_parent = parent ?
      static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() :
      NULL;

  NativeWindow::DialogScope dialog_scope(parent);
  return ShowMessageBoxUTF16(hwnd_parent,
                             type,
                             utf16_buttons,
                             cancel_id,
                             options,
                             base::UTF8ToUTF16(title),
                             base::UTF8ToUTF16(message),
                             base::UTF8ToUTF16(detail),
                             icon);
}

void ShowMessageBox(NativeWindow* parent,
                    MessageBoxType type,
                    const std::vector<std::string>& buttons,
                    int cancel_id,
                    int options,
                    const std::string& title,
                    const std::string& message,
                    const std::string& detail,
                    const gfx::ImageSkia& icon,
                    const MessageBoxCallback& callback) {
  scoped_ptr<base::Thread> thread(
      new base::Thread(ATOM_PRODUCT_NAME "MessageBoxThread"));
  thread->init_com_with_mta(false);
  if (!thread->Start()) {
    callback.Run(cancel_id);
    return;
  }

  base::Thread* unretained = thread.release();
  unretained->message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained),
                 parent, type, buttons, cancel_id, options, title, message,
                 detail, icon, callback));
}

void ShowErrorBox(const base::string16& title, const base::string16& content) {
  ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, 0, 0, L"Error", title,
                      content, gfx::ImageSkia());
}

}  // namespace atom
<|endoftext|>


<commit_before>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/win/notify_icon.h"

#include <shobjidl.h>

#include "atom/browser/ui/win/notify_icon_host.h"
#include "base/md5.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/menu/menu_runner.h"

namespace atom {

NotifyIcon::NotifyIcon(NotifyIconHost* host,
                       UINT id,
                       HWND window,
                       UINT message)
    : host_(host),
      icon_id_(id),
      window_(window),
      message_id_(message),
      menu_model_(NULL),
      has_tray_app_id_hash_(false) {
  // NB: If we have an App Model ID, we should propagate that to the tray.
  // Doing this prevents duplicate items from showing up in the notification
  // preferences (i.e. "Always Show / Show notifications only / etc")
  PWSTR explicit_app_id;
  if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&explicit_app_id))) {
    // GUIDs and MD5 hashes are the same length. So convenient!
    base::MD5Sum(explicit_app_id,
                 sizeof(wchar_t) * wcslen(explicit_app_id),
                 reinterpret_cast<base::MD5Digest*>(&tray_app_id_hash_));
    has_tray_app_id_hash_ = true;
    CoTaskMemFree(explicit_app_id);
  }

  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_MESSAGE;
  icon_data.uCallbackMessage = message_id_;
  BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
  // This can happen if the explorer process isn't running when we try to
  // create the icon for some reason (for example, at startup).
  if (!result)
    LOG(WARNING) << "Unable to create status tray icon.";
}

NotifyIcon::~NotifyIcon() {
  // Remove our icon.
  host_->Remove(this);
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  Shell_NotifyIcon(NIM_DELETE, &icon_data);
}

void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos,
                                  bool left_mouse_click,
                                  bool double_button_click) {
  NOTIFYICONIDENTIFIER icon_id;
  memset(&icon_id, 0, sizeof(NOTIFYICONIDENTIFIER));
  icon_id.uID = icon_id_;
  icon_id.hWnd = window_;
  icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER);
  RECT rect = { 0 };
  Shell_NotifyIconGetRect(&icon_id, &rect);

  if (left_mouse_click) {
    if (double_button_click)  // double left click
      NotifyDoubleClicked(gfx::Rect(rect));
    else  // single left click
      NotifyClicked(gfx::Rect(rect));
    return;
  } else if (!double_button_click) {  // single right click
    NotifyRightClicked(gfx::Rect(rect));
    PopContextMenu(cursor_pos);
  }
}

void NotifyIcon::ResetIcon() {
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  // Delete any previously existing icon.
  Shell_NotifyIcon(NIM_DELETE, &icon_data);
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_MESSAGE;
  icon_data.uCallbackMessage = message_id_;
  icon_data.hIcon = icon_.Get();
  // If we have an image, then set the NIF_ICON flag, which tells
  // Shell_NotifyIcon() to set the image for the status icon it creates.
  if (icon_data.hIcon)
    icon_data.uFlags |= NIF_ICON;
  // Re-add our icon.
  BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to re-create status tray icon.";
}

void NotifyIcon::SetImage(const gfx::Image& image) {
  // Create the icon.
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_ICON;
  icon_.Set(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap()));
  icon_data.hIcon = icon_.Get();
  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Error setting status tray icon image";
}

void NotifyIcon::SetPressedImage(const gfx::Image& image) {
  // Ignore pressed images, since the standard on Windows is to not highlight
  // pressed status icons.
}

void NotifyIcon::SetToolTip(const std::string& tool_tip) {
  // Create the icon.
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_TIP;
  wcscpy_s(icon_data.szTip, base::UTF8ToUTF16(tool_tip).c_str());
  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to set tooltip for status tray icon";
}

void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
                                const base::string16& title,
                                const base::string16& contents) {
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_INFO;
  icon_data.dwInfoFlags = NIIF_INFO;
  wcscpy_s(icon_data.szInfoTitle, title.c_str());
  wcscpy_s(icon_data.szInfo, contents.c_str());
  icon_data.uTimeout = 0;

  base::win::Version win_version = base::win::GetVersion();
  if (!icon.IsEmpty() && win_version != base::win::VERSION_PRE_XP) {
    balloon_icon_.Set(IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap()));
    icon_data.hBalloonIcon = balloon_icon_.Get();
    icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
  }

  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to create status tray balloon.";
}

void NotifyIcon::PopContextMenu(const gfx::Point& pos) {
  // Set our window as the foreground window, so the context menu closes when
  // we click away from it.
  if (!SetForegroundWindow(window_))
    return;

  views::MenuRunner menu_runner(
      menu_model_,
      views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
  ignore_result(menu_runner.RunMenuAt(
      NULL,
      NULL,
      gfx::Rect(pos, gfx::Size()),
      views::MENU_ANCHOR_TOPLEFT,
      ui::MENU_SOURCE_MOUSE));
}

void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {
  menu_model_ = menu_model;
}

void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) {
  memset(icon_data, 0, sizeof(NOTIFYICONDATA));
  icon_data->cbSize = sizeof(NOTIFYICONDATA);
  icon_data->hWnd = window_;
  icon_data->uID = icon_id_;

  if (has_tray_app_id_hash_) {
    icon_data->uFlags |= NIF_GUID;
    memcpy(reinterpret_cast<void*>(&icon_data->guidItem),
           &tray_app_id_hash_,
           sizeof(GUID));
  }
}

}  // namespace atom
<commit_msg>win: Set GUID when getting icon's bounds<commit_after>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/win/notify_icon.h"

#include <shobjidl.h>

#include "atom/browser/ui/win/notify_icon_host.h"
#include "base/md5.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/menu/menu_runner.h"

namespace atom {

NotifyIcon::NotifyIcon(NotifyIconHost* host,
                       UINT id,
                       HWND window,
                       UINT message)
    : host_(host),
      icon_id_(id),
      window_(window),
      message_id_(message),
      menu_model_(NULL),
      has_tray_app_id_hash_(false) {
  // NB: If we have an App Model ID, we should propagate that to the tray.
  // Doing this prevents duplicate items from showing up in the notification
  // preferences (i.e. "Always Show / Show notifications only / etc")
  PWSTR explicit_app_id;
  if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&explicit_app_id))) {
    // GUIDs and MD5 hashes are the same length. So convenient!
    base::MD5Sum(explicit_app_id,
                 sizeof(wchar_t) * wcslen(explicit_app_id),
                 reinterpret_cast<base::MD5Digest*>(&tray_app_id_hash_));
    has_tray_app_id_hash_ = true;
    CoTaskMemFree(explicit_app_id);
  }

  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_MESSAGE;
  icon_data.uCallbackMessage = message_id_;
  BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
  // This can happen if the explorer process isn't running when we try to
  // create the icon for some reason (for example, at startup).
  if (!result)
    LOG(WARNING) << "Unable to create status tray icon.";
}

NotifyIcon::~NotifyIcon() {
  // Remove our icon.
  host_->Remove(this);
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  Shell_NotifyIcon(NIM_DELETE, &icon_data);
}

void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos,
                                  bool left_mouse_click,
                                  bool double_button_click) {
  NOTIFYICONIDENTIFIER icon_id;
  memset(&icon_id, 0, sizeof(NOTIFYICONIDENTIFIER));
  icon_id.uID = icon_id_;
  icon_id.hWnd = window_;
  icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER);
  if (has_tray_app_id_hash_)
    memcpy(reinterpret_cast<void*>(&icon_id.guidItem),
           &tray_app_id_hash_,
           sizeof(GUID));

  RECT rect = { 0 };
  Shell_NotifyIconGetRect(&icon_id, &rect);

  if (left_mouse_click) {
    if (double_button_click)  // double left click
      NotifyDoubleClicked(gfx::Rect(rect));
    else  // single left click
      NotifyClicked(gfx::Rect(rect));
    return;
  } else if (!double_button_click) {  // single right click
    NotifyRightClicked(gfx::Rect(rect));
    PopContextMenu(cursor_pos);
  }
}

void NotifyIcon::ResetIcon() {
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  // Delete any previously existing icon.
  Shell_NotifyIcon(NIM_DELETE, &icon_data);
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_MESSAGE;
  icon_data.uCallbackMessage = message_id_;
  icon_data.hIcon = icon_.Get();
  // If we have an image, then set the NIF_ICON flag, which tells
  // Shell_NotifyIcon() to set the image for the status icon it creates.
  if (icon_data.hIcon)
    icon_data.uFlags |= NIF_ICON;
  // Re-add our icon.
  BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to re-create status tray icon.";
}

void NotifyIcon::SetImage(const gfx::Image& image) {
  // Create the icon.
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_ICON;
  icon_.Set(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap()));
  icon_data.hIcon = icon_.Get();
  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Error setting status tray icon image";
}

void NotifyIcon::SetPressedImage(const gfx::Image& image) {
  // Ignore pressed images, since the standard on Windows is to not highlight
  // pressed status icons.
}

void NotifyIcon::SetToolTip(const std::string& tool_tip) {
  // Create the icon.
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_TIP;
  wcscpy_s(icon_data.szTip, base::UTF8ToUTF16(tool_tip).c_str());
  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to set tooltip for status tray icon";
}

void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
                                const base::string16& title,
                                const base::string16& contents) {
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_INFO;
  icon_data.dwInfoFlags = NIIF_INFO;
  wcscpy_s(icon_data.szInfoTitle, title.c_str());
  wcscpy_s(icon_data.szInfo, contents.c_str());
  icon_data.uTimeout = 0;

  base::win::Version win_version = base::win::GetVersion();
  if (!icon.IsEmpty() && win_version != base::win::VERSION_PRE_XP) {
    balloon_icon_.Set(IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap()));
    icon_data.hBalloonIcon = balloon_icon_.Get();
    icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
  }

  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to create status tray balloon.";
}

void NotifyIcon::PopContextMenu(const gfx::Point& pos) {
  // Set our window as the foreground window, so the context menu closes when
  // we click away from it.
  if (!SetForegroundWindow(window_))
    return;

  views::MenuRunner menu_runner(
      menu_model_,
      views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
  ignore_result(menu_runner.RunMenuAt(
      NULL,
      NULL,
      gfx::Rect(pos, gfx::Size()),
      views::MENU_ANCHOR_TOPLEFT,
      ui::MENU_SOURCE_MOUSE));
}

void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {
  menu_model_ = menu_model;
}

void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) {
  memset(icon_data, 0, sizeof(NOTIFYICONDATA));
  icon_data->cbSize = sizeof(NOTIFYICONDATA);
  icon_data->hWnd = window_;
  icon_data->uID = icon_id_;

  if (has_tray_app_id_hash_) {
    icon_data->uFlags |= NIF_GUID;
    memcpy(reinterpret_cast<void*>(&icon_data->guidItem),
           &tray_app_id_hash_,
           sizeof(GUID));
  }
}

}  // namespace atom
<|endoftext|>