<commit_before>#include "ofApp.h"

using namespace cv;
using namespace ofxCv;

float ofApp::_(string name) {
	return panel.getValueF(name);
}

void ofApp::_(string name, float x) {
	panel.setValueF(name, x);
}

void ofApp::setup() {
	ofSetDataPathRoot("../../../../../SharedData/");
	ofSetVerticalSync(true);
	ofSetFrameRate(60);

	loadDmxSettings();
	setupControlPanel();

	dmx.connect(port, modules * channelsPerModule);
	dmx.update(true); // black on startup

	previous.allocate(kinect.getWidth(), kinect.getHeight(), OF_IMAGE_GRAYSCALE);
	diff.allocate(kinect.getWidth(), kinect.getHeight(), OF_IMAGE_GRAYSCALE);
	kinect.setup();

	loadSounds();
}

void ofApp::loadSounds() {
	sounds.clear();
	ofxXmlSettings xml;
	xml.loadFile("sounds.xml");
	int n = xml.getNumTags("sound");
	for(int i = 0; i < n; i++) {
		Pulse cur;
		xml.pushTag("sound", i);
		cur.load(xml);
		xml.popTag();
		sounds.push_back(cur);
	}
}

void ofApp::loadDmxSettings() {
	ofxXmlSettings xml("dmx.xml");
	port = xml.getValue("port", "");
	modules = xml.getValue("modules", 10);
	channelsPerModule = xml.getValue("channelsPerModule", 4);
}

void ofApp::setupControlPanel() {
	panel.setup(256, 768);
	panel.setPosition(0, 0);
	panel.addPanel("sound and movement");
	panel.addToggle("useAdapt", true);
	panel.addSlider("adaptRate", .01, .0001, .05);
	panel.addSlider("energyGrow", .1, 0, 1);
	panel.addSlider("energyDecay", -.1, -.5, 0);
	panel.addSlider("energyMax", 20, 0, 48);
	panel.addSlider("overallEnergy", 0, 0, 1);
	panel.addSlider("minimumPresence", -.8, -2, 0);
	panel.addSlider("pulseRange", .6, 0, 1);

	panel.addPanel("virtual camera");
	float maxPosition = 4000;
	panel.addSlider("x", 0, -maxPosition, maxPosition);
	panel.addSlider("y", 0, -maxPosition, maxPosition);
	panel.addSlider("z", 0, -maxPosition, maxPosition);
	panel.addSlider("xcr", 0, -180, 180);
	panel.addSlider("ycr", 0, -180, 180);
	panel.addSlider("zcr", 0, -180, 180);
	panel.addSlider("xsr", 0, -180, 180);
	panel.addSlider("ysr", 0, -180, 180);
	panel.addSlider("zsr", 0, -180, 180);
	panel.addSlider("near", 0, 0, maxPosition);
	panel.addSlider("far", maxPosition, 0, maxPosition);
	panel.addSlider("maxLen", 100, 0, maxPosition);
	panel.addSlider("stepSize", 2, 1, 16, true);
	panel.addSlider("orthoScale", 10, 0, 32);
	panel.addToggle("horizontalFlip", false);

	panel.addPanel("lighting modules");
	panel.addToggle("saveCurves", false);
	panel.addToggle("loadCurves", false);
	panel.addSlider("saturation", 255, 0, 255);
	panel.addSlider("brightness", 255, 0, 255);
	for(int module = 1; module <= modules; module++) {
		string label = "mod" + ofToString(module);
		panel.addSlider(label, 0, 0, 1);
	}
	panel.loadSettings("settings.xml");

	redCurve.setup(256);
	greenCurve.setup(256);
	blueCurve.setup(256);
	panel.setValueB("loadCurves", true);
}

void ofApp::exit() {
	dmx.clear();
	dmx.update(true); // black on shutdown
}

ofColor ofApp::rastafari(float x) {
	return ofColor::fromHsb(x * 255. / 3., _("saturation"), _("brightness"));
}

void ofApp::update() {
	updateVirtualKinect();
	updateDmx();
	updateSounds();
}

void ofApp::updateVirtualKinect() {
	ofVec3f position(_("x"), _("y"), _("z"));
	ofVec3f cameraRotation(_("xcr"), _("ycr"), _("zcr"));
	ofVec3f sceneRotation(_("xsr"), _("ysr"), _("zsr"));
	kinect.setPosition(position);
	kinect.setCameraRotation(cameraRotation);
	kinect.setSceneRotation(sceneRotation);
	kinect.setClipping(_("near"), _("far"));
	kinect.setStepSize(_("stepSize"));
	kinect.setMaxLen(_("maxLen"));
	kinect.setOrthoScale(_("orthoScale"));
	kinect.setHorizontalFlip(_("horizontalFlip"));

	kinect.update();
	if(kinect.isFrameNew()) {
		absdiff(kinect, previous, diff);
		// only use pixels that have data both frames
		//Mat kinectMat = toCv(kinect), previousMat = toCv(previous), diffMat = toCv(diff);
		//diffMat &= (kinectMat > 0) & (previousMat > 0);
		diff.update();
		copy(kinect, previous);
		rawMean = (Mat_<float>) meanCols(toCv(diff));
		if(runningMean.rows != rawMean.rows) {
			runningMean = Mat_<float>::zeros(rawMean.rows, 1);
			energy = Mat_<float>::zeros(rawMean.rows, 1);
		}
		accumulateWeighted(rawMean, runningMean, _("adaptRate"));
		subtract(rawMean, runningMean, adaptedMean);
		Mat& cur = _("useAdapt") ? adaptedMean : rawMean;
		max(cur, 0, cur);
		addWeighted(cur, _("energyGrow"), energy, 1, _("energyDecay"), energy);
		min(max(energy, 0), _("energyMax"), energy);
		resize(energy, moduleEnergy, cv::Size(1, modules), 0, 0, INTER_AREA);
		moduleEnergy /= _("energyMax");

		for(int i = 0; i < moduleEnergy.rows; i++) {
			int module = i + 1;
			_("mod" + ofToString(module), moduleEnergy.at<float>(i));
		}
	}
}

void ofApp::updateDmx() {
	if(panel.getValueB("saveCurves")) {
		redCurve.save("redCurve.yml");
		greenCurve.save("greenCurve.yml");
		blueCurve.save("blueCurve.yml");
		panel.setValueB("saveCurves", false);
	}
	if(panel.getValueB("loadCurves")) {
		redCurve.load("redCurve.yml");
		greenCurve.load("greenCurve.yml");
		blueCurve.load("blueCurve.yml");
		panel.setValueB("loadCurves", false);
	}

	int channel = 1;
	for(int module = 1; module <= modules; module++) {
		ofColor cur = rastafari(_("mod" + ofToString(module)));
		dmx.setLevel(channel++, redCurve[cur.r]);
		dmx.setLevel(channel++, greenCurve[cur.g]);
		dmx.setLevel(channel++, blueCurve[cur.b]);
		channel++;
	}
	cout << endl;
	if(dmx.isConnected()) {
		dmx.update();
	} else {
		panel.msg = "Could not connect to port " + port;
	}
}

void ofApp::updateSounds() {
	float endVolume = ofMap(_("overallEnergy"), 0, 1, _("minimumPresence"), 1, true);
	float pulseSpeed = ofMap(_("overallEnergy"), 0, 1, 1 + _("pulseRange"), 1 - _("pulseRange"), true);
	for(int i = 0; i < sounds.size(); i++) {
		float curVolume = ofMap(i, 0, sounds.size() - 1, 1, endVolume);
		sounds[i].setVolume(MAX(curVolume, 0));
		sounds[i].setPulseSpeed(pulseSpeed);
		sounds[i].update();
	}
}

void ofApp::drawVirtualKinect() {
	ofPushMatrix();
	ofSetColor(255);
	ofTranslate(512, 0);
	kinect.draw(0, 0);

	ofEnableBlendMode(OF_BLENDMODE_ADD);
	ofSetColor(yellowPrint);
	diff.draw(0, 0);
	ofEnableAlphaBlending();
	ofDisableBlendMode();

	ofPushStyle();
	ofSetLineWidth(3);
	ofNoFill();

	ofPushMatrix();
	ofTranslate(0, kinect.getHeight());
	ofScale(1, -10);

	ofSetColor(ofColor::white);
	ofBeginShape();
	for(int i = 0; i < energy.rows; i++) {
		ofVertex(i, energy.at<float>(i));
	}
	ofEndShape();

	ofSetColor(128);
	ofLine(0, _("energyMax"), kinect.getWidth(), _("energyMax"));

	ofSetColor(yellowPrint);
	ofBeginShape();
	for(int i = 0; i < rawMean.rows; i++) {
		ofVertex(i, rawMean.at<float>(i));
	}
	ofEndShape();

	if(_("useAdapt")) {
		ofSetColor(cyanPrint);
		ofBeginShape();
		for(int i = 0; i < runningMean.rows; i++) {
			ofVertex(i, runningMean.at<float>(i));
		}
		ofEndShape();

		ofSetColor(magentaPrint);
		ofBeginShape();
		for(int i = 0; i < adaptedMean.rows; i++) {
			ofVertex(i, adaptedMean.at<float>(i));
		}
		ofEndShape();
	}

	ofPopMatrix();

	drawHighlightString("energy", 4, 4);
	drawHighlightString("raw", 4, 24, ofColor::black, yellowPrint);
	if(_("useAdapt")) {
		drawHighlightString("running", 4, 44, ofColor::black, cyanPrint);
		drawHighlightString("adapt", 4, 64, ofColor::black, magentaPrint);
	}

	ofPopStyle();
	ofPopMatrix();
}

void ofApp::drawDmx() {
	ofPushMatrix();
	ofTranslate(256, 0);
	redCurve.draw(0, 0);
	greenCurve.draw(0, 256);
	blueCurve.draw(0, 512);

	ofTranslate(256, 480);
	int channel = 1;
	for(int module = 1; module <= modules; module++) {
		string label = "mod" + ofToString(module);
		int rc = channel++;
		int gc = channel++;
		int bc = channel++;
		int ac = channel++;
		int r = dmx.getLevel(rc), g = dmx.getLevel(gc), b = dmx.getLevel(bc);
		ofSetColor(r, g, b);
		ofFill();
		ofRect(4, module * 16, 14, 14);
		ofSetColor(255);
		ofNoFill();
		ofRect(4, module * 16, 14, 14);
		string rs = ofToString(rc) + ":" + ofToString(r);
		string gs = ofToString(gc) + ":" + ofToString(g);
		string bs = ofToString(bc) + ":" + ofToString(b);
		string text = label + " (" + rs + ", " + gs + ", " + bs + ")";
		drawHighlightString(text, 24, module * 16 - 2);
	}

	ofPopMatrix();
}

void ofApp::drawSounds() {
	ofPushMatrix();
	ofTranslate(800, 480 + 16);
	for(int i = 0; i < sounds.size(); i++) {
		sounds[i].draw();
		ofTranslate(0, 20);
	}
	ofPopMatrix();
}

void ofApp::draw() {
	if(panel.hidden) {
		ofPushMatrix();
		float spacing = ofGetWidth() / modules;
		int channel = 1;
		for(int module = 1; module <= modules; module++) {
			string label = "mod" + ofToString(module);
			int rc = channel++;
			int gc = channel++;
			int bc = channel++;
			int ac = channel++;
			int r = dmx.getLevel(rc), g = dmx.getLevel(gc), b = dmx.getLevel(bc);
			ofSetColor(r, g, b);
			ofFill();
			ofRect(0, 0, spacing, ofGetHeight());
			ofTranslate(spacing, 0);
		}
		ofPopMatrix();
	} else {
		ofBackground(127);
		drawVirtualKinect();
		drawDmx();
		drawSounds();
	}
}

