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

#include "SkBenchLogger.h"
#include "BenchTimer.h"
#include "PictureBenchmark.h"
#include "SkCanvas.h"
#include "SkPicture.h"
#include "SkString.h"
#include "picture_utils.h"

namespace sk_tools {

PictureBenchmark::PictureBenchmark()
: fRepeats(1)
, fLogger(NULL)
, fRenderer(NULL)
, fTimerResult(TimerData::kAvg_Result)
, fTimerTypes(0)
, fTimeIndividualTiles(false)
{}

PictureBenchmark::~PictureBenchmark() {
    SkSafeUnref(fRenderer);
}

void PictureBenchmark::setTimersToShow(bool wall,
                                       bool truncatedWall,
                                       bool cpu,
                                       bool truncatedCpu,
                                       bool gpu) {
    fTimerTypes = 0;
    fTimerTypes |= wall ? TimerData::kWall_Flag : 0;
    fTimerTypes |= truncatedWall ? TimerData::kTruncatedWall_Flag : 0;
    fTimerTypes |= cpu ? TimerData::kCpu_Flag : 0;
    fTimerTypes |= truncatedCpu ? TimerData::kTruncatedCpu_Flag : 0;
    fTimerTypes |= gpu ? TimerData::kGpu_Flag : 0;
}

BenchTimer* PictureBenchmark::setupTimer(bool useGLTimer) {
#if SK_SUPPORT_GPU
    if (useGLTimer && fRenderer != NULL && fRenderer->isUsingGpuDevice()) {
        return SkNEW_ARGS(BenchTimer, (fRenderer->getGLContext()));
    }
#endif
    return SkNEW_ARGS(BenchTimer, (NULL));
}

void PictureBenchmark::logProgress(const char msg[]) {
    if (fLogger != NULL) {
        fLogger->logProgress(msg);
    }
}

PictureRenderer* PictureBenchmark::setRenderer(sk_tools::PictureRenderer* renderer) {
    SkRefCnt_SafeAssign(fRenderer, renderer);
    return renderer;
}

void PictureBenchmark::run(SkPicture* pict) {
    SkASSERT(pict);
    if (NULL == pict) {
        return;
    }

    SkASSERT(fRenderer != NULL);
    if (NULL == fRenderer) {
        return;
    }

    fRenderer->init(pict);

    // We throw this away to remove first time effects (such as paging in this program)
    fRenderer->setup();
    fRenderer->render(NULL);
    fRenderer->resetState(true);

    bool usingGpu = false;
#if SK_SUPPORT_GPU
    usingGpu = fRenderer->isUsingGpuDevice();
#endif

    uint32_t timerTypes = fTimerTypes;
    if (!usingGpu) {
        timerTypes &= ~TimerData::kGpu_Flag;
    }

    SkString timeFormat;
    if (TimerData::kPerIter_Result == fTimerResult) {
        timeFormat = fRenderer->getPerIterTimeFormat();
    } else {
        timeFormat = fRenderer->getNormalTimeFormat();
    }

    if (fTimeIndividualTiles) {
        TiledPictureRenderer* tiledRenderer = fRenderer->getTiledRenderer();
        SkASSERT(tiledRenderer && tiledRenderer->supportsTimingIndividualTiles());
        if (NULL == tiledRenderer || !tiledRenderer->supportsTimingIndividualTiles()) {
            return;
        }
        int xTiles, yTiles;
        if (!tiledRenderer->tileDimensions(xTiles, yTiles)) {
            return;
        }

        // Insert a newline so that each tile is reported on its own line (separate from the line
        // that describes the skp being run).
        this->logProgress("\n");

        int x, y;
        while (tiledRenderer->nextTile(x, y)) {
            // There are two timers, which will behave slightly differently:
            // 1) longRunningTimer, along with perTileTimerData, will time how long it takes to draw
            // one tile fRepeats times, and take the average. As such, it will not respect thea
            // logPerIter or printMin options, since it does not know the time per iteration. It
            // will also be unable to call flush() for each tile.
            // The goal of this timer is to make up for a system timer that is not precise enough to
            // measure the small amount of time it takes to draw one tile once.
            //
            // 2) perTileTimer, along with perTileTimerData, will record each run separately, and
            // then take the average. As such, it supports logPerIter and printMin options.
            //
            // Although "legal", having two gpu timers running at the same time
            // seems to cause problems (i.e., INVALID_OPERATIONs) on several
            // platforms. To work around this, we disable the gpu timer on the
            // long running timer.
            SkAutoTDelete<BenchTimer> longRunningTimer(this->setupTimer());
            TimerData longRunningTimerData(1);
            SkAutoTDelete<BenchTimer> perTileTimer(this->setupTimer(false));
            TimerData perTileTimerData(fRepeats);
            longRunningTimer->start();
            for (int i = 0; i < fRepeats; ++i) {
                perTileTimer->start();
                tiledRenderer->drawCurrentTile();
                perTileTimer->truncatedEnd();
                tiledRenderer->resetState(false);
                perTileTimer->end();
                SkAssertResult(perTileTimerData.appendTimes(perTileTimer.get()));
            }
            longRunningTimer->truncatedEnd();
            tiledRenderer->resetState(true);
            longRunningTimer->end();
            SkAssertResult(longRunningTimerData.appendTimes(longRunningTimer.get()));

            SkString configName = tiledRenderer->getConfigName();
            configName.appendf(": tile [%i,%i] out of [%i,%i]", x, y, xTiles, yTiles);

            SkString result = perTileTimerData.getResult(timeFormat.c_str(), fTimerResult,
                                                         configName.c_str(), timerTypes);
            result.append("\n");

// TODO(borenet): Turn off per-iteration tile time reporting for now.  Avoiding logging the time
// for every iteration for each tile cuts down on data file size by a significant amount. Re-enable
// this once we're loading the bench data directly into a data store and are no longer generating
// SVG graphs.
#if 0
            this->logProgress(result.c_str());
#endif

            configName.append(" <averaged>");
            SkString longRunningResult = longRunningTimerData.getResult(
                tiledRenderer->getNormalTimeFormat().c_str(),
                TimerData::kAvg_Result,
                configName.c_str(), timerTypes, fRepeats);
            longRunningResult.append("\n");
            this->logProgress(longRunningResult.c_str());
        }
    } else {
        SkAutoTDelete<BenchTimer> timer(this->setupTimer());
        TimerData timerData(fRepeats);
        for (int i = 0; i < fRepeats; ++i) {
            fRenderer->setup();

            timer->start();
            fRenderer->render(NULL);
            timer->truncatedEnd();

            // Finishes gl context
            fRenderer->resetState(true);
            timer->end();

            SkAssertResult(timerData.appendTimes(timer.get()));
        }

        SkString configName = fRenderer->getConfigName();

        SkString result = timerData.getResult(timeFormat.c_str(),
                                              fTimerResult,
                                              configName.c_str(),
                                              timerTypes);
        result.append("\n");
        this->logProgress(result.c_str());
    }

    fRenderer->end();
}

}
<commit_msg>Make bench_pictures' timing more GPU friendly<commit_after>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchLogger.h"
#include "BenchTimer.h"
#include "PictureBenchmark.h"
#include "SkCanvas.h"
#include "SkPicture.h"
#include "SkString.h"
#include "picture_utils.h"

