<commit_before>#include <cassert>
#include <cstdlib>

#include "QuadGLWidget.h"

const int HALF_RANGE = 200;

QuadGLWidget::QuadGLWidget(QWidget* const parent) :
	GLWidget(parent)
{
	for(int i = 0; i < QuadGLWidget::NUM_QUADS; i++) {
		const int size = 1 + rand() % (HALF_RANGE / 7);
		Quad quad = {
			QVector3D(
				-HALF_RANGE + size + rand() % ((HALF_RANGE - size) * 2),
				-HALF_RANGE + size + rand() % ((HALF_RANGE - size) * 2),
				-10 + rand() % 10),
			QColor(
				rand() % 255,
				rand() % 255,
				rand() % 255),
			size
		};
		quads << quad;
	}
}

void QuadGLWidget::render()
{
	glBegin(GL_QUADS);

	for (QList<Quad>::const_iterator quadIter = quads.begin(); quadIter != quads.end(); ++quadIter) {
		const Quad quad = *quadIter;
		glColor3f(quad.color.redF(), quad.color.greenF(), quad.color.blueF());
		const double x = quad.pos.x();
		const double y = quad.pos.y();
		const double z = quad.pos.z();
		glVertex3f(x - quad.size, y - quad.size, z);
		glVertex3f(x + quad.size, y - quad.size, z);
		glVertex3f(x + quad.size, y + quad.size, z);
		glVertex3f(x - quad.size, y + quad.size, z);
	}
	glEnd();
}

void QuadGLWidget::resizeGL(int width, int height)
{
	int side = qMin(width, height);
	glViewport((width - side) / 2, (height - side) / 2, side, side);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(
		-HALF_RANGE, HALF_RANGE,
		-HALF_RANGE, HALF_RANGE,
		-HALF_RANGE, HALF_RANGE);
	glMatrixMode(GL_MODELVIEW);
}
<commit_msg>Quads have a few more choices for z-coordinates<commit_after>#include <cassert>
#include <cstdlib>

#include "QuadGLWidget.h"

const int HALF_RANGE = 200;

QuadGLWidget::QuadGLWidget(QWidget* const parent) :
	GLWidget(parent)
{
	for(int i = 0; i < QuadGLWidget::NUM_QUADS; i++) {
		const int size = 1 + rand() % (HALF_RANGE / 7);
		Quad quad = {
			QVector3D(
				-HALF_RANGE + size + rand() % ((HALF_RANGE - size) * 2),
				-HALF_RANGE + size + rand() % ((HALF_RANGE - size) * 2),
				-HALF_RANGE + size + rand() % ((HALF_RANGE - size) * 2)),
			QColor(
				rand() % 255,
				rand() % 255,
				rand() % 255),
			size
		};
		quads << quad;
	}
}

void QuadGLWidget::render()
{
	glBegin(GL_QUADS);

	for (QList<Quad>::const_iterator quadIter = quads.begin(); quadIter != quads.end(); ++quadIter) {
		const Quad quad = *quadIter;
		glColor3f(quad.color.redF(), quad.color.greenF(), quad.color.blueF());
		const double x = quad.pos.x();
		const double y = quad.pos.y();
		const double z = quad.pos.z();
		glVertex3f(x - quad.size, y - quad.size, z);
		glVertex3f(x + quad.size, y - quad.size, z);
		glVertex3f(x + quad.size, y + quad.size, z);
		glVertex3f(x - quad.size, y + quad.size, z);
	}
	glEnd();
}

void QuadGLWidget::resizeGL(int width, int height)
{
	int side = qMin(width, height);
	glViewport((width - side) / 2, (height - side) / 2, side, side);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(
		-HALF_RANGE, HALF_RANGE,
		-HALF_RANGE, HALF_RANGE,
		-HALF_RANGE, HALF_RANGE);
	glMatrixMode(GL_MODELVIEW);
}
<|endoftext|>


<commit_before>

#include "iApp.h"

string iApp::app_name = "iApp";
string iApp::app_version = "1.0.0";

iApp::iApp(string _app_name, string _app_version) {

	auto_hide_cursor = true;
    cursor_visible = true;

	cursor_duration_ms = 3000;

    if(_app_name != "") app_name = _app_name;
    if(_app_version != "") app_version = _app_version;

    logHeader(app_name, app_version);

    cursor_timer = ofGetElapsedTimeMillis() + cursor_duration_ms;

  //  ofRegisterMouseEvents(this);
    // ofRegisterKeyEvents(this);
    // ofRegisterGetMessages(this);
    // ofRegister

   // ofAddListener(ofEvents().update, this, &iApp::update);

}

void iApp::setup() {
    ofBaseApp::setup();
    ofLogNotice("iApp:setup");
    // NOT SURE THIS WILL WORK?

}

void iApp::draw(ofEventArgs & args) {
    ofBaseApp::draw(args);

}

void iApp::update(ofEventArgs& args) {
    ofBaseApp::update(args);

    if(auto_hide_cursor) cursorCheck();

}

void iApp::cursorCheck() {

   // cout << "check cursor " << ofGetElapsedTimeMillis() << endl;

    if(cursor_visible) {
        if(ofGetElapsedTimeMillis() >= cursor_timer) { // its been still long enough to auto hide it

            // Cursor show and hide not working on mac in 0.8.0 : using workaroud from http://forum.openframeworks.cc/t/ofhidecursor-not-working-on-osx-10-8-v0-8-0/13379/3?u=adamh
            // Working in 0.8.1 so do a OF compile check here

            #ifdef __APPLE__
                CGDisplayHideCursor(NULL);
            #else
                ofHideCursor();
            #endif

            cout << " hideCursor " << ofGetElapsedTimeMillis() << endl;
            cursor_visible = false;
        }
    }

}

void iApp::cursorUpdate() {

  //  cout << "cursorUpdate " << ofGetElapsedTimeMillis() << endl;

    if(!cursor_visible) {
        cout << " showCursor " << ofGetElapsedTimeMillis() << endl;
        cursor_visible = true;

        #ifdef __APPLE__
            CGDisplayShowCursor(NULL);
        #else
            ofShowCursor();
        #endif

    }

    cursor_timer = ofGetElapsedTimeMillis() + cursor_duration_ms; // reset timer hid it after 3 seconds of no movement
}

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

void iApp::keyPressed(ofKeyEventArgs & key) {
    ofBaseApp::keyPressed(key);

}

void iApp::keyReleased(ofKeyEventArgs & key) {
    ofBaseApp::keyReleased(key);

}

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

void iApp::mouseMoved( ofMouseEventArgs & mouse ) {
    ofBaseApp::mouseMoved(mouse);

    if(auto_hide_cursor) cursorUpdate();
}

void iApp::mouseDragged( ofMouseEventArgs & mouse ) {
    ofBaseApp::mouseDragged(mouse);

    if(auto_hide_cursor) cursorUpdate();
}

void iApp::mousePressed( ofMouseEventArgs & mouse ) {
    ofBaseApp::mousePressed(mouse);

    if(auto_hide_cursor) cursorUpdate();
}

void iApp::mouseReleased( ofMouseEventArgs & mouse ) {
    ofBaseApp::mouseReleased(mouse);
}

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

void iApp::windowResized(ofResizeEventArgs & resize) {
    ofBaseApp::windowResized(resize);

}

void iApp::dragEvent(ofDragInfo dragInfo) {
    ofBaseApp::dragEvent(dragInfo);

}

void iApp::gotMessage(ofMessage msg){
    ofBaseApp::gotMessage(msg);

}

void iApp::exit(ofEventArgs & args) {
    ofBaseApp::exit(args);
    logFooter(app_name, app_version);

}

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

void iApp::drawCalibration(int alpha) {

    /*
     Draw a screen calibration graphic, useful for projection calibration,
     */

    ofPushStyle();

    float sw = 2.0f;
    ofSetLineWidth(sw);

    float w = ofGetWidth();
    float h = ofGetHeight();

    float cx = w / 2.0;
    float cy = h / 2.0;

    float hsw = sw / 2.0;

    ofSetCircleResolution(36);

    ofSetColor(255, alpha);
    ofNoFill();

    // border
    ofRectMode(OF_RECTMODE_CORNER);
    ofRect(hsw, hsw, w-sw, h-sw);

    // diagonal lines
    ofLine(hsw, hsw, w+hsw, h-hsw);
    ofLine(-hsw, h-hsw, w-hsw, hsw);

    // centre lines
    ofLine(cx, 0, cx, h);
    ofLine(0, cy, w, cy);

    // horizontal 1/4 lines
    ofLine(0, h/4, w, h/4);
    ofLine(0, h-h/4, w, h-h/4);

    // Draw centre rect & circle
    ofRectMode(OF_RECTMODE_CENTER);

    float dim = min(w, h) * .66f;

    ofEllipse(cx, cy, dim, dim);

    ofSetLineWidth(1.0f);

    // Draw circles at the sides
    int n = 8;
    float mini_rad = h / n;
    float y;

    for(int i = 0; i<n-1; i++) {
        y = (mini_rad)+(i*mini_rad);
        int c = i % 4;
        switch(c) {
            case 0: ofSetColor(255, alpha); break;
            case 1: ofSetColor(255,0,0, alpha); break;
            case 2: ofSetColor(0,255,0, alpha); break;
            case 3: ofSetColor(0,0,255, alpha); break;
        }

        ofEllipse(0, y, mini_rad, mini_rad); // LHS
        ofEllipse(w, y, mini_rad, mini_rad); // RHS
    }

    // Draw more comprehensive grid

    // do this at the ratio of the screen?
    // TODO: make the ratio dynamic too reading getWidth and getHeight
    float wc = 16.0f;
    float hc = 9.0f;

    float grid_x = w / wc;
    float grid_y = h / hc;

    ofSetColor(255, alpha);

    // vertical lines
    for(int col = 1; col < wc; col++) {
        int gx = round(col * grid_x);
        ofLine(gx, 0, gx, h);
    }

    // horizontal lines
    for(int row = 1; row < hc; row++) {
        int gy = round(row * grid_y);
        ofLine(0, gy, w, gy);
    }

    ofPopStyle();

}

//-----------------------------------------------------------------------------
void iApp::logHeader(const string& _name, const string& _version) {
    ofLogNotice("");
    ofLogNotice("--------------------------------------");
    ofLogNotice("--- START ") << _name << " app v" << _version << " @ " << ofGetTimestampString("%H:%M:%S %d-%m-%Y");
    // TODO: log OS version and name + opengl properties + OF props, free gpu memory?
    ofLogNotice("--------------------------------------");
}

void iApp::logFooter(const string& _name, const string& _version) {
    ofLogNotice("--------------------------------------");
    ofLogNotice("--- STOP ") << _name << " app v" << _version << " @ " << ofGetTimestampString("%H:%M:%S %d-%m-%Y");
    ofLogNotice("--------------------------------------");
}

//-----------------------------------------------------------------------------<commit_msg>Added auto logging to file in /data/logs<commit_after>

#include "iApp.h"

string iApp::app_name = "iApp";
string iApp::app_version = "1.0.0";

iApp::iApp(string _app_name, string _app_version) {

	auto_hide_cursor = true;
    cursor_visible = true;

	cursor_duration_ms = 3000;

    if(_app_name != "") app_name = _app_name;
    if(_app_version != "") app_version = _app_version;

    // TODO: check logs/ dir and zip up anything of 1MB?
    ofLogToFile("logs/" + _app_name + ".log", true); // appends
    //ofSetLogLevel(OF_LOG_VERBOSE);

    logHeader(app_name, app_version);

    cursor_timer = ofGetElapsedTimeMillis() + cursor_duration_ms;

  //  ofRegisterMouseEvents(this);
    // ofRegisterKeyEvents(this);
    // ofRegisterGetMessages(this);
    // ofRegister

   // ofAddListener(ofEvents().update, this, &iApp::update);

}

void iApp::setup() {
    ofBaseApp::setup();
    ofLogNotice("iApp:setup");
    // NOT SURE THIS WILL WORK?

}

void iApp::draw(ofEventArgs & args) {
    ofBaseApp::draw(args);

}

void iApp::update(ofEventArgs& args) {
    ofBaseApp::update(args);

    if(auto_hide_cursor) cursorCheck();

}

