<commit_before>#include "common.h"

#include "hex/basics/hexgrid.h"
#include "hex/game/game.h"
#include "hex/game/movement/movement.h"
#include "hex/game/movement/pathfinding.h"

Pathfinder::Pathfinder(Level *level, MovementModel *movement): level(level), movement(movement) {
    nodes.resize(level->width, level->height);

    clear();
}

Pathfinder::~Pathfinder() {
}

void Pathfinder::clear() {
    for (int i = 0; i < level->height; i++)
        for (int j = 0; j < level->width; j++) {
            nodes[i][j].cost = INT_MAX;
            nodes[i][j].heuristic = INT_MIN;
            nodes[i][j].state = 0;
        }

    queue.clear();
    state = CLEAR;
}

void Pathfinder::start(const UnitStack& party, const Point start_point, const Point target_point) {
    this->party = party.shared_from_this();

    source.point = start_point.constrain(0, 0, nodes.width - 1, nodes.height - 1);
    source.node = &nodes[source.point];
    source.node->cost = 0;
    source.node->predecessor = source.point;

    target.point = target_point.constrain(0, 0, nodes.width - 1, nodes.height - 1);
    target.node = &nodes[target.point];

    source.node->state = 1;
    source.node->heuristic = heuristic(source, target);
    source.score = source.node->cost + source.node->heuristic;
    queue.push(source);
    path_head = source;
    state = RUNNING;
}

void Pathfinder::get_neighbours(const PathfinderQueueEntry& entry, PathfinderQueueEntry neighbours[]) {
    Point neighbour_points[6];
    ::get_neighbours(entry.point, neighbour_points);
    for (int i = 0; i < 6; i++) {
        if (nodes.contains(neighbour_points[i])) {
            neighbours[i].point = neighbour_points[i];
            neighbours[i].node = &nodes[neighbour_points[i]];
        } else {
            neighbours[i].node = 0;
        }
    }
}

int Pathfinder::cost_between(const PathfinderQueueEntry& entry1, const PathfinderQueueEntry& entry2) {
    int cost = movement->cost_to(*party, entry2.point);
    return cost;
}

int Pathfinder::heuristic(const PathfinderQueueEntry& entry1, const PathfinderQueueEntry& entry2) {
    return distance_between(entry1.point, entry2.point);
}

void Pathfinder::step() {
    if (queue.empty()) {
        state = FINISHED;
        return;
    }

    PathfinderQueueEntry next_node = queue.top();
    queue.pop();

    if (next_node.node->heuristic < path_head.node->heuristic) {
        path_head = next_node;
    }

    if (next_node.point == target.point) {
        state = FINISHED;
        return;
    }

    next_node.node->state = 2;
    PathfinderQueueEntry neighbours[6];
    get_neighbours(next_node, neighbours);

    int offset = next_node.point.x ^ next_node.point.y; // randomise the order we examine neighbours in, for variety

    for (int i = 0; i < 6; i++) {
        PathfinderQueueEntry &neighbour = neighbours[(i + offset) % 6];
        if (neighbour.node == NULL)
            continue;
        if (neighbour.node->state == 2)
            continue;
        int step_cost = cost_between(next_node, neighbour);
        int new_cost = next_node.node->cost + step_cost;
        if (new_cost < neighbour.node->cost && step_cost < INT_MAX) {
            neighbour.node->cost = new_cost;
            neighbour.node->predecessor = next_node.point;
            if (neighbour.node->state == 0) {
                neighbour.node->heuristic = heuristic(neighbour, target);
            }
            neighbour.node->state = 1;
            neighbour.score = neighbour.node->cost + neighbour.node->heuristic;
            queue.push(neighbour);
        }
    }
}

void Pathfinder::complete() {
    while (state == RUNNING) {
        step();
    }
}

void Pathfinder::build_path(Path& path) {
    path.clear();

    PathfinderNode *node = path_head.node;
    Point point = path_head.point;
    while (true) {
        Point pred = node->predecessor;

        if (point == pred)
            break;

        path.push_back(point);

        node = &nodes[pred];
        point = pred;
    }

    std::reverse(path.begin(), path.end());
}
<commit_msg>Fix bug with heuristic not being scaled by per-tile movement costs; now we just use the cost to move into the current tile.<commit_after>#include "common.h"

#include "hex/basics/hexgrid.h"
#include "hex/game/game.h"
#include "hex/game/movement/movement.h"
#include "hex/game/movement/pathfinding.h"

Pathfinder::Pathfinder(Level *level, MovementModel *movement): level(level), movement(movement) {
    nodes.resize(level->width, level->height);

    clear();
}

Pathfinder::~Pathfinder() {
}

void Pathfinder::clear() {
    for (int i = 0; i < level->height; i++)
        for (int j = 0; j < level->width; j++) {
            nodes[i][j].cost = INT_MAX;
            nodes[i][j].heuristic = INT_MIN;
            nodes[i][j].state = 0;
        }

    queue.clear();
    state = CLEAR;
}

void Pathfinder::start(const UnitStack& party, const Point start_point, const Point target_point) {
    this->party = party.shared_from_this();

    source.point = start_point.constrain(0, 0, nodes.width - 1, nodes.height - 1);
    source.node = &nodes[source.point];
    source.node->cost = 0;
    source.node->predecessor = source.point;

    target.point = target_point.constrain(0, 0, nodes.width - 1, nodes.height - 1);
    target.node = &nodes[target.point];

    source.node->state = 1;
    source.node->heuristic = heuristic(source, target);
    source.score = source.node->cost + source.node->heuristic;
    queue.push(source);
    path_head = source;
    state = RUNNING;
}

void Pathfinder::get_neighbours(const PathfinderQueueEntry& entry, PathfinderQueueEntry neighbours[]) {
    Point neighbour_points[6];
    ::get_neighbours(entry.point, neighbour_points);
    for (int i = 0; i < 6; i++) {
        if (nodes.contains(neighbour_points[i])) {
            neighbours[i].point = neighbour_points[i];
            neighbours[i].node = &nodes[neighbour_points[i]];
        } else {
            neighbours[i].node = 0;
        }
    }
}

int Pathfinder::cost_between(const PathfinderQueueEntry& entry1, const PathfinderQueueEntry& entry2) {
    int cost = movement->cost_to(*party, entry2.point);
    return cost;
}

int Pathfinder::heuristic(const PathfinderQueueEntry& entry1, const PathfinderQueueEntry& entry2) {
    return distance_between(entry1.point, entry2.point) * movement->cost_to(*party, entry1.point);
}

void Pathfinder::step() {
    if (queue.empty()) {
        state = FINISHED;
        return;
    }

    PathfinderQueueEntry next_node = queue.top();
    queue.pop();

    if (next_node.node->heuristic < path_head.node->heuristic) {
        path_head = next_node;
    }

    if (next_node.point == target.point) {
        state = FINISHED;
        return;
    }

    next_node.node->state = 2;
    PathfinderQueueEntry neighbours[6];
    get_neighbours(next_node, neighbours);

    int offset = next_node.point.x ^ next_node.point.y; // randomise the order we examine neighbours in, for variety

    for (int i = 0; i < 6; i++) {
        PathfinderQueueEntry &neighbour = neighbours[(i + offset) % 6];
        if (neighbour.node == NULL)
            continue;
        if (neighbour.node->state == 2)
            continue;
        int step_cost = cost_between(next_node, neighbour);
        int new_cost = next_node.node->cost + step_cost;
        if (new_cost < neighbour.node->cost && step_cost < INT_MAX) {
            neighbour.node->cost = new_cost;
            neighbour.node->predecessor = next_node.point;
            if (neighbour.node->state == 0) {
                neighbour.node->heuristic = heuristic(neighbour, target);
            }
            neighbour.node->state = 1;
            neighbour.score = neighbour.node->cost + neighbour.node->heuristic;
            queue.push(neighbour);
        }
    }
}

void Pathfinder::complete() {
    while (state == RUNNING) {
        step();
    }
}

void Pathfinder::build_path(Path& path) {
    path.clear();

    PathfinderNode *node = path_head.node;
    Point point = path_head.point;
    while (true) {
        Point pred = node->predecessor;

        if (point == pred)
            break;

        path.push_back(point);

        node = &nodes[pred];
        point = pred;
    }

    std::reverse(path.begin(), path.end());
}
<|endoftext|>


<commit_before>
#include <cstdio>
#include <gtest/gtest.h>

using namespace std;
using namespace testing;

extern "C" {
   #include <exos/sort.h>
}

static int less_than_cmp_int(const void *a, const void *b)
{
   const int *a_val = (const int *)a;
   const int *b_val = (const int *)b;

   if (a < b)
      return -1;

   if (a == b)
      return 0;

   return 1;
}

static bool my_is_sorted(uptr *arr, int len, cmpfun_ptr cmp)
{
   if (len <= 1)
      return true;

   for (int i = 0; i < len - 1; i++)
      if (cmp(&arr[i], &arr[i+1]) > 0)
         return false;

   return true;
}

TEST(insertion_sort_ptr, basic_test)
{
   int vec[] = { 3, 4, 1, 0, -3, 10, 2 };

   insertion_sort_ptr((uptr *)&vec, ARRAY_SIZE(vec), less_than_cmp_int);
   ASSERT_TRUE(my_is_sorted((uptr *)vec, ARRAY_SIZE(vec), less_than_cmp_int));
}

TEST(insertion_sort_generic, basic_test)
{
   int vec[] = { 3, 4, 1, 0, -3, 10, 2 };

   insertion_sort_generic((uptr *)&vec, sizeof(int),
                          ARRAY_SIZE(vec), less_than_cmp_int);
   ASSERT_TRUE(my_is_sorted((uptr *)vec, ARRAY_SIZE(vec), less_than_cmp_int));
}
<commit_msg>[gtests] Fix a bug in sort_test.cpp [use 'int', which is not ptr-sized]<commit_after>
#include <cstdio>
#include <gtest/gtest.h>

using namespace std;
using namespace testing;

extern "C" {
   #include <exos/sort.h>
}

static int less_than_cmp_int(const void *a, const void *b)
{
   const sptr *a_val = (const sptr *)a;
   const sptr *b_val = (const sptr *)b;

   if (a < b)
      return -1;

   if (a == b)
      return 0;

   return 1;
}

static bool my_is_sorted(uptr *arr, int len, cmpfun_ptr cmp)
{
   if (len <= 1)
      return true;

   for (int i = 0; i < len - 1; i++)
      if (cmp(&arr[i], &arr[i+1]) > 0)
         return false;

   return true;
}

TEST(insertion_sort_ptr, basic_test)
{
   sptr vec[] = { 3, 4, 1, 0, -3, 10, 2 };

   insertion_sort_ptr((uptr *)&vec, ARRAY_SIZE(vec), less_than_cmp_int);
   ASSERT_TRUE(my_is_sorted((uptr *)vec, ARRAY_SIZE(vec), less_than_cmp_int));
}

