<commit_before>#include "main_window.h"

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

#include <QMenuBar>
#include <QAction>
#include <QMessageBox>
#include <QFileDialog>
#include <QDockWidget>
#include <QApplication>
#include <QDesktopWidget>

#include <qt_node_editor/bind.h>
#include <dependency_graph/values.inl>

#include <possumwood_sdk/metadata.h>
#include <possumwood_sdk/node_data.h>
#include <possumwood_sdk/io/node_data.h>
#include <possumwood_sdk/app.h>

#include "adaptor.h"

namespace {

QAction* makeAction(QString title, std::function<void()> fn, QWidget* parent) {
	QAction* result = new QAction(title, parent);
	node_editor::qt_bind(result, SIGNAL(triggered(bool)), fn);
	return result;
}

}

MainWindow::MainWindow() : QMainWindow() {
	possumwood::App::instance().setMainWindow(this);

	m_viewport = new Viewport();
	setCentralWidget(m_viewport);

	m_properties = new Properties();
	QDockWidget* propDock = new QDockWidget("Properties", this);
	propDock->setWidget(m_properties);
	m_properties->setMinimumWidth(300);
	addDockWidget(Qt::RightDockWidgetArea, propDock);

	m_adaptor = new Adaptor(&possumwood::App::instance().graph());
	auto geom = m_adaptor->sizeHint();
	geom.setWidth(QApplication::desktop()->screenGeometry().width() / 2 - 200);
	m_adaptor->setSizeHint(geom);

	QDockWidget* graphDock = new QDockWidget("Graph", this);
	graphDock->setWidget(m_adaptor);
	addDockWidget(Qt::LeftDockWidgetArea, graphDock);

	// connect the selection signal
	m_adaptor->scene().setNodeSelectionCallback(
	[&](std::set<std::reference_wrapper<node_editor::Node>, node_editor::GraphScene::NodeRefComparator> selection) {
		m_properties->show(m_adaptor->selectedNodes());
	}
	);

	// create the context click menu
	m_adaptor->setContextMenuPolicy(Qt::CustomContextMenu);

	{
		QMenu* contextMenu = new QMenu(m_adaptor);
		connect(m_adaptor, &Adaptor::customContextMenuRequested, [contextMenu, this](QPoint pos) {
			contextMenu->popup(m_adaptor->mapToGlobal(pos));
		});

		{
			std::map<std::string, QMenu*> groups;

			for(auto& m : possumwood::Metadata::instances()) {
				std::vector<std::string> pieces;
				boost::split(pieces, m.type(), boost::algorithm::is_any_of("/"));

				QMenu* current = contextMenu;
				for(unsigned a=0;a<pieces.size()-1;++a) {
					if(groups[pieces[a]] == nullptr)
						groups[pieces[a]] = current->addMenu(pieces[a].c_str());

					current = groups[pieces[a]];
				}

				const std::string name = pieces.back();
				current->addAction(makeAction(name.c_str(), [&m, name, contextMenu, this]() {
					QPointF pos = m_adaptor->mapToScene(m_adaptor->mapFromGlobal(contextMenu->pos()));
					possumwood::App::instance().graph().nodes().add(m, name, possumwood::NodeData{pos});
				}, m_adaptor));
			}
		}

		QAction* separator = new QAction(m_adaptor);
		separator->setSeparator(true);
		contextMenu->addAction(separator);

		QAction* deleteAction = new QAction("Delete selected items", m_adaptor);
		deleteAction->setShortcut(QKeySequence::Delete);
		contextMenu->addAction(deleteAction);
		m_adaptor->addAction(deleteAction);
		node_editor::qt_bind(deleteAction, SIGNAL(triggered()), [this]() {
			m_adaptor->deleteSelected();
		});
	}

	// drawing callback
	connect(m_viewport, SIGNAL(render(float)), this, SLOT(draw(float)));
	possumwood::App::instance().graph().onDirty([this]() {
		m_viewport->update();
	});

	////////////////////
	// window actions
	QAction* newAct = new QAction("&New...", this);
	newAct->setShortcuts(QKeySequence::New);
	connect(newAct, &QAction::triggered, [&](bool) {
		QMessageBox::StandardButton res = QMessageBox::question(this, "New file...", "Do you want to clear the scene?");
		if(res == QMessageBox::Yes)
			possumwood::App::instance().newFile();
	});

	QAction* openAct = new QAction("&Open...", this);
	openAct->setShortcuts(QKeySequence::Open);
	connect(openAct, &QAction::triggered, [this](bool) {
		QString filename = QFileDialog::getOpenFileName(this, tr("Open File"),
		                   possumwood::App::instance().filename().string().c_str(),
		                   tr("Possumwood files (*.psw)"));

		if(!filename.isEmpty()) {
			try {
				possumwood::App::instance().loadFile(filename.toStdString());
			}
			catch(std::exception& err) {
				QMessageBox::critical(this, "Error loading file...", "Error loading " + filename + ":\n" + err.what());
			}
			catch(...) {
				QMessageBox::critical(this, "Error loading file...", "Error loading " + filename + ":\nUnhandled exception thrown during loading.");
			}
		}
	});

	QAction* saveAct = new QAction("&Save...", this);
	saveAct->setShortcuts(QKeySequence::Save);
	QAction* saveAsAct = new QAction("Save &As...", this);
	saveAsAct->setShortcuts(QKeySequence::SaveAs);

	connect(saveAct, &QAction::triggered, [saveAsAct, this](bool) {
		if(possumwood::App::instance().filename().empty())
			saveAsAct->triggered(true);

		else {
			try {
				possumwood::App::instance().saveFile();
			}
			catch(std::exception& err) {
				QMessageBox::critical(this, "Error saving file...", "Error saving " + QString(possumwood::App::instance().filename().string().c_str()) + ":\n" + err.what());
			}
			catch(...) {
				QMessageBox::critical(this, "Error saving file...", "Error saving " + QString(possumwood::App::instance().filename().string().c_str()) + ":\nUnhandled exception thrown during saving.");
			}
		}
	});

	connect(saveAsAct, &QAction::triggered, [saveAct, this](bool) {
		QString filename = QFileDialog::getSaveFileName(this, tr("Save File"),
		                   possumwood::App::instance().filename().string().c_str(),
		                   tr("Possumwood files (*.psw)"));

		if(!filename.isEmpty()) {
			try {
				possumwood::App::instance().saveFile(filename.toStdString());
			}
			catch(std::exception& err) {
				QMessageBox::critical(this, "Error saving file...", "Error saving " + QString(possumwood::App::instance().filename().string().c_str()) + ":\n" + err.what());
			}
			catch(...) {
				QMessageBox::critical(this, "Error saving file...", "Error saving " + QString(possumwood::App::instance().filename().string().c_str()) + ":\nUnhandled exception thrown during saving.");
			}
		}
	});

	////////////////////
	// create menu

	QMenu* fileMenu = menuBar()->addMenu("&File");

	fileMenu->addAction(newAct);
	fileMenu->addAction(openAct);
	fileMenu->addAction(saveAct);

	QMenu* viewMenu = menuBar()->addMenu("&View");
	fileMenu->addAction(saveAsAct);

	viewMenu->addAction(propDock->toggleViewAction());
	viewMenu->addAction(graphDock->toggleViewAction());
}

MainWindow::~MainWindow() {
	possumwood::App::instance().graph().clear();
}

void MainWindow::draw(float dt) {
	// draw the floor grid
	glBegin(GL_LINES);

	for(int a = -10; a <= 10; ++a) {
		const float c = 0.3f + (float)(a % 10 == 0) * 0.2f;
		glColor3f(c, c, c);

		glVertex3f(a, 0, -10);
		glVertex3f(a, 0, 10);
	}

	for(int a = -10; a <= 10; ++a) {
		const float c = 0.3f + (float)(a % 10 == 0) * 0.2f;
		glColor3f(c, c, c);

		glVertex3f(-10, 0, a);
		glVertex3f(10, 0, a);
	}

	glEnd();

	// draw everything else
	for(auto& n : m_adaptor->graph().nodes()) {
		glPushAttrib(GL_ALL_ATTRIB_BITS);

		const possumwood::Metadata& meta = dynamic_cast<const possumwood::Metadata&>(n.metadata());
		meta.draw(dependency_graph::Values(n));

		glPopAttrib();
	}

}
<commit_msg>Fixed properties window refresh when opening a new scene<commit_after>#include "main_window.h"

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

#include <QMenuBar>
#include <QAction>
#include <QMessageBox>
#include <QFileDialog>
#include <QDockWidget>
#include <QApplication>
#include <QDesktopWidget>

#include <qt_node_editor/bind.h>
#include <dependency_graph/values.inl>

#include <possumwood_sdk/metadata.h>
#include <possumwood_sdk/node_data.h>
#include <possumwood_sdk/io/node_data.h>
#include <possumwood_sdk/app.h>

#include "adaptor.h"

namespace {

QAction* makeAction(QString title, std::function<void()> fn, QWidget* parent) {
	QAction* result = new QAction(title, parent);
	node_editor::qt_bind(result, SIGNAL(triggered(bool)), fn);
	return result;
}

}