void iApp::cursorCheck() {

   // cout << "check cursor " << ofGetElapsedTimeMillis() << endl;

    if(cursor_visible) {
        if(ofGetElapsedTimeMillis() >= cursor_timer) { // its been still long enough to auto hide it

            // Cursor show and hide not working on mac in 0.8.0 : using workaroud from http://forum.openframeworks.cc/t/ofhidecursor-not-working-on-osx-10-8-v0-8-0/13379/3?u=adamh
            // Working in 0.8.1 so do a OF compile check here

            #ifdef __APPLE__
                CGDisplayHideCursor(NULL);
            #else
                ofHideCursor();
            #endif

            cout << " hideCursor " << ofGetElapsedTimeMillis() << endl;
            cursor_visible = false;
        }
    }

}

void iApp::cursorUpdate() {

  //  cout << "cursorUpdate " << ofGetElapsedTimeMillis() << endl;

    if(!cursor_visible) {
        cout << " showCursor " << ofGetElapsedTimeMillis() << endl;
        cursor_visible = true;

        #ifdef __APPLE__
            CGDisplayShowCursor(NULL);
        #else
            ofShowCursor();
        #endif

    }

    cursor_timer = ofGetElapsedTimeMillis() + cursor_duration_ms; // reset timer hid it after 3 seconds of no movement
}

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

void iApp::keyPressed(ofKeyEventArgs & key) {
    ofBaseApp::keyPressed(key);

}

void iApp::keyReleased(ofKeyEventArgs & key) {
    ofBaseApp::keyReleased(key);

}

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

void iApp::mouseMoved( ofMouseEventArgs & mouse ) {
    ofBaseApp::mouseMoved(mouse);

    if(auto_hide_cursor) cursorUpdate();
}

void iApp::mouseDragged( ofMouseEventArgs & mouse ) {
    ofBaseApp::mouseDragged(mouse);

    if(auto_hide_cursor) cursorUpdate();
}

void iApp::mousePressed( ofMouseEventArgs & mouse ) {
    ofBaseApp::mousePressed(mouse);

    if(auto_hide_cursor) cursorUpdate();
}

void iApp::mouseReleased( ofMouseEventArgs & mouse ) {
    ofBaseApp::mouseReleased(mouse);
}

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

void iApp::windowResized(ofResizeEventArgs & resize) {
    ofBaseApp::windowResized(resize);

}

void iApp::dragEvent(ofDragInfo dragInfo) {
    ofBaseApp::dragEvent(dragInfo);

}

void iApp::gotMessage(ofMessage msg){
    ofBaseApp::gotMessage(msg);

}

void iApp::exit(ofEventArgs & args) {
    ofBaseApp::exit(args);
    logFooter(app_name, app_version);

    ofLogToConsole(); // reset logging to file

}

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

void iApp::drawCalibration(int alpha) {

    /*
     Draw a screen calibration graphic, useful for projection calibration,
     */

    ofPushStyle();

    float sw = 2.0f;
    ofSetLineWidth(sw);

    float w = ofGetWidth();
    float h = ofGetHeight();

    float cx = w / 2.0;
    float cy = h / 2.0;

    float hsw = sw / 2.0;

    ofSetCircleResolution(36);

    ofSetColor(255, alpha);
    ofNoFill();

    // border
    ofRectMode(OF_RECTMODE_CORNER);
    ofRect(hsw, hsw, w-sw, h-sw);

    // diagonal lines
    ofLine(hsw, hsw, w+hsw, h-hsw);
    ofLine(-hsw, h-hsw, w-hsw, hsw);

    // centre lines
    ofLine(cx, 0, cx, h);
    ofLine(0, cy, w, cy);

    // horizontal 1/4 lines
    ofLine(0, h/4, w, h/4);
    ofLine(0, h-h/4, w, h-h/4);

    // Draw centre rect & circle
    ofRectMode(OF_RECTMODE_CENTER);

    float dim = min(w, h) * .66f;

    ofEllipse(cx, cy, dim, dim);

    ofSetLineWidth(1.0f);

    // Draw circles at the sides
    int n = 8;
    float mini_rad = h / n;
    float y;

    for(int i = 0; i<n-1; i++) {
        y = (mini_rad)+(i*mini_rad);
        int c = i % 4;
        switch(c) {
            case 0: ofSetColor(255, alpha); break;
            case 1: ofSetColor(255,0,0, alpha); break;
            case 2: ofSetColor(0,255,0, alpha); break;
            case 3: ofSetColor(0,0,255, alpha); break;
        }

        ofEllipse(0, y, mini_rad, mini_rad); // LHS
        ofEllipse(w, y, mini_rad, mini_rad); // RHS
    }

    // Draw more comprehensive grid

    // do this at the ratio of the screen?
    // TODO: make the ratio dynamic too reading getWidth and getHeight
    float wc = 16.0f;
    float hc = 9.0f;

    float grid_x = w / wc;
    float grid_y = h / hc;

    ofSetColor(255, alpha);

    // vertical lines
    for(int col = 1; col < wc; col++) {
        int gx = round(col * grid_x);
        ofLine(gx, 0, gx, h);
    }

    // horizontal lines
    for(int row = 1; row < hc; row++) {
        int gy = round(row * grid_y);
        ofLine(0, gy, w, gy);
    }

    ofPopStyle();

}

//-----------------------------------------------------------------------------
void iApp::logHeader(const string& _name, const string& _version) {
    ofLogNotice("");
    ofLogNotice("--------------------------------------");
    ofLogNotice("--- START ") << _name << " app v" << _version << " @ " << ofGetTimestampString("%H:%M:%S %d-%m-%Y");
    // TODO: log OS version and name + opengl properties + OF props, free gpu memory?
    ofLogNotice("--------------------------------------");
}

void iApp::logFooter(const string& _name, const string& _version) {
    ofLogNotice("--------------------------------------");
    ofLogNotice("--- STOP ") << _name << " app v" << _version << " @ " << ofGetTimestampString("%H:%M:%S %d-%m-%Y");
    ofLogNotice("--------------------------------------");
}

//-----------------------------------------------------------------------------<|endoftext|>


<commit_before>#if 1 // set to 0 to build minimal lunex example

#include "engine/allocators.h"
#include "engine/command_line_parser.h"
#include "engine/crc32.h"
#include "engine/debug.h"
#include "engine/engine.h"
#include "engine/file_system.h"
#include "engine/geometry.h"
#include "engine/input_system.h"
#include "engine/job_system.h"
#include "engine/log.h"
#include "engine/os.h"
#include "engine/path.h"
#include "engine/profiler.h"
#include "engine/reflection.h"
#include "engine/resource_manager.h"
#include "engine/thread.h"
#include "engine/universe.h"
#include "gui/gui_system.h"
#include "lua_script/lua_script_system.h"
#include "renderer/pipeline.h"
#include "renderer/render_scene.h"
#include "renderer/renderer.h"

using namespace Lumix;

static const ComponentType ENVIRONMENT_TYPE = reflection::getComponentType("environment");
static const ComponentType LUA_SCRIPT_TYPE = reflection::getComponentType("lua_script");

struct GUIInterface : GUISystem::Interface {
	Pipeline* getPipeline() override { return pipeline; }
	Vec2 getPos() const override { return Vec2(0); }
	Vec2 getSize() const override { return size; }
	void setCursor(os::CursorType type) override { os::setCursor(type); }
	void enableCursor(bool enable) override { os::showCursor(enable); }

	Vec2 size;
	Pipeline* pipeline;
};

struct Runner final
{
	Runner()
		: m_allocator(m_main_allocator)
	{
		if (!jobs::init(os::getCPUsCount(), m_allocator)) {
			logError("Failed to initialize job system.");
		}
	}

	~Runner() {
		jobs::shutdown();
		ASSERT(!m_universe);
	}

	void onResize() {
		if (!m_engine.get()) return;
		if (m_engine->getWindowHandle() == os::INVALID_WINDOW) return;

		const os::Rect r = os::getWindowClientRect(m_engine->getWindowHandle());
		m_viewport.w = r.width;
		m_viewport.h = r.height;
		m_gui_interface.size = Vec2((float)r.width, (float)r.height);
	}

	void initRenderPipeline() {
		m_viewport.fov = degreesToRadians(60.f);
		m_viewport.far = 10'000.f;
		m_viewport.is_ortho = false;
		m_viewport.near = 0.1f;
		m_viewport.pos = {0, 0, 0};
		m_viewport.rot = Quat::IDENTITY;

		m_renderer = static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
		PipelineResource* pres = m_engine->getResourceManager().load<PipelineResource>(Path("pipelines/main.pln"));
		m_pipeline = Pipeline::create(*m_renderer, pres, "APP", m_engine->getAllocator());

		while (m_engine->getFileSystem().hasWork()) {
			os::sleep(100);
			m_engine->getFileSystem().processCallbacks();
		}

		m_pipeline->setUniverse(m_universe);
	}

	void initDemoScene() {
		const EntityRef env = m_universe->createEntity({0, 0, 0}, Quat::IDENTITY);
		m_universe->createComponent(ENVIRONMENT_TYPE, env);
		m_universe->createComponent(LUA_SCRIPT_TYPE, env);

		RenderScene* render_scene = (RenderScene*)m_universe->getScene(crc32("renderer"));
		Environment& environment = render_scene->getEnvironment(env);
		environment.direct_intensity = 3;

		Quat rot;
		rot.fromEuler(Vec3(degreesToRadians(45.f), 0, 0));
		m_universe->setRotation(env, rot);

		LuaScriptScene* lua_scene = (LuaScriptScene*)m_universe->getScene(crc32("lua_script"));
		lua_scene->addScript(env, 0);
		lua_scene->setScriptPath(env, 0, Path("pipelines/atmo.lua"));
	}

	bool loadUniverse(const char* path) {
		FileSystem& fs = m_engine->getFileSystem();
		OutputMemoryStream data(m_allocator);
		if (!fs.getContentSync(Path(path), data)) return false;

		InputMemoryStream tmp(data);
		EntityMap entity_map(m_allocator);
		struct Header {
			u32 magic;
			i32 version;
			u32 hash;
			u32 engine_hash;
		} header;

		tmp.read(header);

		m_universe->setName("main");
		if (!m_engine->deserialize(*m_universe, tmp, entity_map)) {
			logError("Failed to deserialize ", path);
			return false;
		}
		return true;
	}

	static bool isWindowCommandLineOption() {
		char cmd_line[2048];
		os::getCommandLine(Span(cmd_line));

		CommandLineParser parser(cmd_line);
		while (parser.next())
		{
			if (parser.currentEquals("-window")) return true;
		}
		return false;
	}

	void onInit() {
		Engine::InitArgs init_data;
		init_data.window_title = "On the hunt";

		if (os::fileExists("main.pak")) {
			init_data.file_system = FileSystem::createPacked("main.pak", m_allocator);
		}

		m_engine = Engine::create(static_cast<Engine::InitArgs&&>(init_data), m_allocator);

		if (!isWindowCommandLineOption()) os::setFullscreen(m_engine->getWindowHandle());

		m_universe = &m_engine->createUniverse(true);
		initRenderPipeline();

		auto* gui = static_cast<GUISystem*>(m_engine->getPluginManager().getPlugin("gui"));
		m_gui_interface.pipeline = m_pipeline.get();
		gui->setInterface(&m_gui_interface);

		if (!loadUniverse("universes/main.unv")) {
			initDemoScene();
		}
		os::showCursor(false);
		while (m_engine->getFileSystem().hasWork()) {
			os::sleep(10);
			m_engine->getFileSystem().processCallbacks();
		}
		m_engine->getFileSystem().processCallbacks();

		os::showCursor(false);
		onResize();
		m_engine->startGame(*m_universe);
	}

	void shutdown() {
		m_engine->destroyUniverse(*m_universe);
		auto* gui = static_cast<GUISystem*>(m_engine->getPluginManager().getPlugin("gui"));
		gui->setInterface(nullptr);
		m_pipeline.reset();
		m_engine.reset();
		m_universe = nullptr;
	}

	void onEvent(const os::Event& event) {
		if (m_engine.get()) {
			if (m_focused || event.type == os::Event::Type::MOUSE_BUTTON && !event.mouse_button.down) {
				InputSystem& input = m_engine->getInputSystem();
				input.injectEvent(event, 0, 0);
			}
		}
		switch (event.type) {
			case os::Event::Type::FOCUS:
				m_focused = event.focus.gained;
				break;
			case os::Event::Type::QUIT:
			case os::Event::Type::WINDOW_CLOSE:
				m_finished = true;
				break;
			case os::Event::Type::WINDOW_MOVE:
			case os::Event::Type::WINDOW_SIZE:
				onResize();
				break;
		}
	}