TEST(insertion_sort_generic, basic_test)
{
   sptr vec[] = { 3, 4, 1, 0, -3, 10, 2 };

   insertion_sort_generic((uptr *)&vec, sizeof(sptr),
                          ARRAY_SIZE(vec), less_than_cmp_int);
   ASSERT_TRUE(my_is_sorted((uptr *)vec, ARRAY_SIZE(vec), less_than_cmp_int));
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Andrei Pangin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <fstream>
#include <sstream>
#include <errno.h>
#include <string.h>
#include "javaApi.h"
#include "arguments.h"
#include "os.h"
#include "profiler.h"
#include "vmStructs.h"

extern "C" JNIEXPORT void JNICALL
Java_one_profiler_AsyncProfiler_start0(JNIEnv* env, jobject unused, jstring event, jlong interval, jboolean reset) {
    Arguments args;
    args._event = env->GetStringUTFChars(event, NULL);
    args._interval = interval;
    Error error = Profiler::_instance.start(args, reset);
    env->ReleaseStringUTFChars(event, args._event);

    if (error) {
        JavaAPI::throwNew(env, "java/lang/IllegalStateException", error.message());
    }
}

extern "C" JNIEXPORT void JNICALL
Java_one_profiler_AsyncProfiler_stop0(JNIEnv* env, jobject unused) {
    Error error = Profiler::_instance.stop();

    if (error) {
        JavaAPI::throwNew(env, "java/lang/IllegalStateException", error.message());
    }
}

extern "C" JNIEXPORT jstring JNICALL
Java_one_profiler_AsyncProfiler_execute0(JNIEnv* env, jobject unused, jstring command) {
    Arguments args;
    const char* command_str = env->GetStringUTFChars(command, NULL);
    Error error = args.parse(command_str);
    env->ReleaseStringUTFChars(command, command_str);

    if (error) {
        JavaAPI::throwNew(env, "java/lang/IllegalArgumentException", error.message());
        return NULL;
    }

    if (args._file == NULL || args._output == OUTPUT_JFR) {
        std::ostringstream out;
        Profiler::_instance.runInternal(args, out);
        return env->NewStringUTF(out.str().c_str());
    } else {
        std::ofstream out(args._file, std::ios::out | std::ios::trunc);
        if (out.is_open()) {
            Profiler::_instance.runInternal(args, out);
            out.close();
            return env->NewStringUTF("OK");
        } else {
            JavaAPI::throwNew(env, "java/io/IOException", strerror(errno));
            return NULL;
        }
    }
}

extern "C" JNIEXPORT jlong JNICALL
Java_one_profiler_AsyncProfiler_getSamples(JNIEnv* env, jobject unused) {
    return (jlong)Profiler::_instance.total_samples();
}

extern "C" JNIEXPORT void JNICALL
Java_one_profiler_AsyncProfiler_filterThread0(JNIEnv* env, jobject unused, jthread thread, jboolean enable) {
    int thread_id;
    if (thread == NULL) {
        thread_id = OS::threadId();
    } else if (VMThread::hasNativeId()) {
        VMThread* vmThread = VMThread::fromJavaThread(env, thread);
        if (vmThread == NULL) {
            return;
        }
        thread_id = vmThread->osThreadId();
    } else {
        return;
    }

    ThreadFilter* thread_filter = Profiler::_instance.threadFilter();
    if (enable) {
        thread_filter->add(thread_id);
    } else {
        thread_filter->remove(thread_id);
    }
}

#define F(name, sig)  {(char*)#name, (char*)sig, (void*)Java_one_profiler_AsyncProfiler_##name}

static const JNINativeMethod profiler_natives[] = {
    F(start0,            "(Ljava/lang/String;JZ)V"),
    F(stop0,             "()V"),
    F(execute0,          "(Ljava/lang/String;)Ljava/lang/String;"),
    F(getSamples,        "()J"),
    F(filterThread0,     "(Ljava/lang/Thread;Z)V"),
};

#undef F

void JavaAPI::throwNew(JNIEnv* env, const char* exception_class, const char* message) {
    jclass cls = env->FindClass(exception_class);
    if (cls != NULL) {
        env->ThrowNew(cls, message);
    }
}

// Since AsyncProfiler class can be renamed or moved to another package (shaded),
// we look for the actual class in the stack trace.
void JavaAPI::registerNatives(jvmtiEnv* jvmti, JNIEnv* jni) {
    jvmtiFrameInfo frame[10];
    jint frame_count;
    if (jvmti->GetStackTrace(NULL, 0, sizeof(frame) / sizeof(frame[0]), frame, &frame_count) != 0) {
        return;
    }

    jclass System = jni->FindClass("java/lang/System");
    jmethodID load = jni->GetStaticMethodID(System, "load", "(Ljava/lang/String;)V");
    jmethodID loadLibrary = jni->GetStaticMethodID(System, "loadLibrary", "(Ljava/lang/String;)V");

    // Look for System.load() or System.loadLibrary() method in the stack trace.
    // The next frame will belong to AsyncProfiler class.
    for (int i = 0; i < frame_count - 1; i++) {
        if (frame[i].method == load || frame[i].method == loadLibrary) {
            jclass profiler_class;
            if (jvmti->GetMethodDeclaringClass(frame[i + 1].method, &profiler_class) == 0) {
                jni->RegisterNatives(profiler_class, profiler_natives, sizeof(profiler_natives) / sizeof(JNINativeMethod));
            }
            break;
        }
    }

    jni->ExceptionClear();
}
<commit_msg>Register natives one-by-one to support partial Java API implementations (#337)<commit_after>/*
 * Copyright 2016 Andrei Pangin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <fstream>
#include <sstream>
#include <errno.h>
#include <string.h>
#include "javaApi.h"
#include "arguments.h"
#include "os.h"
#include "profiler.h"
#include "vmStructs.h"

extern "C" JNIEXPORT void JNICALL
Java_one_profiler_AsyncProfiler_start0(JNIEnv* env, jobject unused, jstring event, jlong interval, jboolean reset) {
    Arguments args;
    args._event = env->GetStringUTFChars(event, NULL);
    args._interval = interval;
    Error error = Profiler::_instance.start(args, reset);
    env->ReleaseStringUTFChars(event, args._event);

    if (error) {
        JavaAPI::throwNew(env, "java/lang/IllegalStateException", error.message());
    }
}

extern "C" JNIEXPORT void JNICALL
Java_one_profiler_AsyncProfiler_stop0(JNIEnv* env, jobject unused) {
    Error error = Profiler::_instance.stop();

    if (error) {
        JavaAPI::throwNew(env, "java/lang/IllegalStateException", error.message());
    }
}

extern "C" JNIEXPORT jstring JNICALL
Java_one_profiler_AsyncProfiler_execute0(JNIEnv* env, jobject unused, jstring command) {
    Arguments args;
    const char* command_str = env->GetStringUTFChars(command, NULL);
    Error error = args.parse(command_str);
    env->ReleaseStringUTFChars(command, command_str);

    if (error) {
        JavaAPI::throwNew(env, "java/lang/IllegalArgumentException", error.message());
        return NULL;
    }

    if (args._file == NULL || args._output == OUTPUT_JFR) {
        std::ostringstream out;
        Profiler::_instance.runInternal(args, out);
        return env->NewStringUTF(out.str().c_str());
    } else {
        std::ofstream out(args._file, std::ios::out | std::ios::trunc);
        if (out.is_open()) {
            Profiler::_instance.runInternal(args, out);
            out.close();
            return env->NewStringUTF("OK");
        } else {
            JavaAPI::throwNew(env, "java/io/IOException", strerror(errno));
            return NULL;
        }
    }
}

extern "C" JNIEXPORT jlong JNICALL
Java_one_profiler_AsyncProfiler_getSamples(JNIEnv* env, jobject unused) {
    return (jlong)Profiler::_instance.total_samples();
}

extern "C" JNIEXPORT void JNICALL
Java_one_profiler_AsyncProfiler_filterThread0(JNIEnv* env, jobject unused, jthread thread, jboolean enable) {
    int thread_id;
    if (thread == NULL) {
        thread_id = OS::threadId();
    } else if (VMThread::hasNativeId()) {
        VMThread* vmThread = VMThread::fromJavaThread(env, thread);
        if (vmThread == NULL) {
            return;
        }
        thread_id = vmThread->osThreadId();
    } else {
        return;
    }

    ThreadFilter* thread_filter = Profiler::_instance.threadFilter();
    if (enable) {
        thread_filter->add(thread_id);
    } else {
        thread_filter->remove(thread_id);
    }
}

#define F(name, sig)  {(char*)#name, (char*)sig, (void*)Java_one_profiler_AsyncProfiler_##name}

static const JNINativeMethod profiler_natives[] = {
    F(start0,            "(Ljava/lang/String;JZ)V"),
    F(stop0,             "()V"),
    F(execute0,          "(Ljava/lang/String;)Ljava/lang/String;"),
    F(getSamples,        "()J"),
    F(filterThread0,     "(Ljava/lang/Thread;Z)V"),
};

#undef F

void JavaAPI::throwNew(JNIEnv* env, const char* exception_class, const char* message) {
    jclass cls = env->FindClass(exception_class);
    if (cls != NULL) {
        env->ThrowNew(cls, message);
    }
}

// Since AsyncProfiler class can be renamed or moved to another package (shaded),
// we look for the actual class in the stack trace.
void JavaAPI::registerNatives(jvmtiEnv* jvmti, JNIEnv* jni) {
    jvmtiFrameInfo frame[10];
    jint frame_count;
    if (jvmti->GetStackTrace(NULL, 0, sizeof(frame) / sizeof(frame[0]), frame, &frame_count) != 0) {
        return;
    }

    jclass System = jni->FindClass("java/lang/System");
    jmethodID load = jni->GetStaticMethodID(System, "load", "(Ljava/lang/String;)V");
    jmethodID loadLibrary = jni->GetStaticMethodID(System, "loadLibrary", "(Ljava/lang/String;)V");

    // Look for System.load() or System.loadLibrary() method in the stack trace.
    // The next frame will belong to AsyncProfiler class.
    for (int i = 0; i < frame_count - 1; i++) {
        if (frame[i].method == load || frame[i].method == loadLibrary) {
            jclass profiler_class;
            if (jvmti->GetMethodDeclaringClass(frame[i + 1].method, &profiler_class) == 0) {
                for (int j = 0; j < sizeof(profiler_natives) / sizeof(JNINativeMethod); j++) {
                    jni->RegisterNatives(profiler_class, &profiler_natives[j], 1);
                }
            }
            break;
        }
    }

    jni->ExceptionClear();
}
<|endoftext|>


<commit_before>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2010 Nokia Corporation
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/FixedFeatureFactory>

#include <TelepathyQt4/Feature>

namespace Tp
{

struct FixedFeatureFactory::Private
{
    Features features;
};

FixedFeatureFactory::FixedFeatureFactory(const QDBusConnection &bus)
    : DBusProxyFactory(bus), mPriv(new Private)
{
}

FixedFeatureFactory::~FixedFeatureFactory()
{
    delete mPriv;
}

Features FixedFeatureFactory::features() const
{
    return mPriv->features;
}

void FixedFeatureFactory::addFeature(const Feature &feature)
{
    addFeatures(Features(feature));
}

void FixedFeatureFactory::addFeatures(const Features &features)
{
    mPriv->features.unite(features);
}

Features FixedFeatureFactory::featuresFor(const SharedPtr<RefCounted> &proxy) const
{
    Q_UNUSED(proxy);

    return features();
}

}
<commit_msg>Doxyment FixedFeatureFactory<commit_after>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2010 Nokia Corporation
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/FixedFeatureFactory>

#include <TelepathyQt4/Feature>

namespace Tp
{

struct FixedFeatureFactory::Private
{
    Features features;
};

/**
 * \class DBusProxyFactory
 * \ingroup clientreadiness
 * \headerfile TelepathyQt4/fixed-features-factory.h <TelepathyQt4/FixedFeatureFactory>
 *
 * Base class for all D-Bus proxy factories which want the same set of features for all constructed
 * proxies.
 */

/**
 * Class constructor.
 *
 * The intention for storing the bus here is that it generally doesn't make sense to construct
 * proxies for multiple buses in the same context. Allowing that would lead to more complex keying
 * needs in the cache, as well.
 *
 * \param bus The D-Bus bus connection for the objects constructed using this factory.
 */
FixedFeatureFactory::FixedFeatureFactory(const QDBusConnection &bus)
    : DBusProxyFactory(bus), mPriv(new Private)
{
}

/**
 * Class destructor.
 */
FixedFeatureFactory::~FixedFeatureFactory()
{
    delete mPriv;
}

/**
 * Gets the features this factory will make ready on constructed proxies.
 *
 * \return The set of features.
 */
Features FixedFeatureFactory::features() const
{
    return mPriv->features;
}

/**
 * Adds a single feature this factory will make ready on further constructed proxies.
 *
 * No feature removal is provided, to guard against uncooperative modules removing features other
 * modules have set and depend on.
 *
 * \param feature The feature to add.
 */
void FixedFeatureFactory::addFeature(const Feature &feature)
{
    addFeatures(Features(feature));
}

/**
 * Adds a set of features this factory will make ready on further constructed proxies.
 *
 * No feature removal is provided, to guard against uncooperative modules removing features other
 * modules have set and depend on.
 *
 * \param features The features to add.
 */
void FixedFeatureFactory::addFeatures(const Features &features)
{
    mPriv->features.unite(features);
}

/**
 * Fixed implementation of the per-proxy feature getter.
 *
 * \return features(), irrespective of the actual \a proxy.
 */
Features FixedFeatureFactory::featuresFor(const SharedPtr<RefCounted> &proxy) const
{
    Q_UNUSED(proxy);

    return features();
}

}
<|endoftext|>


<commit_before>/*
* Copyright (C) 2017 by Godlike
* This code is licensed under the MIT license (MIT)
* (http://opensource.org/licenses/MIT)
*/

#include <unicorn/utility/Logger.hpp>
#include <unicorn/video/Texture.hpp>

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

namespace unicorn
{
namespace video
{
Texture::Texture(): m_width(0)
                  , m_height(0)
                  , m_channels(0)
                  , m_size(0)
                  , m_data(nullptr)
                  , m_initialized(false)
{
}

void Texture::Delete()
{
    if(m_data)
    {
        stbi_image_free(m_data);
        m_data = nullptr;
    }
    m_initialized = false;
}

int32_t Texture::Size() const
{
    return m_size;
}

unsigned char* Texture::Data() const
{
    return m_data;
}

int32_t Texture::Width() const
{
    return m_width;
}

int32_t Texture::Height() const
{
    return m_height;
}

const char* Texture::Path() const
{
    return m_path;
}

bool Texture::Load(const std::string& path)
{
    m_path = path.c_str();
    m_data = stbi_load(m_path, &m_width, &m_height, &m_channels, STBI_rgb_alpha);
    m_size = m_width * m_height * 4;

    if (!m_data) {
        LOG_ERROR("Failed to load texture image with path - ", m_path);
        return false;
    }
    m_initialized = true;
    return true;
}

bool Texture::IsLoaded() const
{
    return m_initialized;
}
}
}
<commit_msg>[#20] Reading from unicorn memory<commit_after>/*
* Copyright (C) 2017 by Godlike
* This code is licensed under the MIT license (MIT)
* (http://opensource.org/licenses/MIT)
*/

#include <unicorn/utility/Logger.hpp>
#include <unicorn/video/Texture.hpp>
#include <unicorn/utility/asset/SimpleStorage.hpp>

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

namespace unicorn
{
namespace video
{
Texture::Texture(): m_width(0)
                  , m_height(0)
                  , m_channels(0)
                  , m_size(0)
                  , m_data(nullptr)
                  , m_initialized(false)
{
}

void Texture::Delete()
{
    if(m_data)
    {
        stbi_image_free(m_data);
        m_data = nullptr;
    }
    m_initialized = false;
}

int32_t Texture::Size() const
{
    return m_size;
}

unsigned char* Texture::Data() const
{
    return m_data;
}

int32_t Texture::Width() const
{
    return m_width;
}

int32_t Texture::Height() const
{
    return m_height;
}

const char* Texture::Path() const
{
    return m_path;
}

bool Texture::Load(const std::string& path)
{
    m_path = path.c_str();

    unicorn::utility::asset::SimpleStorage& storage = unicorn::utility::asset::SimpleStorage::Instance();
    unicorn::utility::asset::Handler textureHandler = storage.Get(path.c_str());

    m_data = stbi_load_from_memory(textureHandler.GetContent().GetBuffer().data(),
                                   textureHandler.GetContent().GetBuffer().size(),
                                   &m_width, &m_height, &m_channels, STBI_rgb_alpha);
    m_size = m_width * m_height * 4;

    if (!m_data) {
        LOG_ERROR("Failed to load texture image with path - ", m_path);
        return false;
    }
    m_initialized = true;
    return true;
}

bool Texture::IsLoaded() const
{
    return m_initialized;
}
}
}
<|endoftext|>


<commit_before>//****************************************************************************
// Copyright © 2015 Jan Erik Breimo. All rights reserved.
// Created by Jan Erik Breimo on 2015-11-03
//
// This file is distributed under the BSD License.
// License text is included with the source distribution.
//****************************************************************************
#include "../../Ystring/Conversion/Converter.hpp"
#include "../../Ystring/YstringException.hpp"
#include "../Ytest/Ytest.hpp"
#include "../../Ystring/Utf8/Utf8Chars.hpp"

using namespace Ystring;
using namespace Ystring::Conversion;

namespace {

    void test_Utf8_to_Utf16()
    {
        Converter converter(Encoding::UTF_8, Encoding::UTF_16);
        std::string s8 = "ABCD";
        std::u16string s16;
        Y_EQUAL(converter.convert(s8.data(), s8.size(), s16), s8.size());
        Y_EQUAL(s16, u"ABCD");
    }

    void test_Utf8_to_Utf16_IncompleteSource()
    {
        Converter converter(Encoding::UTF_8, Encoding::UTF_16);
        std::string s8 = "ABCDEF\xE4\xB8\xA0GHIJKL";
        std::u16string s16;
        Y_EQUAL(converter.convert(s8.data(), 8, s16), 8);
        Y_EQUAL(s16, u"ABCDEF\uFFFD");

        s16.clear();
        Y_EQUAL(converter.convert(s8.data(), 8, s16, true), 6);
        Y_EQUAL(s16, u"ABCDEF");

        converter.setDecoderReplacementCharacter('?');
        s16.clear();
        Y_EQUAL(converter.convert(s8.data(), 8, s16), 8);
        Y_EQUAL(s16, u"ABCDEF?");

        converter.setDecoderErrorHandlingPolicy(ErrorHandlingPolicy::THROW);
        s16.clear();
        Y_THROWS(converter.convert(s8.data(), 8, s16), YstringException);

        converter.setDecoderErrorHandlingPolicy(ErrorHandlingPolicy::STOP);
        s16.clear();
        Y_EQUAL(converter.convert(s8.data(), 8, s16), 6);
        Y_EQUAL(s16, u"ABCDEF");

        converter.setDecoderErrorHandlingPolicy(ErrorHandlingPolicy::SKIP);
        s16.clear();
        Y_EQUAL(converter.convert(s8.data(), 8, s16), 8);
        Y_EQUAL(s16, u"ABCDEF");
    }

    void test_Utf8_to_Utf16_SmallBuffer()
    {
        Converter converter(Encoding::UTF_8, Encoding::UTF_16);
        converter.setBufferSize(4);
        std::string s8 = "ABCDEF\xE4\xB8\xA0GHIJKL";
        std::u16string s16;
        Y_EQUAL(converter.convert(s8.data(), s8.size(), s16), s8.size());
        Y_EQUAL(s16, u"ABCDEF\u4E20GHIJKL");
    }

    void test_Utf16_to_Utf16()
    {
        Converter converter(Encoding::UTF_16, Encoding::UTF_16);
        char16_t src16[] = u"ABCDEFGHIJKL";
        auto src8 = reinterpret_cast<const char*>(src16);
        std::u16string dst;
        Y_EQUAL(converter.convert(src8, sizeof(src16) - 2, dst),
                sizeof(src16) - 2);
        Y_EQUAL(dst, u"ABCDEFGHIJKL");
    }

    void test_Utf16_to_Utf8()
    {
        Converter converter(Encoding::UTF_16, Encoding::UTF_8);
        std::u16string src = u"ABCDEFGHIJKL";
        std::string dst;
        Y_EQUAL(converter.convert(src.data(), src.size(), dst), src.size());
        Y_EQUAL(dst, "ABCDEFGHIJKL");
    }

    void test_Utf16BE_to_Utf16LE()
    {
        Converter converter(Encoding::UTF_16_BE, Encoding::UTF_16_LE);
        char16_t src[] = {'A', 'B', 'C', 'D', 'E', 'F', 'H', 'I'};
        auto srcLen = sizeof(src) / sizeof(*src);
        std::u16string dst;
        Y_EQUAL(converter.convert(src, srcLen, dst), srcLen);
        std::u16string expected;
        for (auto i = 0; i != srcLen; ++i)
            expected.push_back(src[i] << 8);
        Y_EQUAL(dst, expected);
    }

    void test_Utf16LE_to_Utf16BE()
    {
        Converter converter(Encoding::UTF_16_LE, Encoding::UTF_16_BE);
        char16_t src[] = {'A', 'B', 'C', 'D', 'E', 'F', 'H', 'I'};
        auto srcLen = sizeof(src) / sizeof(*src);
        std::u16string dst;
        Y_EQUAL(converter.convert(src, srcLen, dst), srcLen);
        std::u16string expected;
        for (auto i = 0; i != srcLen; ++i)
            expected.push_back(src[i] << 8);
        Y_EQUAL(dst, expected);
    }

    void test_Cp437_to_Utf8()
    {
        Converter converter(Encoding::IBM_437, Encoding::UTF_8);
        std::string src = "ab\x0Aqr\x0Bst\x92uv\xD0";
        std::string dst;
        Y_EQUAL(converter.convert(src.data(), src.size(), dst), src.size());
        Y_EQUAL(dst, "ab\x0Aqr\xE2\x99\x82st\xC3\x86uv\xE2\x95\xA8");
    }

    void test_Cp437_to_Utf32()
    {
        Converter converter(Encoding::IBM_437, Encoding::UTF_32);
        char src[] = "\x01" "1A" "\x7F\xD0\xF0";
        std::u32string dst;
        Y_EQUAL(converter.convert(src, sizeof(src), dst), sizeof(src));
        char32_t expected[] = {0x263A, '1', 'A', 0x2302, 0x2568, 0x2261, 0};
        Y_EQUAL(dst, std::u32string(expected,
                                    sizeof(expected) / sizeof(char32_t)));
    }

    void test_Utf32_to_Cp437()
    {
        Converter converter(Encoding::UTF_32, Encoding::IBM_437);
        std::u32string src = U"\u2642st\u00C6uv\u2568wx\u00F8";
        std::string dst;
        Y_EQUAL(converter.convert(src.data(), src.size(), dst), src.size());
        Y_EQUAL((int)dst[0], (int)0xB);
    }

    void test_Utf8_to_Utf8_WithErrors()
    {
        Converter converter(Encoding::UTF_8, Encoding::UTF_8);
        std::string dst;
        std::string src = "AB\xCF";
        Y_ASSERT(converter.convert(src, dst, true) == src.end() - 1);
        Y_EQUAL(dst, "AB");
        src = "CD\xCF" "E";
        Y_ASSERT(converter.convert(src, dst) == src.end());
        Y_EQUAL(dst, "ABCD" UTF8_REPLACEMENT_CHARACTER "E");
    }

    Y_SUBTEST("Conversion",
              test_Utf8_to_Utf16,
              test_Utf8_to_Utf16_IncompleteSource,
              test_Utf8_to_Utf16_SmallBuffer,
              test_Utf16_to_Utf16,
              test_Utf16_to_Utf8,
              test_Utf16BE_to_Utf16LE,
              test_Utf16LE_to_Utf16BE,
              test_Cp437_to_Utf8,
              test_Cp437_to_Utf32,
              test_Utf32_to_Cp437,
              test_Utf8_to_Utf8_WithErrors);
}
<commit_msg>Added unit test for conveting Utf8 to Windows1252.<commit_after>//****************************************************************************
// Copyright © 2015 Jan Erik Breimo. All rights reserved.
// Created by Jan Erik Breimo on 2015-11-03
//
// This file is distributed under the BSD License.
// License text is included with the source distribution.
//****************************************************************************
#include "../../Ystring/Conversion/Converter.hpp"
#include "../../Ystring/YstringException.hpp"
#include "../Ytest/Ytest.hpp"
#include "../../Ystring/Utf8/Utf8Chars.hpp"

using namespace Ystring;
using namespace Ystring::Conversion;

namespace
{
    void test_Utf8_to_Utf16()
    {
        Converter converter(Encoding::UTF_8, Encoding::UTF_16);
        std::string s8 = "ABCD";
        std::u16string s16;
        Y_EQUAL(converter.convert(s8.data(), s8.size(), s16), s8.size());
        Y_EQUAL(s16, u"ABCD");
    }

    void test_Utf8_to_Utf16_IncompleteSource()
    {
        Converter converter(Encoding::UTF_8, Encoding::UTF_16);
        std::string s8 = "ABCDEF\xE4\xB8\xA0GHIJKL";
        std::u16string s16;
        Y_EQUAL(converter.convert(s8.data(), 8, s16), 8);
        Y_EQUAL(s16, u"ABCDEF\uFFFD");

        s16.clear();
        Y_EQUAL(converter.convert(s8.data(), 8, s16, true), 6);
        Y_EQUAL(s16, u"ABCDEF");

        converter.setDecoderReplacementCharacter('?');
        s16.clear();
        Y_EQUAL(converter.convert(s8.data(), 8, s16), 8);
        Y_EQUAL(s16, u"ABCDEF?");

        converter.setDecoderErrorHandlingPolicy(ErrorHandlingPolicy::THROW);
        s16.clear();
        Y_THROWS(converter.convert(s8.data(), 8, s16), YstringException);

        converter.setDecoderErrorHandlingPolicy(ErrorHandlingPolicy::STOP);
        s16.clear();
        Y_EQUAL(converter.convert(s8.data(), 8, s16), 6);
        Y_EQUAL(s16, u"ABCDEF");

        converter.setDecoderErrorHandlingPolicy(ErrorHandlingPolicy::SKIP);
        s16.clear();
        Y_EQUAL(converter.convert(s8.data(), 8, s16), 8);
        Y_EQUAL(s16, u"ABCDEF");
    }

    void test_Utf8_to_Utf16_SmallBuffer()
    {
        Converter converter(Encoding::UTF_8, Encoding::UTF_16);
        converter.setBufferSize(4);
        std::string s8 = "ABCDEF\xE4\xB8\xA0GHIJKL";
        std::u16string s16;
        Y_EQUAL(converter.convert(s8.data(), s8.size(), s16), s8.size());
        Y_EQUAL(s16, u"ABCDEF\u4E20GHIJKL");
    }

    void test_Utf16_to_Utf16()
    {
        Converter converter(Encoding::UTF_16, Encoding::UTF_16);
        char16_t src16[] = u"ABCDEFGHIJKL";
        auto src8 = reinterpret_cast<const char*>(src16);
        std::u16string dst;
        Y_EQUAL(converter.convert(src8, sizeof(src16) - 2, dst),
                sizeof(src16) - 2);
        Y_EQUAL(dst, u"ABCDEFGHIJKL");
    }

    void test_Utf16_to_Utf8()
    {
        Converter converter(Encoding::UTF_16, Encoding::UTF_8);
        std::u16string src = u"ABCDEFGHIJKL";
        std::string dst;
        Y_EQUAL(converter.convert(src.data(), src.size(), dst), src.size());
        Y_EQUAL(dst, "ABCDEFGHIJKL");
    }

    void test_Utf16BE_to_Utf16LE()
    {
        Converter converter(Encoding::UTF_16_BE, Encoding::UTF_16_LE);
        char16_t src[] = {'A', 'B', 'C', 'D', 'E', 'F', 'H', 'I'};
        auto srcLen = sizeof(src) / sizeof(*src);
        std::u16string dst;
        Y_EQUAL(converter.convert(src, srcLen, dst), srcLen);
        std::u16string expected;
        for (auto i = 0; i != srcLen; ++i)
            expected.push_back(src[i] << 8);
        Y_EQUAL(dst, expected);
    }

    void test_Utf16LE_to_Utf16BE()
    {
        Converter converter(Encoding::UTF_16_LE, Encoding::UTF_16_BE);
        char16_t src[] = {'A', 'B', 'C', 'D', 'E', 'F', 'H', 'I'};
        auto srcLen = sizeof(src) / sizeof(*src);
        std::u16string dst;
        Y_EQUAL(converter.convert(src, srcLen, dst), srcLen);
        std::u16string expected;
        for (auto i = 0; i != srcLen; ++i)
            expected.push_back(src[i] << 8);
        Y_EQUAL(dst, expected);
    }

    void test_Cp437_to_Utf8()
    {
        Converter converter(Encoding::IBM_437, Encoding::UTF_8);
        std::string src = "ab\x0Aqr\x0Bst\x92uv\xD0";
        std::string dst;
        Y_EQUAL(converter.convert(src.data(), src.size(), dst), src.size());
        Y_EQUAL(dst, "ab\x0Aqr\xE2\x99\x82st\xC3\x86uv\xE2\x95\xA8");
    }

    void test_Cp437_to_Utf32()
    {
        Converter converter(Encoding::IBM_437, Encoding::UTF_32);
        char src[] = "\x01" "1A" "\x7F\xD0\xF0";
        std::u32string dst;
        Y_EQUAL(converter.convert(src, sizeof(src), dst), sizeof(src));
        char32_t expected[] = {0x263A, '1', 'A', 0x2302, 0x2568, 0x2261, 0};
        Y_EQUAL(dst, std::u32string(expected,
                                    sizeof(expected) / sizeof(char32_t)));
    }

    void test_Utf32_to_Cp437()
    {
        Converter converter(Encoding::UTF_32, Encoding::IBM_437);
        std::u32string src = U"\u2642st\u00C6uv\u2568wx\u00F8";
        std::string dst;
        Y_EQUAL(converter.convert(src.data(), src.size(), dst), src.size());
        Y_EQUAL((int)dst[0], (int)0xB);
    }

    void test_Utf8_to_Utf8_WithErrors()
    {
        Converter converter(Encoding::UTF_8, Encoding::UTF_8);
        std::string dst;
        std::string src = "AB\xCF";
        Y_ASSERT(converter.convert(src, dst, true) == src.end() - 1);
        Y_EQUAL(dst, "AB");
        src = "CD\xCF" "E";
        Y_ASSERT(converter.convert(src, dst) == src.end());
        Y_EQUAL(dst, "ABCD" UTF8_REPLACEMENT_CHARACTER "E");
    }

    void test_Utf8_to_Windows1252()
    {
        Converter converter(Encoding::UTF_8, Encoding::WINDOWS_1252);
        std::string s8 = "ABCD \xC3\x86\xC3\x98\xC3\x85 \xC3\xA6\xC3\xB8\xC3\xA5";
        std::string s1252;
        Y_EQUAL(converter.convert(s8.data(), s8.size(), s1252), s8.size());
        Y_EQUAL(s1252, "ABCD \xC6\xD8\xC5 \xE6\xF8\xE5");
    }

    Y_SUBTEST("Conversion",
              test_Utf8_to_Utf16,
              test_Utf8_to_Utf16_IncompleteSource,
              test_Utf8_to_Utf16_SmallBuffer,
              test_Utf16_to_Utf16,
              test_Utf16_to_Utf8,
              test_Utf16BE_to_Utf16LE,
              test_Utf16LE_to_Utf16BE,
              test_Cp437_to_Utf8,
              test_Cp437_to_Utf32,
              test_Utf32_to_Cp437,
              test_Utf8_to_Utf8_WithErrors,
              test_Utf8_to_Windows1252);
}
<|endoftext|>


<commit_before>
#include "journal/player.hpp"

#include <list>
#include <string>
#include <thread>
#include <vector>

#include "benchmark/benchmark.h"
#include "glog/logging.h"
#include "gtest/gtest.h"
#include "journal/method.hpp"
#include "journal/profiles.hpp"
#include "journal/recorder.hpp"
#include "ksp_plugin/interface.hpp"
#include "serialization/journal.pb.h"

namespace principia {
namespace journal {

void BM_PlayForReal(benchmark::State& state) {
  while (state.KeepRunning()) {
    Player player(
        R"(P:\Public Mockingbird\Principia\Journals\JOURNAL.20170520-201036)");
    int count = 0;
    while (player.Play()) {
      ++count;
      LOG_IF(ERROR, (count % 100'000) == 0)
          << count << " journal entries replayed";
    }
  }
}

BENCHMARK(BM_PlayForReal);

class PlayerTest : public ::testing::Test {
 protected:
  PlayerTest()
      : test_info_(testing::UnitTest::GetInstance()->current_test_info()),
        test_case_name_(test_info_->test_case_name()),
        test_name_(test_info_->name()),
        plugin_(interface::principia__NewPlugin("MJD0", "MJD0", 0)) {}

  template<typename Profile>
  bool RunIfAppropriate(serialization::Method const& method_in,
                        serialization::Method const& method_out_return,
                        Player& player) {
    return player.RunIfAppropriate<Profile>(method_in, method_out_return);
  }

  ::testing::TestInfo const* const test_info_;
  std::string const test_case_name_;
  std::string const test_name_;
  std::unique_ptr<ksp_plugin::Plugin> plugin_;
};

TEST_F(PlayerTest, PlayTiny) {
  // Do the recording in a separate thread to make sure that it activates using
  // a different static variable than the one in the plugin dynamic library.
  std::thread recorder([this]() {
    Recorder* const r(new Recorder(test_name_ + ".journal.hex"));
    Recorder::Activate(r);

    {
      Method<NewPlugin> m({"MJD1", "MJD2", 3});
      m.Return(plugin_.get());
    }
    {
      const ksp_plugin::Plugin* plugin = plugin_.get();
      Method<DeletePlugin> m({&plugin}, {&plugin});
      m.Return();
    }
    Recorder::Deactivate();
  });
  recorder.join();

  Player player(test_name_ + ".journal.hex");

  // Replay the journal.
  int count = 0;
  while (player.Play()) {
    ++count;
  }
  EXPECT_EQ(2, count);
}

TEST_F(PlayerTest, DISABLED_Benchmarks) {
  benchmark::RunSpecifiedBenchmarks();
}

TEST_F(PlayerTest, DISABLED_Debug) {
  // An example of how journaling may be used for debugging.  You must set
  // |path| and fill the |method_in| and |method_out_return| protocol buffers.
  std::string path =
      R"(C:\Program Files\Kerbal Space Program\1.2.2\glog\Principia\JOURNAL.20170603-094244)";  // NOLINT
  Player player(path);
  int count = 0;
  while (player.Play()) {
    ++count;
    LOG_IF(ERROR, (count % 100'000) == 0) << count
                                          << " journal entries replayed";
  }
  LOG(ERROR) << count << " journal entries in total";
  LOG(ERROR) << "Last successful method in:\n"
              << player.last_method_in().DebugString();
  LOG(ERROR) << "Last successful method out/return: \n"
              << player.last_method_out_return().DebugString();

#if 1
  serialization::Method method_in;
  {
    auto* extension = method_in.MutableExtension(
        serialization::SerializePlugin::extension);
    auto* in = extension->mutable_in();
    in->set_plugin(1524276256);
    in->set_serializer(0);
  }
  serialization::Method method_out_return;
  {
    auto* extension = method_out_return.MutableExtension(
        serialization::SerializePlugin::extension);
    auto* out = extension->mutable_out();
  }
  LOG(ERROR) << "Running unpaired method:\n" << method_in.DebugString();
  CHECK(RunIfAppropriate<SerializePlugin>(method_in,
                                          method_out_return,
                                          player));
#endif
}

}  // namespace journal
}  // namespace principia
<commit_msg>Readying for review.<commit_after>
#include "journal/player.hpp"

#include <list>
#include <string>
#include <thread>
#include <vector>

#include "benchmark/benchmark.h"
#include "glog/logging.h"
#include "gtest/gtest.h"
#include "journal/method.hpp"
#include "journal/profiles.hpp"
#include "journal/recorder.hpp"
#include "ksp_plugin/interface.hpp"
#include "serialization/journal.pb.h"

namespace principia {
namespace journal {

void BM_PlayForReal(benchmark::State& state) {
  while (state.KeepRunning()) {
    Player player(
        R"(P:\Public Mockingbird\Principia\Journals\JOURNAL.20170520-201036)");
    int count = 0;
    while (player.Play()) {
      ++count;
      LOG_IF(ERROR, (count % 100'000) == 0)
          << count << " journal entries replayed";
    }
  }
}

BENCHMARK(BM_PlayForReal);

class PlayerTest : public ::testing::Test {
 protected:
  PlayerTest()
      : test_info_(testing::UnitTest::GetInstance()->current_test_info()),
        test_case_name_(test_info_->test_case_name()),
        test_name_(test_info_->name()),
        plugin_(interface::principia__NewPlugin("MJD0", "MJD0", 0)) {}

  template<typename Profile>
  bool RunIfAppropriate(serialization::Method const& method_in,
                        serialization::Method const& method_out_return,
                        Player& player) {
    return player.RunIfAppropriate<Profile>(method_in, method_out_return);
  }

  ::testing::TestInfo const* const test_info_;
  std::string const test_case_name_;
  std::string const test_name_;
  std::unique_ptr<ksp_plugin::Plugin> plugin_;
};

TEST_F(PlayerTest, PlayTiny) {
  // Do the recording in a separate thread to make sure that it activates using
  // a different static variable than the one in the plugin dynamic library.
  std::thread recorder([this]() {
    Recorder* const r(new Recorder(test_name_ + ".journal.hex"));
    Recorder::Activate(r);

    {
      Method<NewPlugin> m({"MJD1", "MJD2", 3});
      m.Return(plugin_.get());
    }
    {
      const ksp_plugin::Plugin* plugin = plugin_.get();
      Method<DeletePlugin> m({&plugin}, {&plugin});
      m.Return();
    }
    Recorder::Deactivate();
  });
  recorder.join();

  Player player(test_name_ + ".journal.hex");

  // Replay the journal.
  int count = 0;
  while (player.Play()) {
    ++count;
  }
  EXPECT_EQ(2, count);
}

TEST_F(PlayerTest, DISABLED_Benchmarks) {
  benchmark::RunSpecifiedBenchmarks();
}

TEST_F(PlayerTest, DISABLED_Debug) {
  // An example of how journaling may be used for debugging.  You must set
  // |path| and fill the |method_in| and |method_out_return| protocol buffers.
  std::string path =
      R"(C:\Program Files\Kerbal Space Program\1.2.2\glog\Principia\JOURNAL.20170603-094244)";  // NOLINT
  Player player(path);
  int count = 0;
  while (player.Play()) {
    ++count;
    LOG_IF(ERROR, (count % 100'000) == 0) << count
                                          << " journal entries replayed";
  }
  LOG(ERROR) << count << " journal entries in total";
  LOG(ERROR) << "Last successful method in:\n"
              << player.last_method_in().DebugString();
  LOG(ERROR) << "Last successful method out/return: \n"
              << player.last_method_out_return().DebugString();

#if 0
  serialization::Method method_in;
  {
    auto* extension = method_in.MutableExtension(
        serialization::SerializePlugin::extension);
    auto* in = extension->mutable_in();
    in->set_plugin(1524276256);
    in->set_serializer(0);
  }
  serialization::Method method_out_return;
  {
    auto* extension = method_out_return.MutableExtension(
        serialization::SerializePlugin::extension);
    auto* out = extension->mutable_out();
  }
  LOG(ERROR) << "Running unpaired method:\n" << method_in.DebugString();
  CHECK(RunIfAppropriate<SerializePlugin>(method_in,
                                          method_out_return,
                                          player));
#endif
}

}  // namespace journal
}  // namespace principia
<|endoftext|>


<commit_before>#include "Renderable2DComponent.h"
#include "wiResourceManager.h"
#include "wiSprite.h"
#include "wiFont.h"
#include "wiRenderer.h"

using namespace wiGraphicsTypes;

Renderable2DComponent::Renderable2DComponent() : RenderableComponent()
{
	setSpriteSpeed(1.f);
	addLayer(DEFAULT_RENDERLAYER);
	GUI = wiGUI(GRAPHICSTHREAD_IMMEDIATE);
}

Renderable2DComponent::~Renderable2DComponent()
{
	Unload();
}

wiRenderTarget Renderable2DComponent::rtFinal;
void Renderable2DComponent::ResizeBuffers()
{
	FORMAT defaultTextureFormat = GraphicsDevice::GetBackBufferFormat();

	// Protect against multiple buffer resizes when there is no change!
	static UINT lastBufferResWidth = 0, lastBufferResHeight = 0, lastBufferMSAA = 0;
	static FORMAT lastBufferFormat = FORMAT_UNKNOWN;
	if (lastBufferResWidth == (UINT)wiRenderer::GetDevice()->GetScreenWidth() &&
		lastBufferResHeight == (UINT)wiRenderer::GetDevice()->GetScreenHeight() &&
		lastBufferFormat == defaultTextureFormat)
	{
		return;
	}
	else
	{
		lastBufferResWidth = (UINT)wiRenderer::GetDevice()->GetScreenWidth();
		lastBufferResHeight = (UINT)wiRenderer::GetDevice()->GetScreenHeight();
		lastBufferFormat = defaultTextureFormat;
	}

	rtFinal.Initialize(wiRenderer::GetDevice()->GetScreenWidth(), wiRenderer::GetDevice()->GetScreenHeight(), false, defaultTextureFormat);
}

void Renderable2DComponent::Initialize()
{
	ResizeBuffers();

	RenderableComponent::Initialize();
}

void Renderable2DComponent::Load()
{
	RenderableComponent::Load();
}
void Renderable2DComponent::Unload()
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite != nullptr)
			{
				y.sprite->CleanUp();
				delete y.sprite;
			}
			if (y.font != nullptr)
			{
				y.font->CleanUp();
				delete y.font;
			}
		}
	}

	RenderableComponent::Unload();
}
void Renderable2DComponent::Start()
{
	RenderableComponent::Start();
}
void Renderable2DComponent::Update(float dt)
{
	GetGUI().Update(dt);

	RenderableComponent::Update(dt);
}
void Renderable2DComponent::FixedUpdate()
{

	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite != nullptr)
			{
				y.sprite->Update(getSpriteSpeed());
			}
			if (y.font != nullptr)
			{
				// this is intentianally left blank
			}
		}
	}

	RenderableComponent::FixedUpdate();
}
void Renderable2DComponent::Render()
{
	rtFinal.Activate(GRAPHICSTHREAD_IMMEDIATE, 0.0f, 0.0f, 0.0f, 0.0f);

	wiRenderer::GetDevice()->EventBegin("Sprite Layers", GRAPHICSTHREAD_IMMEDIATE);
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite != nullptr)
			{
				y.sprite->Draw(GRAPHICSTHREAD_IMMEDIATE);
			}
			if (y.font != nullptr)
			{
				y.font->Draw(GRAPHICSTHREAD_IMMEDIATE);
			}
		}
	}
	wiRenderer::GetDevice()->EventEnd(GRAPHICSTHREAD_IMMEDIATE);

	GetGUI().Render();

	RenderableComponent::Render();
}
void Renderable2DComponent::Compose()
{
	wiImageEffects fx((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight());
	fx.presentFullScreen = true;
	fx.blendFlag = BLENDMODE_PREMULTIPLIED;

	GPUResource* res[] = {
		rtFinal.GetTexture()
	};
	wiRenderer::GetDevice()->TransitionBarrier(res, 1, RESOURCE_STATE_RENDER_TARGET, RESOURCE_STATE_PIXEL_SHADER_RESOURCE, GRAPHICSTHREAD_IMMEDIATE);

	wiImage::Draw(rtFinal.GetTexture(), fx, GRAPHICSTHREAD_IMMEDIATE);

	RenderableComponent::Compose();
}

void Renderable2DComponent::addSprite(wiSprite* sprite, const std::string& layer)
{
	for (auto& x : layers)
	{
		if (!x.name.compare(layer))
		{
			LayeredRenderEntity entity = LayeredRenderEntity();
			entity.type = LayeredRenderEntity::SPRITE;
			entity.sprite = sprite;
			x.entities.push_back(entity);
		}
	}
	SortLayers();
}
void Renderable2DComponent::removeSprite(wiSprite* sprite)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite == sprite)
			{
				y.sprite = nullptr;
			}
		}
	}
	CleanLayers();
}
void Renderable2DComponent::clearSprites()
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			y.sprite = nullptr;
		}
	}
	CleanLayers();
}
int Renderable2DComponent::getSpriteOrder(wiSprite* sprite)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite == sprite)
			{
				return y.order;
			}
		}
	}
	return 0;
}