namespace sk_tools {

PictureBenchmark::PictureBenchmark()
: fRepeats(1)
, fLogger(NULL)
, fRenderer(NULL)
, fTimerResult(TimerData::kAvg_Result)
, fTimerTypes(0)
, fTimeIndividualTiles(false)
{}

PictureBenchmark::~PictureBenchmark() {
    SkSafeUnref(fRenderer);
}

void PictureBenchmark::setTimersToShow(bool wall,
                                       bool truncatedWall,
                                       bool cpu,
                                       bool truncatedCpu,
                                       bool gpu) {
    fTimerTypes = 0;
    fTimerTypes |= wall ? TimerData::kWall_Flag : 0;
    fTimerTypes |= truncatedWall ? TimerData::kTruncatedWall_Flag : 0;
    fTimerTypes |= cpu ? TimerData::kCpu_Flag : 0;
    fTimerTypes |= truncatedCpu ? TimerData::kTruncatedCpu_Flag : 0;
    fTimerTypes |= gpu ? TimerData::kGpu_Flag : 0;
}

BenchTimer* PictureBenchmark::setupTimer(bool useGLTimer) {
#if SK_SUPPORT_GPU
    if (useGLTimer && fRenderer != NULL && fRenderer->isUsingGpuDevice()) {
        return SkNEW_ARGS(BenchTimer, (fRenderer->getGLContext()));
    }
#endif
    return SkNEW_ARGS(BenchTimer, (NULL));
}

void PictureBenchmark::logProgress(const char msg[]) {
    if (fLogger != NULL) {
        fLogger->logProgress(msg);
    }
}

PictureRenderer* PictureBenchmark::setRenderer(sk_tools::PictureRenderer* renderer) {
    SkRefCnt_SafeAssign(fRenderer, renderer);
    return renderer;
}

void PictureBenchmark::run(SkPicture* pict) {
    SkASSERT(pict);
    if (NULL == pict) {
        return;
    }

    SkASSERT(fRenderer != NULL);
    if (NULL == fRenderer) {
        return;
    }

    fRenderer->init(pict);

    // We throw this away to remove first time effects (such as paging in this program)
    fRenderer->setup();
    fRenderer->render(NULL);
    fRenderer->resetState(true);

    bool usingGpu = false;
#if SK_SUPPORT_GPU
    usingGpu = fRenderer->isUsingGpuDevice();
#endif

    uint32_t timerTypes = fTimerTypes;
    if (!usingGpu) {
        timerTypes &= ~TimerData::kGpu_Flag;
    }

    SkString timeFormat;
    if (TimerData::kPerIter_Result == fTimerResult) {
        timeFormat = fRenderer->getPerIterTimeFormat();
    } else {
        timeFormat = fRenderer->getNormalTimeFormat();
    }

    if (fTimeIndividualTiles) {
        TiledPictureRenderer* tiledRenderer = fRenderer->getTiledRenderer();
        SkASSERT(tiledRenderer && tiledRenderer->supportsTimingIndividualTiles());
        if (NULL == tiledRenderer || !tiledRenderer->supportsTimingIndividualTiles()) {
            return;
        }
        int xTiles, yTiles;
        if (!tiledRenderer->tileDimensions(xTiles, yTiles)) {
            return;
        }

        // Insert a newline so that each tile is reported on its own line (separate from the line
        // that describes the skp being run).
        this->logProgress("\n");

        int x, y;
        while (tiledRenderer->nextTile(x, y)) {
            // There are two timers, which will behave slightly differently:
            // 1) longRunningTimer, along with perTileTimerData, will time how long it takes to draw
            // one tile fRepeats times, and take the average. As such, it will not respect thea
            // logPerIter or printMin options, since it does not know the time per iteration. It
            // will also be unable to call flush() for each tile.
            // The goal of this timer is to make up for a system timer that is not precise enough to
            // measure the small amount of time it takes to draw one tile once.
            //
            // 2) perTileTimer, along with perTileTimerData, will record each run separately, and
            // then take the average. As such, it supports logPerIter and printMin options.
            //
            // Although "legal", having two gpu timers running at the same time
            // seems to cause problems (i.e., INVALID_OPERATIONs) on several
            // platforms. To work around this, we disable the gpu timer on the
            // long running timer.
            SkAutoTDelete<BenchTimer> longRunningTimer(this->setupTimer());
            TimerData longRunningTimerData(1);
            SkAutoTDelete<BenchTimer> perTileTimer(this->setupTimer(false));
            TimerData perTileTimerData(fRepeats);
            longRunningTimer->start();
            for (int i = 0; i < fRepeats; ++i) {
                perTileTimer->start();
                tiledRenderer->drawCurrentTile();
                perTileTimer->truncatedEnd();
                tiledRenderer->resetState(false);
                perTileTimer->end();
                SkAssertResult(perTileTimerData.appendTimes(perTileTimer.get()));
            }
            longRunningTimer->truncatedEnd();
            tiledRenderer->resetState(true);
            longRunningTimer->end();
            SkAssertResult(longRunningTimerData.appendTimes(longRunningTimer.get()));

            SkString configName = tiledRenderer->getConfigName();
            configName.appendf(": tile [%i,%i] out of [%i,%i]", x, y, xTiles, yTiles);

            SkString result = perTileTimerData.getResult(timeFormat.c_str(), fTimerResult,
                                                         configName.c_str(), timerTypes);
            result.append("\n");

// TODO(borenet): Turn off per-iteration tile time reporting for now.  Avoiding logging the time
// for every iteration for each tile cuts down on data file size by a significant amount. Re-enable
// this once we're loading the bench data directly into a data store and are no longer generating
// SVG graphs.
#if 0
            this->logProgress(result.c_str());
#endif

            configName.append(" <averaged>");
            SkString longRunningResult = longRunningTimerData.getResult(
                tiledRenderer->getNormalTimeFormat().c_str(),
                TimerData::kAvg_Result,
                configName.c_str(), timerTypes, fRepeats);
            longRunningResult.append("\n");
            this->logProgress(longRunningResult.c_str());
        }
    } else {
        SkAutoTDelete<BenchTimer> longRunningTimer(this->setupTimer());
        TimerData longRunningTimerData(1);
        SkAutoTDelete<BenchTimer> perRunTimer(this->setupTimer(false));
        TimerData perRunTimerData(fRepeats);

        longRunningTimer->start();
        for (int i = 0; i < fRepeats; ++i) {
            fRenderer->setup();

            perRunTimer->start();
            fRenderer->render(NULL);
            perRunTimer->truncatedEnd();
            fRenderer->resetState(false);
            perRunTimer->end();

            SkAssertResult(perRunTimerData.appendTimes(perRunTimer.get()));
        }
        longRunningTimer->truncatedEnd();
        fRenderer->resetState(true);
        longRunningTimer->end();
        SkAssertResult(longRunningTimerData.appendTimes(longRunningTimer.get()));

        SkString configName = fRenderer->getConfigName();

        // Beware - since the per-run-timer doesn't ever include a glFinish it can
        // report a lower time then the long-running-timer
#if 0
        SkString result = perRunTimerData.getResult(timeFormat.c_str(),
                                                    fTimerResult,
                                                    configName.c_str(),
                                                    timerTypes);
        result.append("\n");

        this->logProgress(result.c_str());
#else
        SkString result = longRunningTimerData.getResult(timeFormat.c_str(),
                                                         fTimerResult,
                                                         configName.c_str(),
                                                         timerTypes,
                                                         fRepeats);
        result.append("\n");
        this->logProgress(result.c_str());
#endif
    }

    fRenderer->end();
}

}
<|endoftext|>


<commit_before>#include "any.hpp"

#include <gtest/gtest.h>

struct A
{
    explicit A(int i) :
        m_i(i) {}
    int m_i;
};

TEST(basic, size)
{
    any<16> a;
    ASSERT_EQ(16, sizeof(a));
}

TEST(pod, assign_rvalue_int)
{
    any<16> a;
    a = 5;
    ASSERT_EQ(5, a.get<int>());
}

TEST(pod, assign_lvalue_int)
{
    any<16> a;
    int i = 6;
    a = i;
    ASSERT_EQ(6, a.get<int>());
}

TEST(pod, assign_rvalue_struct)
{
    any<16> a;
    a = A(0xdeadbeef);
    ASSERT_EQ(0xdeadbeef, a.get<A>().m_i);
}

TEST(deleter, size)
{
    struct del
    {
        void operator()(any<16>&) { }
    };

    any<16, del> s;
    ASSERT_EQ(16, sizeof(s));
}

TEST(deleter, called)
{
    static bool deleter_called = false;

    struct del
    {
        void operator()(any<16>&) { deleter_called = true; }
    };

    {
        any<16, del> s;
    }

    ASSERT_TRUE(deleter_called);
}

struct B
{
    explicit B(int i = 0) :
        m_i(new int)
    {
        *m_i = i;
    }

    int *m_i;
};

TEST(deleter, pointer_freed)
{
    struct del
    {
        void operator()(any<16>& a)
        {
            B& b = a.get<B>();
            delete b.m_i;
        }
    };

    any<16, del> a;
    a = B(1234);
    ASSERT_EQ(1234, *a.get<B>().m_i);
}
<commit_msg>More unit tests ....<commit_after>#include "any.hpp"

#include <gtest/gtest.h>

struct A
{
    explicit A(int i) :
        m_i(i) {}
    int m_i;
};

TEST(basic, size)
{
    any<16> a;
    ASSERT_EQ(16, sizeof(a));
}

TEST(basic, trivial)
{
    any<16> a;
    ASSERT_TRUE(std::is_trivial<decltype(a)>::value);
}

TEST(basic, pod)
{
    any<16> a;
    ASSERT_TRUE(std::is_pod<decltype(a)>::value);
}

TEST(pod, assign_rvalue_int)
{
    any<16> a;
    a = 5;
    ASSERT_EQ(5, a.get<int>());
}

TEST(pod, assign_lvalue_int)
{
    any<16> a;
    int i = 6;
    a = i;
    ASSERT_EQ(6, a.get<int>());
}

TEST(pod, assign_rvalue_struct)
{
    any<16> a;
    a = A(0xdeadbeef);
    ASSERT_EQ(0xdeadbeef, a.get<A>().m_i);
}

TEST(deleter, size)
{
    struct del
    {
        void operator()(any<16>&) { }
    };

    any<16, del> s;
    ASSERT_EQ(16, sizeof(s));
}

TEST(deleter, called)
{
    static bool deleter_called = false;

    struct del
    {
        void operator()(any<16>&) { deleter_called = true; }
    };

    {
        any<16, del> s;
    }

    ASSERT_TRUE(deleter_called);
}

struct B
{
    explicit B(int i = 0) :
        m_i(new int)
    {
        *m_i = i;
    }

    int *m_i;
};

TEST(deleter, pointer_freed)
{
    struct del
    {
        void operator()(any<16>& a)
        {
            B& b = a.get<B>();
            delete b.m_i;
        }
    };

    any<16, del> a;
    a = B(1234);
    ASSERT_EQ(1234, *a.get<B>().m_i);
}

TEST(any_assignment, same_type)
{
    any<16> a;
    a = 1234;

    any<16> a2;
    a2 = 0xdeadbeef;
    a2 = a;

    ASSERT_EQ(1234,  a.get<int>());
    ASSERT_EQ(1234, a2.get<int>());
}

TEST(any_assignment, bigger_size)
{
    any<16> a;
    a = 1234;

    any<32> a2;
    a2 = 0xdeadbeef;
    a2 = a;

    ASSERT_EQ(1234,  a.get<int>());
    ASSERT_EQ(1234, a2.get<int>());
}
<|endoftext|>


<commit_before>#include "data-general.hpp"
#include "data-course.hpp"
#include "data-student.hpp"
using namespace std;

vector<Course> all_courses;
Student user;

void loadCourses() {
	ifstream infile("data/2012-13-s2-csv.csv");
	string str; // read in the header line
	getline(infile, str);
	while (infile.peek() != -1){
		Course incourse(infile);
		all_courses.push_back(incourse);
		// cout << incourse << endl;
	}
	// for (vector<Course>::iterator c = all_courses.begin(); c != all_courses.end(); ++c)
	// 	if (c->getProfessor()[1] == ' ')
	// 		if (c->getProfessor()[2] == '0' || c->getProfessor()[2] == '1')
	// 			c->displayMany();
}

void whatDidICallThisWith(int argc, const char *argv[]) {
	printf ("This program was called with \"%s\".\n",argv[0]);

	if (argc > 1)
		for (int count = 1; count < argc; count++)
			printf("argv[%d] = %s\n", count, argv[count]);
	else
		printf("The command had no other arguments.\n");
}

void welcome() {
	string name, yearS = "", yearE = "", majors;
	// cout << "Welcome!" << endl;
	// cout << "What is your name? ";
	// getline(cin, name);
	name = "Xandra Best";
	// cout << "What year do you graduate? ";
	// cin >> yearE;
	// cout << "What are your majors (ex. CSCI, ASIAN) ";
	// getline(cin, majors);
	majors = "CSCI, STAT, ASIAN";
	user = Student(name, yearS, yearE, majors);
}

void getCourses() {
	string courses;
	// cout << "What are some courses that you have taken? (ex. CSCI125, STAT 110)" << endl;
	// cout << "> ";
	// getline(cin, courses);
	courses = "PHIL 251A,PHIL 251B, REL 296A, REL 296B, STAT 110";
	// courses = "CSCI 251, stat 110, THEAT398, writ211";
	user.addCourses(courses);
}

int main(int argc, const char *argv[]) {
	loadCourses();
	// cout << getCourse("STAT 10") << endl;
	// Course c("BIO 126");
	// cout << c << endl;
	welcome();
	getCourses();
	user.display();

	cout << "Question: Has the user taken CSCI 251? " << user.hasTakenCourse("CSCI251") << endl;

	return 0;
}
<commit_msg>More testcases (majors, this time)<commit_after>#include "data-general.hpp"
#include "data-course.hpp"
#include "data-student.hpp"
using namespace std;

vector<Course> all_courses;
Student user;