	void onIdle() {
		m_engine->update(*m_universe);

		EntityPtr camera = m_pipeline->getScene()->getActiveCamera();
		if (camera.isValid()) {
			int w = m_viewport.w;
			int h = m_viewport.h;
			m_viewport = m_pipeline->getScene()->getCameraViewport((EntityRef)camera);
			m_viewport.w = w;
			m_viewport.h = h;
		}

		m_pipeline->setViewport(m_viewport);
		m_pipeline->render(false);
		m_renderer->frame();
	}

	DefaultAllocator m_main_allocator;
	debug::Allocator m_allocator;
	UniquePtr<Engine> m_engine;
	Renderer* m_renderer = nullptr;
	Universe* m_universe = nullptr;
	UniquePtr<Pipeline> m_pipeline;

	Viewport m_viewport;
	bool m_finished = false;
	bool m_focused = true;
	GUIInterface m_gui_interface;
};

int main(int args, char* argv[])
{
	profiler::setThreadName("Main thread");
	struct Data {
		Data() : semaphore(0, 1) {}
		Runner app;
		Semaphore semaphore;
	} data;

	jobs::runEx(&data, [](void* ptr) {
		Data* data = (Data*)ptr;

		data->app.onInit();
		while(!data->app.m_finished) {
			os::Event e;
			while(os::getEvent(e)) {
				data->app.onEvent(e);
			}
			data->app.onIdle();
		}

		data->app.shutdown();

		data->semaphore.signal();
	}, nullptr, jobs::INVALID_HANDLE, 0);

	PROFILE_BLOCK("sleeping");
	data.semaphore.wait();

	return 0;
}

#else

#include "engine/allocators.h"
#include "engine/os.h"
#include "renderer/gpu/gpu.h"

using namespace Lumix;

int main(int args, char* argv[]) {
	os::WindowHandle win = os::createWindow({});

	DefaultAllocator allocator;
	gpu::preinit(allocator, false);
	gpu::init(win, gpu::InitFlags::NONE);
	gpu::ProgramHandle shader = gpu::allocProgramHandle();

	const gpu::ShaderType types[] = {gpu::ShaderType::VERTEX, gpu::ShaderType::FRAGMENT};
	const char* srcs[] = {
		"void main() { gl_Position = vec4(gl_VertexID & 1, (gl_VertexID >> 1) & 1, 0, 1); }",
		"layout(location = 0) out vec4 color; void main() { color = vec4(1, 0, 1, 1); }",
	};
	gpu::createProgram(shader, {}, srcs, types, 2, nullptr, 0, "shader");

	bool finished = false;
	while (!finished) {
		os::Event e;
		while (os::getEvent(e)) {
			switch (e.type) {
				case os::Event::Type::WINDOW_CLOSE:
				case os::Event::Type::QUIT: finished = true; break;
			}
		}

		gpu::setFramebuffer(nullptr, 0, gpu::INVALID_TEXTURE, gpu::FramebufferFlags::NONE);
		const float clear_col[] = {0, 0, 0, 1};
		gpu::clear(gpu::ClearFlags::COLOR | gpu::ClearFlags::DEPTH, clear_col, 0);
		gpu::useProgram(shader);
		gpu::setState(gpu::StateFlags::NONE);
		gpu::drawArrays(gpu::PrimitiveType::TRIANGLES, 0, 3);

		u32 frame = gpu::swapBuffers();
		gpu::waitFrame(frame);
	}

	gpu::shutdown();

	os::destroyWindow(win);
}

#endif<commit_msg>app - capture mouse<commit_after>#if 1 // set to 0 to build minimal lunex example

#include "engine/allocators.h"
#include "engine/command_line_parser.h"
#include "engine/crc32.h"
#include "engine/debug.h"
#include "engine/engine.h"
#include "engine/file_system.h"
#include "engine/geometry.h"
#include "engine/input_system.h"
#include "engine/job_system.h"
#include "engine/log.h"
#include "engine/os.h"
#include "engine/path.h"
#include "engine/profiler.h"
#include "engine/reflection.h"
#include "engine/resource_manager.h"
#include "engine/thread.h"
#include "engine/universe.h"
#include "gui/gui_system.h"
#include "lua_script/lua_script_system.h"
#include "renderer/pipeline.h"
#include "renderer/render_scene.h"
#include "renderer/renderer.h"

using namespace Lumix;

static const ComponentType ENVIRONMENT_TYPE = reflection::getComponentType("environment");
static const ComponentType LUA_SCRIPT_TYPE = reflection::getComponentType("lua_script");

struct GUIInterface : GUISystem::Interface {
	Pipeline* getPipeline() override { return pipeline; }
	Vec2 getPos() const override { return Vec2(0); }
	Vec2 getSize() const override { return size; }
	void setCursor(os::CursorType type) override { os::setCursor(type); }
	void enableCursor(bool enable) override { os::showCursor(enable); }

	Vec2 size;
	Pipeline* pipeline;
};

struct Runner final
{
	Runner()
		: m_allocator(m_main_allocator)
	{
		if (!jobs::init(os::getCPUsCount(), m_allocator)) {
			logError("Failed to initialize job system.");
		}
	}

	~Runner() {
		jobs::shutdown();
		ASSERT(!m_universe);
	}

	void onResize() {
		if (!m_engine.get()) return;
		if (m_engine->getWindowHandle() == os::INVALID_WINDOW) return;

		const os::Rect r = os::getWindowClientRect(m_engine->getWindowHandle());
		m_viewport.w = r.width;
		m_viewport.h = r.height;
		m_gui_interface.size = Vec2((float)r.width, (float)r.height);
	}

	void initRenderPipeline() {
		m_viewport.fov = degreesToRadians(60.f);
		m_viewport.far = 10'000.f;
		m_viewport.is_ortho = false;
		m_viewport.near = 0.1f;
		m_viewport.pos = {0, 0, 0};
		m_viewport.rot = Quat::IDENTITY;

		m_renderer = static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
		PipelineResource* pres = m_engine->getResourceManager().load<PipelineResource>(Path("pipelines/main.pln"));
		m_pipeline = Pipeline::create(*m_renderer, pres, "APP", m_engine->getAllocator());

		while (m_engine->getFileSystem().hasWork()) {
			os::sleep(100);
			m_engine->getFileSystem().processCallbacks();
		}

		m_pipeline->setUniverse(m_universe);
	}

	void initDemoScene() {
		const EntityRef env = m_universe->createEntity({0, 0, 0}, Quat::IDENTITY);
		m_universe->createComponent(ENVIRONMENT_TYPE, env);
		m_universe->createComponent(LUA_SCRIPT_TYPE, env);

		RenderScene* render_scene = (RenderScene*)m_universe->getScene(crc32("renderer"));
		Environment& environment = render_scene->getEnvironment(env);
		environment.direct_intensity = 3;

		Quat rot;
		rot.fromEuler(Vec3(degreesToRadians(45.f), 0, 0));
		m_universe->setRotation(env, rot);

		LuaScriptScene* lua_scene = (LuaScriptScene*)m_universe->getScene(crc32("lua_script"));
		lua_scene->addScript(env, 0);
		lua_scene->setScriptPath(env, 0, Path("pipelines/atmo.lua"));
	}

	bool loadUniverse(const char* path) {
		FileSystem& fs = m_engine->getFileSystem();
		OutputMemoryStream data(m_allocator);
		if (!fs.getContentSync(Path(path), data)) return false;

		InputMemoryStream tmp(data);
		EntityMap entity_map(m_allocator);
		struct Header {
			u32 magic;
			i32 version;
			u32 hash;
			u32 engine_hash;
		} header;

		tmp.read(header);

		m_universe->setName("main");
		if (!m_engine->deserialize(*m_universe, tmp, entity_map)) {
			logError("Failed to deserialize ", path);
			return false;
		}
		return true;
	}

	static bool isWindowCommandLineOption() {
		char cmd_line[2048];
		os::getCommandLine(Span(cmd_line));

		CommandLineParser parser(cmd_line);
		while (parser.next())
		{
			if (parser.currentEquals("-window")) return true;
		}
		return false;
	}

	void onInit() {
		Engine::InitArgs init_data;
		init_data.window_title = "On the hunt";

		if (os::fileExists("main.pak")) {
			init_data.file_system = FileSystem::createPacked("main.pak", m_allocator);
		}

		m_engine = Engine::create(static_cast<Engine::InitArgs&&>(init_data), m_allocator);

		if (!isWindowCommandLineOption()) {
			os::setFullscreen(m_engine->getWindowHandle());
			captureMouse(true);
		}

		m_universe = &m_engine->createUniverse(true);
		initRenderPipeline();

		auto* gui = static_cast<GUISystem*>(m_engine->getPluginManager().getPlugin("gui"));
		m_gui_interface.pipeline = m_pipeline.get();
		gui->setInterface(&m_gui_interface);

		if (!loadUniverse("universes/main.unv")) {
			initDemoScene();
		}
		os::showCursor(false);
		while (m_engine->getFileSystem().hasWork()) {
			os::sleep(10);
			m_engine->getFileSystem().processCallbacks();
		}
		m_engine->getFileSystem().processCallbacks();

		os::showCursor(false);
		onResize();
		m_engine->startGame(*m_universe);
	}

	void shutdown() {
		m_engine->destroyUniverse(*m_universe);
		auto* gui = static_cast<GUISystem*>(m_engine->getPluginManager().getPlugin("gui"));
		gui->setInterface(nullptr);
		m_pipeline.reset();
		m_engine.reset();
		m_universe = nullptr;
	}

	void captureMouse(bool capture) {
		if (m_focused) {
			os::Rect rect = os::getWindowScreenRect(m_engine->getWindowHandle());
			os::clipCursor(rect.left, rect.top, rect.width, rect.height);
			os::showCursor(false);
		}
		else {
			os::unclipCursor();
			os::showCursor(true);
		}
	}

	void onEvent(const os::Event& event) {
		if (m_engine.get()) {
			if (m_focused
				|| event.type == os::Event::Type::MOUSE_BUTTON && !event.mouse_button.down
				|| event.type == os::Event::Type::KEY && !event.key.down)
			{
				InputSystem& input = m_engine->getInputSystem();
				input.injectEvent(event, 0, 0);
			}
		}
		switch (event.type) {
			case os::Event::Type::FOCUS:
				m_focused = event.focus.gained;
				captureMouse(m_focused);
				break;
			case os::Event::Type::QUIT:
			case os::Event::Type::WINDOW_CLOSE:
				m_finished = true;
				break;
			case os::Event::Type::WINDOW_MOVE:
			case os::Event::Type::WINDOW_SIZE:
				onResize();
				captureMouse(m_focused);
				break;
		}
	}

	void onIdle() {
		m_engine->update(*m_universe);

		EntityPtr camera = m_pipeline->getScene()->getActiveCamera();
		if (camera.isValid()) {
			int w = m_viewport.w;
			int h = m_viewport.h;
			m_viewport = m_pipeline->getScene()->getCameraViewport((EntityRef)camera);
			m_viewport.w = w;
			m_viewport.h = h;
		}

		m_pipeline->setViewport(m_viewport);
		m_pipeline->render(false);
		m_renderer->frame();
	}

	DefaultAllocator m_main_allocator;
	debug::Allocator m_allocator;
	UniquePtr<Engine> m_engine;
	Renderer* m_renderer = nullptr;
	Universe* m_universe = nullptr;
	UniquePtr<Pipeline> m_pipeline;

	Viewport m_viewport;
	bool m_finished = false;
	bool m_focused = true;
	GUIInterface m_gui_interface;
};

int main(int args, char* argv[])
{
	profiler::setThreadName("Main thread");
	struct Data {
		Data() : semaphore(0, 1) {}
		Runner app;
		Semaphore semaphore;
	} data;

	jobs::runEx(&data, [](void* ptr) {
		Data* data = (Data*)ptr;

		data->app.onInit();
		while(!data->app.m_finished) {
			os::Event e;
			while(os::getEvent(e)) {
				data->app.onEvent(e);
			}
			data->app.onIdle();
		}

		data->app.shutdown();

		data->semaphore.signal();
	}, nullptr, jobs::INVALID_HANDLE, 0);

	PROFILE_BLOCK("sleeping");
	data.semaphore.wait();

	return 0;
}