void Renderable2DComponent::addFont(wiFont* font, const std::string& layer)
{
	for (auto& x : layers)
	{
		if (!x.name.compare(layer))
		{
			LayeredRenderEntity entity = LayeredRenderEntity();
			entity.type = LayeredRenderEntity::FONT;
			entity.font = font;
			x.entities.push_back(entity);
		}
	}
	SortLayers();
}
void Renderable2DComponent::removeFont(wiFont* font)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.font == font)
			{
				y.font = nullptr;
			}
		}
	}
	CleanLayers();
}
void Renderable2DComponent::clearFonts()
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			y.font = nullptr;
		}
	}
	CleanLayers();
}
int Renderable2DComponent::getFontOrder(wiFont* font)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.font == font)
			{
				return y.order;
			}
		}
	}
	return 0;
}

void Renderable2DComponent::addLayer(const std::string& name)
{
	for (auto& x : layers)
	{
		if (!x.name.compare(name))
			return;
	}
	RenderLayer layer = RenderLayer(name);
	layer.order = (int)layers.size();
	layers.push_back(layer);
	layers.back().entities.clear();
}
void Renderable2DComponent::setLayerOrder(const std::string& name, int order)
{
	for (auto& x : layers)
	{
		if (!x.name.compare(name))
		{
			x.order = order;
			break;
		}
	}
	SortLayers();
}
void Renderable2DComponent::SetSpriteOrder(wiSprite* sprite, int order)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.type == LayeredRenderEntity::SPRITE && y.sprite == sprite)
			{
				y.order = order;
			}
		}
	}
	SortLayers();
}
void Renderable2DComponent::SetFontOrder(wiFont* font, int order)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.type == LayeredRenderEntity::FONT && y.font == font)
			{
				y.order = order;
			}
		}
	}
	SortLayers();
}
void Renderable2DComponent::SortLayers()
{
	if (layers.empty())
	{
		return;
	}

	for (size_t i = 0; i < layers.size() - 1; ++i)
	{
		for (size_t j = i + 1; j < layers.size(); ++j)
		{
			if (layers[i].order > layers[j].order)
			{
				RenderLayer swap = layers[i];
				layers[i] = layers[j];
				layers[j] = swap;
			}
		}
	}
	for (auto& x : layers)
	{
		if (x.entities.empty())
		{
			continue;
		}
		for (size_t i = 0; i < x.entities.size() - 1; ++i)
		{
			for (size_t j = i + 1; j < x.entities.size(); ++j)
			{
				if (x.entities[i].order > x.entities[j].order)
				{
					LayeredRenderEntity swap = x.entities[i];
					x.entities[i] = x.entities[j];
					x.entities[j] = swap;
				}
			}
		}
	}
}