void loadCourses() {
	ifstream infile("data/2012-13-s2-csv.csv");
	string str; // read in the header line
	getline(infile, str);
	while (infile.peek() != -1){
		Course incourse(infile);
		all_courses.push_back(incourse);
		// cout << incourse << endl;
	}
	// for (vector<Course>::iterator c = all_courses.begin(); c != all_courses.end(); ++c)
	// 	if (c->getProfessor()[1] == ' ')
	// 		if (c->getProfessor()[2] == '0' || c->getProfessor()[2] == '1')
	// 			c->displayMany();
}

void whatDidICallThisWith(int argc, const char *argv[]) {
	printf ("This program was called with \"%s\".\n",argv[0]);

	if (argc > 1)
		for (int count = 1; count < argc; count++)
			printf("argv[%d] = %s\n", count, argv[count]);
	else
		printf("The command had no other arguments.\n");
}

void welcome() {
	string name, yearS = "", yearE = "", majors;
	// cout << "Welcome!" << endl;
	// cout << "What is your name? ";
	// getline(cin, name);
	name = "Xandra Best";
	// cout << "What year do you graduate? ";
	// cin >> yearE;
	// cout << "What are your majors (ex. CSCI, ASIAN) ";
	// getline(cin, majors);
	majors = "CSCI, STAT, AsIaN, math";
	user = Student(name, yearS, yearE, majors);
}

void getCourses() {
	string courses;
	// cout << "What are some courses that you have taken? (ex. CSCI125, STAT 110)" << endl;
	// cout << "> ";
	// getline(cin, courses);
	courses = "PHIL 251A,REL296A,rel 296b, STAT 110,";
	courses += "CSCI251, stat 110, THEAT398, writ211";
	user.addCourses(courses);
}

int main(int argc, const char *argv[]) {
	loadCourses();
	// cout << getCourse("STAT 10") << endl;
	// Course c("BIO 126");
	// cout << c << endl;
	welcome();
	getCourses();
	user.display();

	cout << "Question: Has the user taken CSCI 251? " << user.hasTakenCourse("CSCI251") << endl;

	return 0;
}
<|endoftext|>


<commit_before>// source changed by mrn@paus.ch/ max rheiner
// original source: henryj@paradise.net.nz

#include <iostream>
#include <stdlib.h> // exit()

#ifdef __APPLE_CC__
    #include <GLUT/glut.h>
#else
    #include <GL/glut.h>
#endif

#include "FTGLOutlineFont.h"
#include "FTGLPolygonFont.h"
#include "FTGLBitmapFont.h"
#include "FTGLTextureFont.h"
#include "FTGLPixmapFont.h"

//#include "mmgr.h"

static FTFont* fonts[5];
static int width;
static int height;

// YOU'LL PROBABLY WANT TO CHANGE THESE
#ifdef __linux__
	#define DEFAULT_FONT "/usr/share/fonts/truetype/arial.ttf"
#endif
#ifdef __APPLE_CC__
	#define DEFAULT_FONT "/Users/henry/Development/PROJECTS/FTGL/ftglcvs/FTGL/demo/arial.ttf"
#endif
#ifdef WIN32
	#define DEFAULT_FONT "C:\\WINNT\\Fonts\\arial.ttf"
#endif

void
my_init( const char* font_filename )
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    fonts[0] = new FTGLOutlineFont;
    fonts[1] = new FTGLPolygonFont;
    fonts[2] = new FTGLTextureFont;
    fonts[3] = new FTGLBitmapFont;
    fonts[4] = new FTGLPixmapFont;
    for (int i=0; i< 5; i++)
    {
        if (!fonts[i]->Open(font_filename))
        {
            std::cerr << "ERROR: Unable to open file " << font_filename << std::endl;
        }
        else
        {
            std::cout << "Reading font " << i << " from " << font_filename << std::endl;

            int point_size = 24;
            if (!fonts[i]->FaceSize(point_size))
            {
                std::cerr << "ERROR: Unable to set font face size " << point_size << std::endl;
            }
        }
    }
}

static void
do_ortho()
{
  int w;
  int h;
  GLdouble size;
  GLdouble aspect;

  w = width;
  h = height;
  aspect = (GLdouble)w / (GLdouble)h;

  // Use the whole window.
  glViewport(0, 0, w, h);

  // We are going to do some 2-D orthographic drawing.
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  size = (GLdouble)((w >= h) ? w : h) / 2.0;
  if (w <= h) {
    aspect = (GLdouble)h/(GLdouble)w;
    glOrtho(-size, size, -size*aspect, size*aspect,
            -100000.0, 100000.0);
  }
  else {
    aspect = (GLdouble)w/(GLdouble)h;
    glOrtho(-size*aspect, size*aspect, -size, size,
            -100000.0, 100000.0);
  }

  // Make the world and window coordinates coincide so that 1.0 in
  // model space equals one pixel in window space.
  glScaled(aspect, aspect, 1.0);

   // Now determine where to draw things.
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void
my_reshape(int w, int h)
{
  width = w;
  height = h;

  do_ortho( );
}

void
my_handle_key(unsigned char key, int x, int y)
{
   switch (key) {

	   //!!ELLERS
   case 'q':   // Esc or 'q' Quits the program.
   case 27:
	   {
       for (int i=0; i<5; i++) {
           if (fonts[i]) {
               delete fonts[i];
               fonts[i] = 0;
           }
       }
      exit(1);
	   }
      break;

   default:
      break;
   }
}

void
draw_scene()
{
   /* Set up some strings with the characters to draw. */
   unsigned int count = 0;
   char string[8][256];
   int i;
   for (i=1; i < 32; i++) { /* Skip zero - it's the null terminator! */
      string[0][count] = i;
      count++;
   }
   string[0][count] = '\0';

   count = 0;
   for (i=32; i < 64; i++) {
      string[1][count] = i;
      count++;
   }
   string[1][count] = '\0';

   count = 0;
   for (i=64; i < 96; i++) {
      string[2][count] = i;
      count++;
   }
   string[2][count] = '\0';

   count = 0;
   for (i=96; i < 128; i++) {
      string[3][count] = i;
      count++;
   }
   string[3][count] = '\0';

   count = 0;
   for (i=128; i < 160; i++) {
      string[4][count] = i;
      count++;
   }
   string[4][count] = '\0';

   count = 0;
   for (i=160; i < 192; i++) {
      string[5][count] = i;
      count++;
   }
   string[5][count] = '\0';

   count = 0;
   for (i=192; i < 224; i++) {
      string[6][count] = i;
      count++;
   }
   string[6][count] = '\0';

   count = 0;
   for (i=224; i < 256; i++) {
      string[7][count] = i;
      count++;
   }
   string[7][count] = '\0';

   glColor3f(1.0, 1.0, 1.0);

   for (int font = 0; font < 5; font++) {
       GLfloat x = -250.0;
       GLfloat y;
       GLfloat yild = 20.0;
       for (int j=0; j<4; j++) {
           y = 275.0-font*120.0-j*yild;
           if (font >= 3) {
               glRasterPos2f(x, y);
               fonts[font]->render(string[j]);
           }
           else {
               if (font == 2) {
                   glEnable(GL_TEXTURE_2D);
                   glEnable(GL_BLEND);
                   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
               }
               glPushMatrix(); {
                   glTranslatef(x, y, 0.0);
                   fonts[font]->render(string[j]);
               } glPopMatrix();
               if (font == 2) {
                   glDisable(GL_TEXTURE_2D);
                   glDisable(GL_BLEND);
               }
           }
       }
   }
}

void
my_display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    draw_scene();

    glutSwapBuffers();
}

int
file_exists( const char * filename )
{
	FILE * fp = fopen( filename, "r" );

	if ( fp == NULL )
	{
		// That fopen failed does _not_ definitely mean the file isn't there
		// but for now this is ok
		return 0;
	}
	fclose( fp );
	return 1;
}

void
usage( const char * program )
{
	std::cerr << "Usage: " << program << " <filename.ttf>\n" << std::endl;
}

int
main(int argc, char **argv)
{
	char * filename;

	glutInitWindowSize(600, 600);
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);

	glutCreateWindow("FTGL demo");

	if ( argc >= 2 )
	{
		if ( !file_exists( argv[ 1 ] ))
		{
			usage( argv[ 0 ]);
			std::cerr << "Couldn't open file '" << argv[ 1 ] << "'" << std::endl;
			exit( -1 );
		}
		filename = argv[ 1 ];
	}
	else
	{
		// try a default font
		filename = DEFAULT_FONT;

		if ( !file_exists( filename ))
		{
			usage( argv[ 0 ]);
			std::cerr << "Couldn't open default file '" << filename << "'" << std::endl;
			exit( -1 );
		}
	}

	my_init( filename );

	glutDisplayFunc(my_display);
	glutReshapeFunc(my_reshape);
	glutKeyboardFunc(my_handle_key);

	glutMainLoop();

        for(int x = 0; x < 5; ++x)
        {
            delete fonts[x];
        }

	return 0;
}

<commit_msg>Added Idle function<commit_after>// source changed by mrn@paus.ch/ max rheiner
// original source: henryj@paradise.net.nz

#include <iostream>
#include <stdlib.h> // exit()

#ifdef __APPLE_CC__
    #include <GLUT/glut.h>
#else
    #include <GL/glut.h>
#endif

#include "FTGLOutlineFont.h"
#include "FTGLPolygonFont.h"
#include "FTGLBitmapFont.h"
#include "FTGLTextureFont.h"
#include "FTGLPixmapFont.h"

//#include "mmgr.h"

static FTFont* fonts[5];
static int width;
static int height;

// YOU'LL PROBABLY WANT TO CHANGE THESE
#ifdef __linux__
	#define DEFAULT_FONT "/usr/share/fonts/truetype/arial.ttf"
#endif
#ifdef __APPLE_CC__
	#define DEFAULT_FONT "/Users/henry/Development/PROJECTS/FTGL/ftglcvs/FTGL/demo/arial.ttf"
#endif
#ifdef WIN32
	#define DEFAULT_FONT "C:\\WINNT\\Fonts\\arial.ttf"
#endif

void
my_init( const char* font_filename )
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    fonts[0] = new FTGLOutlineFont;
    fonts[1] = new FTGLPolygonFont;
    fonts[2] = new FTGLTextureFont;
    fonts[3] = new FTGLBitmapFont;
    fonts[4] = new FTGLPixmapFont;
    for (int i=0; i< 5; i++)
    {
        if (!fonts[i]->Open(font_filename))
        {
            std::cerr << "ERROR: Unable to open file " << font_filename << std::endl;
        }
        else
        {
            std::cout << "Reading font " << i << " from " << font_filename << std::endl;

            int point_size = 24;
            if (!fonts[i]->FaceSize(point_size))
            {
                std::cerr << "ERROR: Unable to set font face size " << point_size << std::endl;
            }
        }
    }
}