MainWindow::MainWindow() : QMainWindow() {
	possumwood::App::instance().setMainWindow(this);

	m_viewport = new Viewport();
	setCentralWidget(m_viewport);

	m_properties = new Properties();
	QDockWidget* propDock = new QDockWidget("Properties", this);
	propDock->setWidget(m_properties);
	m_properties->setMinimumWidth(300);
	addDockWidget(Qt::RightDockWidgetArea, propDock);

	m_adaptor = new Adaptor(&possumwood::App::instance().graph());
	auto geom = m_adaptor->sizeHint();
	geom.setWidth(QApplication::desktop()->screenGeometry().width() / 2 - 200);
	m_adaptor->setSizeHint(geom);

	QDockWidget* graphDock = new QDockWidget("Graph", this);
	graphDock->setWidget(m_adaptor);
	addDockWidget(Qt::LeftDockWidgetArea, graphDock);

	// connect the selection signal
	m_adaptor->scene().setNodeSelectionCallback(
	[&](std::set<std::reference_wrapper<node_editor::Node>, node_editor::GraphScene::NodeRefComparator> selection) {
		m_properties->show(m_adaptor->selectedNodes());
	}
	);

	// create the context click menu
	m_adaptor->setContextMenuPolicy(Qt::CustomContextMenu);

	{
		QMenu* contextMenu = new QMenu(m_adaptor);
		connect(m_adaptor, &Adaptor::customContextMenuRequested, [contextMenu, this](QPoint pos) {
			contextMenu->popup(m_adaptor->mapToGlobal(pos));
		});

		{
			std::map<std::string, QMenu*> groups;

			for(auto& m : possumwood::Metadata::instances()) {
				std::vector<std::string> pieces;
				boost::split(pieces, m.type(), boost::algorithm::is_any_of("/"));

				QMenu* current = contextMenu;
				for(unsigned a=0;a<pieces.size()-1;++a) {
					if(groups[pieces[a]] == nullptr)
						groups[pieces[a]] = current->addMenu(pieces[a].c_str());

					current = groups[pieces[a]];
				}

				const std::string name = pieces.back();
				current->addAction(makeAction(name.c_str(), [&m, name, contextMenu, this]() {
					QPointF pos = m_adaptor->mapToScene(m_adaptor->mapFromGlobal(contextMenu->pos()));
					possumwood::App::instance().graph().nodes().add(m, name, possumwood::NodeData{pos});
				}, m_adaptor));
			}
		}

		QAction* separator = new QAction(m_adaptor);
		separator->setSeparator(true);
		contextMenu->addAction(separator);

		QAction* deleteAction = new QAction("Delete selected items", m_adaptor);
		deleteAction->setShortcut(QKeySequence::Delete);
		contextMenu->addAction(deleteAction);
		m_adaptor->addAction(deleteAction);
		node_editor::qt_bind(deleteAction, SIGNAL(triggered()), [this]() {
			m_adaptor->deleteSelected();
		});
	}

	// drawing callback
	connect(m_viewport, SIGNAL(render(float)), this, SLOT(draw(float)));
	possumwood::App::instance().graph().onDirty([this]() {
		m_viewport->update();
	});

	////////////////////
	// window actions
	QAction* newAct = new QAction("&New...", this);
	newAct->setShortcuts(QKeySequence::New);
	connect(newAct, &QAction::triggered, [&](bool) {
		QMessageBox::StandardButton res = QMessageBox::question(this, "New file...", "Do you want to clear the scene?");
		if(res == QMessageBox::Yes) {
			m_properties->show({});
			possumwood::App::instance().newFile();
		}
	});

	QAction* openAct = new QAction("&Open...", this);
	openAct->setShortcuts(QKeySequence::Open);
	connect(openAct, &QAction::triggered, [this](bool) {
		QString filename = QFileDialog::getOpenFileName(this, tr("Open File"),
		                   possumwood::App::instance().filename().string().c_str(),
		                   tr("Possumwood files (*.psw)"));

		if(!filename.isEmpty()) {
			try {
				m_properties->show({});
				possumwood::App::instance().loadFile(filename.toStdString());
			}
			catch(std::exception& err) {
				QMessageBox::critical(this, "Error loading file...", "Error loading " + filename + ":\n" + err.what());
			}
			catch(...) {
				QMessageBox::critical(this, "Error loading file...", "Error loading " + filename + ":\nUnhandled exception thrown during loading.");
			}
		}
	});

	QAction* saveAct = new QAction("&Save...", this);
	saveAct->setShortcuts(QKeySequence::Save);
	QAction* saveAsAct = new QAction("Save &As...", this);
	saveAsAct->setShortcuts(QKeySequence::SaveAs);

	connect(saveAct, &QAction::triggered, [saveAsAct, this](bool) {
		if(possumwood::App::instance().filename().empty())
			saveAsAct->triggered(true);

		else {
			try {
				possumwood::App::instance().saveFile();
			}
			catch(std::exception& err) {
				QMessageBox::critical(this, "Error saving file...", "Error saving " + QString(possumwood::App::instance().filename().string().c_str()) + ":\n" + err.what());
			}
			catch(...) {
				QMessageBox::critical(this, "Error saving file...", "Error saving " + QString(possumwood::App::instance().filename().string().c_str()) + ":\nUnhandled exception thrown during saving.");
			}
		}
	});

	connect(saveAsAct, &QAction::triggered, [saveAct, this](bool) {
		QString filename = QFileDialog::getSaveFileName(this, tr("Save File"),
		                   possumwood::App::instance().filename().string().c_str(),
		                   tr("Possumwood files (*.psw)"));

		if(!filename.isEmpty()) {
			try {
				possumwood::App::instance().saveFile(filename.toStdString());
			}
			catch(std::exception& err) {
				QMessageBox::critical(this, "Error saving file...", "Error saving " + QString(possumwood::App::instance().filename().string().c_str()) + ":\n" + err.what());
			}
			catch(...) {
				QMessageBox::critical(this, "Error saving file...", "Error saving " + QString(possumwood::App::instance().filename().string().c_str()) + ":\nUnhandled exception thrown during saving.");
			}
		}
	});

	////////////////////
	// create menu

	QMenu* fileMenu = menuBar()->addMenu("&File");

	fileMenu->addAction(newAct);
	fileMenu->addAction(openAct);
	fileMenu->addAction(saveAct);

	QMenu* viewMenu = menuBar()->addMenu("&View");
	fileMenu->addAction(saveAsAct);

	viewMenu->addAction(propDock->toggleViewAction());
	viewMenu->addAction(graphDock->toggleViewAction());
}

MainWindow::~MainWindow() {
	possumwood::App::instance().graph().clear();
}

void MainWindow::draw(float dt) {
	// draw the floor grid
	glBegin(GL_LINES);

	for(int a = -10; a <= 10; ++a) {
		const float c = 0.3f + (float)(a % 10 == 0) * 0.2f;
		glColor3f(c, c, c);

		glVertex3f(a, 0, -10);
		glVertex3f(a, 0, 10);
	}

	for(int a = -10; a <= 10; ++a) {
		const float c = 0.3f + (float)(a % 10 == 0) * 0.2f;
		glColor3f(c, c, c);

		glVertex3f(-10, 0, a);
		glVertex3f(10, 0, a);
	}

	glEnd();

	// draw everything else
	for(auto& n : m_adaptor->graph().nodes()) {
		glPushAttrib(GL_ALL_ATTRIB_BITS);

		const possumwood::Metadata& meta = dynamic_cast<const possumwood::Metadata&>(n.metadata());
		meta.draw(dependency_graph::Values(n));

		glPopAttrib();
	}

}
<|endoftext|>


<commit_before>// GlutAppSkeleton.cpp

#ifdef _WIN32
#  define WINDOWS_LEAN_AND_MEAN
#  define NOMINMAX
#  include <windows.h>
#endif
#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>

#include "GlutAppSkeleton.h"

#include "GL/GLUtils.h"
#include "GL/ShaderFunctions.h"
#include "MatrixMath.h"
#include "utils/Logger.h"
#include "paramgl.h"

void GlutAppSkeleton::glut_PrintString(void *font, const char *str)
{
    int l = (int)strlen(str);
    for (int i=0; i<l; ++i)
    {
        glutBitmapCharacter(font, *str++);
    }
}

GlutAppSkeleton::GlutAppSkeleton()
: TriAppSkeleton()
{
    g_colorVal = 0.0f;
    curMouseAction = None;

    paramlist = NULL;
    paramlistA = NULL;

    InitParameters();
}

GlutAppSkeleton::~GlutAppSkeleton()
{
}

void GlutAppSkeleton::InitParameters()
{
    // create a new parameter list
    {
        paramlistA = new ParamListGL("Parameters");
        paramlistA->SetBarColorInner(0.8f, 0.2f, 0.2f);

        paramlistA->AddParam(new Param<float>("rotation.x", g_rotation.x,
                                       0.0f, 360.0f, .1f, &(g_rotation.x)));
        paramlistA->AddParam(new Param<float>("rotation.y", g_rotation.y,
                                       0.0f, 360.0f, .1f, &(g_rotation.y)));
        paramlistA->AddParam(new Param<float>("rotation.z", g_rotation.z,
                                       0.0f, 360.0f, .1f, &(g_rotation.z)));
    }
    paramlist = paramlistA;
}

///
/// Another layer of abstraction for printing text to screen.
/// Allows us to easily use uniforms for color when shaders are the norm.
///
/// @param font A glut \#define like GLUT_BITMAP_HELVETICA_12.
/// @param color A float3 rgb color value.
/// @param prog A GL shader program to set the color as uniform.
/// @param pos An int2 screen space pixel coordinate pair.
/// @param str A pointer to char(string) of ASCII text to print.
///
void GlutAppSkeleton::GlutDrawText(
    void*  font,
    const float3 color,
    const GLuint prog,
    const int2   pos,
    const char*  str) const
{
    if (prog == 0)
    {
        ///@todo Log an error
        return;
    }

    glUniform3f(getUniLoc(prog, "u_col"), color.x, color.y, color.z);
    glRasterPos2i(pos.x, pos.y);
    glut_PrintString(font, str);
}

void GlutAppSkeleton::drawOverlay() const
{
    glUseProgram(g_progOverlay);

    /// Set up a simple orthographic projection matrix for text
    float proj[16];
    glhOrtho(proj,
        0.0f, (float)g_windowWidth,
        0.0f, (float)g_windowHeight,
        -1.0f, 1.0f);
    glUniformMatrix4fv(getUniLoc(g_progOverlay, "prmtx"), 1, false, proj);

    std::ostringstream oss;
    oss.str("");
    oss.clear();
    oss << g_cameraLocation.x << " "
        << g_cameraLocation.y << " "
        << g_cameraLocation.z << "   "
        << g_rotation.x << " "
        << g_rotation.y;

    float3 white = {g_colorVal,1,1};
    int2 pos = make_int2(10,20);
    GlutDrawText(
        GLUT_BITMAP_HELVETICA_12,
        white,
        g_progOverlay,
        pos,
        oss.str().c_str());

    glUseProgram(0);
}

/// Draw param sliders with fixed pipeline
void GlutAppSkeleton::drawSlidersFixedPipeline() const
{
    glUseProgram(0);
    glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); // invert color
    glEnable(GL_BLEND);
    if (paramlist)
        paramlist->Render(0, 0);
    glDisable(GL_BLEND);
}

void GlutAppSkeleton::display() const
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    glUseProgram(g_progBasic);
    {
        /// Set up our 3D transformation matrices
        float modelviewMatrix[16];
        float projectionMatrix[16];

        float3 origin = g_cameraLocation + g_lookVector;
        glhLookAtf2(modelviewMatrix,
                    g_cameraLocation,
                    origin,
                    g_upVector);
        glhTranslate(modelviewMatrix, 0.0f, g_distance, 0.0f);
        glhRotate(modelviewMatrix,  g_rotation.x, 0.0f, 0.0f, 1.0f);
        glhRotate(modelviewMatrix,  g_rotation.y, 1.0f, 0.0f, 0.0f);

        glhPerspectivef2(projectionMatrix, g_viewAngle, (float)g_windowWidth/(float)g_windowHeight, 0.004, 500.0);

        glUniformMatrix4fv(getUniLoc(g_progBasic, "mvmtx"), 1, false, modelviewMatrix);
        glUniformMatrix4fv(getUniLoc(g_progBasic, "prmtx"), 1, false, projectionMatrix);

        //glutWireSphere(1.0f, 16, 16);
        drawObject();
    }
    glUseProgram(0);

    drawOverlay();

    drawSlidersFixedPipeline();

    CHECK_GL_ERROR_MACRO();
}