void Renderable2DComponent::CleanLayers()
{
	for (auto& x : layers)
	{
		if (x.entities.empty())
		{
			continue;
		}
		std::vector<LayeredRenderEntity> cleanEntities(0);
		for (auto& y : x.entities)
		{
			if (y.sprite != nullptr || y.font!=nullptr)
			{
				cleanEntities.push_back(y);
			}
		}
		x.entities.clear();
		x.entities = cleanEntities;
	}
}

<commit_msg>we don't need that probably<commit_after>#include "Renderable2DComponent.h"
#include "wiResourceManager.h"
#include "wiSprite.h"
#include "wiFont.h"
#include "wiRenderer.h"

using namespace wiGraphicsTypes;

Renderable2DComponent::Renderable2DComponent() : RenderableComponent()
{
	setSpriteSpeed(1.f);
	addLayer(DEFAULT_RENDERLAYER);
	GUI = wiGUI(GRAPHICSTHREAD_IMMEDIATE);
}

Renderable2DComponent::~Renderable2DComponent()
{
	Unload();
}

wiRenderTarget Renderable2DComponent::rtFinal;
void Renderable2DComponent::ResizeBuffers()
{
	FORMAT defaultTextureFormat = GraphicsDevice::GetBackBufferFormat();

	// Protect against multiple buffer resizes when there is no change!
	static UINT lastBufferResWidth = 0, lastBufferResHeight = 0, lastBufferMSAA = 0;
	static FORMAT lastBufferFormat = FORMAT_UNKNOWN;
	if (lastBufferResWidth == (UINT)wiRenderer::GetDevice()->GetScreenWidth() &&
		lastBufferResHeight == (UINT)wiRenderer::GetDevice()->GetScreenHeight() &&
		lastBufferFormat == defaultTextureFormat)
	{
		return;
	}
	else
	{
		lastBufferResWidth = (UINT)wiRenderer::GetDevice()->GetScreenWidth();
		lastBufferResHeight = (UINT)wiRenderer::GetDevice()->GetScreenHeight();
		lastBufferFormat = defaultTextureFormat;
	}

	rtFinal.Initialize(wiRenderer::GetDevice()->GetScreenWidth(), wiRenderer::GetDevice()->GetScreenHeight(), false, defaultTextureFormat);
}