static void
do_ortho()
{
  int w;
  int h;
  GLdouble size;
  GLdouble aspect;

  w = width;
  h = height;
  aspect = (GLdouble)w / (GLdouble)h;

  // Use the whole window.
  glViewport(0, 0, w, h);

  // We are going to do some 2-D orthographic drawing.
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  size = (GLdouble)((w >= h) ? w : h) / 2.0;
  if (w <= h) {
    aspect = (GLdouble)h/(GLdouble)w;
    glOrtho(-size, size, -size*aspect, size*aspect,
            -100000.0, 100000.0);
  }
  else {
    aspect = (GLdouble)w/(GLdouble)h;
    glOrtho(-size*aspect, size*aspect, -size, size,
            -100000.0, 100000.0);
  }

  // Make the world and window coordinates coincide so that 1.0 in
  // model space equals one pixel in window space.
  glScaled(aspect, aspect, 1.0);

   // Now determine where to draw things.
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void
my_reshape(int w, int h)
{
  width = w;
  height = h;

  do_ortho( );
}

void
my_handle_key(unsigned char key, int x, int y)
{
   switch (key) {

	   //!!ELLERS
   case 'q':   // Esc or 'q' Quits the program.
   case 27:
	   {
       for (int i=0; i<5; i++) {
           if (fonts[i]) {
               delete fonts[i];
               fonts[i] = 0;
           }
       }
      exit(1);
	   }
      break;

   default:
      break;
   }
}

void
draw_scene()
{
   /* Set up some strings with the characters to draw. */
   unsigned int count = 0;
   char string[8][256];
   int i;
   for (i=1; i < 32; i++) { /* Skip zero - it's the null terminator! */
      string[0][count] = i;
      count++;
   }
   string[0][count] = '\0';

   count = 0;
   for (i=32; i < 64; i++) {
      string[1][count] = i;
      count++;
   }
   string[1][count] = '\0';

   count = 0;
   for (i=64; i < 96; i++) {
      string[2][count] = i;
      count++;
   }
   string[2][count] = '\0';

   count = 0;
   for (i=96; i < 128; i++) {
      string[3][count] = i;
      count++;
   }
   string[3][count] = '\0';

   count = 0;
   for (i=128; i < 160; i++) {
      string[4][count] = i;
      count++;
   }
   string[4][count] = '\0';

   count = 0;
   for (i=160; i < 192; i++) {
      string[5][count] = i;
      count++;
   }
   string[5][count] = '\0';

   count = 0;
   for (i=192; i < 224; i++) {
      string[6][count] = i;
      count++;
   }
   string[6][count] = '\0';

   count = 0;
   for (i=224; i < 256; i++) {
      string[7][count] = i;
      count++;
   }
   string[7][count] = '\0';

   glColor3f(1.0, 1.0, 1.0);

   for (int font = 0; font < 5; font++) {
       GLfloat x = -250.0;
       GLfloat y;
       GLfloat yild = 20.0;
       for (int j=0; j<4; j++) {
           y = 275.0-font*120.0-j*yild;
           if (font >= 3) {
               glRasterPos2f(x, y);
               fonts[font]->render(string[j]);
           }
           else {
               if (font == 2) {
                   glEnable(GL_TEXTURE_2D);
                   glEnable(GL_BLEND);
                   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
               }
               glPushMatrix(); {
                   glTranslatef(x, y, 0.0);
                   fonts[font]->render(string[j]);
               } glPopMatrix();
               if (font == 2) {
                   glDisable(GL_TEXTURE_2D);
                   glDisable(GL_BLEND);
               }
           }
       }
   }
}

void
my_display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    draw_scene();

    glutSwapBuffers();
}

void
my_idle()
{
    glutPostRedisplay();
}

int
file_exists( const char * filename )
{
	FILE * fp = fopen( filename, "r" );

	if ( fp == NULL )
	{
		// That fopen failed does _not_ definitely mean the file isn't there
		// but for now this is ok
		return 0;
	}
	fclose( fp );
	return 1;
}

void
usage( const char * program )
{
	std::cerr << "Usage: " << program << " <filename.ttf>\n" << std::endl;
}

int
main(int argc, char **argv)
{
	char * filename;

	glutInitWindowSize(600, 600);
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);

	glutCreateWindow("FTGL demo");

	if ( argc >= 2 )
	{
		if ( !file_exists( argv[ 1 ] ))
		{
			usage( argv[ 0 ]);
			std::cerr << "Couldn't open file '" << argv[ 1 ] << "'" << std::endl;
			exit( -1 );
		}
		filename = argv[ 1 ];
	}
	else
	{
		// try a default font
		filename = DEFAULT_FONT;

		if ( !file_exists( filename ))
		{
			usage( argv[ 0 ]);
			std::cerr << "Couldn't open default file '" << filename << "'" << std::endl;
			exit( -1 );
		}
	}

	my_init( filename );

	glutDisplayFunc(my_display);
	glutReshapeFunc(my_reshape);
	glutIdleFunc(my_idle);
	glutKeyboardFunc(my_handle_key);

	glutMainLoop();

        for(int x = 0; x < 5; ++x)
        {
            delete fonts[x];
        }

	return 0;
}

<|endoftext|>


<commit_before>#include "demonstrationwindow.h"
#include "particlewidget.h"
#include "ui_DemonstrationWindow.h"
#include <QTimer>
#include "qcustomplot/qcustomplot.h"
#include <limits>

DemonstrationWindow::DemonstrationWindow(QString simulationFile, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::DemonstrationWindow) {
    ui->setupUi(this);
    mWorld = new World(simulationFile);
    ui->canvas->initializeWorld(*mWorld->getGeometry(), mWorld->getParticles());
    ui->sliderState->setMaximum(mWorld->getStateCount());

    ui->plotMaxwell->xAxis->setLabel("Velocity, m/s");
    ui->plotMaxwell->yAxis->setLabel("Particle density");
    mDataMaxwell = new QCPBars(ui->plotMaxwell->xAxis, ui->plotMaxwell->yAxis);
    mDataMaxwellTheoretical = new QCPCurve(ui->plotMaxwell->xAxis, ui->plotMaxwell->yAxis);
    ui->plotMaxwell->addPlottable(mDataMaxwell);
    ui->plotMaxwell->addPlottable(mDataMaxwellTheoretical);

    ui->plotBoltzmann->xAxis->setLabel("Height, m");
    ui->plotBoltzmann->yAxis->setLabel("Particle density");
    mDataBoltzmann = new QCPBars(ui->plotBoltzmann->xAxis, ui->plotBoltzmann->yAxis);
    ui->plotBoltzmann->addPlottable(mDataBoltzmann);

    mTimer = new QTimer(this);
    mActive = true;
    connect(mTimer, &QTimer::timeout, this, &DemonstrationWindow::onTimerTimeout);
    connect(mWorld, &World::onStateChanged, ui->canvas, &ParticleWidget::setParticles);
    mTimer->setInterval((int)(1000.0 / ui->comboFps->value()));
    mTimer->start();
}

DemonstrationWindow::~DemonstrationWindow() {
    delete ui;
    delete mWorld;
    delete mDataBoltzmann;
    delete mDataMaxwellTheoretical;
    delete mDataMaxwell;
}

void DemonstrationWindow::updateBoltzmannPlot(QVector<SParticle> particles) {
    QVector<double> x(15), y(15);
    double hMin = std::numeric_limits<double>::max();
    double hMax = std::numeric_limits<double>::min();
    double yMin = std::numeric_limits<double>::max();
    double yMax = std::numeric_limits<double>::min();
    foreach (SParticle particle, particles) {
        hMin = qMin(hMin, particle.y);
        hMax = qMax(hMax, particle.y);
    }
    double dH = hMax / 15.0;
    for (quint8 i = 0; i < 15; i++) {
        x[i] = dH * (i + 1);
    }

    foreach (SParticle particle, particles) {
        quint8 chunk = int((particle.y - dH / 2.0) / dH);
        y[chunk]++;
    }

    for (quint8 i = 0; i < 15; i++) {
        y[i] = y[i] / (double)particles.size();
    }

    foreach (double val, y) {
        yMin = qMin(yMin, val);
        yMax = qMax(yMax, val);
    }

    ui->plotBoltzmann->xAxis->setRange(0.0, ((int)(hMax / 5.0) + 1) * 5.0);
    ui->plotBoltzmann->yAxis->setRange(0.0, 1.0);
    mDataBoltzmann->setWidth(dH);
    mDataBoltzmann->setData(x, y);
    ui->plotBoltzmann->replot();
}

void DemonstrationWindow::updateMaxwellPlot(QVector<SParticle> particles) {
    QVector<double> x(15), y(15);
    double vMin = std::numeric_limits<double>::max();
    double vMax = std::numeric_limits<double>::min();
    double yMin = std::numeric_limits<double>::max();
    double yMax = std::numeric_limits<double>::min();
    foreach (SParticle particle, particles) {
        double velocity = particleVelocity(particle);
        vMin = qMin(vMin, velocity);
        vMax = qMax(vMax, velocity);
    }
    double dV = vMax / 15.0;
    for (quint8 i = 0; i < 15; i++) {
        x[i] = dV * (i + 1);
    }

    foreach (SParticle particle, particles) {
        double velocity = particleVelocity(particle);
        quint8 chunk = int((velocity - dV / 2.0) / dV);
        y[chunk]++;
    }

    for (quint8 i = 0; i < 15; i++) {
        y[i] = y[i] / (double)particles.size();
    }

    foreach (double val, y) {
        yMin = qMin(yMin, val);
        yMax = qMax(yMax, val);
    }

    ui->plotMaxwell->xAxis->setRange(0.0, ((int)(vMax / 5.0) + 1) * 5.0);
    ui->plotMaxwell->yAxis->setRange(0.0, 1.0);
    ui->plotMaxwell->rescaleAxes();
    mDataBoltzmann->setWidth(dV);
    mDataMaxwell->setData(x, y);

    double vProbable = x[y.indexOf(yMax)];
    double k = 4 / sqrt(M_PI) * pow(1.0 / vProbable, 3.0);
    for (quint8 i = 0; i < 15; i++) {
        y[i] = k * pow(x[i], 2.0) * exp(-pow(x[i], 2.0) / pow(vProbable, 2.0));
    }
    mDataMaxwellTheoretical->setData(x, y);
    ui->plotMaxwell->replot();

}

void DemonstrationWindow::pause() {
    mTimer->stop();
    ui->buttonPlay->setText("▷");
    mActive = false;
}

void DemonstrationWindow::start() {
    mTimer->start();
    ui->buttonPlay->setText("▯▯");
    mActive = true;
}

void DemonstrationWindow::onTimerTimeout() {
    if (mActive) {
        ui->sliderState->setValue(ui->sliderState->value() + 1);
    }
}