void GlutAppSkeleton::mouseDown(int button, int state, int x, int y)
{
    {
        if (paramlist && paramlist->Mouse(x, y, button, state))
        {
            curMouseAction = AdjustParam;
            return;
        }
    }
    curMouseAction = None;

    TriAppSkeleton::mouseDown(button, state, x, y);
}

void GlutAppSkeleton::mouseMove(int x, int y)
{
    if (AdjustParam == curMouseAction)
    {
        if (paramlist && paramlist->Motion(x, y))
        {
        }
        return;
    }

    TriAppSkeleton::mouseMove(x,y);
}

void GlutAppSkeleton::keyboard(int key, int x, int y)
{
    TriAppSkeleton::keyboard(key, x, y);
}

void GlutAppSkeleton::resize(int w, int h)
{
    g_windowWidth = w;
    g_windowHeight = h;

    glViewport(0,0, (GLsizei)w, (GLsizei)h);
}

bool GlutAppSkeleton::initGL(int argc, char **argv)
{
    bool ret = TriAppSkeleton::initGL(argc, argv);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    //glDisable(GL_LIGHTING);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    CHECK_GL_ERROR_MACRO();

    return ret;
}
<commit_msg>Add escape quit clause to Glut key handler.<commit_after>// GlutAppSkeleton.cpp

#ifdef _WIN32
#  define WINDOWS_LEAN_AND_MEAN
#  define NOMINMAX
#  include <windows.h>
#endif
#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>

#include "GlutAppSkeleton.h"

#include "GL/GLUtils.h"
#include "GL/ShaderFunctions.h"
#include "MatrixMath.h"
#include "utils/Logger.h"
#include "paramgl.h"

void GlutAppSkeleton::glut_PrintString(void *font, const char *str)
{
    int l = (int)strlen(str);
    for (int i=0; i<l; ++i)
    {
        glutBitmapCharacter(font, *str++);
    }
}

GlutAppSkeleton::GlutAppSkeleton()
: TriAppSkeleton()
{
    g_colorVal = 0.0f;
    curMouseAction = None;

    paramlist = NULL;
    paramlistA = NULL;

    InitParameters();
}

GlutAppSkeleton::~GlutAppSkeleton()
{
}

void GlutAppSkeleton::InitParameters()
{
    // create a new parameter list
    {
        paramlistA = new ParamListGL("Parameters");
        paramlistA->SetBarColorInner(0.8f, 0.2f, 0.2f);

        paramlistA->AddParam(new Param<float>("rotation.x", g_rotation.x,
                                       0.0f, 360.0f, .1f, &(g_rotation.x)));
        paramlistA->AddParam(new Param<float>("rotation.y", g_rotation.y,
                                       0.0f, 360.0f, .1f, &(g_rotation.y)));
        paramlistA->AddParam(new Param<float>("rotation.z", g_rotation.z,
                                       0.0f, 360.0f, .1f, &(g_rotation.z)));
    }
    paramlist = paramlistA;
}

///
/// Another layer of abstraction for printing text to screen.
/// Allows us to easily use uniforms for color when shaders are the norm.
///
/// @param font A glut \#define like GLUT_BITMAP_HELVETICA_12.
/// @param color A float3 rgb color value.
/// @param prog A GL shader program to set the color as uniform.
/// @param pos An int2 screen space pixel coordinate pair.
/// @param str A pointer to char(string) of ASCII text to print.
///
void GlutAppSkeleton::GlutDrawText(
    void*  font,
    const float3 color,
    const GLuint prog,
    const int2   pos,
    const char*  str) const
{
    if (prog == 0)
    {
        ///@todo Log an error
        return;
    }

    glUniform3f(getUniLoc(prog, "u_col"), color.x, color.y, color.z);
    glRasterPos2i(pos.x, pos.y);
    glut_PrintString(font, str);
}

void GlutAppSkeleton::drawOverlay() const
{
    glUseProgram(g_progOverlay);

    /// Set up a simple orthographic projection matrix for text
    float proj[16];
    glhOrtho(proj,
        0.0f, (float)g_windowWidth,
        0.0f, (float)g_windowHeight,
        -1.0f, 1.0f);
    glUniformMatrix4fv(getUniLoc(g_progOverlay, "prmtx"), 1, false, proj);

    std::ostringstream oss;
    oss.str("");
    oss.clear();
    oss << g_cameraLocation.x << " "
        << g_cameraLocation.y << " "
        << g_cameraLocation.z << "   "
        << g_rotation.x << " "
        << g_rotation.y;

    float3 white = {g_colorVal,1,1};
    int2 pos = make_int2(10,20);
    GlutDrawText(
        GLUT_BITMAP_HELVETICA_12,
        white,
        g_progOverlay,
        pos,
        oss.str().c_str());

    glUseProgram(0);
}

/// Draw param sliders with fixed pipeline
void GlutAppSkeleton::drawSlidersFixedPipeline() const
{
    glUseProgram(0);
    glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); // invert color
    glEnable(GL_BLEND);
    if (paramlist)
        paramlist->Render(0, 0);
    glDisable(GL_BLEND);
}

void GlutAppSkeleton::display() const
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    glUseProgram(g_progBasic);
    {
        /// Set up our 3D transformation matrices
        float modelviewMatrix[16];
        float projectionMatrix[16];

        float3 origin = g_cameraLocation + g_lookVector;
        glhLookAtf2(modelviewMatrix,
                    g_cameraLocation,
                    origin,
                    g_upVector);
        glhTranslate(modelviewMatrix, 0.0f, g_distance, 0.0f);
        glhRotate(modelviewMatrix,  g_rotation.x, 0.0f, 0.0f, 1.0f);
        glhRotate(modelviewMatrix,  g_rotation.y, 1.0f, 0.0f, 0.0f);

        glhPerspectivef2(projectionMatrix, g_viewAngle, (float)g_windowWidth/(float)g_windowHeight, 0.004, 500.0);

        glUniformMatrix4fv(getUniLoc(g_progBasic, "mvmtx"), 1, false, modelviewMatrix);
        glUniformMatrix4fv(getUniLoc(g_progBasic, "prmtx"), 1, false, projectionMatrix);

        //glutWireSphere(1.0f, 16, 16);
        drawObject();
    }
    glUseProgram(0);

    drawOverlay();

    drawSlidersFixedPipeline();

    CHECK_GL_ERROR_MACRO();
}

void GlutAppSkeleton::mouseDown(int button, int state, int x, int y)
{
    {
        if (paramlist && paramlist->Mouse(x, y, button, state))
        {
            curMouseAction = AdjustParam;
            return;
        }
    }
    curMouseAction = None;

    TriAppSkeleton::mouseDown(button, state, x, y);
}

void GlutAppSkeleton::mouseMove(int x, int y)
{
    if (AdjustParam == curMouseAction)
    {
        if (paramlist && paramlist->Motion(x, y))
        {
        }
        return;
    }

    TriAppSkeleton::mouseMove(x,y);
}

void GlutAppSkeleton::keyboard(int key, int x, int y)
{
    switch(key)
    {
    default:
        break;

    case 27: // Escape
        exit(0);
        break;
    }
    TriAppSkeleton::keyboard(key, x, y);
}

void GlutAppSkeleton::resize(int w, int h)
{
    g_windowWidth = w;
    g_windowHeight = h;

    glViewport(0,0, (GLsizei)w, (GLsizei)h);
}

bool GlutAppSkeleton::initGL(int argc, char **argv)
{
    bool ret = TriAppSkeleton::initGL(argc, argv);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    //glDisable(GL_LIGHTING);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    CHECK_GL_ERROR_MACRO();

    return ret;
}
<|endoftext|>


<commit_before><commit_msg>source/qt5xhb_utils.cpp: changes related with xHarbour compatibility<commit_after><|endoftext|>