void Renderable2DComponent::Initialize()
{
	ResizeBuffers();

	RenderableComponent::Initialize();
}

void Renderable2DComponent::Load()
{
	RenderableComponent::Load();
}
void Renderable2DComponent::Unload()
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite != nullptr)
			{
				y.sprite->CleanUp();
				delete y.sprite;
			}
			if (y.font != nullptr)
			{
				y.font->CleanUp();
				delete y.font;
			}
		}
	}

	RenderableComponent::Unload();
}
void Renderable2DComponent::Start()
{
	RenderableComponent::Start();
}
void Renderable2DComponent::Update(float dt)
{
	GetGUI().Update(dt);

	RenderableComponent::Update(dt);
}
void Renderable2DComponent::FixedUpdate()
{

	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite != nullptr)
			{
				y.sprite->Update(getSpriteSpeed());
			}
			if (y.font != nullptr)
			{
				// this is intentianally left blank
			}
		}
	}

	RenderableComponent::FixedUpdate();
}
void Renderable2DComponent::Render()
{
	rtFinal.Activate(GRAPHICSTHREAD_IMMEDIATE, 0.0f, 0.0f, 0.0f, 0.0f);

	wiRenderer::GetDevice()->EventBegin("Sprite Layers", GRAPHICSTHREAD_IMMEDIATE);
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite != nullptr)
			{
				y.sprite->Draw(GRAPHICSTHREAD_IMMEDIATE);
			}
			if (y.font != nullptr)
			{
				y.font->Draw(GRAPHICSTHREAD_IMMEDIATE);
			}
		}
	}
	wiRenderer::GetDevice()->EventEnd(GRAPHICSTHREAD_IMMEDIATE);

	GetGUI().Render();

	RenderableComponent::Render();
}
void Renderable2DComponent::Compose()
{
	wiImageEffects fx((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight());
	fx.presentFullScreen = true;
	fx.blendFlag = BLENDMODE_PREMULTIPLIED;

	wiImage::Draw(rtFinal.GetTexture(), fx, GRAPHICSTHREAD_IMMEDIATE);

	RenderableComponent::Compose();
}

void Renderable2DComponent::addSprite(wiSprite* sprite, const std::string& layer)
{
	for (auto& x : layers)
	{
		if (!x.name.compare(layer))
		{
			LayeredRenderEntity entity = LayeredRenderEntity();
			entity.type = LayeredRenderEntity::SPRITE;
			entity.sprite = sprite;
			x.entities.push_back(entity);
		}
	}
	SortLayers();
}
void Renderable2DComponent::removeSprite(wiSprite* sprite)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite == sprite)
			{
				y.sprite = nullptr;
			}
		}
	}
	CleanLayers();
}
void Renderable2DComponent::clearSprites()
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			y.sprite = nullptr;
		}
	}
	CleanLayers();
}
int Renderable2DComponent::getSpriteOrder(wiSprite* sprite)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.sprite == sprite)
			{
				return y.order;
			}
		}
	}
	return 0;
}