<commit_msg>connected movement to sound<commit_after>#include "ofApp.h"

using namespace cv;
using namespace ofxCv;

float ofApp::_(string name) {
	return panel.getValueF(name);
}

void ofApp::_(string name, float x) {
	panel.setValueF(name, x);
}

void ofApp::setup() {
	ofSetDataPathRoot("../../../../../SharedData/");
	ofSetVerticalSync(true);
	ofSetFrameRate(60);

	loadDmxSettings();
	setupControlPanel();

	dmx.connect(port, modules * channelsPerModule);
	dmx.update(true); // black on startup

	previous.allocate(kinect.getWidth(), kinect.getHeight(), OF_IMAGE_GRAYSCALE);
	diff.allocate(kinect.getWidth(), kinect.getHeight(), OF_IMAGE_GRAYSCALE);
	kinect.setup();

	loadSounds();
}

void ofApp::loadSounds() {
	sounds.clear();
	ofxXmlSettings xml;
	xml.loadFile("sounds.xml");
	int n = xml.getNumTags("sound");
	for(int i = 0; i < n; i++) {
		Pulse cur;
		xml.pushTag("sound", i);
		cur.load(xml);
		xml.popTag();
		sounds.push_back(cur);
	}
}

void ofApp::loadDmxSettings() {
	ofxXmlSettings xml("dmx.xml");
	port = xml.getValue("port", "");
	modules = xml.getValue("modules", 10);
	channelsPerModule = xml.getValue("channelsPerModule", 4);
}

void ofApp::setupControlPanel() {
	panel.setup(256, 768);
	panel.setPosition(0, 0);
	panel.addPanel("sound and movement");
	panel.addToggle("useAdapt", true);
	panel.addSlider("adaptRate", .01, .0001, .05);
	panel.addSlider("energyGrow", .1, 0, 1);
	panel.addSlider("energyDecay", -.1, -.5, 0);
	panel.addSlider("energyMax", 20, 0, 48);
	panel.addSlider("overallEnergy", 0, 0, 1);
	panel.addSlider("minimumPresence", -.8, -2, 0);
	panel.addSlider("pulseRange", .6, 0, 1);

	panel.addPanel("virtual camera");
	float maxPosition = 4000;
	panel.addSlider("x", 0, -maxPosition, maxPosition);
	panel.addSlider("y", 0, -maxPosition, maxPosition);
	panel.addSlider("z", 0, -maxPosition, maxPosition);
	panel.addSlider("xcr", 0, -180, 180);
	panel.addSlider("ycr", 0, -180, 180);
	panel.addSlider("zcr", 0, -180, 180);
	panel.addSlider("xsr", 0, -180, 180);
	panel.addSlider("ysr", 0, -180, 180);
	panel.addSlider("zsr", 0, -180, 180);
	panel.addSlider("near", 0, 0, maxPosition);
	panel.addSlider("far", maxPosition, 0, maxPosition);
	panel.addSlider("maxLen", 100, 0, maxPosition);
	panel.addSlider("stepSize", 2, 1, 16, true);
	panel.addSlider("orthoScale", 10, 0, 32);
	panel.addToggle("horizontalFlip", false);

	panel.addPanel("lighting modules");
	panel.addToggle("saveCurves", false);
	panel.addToggle("loadCurves", false);
	panel.addSlider("saturation", 255, 0, 255);
	panel.addSlider("brightness", 255, 0, 255);
	for(int module = 1; module <= modules; module++) {
		string label = "mod" + ofToString(module);
		panel.addSlider(label, 0, 0, 1);
	}
	panel.loadSettings("settings.xml");

	redCurve.setup(256);
	greenCurve.setup(256);
	blueCurve.setup(256);
	panel.setValueB("loadCurves", true);
}

void ofApp::exit() {
	dmx.clear();
	dmx.update(true); // black on shutdown
}

ofColor ofApp::rastafari(float x) {
	return ofColor::fromHsb(x * 255. / 3., _("saturation"), _("brightness"));
}

void ofApp::update() {
	updateVirtualKinect();
	updateDmx();
	updateSounds();
}

void ofApp::updateVirtualKinect() {
	ofVec3f position(_("x"), _("y"), _("z"));
	ofVec3f cameraRotation(_("xcr"), _("ycr"), _("zcr"));
	ofVec3f sceneRotation(_("xsr"), _("ysr"), _("zsr"));
	kinect.setPosition(position);
	kinect.setCameraRotation(cameraRotation);
	kinect.setSceneRotation(sceneRotation);
	kinect.setClipping(_("near"), _("far"));
	kinect.setStepSize(_("stepSize"));
	kinect.setMaxLen(_("maxLen"));
	kinect.setOrthoScale(_("orthoScale"));
	kinect.setHorizontalFlip(_("horizontalFlip"));

	kinect.update();
	if(kinect.isFrameNew()) {
		absdiff(kinect, previous, diff);
		// only use pixels that have data both frames
		//Mat kinectMat = toCv(kinect), previousMat = toCv(previous), diffMat = toCv(diff);
		//diffMat &= (kinectMat > 0) & (previousMat > 0);
		diff.update();
		copy(kinect, previous);
		rawMean = (Mat_<float>) meanCols(toCv(diff));
		if(runningMean.rows != rawMean.rows) {
			runningMean = Mat_<float>::zeros(rawMean.rows, 1);
			energy = Mat_<float>::zeros(rawMean.rows, 1);
		}
		accumulateWeighted(rawMean, runningMean, _("adaptRate"));
		subtract(rawMean, runningMean, adaptedMean);
		Mat& cur = _("useAdapt") ? adaptedMean : rawMean;
		max(cur, 0, cur);
		addWeighted(cur, _("energyGrow"), energy, 1, _("energyDecay"), energy);
		min(max(energy, 0), _("energyMax"), energy);
		resize(energy, moduleEnergy, cv::Size(1, modules), 0, 0, INTER_AREA);
		moduleEnergy /= _("energyMax");

		_("overallEnergy", 0);
		for(int i = 0; i < moduleEnergy.rows; i++) {
			int module = i + 1;
			float cur = moduleEnergy.at<float>(i);
			_("mod" + ofToString(module), cur);
			_("overallEnergy", MAX(_("overallEnergy"), cur));
		}
	}
}

void ofApp::updateDmx() {
	if(panel.getValueB("saveCurves")) {
		redCurve.save("redCurve.yml");
		greenCurve.save("greenCurve.yml");
		blueCurve.save("blueCurve.yml");
		panel.setValueB("saveCurves", false);
	}
	if(panel.getValueB("loadCurves")) {
		redCurve.load("redCurve.yml");
		greenCurve.load("greenCurve.yml");
		blueCurve.load("blueCurve.yml");
		panel.setValueB("loadCurves", false);
	}

	int channel = 1;
	for(int module = 1; module <= modules; module++) {
		ofColor cur = rastafari(_("mod" + ofToString(module)));
		dmx.setLevel(channel++, redCurve[cur.r]);
		dmx.setLevel(channel++, greenCurve[cur.g]);
		dmx.setLevel(channel++, blueCurve[cur.b]);
		channel++;
	}
	if(dmx.isConnected()) {
		dmx.update();
	} else {
		panel.msg = "Could not connect to port " + port;
	}
}

void ofApp::updateSounds() {
	float endVolume = ofMap(_("overallEnergy"), 0, 1, _("minimumPresence"), 1, true);
	float pulseSpeed = ofMap(_("overallEnergy"), 0, 1, 1 + _("pulseRange"), 1 - _("pulseRange"), true);
	for(int i = 0; i < sounds.size(); i++) {
		float curVolume = ofMap(i, 0, sounds.size() - 1, 1, endVolume);
		sounds[i].setVolume(MAX(curVolume, 0));
		sounds[i].setPulseSpeed(pulseSpeed);
		sounds[i].update();
	}
}

void ofApp::drawVirtualKinect() {
	ofPushMatrix();
	ofSetColor(255);
	ofTranslate(512, 0);
	kinect.draw(0, 0);

	ofEnableBlendMode(OF_BLENDMODE_ADD);
	ofSetColor(yellowPrint);
	diff.draw(0, 0);
	ofEnableAlphaBlending();
	ofDisableBlendMode();

	ofPushStyle();
	ofSetLineWidth(3);
	ofNoFill();

	ofPushMatrix();
	ofTranslate(0, kinect.getHeight());
	ofScale(1, -10);

	ofSetColor(ofColor::white);
	ofBeginShape();
	for(int i = 0; i < energy.rows; i++) {
		ofVertex(i, energy.at<float>(i));
	}
	ofEndShape();

	ofSetColor(128);
	ofLine(0, _("energyMax"), kinect.getWidth(), _("energyMax"));

	ofSetColor(yellowPrint);
	ofBeginShape();
	for(int i = 0; i < rawMean.rows; i++) {
		ofVertex(i, rawMean.at<float>(i));
	}
	ofEndShape();

	if(_("useAdapt")) {
		ofSetColor(cyanPrint);
		ofBeginShape();
		for(int i = 0; i < runningMean.rows; i++) {
			ofVertex(i, runningMean.at<float>(i));
		}
		ofEndShape();

		ofSetColor(magentaPrint);
		ofBeginShape();
		for(int i = 0; i < adaptedMean.rows; i++) {
			ofVertex(i, adaptedMean.at<float>(i));
		}
		ofEndShape();
	}

	ofPopMatrix();

	drawHighlightString("energy", 4, 4);
	drawHighlightString("raw", 4, 24, ofColor::black, yellowPrint);
	if(_("useAdapt")) {
		drawHighlightString("running", 4, 44, ofColor::black, cyanPrint);
		drawHighlightString("adapt", 4, 64, ofColor::black, magentaPrint);
	}

	ofPopStyle();
	ofPopMatrix();
}

void ofApp::drawDmx() {
	ofPushMatrix();
	ofTranslate(256, 0);
	redCurve.draw(0, 0);
	greenCurve.draw(0, 256);
	blueCurve.draw(0, 512);

	ofTranslate(256 + 14, 480);
	int channel = 1;
	for(int module = 1; module <= modules; module++) {
		string label = "mod" + ofToString(module);
		int rc = channel++;
		int gc = channel++;
		int bc = channel++;
		int ac = channel++;
		int r = dmx.getLevel(rc), g = dmx.getLevel(gc), b = dmx.getLevel(bc);
		ofSetColor(r, g, b);
		ofFill();
		ofRect(4, module * 16, 14, 14);
		ofSetColor(255);
		ofNoFill();
		ofRect(4, module * 16, 14, 14);
		string rs = ofToString(rc) + ":" + ofToString(r);
		string gs = ofToString(gc) + ":" + ofToString(g);
		string bs = ofToString(bc) + ":" + ofToString(b);
		string text = label + " (" + rs + ", " + gs + ", " + bs + ")";
		drawHighlightString(text, 24, module * 16 - 2);
	}

	ofPopMatrix();
}

void ofApp::drawSounds() {
	ofPushMatrix();
	ofTranslate(800, 480 + 16);
	for(int i = 0; i < sounds.size(); i++) {
		sounds[i].draw();
		ofTranslate(0, 20);
	}
	ofPopMatrix();
}