<commit_before>/*
 * ArcEmu MMORPG Server
 * Copyright (C) 2005-2007 Ascent Team <http://www.ascentemu.com/>
 * Copyright (C) 2008-2010 <http://www.ArcEmu.org/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "StdAfx.h"

class HotStreakSpellProc : public SpellProc
{
	SPELL_PROC_FACTORY_FUNCTION(HotStreakSpellProc);

	void Init(Object* obj)
	{
		mCritsInARow = 0;
	}

	bool DoEffect(Unit *victim, SpellEntry *CastingSpell, uint32 flag, uint32 dmg, uint32 abs, int *dmg_overwrite)
	{
		// Check for classmask. Should proc only if CastingSpell is one listed in http://www.wowhead.com/spell=44448
		if ( ! CheckClassMask(victim, CastingSpell) )
			return true;

		// If was not a crit, reset counter and don't proc
		if ( ! (flag & PROC_ON_SPELL_CRIT_HIT) )
		{
			mCritsInARow = 0;
			return true;
		}

		// If was not at least 2nd crit in a row, don't proc
		if ( ++mCritsInARow < 2 )
			return true;

		return false;
	}

private:
	int mCritsInARow;
};

void SpellProcMgr::SetupMage()
{
	AddById( 48108, &HotStreakSpellProc::Create );
}<commit_msg>FIXED: Mage Hot Streak was triggering by any spell. r3425 introduced a new parameter in DoEffect, and it was missing in HotStreakSpellProc<commit_after>/*
 * ArcEmu MMORPG Server
 * Copyright (C) 2005-2007 Ascent Team <http://www.ascentemu.com/>
 * Copyright (C) 2008-2010 <http://www.ArcEmu.org/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "StdAfx.h"

class HotStreakSpellProc : public SpellProc
{
	SPELL_PROC_FACTORY_FUNCTION(HotStreakSpellProc);

	void Init(Object* obj)
	{
		mCritsInARow = 0;
	}

	bool DoEffect(Unit *victim, SpellEntry *CastingSpell, uint32 flag, uint32 dmg, uint32 abs, int *dmg_overwrite, uint32 weapon_damage_type)
	{
		// Check for classmask. Should proc only if CastingSpell is one listed in http://www.wowhead.com/spell=44448
		if ( ! CheckClassMask(victim, CastingSpell) )
			return true;

		// If was not a crit, reset counter and don't proc
		if ( ! (flag & PROC_ON_SPELL_CRIT_HIT) )
		{
			mCritsInARow = 0;
			return true;
		}

		// If was not at least 2nd crit in a row, don't proc
		if ( ++mCritsInARow < 2 )
			return true;

		return false;
	}

private:
	int mCritsInARow;
};

void SpellProcMgr::SetupMage()
{
	AddById( 48108, &HotStreakSpellProc::Create );
}<|endoftext|>


<commit_before>/*
    Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>

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

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "contactswitcher.h"

#include <klocale.h>

#include <QtGui/QAbstractItemView>
#include <QtGui/QHBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>

ContactSwitcher::ContactSwitcher( QWidget *parent )
  : QWidget( parent ),
    mView( 0 )
{
  QHBoxLayout *layout = new QHBoxLayout( this );

  mPreviousButton = new QPushButton( i18n( "Previous" ) );
  mNextButton = new QPushButton( i18n( "Next" ) );
  mStatusLabel = new QLabel();

  layout->addWidget( mPreviousButton );
  layout->addWidget( mNextButton );
  layout->addStretch( 1 );
  layout->addWidget( mStatusLabel );

  connect( mPreviousButton, SIGNAL( clicked() ), SLOT( previousClicked() ) );
  connect( mNextButton, SIGNAL( clicked() ), SLOT( nextClicked() ) );
}

void ContactSwitcher::setView( QAbstractItemView *view )
{
  mView = view;

  Q_ASSERT_X( mView->model(), "ContactSwitcher::setView", "The view has no model set!" );

  connect( mView->model(), SIGNAL( layoutChanged() ), SLOT( updateStatus() ) );
  connect( mView->model(), SIGNAL( rowsInserted(const QModelIndex&, int, int) ), SLOT( updateStatus() ) );
  connect( mView->model(), SIGNAL( rowsRemoved(const QModelIndex&, int, int) ), SLOT( updateStatus() ) );

  updateStatus();
}

void ContactSwitcher::nextClicked()
{
  if ( !mView || !mView->model() )
    return;

  const QModelIndex index = mView->selectionModel()->currentIndex();

  int row = 0;
  if ( index.isValid() )
    row = index.row() + 1;

  mView->selectionModel()->setCurrentIndex( mView->model()->index( row, 0 ),
                                            QItemSelectionModel::Rows |
                                            QItemSelectionModel::ClearAndSelect );

  updateStatus();
}

void ContactSwitcher::previousClicked()
{
  if ( !mView || !mView->model() )
    return;

  const QModelIndex index = mView->selectionModel()->currentIndex();

  int row = 0;
  if ( index.isValid() )
    row = index.row() - 1;

  mView->selectionModel()->setCurrentIndex( mView->model()->index( row, 0 ),
                                            QItemSelectionModel::Rows |
                                            QItemSelectionModel::ClearAndSelect );

  updateStatus();
}

void ContactSwitcher::updateStatus()
{
  if ( !mView || !mView->model() )
    return;

  const QModelIndex index = mView->selectionModel()->currentIndex();

  int row = 0;
  if ( index.isValid() )
    row = index.row();

  mPreviousButton->setEnabled( row != 0 );
  mNextButton->setEnabled( row != (mView->model()->rowCount() - 1) );

  mStatusLabel->setText( i18n( "%1 out of %2" ).arg( row + 1 ).arg( mView->model()->rowCount() ) );
}

#include "contactswitcher.moc"
<commit_msg>fix broken i18n call<commit_after>/*
    Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>

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

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "contactswitcher.h"

#include <klocale.h>

#include <QtGui/QAbstractItemView>
#include <QtGui/QHBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>

ContactSwitcher::ContactSwitcher( QWidget *parent )
  : QWidget( parent ),
    mView( 0 )
{
  QHBoxLayout *layout = new QHBoxLayout( this );

  mPreviousButton = new QPushButton( i18n( "Previous" ) );
  mNextButton = new QPushButton( i18n( "Next" ) );
  mStatusLabel = new QLabel();

  layout->addWidget( mPreviousButton );
  layout->addWidget( mNextButton );
  layout->addStretch( 1 );
  layout->addWidget( mStatusLabel );

  connect( mPreviousButton, SIGNAL( clicked() ), SLOT( previousClicked() ) );
  connect( mNextButton, SIGNAL( clicked() ), SLOT( nextClicked() ) );
}

void ContactSwitcher::setView( QAbstractItemView *view )
{
  mView = view;

  Q_ASSERT_X( mView->model(), "ContactSwitcher::setView", "The view has no model set!" );

  connect( mView->model(), SIGNAL( layoutChanged() ), SLOT( updateStatus() ) );
  connect( mView->model(), SIGNAL( rowsInserted(const QModelIndex&, int, int) ), SLOT( updateStatus() ) );
  connect( mView->model(), SIGNAL( rowsRemoved(const QModelIndex&, int, int) ), SLOT( updateStatus() ) );

  updateStatus();
}

void ContactSwitcher::nextClicked()
{
  if ( !mView || !mView->model() )
    return;

  const QModelIndex index = mView->selectionModel()->currentIndex();

  int row = 0;
  if ( index.isValid() )
    row = index.row() + 1;

  mView->selectionModel()->setCurrentIndex( mView->model()->index( row, 0 ),
                                            QItemSelectionModel::Rows |
                                            QItemSelectionModel::ClearAndSelect );

  updateStatus();
}

void ContactSwitcher::previousClicked()
{
  if ( !mView || !mView->model() )
    return;

  const QModelIndex index = mView->selectionModel()->currentIndex();

  int row = 0;
  if ( index.isValid() )
    row = index.row() - 1;

  mView->selectionModel()->setCurrentIndex( mView->model()->index( row, 0 ),
                                            QItemSelectionModel::Rows |
                                            QItemSelectionModel::ClearAndSelect );

  updateStatus();
}

void ContactSwitcher::updateStatus()
{
  if ( !mView || !mView->model() )
    return;

  const QModelIndex index = mView->selectionModel()->currentIndex();

  int row = 0;
  if ( index.isValid() )
    row = index.row();

  mPreviousButton->setEnabled( row != 0 );
  mNextButton->setEnabled( row != (mView->model()->rowCount() - 1) );

  mStatusLabel->setText( i18n( "%1 out of %2", row + 1,  mView->model()->rowCount() ) );
}

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


<commit_before>
// (c) COPYRIGHT URI/MIT 1994-1996
// Please read the full copyright statement in the file COPYRIGH.
//
// Authors:
//      jhrg,jimg       James Gallagher (jgallagher@gso.uri.edu)

// Implementation for the CE Clause class.

// $Log: Error.cc,v $
// Revision 1.5  1996/06/22 00:02:46  jimg
// Added Gui pointer to the Error oject's correct_error() and
// display_message() mfuncs. These mfuncs now used the GUI to display
// messages.
//
// Revision 1.4  1996/06/04 21:33:22  jimg
// Multiple connections are now possible. It is now possible to open several
// URLs at the same time and read from them in a round-robin fashion. To do
// this I added data source and sink parameters to the serialize and
// deserialize mfuncs. Connect was also modified so that it manages the data
// source `object' (which is just an XDR pointer).
//
// Revision 1.3  1996/06/03 06:26:51  jimg
// Added declarations for Errorparse() and Errorrestart().
//
// Revision 1.2  1996/06/01 00:03:38  jimg
// Added.
//

#ifdef __GNUG__
#pragma implementation
#endif

static char rcsid[]={"$Id: Error.cc,v 1.5 1996/06/22 00:02:46 jimg Exp $"};

#include <assert.h>

#include "Error.h"
#include "parser.h"

void Errorrestart(FILE *yyin);
int Errorparse(void *arg); // defined in dds.tab.c

Error::Error()
    : _error_code(undefined_error), _error_message(""),
      _program_type(undefined_prog_type), _program(0)
{
}

Error::Error(ErrorCode ec, String msg)
    : _error_code(ec), _error_message(msg),
      _program_type(undefined_prog_type), _program(0)
{
}

Error::Error(ErrorCode ec, String msg, ProgramType pt, char *pgm)
    : _error_code(ec), _error_message(msg),
      _program_type(pt), _program(0)
{
    _program = new char[strlen(pgm) + 1];
    strcpy(_program, pgm);
}

Error::Error(const Error &copy_from)
    : _error_code(copy_from._error_code),
      _error_message(copy_from._error_message),
      _program_type(copy_from._program_type), _program(0)
{
    _program = new char[strlen(copy_from._program) + 1];
    strcpy(_program, copy_from._program);
}

Error::~Error()
{
    delete _program;
}

Error &
Error::operator=(const Error &rhs)
{
    if (&rhs == this)		// are they identical?
	return *this;
    else {
	_error_code = rhs._error_code;
	_error_message = rhs._error_message;
	_program_type = rhs._program_type;

	_program = new char[strlen(rhs._program) + 1];
	strcpy(_program, rhs._program);

	return *this;
    }
}

// To be a valid, an Error object must either be: 1) empty, 2) contain a
// message and a program or 3) contain only a message. Since the program is
// optional, there is no need to test for it here.
//
// NB: This mfunc does not test for malformed messages or programs - ones
// where the code is defined but not the `data'.

bool
Error::OK()
{
    bool empty = ((_error_code == undefined_error)
		  && (_error_message == "")
		  && (_program_type == undefined_prog_type)
		  && (_program == 0));

    bool message = ((_error_code != undefined_error)
		    && (_error_message != ""));

    // bool program = ((_program_type != undefined_prog_type)
    //                 && (_program != 0))

    return empty || message;
}

bool
Error::parse(FILE *fp)
{
    if (!fp) {
	cerr << "Error::parse: Null input stream" << endl;
	return false;
    }

    Errorrestart(fp);

    parser_arg arg(this);

    bool status = Errorparse((void *)&arg) == 0;

    fclose(fp);

    // need to check the arg status because the parser may have recovered
    // from an error (and thus returned true).
    return status && arg.status() && OK();
}

void
Error::print(ostream &os = cout)
{
    if (!OK()) {
	cerr << "Bad Error object" << endl;
	return;
    }

    os << "Error {" << endl;

    if (_error_code != undefined_error) {
	os << "    " << "code = " << _error_code << ";" << endl;
	os << "    " << "message = " << _error_message << ";" << endl;

	if (_program_type != undefined_prog_type) {
	    os << "    " << "program_type = " << _program_type << ";" << endl;
	    os << "    " << "program = " << _program << ";" << endl;
	}
    }

    os << "};" << endl;
}

ErrorCode
Error::error_code(ErrorCode ec = undefined_error)
{
    if (ec == undefined_error)
	return _error_code;
    else {
	_error_code = ec;
	return _error_code;
    }
}

String
Error::error_message(String msg = "")
{
    if (msg == "")
	return String(_error_message);
    else {
	_error_message = msg;
	return String (_error_message);
    }
}

// Check the DISPLAY environment variable, if defined, use X11. If not use
// stderr.
void
Error::display_message(Gui *gui)
{
    if (gui->show_gui()) {
	String cmd = (String)"dialog " + _error_message + "\r";
	(void)gui->command(cmd);
    }
    else
	cerr << _error_message << endl;
}

ProgramType
Error::program_type(ProgramType pt = undefined_prog_type)
{
    if (pt == undefined_prog_type)
	return _program_type;
    else {
	_program_type = pt;
	return _program_type;
    }
}

char *
Error::program(char *pgm = 0)
{
    if (pgm == 0)
	return _program;
    else {
	_program = new char[strlen(pgm) + 1];
	strcpy(_program, pgm);
	return _program;
    }
}

String
Error::correct_error(Gui *gui)
{
    if (OK())
	display_message(gui);

    return String("");
}
<commit_msg>Switched to the parser_arg object for passing parameters to/from the Error.y parser. NB: if an error object is bad a message is sent to stderr to avoid going round and round with bad error objects! Changed the interface to display_message; Gui is by default NULL so that calling it with an empty parameter list causes the message string to be sent to stderr. Changed the interface to correct_error(); it now returns a string which is the corrected error or "".<commit_after>
// (c) COPYRIGHT URI/MIT 1994-1996
// Please read the full copyright statement in the file COPYRIGH.
//
// Authors:
//      jhrg,jimg       James Gallagher (jgallagher@gso.uri.edu)

// Implementation for the Error class.

// $Log: Error.cc,v $
// Revision 1.6  1996/08/13 18:14:28  jimg
// Switched to the parser_arg object for passing parameters to/from the Error.y
// parser. NB: if an error object is bad a message is sent to stderr to avoid
// going round and round with bad error objects!
// Changed the interface to display_message; Gui is by default NULL so that
// calling it with an empty parameter list causes the message string to be sent
// to stderr.
// Changed the interface to correct_error(); it now returns a string which is
// the corrected error or "".
//
// Revision 1.5  1996/06/22 00:02:46  jimg
// Added Gui pointer to the Error oject's correct_error() and
// display_message() mfuncs. These mfuncs now used the GUI to display
// messages.
//
// Revision 1.4  1996/06/04 21:33:22  jimg
// Multiple connections are now possible. It is now possible to open several
// URLs at the same time and read from them in a round-robin fashion. To do
// this I added data source and sink parameters to the serialize and
// deserialize mfuncs. Connect was also modified so that it manages the data
// source `object' (which is just an XDR pointer).
//
// Revision 1.3  1996/06/03 06:26:51  jimg
// Added declarations for Errorparse() and Errorrestart().
//
// Revision 1.2  1996/06/01 00:03:38  jimg
// Added.
//

#ifdef __GNUG__
#pragma implementation
#endif

#include "config_dap.h"

static char rcsid[] __unused__ = {"$Id: Error.cc,v 1.6 1996/08/13 18:14:28 jimg Exp $"};

#include <stdio.h>
#include <assert.h>

#include "Error.h"
#include "parser.h"

void Errorrestart(FILE *yyin);	// defined in Error.tab.c
int Errorparse(void *arg);

Error::Error()
    : _error_code(undefined_error), _error_message(""),
      _program_type(undefined_prog_type), _program(0)
{
}

Error::Error(ErrorCode ec, String msg)
    : _error_code(ec), _error_message(msg),
      _program_type(undefined_prog_type), _program(0)
{
}

Error::Error(ErrorCode ec, String msg, ProgramType pt, char *pgm)
    : _error_code(ec), _error_message(msg),
      _program_type(pt), _program(0)
{
    _program = new char[strlen(pgm) + 1];
    strcpy(_program, pgm);
}

Error::Error(const Error &copy_from)
    : _error_code(copy_from._error_code),
      _error_message(copy_from._error_message),
      _program_type(copy_from._program_type), _program(0)
{
    _program = new char[strlen(copy_from._program) + 1];
    strcpy(_program, copy_from._program);
}

Error::~Error()
{
    delete _program;
}

Error &
Error::operator=(const Error &rhs)
{
    if (&rhs == this)		// are they identical?
	return *this;
    else {
	_error_code = rhs._error_code;
	_error_message = rhs._error_message;
	_program_type = rhs._program_type;

	_program = new char[strlen(rhs._program) + 1];
	strcpy(_program, rhs._program);

	return *this;
    }
}

// To be a valid, an Error object must either be: 1) empty, 2) contain a
// message and a program or 3) contain only a message. Since the program is
// optional, there is no need to test for it here.
//
// NB: This mfunc does not test for malformed messages or programs - ones
// where the code is defined but not the `data'.

bool
Error::OK()
{
    bool empty = ((_error_code == undefined_error)
		  && (_error_message == "")
		  && (_program_type == undefined_prog_type)
		  && (_program == 0));

    bool message = ((_error_code != undefined_error)
		    && (_error_message != ""));

    // bool program = ((_program_type != undefined_prog_type)
    //                 && (_program != 0))

    return empty || message;
}

bool
Error::parse(FILE *fp)
{
    if (!fp) {
	cerr << "Error::parse: Null input stream" << endl;
	return false;
    }

    Errorrestart(fp);

    parser_arg arg(this);

    bool status = Errorparse((void *)&arg) == 0;

    fclose(fp);

    //  STATUS is the result of the parser function; if a recoverable error
    //  was found it will be true but arg.status() will be false.
    if (!status || !arg.status()) {// Check parse result
	cerr << "Error parsing error object!" << endl;
	return false;
    }
    else
	return OK();		// Check object consistancy
}

void
Error::print(ostream &os = cout)
{
    if (!OK()) {
	cerr << "Bad Error object" << endl;
	return;
    }

    os << "Error {" << endl;

    if (_error_code != undefined_error) {
	os << "    " << "code = " << _error_code << ";" << endl;
	os << "    " << "message = " << _error_message << ";" << endl;

	if (_program_type != undefined_prog_type) {
	    os << "    " << "program_type = " << _program_type << ";" << endl;
	    os << "    " << "program = " << _program << ";" << endl;
	}
    }

    os << "};" << endl;
}

ErrorCode
Error::error_code(ErrorCode ec = undefined_error)
{
    if (ec == undefined_error)
	return _error_code;
    else {
	_error_code = ec;
	return _error_code;
    }
}

String
Error::error_message(String msg = "")
{
    if (msg == "")
	return String(_error_message);
    else {
	_error_message = msg;
	return String (_error_message);
    }
}

void
Error::display_message(Gui *gui = 0)
{
    if (gui && gui->show_gui()) {
	String cmd = (String)"dialog " + _error_message + "\r";
	gui->command(cmd);
    }
    else
	cerr << _error_message << endl;
}

ProgramType
Error::program_type(ProgramType pt = undefined_prog_type)
{
    if (pt == undefined_prog_type)
	return _program_type;
    else {
	_program_type = pt;
	return _program_type;
    }
}

char *
Error::program(char *pgm = 0)
{
    if (pgm == 0)
	return _program;
    else {
	_program = new char[strlen(pgm) + 1];
	strcpy(_program, pgm);
	return _program;
    }
}

// Assuming the object is OK, if the Error object has only a meesage, dispay
// it in a dialog box. Once the user dismisses the dialog, return the null
// string. However, if program() is true, then source the code it returns in
// the Gui object and return the value of Gui::command(). Note that this
// means that the code in the program must run itself (i.e., in addition to
// any procedure definitions, etc. it must also contain the necessary
// instructions to popup an initial window).

String
Error::correct_error(Gui *gui)
{
    if (!OK())
	return String("");

    if (program()) {
	String result;

	if (gui->response(program(), result))
	    return result;
	else
	    return String("");
    }
    else {
	display_message(gui);
	return String("");
    }
}
<|endoftext|>


<commit_before>/*
 * HTTP server implementation.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "Internal.hxx"
#include "Request.hxx"
#include "http_headers.hxx"
#include "http_upgrade.hxx"
#include "direct.hxx"
#include "header_writer.hxx"
#include "format.h"
#include "date.h"
#include "growing_buffer.hxx"
#include "istream_gb.hxx"
#include "istream/istream_cat.hxx"
#include "istream/istream_chunked.hxx"
#include "istream/istream_dechunk.hxx"
#include "istream/istream_memory.hxx"
#include "istream/istream_string.hxx"

#include <string.h>

bool
http_server_connection::MaybeSend100Continue()
{
    assert(IsValid());
    assert(request.read_state == Request::BODY);

    if (!request.expect_100_continue)
        return true;

    assert(response.istream == nullptr);

    request.expect_100_continue = false;

    /* this string is simple enough to expect that we don't need to
       check for partial writes, not before we have sent a single byte
       of response to the peer */
    static const char *const response = "HTTP/1.1 100 Continue\r\n\r\n";
    const size_t length = strlen(response);
    ssize_t nbytes = socket.Write(response, length);
    if (gcc_likely(nbytes == (ssize_t)length))
        return true;

    if (nbytes == WRITE_ERRNO)
        ErrorErrno("write error");
    else if (nbytes != WRITE_DESTROYED)
        Error("write error");
    return false;
}