void DemonstrationWindow::on_comboFps_valueChanged(int value) {
    mTimer->setInterval((int)(1000.0 / ui->comboFps->value()));
}

void DemonstrationWindow::on_sliderState_valueChanged(int value){
    mWorld->readParticlesState(value);
    ui->labelTime->setText(tr("Time elapsed: %1s").arg(mWorld->getTime(), 0, 'g', 5));
    QVector<SParticle> particles = mWorld->getParticles();
    updateBoltzmannPlot(particles);
    updateMaxwellPlot(particles);
}

void DemonstrationWindow::on_buttonPlay_released() {
    if (mActive) {
        pause();
    }
    else {
        start();
    }

}
<commit_msg>Исправлена ширина гистограм в графике распределения Максвелла<commit_after>#include "demonstrationwindow.h"
#include "particlewidget.h"
#include "ui_DemonstrationWindow.h"
#include <QTimer>
#include "qcustomplot/qcustomplot.h"
#include <limits>

DemonstrationWindow::DemonstrationWindow(QString simulationFile, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::DemonstrationWindow) {
    ui->setupUi(this);
    mWorld = new World(simulationFile);
    ui->canvas->initializeWorld(*mWorld->getGeometry(), mWorld->getParticles());
    ui->sliderState->setMaximum(mWorld->getStateCount());

    ui->plotMaxwell->xAxis->setLabel("Velocity, m/s");
    ui->plotMaxwell->yAxis->setLabel("Particle density");
    mDataMaxwell = new QCPBars(ui->plotMaxwell->xAxis, ui->plotMaxwell->yAxis);
    mDataMaxwellTheoretical = new QCPCurve(ui->plotMaxwell->xAxis, ui->plotMaxwell->yAxis);
    ui->plotMaxwell->addPlottable(mDataMaxwell);
    ui->plotMaxwell->addPlottable(mDataMaxwellTheoretical);

    ui->plotBoltzmann->xAxis->setLabel("Height, m");
    ui->plotBoltzmann->yAxis->setLabel("Particle density");
    mDataBoltzmann = new QCPBars(ui->plotBoltzmann->xAxis, ui->plotBoltzmann->yAxis);
    ui->plotBoltzmann->addPlottable(mDataBoltzmann);

    mTimer = new QTimer(this);
    mActive = true;
    connect(mTimer, &QTimer::timeout, this, &DemonstrationWindow::onTimerTimeout);
    connect(mWorld, &World::onStateChanged, ui->canvas, &ParticleWidget::setParticles);
    mTimer->setInterval((int)(1000.0 / ui->comboFps->value()));
    mTimer->start();
}

DemonstrationWindow::~DemonstrationWindow() {
    delete ui;
    delete mWorld;
    delete mDataBoltzmann;
    delete mDataMaxwellTheoretical;
    delete mDataMaxwell;
}

void DemonstrationWindow::updateBoltzmannPlot(QVector<SParticle> particles) {
    QVector<double> x(15), y(15);
    double hMin = std::numeric_limits<double>::max();
    double hMax = std::numeric_limits<double>::min();
    double yMin = std::numeric_limits<double>::max();
    double yMax = std::numeric_limits<double>::min();
    foreach (SParticle particle, particles) {
        hMin = qMin(hMin, particle.y);
        hMax = qMax(hMax, particle.y);
    }
    double dH = hMax / 15.0;
    for (quint8 i = 0; i < 15; i++) {
        x[i] = dH * (i + 1);
    }

    foreach (SParticle particle, particles) {
        quint8 chunk = int((particle.y - dH / 2.0) / dH);
        y[chunk]++;
    }

    for (quint8 i = 0; i < 15; i++) {
        y[i] = y[i] / (double)particles.size();
    }

    foreach (double val, y) {
        yMin = qMin(yMin, val);
        yMax = qMax(yMax, val);
    }

    ui->plotBoltzmann->xAxis->setRange(0.0, ((int)(hMax / 5.0) + 1) * 5.0);
    ui->plotBoltzmann->yAxis->setRange(0.0, 1.0);
    mDataBoltzmann->setWidth(dH);
    mDataBoltzmann->setData(x, y);
    ui->plotBoltzmann->replot();
}

void DemonstrationWindow::updateMaxwellPlot(QVector<SParticle> particles) {
    QVector<double> x(15), y(15);
    double vMin = std::numeric_limits<double>::max();
    double vMax = std::numeric_limits<double>::min();
    double yMin = std::numeric_limits<double>::max();
    double yMax = std::numeric_limits<double>::min();
    foreach (SParticle particle, particles) {
        double velocity = particleVelocity(particle);
        vMin = qMin(vMin, velocity);
        vMax = qMax(vMax, velocity);
    }
    double dV = vMax / 15.0;
    for (quint8 i = 0; i < 15; i++) {
        x[i] = dV * (i + 1);
    }

    foreach (SParticle particle, particles) {
        double velocity = particleVelocity(particle);
        quint8 chunk = int((velocity - dV / 2.0) / dV);
        y[chunk]++;
    }

    for (quint8 i = 0; i < 15; i++) {
        y[i] = y[i] / (double)particles.size();
    }

    foreach (double val, y) {
        yMin = qMin(yMin, val);
        yMax = qMax(yMax, val);
    }

    ui->plotMaxwell->xAxis->setRange(0.0, ((int)(vMax / 5.0) + 1) * 5.0);
    ui->plotMaxwell->yAxis->setRange(0.0, 1.0);
    ui->plotMaxwell->rescaleAxes();
    mDataMaxwell->setWidth(dV);
    mDataMaxwell->setData(x, y);

    double vProbable = x[y.indexOf(yMax)];
    double k = 4 / sqrt(M_PI) * pow(1.0 / vProbable, 3.0);
    for (quint8 i = 0; i < 15; i++) {
        y[i] = k * pow(x[i], 2.0) * exp(-pow(x[i], 2.0) / pow(vProbable, 2.0));
    }
    mDataMaxwellTheoretical->setData(x, y);
    ui->plotMaxwell->replot();

}

void DemonstrationWindow::pause() {
    mTimer->stop();
    ui->buttonPlay->setText("▷");
    mActive = false;
}

void DemonstrationWindow::start() {
    mTimer->start();
    ui->buttonPlay->setText("▯▯");
    mActive = true;
}

void DemonstrationWindow::onTimerTimeout() {
    if (mActive) {
        ui->sliderState->setValue(ui->sliderState->value() + 1);
    }
}

void DemonstrationWindow::on_comboFps_valueChanged(int value) {
    mTimer->setInterval((int)(1000.0 / ui->comboFps->value()));
}

void DemonstrationWindow::on_sliderState_valueChanged(int value){
    mWorld->readParticlesState(value);
    ui->labelTime->setText(tr("Time elapsed: %1s").arg(mWorld->getTime(), 0, 'g', 5));
    QVector<SParticle> particles = mWorld->getParticles();
    updateBoltzmannPlot(particles);
    updateMaxwellPlot(particles);
}

void DemonstrationWindow::on_buttonPlay_released() {
    if (mActive) {
        pause();
    }
    else {
        start();
    }

}
<|endoftext|>


<commit_before>#include <cassert>

#include "barrier_sync_client.h"
#include "simulator.h"
#include "config.h"
#include "message_types.h"
#include "packet_type.h"
#include "packetize.h"
#include "network.h"
#include "core.h"
#include "performance_model.h"
#include "clock_converter.h"
#include "fxsupport.h"

BarrierSyncClient::BarrierSyncClient(Core* core):
   m_core(core)
{
   try
   {
      m_barrier_interval = (UInt64) Sim()->getCfg()->getInt("clock_skew_minimization/barrier/quantum");
   }
   catch(...)
   {
      LOG_PRINT_ERROR("Error Reading 'clock_skew_minimization/barrier/quantum' from the config file");
   }
   m_next_sync_time = m_barrier_interval;
}

BarrierSyncClient::~BarrierSyncClient()
{}

void
BarrierSyncClient::synchronize(UInt64 cycle_count)
{
   UnstructuredBuffer m_send_buff;
   UnstructuredBuffer m_recv_buff;

   // Floating Point Save/Restore
   FloatingPointHandler floating_point_handler;

   if (cycle_count == 0)
      cycle_count = m_core->getPerformanceModel()->getCycleCount();

   // Convert from core clock to global clock
   UInt64 curr_time = convertCycleCount(cycle_count, m_core->getPerformanceModel()->getFrequency(), 1.0);

   if (curr_time >= m_next_sync_time)
   {
      // Send 'SIM_BARRIER_WAIT' request
      int msg_type = MCP_MESSAGE_CLOCK_SKEW_MINIMIZATION;

      m_send_buff << msg_type << curr_time;
      m_core->getNetwork()->netSend(Config::getSingleton()->getMCPCoreNum(), MCP_SYSTEM_TYPE, m_send_buff.getBuffer(), m_send_buff.size());

      LOG_PRINT("Core(%i), curr_time(%llu), m_next_sync_time(%llu) sent SIM_BARRIER_WAIT", m_core->getId(), curr_time, m_next_sync_time);

      // Receive 'BARRIER_RELEASE' response
      NetPacket recv_pkt;
      recv_pkt = m_core->getNetwork()->netRecv(Config::getSingleton()->getMCPCoreNum(), MCP_SYSTEM_RESPONSE_TYPE);
      assert(recv_pkt.length == sizeof(int));

      unsigned int dummy;
      m_recv_buff << make_pair(recv_pkt.data, recv_pkt.length);
      m_recv_buff >> dummy;
      assert(dummy == BARRIER_RELEASE);

      LOG_PRINT("Core(%i) received SIM_BARRIER_RELEASE", m_core->getId());

      // Update 'm_next_sync_time'
      m_next_sync_time = ((curr_time / m_barrier_interval) * m_barrier_interval) + m_barrier_interval;

      // Delete the data buffer
      delete [] (Byte*) recv_pkt.data;
   }
}
<commit_msg>[barrier_sync_client] New network API changes<commit_after>#include <cassert>

#include "barrier_sync_client.h"
#include "simulator.h"
#include "config.h"
#include "message_types.h"
#include "packet_type.h"
#include "packetize.h"
#include "network.h"
#include "core.h"
#include "performance_model.h"
#include "clock_converter.h"
#include "fxsupport.h"

BarrierSyncClient::BarrierSyncClient(Core* core):
   m_core(core)
{
   try
   {
      m_barrier_interval = (UInt64) Sim()->getCfg()->getInt("clock_skew_minimization/barrier/quantum");
   }
   catch(...)
   {
      LOG_PRINT_ERROR("Error Reading 'clock_skew_minimization/barrier/quantum' from the config file");
   }
   m_next_sync_time = m_barrier_interval;
}

BarrierSyncClient::~BarrierSyncClient()
{}