void ofApp::draw() {
	if(panel.hidden) {
		ofPushMatrix();
		float spacing = ofGetWidth() / modules;
		int channel = 1;
		for(int module = 1; module <= modules; module++) {
			string label = "mod" + ofToString(module);
			int rc = channel++;
			int gc = channel++;
			int bc = channel++;
			int ac = channel++;
			int r = dmx.getLevel(rc), g = dmx.getLevel(gc), b = dmx.getLevel(bc);
			ofSetColor(r, g, b);
			ofFill();
			ofRect(0, 0, spacing, ofGetHeight());
			ofTranslate(spacing, 0);
		}
		ofPopMatrix();
	} else {
		ofBackground(127);
		drawVirtualKinect();
		drawDmx();
		drawSounds();
	}
}

<|endoftext|>


<commit_before>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2014 Michael Fink
//
/// \file PsrecSourceDeviceImpl.hpp PS-ReC - SourceDevice impl
//
#pragma once

// includes
#include "SourceDevice.hpp"
#include "PsrecCommon.hpp"
#include "PsrecRemoteReleaseControlImpl.hpp"
#include "PsrecPropertyAccess.hpp"
#include "PsrecDeviceInfo.hpp"

namespace PSREC
{

/// source device impl for PSREC
class SourceDeviceImpl:
   public SourceDevice,
   public std::enable_shared_from_this<SourceDeviceImpl>
{
public:
   /// ctor
   SourceDeviceImpl(RefSp spRef, prDeviceInfoTable& deviceInfo)
      :m_spRef(spRef),
       m_hCamera(0)
   {
      LOG_TRACE(_T("about to call PR_CreateCameraObject...\n"));

      prHandle hCamera = 0;
      // may return prINVALID_FN_CALL when SDK wasn't initialized
      // may return prINVALID_PARAMETER when specified device info is invalid
      // may return prMEM_ALLOC_FAILED on memory error
      prResponse err = PR_CreateCameraObject(&deviceInfo, &hCamera);
      LOG_TRACE(_T("PR_CreateCameraObject(&si = \"%ls\", &handle) returned %08x, handle %08x\n"),
         deviceInfo.ModelName, err, hCamera);
      CheckError(_T("PR_CreateCameraObject"), err, __FILE__, __LINE__);

      m_hCamera = hCamera;

      // connect to camera itself
      // may return prINVALID_FN_CALL, prINVALID_HANDLE, prMEM_ALLOC_FAILED
      err = PR_ConnectCamera(m_hCamera);
      LOG_TRACE(_T("PR_ConnectCamera(handle = %08x) returned %08x\n"), m_hCamera, err);
      CheckError(_T("PR_ConnectCamera"), err, __FILE__, __LINE__);

      // get device info so that we don't have to query every time
      m_spDeviceInfo.reset(new DeviceInfo(m_hCamera));
   }

   /// dtor
   virtual ~SourceDeviceImpl() throw()
   {
      // disconnect from camera
      prResponse err = PR_DisconnectCamera(m_hCamera);
      LOG_TRACE(_T("PR_DisconnectCamera(%08x) returned %08x\n"), m_hCamera, err);

      // may return prINVALID_FN_CALL when SDK wasn't initialized
      // may return prINVALID_HANDLE when specified handle is invalid
      err = PR_DestroyCameraObject(m_hCamera);
      LOG_TRACE(_T("PR_DestroyCameraObject(%08x) returned %08x\n"), m_hCamera, err);
   }

   virtual bool GetDeviceCapability(SourceDevice::T_enDeviceCapability enDeviceCapability) const override
   {
      ATLASSERT(m_spDeviceInfo != nullptr);
      DeviceInfo& info = *m_spDeviceInfo.get();

      switch (enDeviceCapability)
      {
      case SourceDevice::capRemoteReleaseControl:
         {
            bool bInitiateRelease =
               info.m_setOperationsSupported.find(prPTP_INITIATE_RELEASE_CONTROL) != info.m_setOperationsSupported.end();
            return bInitiateRelease;
         }
         break;

      case SourceDevice::capRemoteViewfinder:
         {
            bool bInitiateViewfinder =
               info.m_setOperationsSupported.find(prPTP_RC_INITIATE_VIEW_FINDER) != info.m_setOperationsSupported.end();

            return bInitiateViewfinder;
         }
         break;

      default:
         ATLASSERT(false);
      }
      return false;
   }

   virtual CString ModelName() const override
   {
      ATLASSERT(m_spDeviceInfo != nullptr);

      return m_spDeviceInfo->m_cszModel;
   }

   virtual CString SerialNumber() const override
   {
      ATLASSERT(m_spDeviceInfo != nullptr);

      return m_spDeviceInfo->m_cszSerialNumber;
   }

   virtual std::vector<unsigned int> EnumDeviceProperties() const override
   {
      ATLASSERT(m_spDeviceInfo != nullptr);
      DeviceInfo& info = *m_spDeviceInfo.get();

      const std::set<prUInt16>& setDeviceProperties =  info.m_setDevicePropertiesSupported;
      std::set<prUInt16>::const_iterator iter = setDeviceProperties.begin(),
         stop = setDeviceProperties.end();

      std::vector<unsigned int> vecData;

      // just put the device property id's into the vector
      for (; iter != stop; ++iter)
         vecData.push_back(*iter);

      return vecData;
   }

   virtual DeviceProperty GetDeviceProperty(unsigned int uiPropertyId) const override
   {
      prUInt16 propId = static_cast<prUInt16>(uiPropertyId & 0xFFFF);

      // get device property value
      DevicePropDesc desc(m_hCamera, propId, false);

      DeviceProperty dp(variantPsrec, uiPropertyId, desc.m_varCurrentValue, !desc.IsSetAllowed());

      // TODO needed to create PropertyAccess object here?
      PropertyAccess pa(m_hCamera);
      pa.Enum(propId, dp.m_vecValidValues);

      return dp;
   }

   virtual std::shared_ptr<RemoteReleaseControl> EnterReleaseControl() override
   {
      if (!GetDeviceCapability(capRemoteReleaseControl))
      {
         throw CameraException(_T("SourceDevice::EnterReleaseControl"), _T("Not supported"),
            prERROR_PRSDK_COMPONENTID | prNOT_SUPPORTED, __FILE__, __LINE__);
      }

      std::shared_ptr<SourceDeviceImpl> spSourceDevice = shared_from_this();

      return std::shared_ptr<RemoteReleaseControl>(new RemoteReleaseControlImpl(m_hCamera, spSourceDevice));
   }

   /// returns device info
   std::shared_ptr<DeviceInfo> GetDeviceInfo() { return m_spDeviceInfo; }

private:
   /// camera handle
   prHandle m_hCamera;

   /// SDK ref
   RefSp m_spRef;

   /// device info
   std::shared_ptr<DeviceInfo> m_spDeviceInfo;
};

} // namespace PSREC
<commit_msg>removed extra instance of PropertyAccess when getting device properties<commit_after>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2014 Michael Fink
//
/// \file PsrecSourceDeviceImpl.hpp PS-ReC - SourceDevice impl
//
#pragma once

// includes
#include "SourceDevice.hpp"
#include "PsrecCommon.hpp"
#include "PsrecRemoteReleaseControlImpl.hpp"
#include "PsrecPropertyAccess.hpp"
#include "PsrecDeviceInfo.hpp"

namespace PSREC
{

/// source device impl for PSREC
class SourceDeviceImpl:
   public SourceDevice,
   public std::enable_shared_from_this<SourceDeviceImpl>
{
public:
   /// ctor
   SourceDeviceImpl(RefSp spRef, prDeviceInfoTable& deviceInfo)
      :m_spRef(spRef),
       m_hCamera(0)
   {
      LOG_TRACE(_T("about to call PR_CreateCameraObject...\n"));

      prHandle hCamera = 0;
      // may return prINVALID_FN_CALL when SDK wasn't initialized
      // may return prINVALID_PARAMETER when specified device info is invalid
      // may return prMEM_ALLOC_FAILED on memory error
      prResponse err = PR_CreateCameraObject(&deviceInfo, &hCamera);
      LOG_TRACE(_T("PR_CreateCameraObject(&si = \"%ls\", &handle) returned %08x, handle %08x\n"),
         deviceInfo.ModelName, err, hCamera);
      CheckError(_T("PR_CreateCameraObject"), err, __FILE__, __LINE__);

      m_hCamera = hCamera;

      // connect to camera itself
      // may return prINVALID_FN_CALL, prINVALID_HANDLE, prMEM_ALLOC_FAILED
      err = PR_ConnectCamera(m_hCamera);
      LOG_TRACE(_T("PR_ConnectCamera(handle = %08x) returned %08x\n"), m_hCamera, err);
      CheckError(_T("PR_ConnectCamera"), err, __FILE__, __LINE__);

      // get device info so that we don't have to query every time
      m_spDeviceInfo.reset(new DeviceInfo(m_hCamera));
   }

   /// dtor
   virtual ~SourceDeviceImpl() throw()
   {
      // disconnect from camera
      prResponse err = PR_DisconnectCamera(m_hCamera);
      LOG_TRACE(_T("PR_DisconnectCamera(%08x) returned %08x\n"), m_hCamera, err);

      // may return prINVALID_FN_CALL when SDK wasn't initialized
      // may return prINVALID_HANDLE when specified handle is invalid
      err = PR_DestroyCameraObject(m_hCamera);
      LOG_TRACE(_T("PR_DestroyCameraObject(%08x) returned %08x\n"), m_hCamera, err);
   }

   virtual bool GetDeviceCapability(SourceDevice::T_enDeviceCapability enDeviceCapability) const override
   {
      ATLASSERT(m_spDeviceInfo != nullptr);
      DeviceInfo& info = *m_spDeviceInfo.get();

      switch (enDeviceCapability)
      {
      case SourceDevice::capRemoteReleaseControl:
         {
            bool bInitiateRelease =
               info.m_setOperationsSupported.find(prPTP_INITIATE_RELEASE_CONTROL) != info.m_setOperationsSupported.end();
            return bInitiateRelease;
         }
         break;

      case SourceDevice::capRemoteViewfinder:
         {
            bool bInitiateViewfinder =
               info.m_setOperationsSupported.find(prPTP_RC_INITIATE_VIEW_FINDER) != info.m_setOperationsSupported.end();

            return bInitiateViewfinder;
         }
         break;

      default:
         ATLASSERT(false);
      }
      return false;
   }

   virtual CString ModelName() const override
   {
      ATLASSERT(m_spDeviceInfo != nullptr);

      return m_spDeviceInfo->m_cszModel;
   }

   virtual CString SerialNumber() const override
   {
      ATLASSERT(m_spDeviceInfo != nullptr);

      return m_spDeviceInfo->m_cszSerialNumber;
   }

   virtual std::vector<unsigned int> EnumDeviceProperties() const override
   {
      ATLASSERT(m_spDeviceInfo != nullptr);
      DeviceInfo& info = *m_spDeviceInfo.get();

      const std::set<prUInt16>& setDeviceProperties =  info.m_setDevicePropertiesSupported;
      std::set<prUInt16>::const_iterator iter = setDeviceProperties.begin(),
         stop = setDeviceProperties.end();

      std::vector<unsigned int> vecData;

      // just put the device property id's into the vector
      for (; iter != stop; ++iter)
         vecData.push_back(*iter);

      return vecData;
   }

   virtual DeviceProperty GetDeviceProperty(unsigned int uiPropertyId) const override
   {
      prUInt16 propId = static_cast<prUInt16>(uiPropertyId & 0xFFFF);

      // get device property value
      DevicePropDesc desc(m_hCamera, propId, true);

      DeviceProperty dp(variantPsrec, uiPropertyId, desc.m_varCurrentValue, !desc.IsSetAllowed());
      dp.m_vecValidValues = desc.m_vecAllValues;

      return dp;
   }

   virtual std::shared_ptr<RemoteReleaseControl> EnterReleaseControl() override
   {
      if (!GetDeviceCapability(capRemoteReleaseControl))
      {
         throw CameraException(_T("SourceDevice::EnterReleaseControl"), _T("Not supported"),
            prERROR_PRSDK_COMPONENTID | prNOT_SUPPORTED, __FILE__, __LINE__);
      }

      std::shared_ptr<SourceDeviceImpl> spSourceDevice = shared_from_this();

      return std::shared_ptr<RemoteReleaseControl>(new RemoteReleaseControlImpl(m_hCamera, spSourceDevice));
   }

   /// returns device info
   std::shared_ptr<DeviceInfo> GetDeviceInfo() { return m_spDeviceInfo; }

private:
   /// camera handle
   prHandle m_hCamera;

   /// SDK ref
   RefSp m_spRef;

   /// device info
   std::shared_ptr<DeviceInfo> m_spDeviceInfo;
};

} // namespace PSREC
<|endoftext|>