static size_t
format_status_line(char *p, http_status_t status)
{
    assert(http_status_is_valid(status));

    const char *status_string = http_status_to_string(status);
    assert(status_string != nullptr);
    size_t length = strlen(status_string);

    memcpy(p, "HTTP/1.1 ", 9);
    memcpy(p + 9, status_string, length);
    length += 9;
    p[length++] = '\r';
    p[length++] = '\n';

    return length;
}

void
http_server_response(const struct http_server_request *request,
                     http_status_t status,
                     HttpHeaders &&headers,
                     struct istream *body)
{
    struct http_server_connection *connection = request->connection;

    assert(connection->score != HTTP_SERVER_NEW);
    assert(connection->request.request == request);
    assert(connection->socket.IsConnected());

    connection->request.async_ref.Poison();

    if (http_status_is_success(status)) {
        if (connection->score == HTTP_SERVER_FIRST)
            connection->score = HTTP_SERVER_SUCCESS;
    } else {
        connection->score = HTTP_SERVER_ERROR;
    }

    if (connection->request.read_state == http_server_connection::Request::BODY &&
        /* if we didn't send "100 Continue" yet, we should do it now;
           we don't know if the request body will be used, but at
           least it hasn't been closed yet */
        !connection->MaybeSend100Continue())
        return;

    connection->response.status = status;
    struct istream *status_stream
        = istream_memory_new(request->pool,
                             connection->response.status_buffer,
                             format_status_line(connection->response.status_buffer,
                                                status));

    GrowingBuffer &headers2 = headers.MakeBuffer(*request->pool, 256);

    /* how will we transfer the body?  determine length and
       transfer-encoding */