#else

#include "engine/allocators.h"
#include "engine/os.h"
#include "renderer/gpu/gpu.h"

using namespace Lumix;

int main(int args, char* argv[]) {
	os::WindowHandle win = os::createWindow({});

	DefaultAllocator allocator;
	gpu::preinit(allocator, false);
	gpu::init(win, gpu::InitFlags::NONE);
	gpu::ProgramHandle shader = gpu::allocProgramHandle();

	const gpu::ShaderType types[] = {gpu::ShaderType::VERTEX, gpu::ShaderType::FRAGMENT};
	const char* srcs[] = {
		"void main() { gl_Position = vec4(gl_VertexID & 1, (gl_VertexID >> 1) & 1, 0, 1); }",
		"layout(location = 0) out vec4 color; void main() { color = vec4(1, 0, 1, 1); }",
	};
	gpu::createProgram(shader, {}, srcs, types, 2, nullptr, 0, "shader");

	bool finished = false;
	while (!finished) {
		os::Event e;
		while (os::getEvent(e)) {
			switch (e.type) {
				case os::Event::Type::WINDOW_CLOSE:
				case os::Event::Type::QUIT: finished = true; break;
			}
		}

		gpu::setFramebuffer(nullptr, 0, gpu::INVALID_TEXTURE, gpu::FramebufferFlags::NONE);
		const float clear_col[] = {0, 0, 0, 1};
		gpu::clear(gpu::ClearFlags::COLOR | gpu::ClearFlags::DEPTH, clear_col, 0);
		gpu::useProgram(shader);
		gpu::setState(gpu::StateFlags::NONE);
		gpu::drawArrays(gpu::PrimitiveType::TRIANGLES, 0, 3);

		u32 frame = gpu::swapBuffers();
		gpu::waitFrame(frame);
	}

	gpu::shutdown();

	os::destroyWindow(win);
}

#endif<|endoftext|>


<commit_before>/*
  Copyright (C) 2013-2015 The Communi Project

  You may use this file under the terms of BSD license as follows:

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the copyright holder nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <QGuiApplication>
#include <QQuickView>
#include <QtQml>
#include <QFileInfo>
#include <QDir>
#include <QStandardPaths>

#include <sailfishapp.h>

#include "activitymodel.h"
#include "bufferfiltermodel.h"
#include "bufferproxymodel.h"
#include "networksession.h"

// Needed to connect MessageStorage
#include "messagemodel.h"

#include "messagestorage.h"
#include "messageformatter.h"
#include "stringfiltermodel.h"
#include "ignoremanager.h"
#include "messagefilter.h"
#include "pluginloader.h"
#include "settingsproxy.h"

#include <IrcCore>
#include <IrcModel>
#include <IrcUtil>

const QString ApplicationName = "harbour-communi";
const QString OrganizationNameName = "harbour-communi";

class SortedUserModel : public IRC_PREPEND_NAMESPACE(IrcUserModel)
{
public:
    SortedUserModel(QObject* parent = 0) : IRC_PREPEND_NAMESPACE(IrcUserModel)(parent)
    {
        setSortMethod(IRC_PREPEND_NAMESPACE(Irc)::SortByTitle);
    }
};

IRC_USE_NAMESPACE

static void migrateConfig()
{
    const QString oldConfig = "harbour-communi/IRC for Sailfish.conf";
    QString xdgConfigHome = QString::fromLocal8Bit(qgetenv("XDG_CONFIG_HOME"));

    if (xdgConfigHome == nullptr)
        xdgConfigHome = QString::fromLocal8Bit(qgetenv("HOME")) + "/.config";
    QString oldConfigFileStr = xdgConfigHome + "/" + oldConfig;
    QString newConfigFileStr = xdgConfigHome + "/" + ApplicationName + "/" +
        ApplicationName + ".conf";

    if((!QFileInfo(newConfigFileStr).exists() && !QDir(newConfigFileStr).exists()) &&
        (QFileInfo(oldConfigFileStr).exists() && !QDir(oldConfigFileStr).exists())) {
        QFile::rename(oldConfigFileStr, newConfigFileStr);
    }
}

static void registerCommuniTypes()
{
    Irc::registerMetaTypes();

    qRegisterMetaType<IrcBuffer*>("IrcBuffer*");
    qRegisterMetaType<IrcBufferModel*>("IrcBufferModel*");
    qRegisterMetaType<IrcChannel*>("IrcChannel*");
    qRegisterMetaType<IrcUser*>("IrcUser*");
    qRegisterMetaType<IrcUserModel*>("IrcUserModel*");

    qRegisterMetaType<IrcCommandParser*>("IrcCommandParser*");
    qRegisterMetaType<IrcCompleter*>("IrcCompleter*");
    qRegisterMetaType<IrcLagTimer*>("IrcLagTimer*");
    qRegisterMetaType<IrcPalette*>("IrcPalette*");
    qRegisterMetaType<IrcTextFormat*>("IrcTextFormat*");
}

Q_DECL_EXPORT int main(int argc, char* argv[])
{
    QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));

    migrateConfig();

    QGuiApplication::setApplicationName(ApplicationName);
    QGuiApplication::setApplicationVersion(APP_VERSION);
    QGuiApplication::setOrganizationName(QString());
    QGuiApplication::setOrganizationDomain(QString());

    QString AppDataLocationReadOnly =
        QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation).last();

    QScopedPointer<QQuickView> viewer(SailfishApp::createView());
    viewer->engine()->addImportPath(AppDataLocationReadOnly + "/qml");

    registerCommuniTypes();

    qRegisterMetaType<QAbstractItemModel*>();
    qmlRegisterType<MessageFilter>("MessageFilter", 1, 0, "MessageFilter");
    qmlRegisterType<SortedUserModel>("SortedUserModel", 1, 0, "SortedUserModel");
    qmlRegisterType<StringFilterModel>("StringFilterModel", 1, 0, "StringFilterModel");

    NetworkSession* session = new NetworkSession(app.data());
    viewer->rootContext()->setContextProperty("NetworkSession", session);

    BufferProxyModel* model = new BufferProxyModel(app.data());
    viewer->rootContext()->setContextProperty("BufferModel", model);

    MessageStorage* storage = new MessageStorage(model);
    viewer->rootContext()->setContextProperty("MessageStorage", storage);
    QObject::connect(model, &BufferProxyModel::bufferAdded, storage,  &MessageStorage::add);

    BufferFilterModel* filter = new BufferFilterModel(storage);
    filter->setSourceModel(model);
    viewer->rootContext()->setContextProperty("FilterModel", filter);

    ActivityModel* activity = new ActivityModel(app.data());
    viewer->rootContext()->setContextProperty("ActivityModel", activity);
    QObject::connect(storage, &MessageStorage::added, activity, &ActivityModel::add);
    QObject::connect(storage, &MessageStorage::removed, activity, &ActivityModel::remove);

    IgnoreManager* ignore = IgnoreManager::instance();;
    viewer->rootContext()->setContextProperty("IgnoreManager", ignore);
    QObject::connect(model, &BufferProxyModel::connectionAdded, ignore, &IgnoreManager::addConnection);
    QObject::connect(model, &BufferProxyModel::connectionRemoved, ignore, &IgnoreManager::removeConnection);

    PluginLoader loader;
    loader.setPluginPath(AppDataLocationReadOnly + "/plugins");
    if (loader.load()) {
        QObject::connect(model, &BufferProxyModel::connectionAdded, &loader, &PluginLoader::connectionAdded);
        QObject::connect(model, &BufferProxyModel::connectionRemoved, &loader, &PluginLoader::connectionRemoved);
    }

    SettingsProxy settingsProxy(model, ignore, app.data());

    viewer->rootContext()->setContextProperty("settingsProxy", &settingsProxy);

    QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
                     &settingsProxy, &SettingsProxy::saveSettings );

#ifndef NO_RESOURCES
    viewer->setSource(QUrl("qrc:///qml/main.qml"));
#else
    viewer->setSource(SailfishApp::pathTo("qml/main.qml"));
#endif
    viewer->showFullScreen();

    return app->exec();
}
<commit_msg>[app] Load translation if found<commit_after>/*
  Copyright (C) 2013-2015 The Communi Project

  You may use this file under the terms of BSD license as follows:

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the copyright holder nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <QGuiApplication>
#include <QTranslator>
#include <QQuickView>
#include <QtQml>
#include <QFileInfo>
#include <QDir>
#include <QStandardPaths>

#include <sailfishapp.h>

#include "activitymodel.h"
#include "bufferfiltermodel.h"
#include "bufferproxymodel.h"
#include "networksession.h"

// Needed to connect MessageStorage
#include "messagemodel.h"

#include "messagestorage.h"
#include "messageformatter.h"
#include "stringfiltermodel.h"
#include "ignoremanager.h"
#include "messagefilter.h"
#include "pluginloader.h"
#include "settingsproxy.h"

#include <IrcCore>
#include <IrcModel>
#include <IrcUtil>

const QString ApplicationName = "harbour-communi";
const QString OrganizationNameName = "harbour-communi";

class SortedUserModel : public IRC_PREPEND_NAMESPACE(IrcUserModel)
{
public:
    SortedUserModel(QObject* parent = 0) : IRC_PREPEND_NAMESPACE(IrcUserModel)(parent)
    {
        setSortMethod(IRC_PREPEND_NAMESPACE(Irc)::SortByTitle);
    }
};

IRC_USE_NAMESPACE

static void migrateConfig()
{
    const QString oldConfig = "harbour-communi/IRC for Sailfish.conf";
    QString xdgConfigHome = QString::fromLocal8Bit(qgetenv("XDG_CONFIG_HOME"));

    if (xdgConfigHome == nullptr)
        xdgConfigHome = QString::fromLocal8Bit(qgetenv("HOME")) + "/.config";
    QString oldConfigFileStr = xdgConfigHome + "/" + oldConfig;
    QString newConfigFileStr = xdgConfigHome + "/" + ApplicationName + "/" +
        ApplicationName + ".conf";

    if((!QFileInfo(newConfigFileStr).exists() && !QDir(newConfigFileStr).exists()) &&
        (QFileInfo(oldConfigFileStr).exists() && !QDir(oldConfigFileStr).exists())) {
        QFile::rename(oldConfigFileStr, newConfigFileStr);
    }
}

static void registerCommuniTypes()
{
    Irc::registerMetaTypes();

    qRegisterMetaType<IrcBuffer*>("IrcBuffer*");
    qRegisterMetaType<IrcBufferModel*>("IrcBufferModel*");
    qRegisterMetaType<IrcChannel*>("IrcChannel*");
    qRegisterMetaType<IrcUser*>("IrcUser*");
    qRegisterMetaType<IrcUserModel*>("IrcUserModel*");

    qRegisterMetaType<IrcCommandParser*>("IrcCommandParser*");
    qRegisterMetaType<IrcCompleter*>("IrcCompleter*");
    qRegisterMetaType<IrcLagTimer*>("IrcLagTimer*");
    qRegisterMetaType<IrcPalette*>("IrcPalette*");
    qRegisterMetaType<IrcTextFormat*>("IrcTextFormat*");
}

Q_DECL_EXPORT int main(int argc, char* argv[])
{
    QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));

    migrateConfig();

    QGuiApplication::setApplicationName(ApplicationName);
    QGuiApplication::setApplicationVersion(APP_VERSION);
    QGuiApplication::setOrganizationName(QString());
    QGuiApplication::setOrganizationDomain(QString());

    QString AppDataLocationReadOnly =
        QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation).last();

    QScopedPointer<QQuickView> viewer(SailfishApp::createView());
    viewer->engine()->addImportPath(AppDataLocationReadOnly + "/qml");

    QTranslator translator;

    if (translator.load(QLocale(),
                        QCoreApplication::applicationName(),
                        QLatin1String("_"),
                        QStandardPaths::locate(QStandardPaths::AppDataLocation,
                                               "translations")))
        QCoreApplication::installTranslator(&translator);

    registerCommuniTypes();

    qRegisterMetaType<QAbstractItemModel*>();
    qmlRegisterType<MessageFilter>("MessageFilter", 1, 0, "MessageFilter");
    qmlRegisterType<SortedUserModel>("SortedUserModel", 1, 0, "SortedUserModel");
    qmlRegisterType<StringFilterModel>("StringFilterModel", 1, 0, "StringFilterModel");

    NetworkSession* session = new NetworkSession(app.data());
    viewer->rootContext()->setContextProperty("NetworkSession", session);

    BufferProxyModel* model = new BufferProxyModel(app.data());
    viewer->rootContext()->setContextProperty("BufferModel", model);

    MessageStorage* storage = new MessageStorage(model);
    viewer->rootContext()->setContextProperty("MessageStorage", storage);
    QObject::connect(model, &BufferProxyModel::bufferAdded, storage,  &MessageStorage::add);

    BufferFilterModel* filter = new BufferFilterModel(storage);
    filter->setSourceModel(model);
    viewer->rootContext()->setContextProperty("FilterModel", filter);

    ActivityModel* activity = new ActivityModel(app.data());
    viewer->rootContext()->setContextProperty("ActivityModel", activity);
    QObject::connect(storage, &MessageStorage::added, activity, &ActivityModel::add);
    QObject::connect(storage, &MessageStorage::removed, activity, &ActivityModel::remove);

    IgnoreManager* ignore = IgnoreManager::instance();;
    viewer->rootContext()->setContextProperty("IgnoreManager", ignore);
    QObject::connect(model, &BufferProxyModel::connectionAdded, ignore, &IgnoreManager::addConnection);
    QObject::connect(model, &BufferProxyModel::connectionRemoved, ignore, &IgnoreManager::removeConnection);

    PluginLoader loader;
    loader.setPluginPath(AppDataLocationReadOnly + "/plugins");
    if (loader.load()) {
        QObject::connect(model, &BufferProxyModel::connectionAdded, &loader, &PluginLoader::connectionAdded);
        QObject::connect(model, &BufferProxyModel::connectionRemoved, &loader, &PluginLoader::connectionRemoved);
    }

    SettingsProxy settingsProxy(model, ignore, app.data());

    viewer->rootContext()->setContextProperty("settingsProxy", &settingsProxy);

    QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
                     &settingsProxy, &SettingsProxy::saveSettings );

#ifndef NO_RESOURCES
    viewer->setSource(QUrl("qrc:///qml/main.qml"));
#else
    viewer->setSource(SailfishApp::pathTo("qml/main.qml"));
#endif
    viewer->showFullScreen();

    return app->exec();
}
<|endoftext|>


<commit_before>/************************************************************************
*
* Flood Project  (2008-201x)
* Licensed under the simplified BSD license. All rights reserved.
*
************************************************************************/