void
BarrierSyncClient::synchronize(UInt64 cycle_count)
{
   UnstructuredBuffer m_send_buff;
   UnstructuredBuffer m_recv_buff;

   // Floating Point Save/Restore
   FloatingPointHandler floating_point_handler;

   if (cycle_count == 0)
      cycle_count = m_core->getPerformanceModel()->getCycleCount();

   // Convert from core clock to global clock
   UInt64 curr_time = convertCycleCount(cycle_count, m_core->getPerformanceModel()->getFrequency(), 1.0);

   if (curr_time >= m_next_sync_time)
   {
      // Send 'SIM_BARRIER_WAIT' request
      int msg_type = MCP_MESSAGE_CLOCK_SKEW_MINIMIZATION;

      m_send_buff << msg_type << curr_time;
      m_core->getNetwork()->netSend(Config::getSingleton()->getMCPCoreNum(), MCP_SYSTEM_TYPE, m_send_buff.getBuffer(), m_send_buff.size());

      LOG_PRINT("Core(%i), curr_time(%llu), m_next_sync_time(%llu) sent SIM_BARRIER_WAIT", m_core->getId(), curr_time, m_next_sync_time);

      // Receive 'BARRIER_RELEASE' response
      NetPacket* recv_pkt;
      recv_pkt = m_core->getNetwork()->netRecv(Config::getSingleton()->getMCPCoreNum(), MCP_SYSTEM_RESPONSE_TYPE);
      assert(recv_pkt->length == sizeof(int));

      unsigned int dummy;
      m_recv_buff << make_pair(recv_pkt->data, recv_pkt->length);
      m_recv_buff >> dummy;
      assert(dummy == BARRIER_RELEASE);

      LOG_PRINT("Core(%i) received SIM_BARRIER_RELEASE", m_core->getId());

      // Update 'm_next_sync_time'
      m_next_sync_time = ((curr_time / m_barrier_interval) * m_barrier_interval) + m_barrier_interval;

      // Delete the data buffer
      recv_pkt->release();
   }
}
<|endoftext|>


<commit_before>#include <sx/ResFileHelper.h>
#include <ns/NodeFactory.h>
#include <node0/SceneNode.h>
#include <node0/CompComplex.h>
#include <unirender/Factory.h>
#include <ns/RegistCallback.h>
#include <facade/Facade.h>
#include <shadergraph/Evaluator.h>
#include <shadergraph/Block.h>
#include <shadergraph/ShaderGraph.h>
#include <shadergraph/block/FragmentShader.h>
#include <js/RapidJsonHelper.h>
#include <dag/Node.h>
#include <unirender/typedef.h>
#include <unirender/Device.h>
#include <unirender/ShaderProgram.h>
#include <unirender/TextureDescription.h>
#include <unirender/Framebuffer.h>
#include <unirender/Context.h>
#include <unirender/DrawState.h>
#include <unirender/ClearState.h>
#include <shadertrans/ShaderTrans.h>
#include <gimg_export.h>
#include <gimg_typedef.h>

#include <blueprint/Node.h>
#include <blueprint/Pin.h>
#include <blueprint/Connecting.h>
#include <blueprint/Blueprint.h>
#include <blueprint/CompNode.h>
#include <blueprint/NSCompNode.h>
#include <blueprint/SerializeHelper.h>
#include <blueprint/node/SubGraph.h>
#include <shaderlab/ShaderLab.h>
#include <shaderlab/ShaderAdapter.h>
#include <shaderlab/Evaluator.h>
#include <shaderlab/Node.h>
#include <shaderlab/node/Texture2DAsset.h>

#include <gl/glew.h>
#include <glfw3.h>

#include <boost/filesystem.hpp>

#include <stdio.h>
#include <stdlib.h>

namespace
{

const char* vs = R"(
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

void main()
{
	gl_Position = vec4(aPos, 0.0, 1.0);
	TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
)";

const int TEX_SIZE = 512;

uint8_t* BUFFER = nullptr;

}

void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}

bool init_gl()
{
	glfwSetErrorCallback(error_callback);
	if (!glfwInit()) {
		exit(EXIT_FAILURE);
		return false;
	}

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
	GLFWwindow* window = glfwCreateWindow(100, 100, "rotate-crop", nullptr, nullptr);
	if (!window)
	{
		glfwTerminate();
		return false;
	}
	glfwMakeContextCurrent(window);

	// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
	glewExperimental = GL_TRUE;
	//// Initialize GLEW to setup the OpenGL Function pointers
	//if (glewInit() != GLEW_OK) {
	//	return -1;
	//}

	return true;
}

std::shared_ptr<ur::ShaderProgram>
build_shader(const ur::Device& dev, const std::vector<bp::NodePtr>& front_nodes,
             const std::vector<std::shared_ptr<dag::Node<shadergraph::Variant>>>& back_nodes,
             std::vector<std::pair<size_t, ur::TexturePtr>>& textures)
{
    shadergraph::Evaluator eval;

    std::string fs;

    // build frag m_shader
    for (auto& back : back_nodes)
    {
        if (!back) {
            continue;
        }
        auto block = std::static_pointer_cast<shadergraph::Block>(back);
        if (block->get_type() == rttr::type::get<shadergraph::block::FragmentShader>())
        {
            eval.Rebuild(block);
            fs = eval.GenShaderCode();
            break;
        }
    }

    if (fs.empty()) {
        return nullptr;
    }

    std::vector<unsigned int> _vs, _fs;
    shadertrans::ShaderTrans::GLSL2SpirV(shadertrans::ShaderStage::VertexShader, vs, _vs);
    shadertrans::ShaderTrans::GLSL2SpirV(shadertrans::ShaderStage::PixelShader, fs, _fs);
    auto shader = dev.CreateShaderProgram(_vs, _fs);
    if (!shader || !shader->CheckStatus()) {
        return nullptr;
    }

    // textures
    assert(front_nodes.size() == back_nodes.size());
    for (int i = 0, n = front_nodes.size(); i < n; ++i)
    {
        auto& front = front_nodes[i];
        auto& back = back_nodes[i];
        if (front->get_type() != rttr::type::get<shaderlab::node::Texture2DAsset>()) {
            continue;
        }

        auto tex = std::static_pointer_cast<shaderlab::node::Texture2DAsset>(front)->GetTexture();
        if (!tex) {
            continue;
        }

        assert(back);
        auto block = std::static_pointer_cast<shadergraph::Block>(back);
        auto name = eval.QueryRealName(&block->GetExports()[0].var.type);

        auto slot = shader->QueryTexSlot(name);
        if (slot >= 0) {
            textures.push_back({ slot, tex });
        }
    }

    // update uniforms
    shaderlab::Evaluator::UpdateUniforms(eval, shader);

    return shader;
}

void test_file(const ur::Device& dev, ur::Context& ctx,
               const std::shared_ptr<ur::Framebuffer>& rt,
               const std::string& filepath)
{
    auto dir = boost::filesystem::path(filepath).parent_path().string();

    auto root = ns::NodeFactory::Create(dev, filepath);

    auto& ccomplex = root->GetSharedComp<n0::CompComplex>();
    auto& children = ccomplex.GetAllChildren();

    // update subgraph
    for (auto& c : children)
    {
        if (!c->HasUniqueComp<bp::CompNode>()) {
            continue;
        }
        auto bp_node = c->GetUniqueComp<bp::CompNode>().GetNode();
        if (!bp_node->get_type().is_derived_from<bp::node::SubGraph<shadergraph::Variant>>()) {
            continue;
        }
        assert(c->HasSharedComp<n0::CompComplex>());
        auto& c_ccomplex = c->GetSharedComp<n0::CompComplex>();
        std::vector<bp::NodePtr> bp_nodes;
        for (auto& cc : c_ccomplex.GetAllChildren()) {
            if (cc->HasUniqueComp<bp::CompNode>()) {
                bp_nodes.push_back(cc->GetUniqueComp<bp::CompNode>().GetNode());
            }
        }
        auto sub_graph = std::static_pointer_cast<bp::node::SubGraph<shadergraph::Variant>>(bp_node);
        sub_graph->SetChildren(bp_nodes, true);
    }

    std::vector<bp::NodePtr> front_nodes(children.size(), nullptr);
    std::vector<std::shared_ptr<dag::Node<shadergraph::Variant>>> back_nodes(children.size(), nullptr);

    bp::SerializeHelper::SetupNodes<shaderlab::Node, shadergraph::Variant>(
        children, "shaderlab", "shadergraph", front_nodes, back_nodes
    );
    assert(front_nodes.size() == back_nodes.size());
    for (int i = 0, n = front_nodes.size(); i < n; ++i) {
        shaderlab::ShaderAdapter::Front2Back(*front_nodes[i], *back_nodes[i], dir, dev);
    }

    bp::SerializeHelper::SetupConnections(filepath, children, front_nodes, back_nodes);

    std::vector<std::pair<size_t, ur::TexturePtr>> textures;
    auto shader = build_shader(dev, front_nodes, back_nodes, textures);

    ctx.SetFramebuffer(rt);
    ctx.SetViewport(0, 0, TEX_SIZE, TEX_SIZE);

    ur::ClearState clear;
    clear.buffers = ur::ClearBuffers::ColorAndDepthBuffer;
    clear.color.FromRGBA(0x88888888);
    ctx.Clear(clear);

    ur::DrawState ds;
    ds.program      = shader;
    ds.render_state = ur::DefaultRenderState2D();
    ds.vertex_array = dev.GetVertexArray(ur::Device::PrimitiveType::Quad, ur::VertexLayoutType::PosTex);

    for (auto& t : textures) {
        ctx.SetTexture(t.first, t.second);
    }

    ctx.Draw(ur::PrimitiveType::TriangleStrip, ds, nullptr);

    dev.ReadPixels(BUFFER, ur::TextureFormat::RGB, 0, 0, TEX_SIZE, TEX_SIZE);

    auto out_filepath = filepath.substr(0, filepath.find_last_of('.')) + ".jpg";
    gimg_export(out_filepath.c_str(), BUFFER, TEX_SIZE, TEX_SIZE, GPF_RGB, false);

    ctx.SetFramebuffer(nullptr);
}

void test_folder(const ur::Device& dev, ur::Context& ctx,
                 const std::string& dir)
{
    ur::TextureDescription desc;
    desc.target = ur::TextureTarget::Texture2D;
    desc.width  = TEX_SIZE;
    desc.height = TEX_SIZE;
    desc.format = ur::TextureFormat::RGB;
    auto tex = dev.CreateTexture(desc);

    auto fbo = dev.CreateFramebuffer();
    fbo->SetAttachment(ur::AttachmentType::Color0, ur::TextureTarget::Texture2D, tex, nullptr);

    boost::filesystem::recursive_directory_iterator itr(dir), end;
    while (itr != end)
    {
        if (boost::filesystem::is_regular(itr->path()))
        {
            auto path = itr->path().string();
            if (sx::ResFileHelper::Type(path) == sx::ResFileType::RES_FILE_JSON) {
                test_file(dev, ctx, fbo, path);
            }
        }
        ++itr;
    }
}