    const off_t content_length = body == nullptr
        ? 0 : istream_available(body, false);
    if (content_length == (off_t)-1) {
        /* the response length is unknown yet */
        assert(!http_status_is_empty(status));

        if (!http_method_is_empty(request->method) && connection->keep_alive) {
            /* keep-alive is enabled, which means that we have to
               enable chunking */
            header_write(&headers2, "transfer-encoding", "chunked");

            /* optimized code path: if an istream_dechunked shall get
               chunked via istream_chunk, let's just skip both to
               reduce the amount of work and I/O we have to do */
            if (!istream_dechunk_check_verbatim(body))
                body = istream_chunked_new(request->pool, body);
        }
    } else if (http_status_is_empty(status)) {
        assert(content_length == 0);
    } else if (body != nullptr || !http_method_is_empty(request->method)) {
        /* fixed body size */
        format_uint64(connection->response.content_length_buffer, content_length);
        header_write(&headers2, "content-length",
                     connection->response.content_length_buffer);
    }

    if (http_method_is_empty(request->method) && body != nullptr)
        istream_free_unused(&body);

    const bool upgrade = body != nullptr && http_is_upgrade(status, headers);
    if (upgrade) {
        headers.Write(*request->pool, "connection", "upgrade");
        headers.MoveToBuffer(*request->pool, "upgrade");
    } else if (!connection->keep_alive && !connection->request.http_1_0)
        header_write(&headers2, "connection", "close");

    GrowingBuffer &headers3 = headers.ToBuffer(*request->pool);
    growing_buffer_write_buffer(&headers3, "\r\n", 2);
    struct istream *header_stream = istream_gb_new(request->pool, &headers3);

    connection->response.length = - istream_available(status_stream, false)
        - istream_available(header_stream, false);

    body = istream_cat_new(request->pool, status_stream,
                           header_stream, body, nullptr);

    connection->response.istream = body;
    istream_handler_set(connection->response.istream,
                        &http_server_response_stream_handler, connection,
                        connection->socket.GetDirectMask());

    connection->socket.SetCork(true);
    if (connection->TryWrite())
        connection->socket.SetCork(false);
}

void
http_server_send_message(const struct http_server_request *request,
                         http_status_t status, const char *msg)
{
    HttpHeaders headers;
    GrowingBuffer &headers2 = headers.MakeBuffer(*request->pool, 256);

    header_write(&headers2, "content-type", "text/plain");

#ifndef NO_DATE_HEADER
    header_write(&headers2, "date", http_date_format(time(nullptr)));
#endif

    http_server_response(request, status, std::move(headers),
                         istream_string_new(request->pool, msg));
}

void
http_server_send_redirect(const struct http_server_request *request,
                          http_status_t status, const char *location,
                          const char *msg)
{
    assert(request != nullptr);
    assert(status >= 300 && status < 400);
    assert(location != nullptr);

    if (msg == nullptr)
        msg = "redirection";

    HttpHeaders headers;
    GrowingBuffer &headers2 = headers.MakeBuffer(*request->pool, 1024);

    header_write(&headers2, "content-type", "text/plain");
    header_write(&headers2, "location", location);

#ifndef NO_DATE_HEADER
    header_write(&headers2, "date", http_date_format(time(nullptr)));
#endif

    http_server_response(request, status, std::move(headers),
                         istream_string_new(request->pool, msg));
}
<commit_msg>http_server: fix shadow warning<commit_after>/*
 * HTTP server implementation.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "Internal.hxx"
#include "Request.hxx"
#include "http_headers.hxx"
#include "http_upgrade.hxx"
#include "direct.hxx"
#include "header_writer.hxx"
#include "format.h"
#include "date.h"
#include "growing_buffer.hxx"
#include "istream_gb.hxx"
#include "istream/istream_cat.hxx"
#include "istream/istream_chunked.hxx"
#include "istream/istream_dechunk.hxx"
#include "istream/istream_memory.hxx"
#include "istream/istream_string.hxx"

#include <string.h>

bool
http_server_connection::MaybeSend100Continue()
{
    assert(IsValid());
    assert(request.read_state == Request::BODY);

    if (!request.expect_100_continue)
        return true;

    assert(response.istream == nullptr);

    request.expect_100_continue = false;

    /* this string is simple enough to expect that we don't need to
       check for partial writes, not before we have sent a single byte
       of response to the peer */
    static const char *const response_string = "HTTP/1.1 100 Continue\r\n\r\n";
    const size_t length = strlen(response_string);
    ssize_t nbytes = socket.Write(response_string, length);
    if (gcc_likely(nbytes == (ssize_t)length))
        return true;

    if (nbytes == WRITE_ERRNO)
        ErrorErrno("write error");
    else if (nbytes != WRITE_DESTROYED)
        Error("write error");
    return false;
}

static size_t
format_status_line(char *p, http_status_t status)
{
    assert(http_status_is_valid(status));

    const char *status_string = http_status_to_string(status);
    assert(status_string != nullptr);
    size_t length = strlen(status_string);

    memcpy(p, "HTTP/1.1 ", 9);
    memcpy(p + 9, status_string, length);
    length += 9;
    p[length++] = '\r';
    p[length++] = '\n';

    return length;
}

void
http_server_response(const struct http_server_request *request,
                     http_status_t status,
                     HttpHeaders &&headers,
                     struct istream *body)
{
    struct http_server_connection *connection = request->connection;

    assert(connection->score != HTTP_SERVER_NEW);
    assert(connection->request.request == request);
    assert(connection->socket.IsConnected());

    connection->request.async_ref.Poison();

    if (http_status_is_success(status)) {
        if (connection->score == HTTP_SERVER_FIRST)
            connection->score = HTTP_SERVER_SUCCESS;
    } else {
        connection->score = HTTP_SERVER_ERROR;
    }

    if (connection->request.read_state == http_server_connection::Request::BODY &&
        /* if we didn't send "100 Continue" yet, we should do it now;
           we don't know if the request body will be used, but at
           least it hasn't been closed yet */
        !connection->MaybeSend100Continue())
        return;

    connection->response.status = status;
    struct istream *status_stream
        = istream_memory_new(request->pool,
                             connection->response.status_buffer,
                             format_status_line(connection->response.status_buffer,
                                                status));

    GrowingBuffer &headers2 = headers.MakeBuffer(*request->pool, 256);

    /* how will we transfer the body?  determine length and
       transfer-encoding */

    const off_t content_length = body == nullptr
        ? 0 : istream_available(body, false);
    if (content_length == (off_t)-1) {
        /* the response length is unknown yet */
        assert(!http_status_is_empty(status));

        if (!http_method_is_empty(request->method) && connection->keep_alive) {
            /* keep-alive is enabled, which means that we have to
               enable chunking */
            header_write(&headers2, "transfer-encoding", "chunked");

            /* optimized code path: if an istream_dechunked shall get
               chunked via istream_chunk, let's just skip both to
               reduce the amount of work and I/O we have to do */
            if (!istream_dechunk_check_verbatim(body))
                body = istream_chunked_new(request->pool, body);
        }
    } else if (http_status_is_empty(status)) {
        assert(content_length == 0);
    } else if (body != nullptr || !http_method_is_empty(request->method)) {
        /* fixed body size */
        format_uint64(connection->response.content_length_buffer, content_length);
        header_write(&headers2, "content-length",
                     connection->response.content_length_buffer);
    }

    if (http_method_is_empty(request->method) && body != nullptr)
        istream_free_unused(&body);

    const bool upgrade = body != nullptr && http_is_upgrade(status, headers);
    if (upgrade) {
        headers.Write(*request->pool, "connection", "upgrade");
        headers.MoveToBuffer(*request->pool, "upgrade");
    } else if (!connection->keep_alive && !connection->request.http_1_0)
        header_write(&headers2, "connection", "close");

    GrowingBuffer &headers3 = headers.ToBuffer(*request->pool);
    growing_buffer_write_buffer(&headers3, "\r\n", 2);
    struct istream *header_stream = istream_gb_new(request->pool, &headers3);

    connection->response.length = - istream_available(status_stream, false)
        - istream_available(header_stream, false);

    body = istream_cat_new(request->pool, status_stream,
                           header_stream, body, nullptr);

    connection->response.istream = body;
    istream_handler_set(connection->response.istream,
                        &http_server_response_stream_handler, connection,
                        connection->socket.GetDirectMask());

    connection->socket.SetCork(true);
    if (connection->TryWrite())
        connection->socket.SetCork(false);
}

void
http_server_send_message(const struct http_server_request *request,
                         http_status_t status, const char *msg)
{
    HttpHeaders headers;
    GrowingBuffer &headers2 = headers.MakeBuffer(*request->pool, 256);

    header_write(&headers2, "content-type", "text/plain");

#ifndef NO_DATE_HEADER
    header_write(&headers2, "date", http_date_format(time(nullptr)));
#endif

    http_server_response(request, status, std::move(headers),
                         istream_string_new(request->pool, msg));
}

void
http_server_send_redirect(const struct http_server_request *request,
                          http_status_t status, const char *location,
                          const char *msg)
{
    assert(request != nullptr);
    assert(status >= 300 && status < 400);
    assert(location != nullptr);

    if (msg == nullptr)
        msg = "redirection";

    HttpHeaders headers;
    GrowingBuffer &headers2 = headers.MakeBuffer(*request->pool, 1024);

    header_write(&headers2, "content-type", "text/plain");
    header_write(&headers2, "location", location);

#ifndef NO_DATE_HEADER
    header_write(&headers2, "date", http_date_format(time(nullptr)));
#endif

    http_server_response(request, status, std::move(headers),
                         istream_string_new(request->pool, msg));
}
<|endoftext|>


<commit_before>#include "Game.h"
#include "TextureManager.h"
#include "Player.h"
#include "Enemy.h"
#include "InputHandler.h"
#include "MenuState.h"
#include "PlayState.h"

//definition for static instance
Game* Game::s_pInstance = 0;

bool Game::init(const char *title, int xpos, int ypos, int width, int height, bool fullscreen)
{
	int flags = 0;
	if (fullscreen)
	{
		flags = SDL_WINDOW_FULLSCREEN;
	}

	//attempt to initialize SDL
	if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
	{
		std::cout << "SDL init success\n";
		//init the window
		m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);

		if (m_pWindow != 0)	//window init success
		{
			std::cout << "Window creation success\n";
			m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);

			if (m_pRenderer != 0) //renderer init success
			{
				std::cout << "renderer init success\n";
				SDL_SetRenderDrawColor(m_pRenderer, 255, 0, 0, 255);
			}
			else
			{
				std::cout << "renderer init failed\n";
				return false;	//renderer init fail
			}
		}
		else
		{
			std::cout << "window init fail\n";
			return false;	//window init fail
		}
	}
	else
	{
		std::cout << "SDL init fail\n";
		return false;	//SDL init fail
	}

	//initialise joysticks
	TheInputHandler::Instance()->initialiseJoysticks();

	std::cout << "init success\n";

	//load TextureManager
	if (!TheTextureManager::Instance()->load("assets/animate-alpha.png", "animate", m_pRenderer))
	{
		return false;
	}

	//creating and pushing objects
	m_gameObjects.push_back(new Player(new LoaderParams(100, 100, 128, 82, "animate")));
	m_gameObjects.push_back(new Enemy(new LoaderParams(300, 300, 128, 82, "animate")));

	m_bRunning = true;	//everything inited successfully, start the main loop

	//load MENU state
	m_pGameStateMachine = new GameStateMachine();
	m_pGameStateMachine->changeState(new MenuState());

	return true;
}