#include "Runtime/API.h"
#include "Runtime/Mono.h"
#include "Core/Utilities.h"

#include <mono/metadata/mono-config.h>
#include <mono/mini/jit.h>
#include <mono/metadata/assembly.h>
#include <eglib/src/glib.h>

#ifdef PLATFORM_WINDOWS

#define WIN32_LEAN_AND_MEAN
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <Windows.h>

static LPTOP_LEVEL_EXCEPTION_FILTER GetUnhandledExceptionFilter(void)
{
	/* Windows does not provide a GetUnhandledExceptionFilter()
	* function, so simulate it by unsetting the handler (getting the
	* previous handler) and then re-setting the handler.
	*/
	LPTOP_LEVEL_EXCEPTION_FILTER handler = SetUnhandledExceptionFilter(NULL);
	SetUnhandledExceptionFilter(handler);
	return handler;
}

static LPTOP_LEVEL_EXCEPTION_FILTER gs_MonoUnhandledExceptionFilter = nullptr;

#endif

NAMESPACE_RUNTIME_BEGIN

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

//REFLECT_CHILD_CLASS(MonoScript, Script)
//REFLECT_CLASS_END()

REFLECT_CHILD_CLASS(MonoRuntime, Plugin)
REFLECT_CLASS_END()

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

MonoRuntime::MonoRuntime()
	: domain(nullptr)
{
}

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

PluginMetadata MonoRuntime::getMetadata()
{
	static PluginMetadata metadata;

	metadata.name = "Mono";
	metadata.description = "Provides .NET scripting via Mono";
	metadata.author = "triton";
	metadata.version = "1.0";
	metadata.startEnabled = false;

	return metadata;
}

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

void MonoRuntime::onPluginEnable()
{
	initialize();
}

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

void MonoRuntime::onPluginDisable()
{

}

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

void MonoRuntime::onPluginUpdate()
{
}

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

static Allocator* g_MonoAlloc = 0;
static GMemVTable g_MonoVTable;

static gpointer mono_malloc (gsize n_bytes)
{
	assert(g_MonoAlloc && "Expected a valid allocator");
	return g_MonoAlloc->allocate(g_MonoAlloc, n_bytes, 0);
}

static gpointer mono_realloc (gpointer mem, gsize n_bytes)
{
	assert(g_MonoAlloc && "Expected a valid allocator");

	g_MonoAlloc->deallocate(g_MonoAlloc, mem);
	return g_MonoAlloc->allocate(g_MonoAlloc, n_bytes, 0);
}

static void mono_free (gpointer mem)
{
	assert(g_MonoAlloc && "Expected a valid allocator");
	return g_MonoAlloc->deallocate(g_MonoAlloc, mem);
}

static gpointer mono_calloc (gsize n_blocks, gsize n_block_bytes)
{
	return mono_malloc(n_blocks * n_block_bytes);
}

static gpointer mono_try_malloc (gsize n_bytes)
{
	return mono_malloc(n_bytes);
}

static gpointer mono_try_realloc (gpointer mem, gsize n_bytes)
{
	return mono_realloc(mem, n_bytes);
}

void MonoRuntime::initialize()
{
	heap = AllocatorCreateHeap( AllocatorGetHeap() );

	// Initialize the memory hooks.
	g_MonoVTable.malloc = mono_malloc;
	g_MonoVTable.realloc = mono_realloc;
	g_MonoVTable.free = mono_free;
	g_MonoVTable.calloc = mono_calloc;
	g_MonoVTable.try_malloc = mono_try_malloc;
	g_MonoVTable.try_realloc = mono_try_realloc;
	//g_mem_set_vtable(&g_MonoVTable);

	//Path dir = PathCombine(PathGetCurrentDir(), "Plugins");
	//mono_set_dirs(dir.c_str(), dir.c_str());

	// Load the default Mono configuration file.
	mono_config_parse(nullptr);

	// Creates a new domain where each assembly is loaded and run.
	domain = mono_jit_init_version("Runtime", "v2.0.50727");

	if (!domain)
	{
		LogError("Could not initialize the Mono runtime.");
		return;
	}

	const char* error = mono_check_corlib_version();

	if(error)
	{
		LogError("Corlib not in sync with this runtime: %s", error);
		return;
	}

#ifdef PLATFORM_WINDOWS
	gs_MonoUnhandledExceptionFilter = GetUnhandledExceptionFilter();
#endif
}

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

void MonoRuntime::cleanup()
{
	// Cleanup the Mono JIT context.
	mono_jit_cleanup(domain);

	//mono_config_cleanup();

	//g_mem_set_vtable(nullptr);
}

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

void MonoRuntime::call(MonoMethod* method)
{
	if( !method ) return;

	MonoObject* exception = nullptr;

#ifdef PLATFORM_WINDOWS
	/* Workaround for SEH exception handling. The top-level exception filter
	 * set by SetUnhandledExceptionFilter isn't called when in debug mode.
	 * Behaviour documented here: http://support.microsoft.com/kb/173652/en-us
	 * We add our own SEH try-catch block and redirect to the Mono defined handler.
	 */
	__try
	{
		mono_runtime_invoke(method, nullptr, nullptr, &exception);
	}
	__except ( gs_MonoUnhandledExceptionFilter( GetExceptionInformation() ) )
	{
	}
#endif

	if( exception != nullptr )
	{
		MonoString* trace = mono_object_to_string(exception, nullptr);
		assert( trace && "Expected to get a valid stack trace" );

		LogError("Exception from managed code:\n%s", mono_string_to_utf8(trace));
		return;
	}
}

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

NAMESPACE_RUNTIME_END<commit_msg>Only cleanup the Mono runtime if we got a domain.<commit_after>/************************************************************************
*
* Flood Project  (2008-201x)
* Licensed under the simplified BSD license. All rights reserved.
*
************************************************************************/

#include "Runtime/API.h"
#include "Runtime/Mono.h"
#include "Core/Utilities.h"

#include <mono/metadata/mono-config.h>
#include <mono/mini/jit.h>
#include <mono/metadata/assembly.h>
#include <eglib/src/glib.h>

#ifdef PLATFORM_WINDOWS

#define WIN32_LEAN_AND_MEAN
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <Windows.h>

static LPTOP_LEVEL_EXCEPTION_FILTER GetUnhandledExceptionFilter(void)
{
	/* Windows does not provide a GetUnhandledExceptionFilter()
	* function, so simulate it by unsetting the handler (getting the
	* previous handler) and then re-setting the handler.
	*/
	LPTOP_LEVEL_EXCEPTION_FILTER handler = SetUnhandledExceptionFilter(NULL);
	SetUnhandledExceptionFilter(handler);
	return handler;
}

static LPTOP_LEVEL_EXCEPTION_FILTER gs_MonoUnhandledExceptionFilter = nullptr;

#endif

NAMESPACE_RUNTIME_BEGIN

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

//REFLECT_CHILD_CLASS(MonoScript, Script)
//REFLECT_CLASS_END()

REFLECT_CHILD_CLASS(MonoRuntime, Plugin)
REFLECT_CLASS_END()

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

MonoRuntime::MonoRuntime()
	: domain(nullptr)
{
}

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

PluginMetadata MonoRuntime::getMetadata()
{
	static PluginMetadata metadata;

	metadata.name = "Mono";
	metadata.description = "Provides .NET scripting via Mono";
	metadata.author = "triton";
	metadata.version = "1.0";
	metadata.startEnabled = false;

	return metadata;
}

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

void MonoRuntime::onPluginEnable()
{
	initialize();
}

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

void MonoRuntime::onPluginDisable()
{

}

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

void MonoRuntime::onPluginUpdate()
{
}

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

static Allocator* g_MonoAlloc = 0;
static GMemVTable g_MonoVTable;

static gpointer mono_malloc (gsize n_bytes)
{
	assert(g_MonoAlloc && "Expected a valid allocator");
	return g_MonoAlloc->allocate(g_MonoAlloc, n_bytes, 0);
}

static gpointer mono_realloc (gpointer mem, gsize n_bytes)
{
	assert(g_MonoAlloc && "Expected a valid allocator");

	g_MonoAlloc->deallocate(g_MonoAlloc, mem);
	return g_MonoAlloc->allocate(g_MonoAlloc, n_bytes, 0);
}

static void mono_free (gpointer mem)
{
	assert(g_MonoAlloc && "Expected a valid allocator");
	return g_MonoAlloc->deallocate(g_MonoAlloc, mem);
}

static gpointer mono_calloc (gsize n_blocks, gsize n_block_bytes)
{
	return mono_malloc(n_blocks * n_block_bytes);
}

static gpointer mono_try_malloc (gsize n_bytes)
{
	return mono_malloc(n_bytes);
}

static gpointer mono_try_realloc (gpointer mem, gsize n_bytes)
{
	return mono_realloc(mem, n_bytes);
}

void MonoRuntime::initialize()
{
	heap = AllocatorCreateHeap( AllocatorGetHeap() );

	// Initialize the memory hooks.
	g_MonoVTable.malloc = mono_malloc;
	g_MonoVTable.realloc = mono_realloc;
	g_MonoVTable.free = mono_free;
	g_MonoVTable.calloc = mono_calloc;
	g_MonoVTable.try_malloc = mono_try_malloc;
	g_MonoVTable.try_realloc = mono_try_realloc;
	//g_mem_set_vtable(&g_MonoVTable);

	//Path dir = PathCombine(PathGetCurrentDir(), "Plugins");
	//mono_set_dirs(dir.c_str(), dir.c_str());

	// Load the default Mono configuration file.
	mono_config_parse(nullptr);

	// Creates a new domain where each assembly is loaded and run.
	domain = mono_jit_init_version("Runtime", "v2.0.50727");

	if (!domain)
	{
		LogError("Could not initialize the Mono runtime.");
		return;
	}

	const char* error = mono_check_corlib_version();

	if(error)
	{
		LogError("Corlib not in sync with this runtime: %s", error);
		return;
	}

#ifdef PLATFORM_WINDOWS
	gs_MonoUnhandledExceptionFilter = GetUnhandledExceptionFilter();
#endif
}

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