<commit_before>#include "compiler.h"
#include "generator.h"

#include <algorithm>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/scope_exit.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <ostream>
#include <stdexcept>
#include <string>
#include <vector>

#include <iostream> // debug outputs

// ----- Program structs -------------------------------------------------------
namespace bf {

namespace instruction {

struct function_call_t {
    std::string function_name;
};

struct variable_declaration_t {
    std::string variable_name;
    int         init_value;
};

struct print_variable_t {
    std::string variable_name;
};

struct print_text_t {
    std::string text;
};

struct scan_variable_t {
    std::string variable_name;
};

} // namespace bf::instruction

typedef boost::variant<
    instruction::function_call_t,
    instruction::variable_declaration_t,
    instruction::print_variable_t,
    instruction::print_text_t,
    instruction::scan_variable_t
> instruction_t;

struct function_t {
    std::string name;
    std::vector<std::string> parameters;
    std::vector<instruction_t> instructions;
};

typedef std::vector<function_t> program_t;

} // namespace bf

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::function_call_t,
        (std::string, function_name))

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::variable_declaration_t,
        (std::string, variable_name)
        (int,         init_value))

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::print_variable_t,
        (std::string, variable_name))

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::print_text_t,
        (std::string, text))

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::scan_variable_t,
        (std::string, variable_name))

BOOST_FUSION_ADAPT_STRUCT(
        bf::function_t,
        (std::string, name)
        (std::vector<std::string>, parameters)
        (std::vector<bf::instruction_t>, instructions))

// ----- Parser grammar --------------------------------------------------------
namespace bf {

namespace qi    = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename iterator>
struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
    grammar() : grammar::base_type(program) {
        program = *function;
        function = "function" >> function_name
            >> '(' >> -(variable_name % ',') >> ')'
            >> '{' >> *instruction >> '}';
        function_name = qi::lexeme[+qi::alpha];
        variable_name = qi::lexeme[+qi::alpha];

        instruction = function_call
            | variable_declaration
            | print_variable
            | print_text
            | scan_variable;

        function_call        = function_name >> '(' >> -(variable_name % ',') >> ')' >> ';';
        variable_declaration = "var" >> variable_name >> (('=' >> qi::uint_) | qi::attr(0)) >> ';';
        print_variable       = "print" >> variable_name >> ';';
        print_text           = "print" >> qi::lexeme['"' >> *(qi::char_ - '"') >> '"'] >> ';';
        scan_variable        = "scan" >> variable_name >> ';';
    }

    qi::rule<iterator, program_t(),                           ascii::space_type> program;
    qi::rule<iterator, function_t(),                          ascii::space_type> function;
    qi::rule<iterator, std::string(),                         ascii::space_type> function_name;
    qi::rule<iterator, std::string(),                         ascii::space_type> variable_name;
    qi::rule<iterator, instruction_t(),                       ascii::space_type> instruction;

    qi::rule<iterator, instruction::function_call_t(),        ascii::space_type> function_call;
    qi::rule<iterator, instruction::variable_declaration_t(), ascii::space_type> variable_declaration;
    qi::rule<iterator, instruction::print_variable_t(),       ascii::space_type> print_variable;
    qi::rule<iterator, instruction::print_text_t(),           ascii::space_type> print_text;
    qi::rule<iterator, instruction::scan_variable_t(),        ascii::space_type> scan_variable;
};

// ----- Compilation algorithms ------------------------------------------------
program_t parse(const std::string &source) {
    // Build program struct from source input.
    grammar<decltype(source.begin())> g;
    program_t program;
    auto begin = source.begin(), end = source.end();
    const bool success = qi::phrase_parse(begin, end, g, ascii::space, program);

    if (!success || begin != end)
        throw std::logic_error("Parse unsuccessful!");

    // ----- Check program struct -----
    std::sort(program.begin(), program.end(),
            [](const function_t &f1, const function_t &f2) {return f1.name < f2.name;});
    // Ensure unique function names.
    if (program.size() > 1) {
        auto before_it = program.begin();
        for (auto it = before_it + 1; it != program.end(); ++before_it, ++it)
            if (before_it->name == it->name)
                throw std::logic_error("Function name used multiply times: " + it->name);
    }

    return program;
}

class instruction_visitor : public boost::static_visitor<void> {
public:
    instruction_visitor(const program_t &program) : m_program(program) {}

    void operator()(const instruction::function_call_t &i) {
        // Check if called function exists.
        auto function_it = std::find_if(m_program.begin(), m_program.end(),
                [&i](const function_t &f) {return f.name == i.function_name;});
        if (function_it == m_program.end())
            throw std::logic_error("Function not found: " + i.function_name);

        // Check for recursion (which is not supported).
        auto recursion_it = std::find(m_call_stack.begin(), m_call_stack.end(), i.function_name);
        if (recursion_it != m_call_stack.end()) {
            std::string call_stack_dump;
            for (const auto &function : m_call_stack)
                call_stack_dump += function + ", ";
            call_stack_dump += "(*) " + i.function_name;
            throw std::logic_error("Recursion not supported: " + call_stack_dump);
        }

        // Provide a clean scope for the called function.
        std::vector<std::map<std::string, generator::var_ptr>> scope_backup;
        std::swap(m_scope, scope_backup);
        m_scope.emplace_back();
        // TODO: Copy arguments
        // Restore old scope after the function returns.
        BOOST_SCOPE_EXIT(this_, &scope_backup) {
            std::swap(this_->m_scope, scope_backup);
        } BOOST_SCOPE_EXIT_END

        // Just for error report on recursion: Keep track of the call stack.
        m_call_stack.push_back(i.function_name);
        BOOST_SCOPE_EXIT(this_) {
            this_->m_call_stack.pop_back();
        } BOOST_SCOPE_EXIT_END

        // Finally, visit all instructions in the called function.
        for (const auto &instruction : function_it->instructions)
            boost::apply_visitor(*this, instruction);
    }

    void operator()(const instruction::variable_declaration_t &i) {
        auto it = m_scope.back().find(i.variable_name);
        if (it != m_scope.back().end())
            throw std::logic_error("Redeclaration of variable: " + i.variable_name);

        m_scope.back().emplace(i.variable_name, m_bfg.new_var(i.variable_name, i.init_value));
    }

    void operator()(const instruction::print_variable_t &i) {
        get_var(i.variable_name)->write_output();
    }

    void operator()(const instruction::print_text_t &i) {
        m_bfg.print(i.text);
    }

    void operator()(const instruction::scan_variable_t &i) {
        get_var(i.variable_name)->read_input();
    }

    const generator::var_ptr &get_var(const std::string &variable_name) const {
        for (auto scope_it = m_scope.rbegin(); scope_it != m_scope.rend(); ++scope_it) {
            auto it = scope_it->find(variable_name);
            if (it != scope_it->end())
                return it->second;
        }

        throw std::logic_error("Variable not declared in this scope: " + variable_name);
    }

    const generator &get_generator() const {
        return m_bfg;
    }

private:
    program_t                                              m_program; // TODO: just const ref?
    generator                                              m_bfg;
    std::vector<std::map<std::string, generator::var_ptr>> m_scope;
    std::vector<std::string>                               m_call_stack;
};

std::string generate(const program_t &program) {
    // As long as all function calls are inlined, this makes sense.
    instruction_visitor visitor(program);
    instruction::function_call_t call_to_main {"main"};
    instruction_t start = call_to_main;
    boost::apply_visitor(visitor, start);

    return visitor.get_generator().get_code();
}

std::string compiler::compile(const std::string &source) const {
    program_t program = parse(source);
    return generate(program);
}

} // namespace
<commit_msg>Added error message on syntax errors.<commit_after>#include "compiler.h"
#include "generator.h"

#define BOOST_RESULT_OF_USE_DECLTYPE
#define BOOST_SPIRIT_USE_PHOENIX_V3

#include <algorithm>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/scope_exit.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <iostream> // for std::cerr in parser
#include <ostream>
#include <stdexcept>
#include <string>
#include <vector>

// ----- Program structs -------------------------------------------------------
namespace bf {

namespace instruction {

struct function_call_t {
    std::string function_name;
};

struct variable_declaration_t {
    std::string variable_name;
    int         init_value;
};

struct print_variable_t {
    std::string variable_name;
};

struct print_text_t {
    std::string text;
};

struct scan_variable_t {
    std::string variable_name;
};

} // namespace bf::instruction

typedef boost::variant<
    instruction::function_call_t,
    instruction::variable_declaration_t,
    instruction::print_variable_t,
    instruction::print_text_t,
    instruction::scan_variable_t
> instruction_t;

struct function_t {
    std::string name;
    std::vector<std::string> parameters;
    std::vector<instruction_t> instructions;
};

typedef std::vector<function_t> program_t;

} // namespace bf

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::function_call_t,
        (std::string, function_name))

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::variable_declaration_t,
        (std::string, variable_name)
        (int,         init_value))

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::print_variable_t,
        (std::string, variable_name))

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::print_text_t,
        (std::string, text))

BOOST_FUSION_ADAPT_STRUCT(
        bf::instruction::scan_variable_t,
        (std::string, variable_name))

BOOST_FUSION_ADAPT_STRUCT(
        bf::function_t,
        (std::string, name)
        (std::vector<std::string>, parameters)
        (std::vector<bf::instruction_t>, instructions))

// ----- Parser grammar --------------------------------------------------------
namespace bf {

namespace qi    = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

#define KEYWORDS (qi::lit("function") | "var" | "print" | "scan")
template <typename iterator>
struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
    grammar() : grammar::base_type(program) {
        program = *function;
        function = qi::lexeme["function"] > function_name
            > '(' > -(variable_name % ',') > ')'
            > '{' > *instruction > '}';
        function_name = qi::lexeme[+qi::alpha - KEYWORDS];
        variable_name = qi::lexeme[+qi::alpha - KEYWORDS];

        instruction = function_call
            | variable_declaration
            | print_variable
            | print_text
            | scan_variable;

        function_call        = function_name >> '(' > -(variable_name % ',') > ')' > ';';
        variable_declaration = qi::lexeme["var"] > variable_name > (('=' > qi::uint_) | qi::attr(0)) > ';';
        print_variable       = qi::lexeme["print"] >> variable_name > ';';
        print_text           = qi::lexeme["print"] >> qi::lexeme['"' > *(qi::char_ - '"') > '"'] > ';';
        scan_variable        = qi::lexeme["scan"] > variable_name > ';';

        program.name("program");
        function.name("function");
        function_name.name("function name");
        variable_name.name("variable name");
        instruction.name("instruction");
        function_call.name("function call");
        variable_declaration.name("variable declaration");
        print_variable.name("print variable");
        print_text.name("print text");
        scan_variable.name("scan variable");

        auto on_error = [](auto first, auto last, auto err, auto what) {
            std::string before(first, err);
            std::size_t bpos = before.find_last_of('\n');
            if (bpos != std::string::npos)
                before = before.substr(bpos + 1);

            std::string after(err, last);
            std::size_t apos = after.find_first_of('\n');
            if (apos != std::string::npos)
                after = after.substr(0, apos);

            std::cerr << "Error! Expecting " << what << " here:\n"
                << before << after << '\n'
                << std::string(before.size(), ' ') << '^'
                << std::endl;
        };

        qi::on_error<qi::fail>(program, boost::phoenix::bind(on_error, qi::_1, qi::_2, qi::_3, qi::_4));
    }