void Renderable2DComponent::addFont(wiFont* font, const std::string& layer)
{
	for (auto& x : layers)
	{
		if (!x.name.compare(layer))
		{
			LayeredRenderEntity entity = LayeredRenderEntity();
			entity.type = LayeredRenderEntity::FONT;
			entity.font = font;
			x.entities.push_back(entity);
		}
	}
	SortLayers();
}
void Renderable2DComponent::removeFont(wiFont* font)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.font == font)
			{
				y.font = nullptr;
			}
		}
	}
	CleanLayers();
}
void Renderable2DComponent::clearFonts()
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			y.font = nullptr;
		}
	}
	CleanLayers();
}
int Renderable2DComponent::getFontOrder(wiFont* font)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.font == font)
			{
				return y.order;
			}
		}
	}
	return 0;
}

void Renderable2DComponent::addLayer(const std::string& name)
{
	for (auto& x : layers)
	{
		if (!x.name.compare(name))
			return;
	}
	RenderLayer layer = RenderLayer(name);
	layer.order = (int)layers.size();
	layers.push_back(layer);
	layers.back().entities.clear();
}
void Renderable2DComponent::setLayerOrder(const std::string& name, int order)
{
	for (auto& x : layers)
	{
		if (!x.name.compare(name))
		{
			x.order = order;
			break;
		}
	}
	SortLayers();
}
void Renderable2DComponent::SetSpriteOrder(wiSprite* sprite, int order)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.type == LayeredRenderEntity::SPRITE && y.sprite == sprite)
			{
				y.order = order;
			}
		}
	}
	SortLayers();
}
void Renderable2DComponent::SetFontOrder(wiFont* font, int order)
{
	for (auto& x : layers)
	{
		for (auto& y : x.entities)
		{
			if (y.type == LayeredRenderEntity::FONT && y.font == font)
			{
				y.order = order;
			}
		}
	}
	SortLayers();
}
void Renderable2DComponent::SortLayers()
{
	if (layers.empty())
	{
		return;
	}

	for (size_t i = 0; i < layers.size() - 1; ++i)
	{
		for (size_t j = i + 1; j < layers.size(); ++j)
		{
			if (layers[i].order > layers[j].order)
			{
				RenderLayer swap = layers[i];
				layers[i] = layers[j];
				layers[j] = swap;
			}
		}
	}
	for (auto& x : layers)
	{
		if (x.entities.empty())
		{
			continue;
		}
		for (size_t i = 0; i < x.entities.size() - 1; ++i)
		{
			for (size_t j = i + 1; j < x.entities.size(); ++j)
			{
				if (x.entities[i].order > x.entities[j].order)
				{
					LayeredRenderEntity swap = x.entities[i];
					x.entities[i] = x.entities[j];
					x.entities[j] = swap;
				}
			}
		}
	}
}

void Renderable2DComponent::CleanLayers()
{
	for (auto& x : layers)
	{
		if (x.entities.empty())
		{
			continue;
		}
		std::vector<LayeredRenderEntity> cleanEntities(0);
		for (auto& y : x.entities)
		{
			if (y.sprite != nullptr || y.font!=nullptr)
			{
				cleanEntities.push_back(y);
			}
		}
		x.entities.clear();
		x.entities = cleanEntities;
	}
}

<|endoftext|>


<commit_before>#include <iostream>

template <typename T>
class stack
{
public:
    stack();											// êîíñòðóêòîð
    stack(stack const &);
    ~stack();											// äåñòðóêòîð
    size_t count() const;
    auto push(T const &) -> void;						// ïîìåñòèòü ýëåìåíò â âåðøèíó ñòåêà
    T pop();											// óäàëèòü ýëåìåíò èç âåðøèíû ñòåêà è âåðíóòü åãî
    auto operator=(stack const & right)->stack &;		// ïåðåîïðåäåëåíèå îïåðàòîðà, ïðèñâàèâàåò çíà÷åíèå êîíòåéíåðó"
private:
    T *array_;											// óêàçàòåëü íà ñòåê
    size_t array_size_;									// êîëè÷åñòâî ýëåìåíòîâ â ñòåêå
    size_t count_;										// íîìåð òåêóùåãî ýëåìåíòà ñòåêà
};
template<typename>
auto newcopy(T * item, size_t size, size_t count) -> T*
{
	T * buff = new T[size];
	std::copy(item, item + count, buff);
	return buff;
}
template <typename T>
size_t stack<T>::count() const
{
    return count_;
}
template <typename T>
stack<T>::stack()
{
    array_size_ = 0;
    array_ = new T[array_size_];
    count_ = 0;
}

template<typename T>
stack<T>::stack(stack const & other):array_size_(other.array_size_), count_(other.count_),array_(newcopy(other.array_, other.array_size_,other.count_))
{

}

template <typename T>
stack<T>::~stack()
{
    delete[] array_;
}

template<typename T>
void stack<T>::push(T const &item)
{
    if (count_ == array_size_)
    {
	    size_t size = array_size_ * 2 + (array_size_ == 0);
	    T *buff = newcopy(array_, size, array_size_);
	    delete[] array_;
	    array_ = newcopy(array_, size, array_size_);
	    array_size_ = size;
	}
	++count_;
	array_[count_ - 1]= item;
}
template<typename T>
T stack<T>::pop()
{
    if (count_ == 0)
    {
        throw std::logic_error("Stack is empty!");
    }
    return array_[--count_];
}
template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right)
	{
		delete[] array_;
		newcopy(right.array_, right.array_size_, right.count_)
	}
	return *this;
}
<commit_msg>Update stack.cpp<commit_after>#include <iostream>

template <typename T>
class stack
{
public:
	stack();											// êîíñòðóêòîð
	stack(stack const &);
	~stack();											// äåñòðóêòîð
	size_t count() const;
	auto push(T const &) -> void;						// ïîìåñòèòü ýëåìåíò â âåðøèíó ñòåêà
	T pop();											// óäàëèòü ýëåìåíò èç âåðøèíû ñòåêà è âåðíóòü åãî
	auto operator=(stack const & right)->stack &;		// ïåðåîïðåäåëåíèå îïåðàòîðà, ïðèñâàèâàåò çíà÷åíèå êîíòåéíåðó"
private:
	T *array_;											// óêàçàòåëü íà ñòåê
	size_t array_size_;									// êîëè÷åñòâî ýëåìåíòîâ â ñòåêå
	size_t count_;										// íîìåð òåêóùåãî ýëåìåíòà ñòåêà
};
template<typename T>
auto newcopy(const T * item, size_t size, size_t count) -> T*
{
	T * buff = new T[size];
	std::copy(item, item + count, buff);
	return buff;
}
template <typename T>
size_t stack<T>::count() const
{
	std::cout << count_;
	return count_;
}
template <typename T>
stack<T>::stack()
{
	array_size_ = 0;
	array_ = new T[array_size_];
	count_ = 0;
}

template<typename T>
stack<T>::stack(stack const & other) :array_size_(other.array_size_), count_(other.count_), array_(newcopy(other.array_, other.array_size_, other.count_))
{

}

template <typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
void stack<T>::push(T const &item)
{
	if (count_ == array_size_)
	{
		size_t size = array_size_ * 2 + (array_size_ == 0);
		delete[] array_;
		array_ = newcopy(array_, size, array_size_);
		array_size_ = size;
	}
	array_[count_] = item;
	++count_;
}
template<typename T>
T stack<T>::pop()
{
	if (count_ == 0)
	{
		throw std::logic_error("Stack is empty!");
	}
	return array_[--count_];
}
template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
		delete[] array_;
		newcopy(right.array_, right.array_size_, right.count_);
	}
	return *this;
}
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