void MonoRuntime::cleanup()
{
	// Cleanup the Mono JIT context.
	if (domain)
		mono_jit_cleanup(domain);

	//mono_config_cleanup();

	//g_mem_set_vtable(nullptr);
}

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

void MonoRuntime::call(MonoMethod* method)
{
	if( !method ) return;

	MonoObject* exception = nullptr;

#ifdef PLATFORM_WINDOWS
	/* Workaround for SEH exception handling. The top-level exception filter
	 * set by SetUnhandledExceptionFilter isn't called when in debug mode.
	 * Behaviour documented here: http://support.microsoft.com/kb/173652/en-us
	 * We add our own SEH try-catch block and redirect to the Mono defined handler.
	 */
	__try
	{
		mono_runtime_invoke(method, nullptr, nullptr, &exception);
	}
	__except ( gs_MonoUnhandledExceptionFilter( GetExceptionInformation() ) )
	{
	}
#endif

	if( exception != nullptr )
	{
		MonoString* trace = mono_object_to_string(exception, nullptr);
		assert( trace && "Expected to get a valid stack trace" );

		LogError("Exception from managed code:\n%s", mono_string_to_utf8(trace));
		return;
	}
}

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

NAMESPACE_RUNTIME_END<|endoftext|>


<commit_before>#include "ProgramReader.h"
#include "../types/InternalTypes.h"

const std::string ProgramReader::MAGIC = "THING";

ProgramInfo ProgramReader::process()
{
	read_header();

	auto data = read_data();
	auto code = read_code();
	return ProgramInfo(data, code);
}

void ProgramReader::read_header()
{
    if (!file.is_open()) {
        throw RuntimeError("Cannot open file");
    }

    auto magic = read(MAGIC.size());

    if (magic != MAGIC) {
        throw RuntimeError("Invalid file format");
    }

    auto version = read<uint16_t>();
    program_size = read<uint32_t>();
    data_size = read<uint32_t>();
    index = 0; // reset the index, since the program_size in the header does not include the header itself

    std::cerr << "thinglang bytecode version: " << version << ", total size: " << program_size << ", data size: " << data_size << std::endl;
}

std::vector<PThingInstance> ProgramReader::read_data() {
    std::cerr << "Reading data section..." << std::endl;

    std::vector<PThingInstance> static_data;

    while (in_data()) {
        static_data.push_back(read_data_block());
    }

    return static_data;

}

PThingInstance ProgramReader::read_data_block() {
    auto type = static_cast<InternalTypes >(read<int32_t>());

    switch (type) {
        case InternalTypes::TEXT: {
            auto size = read_size();
            auto data = read(size);
            std::cerr << "\tReading text (" << size << " bytes): " << data << std::endl;
            return PThingInstance(new TextInstance(data));
        }
        case InternalTypes::NUMBER: {
            auto data = read<int32_t>();
            std::cerr << "\tReading int: " << data << std::endl;
            return PThingInstance(new NumberInstance(data));
        }

        default:
            throw RuntimeError("Unknown static data type " + std::to_string(int(type)));

    }
}

std::vector<TypeInfo> ProgramReader::read_code() {
    std::cerr << "Reading program..." << std::endl;
    std::vector<TypeInfo> user_types;

    while (in_program()) {
        user_types.push_back(read_class());
    }

    if (index != program_size) {
        throw RuntimeError(std::string("Index mismatch " + std::to_string(index) + ", " + std::to_string(program_size)).c_str());
    }
    else {
        std::cerr << "Program processed successfully" << std::endl << std::endl;
    }

    return user_types;
}

TypeInfo ProgramReader::read_class() {
    auto member_count = read_size();
    auto method_count = read_size();
    std::cerr << "\tEncountered class of " << member_count << " members and " << method_count << " methods" << std::endl;
    std::vector<MethodDefinition> methods;

    for(int i = 0; i < method_count; i++){
        methods.push_back(read_method());
    }
    return TypeInfo("Unknown class", "", methods);

}

MethodDefinition ProgramReader::read_method() {
    uint32_t frame_size = read_size();
    uint32_t arguments = read_size();

    std::cerr << "\tEncountered method (frame size=" << frame_size << ", args=" << arguments << ")" << std::endl;
    std::vector<Symbol> symbols;

    for(auto opcode = read_opcode(); opcode != Opcode::METHOD_END; opcode = read_opcode()){
        auto symbol = read_symbol(opcode);
        symbols.push_back(symbol);
        //bytecode.push_back(symbol);
    }

    return MethodDefinition(frame_size, arguments, symbols);
}

Symbol ProgramReader::read_symbol(Opcode opcode) {
    std::cerr << "\t\t\tReading symbol " << describe(opcode) << std::endl;

    switch (opcode) {

        case Opcode ::PUSH_STATIC:
        case Opcode::PUSH: {
            auto data_index = read_size();
            return Symbol(opcode, data_index);
        }

        case Opcode::PRINT:
        case Opcode::RETURN: {
            return Symbol(opcode);
        }

        case Opcode::CALL_METHOD:
            return Symbol(opcode, read_size());

        case Opcode::CALL:
        case Opcode::CALL_INTERNAL: {
            auto target = read_size();
            auto value = read_size();
            return Symbol(opcode, target, value);
        }

        default:
            throw RuntimeError(std::string("Unknown opcode " + std::to_string((int)opcode)).c_str());
    }
}
<commit_msg>Added SET_STATIC to opcode generation<commit_after>#include "ProgramReader.h"
#include "../types/InternalTypes.h"

const std::string ProgramReader::MAGIC = "THING";

ProgramInfo ProgramReader::process()
{
	read_header();

	auto data = read_data();
	auto code = read_code();
	return ProgramInfo(data, code);
}

void ProgramReader::read_header()
{
    if (!file.is_open()) {
        throw RuntimeError("Cannot open file");
    }

    auto magic = read(MAGIC.size());

    if (magic != MAGIC) {
        throw RuntimeError("Invalid file format");
    }

    auto version = read<uint16_t>();
    program_size = read<uint32_t>();
    data_size = read<uint32_t>();
    index = 0; // reset the index, since the program_size in the header does not include the header itself

    std::cerr << "thinglang bytecode version: " << version << ", total size: " << program_size << ", data size: " << data_size << std::endl;
}

std::vector<PThingInstance> ProgramReader::read_data() {
    std::cerr << "Reading data section..." << std::endl;

    std::vector<PThingInstance> static_data;

    while (in_data()) {
        static_data.push_back(read_data_block());
    }

    return static_data;

}

PThingInstance ProgramReader::read_data_block() {
    auto type = static_cast<InternalTypes >(read<int32_t>());

    switch (type) {
        case InternalTypes::TEXT: {
            auto size = read_size();
            auto data = read(size);
            std::cerr << "\tReading text (" << size << " bytes): " << data << std::endl;
            return PThingInstance(new TextInstance(data));
        }
        case InternalTypes::NUMBER: {
            auto data = read<int32_t>();
            std::cerr << "\tReading int: " << data << std::endl;
            return PThingInstance(new NumberInstance(data));
        }

        default:
            throw RuntimeError("Unknown static data type " + std::to_string(int(type)));

    }
}

std::vector<TypeInfo> ProgramReader::read_code() {
    std::cerr << "Reading program..." << std::endl;
    std::vector<TypeInfo> user_types;

    while (in_program()) {
        user_types.push_back(read_class());
    }

    if (index != program_size) {
        throw RuntimeError(std::string("Index mismatch " + std::to_string(index) + ", " + std::to_string(program_size)).c_str());
    }
    else {
        std::cerr << "Program processed successfully" << std::endl << std::endl;
    }

    return user_types;
}

TypeInfo ProgramReader::read_class() {
    auto member_count = read_size();
    auto method_count = read_size();
    std::cerr << "\tEncountered class of " << member_count << " members and " << method_count << " methods" << std::endl;
    std::vector<MethodDefinition> methods;

    for(int i = 0; i < method_count; i++){
        methods.push_back(read_method());
    }
    return TypeInfo("Unknown class", "", methods);

}

MethodDefinition ProgramReader::read_method() {
    uint32_t frame_size = read_size();
    uint32_t arguments = read_size();

    std::cerr << "\tEncountered method (frame size=" << frame_size << ", args=" << arguments << ")" << std::endl;
    std::vector<Symbol> symbols;

    for(auto opcode = read_opcode(); opcode != Opcode::METHOD_END; opcode = read_opcode()){
        auto symbol = read_symbol(opcode);
        symbols.push_back(symbol);
        //bytecode.push_back(symbol);
    }

    return MethodDefinition(frame_size, arguments, symbols);
}

Symbol ProgramReader::read_symbol(Opcode opcode) {
    std::cerr << "\t\t\tReading symbol " << describe(opcode) << std::endl;

    switch (opcode) {

        case Opcode::PUSH_STATIC:
        case Opcode::PUSH: {
            return Symbol(opcode, read_size());
        }

        case Opcode::PRINT:
        case Opcode::RETURN: {
            return Symbol(opcode);
        }

        case Opcode::CALL_METHOD:
            return Symbol(opcode, read_size());

        case Opcode::SET_STATIC:
        case Opcode::CALL:
        case Opcode::CALL_INTERNAL: {
            auto target = read_size();
            auto value = read_size();
            return Symbol(opcode, target, value);
        }

        default:
            throw RuntimeError(std::string("Unknown opcode " + std::to_string((int)opcode)).c_str());
    }
}
<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2011 LunarG, Inc.
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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 <assert.h>
#include <stdlib.h>

#include <iostream>

#include <dlfcn.h>

#include "glproc.hpp"
#include "glws.hpp"

namespace glws {

static Display *display = NULL;
static EGLDisplay eglDisplay = EGL_NO_DISPLAY;
static int screen = 0;

class EglVisual : public Visual
{
public:
    EGLConfig config;
    XVisualInfo *visinfo;

    EglVisual() :
        config(0),
        visinfo(0)
    {}

    ~EglVisual() {
        XFree(visinfo);
    }
};

static void describeEvent(const XEvent &event) {
    if (0) {
        switch (event.type) {
        case ConfigureNotify:
            std::cerr << "ConfigureNotify";
            break;
        case Expose:
            std::cerr << "Expose";
            break;
        case KeyPress:
            std::cerr << "KeyPress";
            break;
        case MapNotify:
            std::cerr << "MapNotify";
            break;
        case ReparentNotify:
            std::cerr << "ReparentNotify";
            break;
        default:
            std::cerr << "Event " << event.type;
        }
        std::cerr << " " << event.xany.window << "\n";
    }
}

class EglDrawable : public Drawable
{
public:
    Window window;
    EGLSurface surface;
    EGLint api;

    EglDrawable(const Visual *vis, int w, int h) :
        Drawable(vis, w, h), api(EGL_OPENGL_ES_API)
    {
        XVisualInfo *visinfo = static_cast<const EglVisual *>(visual)->visinfo;

        Window root = RootWindow(display, screen);

        /* window attributes */
        XSetWindowAttributes attr;
        attr.background_pixel = 0;
        attr.border_pixel = 0;
        attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone);
        attr.event_mask = StructureNotifyMask;

        unsigned long mask;
        mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

        int x = 0, y = 0;

        window = XCreateWindow(
            display, root,
            x, y, width, height,
            0,
            visinfo->depth,
            InputOutput,
            visinfo->visual,
            mask,
            &attr);

        XSizeHints sizehints;
        sizehints.x = x;
        sizehints.y = y;
        sizehints.width  = width;
        sizehints.height = height;
        sizehints.flags = USSize | USPosition;
        XSetNormalHints(display, window, &sizehints);

        const char *name = "glretrace";
        XSetStandardProperties(
            display, window, name, name,
            None, (char **)NULL, 0, &sizehints);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);