    qi::rule<iterator, program_t(),                           ascii::space_type> program;
    qi::rule<iterator, function_t(),                          ascii::space_type> function;
    qi::rule<iterator, std::string(),                         ascii::space_type> function_name;
    qi::rule<iterator, std::string(),                         ascii::space_type> variable_name;
    qi::rule<iterator, instruction_t(),                       ascii::space_type> instruction;

    qi::rule<iterator, instruction::function_call_t(),        ascii::space_type> function_call;
    qi::rule<iterator, instruction::variable_declaration_t(), ascii::space_type> variable_declaration;
    qi::rule<iterator, instruction::print_variable_t(),       ascii::space_type> print_variable;
    qi::rule<iterator, instruction::print_text_t(),           ascii::space_type> print_text;
    qi::rule<iterator, instruction::scan_variable_t(),        ascii::space_type> scan_variable;
};

// ----- Compilation algorithms ------------------------------------------------
program_t parse(const std::string &source) {
    // Build program struct from source input.
    grammar<decltype(source.begin())> g;
    program_t program;
    auto begin = source.begin(), end = source.end();
    const bool success = qi::phrase_parse(begin, end, g, ascii::space, program);

    if (!success || begin != end)
        throw std::logic_error("Parse unsuccessful!");

    // ----- Check program struct -----
    std::sort(program.begin(), program.end(),
            [](const function_t &f1, const function_t &f2) {return f1.name < f2.name;});
    // Ensure unique function names.
    if (program.size() > 1) {
        auto before_it = program.begin();
        for (auto it = before_it + 1; it != program.end(); ++before_it, ++it)
            if (before_it->name == it->name)
                throw std::logic_error("Function name used multiply times: " + it->name);
    }

    return program;
}

class instruction_visitor : public boost::static_visitor<void> {
public:
    instruction_visitor(const program_t &program) : m_program(program) {}

    void operator()(const instruction::function_call_t &i) {
        // Check if called function exists.
        auto function_it = std::find_if(m_program.begin(), m_program.end(),
                [&i](const function_t &f) {return f.name == i.function_name;});
        if (function_it == m_program.end())
            throw std::logic_error("Function not found: " + i.function_name);

        // Check for recursion (which is not supported).
        auto recursion_it = std::find(m_call_stack.begin(), m_call_stack.end(), i.function_name);
        if (recursion_it != m_call_stack.end()) {
            std::string call_stack_dump;
            for (const auto &function : m_call_stack)
                call_stack_dump += function + ", ";
            call_stack_dump += "(*) " + i.function_name;
            throw std::logic_error("Recursion not supported: " + call_stack_dump);
        }

        // Provide a clean scope for the called function.
        std::vector<std::map<std::string, generator::var_ptr>> scope_backup;
        std::swap(m_scope, scope_backup);
        m_scope.emplace_back();
        // TODO: Copy arguments
        // Restore old scope after the function returns.
        BOOST_SCOPE_EXIT(this_, &scope_backup) {
            std::swap(this_->m_scope, scope_backup);
        } BOOST_SCOPE_EXIT_END

        // Just for error report on recursion: Keep track of the call stack.
        m_call_stack.push_back(i.function_name);
        BOOST_SCOPE_EXIT(this_) {
            this_->m_call_stack.pop_back();
        } BOOST_SCOPE_EXIT_END

        // Finally, visit all instructions in the called function.
        for (const auto &instruction : function_it->instructions)
            boost::apply_visitor(*this, instruction);
    }

    void operator()(const instruction::variable_declaration_t &i) {
        auto it = m_scope.back().find(i.variable_name);
        if (it != m_scope.back().end())
            throw std::logic_error("Redeclaration of variable: " + i.variable_name);

        m_scope.back().emplace(i.variable_name, m_bfg.new_var(i.variable_name, i.init_value));
    }

    void operator()(const instruction::print_variable_t &i) {
        get_var(i.variable_name)->write_output();
    }

    void operator()(const instruction::print_text_t &i) {
        m_bfg.print(i.text);
    }

    void operator()(const instruction::scan_variable_t &i) {
        get_var(i.variable_name)->read_input();
    }

    const generator::var_ptr &get_var(const std::string &variable_name) const {
        for (auto scope_it = m_scope.rbegin(); scope_it != m_scope.rend(); ++scope_it) {
            auto it = scope_it->find(variable_name);
            if (it != scope_it->end())
                return it->second;
        }

        throw std::logic_error("Variable not declared in this scope: " + variable_name);
    }

    const generator &get_generator() const {
        return m_bfg;
    }

private:
    program_t                                              m_program; // TODO: just const ref?
    generator                                              m_bfg;
    std::vector<std::map<std::string, generator::var_ptr>> m_scope;
    std::vector<std::string>                               m_call_stack;
};

std::string generate(const program_t &program) {
    // As long as all function calls are inlined, this makes sense.
    instruction_visitor visitor(program);
    instruction::function_call_t call_to_main {"main"};
    instruction_t start = call_to_main;
    boost::apply_visitor(visitor, start);

    return visitor.get_generator().get_code();
}

std::string compiler::compile(const std::string &source) const {
    program_t program = parse(source);
    return generate(program);
}

} // namespace
<|endoftext|>


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

#include "ui/base/accelerators/accelerator.h"

#if defined(OS_WIN)
#include <windows.h>
#elif defined(TOOLKIT_USES_GTK)
#include <gdk/gdk.h>
#endif

#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "grit/ui_strings.h"
#include "ui/base/l10n/l10n_util.h"

namespace ui {

string16 Accelerator::GetShortcutText() const {
  int string_id = 0;
  switch(key_code_) {
    case ui::VKEY_TAB:
      string_id = IDS_APP_TAB_KEY;
      break;
    case ui::VKEY_RETURN:
      string_id = IDS_APP_ENTER_KEY;
      break;
    case ui::VKEY_ESCAPE:
      string_id = IDS_APP_ESC_KEY;
      break;
    case ui::VKEY_PRIOR:
      string_id = IDS_APP_PAGEUP_KEY;
      break;
    case ui::VKEY_NEXT:
      string_id = IDS_APP_PAGEDOWN_KEY;
      break;
    case ui::VKEY_END:
      string_id = IDS_APP_END_KEY;
      break;
    case ui::VKEY_HOME:
      string_id = IDS_APP_HOME_KEY;
      break;
    case ui::VKEY_INSERT:
      string_id = IDS_APP_INSERT_KEY;
      break;
    case ui::VKEY_DELETE:
      string_id = IDS_APP_DELETE_KEY;
      break;
    case ui::VKEY_LEFT:
      string_id = IDS_APP_LEFT_ARROW_KEY;
      break;
    case ui::VKEY_RIGHT:
      string_id = IDS_APP_RIGHT_ARROW_KEY;
      break;
    case ui::VKEY_BACK:
      string_id = IDS_APP_BACKSPACE_KEY;
      break;
    case ui::VKEY_F1:
      string_id = IDS_APP_F1_KEY;
      break;
    case ui::VKEY_F11:
      string_id = IDS_APP_F11_KEY;
      break;
    default:
      break;
  }

  string16 shortcut;
  if (!string_id) {
#if defined(OS_WIN)
    // Our fallback is to try translate the key code to a regular character
    // unless it is one of digits (VK_0 to VK_9). Some keyboard
    // layouts have characters other than digits assigned in
    // an unshifted mode (e.g. French AZERY layout has 'a with grave
    // accent' for '0'). For display in the menu (e.g. Ctrl-0 for the
    // default zoom level), we leave VK_[0-9] alone without translation.
    wchar_t key;
    if (key_code_ >= '0' && key_code_ <= '9')
      key = key_code_;
    else
      key = LOWORD(::MapVirtualKeyW(key_code_, MAPVK_VK_TO_CHAR));
    shortcut += key;
#elif defined(TOOLKIT_USES_GTK)
    const gchar* name = NULL;
    switch (key_code_) {
      case ui::VKEY_OEM_2:
        name = static_cast<const gchar*>("/");
        break;
      default:
        name = gdk_keyval_name(gdk_keyval_to_lower(key_code_));
        break;
    }
    if (name) {
      if (name[0] != 0 && name[1] == 0)
        shortcut += static_cast<string16::value_type>(g_ascii_toupper(name[0]));
      else
        shortcut += UTF8ToUTF16(name);
    }
#endif
  } else {
    shortcut = l10n_util::GetStringUTF16(string_id);
  }

  // Checking whether the character used for the accelerator is alphanumeric.
  // If it is not, then we need to adjust the string later on if the locale is
  // right-to-left. See below for more information of why such adjustment is
  // required.
  string16 shortcut_rtl;
  bool adjust_shortcut_for_rtl = false;
  if (base::i18n::IsRTL() && shortcut.length() == 1 &&
      !IsAsciiAlpha(shortcut[0]) && !IsAsciiDigit(shortcut[0])) {
    adjust_shortcut_for_rtl = true;
    shortcut_rtl.assign(shortcut);
  }

  if (IsShiftDown())
    shortcut = l10n_util::GetStringFUTF16(IDS_APP_SHIFT_MODIFIER, shortcut);

  // Note that we use 'else-if' in order to avoid using Ctrl+Alt as a shortcut.
  // See http://blogs.msdn.com/oldnewthing/archive/2004/03/29/101121.aspx for
  // more information.
  if (IsCtrlDown())
    shortcut = l10n_util::GetStringFUTF16(IDS_APP_CONTROL_MODIFIER, shortcut);
  else if (IsAltDown())
    shortcut = l10n_util::GetStringFUTF16(IDS_APP_ALT_MODIFIER, shortcut);

  // For some reason, menus in Windows ignore standard Unicode directionality
  // marks (such as LRE, PDF, etc.). On RTL locales, we use RTL menus and
  // therefore any text we draw for the menu items is drawn in an RTL context.
  // Thus, the text "Ctrl++" (which we currently use for the Zoom In option)
  // appears as "++Ctrl" in RTL because the Unicode BiDi algorithm puts
  // punctuations on the left when the context is right-to-left. Shortcuts that
  // do not end with a punctuation mark (such as "Ctrl+H" do not have this
  // problem).
  //
  // The only way to solve this problem is to adjust the string if the locale
  // is RTL so that it is drawn correnctly in an RTL context. Instead of
  // returning "Ctrl++" in the above example, we return "++Ctrl". This will
  // cause the text to appear as "Ctrl++" when Windows draws the string in an
  // RTL context because the punctunation no longer appears at the end of the
  // string.
  //
  // TODO(idana) bug# 1232732: this hack can be avoided if instead of using
  // views::Menu we use views::MenuItemView because the latter is a View
  // subclass and therefore it supports marking text as RTL or LTR using
  // standard Unicode directionality marks.
  if (adjust_shortcut_for_rtl) {
    int key_length = static_cast<int>(shortcut_rtl.length());
    DCHECK_GT(key_length, 0);
    shortcut_rtl.append(ASCIIToUTF16("+"));

    // Subtracting the size of the shortcut key and 1 for the '+' sign.
    shortcut_rtl.append(shortcut, 0, shortcut.length() - key_length - 1);
    shortcut.swap(shortcut_rtl);
  }

  return shortcut;
}

}  // namespace ui
<commit_msg>Implement Accelerator::GetShortcutText for non-Windows Aura.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/accelerators/accelerator.h"