template <typename T>
class stack
{
public:
	stack();/*noexept*/
	stack(const stack<T> &);/*no safety*/
	size_t count() const; /*noexcept*/
	void print()const;/*strong*/
	void push(T const &); /*no safety*/
	void swap(stack<T>&); /*noexcept*/
	void pop(); /*no safety*/
	T top(); /*strong*/
	bool empty() const; /*noexcept*/
	stack<T>& operator=(stack<T> &); /*basic*/
	~stack();/*noexcept*/
private:
	T * array_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
stack<T>::stack() : count_(0), array_size_(0), array_{ nullptr }
{}

template<class T>
stack<T>::~stack()
{
	count_ = 0;
	array_size_ = 0;
	delete[] array_;
}

template <typename T>
stack<T>::stack(const stack<T>& copy)
{
	array_size_ = copy.array_size_;
	count_ = copy.count_;
	array_ = new T[count_];
	std::copy(copy.array_, copy.array_ + copy.count_, array_);
}

template<class T>
size_t stack<T>::count() const
{
	return count_;
}

template <typename T>
bool stack<T>::empty() const
{
	return (count_ == 0);
}

template<typename T>
void stack<T>::swap(stack& x)
{
	std::swap(x.array_size_, array_size_);
	std::swap(count_, x.count_);
	std::swap(x.array_, array_);
}

template <typename T>
T stack<T>::top()
{
	if (empty())
	{
		std::cout << "Stack is empty!";
	}
	return array_[count_ - 1];
}

template <typename T>
void stack<T>::push(T const &value)
{
	if (array_size_ == 0)
	{
		array_size_ = 1;
		array_ = new T[array_size_];
	}
	else if (array_size_ == count_)
	{
		array_size_ = array_size_ * 2;
		T *s1 = new T[array_size_];
		std::copy(array_, array_ + count_, s1);
		//for (int i = 0; i < count_; i++)
		//std::copy(int i = 0; i < count; i++)
		//	s1[i] = array_[i];
		delete[] array_;
		array_ = s1;
	}
	array_[count_] = value;
	count_++;
}

template <typename T>
void stack<T>::pop()
{
	if (count_ == 0)
		throw "Stack is empty" ;
	count_--;
}

template <typename T>
void stack<T>::print() const
{
	for (int i = 0; i < array_size_; i++)
		cout << array_[i];
}

template<typename T>
stack<T>& stack<T>::operator=(stack<T> & tmp)
{
	if (this != &tmp)
	{
		stack(tmp).swap(*this);
	}
	return *this;
}
<commit_msg>Update stack.hpp<commit_after>#include <iostream>

using namespace std;

template <typename T>
class stack
{
public:
	stack();/*noexept*/
	stack(const stack<T> &);/*no safety*/
	size_t count() const; /*noexcept*/
	void print()const;/*no safety*/
	void push(T const &); /*no safety*/
	void swap(stack<T>&); /*noexcept*/
	void pop(); /*no safety*/
	T top(); /*strong*/
	bool empty() const; /*noexcept*/
	stack<T>& operator=(stack<T> &); /*basic*/
	~stack();/*noexcept*/
private:
	T * array_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
stack<T>::stack() : count_(0), array_size_(0), array_{ nullptr }
{}

template<class T>
stack<T>::~stack()
{
	count_ = 0;
	array_size_ = 0;
	delete[] array_;
}

template <typename T>
stack<T>::stack(const stack<T>& copy)
{
	array_size_ = copy.array_size_;
	count_ = copy.count_;
	array_ = new T[count_];
	std::copy(copy.array_, copy.array_ + copy.count_, array_);
}

template<class T>
size_t stack<T>::count() const
{
	return count_;
}

template <typename T>
bool stack<T>::empty() const
{
	return (count_ == 0);
}

template<typename T>
void stack<T>::swap(stack& x)
{
	std::swap(x.array_size_, array_size_);
	std::swap(count_, x.count_);
	std::swap(x.array_, array_);
}

template <typename T>
T stack<T>::top()
{
	if (empty())
	{
		std::cout << "Stack is empty!";
	}
	return array_[count_ - 1];
}

template <typename T>
void stack<T>::push(T const &value)
{
	if (array_size_ == 0)
	{
		array_size_ = 1;
		array_ = new T[array_size_];
	}
	else if (array_size_ == count_)
	{
		array_size_ = array_size_ * 2;
		T *s1 = new T[array_size_];
		std::copy(array_, array_ + count_, s1);
		//for (int i = 0; i < count_; i++)
		//std::copy(int i = 0; i < count; i++)
		//	s1[i] = array_[i];
		delete[] array_;
		array_ = s1;
	}
	array_[count_] = value;
	count_++;
}

template <typename T>
void stack<T>::pop()
{
	if (count_ == 0)
		throw "Stack is empty" ;
	count_--;
}

template <typename T>
void stack<T>::print() const
{
	for (int i = 0; i < array_size_; i++)
		cout << array_[i];
}

template<typename T>
stack<T>& stack<T>::operator=(stack<T> & tmp)
{
	if (this != &tmp)
	{
		stack(tmp).swap(*this);
	}
	return *this;
}
<|endoftext|>


<commit_before>// Copyright 2010 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string>
#include <sstream>
#include <cstdlib>
#include <cmath>

#ifndef UTILS_HPP
#define UTILS_HPP

namespace isa {

namespace utils {

// Convert value into a string
template< typename T > std::string toString(T value);
template< typename T > std::string * toStringPointer(T value);

// Replace the occurrences of placeholder in src with value
std::string * replace(std::string * src, std::string placeholder, std::string & value, bool deleteSrc = false);

// Casts value from N to T
template< typename N, typename T > T castToType(N value);

// Compare two single precision floats
bool same(const float result, const float expected);

// Divide x by 10^9
double giga(long long unsigned int x);
// Divide x by 10^6
double mega(long long unsigned int x);
// Divide x by 2^30
double gibi(long long unsigned int x);
// Divide x by 2^20
double mebi(long long unsigned int x);

// Modify the endianness of a 32 bits value
// See http://stackoverflow.com/questions/2782725/converting-float-values-from-big-endian-to-little-endian
void bigEndianToLittleEndian(char * value);

// Pad x to be a multiple of padding
long long unsigned int pad(long long unsigned int x, unsigned int padding);

// Bit operations
template< typename T > inline uint8_t getBit(const T value, const uint8_t bit);
template< typename T > inline void setBit(T & value, const uint8_t newBit, const uint8_t bit);

// Implementations

template< typename T > inline std::string toString(T value) {
	return castToType< T, std::string >(value);
}

template< typename T > inline std::string * toStringPointer(T value) {
	std::string temp = castToType< T, std::string >(value);
	return new std::string(temp);
}

template< typename N, typename T > T castToType(N value) {
	T toRet;

  std::stringstream converter;
	converter << value;
	converter >> toRet;

	return toRet;
}

inline bool same(const float result, const float expected) {
	return abs(result - expected) < 1e-6;
}

inline double giga(long long unsigned int x) {
	return x / 1000000000.0;
}

inline double mega(long long unsigned int x) {
	return x / 1000000.0;
}

inline double gibi(long long unsigned int x) {
	return x / 1073741824.0;
}

inline double mebi(long long unsigned int x) {
	return x / 1048576.0;
}

inline long long unsigned int pad(long long unsigned int x, unsigned int padding) {
	if ( (x % padding) == 0 ) {
		return x;
	} else {
    return static_cast< long long unsigned int >(padding * std::ceil(x / static_cast< double >(padding)));
	}
}

template< typename T > inline uint8_t getBit(const T value, const uint8_t bit) {
  return static_cast< uint8_t >((value >> bit) & 1);
}

template< typename T > inline void setBit(T & value, const uint8_t newBit, const uint8_t bit) {
  value ^= (-newBit ^ value) & (1 << bit);
}

} // utils
} // isa

#endif // UTILS_HPP
<commit_msg>Adding the same() function for doubles, plus making it possible to specify the error.<commit_after>// Copyright 2010 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string>
#include <sstream>
#include <cstdlib>
#include <cmath>

#ifndef UTILS_HPP
#define UTILS_HPP

namespace isa {

namespace utils {

// Convert value into a string
template< typename T > std::string toString(T value);
template< typename T > std::string * toStringPointer(T value);

// Replace the occurrences of placeholder in src with value
std::string * replace(std::string * src, std::string placeholder, std::string & value, bool deleteSrc = false);

// Casts value from N to T
template< typename N, typename T > T castToType(N value);

// Compare two single precision floats
bool same(const float result, const float expected);
bool same(const float result, const float expected, const float error);
// Compare two double precision floats
bool same(const double result, const double expected);
bool same(const double result, const double expected, const double error);

// Divide x by 10^9
double giga(long long unsigned int x);
// Divide x by 10^6
double mega(long long unsigned int x);
// Divide x by 2^30
double gibi(long long unsigned int x);
// Divide x by 2^20
double mebi(long long unsigned int x);

// Modify the endianness of a 32 bits value
// See http://stackoverflow.com/questions/2782725/converting-float-values-from-big-endian-to-little-endian
void bigEndianToLittleEndian(char * value);

// Pad x to be a multiple of padding
long long unsigned int pad(long long unsigned int x, unsigned int padding);

// Bit operations
template< typename T > inline uint8_t getBit(const T value, const uint8_t bit);
template< typename T > inline void setBit(T & value, const uint8_t newBit, const uint8_t bit);

// Implementations

template< typename T > inline std::string toString(T value) {
	return castToType< T, std::string >(value);
}

template< typename T > inline std::string * toStringPointer(T value) {
	std::string temp = castToType< T, std::string >(value);
	return new std::string(temp);
}

template< typename N, typename T > T castToType(N value) {
	T toRet;

  std::stringstream converter;
	converter << value;
	converter >> toRet;

	return toRet;
}

inline bool same(const float result, const float expected) {
	return abs(result - expected) < 1e-6;
}

inline bool same(const float result, const float expected, const float error) {
	return abs(result - expected) < error;
}

inline bool same(const double result, const double expected) {
	return abs(result - expected) < 1e-6;
}

inline bool same(const double result, const double expected, const double error) {
	return abs(result - expected) < error;
}

inline double giga(long long unsigned int x) {
	return x / 1000000000.0;
}

inline double mega(long long unsigned int x) {
	return x / 1000000.0;
}

inline double gibi(long long unsigned int x) {
	return x / 1073741824.0;
}

inline double mebi(long long unsigned int x) {
	return x / 1048576.0;
}

inline long long unsigned int pad(long long unsigned int x, unsigned int padding) {
	if ( (x % padding) == 0 ) {
		return x;
	} else {
    return static_cast< long long unsigned int >(padding * std::ceil(x / static_cast< double >(padding)));
	}
}

template< typename T > inline uint8_t getBit(const T value, const uint8_t bit) {
  return static_cast< uint8_t >((value >> bit) & 1);
}

template< typename T > inline void setBit(T & value, const uint8_t newBit, const uint8_t bit) {
  value ^= (-newBit ^ value) & (1 << bit);
}

} // utils
} // isa

#endif // UTILS_HPP
<|endoftext|>


<commit_before>#include "textures_gl_forward.h"
#include "mathlib.h"
#include <assert.h>
#include <stdint.h>

#include "dds_helper.h"

// Instead of rebinding the texture, GL_TEXTURES_ALTERNATE_BIND_POINT says "let's bind the textures
// into different samplers, then use a simple glUniform call to update which sampler we're using."
// This turns out to be super expensive, because validating that mapping is much more expensive that
// the validation that has to occur from just calling activeTexture/bindTexture
#define GL_TEXTURES_ALTERNATE_BIND_POINT 0

Textures_GL_Forward::Textures_GL_Forward()
    : m_ib()
    , m_vb_pos()
    , m_vb_tex()
    , m_tex1()
    , m_tex2()
    , m_vs()
    , m_fs()
    , m_prog()
    , m_transform_buffer()
{}

Textures_GL_Forward::~Textures_GL_Forward()
{
    glDeleteBuffers(1, &m_ib);
    glDeleteBuffers(1, &m_vb_pos);
    glDeleteBuffers(1, &m_vb_tex);
    glDeleteBuffers(1, &m_transform_buffer);
    glDeleteTextures(1, &m_tex1);
    glDeleteTextures(1, &m_tex2);
    glDeleteShader(m_vs);
    glDeleteShader(m_fs);
    glDeleteProgram(m_prog);
}

bool Textures_GL_Forward::init()
{
    // Shaders
    if (!create_shader(GL_VERTEX_SHADER, "textures_gl_forward_vs.glsl", &m_vs))
        return false;

    if (!create_shader(GL_FRAGMENT_SHADER, "textures_gl_forward_fs.glsl", &m_fs))
        return false;

    if (!compile_program(&m_prog, m_vs, m_fs, 0))
        return false;

    // Buffers
    Vec3 vertices_pos[] =
    {
        { -0.5, -0.5f,  0.0f },
        {  0.5, -0.5f,  0.0f },
        {  0.5,  0.5f,  0.0f },
        { -0.5,  0.5f,  0.0f },
    };

    Vec2 vertices_tex[] =
    {
        { 0, 0 },
        { 0, 1 },
        { 1, 0 },
        { 1, 1 }
    };

    GLushort indices[] =
    {
        0, 1, 2, 0, 2, 3,
    };

    GLuint texs[2] = { 0 };

    glGenTextures(2, texs);
    m_tex1 = texs[0];
    m_tex2 = texs[1];
    // Textures (TODO: This should go in a utility function elsewhere).
    TextureDetails tex_details;
    if (!readDDSFromFile("Media/tex/Mandelbrot.dds", &tex_details)) {
        return false;
    }

    glBindTexture(GL_TEXTURE_2D, m_tex1);
    glTexStorage2D(GL_TEXTURE_2D, tex_details.szMipMapCount, tex_details.glFormat,
                   tex_details.dwWidth, tex_details.dwHeight);

    size_t offset = 0;
    for (int mip = 0; mip < tex_details.szMipMapCount; ++mip) {
        glCompressedTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, tex_details.MipMapWidth(mip), tex_details.MipMapHeight(mip), tex_details.glFormat, tex_details.pSizes[mip], (char*)tex_details.pPixels + offset);
        offset += tex_details.pSizes[mip];
    }

    if (!readDDSFromFile("Media/tex/image.dds", &tex_details)) {
        return false;
    }

    glBindTexture(GL_TEXTURE_2D, m_tex2);
    glTexStorage2D(GL_TEXTURE_2D, tex_details.szMipMapCount, tex_details.glFormat,
                   tex_details.dwWidth, tex_details.dwHeight);

    offset = 0;
    for (int mip = 0; mip < tex_details.szMipMapCount; ++mip) {
        glCompressedTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, tex_details.MipMapWidth(mip), tex_details.MipMapHeight(mip), tex_details.glFormat, tex_details.pSizes[mip], (char*)tex_details.pPixels + offset);
        offset += tex_details.pSizes[mip];
    }

    // Buffers
    GLuint vbs[2] = { 0 };

    glGenBuffers(2, vbs);
    m_vb_pos = vbs[0];
    m_vb_tex = vbs[1];

    glBindBuffer(GL_ARRAY_BUFFER, m_vb_pos);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_pos), vertices_pos, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, m_vb_tex);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_tex), vertices_tex, GL_STATIC_DRAW);

    glGenBuffers(1, &m_ib);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glGenBuffers(1, &m_transform_buffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_transform_buffer);

    return glGetError() == GL_NO_ERROR;
}