bool Game::running()
{
	return m_bRunning;
}

GameStateMachine* Game::getStateMachine()
{
	return m_pGameStateMachine;
}

void Game::handleEvents()
{
	//waits and listens for a quit event
	TheInputHandler::Instance()->update();

	if (TheInputHandler::Instance()->isKeyDown(SDL_SCANCODE_RETURN))
	{
		m_pGameStateMachine->changeState(new PlayState());
	}
}

void Game::update()
{
	//use GameStateMachine's update function
	m_pGameStateMachine->update();
}

void Game::render()
{
	SDL_RenderClear(m_pRenderer); //clear the renderer to the draw color

	//use GameStateMachine's render function
	m_pGameStateMachine->render();

	SDL_RenderPresent(m_pRenderer);	//draw to the screen
}

void Game::clean()
{
	std::cout << "cleaning game\n";

	//close the joysticks
	TheInputHandler::Instance()->clean();

	SDL_DestroyWindow(m_pWindow);
	SDL_DestroyRenderer(m_pRenderer);
	SDL_Quit();
}

void Game::quit()
{
	m_bRunning = false;
}<commit_msg>Frame value is set to 6 for Enemy and Player in Game.cpp<commit_after>#include "Game.h"
#include "TextureManager.h"
#include "Player.h"
#include "Enemy.h"
#include "InputHandler.h"
#include "MenuState.h"
#include "PlayState.h"

//definition for static instance
Game* Game::s_pInstance = 0;

bool Game::init(const char *title, int xpos, int ypos, int width, int height, bool fullscreen)
{
	int flags = 0;
	if (fullscreen)
	{
		flags = SDL_WINDOW_FULLSCREEN;
	}

	//attempt to initialize SDL
	if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
	{
		std::cout << "SDL init success\n";
		//init the window
		m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);

		if (m_pWindow != 0)	//window init success
		{
			std::cout << "Window creation success\n";
			m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);

			if (m_pRenderer != 0) //renderer init success
			{
				std::cout << "renderer init success\n";
				SDL_SetRenderDrawColor(m_pRenderer, 255, 0, 0, 255);
			}
			else
			{
				std::cout << "renderer init failed\n";
				return false;	//renderer init fail
			}
		}
		else
		{
			std::cout << "window init fail\n";
			return false;	//window init fail
		}
	}
	else
	{
		std::cout << "SDL init fail\n";
		return false;	//SDL init fail
	}

	//initialise joysticks
	TheInputHandler::Instance()->initialiseJoysticks();

	std::cout << "init success\n";

	//load TextureManager
	if (!TheTextureManager::Instance()->load("assets/animate-alpha.png", "animate", m_pRenderer))
	{
		return false;
	}

	//creating and pushing objects
	m_gameObjects.push_back(new Player(new LoaderParams(100, 100, 128, 82, 6, "animate")));
	m_gameObjects.push_back(new Enemy(new LoaderParams(300, 300, 128, 82, 6, "animate")));

	m_bRunning = true;	//everything inited successfully, start the main loop

	//load MENU state
	m_pGameStateMachine = new GameStateMachine();
	m_pGameStateMachine->changeState(new MenuState());

	return true;
}

bool Game::running()
{
	return m_bRunning;
}

GameStateMachine* Game::getStateMachine()
{
	return m_pGameStateMachine;
}

void Game::handleEvents()
{
	//waits and listens for a quit event
	TheInputHandler::Instance()->update();

	if (TheInputHandler::Instance()->isKeyDown(SDL_SCANCODE_RETURN))
	{
		m_pGameStateMachine->changeState(new PlayState());
	}
}

void Game::update()
{
	//use GameStateMachine's update function
	m_pGameStateMachine->update();
}

void Game::render()
{
	SDL_RenderClear(m_pRenderer); //clear the renderer to the draw color

	//use GameStateMachine's render function
	m_pGameStateMachine->render();

	SDL_RenderPresent(m_pRenderer);	//draw to the screen
}

void Game::clean()
{
	std::cout << "cleaning game\n";

	//close the joysticks
	TheInputHandler::Instance()->clean();

	SDL_DestroyWindow(m_pWindow);
	SDL_DestroyRenderer(m_pRenderer);
	SDL_Quit();
}

void Game::quit()
{
	m_bRunning = false;
}<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////
//
// Game Base
// Copyright (C) 2012 Chase Warrington (staff@spacechase0.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////

#include "Game.h"

#include <iostream>

#include "Scene.h"
#include "scenes/GameScene.h"

const int Game::UPDATE_RATE = 50;
const int Game::RENDER_RATE = 50;

Game::Game()
   : isRunning( false )
{
}

void Game::run()
{
	initialize();

	const float DELTA = 1.f / UPDATE_RATE;
	float updateBuffer = 0.f; // Can't think of a good name. :P
	sf::Clock updateTimer;

	isRunning = true;
	while ( isRunning )
	{
	    Debug::draw(window);

		std::shared_ptr< Scene > scene;
		if ( currentScene != nextScene )
		{
			if ( currentScene != "" )
			{
				scenes[ currentScene ]->terminate();
			}

			scene = scenes[ nextScene ];
			scene->initialize( changeEvent );

			currentScene = nextScene;
		}
		else if ( currentScene != "" )
		{
			scene = scenes[ currentScene ];
		}

		while ( updateBuffer >= DELTA )
		{
			sf::Event event;
			while ( window.pollEvent( event ) )
			{
				if ( event.type == sf::Event::Closed )
				{
					close();
				}

				scene->update( event );
			}

			scene->update();

			updateBuffer -= DELTA;
		}
		updateBuffer += updateTimer.restart().asSeconds();

		window.clear();
		scene->render( window );
		window.display();
	}

	terminate();
}

void Game::close()
{
	isRunning = false;
}

void Game::changeScenes( const std::string& name, SceneChangeEvent event )
{
	nextScene = name;
	changeEvent = event;
}

std::shared_ptr< Scene > Game::getScene( const std::string& name )
{
	if ( scenes.find( name ) == scenes.end() )
	{
		std::cout << "Failed to find scene '" << name << "'." << std::endl;
		return std::shared_ptr< Scene >();
	}

	return scenes.find( name )->second;
}

void Game::initialize()
{
	window.create( sf::VideoMode( 640, 480 ), "Game Base" );
	window.setFramerateLimit( RENDER_RATE );

	addScene( "Game", std::shared_ptr< Scene >( new GameScene( * this ) ) );

	changeScenes( "Game", SceneChangeEvent() );
}

void Game::terminate()
{
}

void Game::addScene( const std::string& name, std::shared_ptr< Scene > scene )
{
	scenes.insert( std::make_pair( name, scene ) );
}
<commit_msg>Leftover stuff from the project I pulled this from. :P<commit_after>////////////////////////////////////////////////////////////
//
// Game Base
// Copyright (C) 2012 Chase Warrington (staff@spacechase0.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////

#include "Game.h"

#include <iostream>

#include "Scene.h"
#include "scenes/GameScene.h"

const int Game::UPDATE_RATE = 50;
const int Game::RENDER_RATE = 50;

Game::Game()
   : isRunning( false )
{
}

void Game::run()
{
	initialize();

	const float DELTA = 1.f / UPDATE_RATE;
	float updateBuffer = 0.f; // Can't think of a good name. :P
	sf::Clock updateTimer;

	isRunning = true;
	while ( isRunning )
	{
		std::shared_ptr< Scene > scene;
		if ( currentScene != nextScene )
		{
			if ( currentScene != "" )
			{
				scenes[ currentScene ]->terminate();
			}

			scene = scenes[ nextScene ];
			scene->initialize( changeEvent );

			currentScene = nextScene;
		}
		else if ( currentScene != "" )
		{
			scene = scenes[ currentScene ];
		}

		while ( updateBuffer >= DELTA )
		{
			sf::Event event;
			while ( window.pollEvent( event ) )
			{
				if ( event.type == sf::Event::Closed )
				{
					close();
				}

				scene->update( event );
			}

			scene->update();

			updateBuffer -= DELTA;
		}
		updateBuffer += updateTimer.restart().asSeconds();

		window.clear();
		scene->render( window );
		window.display();
	}

	terminate();
}

void Game::close()
{
	isRunning = false;
}

void Game::changeScenes( const std::string& name, SceneChangeEvent event )
{
	nextScene = name;
	changeEvent = event;
}

std::shared_ptr< Scene > Game::getScene( const std::string& name )
{
	if ( scenes.find( name ) == scenes.end() )
	{
		std::cout << "Failed to find scene '" << name << "'." << std::endl;
		return std::shared_ptr< Scene >();
	}

	return scenes.find( name )->second;
}

void Game::initialize()
{
	window.create( sf::VideoMode( 640, 480 ), "Game Base" );
	window.setFramerateLimit( RENDER_RATE );

	addScene( "Game", std::shared_ptr< Scene >( new GameScene( * this ) ) );

	changeScenes( "Game", SceneChangeEvent() );
}

void Game::terminate()
{
}

void Game::addScene( const std::string& name, std::shared_ptr< Scene > scene )
{
	scenes.insert( std::make_pair( name, scene ) );
}
<|endoftext|>


<commit_before>/*******************************************************************************
*     ALMA - Atacama Large Millimiter Array
*    (c) European Southern Observatory, 2002
*    Copyright by ESO (in the framework of the ALMA collaboration)
*    and Cosylab 2002, All rights reserved
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation; either
*    version 2.1 of the License, or (at your option) any later version.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: basencSupplier.cpp,v 1.5 2006/05/25 16:53:58 dfugate Exp $"
*
* who       when        what
* --------  ---------   ----------------------------------------------
*/

#include "basencSupplier.h"
#include <iostream>