#if defined(OS_WIN)
#include <windows.h>
#elif defined(TOOLKIT_USES_GTK)
#include <gdk/gdk.h>
#endif

#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "grit/ui_strings.h"
#include "ui/base/l10n/l10n_util.h"

#if !defined(OS_WIN) && defined(USE_AURA)
#include "ui/base/keycodes/keyboard_code_conversion.h"
#endif

namespace ui {

string16 Accelerator::GetShortcutText() const {
  int string_id = 0;
  switch(key_code_) {
    case ui::VKEY_TAB:
      string_id = IDS_APP_TAB_KEY;
      break;
    case ui::VKEY_RETURN:
      string_id = IDS_APP_ENTER_KEY;
      break;
    case ui::VKEY_ESCAPE:
      string_id = IDS_APP_ESC_KEY;
      break;
    case ui::VKEY_PRIOR:
      string_id = IDS_APP_PAGEUP_KEY;
      break;
    case ui::VKEY_NEXT:
      string_id = IDS_APP_PAGEDOWN_KEY;
      break;
    case ui::VKEY_END:
      string_id = IDS_APP_END_KEY;
      break;
    case ui::VKEY_HOME:
      string_id = IDS_APP_HOME_KEY;
      break;
    case ui::VKEY_INSERT:
      string_id = IDS_APP_INSERT_KEY;
      break;
    case ui::VKEY_DELETE:
      string_id = IDS_APP_DELETE_KEY;
      break;
    case ui::VKEY_LEFT:
      string_id = IDS_APP_LEFT_ARROW_KEY;
      break;
    case ui::VKEY_RIGHT:
      string_id = IDS_APP_RIGHT_ARROW_KEY;
      break;
    case ui::VKEY_BACK:
      string_id = IDS_APP_BACKSPACE_KEY;
      break;
    case ui::VKEY_F1:
      string_id = IDS_APP_F1_KEY;
      break;
    case ui::VKEY_F11:
      string_id = IDS_APP_F11_KEY;
      break;
    default:
      break;
  }

  string16 shortcut;
  if (!string_id) {
#if defined(OS_WIN)
    // Our fallback is to try translate the key code to a regular character
    // unless it is one of digits (VK_0 to VK_9). Some keyboard
    // layouts have characters other than digits assigned in
    // an unshifted mode (e.g. French AZERY layout has 'a with grave
    // accent' for '0'). For display in the menu (e.g. Ctrl-0 for the
    // default zoom level), we leave VK_[0-9] alone without translation.
    wchar_t key;
    if (key_code_ >= '0' && key_code_ <= '9')
      key = key_code_;
    else
      key = LOWORD(::MapVirtualKeyW(key_code_, MAPVK_VK_TO_CHAR));
    shortcut += key;
#elif defined(USE_AURA)
    const uint16 c = GetCharacterFromKeyCode(key_code_, false);
    if (c != 0) {
      shortcut += static_cast<string16::value_type>(base::ToUpperASCII(c));
    }
#elif defined(TOOLKIT_USES_GTK)
    const gchar* name = NULL;
    switch (key_code_) {
      case ui::VKEY_OEM_2:
        name = static_cast<const gchar*>("/");
        break;
      default:
        name = gdk_keyval_name(gdk_keyval_to_lower(key_code_));
        break;
    }
    if (name) {
      if (name[0] != 0 && name[1] == 0)
        shortcut += static_cast<string16::value_type>(g_ascii_toupper(name[0]));
      else
        shortcut += UTF8ToUTF16(name);
    }
#endif
  } else {
    shortcut = l10n_util::GetStringUTF16(string_id);
  }

  // Checking whether the character used for the accelerator is alphanumeric.
  // If it is not, then we need to adjust the string later on if the locale is
  // right-to-left. See below for more information of why such adjustment is
  // required.
  string16 shortcut_rtl;
  bool adjust_shortcut_for_rtl = false;
  if (base::i18n::IsRTL() && shortcut.length() == 1 &&
      !IsAsciiAlpha(shortcut[0]) && !IsAsciiDigit(shortcut[0])) {
    adjust_shortcut_for_rtl = true;
    shortcut_rtl.assign(shortcut);
  }

  if (IsShiftDown())
    shortcut = l10n_util::GetStringFUTF16(IDS_APP_SHIFT_MODIFIER, shortcut);

  // Note that we use 'else-if' in order to avoid using Ctrl+Alt as a shortcut.
  // See http://blogs.msdn.com/oldnewthing/archive/2004/03/29/101121.aspx for
  // more information.
  if (IsCtrlDown())
    shortcut = l10n_util::GetStringFUTF16(IDS_APP_CONTROL_MODIFIER, shortcut);
  else if (IsAltDown())
    shortcut = l10n_util::GetStringFUTF16(IDS_APP_ALT_MODIFIER, shortcut);

  // For some reason, menus in Windows ignore standard Unicode directionality
  // marks (such as LRE, PDF, etc.). On RTL locales, we use RTL menus and
  // therefore any text we draw for the menu items is drawn in an RTL context.
  // Thus, the text "Ctrl++" (which we currently use for the Zoom In option)
  // appears as "++Ctrl" in RTL because the Unicode BiDi algorithm puts
  // punctuations on the left when the context is right-to-left. Shortcuts that
  // do not end with a punctuation mark (such as "Ctrl+H" do not have this
  // problem).
  //
  // The only way to solve this problem is to adjust the string if the locale
  // is RTL so that it is drawn correnctly in an RTL context. Instead of
  // returning "Ctrl++" in the above example, we return "++Ctrl". This will
  // cause the text to appear as "Ctrl++" when Windows draws the string in an
  // RTL context because the punctunation no longer appears at the end of the
  // string.
  //
  // TODO(idana) bug# 1232732: this hack can be avoided if instead of using
  // views::Menu we use views::MenuItemView because the latter is a View
  // subclass and therefore it supports marking text as RTL or LTR using
  // standard Unicode directionality marks.
  if (adjust_shortcut_for_rtl) {
    int key_length = static_cast<int>(shortcut_rtl.length());
    DCHECK_GT(key_length, 0);
    shortcut_rtl.append(ASCIIToUTF16("+"));

    // Subtracting the size of the shortcut key and 1 for the '+' sign.
    shortcut_rtl.append(shortcut, 0, shortcut.length() - key_length - 1);
    shortcut.swap(shortcut_rtl);
  }

  return shortcut;
}

}  // namespace ui
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2009 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreShaderScriptTranslator.h"
#include "OgrePass.h"
#include "OgreTechnique.h"
#include "OgreMaterial.h"
#include "OgreShaderGenerator.h"

namespace Ogre {
namespace RTShader {

//-----------------------------------------------------------------------------
void SGScriptTranslator::translate(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
	ObjectAbstractNode* obj = reinterpret_cast<ObjectAbstractNode*>(node.get());
	ObjectAbstractNode* parent = reinterpret_cast<ObjectAbstractNode*>(obj->parent);

	// Translate section within a pass context.
	if (parent->cls == "pass")
	{
		translatePass(compiler, node);
	}
	if (parent->cls == "texture_unit")
	{
		translateTextureUnit(compiler, node);
	}
}

//-----------------------------------------------------------------------------
SGScriptTranslator::TexturesParamCollection SGScriptTranslator::getParamCollection()
{
	return mParamCollection;
}

//-----------------------------------------------------------------------------
void SGScriptTranslator::clearParamCollection()
{
	mParamCollection.clear();
}

//-----------------------------------------------------------------------------
/*
note: we can know the texture unit index by getting parent then finding it in the list of children
*/
void SGScriptTranslator::translateTextureUnit(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
	ObjectAbstractNode *obj = reinterpret_cast<ObjectAbstractNode*>(node.get());
	TextureUnitState* textureUnitState = any_cast<TextureUnitState*>(obj->parent->context);
	String strValue = "";

	Properties properties;
	for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
	{
		if((*i)->type == ANT_PROPERTY)
		{
			PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
			AbstractNodeList::const_iterator it = prop->values.begin();
			PropertyValues popertyValues;
			for( ;it != prop->values.end(); ++it)
			{
				if(true == SGScriptTranslator::getString(*it, &strValue))
				{
					popertyValues.push_back(strValue);
				}
			}
			properties[prop->name] = popertyValues;
		}
	}
	mParamCollection[textureUnitState] = properties;
}

//-----------------------------------------------------------------------------
void SGScriptTranslator::translatePass(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
	ObjectAbstractNode *obj = reinterpret_cast<ObjectAbstractNode*>(node.get());
	Pass* pass = any_cast<Pass*>(obj->parent->context);
	Technique* technique = pass->getParent();
	Material* material = technique->getParent();
	ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr();
	String dstTechniqueSchemeName = obj->name;
	bool techniqueCreated;

	// Make sure the scheme name is valid - use default if none exists.
	if (dstTechniqueSchemeName.empty())
		dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME;

	// Create the shader based technique.
	techniqueCreated = shaderGenerator->createShaderBasedTechnique(material->getName(),
		technique->getSchemeName(),
		dstTechniqueSchemeName);

	// Case technique successfully created.
	if (techniqueCreated)
	{
		// Go over all the render state properties.
		for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
		{
			if((*i)->type == ANT_PROPERTY)
			{
				PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
				SubRenderState* subRenderState;

				// Handle light count property.
				if (prop->name == "light_count")
				{
					if (prop->values.size() != 3)
					{
						compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
					}
					else
					{
						int lightCount[3];

						if (false == SGScriptTranslator::getInts(prop->values.begin(), prop->values.end(), lightCount, 3))
						{
							compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
						}
						else
						{
							shaderGenerator->createScheme(dstTechniqueSchemeName);
							RenderState* renderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, material->getName(), pass->getIndex());

							renderState->setLightCount(lightCount);
							renderState->setLightCountAutoUpdate(false);
						}
					}
				}

				// Handle the rest of the custom properties.
				else
				{
					subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, pass, this);
					if (subRenderState != NULL)
					{
						shaderGenerator->createScheme(dstTechniqueSchemeName);
						RenderState* renderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, material->getName(), pass->getIndex());

						renderState->addTemplateSubRenderState(subRenderState);
					}
				}
			}
			else
			{
				processNode(compiler, *i);
			}
		}
	}
}

}
}
<commit_msg>Being picky.  Correct a variable name typo.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2009 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreShaderScriptTranslator.h"
#include "OgrePass.h"
#include "OgreTechnique.h"
#include "OgreMaterial.h"
#include "OgreShaderGenerator.h"