int main()
{
    init_gl();

    auto dev = ur::CreateDevice(ur::APIType::OpenGL);
    dev->Init();

    auto ctx = ur::CreateContext(ur::APIType::OpenGL, *dev, nullptr);

    ns::RegistCallback::Init();
    facade::Facade::Instance()->Init(*dev);
    bp::Blueprint::Instance();
    shadergraph::ShaderGraph::Instance();
    shaderlab::ShaderLab::Instance();

    BUFFER = new uint8_t[TEX_SIZE * TEX_SIZE * 4];

    // fixme: id
    auto node = std::make_shared<n0::SceneNode>();
    node->AddSharedComp<n0::CompComplex>();

    test_folder(*dev, *ctx, "../../../test/cases");

    return 0;
}<commit_msg>[FIXED] not draw if shader error<commit_after>#include <sx/ResFileHelper.h>
#include <ns/NodeFactory.h>
#include <node0/SceneNode.h>
#include <node0/CompComplex.h>
#include <unirender/Factory.h>
#include <ns/RegistCallback.h>
#include <facade/Facade.h>
#include <shadergraph/Evaluator.h>
#include <shadergraph/Block.h>
#include <shadergraph/ShaderGraph.h>
#include <shadergraph/block/FragmentShader.h>
#include <js/RapidJsonHelper.h>
#include <dag/Node.h>
#include <unirender/typedef.h>
#include <unirender/Device.h>
#include <unirender/ShaderProgram.h>
#include <unirender/TextureDescription.h>
#include <unirender/Framebuffer.h>
#include <unirender/Context.h>
#include <unirender/DrawState.h>
#include <unirender/ClearState.h>
#include <shadertrans/ShaderTrans.h>
#include <gimg_export.h>
#include <gimg_typedef.h>

#include <blueprint/Node.h>
#include <blueprint/Pin.h>
#include <blueprint/Connecting.h>
#include <blueprint/Blueprint.h>
#include <blueprint/CompNode.h>
#include <blueprint/NSCompNode.h>
#include <blueprint/SerializeHelper.h>
#include <blueprint/node/SubGraph.h>
#include <shaderlab/ShaderLab.h>
#include <shaderlab/ShaderAdapter.h>
#include <shaderlab/Evaluator.h>
#include <shaderlab/Node.h>
#include <shaderlab/node/Texture2DAsset.h>

#include <gl/glew.h>
#include <glfw3.h>

#include <boost/filesystem.hpp>

#include <stdio.h>
#include <stdlib.h>

namespace
{

const char* vs = R"(
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

void main()
{
	gl_Position = vec4(aPos, 0.0, 1.0);
	TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
)";

const int TEX_SIZE = 512;

uint8_t* BUFFER = nullptr;

}

void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}

bool init_gl()
{
	glfwSetErrorCallback(error_callback);
	if (!glfwInit()) {
		exit(EXIT_FAILURE);
		return false;
	}

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
	GLFWwindow* window = glfwCreateWindow(100, 100, "rotate-crop", nullptr, nullptr);
	if (!window)
	{
		glfwTerminate();
		return false;
	}
	glfwMakeContextCurrent(window);

	// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
	glewExperimental = GL_TRUE;
	//// Initialize GLEW to setup the OpenGL Function pointers
	//if (glewInit() != GLEW_OK) {
	//	return -1;
	//}

	return true;
}

std::shared_ptr<ur::ShaderProgram>
build_shader(const ur::Device& dev, const std::vector<bp::NodePtr>& front_nodes,
             const std::vector<std::shared_ptr<dag::Node<shadergraph::Variant>>>& back_nodes,
             std::vector<std::pair<size_t, ur::TexturePtr>>& textures)
{
    shadergraph::Evaluator eval;

    std::string fs;

    // build frag m_shader
    for (auto& back : back_nodes)
    {
        if (!back) {
            continue;
        }
        auto block = std::static_pointer_cast<shadergraph::Block>(back);
        if (block->get_type() == rttr::type::get<shadergraph::block::FragmentShader>())
        {
            eval.Rebuild(block);
            fs = eval.GenShaderCode();
            break;
        }
    }

    if (fs.empty()) {
        return nullptr;
    }

    std::vector<unsigned int> _vs, _fs;
    shadertrans::ShaderTrans::GLSL2SpirV(shadertrans::ShaderStage::VertexShader, vs, _vs);
    shadertrans::ShaderTrans::GLSL2SpirV(shadertrans::ShaderStage::PixelShader, fs, _fs);
    auto shader = dev.CreateShaderProgram(_vs, _fs);
    if (!shader || !shader->CheckStatus()) {
        return nullptr;
    }

    // textures
    assert(front_nodes.size() == back_nodes.size());
    for (int i = 0, n = front_nodes.size(); i < n; ++i)
    {
        auto& front = front_nodes[i];
        auto& back = back_nodes[i];
        if (front->get_type() != rttr::type::get<shaderlab::node::Texture2DAsset>()) {
            continue;
        }

        auto tex = std::static_pointer_cast<shaderlab::node::Texture2DAsset>(front)->GetTexture();
        if (!tex) {
            continue;
        }

        assert(back);
        auto block = std::static_pointer_cast<shadergraph::Block>(back);
        auto name = eval.QueryRealName(&block->GetExports()[0].var.type);

        auto slot = shader->QueryTexSlot(name);
        if (slot >= 0) {
            textures.push_back({ slot, tex });
        }
    }

    // update uniforms
    shaderlab::Evaluator::UpdateUniforms(eval, shader);

    return shader;
}

void test_file(const ur::Device& dev, ur::Context& ctx,
               const std::shared_ptr<ur::Framebuffer>& rt,
               const std::string& filepath)
{
    auto dir = boost::filesystem::path(filepath).parent_path().string();

    auto root = ns::NodeFactory::Create(dev, filepath);

    auto& ccomplex = root->GetSharedComp<n0::CompComplex>();
    auto& children = ccomplex.GetAllChildren();

    // update subgraph
    for (auto& c : children)
    {
        if (!c->HasUniqueComp<bp::CompNode>()) {
            continue;
        }
        auto bp_node = c->GetUniqueComp<bp::CompNode>().GetNode();
        if (!bp_node->get_type().is_derived_from<bp::node::SubGraph<shadergraph::Variant>>()) {
            continue;
        }
        assert(c->HasSharedComp<n0::CompComplex>());
        auto& c_ccomplex = c->GetSharedComp<n0::CompComplex>();
        std::vector<bp::NodePtr> bp_nodes;
        for (auto& cc : c_ccomplex.GetAllChildren()) {
            if (cc->HasUniqueComp<bp::CompNode>()) {
                bp_nodes.push_back(cc->GetUniqueComp<bp::CompNode>().GetNode());
            }
        }
        auto sub_graph = std::static_pointer_cast<bp::node::SubGraph<shadergraph::Variant>>(bp_node);
        sub_graph->SetChildren(bp_nodes, true);
    }

    std::vector<bp::NodePtr> front_nodes(children.size(), nullptr);
    std::vector<std::shared_ptr<dag::Node<shadergraph::Variant>>> back_nodes(children.size(), nullptr);

    bp::SerializeHelper::SetupNodes<shaderlab::Node, shadergraph::Variant>(
        children, "shaderlab", "shadergraph", front_nodes, back_nodes
    );
    assert(front_nodes.size() == back_nodes.size());
    for (int i = 0, n = front_nodes.size(); i < n; ++i) {
        shaderlab::ShaderAdapter::Front2Back(*front_nodes[i], *back_nodes[i], dir, dev);
    }

    bp::SerializeHelper::SetupConnections(filepath, children, front_nodes, back_nodes);

    ctx.SetFramebuffer(rt);
    ctx.SetViewport(0, 0, TEX_SIZE, TEX_SIZE);

    ur::ClearState clear;
    clear.buffers = ur::ClearBuffers::ColorAndDepthBuffer;
    clear.color.FromRGBA(0x88888888);
    ctx.Clear(clear);

    std::vector<std::pair<size_t, ur::TexturePtr>> textures;
    auto shader = build_shader(dev, front_nodes, back_nodes, textures);
    if (shader)
    {
        ur::DrawState ds;
        ds.program = shader;
        ds.render_state = ur::DefaultRenderState2D();
        ds.vertex_array = dev.GetVertexArray(ur::Device::PrimitiveType::Quad, ur::VertexLayoutType::PosTex);

        for (auto& t : textures) {
            ctx.SetTexture(t.first, t.second);
        }

        ctx.Draw(ur::PrimitiveType::TriangleStrip, ds, nullptr);
    }

    dev.ReadPixels(BUFFER, ur::TextureFormat::RGB, 0, 0, TEX_SIZE, TEX_SIZE);

    auto out_filepath = filepath.substr(0, filepath.find_last_of('.')) + ".jpg";
    gimg_export(out_filepath.c_str(), BUFFER, TEX_SIZE, TEX_SIZE, GPF_RGB, false);

    ctx.SetFramebuffer(nullptr);
}

void test_folder(const ur::Device& dev, ur::Context& ctx,
                 const std::string& dir)
{
    ur::TextureDescription desc;
    desc.target = ur::TextureTarget::Texture2D;
    desc.width  = TEX_SIZE;
    desc.height = TEX_SIZE;
    desc.format = ur::TextureFormat::RGB;
    auto tex = dev.CreateTexture(desc);

    auto fbo = dev.CreateFramebuffer();
    fbo->SetAttachment(ur::AttachmentType::Color0, ur::TextureTarget::Texture2D, tex, nullptr);

    boost::filesystem::recursive_directory_iterator itr(dir), end;
    while (itr != end)
    {
        if (boost::filesystem::is_regular(itr->path()))
        {
            auto path = itr->path().string();
            if (sx::ResFileHelper::Type(path) == sx::ResFileType::RES_FILE_JSON) {
                test_file(dev, ctx, fbo, path);
            }
        }
        ++itr;
    }
}

int main()
{
    init_gl();

    auto dev = ur::CreateDevice(ur::APIType::OpenGL);
    dev->Init();

    auto ctx = ur::CreateContext(ur::APIType::OpenGL, *dev, nullptr);

    ns::RegistCallback::Init();
    facade::Facade::Instance()->Init(*dev);
    bp::Blueprint::Instance();
    shadergraph::ShaderGraph::Instance();
    shaderlab::ShaderLab::Instance();

    BUFFER = new uint8_t[TEX_SIZE * TEX_SIZE * 4];

    // fixme: id
    auto node = std::make_shared<n0::SceneNode>();
    node->AddSharedComp<n0::CompComplex>();

    test_folder(*dev, *ctx, "../../../test/cases");

    return 0;
}<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// 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.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <iostream>
#include <Context.h>
#include <Filter.h>
#include <util.h>
#include <text.h>
#include <i18n.h>
#include <main.h>
#include <CmdPrepend.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
CmdPrepend::CmdPrepend ()
{
  _keyword     = "prepend";
  _usage       = "task <filter> prepend <mods>";
  _description = STRING_CMD_PREPEND_USAGE;
  _read_only   = false;
  _displays_id = false;
}