//-----------------------------------------------------------------------------
BaseSupplier::BaseSupplier(const char* channelName) :
    BaseHelper(channelName)
{
    //no-op
}
//-----------------------------------------------------------------------------
void
BaseSupplier::init(CosNaming::NamingContext_ptr nc_p)
{
    //delegate to common helper class
    BaseHelper::init(nc_p);

    //get the supplier admin
    supplierAdmin_m = notifyChannel_m->new_for_suppliers(ifgop_m, adminID_m);
    ACE_ASSERT (!CORBA::is_nil(supplierAdmin_m.in()));

    //connect the supplier admin which really means connect
    //ourselves to the proxy consumer
    this->connect();

}
//-----------------------------------------------------------------------------
BaseSupplier::~BaseSupplier()
{
}
//-----------------------------------------------------------------------------
void
BaseSupplier::connect()
{
    //turn ourselves into a CORBA object
    corbaRef_m = acsnc::OSPushSupplier::_duplicate(getCORBARef());
    ACE_ASSERT(!CORBA::is_nil(corbaRef_m.in()));

    //get the proxy consumer from the supplier admin.
    CosNotifyChannelAdmin::ProxyConsumer_var proxyconsumer =
	supplierAdmin_m->obtain_notification_push_consumer(CosNotifyChannelAdmin::STRUCTURED_EVENT,
							   proxyConsumerID_m);
    ACE_ASSERT(!CORBA::is_nil(proxyconsumer.in()));

    // narrow
    proxyConsumer_m = CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow(proxyconsumer.in());
    ACE_ASSERT(!CORBA::is_nil(proxyConsumer_m.in()));

    //final piece of code connects us to the channel
    proxyConsumer_m->connect_structured_push_supplier(corbaRef_m.in());
}
//-----------------------------------------------------------------------------
void
BaseSupplier::disconnect()
{
    //take care of the proxy consumer
    ACE_ASSERT(!CORBA::is_nil(proxyConsumer_m.in()));
    //sole ownership of the proxy
    CosNotifyChannelAdmin::StructuredProxyPushConsumer_var proxyConsumer = proxyConsumer_m;
    proxyConsumer_m=CosNotifyChannelAdmin::StructuredProxyPushConsumer::_nil();
    //disconnect from the proxy consumer
    proxyConsumer->disconnect_structured_push_consumer();

    //take care of the supplier admin
    ACE_ASSERT(!CORBA::is_nil(supplierAdmin_m.in()));
    //sole ownership of the proxy
    CosNotifyChannelAdmin::SupplierAdmin_var supplierAdmin = supplierAdmin_m;
    supplierAdmin_m = CosNotifyChannelAdmin::SupplierAdmin::_nil();
    //destroy it
    supplierAdmin->destroy();

    //DWF-need some code here to remove our own CORBA servant???

    BaseHelper::disconnect();
}
//-----------------------------------------------------------------------------
void
BaseSupplier::subscription_change(const CosNotification::EventTypeSeq &a,
				  const CosNotification::EventTypeSeq &b)
    throw(CORBA::SystemException,
	  CosNotifyComm::InvalidEventType)
{
    //No-Op.
}
//-----------------------------------------------------------------------------
void
BaseSupplier::publishEvent(const CosNotification::StructuredEvent& event)
{
    ACE_ASSERT(!CORBA::is_nil(this->proxyConsumer_m.in()));
    //pass it on to the proxy consumer
    try
	{
	proxyConsumer_m->push_structured_event(event);
	}
    catch(CORBA::COMM_FAILURE ex)
	{
	std::cerr << "ERROR (CORBA::COMM_FAILURE): ";
	std::cerr << "failed to send an event of type '";
	std::cerr << event.header.fixed_header.event_type.type_name;
	std::cerr << "' to the '";
	std::cerr << channelName_mp << "' channel!" << std::endl;
	}
    catch(CORBA::TRANSIENT ex)
	{
	std::cerr << "ERROR (CORBA::TRANSIENT): ";
	std::cerr << "failed to send an event of type '";
	std::cerr << event.header.fixed_header.event_type.type_name;
	std::cerr << "' to the '";
	std::cerr << channelName_mp << "' channel!" << std::endl;
	}
    catch(...)
	{
	std::cerr << "ERROR (Unkwown): ";
	std::cerr << "failed to send an event of type '";
	std::cerr << event.header.fixed_header.event_type.type_name;
	std::cerr << "' to the '";
	std::cerr << channelName_mp << "' channel!" << std::endl;
	}
}
//-----------------------------------------------------------------------------
void
BaseSupplier::disconnect_structured_push_supplier()
    throw(CORBA::SystemException)
{
    // No-Op.
}
//-----------------------------------------------------------------------------
acsnc::OSPushSupplier_ptr
BaseSupplier::getCORBARef()
{
    acsnc::OSPushSupplier_var retVal = this->_this();
    return retVal._retn();
}
//-----------------------------------------------------------------------------
void
BaseSupplier::populateHeader(CosNotification::StructuredEvent& event)
{
    //just delegate this to other functions
    event.header.fixed_header.event_type.domain_name = CORBA::string_dup(getChannelDomain());
    event.header.fixed_header.event_type.type_name   = CORBA::string_dup(getEventType());
    event.header.fixed_header.event_name             = CORBA::string_dup(getEventName());

    //no reason to put anything in the variable header.
    event.header.variable_header.length(0);
}

<commit_msg>put deactivation of corba object in the dicvonnect method<commit_after>/*******************************************************************************
*     ALMA - Atacama Large Millimiter Array
*    (c) European Southern Observatory, 2002
*    Copyright by ESO (in the framework of the ALMA collaboration)
*    and Cosylab 2002, All rights reserved
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation; either
*    version 2.1 of the License, or (at your option) any later version.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: basencSupplier.cpp,v 1.6 2006/10/24 15:30:18 bjeram Exp $"
*
* who       when        what
* --------  ---------   ----------------------------------------------
*/

#include "basencSupplier.h"
#include <iostream>

//-----------------------------------------------------------------------------
BaseSupplier::BaseSupplier(const char* channelName) :
    BaseHelper(channelName)
{
    //no-op
}
//-----------------------------------------------------------------------------
void
BaseSupplier::init(CosNaming::NamingContext_ptr nc_p)
{
    //delegate to common helper class
    BaseHelper::init(nc_p);

    //get the supplier admin
    supplierAdmin_m = notifyChannel_m->new_for_suppliers(ifgop_m, adminID_m);
    ACE_ASSERT (!CORBA::is_nil(supplierAdmin_m.in()));

    //connect the supplier admin which really means connect
    //ourselves to the proxy consumer
    this->connect();

}
//-----------------------------------------------------------------------------
BaseSupplier::~BaseSupplier()
{
}
//-----------------------------------------------------------------------------
void
BaseSupplier::connect()
{
    //turn ourselves into a CORBA object
    corbaRef_m = acsnc::OSPushSupplier::_duplicate(getCORBARef());
    ACE_ASSERT(!CORBA::is_nil(corbaRef_m.in()));

    //get the proxy consumer from the supplier admin.
    CosNotifyChannelAdmin::ProxyConsumer_var proxyconsumer =
	supplierAdmin_m->obtain_notification_push_consumer(CosNotifyChannelAdmin::STRUCTURED_EVENT,
							   proxyConsumerID_m);
    ACE_ASSERT(!CORBA::is_nil(proxyconsumer.in()));

    // narrow
    proxyConsumer_m = CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow(proxyconsumer.in());
    ACE_ASSERT(!CORBA::is_nil(proxyConsumer_m.in()));

    //final piece of code connects us to the channel
    proxyConsumer_m->connect_structured_push_supplier(corbaRef_m.in());
}
//-----------------------------------------------------------------------------
void
BaseSupplier::disconnect()
{
    //take care of the proxy consumer
    ACE_ASSERT(!CORBA::is_nil(proxyConsumer_m.in()));
    //sole ownership of the proxy
    CosNotifyChannelAdmin::StructuredProxyPushConsumer_var proxyConsumer = proxyConsumer_m;
    proxyConsumer_m=CosNotifyChannelAdmin::StructuredProxyPushConsumer::_nil();
    //disconnect from the proxy consumer
    proxyConsumer->disconnect_structured_push_consumer();

    //take care of the supplier admin
    ACE_ASSERT(!CORBA::is_nil(supplierAdmin_m.in()));
    //sole ownership of the proxy
    CosNotifyChannelAdmin::SupplierAdmin_var supplierAdmin = supplierAdmin_m;
    supplierAdmin_m = CosNotifyChannelAdmin::SupplierAdmin::_nil();
    //destroy it
    supplierAdmin->destroy();

    //DWF-need some code here to remove our own CORBA servant???
    this->_default_POA()->deactivate_object(*(this->_default_POA()->servant_to_id(this)));

    BaseHelper::disconnect();
}
//-----------------------------------------------------------------------------
void
BaseSupplier::subscription_change(const CosNotification::EventTypeSeq &a,
				  const CosNotification::EventTypeSeq &b)
    throw(CORBA::SystemException,
	  CosNotifyComm::InvalidEventType)
{
    //No-Op.
}
//-----------------------------------------------------------------------------
void
BaseSupplier::publishEvent(const CosNotification::StructuredEvent& event)
{
    ACE_ASSERT(!CORBA::is_nil(this->proxyConsumer_m.in()));
    //pass it on to the proxy consumer
    try
	{
	proxyConsumer_m->push_structured_event(event);
	}
    catch(CORBA::COMM_FAILURE ex)
	{
	std::cerr << "ERROR (CORBA::COMM_FAILURE): ";
	std::cerr << "failed to send an event of type '";
	std::cerr << event.header.fixed_header.event_type.type_name;
	std::cerr << "' to the '";
	std::cerr << channelName_mp << "' channel!" << std::endl;
	}
    catch(CORBA::TRANSIENT ex)
	{
	std::cerr << "ERROR (CORBA::TRANSIENT): ";
	std::cerr << "failed to send an event of type '";
	std::cerr << event.header.fixed_header.event_type.type_name;
	std::cerr << "' to the '";
	std::cerr << channelName_mp << "' channel!" << std::endl;
	}
    catch(...)
	{
	std::cerr << "ERROR (Unkwown): ";
	std::cerr << "failed to send an event of type '";
	std::cerr << event.header.fixed_header.event_type.type_name;
	std::cerr << "' to the '";
	std::cerr << channelName_mp << "' channel!" << std::endl;
	}
}
//-----------------------------------------------------------------------------
void
BaseSupplier::disconnect_structured_push_supplier()
    throw(CORBA::SystemException)
{
    // No-Op.
}
//-----------------------------------------------------------------------------
acsnc::OSPushSupplier_ptr
BaseSupplier::getCORBARef()
{
    acsnc::OSPushSupplier_var retVal = this->_this();
    return retVal._retn();
}
//-----------------------------------------------------------------------------
void
BaseSupplier::populateHeader(CosNotification::StructuredEvent& event)
{
    //just delegate this to other functions
    event.header.fixed_header.event_type.domain_name = CORBA::string_dup(getChannelDomain());
    event.header.fixed_header.event_type.type_name   = CORBA::string_dup(getEventType());
    event.header.fixed_header.event_name             = CORBA::string_dup(getEventName());

    //no reason to put anything in the variable header.
    event.header.variable_header.length(0);
}

<|endoftext|>