namespace Ogre {
namespace RTShader {

//-----------------------------------------------------------------------------
void SGScriptTranslator::translate(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
	ObjectAbstractNode* obj = reinterpret_cast<ObjectAbstractNode*>(node.get());
	ObjectAbstractNode* parent = reinterpret_cast<ObjectAbstractNode*>(obj->parent);

	// Translate section within a pass context.
	if (parent->cls == "pass")
	{
		translatePass(compiler, node);
	}
	if (parent->cls == "texture_unit")
	{
		translateTextureUnit(compiler, node);
	}
}

//-----------------------------------------------------------------------------
SGScriptTranslator::TexturesParamCollection SGScriptTranslator::getParamCollection()
{
	return mParamCollection;
}

//-----------------------------------------------------------------------------
void SGScriptTranslator::clearParamCollection()
{
	mParamCollection.clear();
}

//-----------------------------------------------------------------------------
/*
note: we can know the texture unit index by getting parent then finding it in the list of children
*/
void SGScriptTranslator::translateTextureUnit(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
	ObjectAbstractNode *obj = reinterpret_cast<ObjectAbstractNode*>(node.get());
	TextureUnitState* textureUnitState = any_cast<TextureUnitState*>(obj->parent->context);
	String strValue = "";

	Properties properties;
	for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
	{
		if((*i)->type == ANT_PROPERTY)
		{
			PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
			AbstractNodeList::const_iterator it = prop->values.begin();
			PropertyValues propertyValues;
			for( ;it != prop->values.end(); ++it)
			{
				if(true == SGScriptTranslator::getString(*it, &strValue))
				{
					propertyValues.push_back(strValue);
				}
			}
			properties[prop->name] = propertyValues;
		}
	}
	mParamCollection[textureUnitState] = properties;
}

//-----------------------------------------------------------------------------
void SGScriptTranslator::translatePass(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
	ObjectAbstractNode *obj = reinterpret_cast<ObjectAbstractNode*>(node.get());
	Pass* pass = any_cast<Pass*>(obj->parent->context);
	Technique* technique = pass->getParent();
	Material* material = technique->getParent();
	ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr();
	String dstTechniqueSchemeName = obj->name;
	bool techniqueCreated;

	// Make sure the scheme name is valid - use default if none exists.
	if (dstTechniqueSchemeName.empty())
		dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME;

	// Create the shader based technique.
	techniqueCreated = shaderGenerator->createShaderBasedTechnique(material->getName(),
		technique->getSchemeName(),
		dstTechniqueSchemeName);

	// Case technique successfully created.
	if (techniqueCreated)
	{
		// Go over all the render state properties.
		for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
		{
			if((*i)->type == ANT_PROPERTY)
			{
				PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
				SubRenderState* subRenderState;

				// Handle light count property.
				if (prop->name == "light_count")
				{
					if (prop->values.size() != 3)
					{
						compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
					}
					else
					{
						int lightCount[3];

						if (false == SGScriptTranslator::getInts(prop->values.begin(), prop->values.end(), lightCount, 3))
						{
							compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
						}
						else
						{
							shaderGenerator->createScheme(dstTechniqueSchemeName);
							RenderState* renderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, material->getName(), pass->getIndex());

							renderState->setLightCount(lightCount);
							renderState->setLightCountAutoUpdate(false);
						}
					}
				}

				// Handle the rest of the custom properties.
				else
				{
					subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, pass, this);
					if (subRenderState != NULL)
					{
						shaderGenerator->createScheme(dstTechniqueSchemeName);
						RenderState* renderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, material->getName(), pass->getIndex());

						renderState->addTemplateSubRenderState(subRenderState);
					}
				}
			}
			else
			{
				processNode(compiler, *i);
			}
		}
	}
}

}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "ui/base/cursor/cursor_loader_win.h"

#include "base/lazy_instance.h"
#include "base/strings/string16.h"
#include "ui/base/cursor/cursor.h"
#include "ui/resources/grit/ui_unscaled_resources.h"

namespace ui {

namespace {

base::LazyInstance<base::string16> g_cursor_resource_module_name;

const wchar_t* GetCursorId(gfx::NativeCursor native_cursor) {
  switch (native_cursor.native_type()) {
    case kCursorNull:
      return IDC_ARROW;
    case kCursorPointer:
      return IDC_ARROW;
    case kCursorCross:
      return IDC_CROSS;
    case kCursorHand:
      return IDC_HAND;
    case kCursorIBeam:
      return IDC_IBEAM;
    case kCursorWait:
      return IDC_WAIT;
    case kCursorHelp:
      return IDC_HELP;
    case kCursorEastResize:
      return IDC_SIZEWE;
    case kCursorNorthResize:
      return IDC_SIZENS;
    case kCursorNorthEastResize:
      return IDC_SIZENESW;
    case kCursorNorthWestResize:
      return IDC_SIZENWSE;
    case kCursorSouthResize:
      return IDC_SIZENS;
    case kCursorSouthEastResize:
      return IDC_SIZENWSE;
    case kCursorSouthWestResize:
      return IDC_SIZENESW;
    case kCursorWestResize:
      return IDC_SIZEWE;
    case kCursorNorthSouthResize:
      return IDC_SIZENS;
    case kCursorEastWestResize:
      return IDC_SIZEWE;
    case kCursorNorthEastSouthWestResize:
      return IDC_SIZENESW;
    case kCursorNorthWestSouthEastResize:
      return IDC_SIZENWSE;
    case kCursorMove:
      return IDC_SIZEALL;
    case kCursorProgress:
      return IDC_APPSTARTING;
    case kCursorNoDrop:
      return IDC_NO;
    case kCursorNotAllowed:
      return IDC_NO;
    case kCursorColumnResize:
      return MAKEINTRESOURCE(IDC_COLRESIZE);
    case kCursorRowResize:
      return MAKEINTRESOURCE(IDC_ROWRESIZE);
    case kCursorMiddlePanning:
      return MAKEINTRESOURCE(IDC_PAN_MIDDLE);
    case kCursorEastPanning:
      return MAKEINTRESOURCE(IDC_PAN_EAST);
    case kCursorNorthPanning:
      return MAKEINTRESOURCE(IDC_PAN_NORTH);
    case kCursorNorthEastPanning:
      return MAKEINTRESOURCE(IDC_PAN_NORTH_EAST);
    case kCursorNorthWestPanning:
      return MAKEINTRESOURCE(IDC_PAN_NORTH_WEST);
    case kCursorSouthPanning:
      return MAKEINTRESOURCE(IDC_PAN_SOUTH);
    case kCursorSouthEastPanning:
      return MAKEINTRESOURCE(IDC_PAN_SOUTH_EAST);
    case kCursorSouthWestPanning:
      return MAKEINTRESOURCE(IDC_PAN_SOUTH_WEST);
    case kCursorWestPanning:
      return MAKEINTRESOURCE(IDC_PAN_WEST);
    case kCursorVerticalText:
      return MAKEINTRESOURCE(IDC_VERTICALTEXT);
    case kCursorCell:
      return MAKEINTRESOURCE(IDC_CELL);
    case kCursorZoomIn:
      return MAKEINTRESOURCE(IDC_ZOOMIN);
    case kCursorZoomOut:
      return MAKEINTRESOURCE(IDC_ZOOMOUT);
    case kCursorGrab:
      return MAKEINTRESOURCE(IDC_HAND_GRAB);
    case kCursorGrabbing:
      return MAKEINTRESOURCE(IDC_HAND_GRABBING);
    case kCursorCopy:
      return MAKEINTRESOURCE(IDC_COPYCUR);
    case kCursorAlias:
      return MAKEINTRESOURCE(IDC_ALIAS);
    case kCursorNone:
      return MAKEINTRESOURCE(IDC_CURSOR_NONE);
    case kCursorContextMenu:
    case kCursorCustom:
      NOTIMPLEMENTED();
      return IDC_ARROW;
    default:
      NOTREACHED();
      return IDC_ARROW;
  }
}

}  // namespace

CursorLoader* CursorLoader::Create() {
  return new CursorLoaderWin;
}

CursorLoaderWin::CursorLoaderWin() {
}

CursorLoaderWin::~CursorLoaderWin() {
}

void CursorLoaderWin::LoadImageCursor(int id,
                                      int resource_id,
                                      const gfx::Point& hot) {
  // NOTIMPLEMENTED();
}

void CursorLoaderWin::LoadAnimatedCursor(int id,
                                         int resource_id,
                                         const gfx::Point& hot,
                                         int frame_delay_ms) {
  // NOTIMPLEMENTED();
}

void CursorLoaderWin::UnloadAll() {
  // NOTIMPLEMENTED();
}

void CursorLoaderWin::SetPlatformCursor(gfx::NativeCursor* cursor) {
  if (cursor->native_type() != kCursorCustom) {
    if (cursor->platform()) {
      cursor->SetPlatformCursor(cursor->platform());
    } else {
      const wchar_t* cursor_id = GetCursorId(*cursor);
      PlatformCursor platform_cursor = LoadCursor(NULL, cursor_id);
      if (!platform_cursor && !g_cursor_resource_module_name.Get().empty()) {
        platform_cursor = LoadCursor(
            GetModuleHandle(g_cursor_resource_module_name.Get().c_str()),
                            cursor_id);
      }
      cursor->SetPlatformCursor(platform_cursor);
    }
  }
}

// static
void CursorLoaderWin::SetCursorResourceModule(
    const base::string16& module_name) {
  g_cursor_resource_module_name.Get() = module_name;
}

}  // namespace ui
<commit_msg>[WIN] LoadCursor from the current executable<commit_after>// Copyright (c) 2012 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 "ui/base/cursor/cursor_loader_win.h"

#include "base/lazy_instance.h"
#include "base/strings/string16.h"
#include "ui/base/cursor/cursor.h"
#include "ui/resources/grit/ui_unscaled_resources.h"