bool Textures_GL_Forward::begin(void* window, GfxSwapChain* swap_chain, GfxFrameBuffer* frame_buffer)
{
    HWND hWnd = reinterpret_cast<HWND>(window);

    RECT rc;
    GetClientRect(hWnd, &rc);
    int width = rc.right - rc.left;
    int height = rc.bottom - rc.top;

    // Bind and clear frame buffer
    int fbo = PTR_AS_INT(frame_buffer);
    float c[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
    float d = 1.0f;
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    glClearBufferfv(GL_COLOR, 0, c);
    glClearBufferfv(GL_DEPTH, 0, &d);

    // Program
    Vec3 dir = { 0, 0, 1 };
    Vec3 at = { 0, 0, 0 };
    Vec3 up = { 0, 1, 0 };
    dir = normalize(dir);
    Vec3 eye = at - 250 * dir;
    Matrix view = matrix_look_at(eye, at, up);
    Matrix proj = matrix_perspective_rh_gl(radians(45.0f), (float)width / (float)height, 0.1f, 10000.0f);
    Matrix view_proj = proj * view;

    glUseProgram(m_prog);
    glUniformMatrix4fv(0, 1, GL_TRUE, &view_proj.x.x);
    // We will bind the texture we care about to unit 0, if we're not doing GL_TEXTURES_ALTERNATE_BIND_POINT
#if !GL_TEXTURES_ALTERNATE_BIND_POINT
    glUniform1i(128, 0);
#endif

    // Input Layout. First the IB
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib);

    // Then the VBs (SOA).
    glBindBuffer(GL_ARRAY_BUFFER, m_vb_pos);
    glVertexAttribPointer(0, 3, GL_FLOAT, FALSE, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, m_vb_tex);
    glVertexAttribPointer(1, 2, GL_FLOAT, FALSE, 0, 0);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    // Rasterizer State
    glEnable(GL_CULL_FACE);
    glCullFace(GL_FRONT);
    glFrontFace(GL_CCW);

    glDisable(GL_SCISSOR_TEST);
    glViewport(0, 0, width, height);

    // Blend State
    glDisable(GL_BLEND);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

    // Depth Stencil State
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

#if GL_TEXTURES_ALTERNATE_BIND_POINT
    glActiveTexture(GL_TEXTURE0 + 0);
    glBindTexture(GL_TEXTURE_2D, m_tex1);

    glActiveTexture(GL_TEXTURE0 + 1);
    glBindTexture(GL_TEXTURE_2D, m_tex2);
#endif

    return true;
}

void Textures_GL_Forward::end(GfxSwapChain* swap_chain)
{
    SwapBuffers(swap_chain->hdc);
#if defined(_DEBUG)
    GLenum error = glGetError();
    assert(error == GL_NO_ERROR);
#endif
}

void Textures_GL_Forward::draw(Matrix* transforms, int count)
{
    assert(count <= TEXTURES_COUNT);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_transform_buffer);
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Matrix) * count, transforms, GL_DYNAMIC_DRAW);

    for (int i = 0; i < count; ++i) {
        // Update the draw ID (since we cannot use multi_draw here
        glUniform1i(1, i);

#if GL_TEXTURES_ALTERNATE_BIND_POINT
        glUniform1i(128, ((i & 1) == 1) ? 1 : 0);
#else
        // And update our texture via binding.
        GLuint activeTex = 0;
        activeTex = ((i & 1) == 1) ? m_tex2 : m_tex1;

#if GL_USE_DIRECT_STATE_ACCESS
        glBindMultiTextureEXT(GL_TEXTURE0, GL_TEXTURE_2D, activeTex);
#else
        glActiveTexture(GL_TEXTURE0 + 0);
        glBindTexture(GL_TEXTURE_2D, activeTex);
#endif
#endif
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
    }
}
<commit_msg>Remove useless GL_TEXTURES_ALTERNATE_BIND_POINT, which is slow and wouldn't ever really be used in production.<commit_after>#include "textures_gl_forward.h"
#include "mathlib.h"
#include <assert.h>
#include <stdint.h>

#include "dds_helper.h"

Textures_GL_Forward::Textures_GL_Forward()
    : m_ib()
    , m_vb_pos()
    , m_vb_tex()
    , m_tex1()
    , m_tex2()
    , m_vs()
    , m_fs()
    , m_prog()
    , m_transform_buffer()
{}

Textures_GL_Forward::~Textures_GL_Forward()
{
    glDeleteBuffers(1, &m_ib);
    glDeleteBuffers(1, &m_vb_pos);
    glDeleteBuffers(1, &m_vb_tex);
    glDeleteBuffers(1, &m_transform_buffer);
    glDeleteTextures(1, &m_tex1);
    glDeleteTextures(1, &m_tex2);
    glDeleteShader(m_vs);
    glDeleteShader(m_fs);
    glDeleteProgram(m_prog);
}

bool Textures_GL_Forward::init()
{
    // Shaders
    if (!create_shader(GL_VERTEX_SHADER, "textures_gl_forward_vs.glsl", &m_vs))
        return false;

    if (!create_shader(GL_FRAGMENT_SHADER, "textures_gl_forward_fs.glsl", &m_fs))
        return false;

    if (!compile_program(&m_prog, m_vs, m_fs, 0))
        return false;

    // Buffers
    Vec3 vertices_pos[] =
    {
        { -0.5, -0.5f,  0.0f },
        {  0.5, -0.5f,  0.0f },
        {  0.5,  0.5f,  0.0f },
        { -0.5,  0.5f,  0.0f },
    };

    Vec2 vertices_tex[] =
    {
        { 0, 0 },
        { 0, 1 },
        { 1, 0 },
        { 1, 1 }
    };

    GLushort indices[] =
    {
        0, 1, 2, 0, 2, 3,
    };

    GLuint texs[2] = { 0 };

    glGenTextures(2, texs);
    m_tex1 = texs[0];
    m_tex2 = texs[1];
    // Textures (TODO: This should go in a utility function elsewhere).
    TextureDetails tex_details;
    if (!readDDSFromFile("Media/tex/Mandelbrot.dds", &tex_details)) {
        return false;
    }

    glBindTexture(GL_TEXTURE_2D, m_tex1);
    glTexStorage2D(GL_TEXTURE_2D, tex_details.szMipMapCount, tex_details.glFormat,
                   tex_details.dwWidth, tex_details.dwHeight);

    size_t offset = 0;
    for (int mip = 0; mip < tex_details.szMipMapCount; ++mip) {
        glCompressedTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, tex_details.MipMapWidth(mip), tex_details.MipMapHeight(mip), tex_details.glFormat, tex_details.pSizes[mip], (char*)tex_details.pPixels + offset);
        offset += tex_details.pSizes[mip];
    }

    if (!readDDSFromFile("Media/tex/image.dds", &tex_details)) {
        return false;
    }

    glBindTexture(GL_TEXTURE_2D, m_tex2);
    glTexStorage2D(GL_TEXTURE_2D, tex_details.szMipMapCount, tex_details.glFormat,
                   tex_details.dwWidth, tex_details.dwHeight);

    offset = 0;
    for (int mip = 0; mip < tex_details.szMipMapCount; ++mip) {
        glCompressedTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, tex_details.MipMapWidth(mip), tex_details.MipMapHeight(mip), tex_details.glFormat, tex_details.pSizes[mip], (char*)tex_details.pPixels + offset);
        offset += tex_details.pSizes[mip];
    }

    // Buffers
    GLuint vbs[2] = { 0 };

    glGenBuffers(2, vbs);
    m_vb_pos = vbs[0];
    m_vb_tex = vbs[1];

    glBindBuffer(GL_ARRAY_BUFFER, m_vb_pos);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_pos), vertices_pos, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, m_vb_tex);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_tex), vertices_tex, GL_STATIC_DRAW);

    glGenBuffers(1, &m_ib);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glGenBuffers(1, &m_transform_buffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_transform_buffer);

    return glGetError() == GL_NO_ERROR;
}

bool Textures_GL_Forward::begin(void* window, GfxSwapChain* swap_chain, GfxFrameBuffer* frame_buffer)
{
    HWND hWnd = reinterpret_cast<HWND>(window);

    RECT rc;
    GetClientRect(hWnd, &rc);
    int width = rc.right - rc.left;
    int height = rc.bottom - rc.top;

    // Bind and clear frame buffer
    int fbo = PTR_AS_INT(frame_buffer);
    float c[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
    float d = 1.0f;
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    glClearBufferfv(GL_COLOR, 0, c);
    glClearBufferfv(GL_DEPTH, 0, &d);

    // Program
    Vec3 dir = { 0, 0, 1 };
    Vec3 at = { 0, 0, 0 };
    Vec3 up = { 0, 1, 0 };
    dir = normalize(dir);
    Vec3 eye = at - 250 * dir;
    Matrix view = matrix_look_at(eye, at, up);
    Matrix proj = matrix_perspective_rh_gl(radians(45.0f), (float)width / (float)height, 0.1f, 10000.0f);
    Matrix view_proj = proj * view;

    glUseProgram(m_prog);
    glUniformMatrix4fv(0, 1, GL_TRUE, &view_proj.x.x);
    // We will bind the texture we care about to unit 0, so let the program know now.
    glUniform1i(128, 0);

    // Input Layout. First the IB
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib);

    // Then the VBs (SOA).
    glBindBuffer(GL_ARRAY_BUFFER, m_vb_pos);
    glVertexAttribPointer(0, 3, GL_FLOAT, FALSE, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, m_vb_tex);
    glVertexAttribPointer(1, 2, GL_FLOAT, FALSE, 0, 0);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    // Rasterizer State
    glEnable(GL_CULL_FACE);
    glCullFace(GL_FRONT);
    glFrontFace(GL_CCW);

    glDisable(GL_SCISSOR_TEST);
    glViewport(0, 0, width, height);

    // Blend State
    glDisable(GL_BLEND);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

    // Depth Stencil State
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    return true;
}

void Textures_GL_Forward::end(GfxSwapChain* swap_chain)
{
    SwapBuffers(swap_chain->hdc);
#if defined(_DEBUG)
    GLenum error = glGetError();
    assert(error == GL_NO_ERROR);
#endif
}

void Textures_GL_Forward::draw(Matrix* transforms, int count)
{
    assert(count <= TEXTURES_COUNT);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_transform_buffer);
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Matrix) * count, transforms, GL_DYNAMIC_DRAW);

    for (int i = 0; i < count; ++i) {
        // Update the draw ID (since we cannot use multi_draw here
        glUniform1i(1, i);

        // And update our texture via binding.
        GLuint activeTex = 0;
        activeTex = ((i & 1) == 1) ? m_tex2 : m_tex1;

#if GL_USE_DIRECT_STATE_ACCESS
        glBindMultiTextureEXT(GL_TEXTURE0, GL_TEXTURE_2D, activeTex);
#else
        glActiveTexture(GL_TEXTURE0 + 0);
        glBindTexture(GL_TEXTURE_2D, activeTex);
#endif
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
	> File Name: main.cpp
	> Author:
	> Mail:
	> Created Time: 2016年02月17日 星期三 22时01分17秒
 ************************************************************************/

#include <iostream>
#include <thread>
#include <chrono>
#include <functional>
#include "CThreadManage.h"
#include "CRealJob.h"

void doTask(void* jobData)
{
    (void)jobData;
    std::cout << "Hello world" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
}

int main()
{
    CThreadManagePtr manage(new CThreadManage);
    manage->initThreadNum(10);

    for (int i = 0; i < 100; ++i)
    {
        CRealJobPtr job(new CRealJob(std::bind(doTask, std::placeholders::_1), NULL));
        manage->run(job);
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    std::cout << "##############END###################" << std::endl;
    return 0;
}
<commit_msg>Update threadpool<commit_after>/*************************************************************************
	> File Name: main.cpp
	> Author:
	> Mail:
	> Created Time: 2016年02月17日 星期三 22时01分17秒
 ************************************************************************/

#include <iostream>
#include <thread>
#include <chrono>
#include <functional>
#include "CThreadManage.h"
#include "CRealJob.h"

void doTask(void* jobData)
{
    (void)jobData;
    std::cout << "Hello world" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
}

int main()
{
    CThreadManagePtr manage(new CThreadManage);
    manage->initThreadNum(10);

    for (int i = 0; i < 100; ++i)
    {
        CRealJobPtr job(new CRealJob(std::bind(doTask, std::placeholders::_1), nullptr));
        manage->run(job);
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    std::cout << "##############END###################" << std::endl;
    return 0;
}
<|endoftext|>