////////////////////////////////////////////////////////////////////////////////
int CmdPrepend::execute (std::string& output)
{
  int rc = 0;
  int count = 0;

  // Apply filter.
  Filter filter;
  std::vector <Task> filtered;
  filter.subset (filtered);
  if (filtered.size () == 0)
  {
    context.footnote (STRING_FEEDBACK_NO_TASKS_SP);
    return 1;
  }

  // TODO Complain when no modifications are specified.

  // Accumulated project change notifications.
  std::map <std::string, std::string> projectChanges;

  std::vector <Task>::iterator task;
  for (task = filtered.begin (); task != filtered.end (); ++task)
  {
    Task before (*task);

    // Prepend to the specified task.
    std::string question = format (STRING_CMD_PREPEND_CONFIRM,
                                   task->id,
                                   task->get ("description"));

    task->modify (Task::modPrepend, true);

    if (permission (*task, taskDifferences (before, *task) + question, filtered.size ()))
    {
      context.tdb2.modify (*task);
      ++count;
      feedback_affected (STRING_CMD_PREPEND_TASK, *task);
      if (context.verbose ("project"))
        projectChanges[task->get ("project")] = onProjectChange (*task, false);

      // Prepend to siblings.
      if (task->has ("parent"))
      {
        if (confirm (STRING_CMD_PREPEND_CONFIRM_R))
        {
          std::vector <Task> siblings = context.tdb2.siblings (*task);
          std::vector <Task>::iterator sibling;
          for (sibling = siblings.begin (); sibling != siblings.end (); ++sibling)
          {
            sibling->modify (Task::modPrepend, true);
            context.tdb2.modify (*sibling);
            ++count;
            feedback_affected (STRING_CMD_PREPEND_TASK_R, *sibling);
          }

          // Prepend to the parent
          Task parent;
          context.tdb2.get (task->get ("parent"), parent);
          parent.modify (Task::modPrepend, true);
          context.tdb2.modify (parent);
        }
      }
    }
    else
    {
      std::cout << STRING_CMD_PREPEND_NO << "\n";
      rc = 1;
      if (_permission_quit)
        break;
    }
  }

  // Now list the project changes.
  std::map <std::string, std::string>::iterator i;
  for (i = projectChanges.begin (); i != projectChanges.end (); ++i)
    if (i->first != "")
      context.footnote (i->second);

  context.tdb2.commit ();
  feedback_affected (count == 1 ? STRING_CMD_PREPEND_1 : STRING_CMD_PREPEND_N, count);
  return rc;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>CmdPrepend<commit_after>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// 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.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <iostream>
#include <Context.h>
#include <Filter.h>
#include <util.h>
#include <text.h>
#include <i18n.h>
#include <main.h>
#include <CmdPrepend.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
CmdPrepend::CmdPrepend ()
{
  _keyword     = "prepend";
  _usage       = "task <filter> prepend <mods>";
  _description = STRING_CMD_PREPEND_USAGE;
  _read_only   = false;
  _displays_id = false;
}

////////////////////////////////////////////////////////////////////////////////
int CmdPrepend::execute (std::string& output)
{
  int rc = 0;
  int count = 0;

  // Apply filter.
  Filter filter;
  std::vector <Task> filtered;
  filter.subset (filtered);
  if (filtered.size () == 0)
  {
    context.footnote (STRING_FEEDBACK_NO_TASKS_SP);
    return 1;
  }

  // TODO Complain when no modifications are specified.

  // Accumulated project change notifications.
  std::map <std::string, std::string> projectChanges;

  std::vector <Task>::iterator task;
  for (task = filtered.begin (); task != filtered.end (); ++task)
  {
    Task before (*task);

    // Prepend to the specified task.
    std::string question = format (STRING_CMD_PREPEND_CONFIRM,
                                   task->id,
                                   task->get ("description"));

    task->modify (Task::modPrepend, true);

    if (permission (*task, taskDifferences (before, *task) + question, filtered.size ()))
    {
      context.tdb2.modify (*task);
      ++count;
      feedback_affected (STRING_CMD_PREPEND_TASK, *task);
      if (context.verbose ("project"))
        projectChanges[task->get ("project")] = onProjectChange (*task, false);

      // Prepend to siblings.
      if (task->has ("parent"))
      {
        if (confirm (STRING_CMD_PREPEND_CONFIRM_R))
        {
          std::vector <Task> siblings = context.tdb2.siblings (*task);
          std::vector <Task>::iterator sibling;
          for (sibling = siblings.begin (); sibling != siblings.end (); ++sibling)
          {
            sibling->modify (Task::modPrepend, true);
            context.tdb2.modify (*sibling);
            ++count;
            feedback_affected (STRING_CMD_PREPEND_TASK_R, *sibling);
          }

          // Prepend to the parent
          Task parent;
          context.tdb2.get (task->get ("parent"), parent);
          parent.modify (Task::modPrepend, true);
          context.tdb2.modify (parent);
        }
      }
    }
    else
    {
      std::cout << STRING_CMD_PREPEND_NO << "\n";
      rc = 1;
      if (_permission_quit)
        break;
    }
  }

  // Now list the project changes.
  std::map <std::string, std::string>::iterator i;
  for (i = projectChanges.begin (); i != projectChanges.end (); ++i)
    if (i->first != "")
      context.footnote (i->second);

  feedback_affected (count == 1 ? STRING_CMD_PREPEND_1 : STRING_CMD_PREPEND_N, count);
  return rc;
}

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


<commit_before>/**
 * @file
 * @brief Dynamic memory management
 * @date 04.07.12
 * @author Ilia Vaprol
 */

#include <new>

#if defined(__EXCEPTIONS) && __EXCEPTIONS==1
#error Exceptions must be disabled
#endif

const std::nothrow_t std::nothrow = { };

static std::new_handler __new_handler = 0;

std::new_handler std::set_new_handler(std::new_handler handler) throw() {
	std::new_handler prev_handler = __new_handler;
	__new_handler = handler;
	return prev_handler;
}

#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
#endif
#endif
// Implementation of new and delete operators for single object
void* operator new(std::size_t size) throw(std::bad_alloc) {
	void *ptr;

	if (size == 0) { /* std::malloc(0) is not predictable */
		size = 1;
	}

	if ((ptr = std::malloc(size)) == 0) {
		std::new_handler handler = __new_handler;
		if (handler == 0) {
		/*
			Cannot throw: exceptions are disabled
			throw std::bad_alloc();
		*/
		} else {
			handler();
		}
	}

	return ptr;
}
#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic pop
#endif
#endif

void* operator new(std::size_t size, const std::nothrow_t& nothrow_const) throw() {
	void *ptr;

	if (size == 0) { /* std::malloc(0) is not predictable */
		size = 1;
	}

	if ((ptr = std::malloc(size)) == 0) {
		std::new_handler handler = __new_handler;
		if (handler == 0) {
			return 0;
		}
		/*
		Cannot use: no exceptions
		try {
			handler();
		}
		catch (const std::bad_alloc&) {
			return 0;
		}
		*/
		handler();
	}

	return ptr;
}

void operator delete(void* ptr) throw() {
	std::free(ptr);
}

void operator delete(void* ptr, unsigned int i) throw() {
	/* XXX */
	std::free(ptr);
}

void operator delete(void* ptr, const std::nothrow_t& nothrow_const) throw() {
	::operator delete(ptr);
}

void operator delete[](void* ptr, unsigned int) throw() {
	/* XXX */
	::operator delete(ptr);
}
#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
#endif
#endif
// Forwarding functions for array of objects
void* operator new[](std::size_t size) throw(std::bad_alloc) {
	return ::operator new(size);
}
#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic pop
#endif
#endif
void* operator new[](std::size_t size, const std::nothrow_t& nothrow_const) throw() {
	return ::operator new(size, nothrow_const);
}

void operator delete[](void* ptr) throw() {
	::operator delete(ptr);
}

void operator delete[](void* ptr, const std::nothrow_t& nothrow_const) throw() {
	::operator delete(ptr, nothrow_const);
}

<commit_msg>compat: cxx: Refactoring <new><commit_after>/**
 * @file
 * @brief Dynamic memory management
 * @date 04.07.12
 * @author Ilia Vaprol
 */

#include <new>

#if defined(__EXCEPTIONS) && __EXCEPTIONS==1
#error Exceptions must be disabled
#endif

const std::nothrow_t std::nothrow = { };

static std::new_handler alloc_failure_handler = 0;

std::new_handler std::set_new_handler(std::new_handler handler) throw() {
	std::new_handler prev_handler = alloc_failure_handler;
	alloc_failure_handler = handler;
	return prev_handler;
}

#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
#endif
#endif
// Implementation of new and delete operators for single object
void* operator new(std::size_t size)  throw() {
	void *ptr = NULL;

	if ((ptr = std::malloc(size)) == 0) {
		if (alloc_failure_handler) {
			alloc_failure_handler();
		}
	}

	return ptr;
}
#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic pop
#endif
#endif

void* operator new(std::size_t size, const std::nothrow_t& nothrow_const) throw() {
	void *ptr = NULL;

	if ((ptr = std::malloc(size)) == 0) {
		if (alloc_failure_handler) {
			alloc_failure_handler();
		}
	}

	return ptr;
}

void operator delete(void* ptr) throw() {
	std::free(ptr);
}

void operator delete(void* ptr, unsigned int i) throw() {
	/* XXX */
	std::free(ptr);
}

void operator delete(void* ptr, const std::nothrow_t& nothrow_const) throw() {
	::operator delete(ptr);
}

void operator delete[](void* ptr, unsigned int) throw() {
	/* XXX */
	::operator delete(ptr);
}
#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
#endif
#endif
// Forwarding functions for array of objects
void* operator new[](std::size_t size) throw() {
	return ::operator new(size);
}
#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic pop
#endif
#endif
void* operator new[](std::size_t size, const std::nothrow_t& nothrow_const) throw() {
	return ::operator new(size, nothrow_const);
}

void operator delete[](void* ptr) throw() {
	::operator delete(ptr);
}

void operator delete[](void* ptr, const std::nothrow_t& nothrow_const) throw() {
	::operator delete(ptr, nothrow_const);
}

<|endoftext|>