        EGLConfig config = static_cast<const EglVisual *>(visual)->config;
        surface = eglCreateWindowSurface(eglDisplay, config, (EGLNativeWindowType)window, NULL);
    }

    void waitForEvent(int type) {
        XEvent event;
        do {
            XWindowEvent(display, window, StructureNotifyMask, &event);
            describeEvent(event);
        } while (event.type != type);
    }

    ~EglDrawable() {
        eglDestroySurface(eglDisplay, surface);
        XDestroyWindow(display, window);
    }

    void
    resize(int w, int h) {
        if (w == width && h == height) {
            return;
        }

        eglWaitClient();

        // We need to ensure that pending events are processed here, and XSync
        // with discard = True guarantees that, but it appears the limited
        // event processing we do so far is sufficient
        //XSync(display, True);

        Drawable::resize(w, h);

        XResizeWindow(display, window, w, h);

        // Tell the window manager to respect the requested size
        XSizeHints size_hints;
        size_hints.max_width  = size_hints.min_width  = w;
        size_hints.max_height = size_hints.min_height = h;
        size_hints.flags = PMinSize | PMaxSize;
        XSetWMNormalHints(display, window, &size_hints);

        waitForEvent(ConfigureNotify);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);
    }

    void show(void) {
        if (visible) {
            return;
        }

        eglWaitClient();

        XMapWindow(display, window);

        waitForEvent(MapNotify);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);

        Drawable::show();
    }

    void swapBuffers(void) {
        eglBindAPI(api);
        eglSwapBuffers(eglDisplay, surface);
    }
};

class EglContext : public Context
{
public:
    EGLContext context;

    EglContext(const Visual *vis, Profile prof, EGLContext ctx) :
        Context(vis, prof),
        context(ctx)
    {}

    ~EglContext() {
        eglDestroyContext(eglDisplay, context);
    }
};

/**
 * Load the symbols from the specified shared object into global namespace, so
 * that they can be later found by dlsym(RTLD_NEXT, ...);
 */
static void
load(const char *filename)
{
    if (!dlopen(filename, RTLD_GLOBAL | RTLD_LAZY)) {
        std::cerr << "error: unable to open " << filename << "\n";
        exit(1);
    }
}

void
init(void) {
    load("libEGL.so.1");

    display = XOpenDisplay(NULL);
    if (!display) {
        std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n";
        exit(1);
    }

    screen = DefaultScreen(display);

    eglDisplay = eglGetDisplay((EGLNativeDisplayType)display);
    if (eglDisplay == EGL_NO_DISPLAY) {
        std::cerr << "error: unable to get EGL display\n";
        XCloseDisplay(display);
        exit(1);
    }

    EGLint major, minor;
    if (!eglInitialize(eglDisplay, &major, &minor)) {
        std::cerr << "error: unable to initialize EGL display\n";
        XCloseDisplay(display);
        exit(1);
    }
}

void
cleanup(void) {
    if (display) {
        eglTerminate(eglDisplay);
        XCloseDisplay(display);
        display = NULL;
    }
}

Visual *
createVisual(bool doubleBuffer, Profile profile) {
    EglVisual *visual = new EglVisual();
    // possible combinations
    const EGLint api_bits[7] = {
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES_BIT,
        EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT,
    };

    for (int i = 0; i < 7; i++) {
        Attributes<EGLint> attribs;

        attribs.add(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
        attribs.add(EGL_RED_SIZE, 1);
        attribs.add(EGL_GREEN_SIZE, 1);
        attribs.add(EGL_BLUE_SIZE, 1);
        attribs.add(EGL_ALPHA_SIZE, 1);
        attribs.add(EGL_DEPTH_SIZE, 1);
        attribs.add(EGL_STENCIL_SIZE, 1);
        attribs.add(EGL_RENDERABLE_TYPE, api_bits[i]);
        attribs.end(EGL_NONE);

        EGLint num_configs, vid;
        if (eglChooseConfig(eglDisplay, attribs, &visual->config, 1, &num_configs) &&
            num_configs == 1 &&
            eglGetConfigAttrib(eglDisplay, visual->config, EGL_NATIVE_VISUAL_ID, &vid)) {
            XVisualInfo templ;
            int num_visuals;

            templ.visualid = vid;
            visual->visinfo = XGetVisualInfo(display, VisualIDMask, &templ, &num_visuals);
            break;
        }
    }

    assert(visual->visinfo);

    return visual;
}

Drawable *
createDrawable(const Visual *visual, int width, int height)
{
    return new EglDrawable(visual, width, height);
}

Context *
createContext(const Visual *_visual, Context *shareContext, Profile profile)
{
    const EglVisual *visual = static_cast<const EglVisual *>(_visual);
    EGLContext share_context = EGL_NO_CONTEXT;
    EGLContext context;
    Attributes<EGLint> attribs;

    if (shareContext) {
        share_context = static_cast<EglContext*>(shareContext)->context;
    }

    EGLint api = eglQueryAPI();

    switch (profile) {
    case PROFILE_COMPAT:
        load("libGL.so.1");
        eglBindAPI(EGL_OPENGL_API);
        break;
    case PROFILE_CORE:
        assert(0);
        return NULL;
    case PROFILE_ES1:
        load("libGLESv1_CM.so.1");
        eglBindAPI(EGL_OPENGL_ES_API);
        break;
    case PROFILE_ES2:
        load("libGLESv2.so.2");
        eglBindAPI(EGL_OPENGL_ES_API);
        attribs.add(EGL_CONTEXT_CLIENT_VERSION, 2);
        break;
    }

    attribs.end(EGL_NONE);

    context = eglCreateContext(eglDisplay, visual->config, share_context, attribs);
    if (!context)
        return NULL;

    eglBindAPI(api);

    return new EglContext(visual, profile, context);
}

bool
makeCurrent(Drawable *drawable, Context *context)
{
    if (!drawable || !context) {
        return eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    } else {
        EglDrawable *eglDrawable = static_cast<EglDrawable *>(drawable);
        EglContext *eglContext = static_cast<EglContext *>(context);
        EGLBoolean ok;

        ok = eglMakeCurrent(eglDisplay, eglDrawable->surface,
                            eglDrawable->surface, eglContext->context);

        if (ok) {
            EGLint api;

            eglQueryContext(eglDisplay, eglContext->context,
                            EGL_CONTEXT_CLIENT_TYPE, &api);

            eglDrawable->api = api;
        }

        return ok;
    }
}

bool
processEvents(void) {
    while (XPending(display) > 0) {
        XEvent event;
        XNextEvent(display, &event);
        describeEvent(event);
    }
    return true;
}

} /* namespace glws */
<commit_msg>Try to find the best matching EGL visual according to the profile.<commit_after>/**************************************************************************
 *
 * Copyright 2011 LunarG, Inc.
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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 <assert.h>
#include <stdlib.h>

#include <iostream>

#include <dlfcn.h>

#include "glproc.hpp"
#include "glws.hpp"

namespace glws {

static Display *display = NULL;
static EGLDisplay eglDisplay = EGL_NO_DISPLAY;
static int screen = 0;

class EglVisual : public Visual
{
public:
    EGLConfig config;
    XVisualInfo *visinfo;

    EglVisual() :
        config(0),
        visinfo(0)
    {}

    ~EglVisual() {
        XFree(visinfo);
    }
};

static void describeEvent(const XEvent &event) {
    if (0) {
        switch (event.type) {
        case ConfigureNotify:
            std::cerr << "ConfigureNotify";
            break;
        case Expose:
            std::cerr << "Expose";
            break;
        case KeyPress:
            std::cerr << "KeyPress";
            break;
        case MapNotify:
            std::cerr << "MapNotify";
            break;
        case ReparentNotify:
            std::cerr << "ReparentNotify";
            break;
        default:
            std::cerr << "Event " << event.type;
        }
        std::cerr << " " << event.xany.window << "\n";
    }
}

class EglDrawable : public Drawable
{
public:
    Window window;
    EGLSurface surface;
    EGLint api;

    EglDrawable(const Visual *vis, int w, int h) :
        Drawable(vis, w, h), api(EGL_OPENGL_ES_API)
    {
        XVisualInfo *visinfo = static_cast<const EglVisual *>(visual)->visinfo;

        Window root = RootWindow(display, screen);

        /* window attributes */
        XSetWindowAttributes attr;
        attr.background_pixel = 0;
        attr.border_pixel = 0;
        attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone);
        attr.event_mask = StructureNotifyMask;

        unsigned long mask;
        mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

        int x = 0, y = 0;

        window = XCreateWindow(
            display, root,
            x, y, width, height,
            0,
            visinfo->depth,
            InputOutput,
            visinfo->visual,
            mask,
            &attr);

        XSizeHints sizehints;
        sizehints.x = x;
        sizehints.y = y;
        sizehints.width  = width;
        sizehints.height = height;
        sizehints.flags = USSize | USPosition;
        XSetNormalHints(display, window, &sizehints);

        const char *name = "glretrace";
        XSetStandardProperties(
            display, window, name, name,
            None, (char **)NULL, 0, &sizehints);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);

        EGLConfig config = static_cast<const EglVisual *>(visual)->config;
        surface = eglCreateWindowSurface(eglDisplay, config, (EGLNativeWindowType)window, NULL);
    }

    void waitForEvent(int type) {
        XEvent event;
        do {
            XWindowEvent(display, window, StructureNotifyMask, &event);
            describeEvent(event);
        } while (event.type != type);
    }

    ~EglDrawable() {
        eglDestroySurface(eglDisplay, surface);
        XDestroyWindow(display, window);
    }

    void
    resize(int w, int h) {
        if (w == width && h == height) {
            return;
        }

        eglWaitClient();

        // We need to ensure that pending events are processed here, and XSync
        // with discard = True guarantees that, but it appears the limited
        // event processing we do so far is sufficient
        //XSync(display, True);

        Drawable::resize(w, h);

        XResizeWindow(display, window, w, h);

        // Tell the window manager to respect the requested size
        XSizeHints size_hints;
        size_hints.max_width  = size_hints.min_width  = w;
        size_hints.max_height = size_hints.min_height = h;
        size_hints.flags = PMinSize | PMaxSize;
        XSetWMNormalHints(display, window, &size_hints);

        waitForEvent(ConfigureNotify);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);
    }

    void show(void) {
        if (visible) {
            return;
        }

        eglWaitClient();

        XMapWindow(display, window);

        waitForEvent(MapNotify);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);

        Drawable::show();
    }

    void swapBuffers(void) {
        eglBindAPI(api);
        eglSwapBuffers(eglDisplay, surface);
    }
};

class EglContext : public Context
{
public:
    EGLContext context;

    EglContext(const Visual *vis, Profile prof, EGLContext ctx) :
        Context(vis, prof),
        context(ctx)
    {}

    ~EglContext() {
        eglDestroyContext(eglDisplay, context);
    }
};

/**
 * Load the symbols from the specified shared object into global namespace, so
 * that they can be later found by dlsym(RTLD_NEXT, ...);
 */
static void
load(const char *filename)
{
    if (!dlopen(filename, RTLD_GLOBAL | RTLD_LAZY)) {
        std::cerr << "error: unable to open " << filename << "\n";
        exit(1);
    }
}

void
init(void) {
    load("libEGL.so.1");

    display = XOpenDisplay(NULL);
    if (!display) {
        std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n";
        exit(1);
    }

    screen = DefaultScreen(display);

    eglDisplay = eglGetDisplay((EGLNativeDisplayType)display);
    if (eglDisplay == EGL_NO_DISPLAY) {
        std::cerr << "error: unable to get EGL display\n";
        XCloseDisplay(display);
        exit(1);
    }

    EGLint major, minor;
    if (!eglInitialize(eglDisplay, &major, &minor)) {
        std::cerr << "error: unable to initialize EGL display\n";
        XCloseDisplay(display);
        exit(1);
    }
}

void
cleanup(void) {
    if (display) {
        eglTerminate(eglDisplay);
        XCloseDisplay(display);
        display = NULL;
    }
}