namespace ui {

namespace {

base::LazyInstance<base::string16> g_cursor_resource_module_name;

const wchar_t* GetCursorId(gfx::NativeCursor native_cursor) {
  switch (native_cursor.native_type()) {
    case kCursorNull:
      return IDC_ARROW;
    case kCursorPointer:
      return IDC_ARROW;
    case kCursorCross:
      return IDC_CROSS;
    case kCursorHand:
      return IDC_HAND;
    case kCursorIBeam:
      return IDC_IBEAM;
    case kCursorWait:
      return IDC_WAIT;
    case kCursorHelp:
      return IDC_HELP;
    case kCursorEastResize:
      return IDC_SIZEWE;
    case kCursorNorthResize:
      return IDC_SIZENS;
    case kCursorNorthEastResize:
      return IDC_SIZENESW;
    case kCursorNorthWestResize:
      return IDC_SIZENWSE;
    case kCursorSouthResize:
      return IDC_SIZENS;
    case kCursorSouthEastResize:
      return IDC_SIZENWSE;
    case kCursorSouthWestResize:
      return IDC_SIZENESW;
    case kCursorWestResize:
      return IDC_SIZEWE;
    case kCursorNorthSouthResize:
      return IDC_SIZENS;
    case kCursorEastWestResize:
      return IDC_SIZEWE;
    case kCursorNorthEastSouthWestResize:
      return IDC_SIZENESW;
    case kCursorNorthWestSouthEastResize:
      return IDC_SIZENWSE;
    case kCursorMove:
      return IDC_SIZEALL;
    case kCursorProgress:
      return IDC_APPSTARTING;
    case kCursorNoDrop:
      return IDC_NO;
    case kCursorNotAllowed:
      return IDC_NO;
    case kCursorColumnResize:
      return MAKEINTRESOURCE(IDC_COLRESIZE);
    case kCursorRowResize:
      return MAKEINTRESOURCE(IDC_ROWRESIZE);
    case kCursorMiddlePanning:
      return MAKEINTRESOURCE(IDC_PAN_MIDDLE);
    case kCursorEastPanning:
      return MAKEINTRESOURCE(IDC_PAN_EAST);
    case kCursorNorthPanning:
      return MAKEINTRESOURCE(IDC_PAN_NORTH);
    case kCursorNorthEastPanning:
      return MAKEINTRESOURCE(IDC_PAN_NORTH_EAST);
    case kCursorNorthWestPanning:
      return MAKEINTRESOURCE(IDC_PAN_NORTH_WEST);
    case kCursorSouthPanning:
      return MAKEINTRESOURCE(IDC_PAN_SOUTH);
    case kCursorSouthEastPanning:
      return MAKEINTRESOURCE(IDC_PAN_SOUTH_EAST);
    case kCursorSouthWestPanning:
      return MAKEINTRESOURCE(IDC_PAN_SOUTH_WEST);
    case kCursorWestPanning:
      return MAKEINTRESOURCE(IDC_PAN_WEST);
    case kCursorVerticalText:
      return MAKEINTRESOURCE(IDC_VERTICALTEXT);
    case kCursorCell:
      return MAKEINTRESOURCE(IDC_CELL);
    case kCursorZoomIn:
      return MAKEINTRESOURCE(IDC_ZOOMIN);
    case kCursorZoomOut:
      return MAKEINTRESOURCE(IDC_ZOOMOUT);
    case kCursorGrab:
      return MAKEINTRESOURCE(IDC_HAND_GRAB);
    case kCursorGrabbing:
      return MAKEINTRESOURCE(IDC_HAND_GRABBING);
    case kCursorCopy:
      return MAKEINTRESOURCE(IDC_COPYCUR);
    case kCursorAlias:
      return MAKEINTRESOURCE(IDC_ALIAS);
    case kCursorNone:
      return MAKEINTRESOURCE(IDC_CURSOR_NONE);
    case kCursorContextMenu:
    case kCursorCustom:
      NOTIMPLEMENTED();
      return IDC_ARROW;
    default:
      NOTREACHED();
      return IDC_ARROW;
  }
}

}  // namespace

CursorLoader* CursorLoader::Create() {
  return new CursorLoaderWin;
}

CursorLoaderWin::CursorLoaderWin() {
}

CursorLoaderWin::~CursorLoaderWin() {
}

void CursorLoaderWin::LoadImageCursor(int id,
                                      int resource_id,
                                      const gfx::Point& hot) {
  // NOTIMPLEMENTED();
}

void CursorLoaderWin::LoadAnimatedCursor(int id,
                                         int resource_id,
                                         const gfx::Point& hot,
                                         int frame_delay_ms) {
  // NOTIMPLEMENTED();
}

void CursorLoaderWin::UnloadAll() {
  // NOTIMPLEMENTED();
}

void CursorLoaderWin::SetPlatformCursor(gfx::NativeCursor* cursor) {
  if (cursor->native_type() != kCursorCustom) {
    if (cursor->platform()) {
      cursor->SetPlatformCursor(cursor->platform());
    } else {
      const wchar_t* cursor_id = GetCursorId(*cursor);
      PlatformCursor platform_cursor = LoadCursor(NULL, cursor_id);
      if (!platform_cursor) {
        //node-webkit: we don't use g_cursor_resource_module_name
        //because it's not fixed as Chrome
        platform_cursor = LoadCursor(GetModuleHandle(NULL), cursor_id);
      }
      cursor->SetPlatformCursor(platform_cursor);
    }
  }
}

// static
void CursorLoaderWin::SetCursorResourceModule(
    const base::string16& module_name) {
  g_cursor_resource_module_name.Get() = module_name;
}

}  // namespace ui
<|endoftext|>


<commit_before><commit_msg>gtk: Remove Backspace and Shift-Backspace accelerators.<commit_after><|endoftext|>


<commit_before><commit_msg>[linux] Skip stats question dialog on Linux if managed by policy.<commit_after><|endoftext|>


<commit_before><commit_msg>Wrap the task manager treeview in a GtkScrolledWindow in order to have a frame around it.<commit_after><|endoftext|>


<commit_before><commit_msg>Make Chrome default after importing from current default browser.<commit_after><|endoftext|>


<commit_before>/*
Copyright (C) 2001-2011 by Serge Lamikhov-Center

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef ELFIO_SEGMENT_HPP
#define ELFIO_SEGMENT_HPP

#include <fstream>
#include <vector>

namespace ELFIO {

class segment
{
    friend class elfio;
  public:
    virtual ~segment() {};

    virtual Elf_Half get_index() const = 0;

    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,   type             );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,   flags            );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  align            );
    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address  );
    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  file_size        );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  memory_size      );

    virtual const char* get_data() const = 0;

    virtual Elf_Half add_section_index( Elf_Half index, Elf_Xword addr_align ) = 0;
    virtual Elf_Half get_sections_num()                                  const = 0;
    virtual Elf_Half get_section_index_at( Elf_Half num )                const = 0;

  protected:
    virtual void set_index( Elf_Half )                                             = 0;
    virtual void load( std::ifstream& stream, std::streampos header_offset ) const = 0;
    virtual void save( std::ofstream& f, std::streampos header_offset,
                       std::streampos data_offset )                                = 0;
};

//------------------------------------------------------------------------------
template< class T >
class segment_impl : public segment
{
  public:
//------------------------------------------------------------------------------
    segment_impl( endianess_convertor* convertor_ ) :
        convertor( convertor_ )
    {
        std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' );
        data = 0;
    }

//------------------------------------------------------------------------------
    virtual ~segment_impl()
    {
        delete [] data;
    }

//------------------------------------------------------------------------------
    // Section info functions
    ELFIO_GET_SET_ACCESS( Elf_Word,   type,             ph.p_type   );
    ELFIO_GET_SET_ACCESS( Elf_Word,   flags,            ph.p_flags  );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  align,            ph.p_align  );
    ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address,  ph.p_vaddr  );
    ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr  );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  file_size,        ph.p_filesz );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  memory_size,      ph.p_memsz  );

//------------------------------------------------------------------------------
    Elf_Half
    get_index() const
    {
        return index;
    }

//------------------------------------------------------------------------------
    const char*
    get_data() const
    {
        return data;
    }

//------------------------------------------------------------------------------
    Elf_Half
    add_section_index( Elf_Half index, Elf_Xword addr_align )
    {
        sections.push_back( index );
        if ( addr_align > get_align() ) {
            set_align( addr_align );
        }

        return (Elf_Half)sections.size();
    }

//------------------------------------------------------------------------------
    Elf_Half
    get_sections_num() const
    {
        return (Elf_Half)sections.size();
    }

//------------------------------------------------------------------------------
    Elf_Half
    get_section_index_at( Elf_Half num ) const
    {
        if ( num < sections.size() ) {
            return sections[num];
        }

        return -1;
    }

//------------------------------------------------------------------------------
  protected:
//------------------------------------------------------------------------------
    void
    set_index( Elf_Half value )
    {
        index = value;
    }

//------------------------------------------------------------------------------
    void
    load( std::ifstream& stream,
          std::streampos header_offset ) const
    {
        stream.seekg( header_offset );
        stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) );

        if ( PT_NULL != get_type() && 0 != get_file_size() ) {
            stream.seekg( (*convertor)( ph.p_offset ) );
            Elf_Xword size = get_file_size();
            data = new char[size];
            if ( 0 != data ) {
                stream.read( data, size );
            }
        }
    }

//------------------------------------------------------------------------------
    void save( std::ofstream& f,
               std::streampos header_offset,
               std::streampos data_offset )
    {
        ph.p_offset = data_offset;
        f.seekp( header_offset );
        f.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) );
    }

//------------------------------------------------------------------------------
  private:
    mutable T             ph;
    Elf_Half              index;
    mutable char*         data;
    std::vector<Elf_Half> sections;
    endianess_convertor*  convertor;
};

} // namespace ELFIO

#endif // ELFIO_SEGMENT_HPP
<commit_msg>Ticket #9: Segment offset written in wrong endianess.<commit_after>/*
Copyright (C) 2001-2011 by Serge Lamikhov-Center

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef ELFIO_SEGMENT_HPP
#define ELFIO_SEGMENT_HPP

#include <fstream>
#include <vector>

namespace ELFIO {

class segment
{
    friend class elfio;
  public:
    virtual ~segment() {};

    virtual Elf_Half get_index() const = 0;

    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,   type             );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,   flags            );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  align            );
    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address  );
    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  file_size        );
    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  memory_size      );

    virtual const char* get_data() const = 0;

    virtual Elf_Half add_section_index( Elf_Half index, Elf_Xword addr_align ) = 0;
    virtual Elf_Half get_sections_num()                                  const = 0;
    virtual Elf_Half get_section_index_at( Elf_Half num )                const = 0;

  protected:
    virtual void set_index( Elf_Half )                                             = 0;
    virtual void load( std::ifstream& stream, std::streampos header_offset ) const = 0;
    virtual void save( std::ofstream& f, std::streampos header_offset,
                       std::streampos data_offset )                                = 0;
};

//------------------------------------------------------------------------------
template< class T >
class segment_impl : public segment
{
  public:
//------------------------------------------------------------------------------
    segment_impl( endianess_convertor* convertor_ ) :
        convertor( convertor_ )
    {
        std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' );
        data = 0;
    }

//------------------------------------------------------------------------------
    virtual ~segment_impl()
    {
        delete [] data;
    }

//------------------------------------------------------------------------------
    // Section info functions
    ELFIO_GET_SET_ACCESS( Elf_Word,   type,             ph.p_type   );
    ELFIO_GET_SET_ACCESS( Elf_Word,   flags,            ph.p_flags  );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  align,            ph.p_align  );
    ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address,  ph.p_vaddr  );
    ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr  );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  file_size,        ph.p_filesz );
    ELFIO_GET_SET_ACCESS( Elf_Xword,  memory_size,      ph.p_memsz  );

//------------------------------------------------------------------------------
    Elf_Half
    get_index() const
    {
        return index;
    }

//------------------------------------------------------------------------------
    const char*
    get_data() const
    {
        return data;
    }

//------------------------------------------------------------------------------
    Elf_Half
    add_section_index( Elf_Half index, Elf_Xword addr_align )
    {
        sections.push_back( index );
        if ( addr_align > get_align() ) {
            set_align( addr_align );
        }

        return (Elf_Half)sections.size();
    }

//------------------------------------------------------------------------------
    Elf_Half
    get_sections_num() const
    {
        return (Elf_Half)sections.size();
    }

//------------------------------------------------------------------------------
    Elf_Half
    get_section_index_at( Elf_Half num ) const
    {
        if ( num < sections.size() ) {
            return sections[num];
        }

        return -1;
    }

//------------------------------------------------------------------------------
  protected:
//------------------------------------------------------------------------------
    void
    set_index( Elf_Half value )
    {
        index = value;
    }

//------------------------------------------------------------------------------
    void
    load( std::ifstream& stream,
          std::streampos header_offset ) const
    {
        stream.seekg( header_offset );
        stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) );

        if ( PT_NULL != get_type() && 0 != get_file_size() ) {
            stream.seekg( (*convertor)( ph.p_offset ) );
            Elf_Xword size = get_file_size();
            data = new char[size];
            if ( 0 != data ) {
                stream.read( data, size );
            }
        }
    }

//------------------------------------------------------------------------------
    void save( std::ofstream& f,
               std::streampos header_offset,
               std::streampos data_offset )
    {
        ph.p_offset = data_offset;
        ph.p_offset = (*convertor)(ph.p_offset);
        f.seekp( header_offset );
        f.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) );
    }

//------------------------------------------------------------------------------
  private:
    mutable T             ph;
    Elf_Half              index;
    mutable char*         data;
    std::vector<Elf_Half> sections;
    endianess_convertor*  convertor;
};

} // namespace ELFIO

#endif // ELFIO_SEGMENT_HPP
<|endoftext|>