Visual *
createVisual(bool doubleBuffer, Profile profile) {
    EglVisual *visual = new EglVisual();
    // possible combinations
    const EGLint api_bits_gl[7] = {
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT,
        EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES_BIT,
    };
    const EGLint api_bits_gles1[7] = {
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
        EGL_OPENGL_ES_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT,
        EGL_OPENGL_ES2_BIT,
    };
    const EGLint api_bits_gles2[7] = {
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
        EGL_OPENGL_BIT,
        EGL_OPENGL_ES_BIT,
    };
    const EGLint *api_bits;

    switch(profile) {
    case PROFILE_COMPAT:
        api_bits = api_bits_gl;
        break;
    case PROFILE_ES1:
        api_bits = api_bits_gles1;
        break;
    case PROFILE_ES2:
        api_bits = api_bits_gles2;
        break;
    default:
        return NULL;
    };

    for (int i = 0; i < 7; i++) {
        Attributes<EGLint> attribs;

        attribs.add(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
        attribs.add(EGL_RED_SIZE, 1);
        attribs.add(EGL_GREEN_SIZE, 1);
        attribs.add(EGL_BLUE_SIZE, 1);
        attribs.add(EGL_ALPHA_SIZE, 1);
        attribs.add(EGL_DEPTH_SIZE, 1);
        attribs.add(EGL_STENCIL_SIZE, 1);
        attribs.add(EGL_RENDERABLE_TYPE, api_bits[i]);
        attribs.end(EGL_NONE);

        EGLint num_configs, vid;
        if (eglChooseConfig(eglDisplay, attribs, &visual->config, 1, &num_configs) &&
            num_configs == 1 &&
            eglGetConfigAttrib(eglDisplay, visual->config, EGL_NATIVE_VISUAL_ID, &vid)) {
            XVisualInfo templ;
            int num_visuals;

            templ.visualid = vid;
            visual->visinfo = XGetVisualInfo(display, VisualIDMask, &templ, &num_visuals);
            break;
        }
    }

    assert(visual->visinfo);

    return visual;
}

Drawable *
createDrawable(const Visual *visual, int width, int height)
{
    return new EglDrawable(visual, width, height);
}

Context *
createContext(const Visual *_visual, Context *shareContext, Profile profile)
{
    const EglVisual *visual = static_cast<const EglVisual *>(_visual);
    EGLContext share_context = EGL_NO_CONTEXT;
    EGLContext context;
    Attributes<EGLint> attribs;

    if (shareContext) {
        share_context = static_cast<EglContext*>(shareContext)->context;
    }

    EGLint api = eglQueryAPI();

    switch (profile) {
    case PROFILE_COMPAT:
        load("libGL.so.1");
        eglBindAPI(EGL_OPENGL_API);
        break;
    case PROFILE_CORE:
        assert(0);
        return NULL;
    case PROFILE_ES1:
        load("libGLESv1_CM.so.1");
        eglBindAPI(EGL_OPENGL_ES_API);
        break;
    case PROFILE_ES2:
        load("libGLESv2.so.2");
        eglBindAPI(EGL_OPENGL_ES_API);
        attribs.add(EGL_CONTEXT_CLIENT_VERSION, 2);
        break;
    }

    attribs.end(EGL_NONE);

    context = eglCreateContext(eglDisplay, visual->config, share_context, attribs);
    if (!context)
        return NULL;

    eglBindAPI(api);

    return new EglContext(visual, profile, context);
}

bool
makeCurrent(Drawable *drawable, Context *context)
{
    if (!drawable || !context) {
        return eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    } else {
        EglDrawable *eglDrawable = static_cast<EglDrawable *>(drawable);
        EglContext *eglContext = static_cast<EglContext *>(context);
        EGLBoolean ok;

        ok = eglMakeCurrent(eglDisplay, eglDrawable->surface,
                            eglDrawable->surface, eglContext->context);

        if (ok) {
            EGLint api;

            eglQueryContext(eglDisplay, eglContext->context,
                            EGL_CONTEXT_CLIENT_TYPE, &api);

            eglDrawable->api = api;
        }

        return ok;
    }
}

bool
processEvents(void) {
    while (XPending(display) > 0) {
        XEvent event;
        XNextEvent(display, &event);
        describeEvent(event);
    }
    return true;
}

} /* namespace glws */
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkDashPathEffect.h"

static void test_nulldev(SkCanvas* canvas) {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, 30, 30);
    // notice: no pixels mom! be sure we don't crash
    // https://code.google.com/p/chromium/issues/detail?id=352616
    SkCanvas c(bm);

    SkBitmap src;
    src.allocN32Pixels(10, 10);
    src.eraseColor(SK_ColorRED);

    // ensure we don't crash
    c.writePixels(src, 0, 0);
}

static void draw_text_stroked(SkCanvas* canvas, const SkPaint& paint, SkScalar strokeWidth) {
    SkPaint p(paint);
    SkPoint loc = { 20, 435 };

    if (strokeWidth > 0) {
        p.setStyle(SkPaint::kFill_Style);
        canvas->drawText("P", 1, loc.fX, loc.fY - 225, p);
        canvas->drawPosText("P", 1, &loc, p);
    }

    p.setColor(SK_ColorRED);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(strokeWidth);

    canvas->drawText("P", 1, loc.fX, loc.fY - 225, p);
    canvas->drawPosText("P", 1, &loc, p);
}

static void draw_text_set(SkCanvas* canvas, const SkPaint& paint) {
    SkAutoCanvasRestore acr(canvas, true);

    draw_text_stroked(canvas, paint, 10);

    canvas->translate(200, 0);
    draw_text_stroked(canvas, paint, 0);

    const SkScalar intervals[] = { 20, 10, 5, 10 };
    const SkScalar phase = 0;

    canvas->translate(200, 0);
    SkPaint p(paint);
    p.setPathEffect(SkDashPathEffect::Create(intervals, SK_ARRAY_COUNT(intervals), phase))->unref();
    draw_text_stroked(canvas, paint, 10);
}

class StrokeTextGM : public skiagm::GM {
    // Skia has a threshold above which it draws text via paths instead of using scalercontext
    // and caching the glyph. This GM wants to ensure that we draw stroking correctly on both
    // sides of this threshold.
    enum {
        kBelowThreshold_TextSize = 255,
        kAboveThreshold_TextSize = 257
    };
public:
    StrokeTextGM() {}

protected:
    virtual uint32_t onGetFlags() const SK_OVERRIDE {
        return kSkipTiled_Flag;
    }

    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("stroketext");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(1200, 480);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        if (true) { test_nulldev(canvas); }
        SkPaint paint;
        paint.setAntiAlias(true);

        paint.setTextSize(kBelowThreshold_TextSize);
        draw_text_set(canvas, paint);

        canvas->translate(600, 0);
        paint.setTextSize(kAboveThreshold_TextSize);
        draw_text_set(canvas, paint);
    }

private:
    typedef skiagm::GM INHERITED;
};

DEF_GM( return SkNEW(StrokeTextGM); )
<commit_msg>tweak stroketext GM to actually test dashing<commit_after>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkDashPathEffect.h"

static void test_nulldev(SkCanvas* canvas) {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, 30, 30);
    // notice: no pixels mom! be sure we don't crash
    // https://code.google.com/p/chromium/issues/detail?id=352616
    SkCanvas c(bm);

    SkBitmap src;
    src.allocN32Pixels(10, 10);
    src.eraseColor(SK_ColorRED);

    // ensure we don't crash
    c.writePixels(src, 0, 0);
}

static void draw_text_stroked(SkCanvas* canvas, const SkPaint& paint, SkScalar strokeWidth) {
    SkPaint p(paint);
    SkPoint loc = { 20, 435 };

    if (strokeWidth > 0) {
        p.setStyle(SkPaint::kFill_Style);
        canvas->drawText("P", 1, loc.fX, loc.fY - 225, p);
        canvas->drawPosText("P", 1, &loc, p);
    }

    p.setColor(SK_ColorRED);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(strokeWidth);

    canvas->drawText("P", 1, loc.fX, loc.fY - 225, p);
    canvas->drawPosText("P", 1, &loc, p);
}

static void draw_text_set(SkCanvas* canvas, const SkPaint& paint) {
    SkAutoCanvasRestore acr(canvas, true);

    draw_text_stroked(canvas, paint, 10);

    canvas->translate(200, 0);
    draw_text_stroked(canvas, paint, 0);

    const SkScalar intervals[] = { 20, 10, 5, 10 };
    const SkScalar phase = 0;

    canvas->translate(200, 0);
    SkPaint p(paint);
    p.setPathEffect(SkDashPathEffect::Create(intervals, SK_ARRAY_COUNT(intervals), phase))->unref();
    draw_text_stroked(canvas, p, 10);
}

class StrokeTextGM : public skiagm::GM {
    // Skia has a threshold above which it draws text via paths instead of using scalercontext
    // and caching the glyph. This GM wants to ensure that we draw stroking correctly on both
    // sides of this threshold.
    enum {
        kBelowThreshold_TextSize = 255,
        kAboveThreshold_TextSize = 257
    };
public:
    StrokeTextGM() {}

protected:
    virtual uint32_t onGetFlags() const SK_OVERRIDE {
        return kSkipTiled_Flag;
    }

    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("stroketext");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(1200, 480);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        if (true) { test_nulldev(canvas); }
        SkPaint paint;
        paint.setAntiAlias(true);

        paint.setTextSize(kBelowThreshold_TextSize);
        draw_text_set(canvas, paint);

        canvas->translate(600, 0);
        paint.setTextSize(kAboveThreshold_TextSize);
        draw_text_set(canvas, paint);
    }

private:
    typedef skiagm::GM INHERITED;
};

DEF_GM( return SkNEW(StrokeTextGM); )
<|endoftext|>


<commit_before>#include "DissentTest.hpp"
//#include <cryptosha.h>

using Dissent::Connections::Id;

namespace Dissent {
namespace Tests {
  TEST(Id, Basic) {
    CryptoPP::SHA1 sha1;
    QByteArray hash(20, 0);
    byte *hashb = reinterpret_cast<byte *>(hash.data());

    QByteArray zero("hello");
    const byte *zerob = reinterpret_cast<const byte *>(zero.data());
    sha1.CalculateDigest(hashb, zerob, 5);
    QByteArray hash0(hash.data());

    QByteArray one("world");
    const byte *oneb = reinterpret_cast<const byte *>(one.data());
    sha1.CalculateDigest(hashb, oneb, 5);
    QByteArray hash1(hash.data());

    EXPECT_NE(hash0, hash1);
    EXPECT_NE(zero, hash0);
    EXPECT_NE(hash1, one);

    Id id0(hash0);
    Id id1(hash1);

    EXPECT_NE(id0, id1);

    if(id0 > id1) {
      Id temp = id0;
      id0 = id1;
      id1 = temp;
    }

    ASSERT_TRUE(id0 < id1);
    ASSERT_TRUE(id1 > id0);
    ASSERT_TRUE(id0 != id1);

    Id id0_0(id0.GetBase64String());
    Id id0_1(id0.GetByteArray());
    Id id0_2(id0.GetInteger());

    EXPECT_EQ(id0, id0_0);
    EXPECT_EQ(id0, id0_1);
    EXPECT_EQ(id0, id0_2);

  }
}
}
<commit_msg>[Tests] removed unused code<commit_after>#include "DissentTest.hpp"

using Dissent::Connections::Id;

namespace Dissent {
namespace Tests {
  TEST(Id, Basic) {
    CryptoPP::SHA1 sha1;
    QByteArray hash(20, 0);
    byte *hashb = reinterpret_cast<byte *>(hash.data());

    QByteArray zero("hello");
    const byte *zerob = reinterpret_cast<const byte *>(zero.data());
    sha1.CalculateDigest(hashb, zerob, 5);
    QByteArray hash0(hash.data());

    QByteArray one("world");
    const byte *oneb = reinterpret_cast<const byte *>(one.data());
    sha1.CalculateDigest(hashb, oneb, 5);
    QByteArray hash1(hash.data());

    EXPECT_NE(hash0, hash1);
    EXPECT_NE(zero, hash0);
    EXPECT_NE(hash1, one);

    Id id0(hash0);
    Id id1(hash1);

    EXPECT_NE(id0, id1);

    if(id0 > id1) {
      Id temp = id0;
      id0 = id1;
      id1 = temp;
    }

    ASSERT_TRUE(id0 < id1);
    ASSERT_TRUE(id1 > id0);
    ASSERT_TRUE(id0 != id1);

    Id id0_0(id0.GetBase64String());
    Id id0_1(id0.GetByteArray());
    Id id0_2(id0.GetInteger());

    EXPECT_EQ(id0, id0_0);
    EXPECT_EQ(id0, id0_1);
    EXPECT_EQ(id0, id0_2);

  }
}
}
<|endoftext|>