<commit_before>/* Please avoid #include'ing this file from other headers unless you absolutely
 * need to. Please #include "perfmon_types.hpp" instead. This helps avoid
 * potential circular dependency problems, since perfmons are used all over the
 * place but also depend on a significant chunk of our threading infrastructure
 * (by way of get_thread_id() & co).
 */
#ifndef __PERFMON_HPP__
#define __PERFMON_HPP__

#include <stdarg.h>

#include <map>
#include <limits>
#include <string>

#include "arch/runtime/runtime.hpp"
#include "utils.hpp"
#include "config/args.hpp"
#include "containers/intrusive_list.hpp"
#include "stats/control.hpp"
#include "perfmon_types.hpp"

// Pad a value to the size of a cache line to avoid false sharing.
// TODO: This is implemented as a struct with subtraction rather than a union
// so that it gives an error when trying to pad a value bigger than
// CACHE_LINE_SIZE. If that's needed, this may have to be done differently.
// TODO: Use this in the rest of the perfmons, if it turns out to make any
// difference.

template<typename value_t>
struct cache_line_padded_t {
    value_t value;
    char padding[CACHE_LINE_SIZE - sizeof(value_t)];
};

/* The perfmon (short for "PERFormance MONitor") is responsible for gathering data about
various parts of the server. */

/* A perfmon_stats_t is just a mapping from string keys to string values; it
stores statistics about the server. */

typedef std::map<std::string, std::string> perfmon_stats_t;

/* perfmon_get_stats() collects all the stats about the server and puts them
into the given perfmon_stats_t object. It must be run in a coroutine and it blocks
until it is done. */

void perfmon_get_stats(perfmon_stats_t *dest, bool include_internal);

/* A perfmon_t represents a stat about the server.

To monitor something, declare a global variable that is an instance of a subclass of
perfmon_t and pass its name to the constructor. It is not safe to create a perfmon_t
after the server starts up because the global list is not thread-safe. */

class perfmon_t :
    public intrusive_list_node_t<perfmon_t>
{
public:
    bool internal;
public:
    perfmon_t(bool internal = true);
    virtual ~perfmon_t();

    /* To get a value from a given perfmon: Call begin_stats(). On each core, call the visit_stats()
    method with the pointer that was returned from begin_stats(). Then call end_stats() on the
    pointer on the same core that you called begin_stats() on.

    You usually want to call perfmon_get_stats() instead of calling these methods directly. */
    virtual void *begin_stats() = 0;
    virtual void visit_stats(void *) = 0;
    virtual void end_stats(void *, perfmon_stats_t *) = 0;
};

/* When `global_full_perfmon` is true, some perfmons will perform more elaborate stat
calculations, which might take longer but will produce more informative performance
stats. The command-line flag `--full-perfmon` sets `global_full_perfmon` to true. */

extern bool global_full_perfmon;

// Abstract perfmon subclass that implements perfmon tracking by combining per-thread values.
template<typename thread_stat_t, typename combined_stat_t = thread_stat_t>
struct perfmon_perthread_t
    : public perfmon_t
{
    perfmon_perthread_t(bool internal = true) : perfmon_t(internal) {};

    void *begin_stats() {
        return new thread_stat_t[get_num_threads()];
    }
    void visit_stats(void *data) {
        get_thread_stat(&(reinterpret_cast<thread_stat_t *>(data))[get_thread_id()]);
    }
    void end_stats(void *data, perfmon_stats_t *dest) {
        combined_stat_t combined = combine_stats(reinterpret_cast<thread_stat_t *>(data));
        output_stat(combined, dest);
        delete[] reinterpret_cast<thread_stat_t *>(data);
    }

  protected:
    virtual void get_thread_stat(thread_stat_t *) = 0;
    virtual combined_stat_t combine_stats(thread_stat_t *) = 0;
    virtual void output_stat(const combined_stat_t &, perfmon_stats_t *) = 0;
};

/* perfmon_counter_t is a perfmon_t that keeps a global counter that can be incremented
and decremented. (Internally, it keeps many individual counters for thread-safety.) */
class perfmon_counter_t :
    // TODO (rntz) does having the values when collecting stats be cache-padded matter?
    public perfmon_perthread_t<cache_line_padded_t<int64_t>, int64_t>
{
    friend class perfmon_counter_step_t;
  protected:
    typedef cache_line_padded_t<int64_t> padded_int64_t;
    std::string name;
    padded_int64_t thread_data[MAX_THREADS];
    int64_t &get();

    void get_thread_stat(padded_int64_t *);
    int64_t combine_stats(padded_int64_t *);
    void output_stat(const int64_t&, perfmon_stats_t *);
  public:
    explicit perfmon_counter_t(std::string name, bool internal = true);
    void operator++(int) { get()++; }
    void operator+=(int64_t num) { get() += num; }
    void operator--(int) { get()--; }
    void operator-=(int64_t num) { get() -= num; }
};

/* perfmon_sampler_t is a perfmon_t that keeps a log of events that happen. When something
happens, call the perfmon_sampler_t's record() method. The perfmon_sampler_t will retain that
record until 'length' ticks have passed. It will produce stats for the number of records in the
time period, the average record, and the min and max records. */

// need to use a namespace, not inner classes, so we can pass the auxiliary
// classes to the templated base classes
namespace perfmon_sampler {
    struct stats_t {
        int count;
        double sum, min, max;
        stats_t() : count(0), sum(0),
            min(std::numeric_limits<double>::max()),
            max(std::numeric_limits<double>::min())
            { }
        void record(double v) {
            count++;
            sum += v;
            if (count) {
                min = std::min(min, v);
                max = std::max(max, v);
            } else {
                min = max = v;
            }
        }
        void aggregate(const stats_t &s) {
            count += s.count;
            sum += s.sum;
            if (s.count) {
                min = std::min(min, s.min);
                max = std::max(max, s.max);
            }
        }
    };
}

class perfmon_sampler_t
    : public perfmon_perthread_t<perfmon_sampler::stats_t>
{
    typedef perfmon_sampler::stats_t stats_t;
    struct thread_info_t {
        stats_t current_stats, last_stats;
        int current_interval;
    } thread_data[MAX_THREADS];

    void get_thread_stat(stats_t *);
    stats_t combine_stats(stats_t *);
    void output_stat(const stats_t&, perfmon_stats_t *);

    void update(ticks_t now);

    std::string name;
    ticks_t length;
    bool include_rate;
  public:
    perfmon_sampler_t(std::string name, ticks_t length, bool include_rate = false, bool internal = true);
    void record(double value);
};

/* Tracks the mean and standard deviation of a sequence value in constant space
 * & time.
 */

// One-pass variance calculation algorithm/datastructure taken from
// http://www.cs.berkeley.edu/~mhoemmen/cs194/Tutorials/variance.pdf
struct stddev_t {
    stddev_t();
    stddev_t(size_t datapoints, float mean, float variance);

    void add(float value);
    size_t datapoints() const;
    float mean() const;
    float standard_deviation() const;
    float standard_variance() const;
    //stddev_t merge(const stddev_t &other);
    static stddev_t combine(size_t nelts, stddev_t *data);

  private:
    // N is the number of datapoints, M is the current mean, Q/N is
    // the standard variance, and sqrt(Q/N) is the standard
    // deviation. Read the paper for why it works or use algebra.
    //
    // (Note that this is a better scheme numerically than using the
    // classic calculator technique of storing sum(x), sum(x^2), n.)
    size_t N;
    float M, Q;
};

struct perfmon_stddev_t
    : public perfmon_perthread_t<stddev_t>
{
    // should be possible to make this a templated class if necessary
    explicit perfmon_stddev_t(std::string name, bool internal = true);
    void record(float value);

  protected:
    std::string name;

    void get_thread_stat(stddev_t *);
    stddev_t combine_stats(stddev_t *);
    void output_stat(const stddev_t&, perfmon_stats_t *);
  private:
    stddev_t thread_data[MAX_THREADS]; // TODO (rntz) should this be cache-line padded?
};

/* `perfmon_rate_monitor_t` keeps track of the number of times some event happens
per second. It is different from `perfmon_sampler_t` in that it does not associate
a number with each event, but you can record many events at once. For example, it
would be good for recording how fast bytes are sent over the network. */

class perfmon_rate_monitor_t
    : public perfmon_perthread_t<double>
{
private:
    struct thread_info_t {
        double current_count, last_count;
        int current_interval;
    } thread_data[MAX_THREADS];
    void update(ticks_t now);
    std::string name;
    ticks_t length;

    void get_thread_stat(double *);
    double combine_stats(double *);
    void output_stat(const double&, perfmon_stats_t *);
public:
    perfmon_rate_monitor_t(std::string name, ticks_t length, bool internal = true);
    void record(double value = 1.0);
};

/* perfmon_duration_sampler_t is a perfmon_t that monitors events that have a
 * starting and ending time. When something starts, call begin(); when
 * something ends, call end() with the same value as begin. It will produce
 * stats for the number of active events, the average length of an event, and
 * so on. If `global_full_perfmon` is false, it won't report any timing-related
 * stats because `get_ticks()` is rather slow.
 *
 * Frequently we're in the case
 * where we'd like to have a single slow perfmon up, but don't want the other
 * ones, perfmon_duration_sampler_t has an ignore_global_full_perfmon
 * field on it, which when true makes it run regardless of --full-perfmon flag
 * this can also be enable and disabled at runtime. */

struct perfmon_duration_sampler_t
    : public control_t
{

private:
    perfmon_counter_t active;
    perfmon_counter_t total;
    perfmon_sampler_t recent;
    bool ignore_global_full_perfmon;
public:
    perfmon_duration_sampler_t(std::string name, ticks_t length, bool internal = true, bool ignore_global_full_perfmon = false)
        : control_t(std::string("pm_") + name + "_toggle", name + " toggle on and off", true),
          active(name + "_active_count", internal), total(name + "_total", internal),
          recent(name, length, true, internal), ignore_global_full_perfmon(ignore_global_full_perfmon)
        { }
    void begin(ticks_t *v) {
        active++;
        total++;
        if (global_full_perfmon || ignore_global_full_perfmon) *v = get_ticks();
        else *v = 0;
    }
    void end(ticks_t *v) {
        active--;
        if (*v != 0) recent.record(ticks_to_secs(get_ticks() - *v));
    }

//Control interface used for enabling and disabling duration samplers at run time
public:
    std::string call(UNUSED int argc, UNUSED char **argv) {
        ignore_global_full_perfmon = !ignore_global_full_perfmon;
        if (ignore_global_full_perfmon) {
            return "Enabled\n";
        }
        else {
            return "Disabled\n";
        }
    }
};

/* perfmon_function_t is a perfmon for calling an arbitrary function to compute a stat. You should
not create such a perfmon at runtime; instead, declare it as a static variable and then construct
a perfmon_function_t::internal_function_t instance for it. This way things get called on the
right cores and if there are multiple internal_function_t instances the perfmon_function_t can
combine them by inserting commas. */
struct perfmon_function_t :
    public perfmon_t
{
public:
    class internal_function_t :
        public intrusive_list_node_t<internal_function_t>
    {
    public:
        internal_function_t(perfmon_function_t *p);
        virtual ~internal_function_t();
        virtual std::string compute_stat() = 0;
    private:
        perfmon_function_t *parent;
    };

private:
    friend class internal_function_t;
    std::string name;
    intrusive_list_t<internal_function_t> funs[MAX_THREADS];

public:
    perfmon_function_t(std::string name, bool internal = true)
        : perfmon_t(internal), name(name) {}
    ~perfmon_function_t() {}

    void *begin_stats();
    void visit_stats(void *data);
    void end_stats(void *data, perfmon_stats_t *dest);
};

struct block_pm_duration {
    ticks_t time;
    bool ended;
    perfmon_duration_sampler_t *pm;
    block_pm_duration(perfmon_duration_sampler_t *pm)
        : ended(false), pm(pm)
    {
        pm->begin(&time);
    }
    void end() {
        rassert(!ended);
        ended = true;
        pm->end(&time);
    }
    ~block_pm_duration() {
        if (!ended) end();
    }
};

#endif /* __PERFMON_HPP__ */
<commit_msg>Removed arch/runtime/runtime.hpp inclusion from perfmon.hpp.<commit_after>/* Please avoid #include'ing this file from other headers unless you absolutely
 * need to. Please #include "perfmon_types.hpp" instead. This helps avoid
 * potential circular dependency problems, since perfmons are used all over the
 * place but also depend on a significant chunk of our threading infrastructure
 * (by way of get_thread_id() & co).
 */
#ifndef __PERFMON_HPP__
#define __PERFMON_HPP__

#include <stdarg.h>

#include <map>
#include <limits>
#include <string>

#include "utils.hpp"
#include "config/args.hpp"
#include "containers/intrusive_list.hpp"
#include "stats/control.hpp"
#include "perfmon_types.hpp"

// Some arch/runtime declarations.
int get_num_threads();
int get_thread_id();

// Pad a value to the size of a cache line to avoid false sharing.
// TODO: This is implemented as a struct with subtraction rather than a union
// so that it gives an error when trying to pad a value bigger than
// CACHE_LINE_SIZE. If that's needed, this may have to be done differently.
// TODO: Use this in the rest of the perfmons, if it turns out to make any
// difference.

template<typename value_t>
struct cache_line_padded_t {
    value_t value;
    char padding[CACHE_LINE_SIZE - sizeof(value_t)];
};

/* The perfmon (short for "PERFormance MONitor") is responsible for gathering data about
various parts of the server. */

/* A perfmon_stats_t is just a mapping from string keys to string values; it
stores statistics about the server. */

typedef std::map<std::string, std::string> perfmon_stats_t;

/* perfmon_get_stats() collects all the stats about the server and puts them
into the given perfmon_stats_t object. It must be run in a coroutine and it blocks
until it is done. */

void perfmon_get_stats(perfmon_stats_t *dest, bool include_internal);

/* A perfmon_t represents a stat about the server.

To monitor something, declare a global variable that is an instance of a subclass of
perfmon_t and pass its name to the constructor. It is not safe to create a perfmon_t
after the server starts up because the global list is not thread-safe. */

class perfmon_t :
    public intrusive_list_node_t<perfmon_t>
{
public:
    bool internal;
public:
    perfmon_t(bool internal = true);
    virtual ~perfmon_t();

    /* To get a value from a given perfmon: Call begin_stats(). On each core, call the visit_stats()
    method with the pointer that was returned from begin_stats(). Then call end_stats() on the
    pointer on the same core that you called begin_stats() on.

    You usually want to call perfmon_get_stats() instead of calling these methods directly. */
    virtual void *begin_stats() = 0;
    virtual void visit_stats(void *) = 0;
    virtual void end_stats(void *, perfmon_stats_t *) = 0;
};

/* When `global_full_perfmon` is true, some perfmons will perform more elaborate stat
calculations, which might take longer but will produce more informative performance
stats. The command-line flag `--full-perfmon` sets `global_full_perfmon` to true. */

extern bool global_full_perfmon;

// Abstract perfmon subclass that implements perfmon tracking by combining per-thread values.
template<typename thread_stat_t, typename combined_stat_t = thread_stat_t>
struct perfmon_perthread_t
    : public perfmon_t
{
    perfmon_perthread_t(bool internal = true) : perfmon_t(internal) {};

    void *begin_stats() {
        return new thread_stat_t[get_num_threads()];
    }
    void visit_stats(void *data) {
        get_thread_stat(&(reinterpret_cast<thread_stat_t *>(data))[get_thread_id()]);
    }
    void end_stats(void *data, perfmon_stats_t *dest) {
        combined_stat_t combined = combine_stats(reinterpret_cast<thread_stat_t *>(data));
        output_stat(combined, dest);
        delete[] reinterpret_cast<thread_stat_t *>(data);
    }

  protected:
    virtual void get_thread_stat(thread_stat_t *) = 0;
    virtual combined_stat_t combine_stats(thread_stat_t *) = 0;
    virtual void output_stat(const combined_stat_t &, perfmon_stats_t *) = 0;
};

/* perfmon_counter_t is a perfmon_t that keeps a global counter that can be incremented
and decremented. (Internally, it keeps many individual counters for thread-safety.) */
class perfmon_counter_t :
    // TODO (rntz) does having the values when collecting stats be cache-padded matter?
    public perfmon_perthread_t<cache_line_padded_t<int64_t>, int64_t>
{
    friend class perfmon_counter_step_t;
  protected:
    typedef cache_line_padded_t<int64_t> padded_int64_t;
    std::string name;
    padded_int64_t thread_data[MAX_THREADS];
    int64_t &get();

    void get_thread_stat(padded_int64_t *);
    int64_t combine_stats(padded_int64_t *);
    void output_stat(const int64_t&, perfmon_stats_t *);
  public:
    explicit perfmon_counter_t(std::string name, bool internal = true);
    void operator++(int) { get()++; }
    void operator+=(int64_t num) { get() += num; }
    void operator--(int) { get()--; }
    void operator-=(int64_t num) { get() -= num; }
};

/* perfmon_sampler_t is a perfmon_t that keeps a log of events that happen. When something
happens, call the perfmon_sampler_t's record() method. The perfmon_sampler_t will retain that
record until 'length' ticks have passed. It will produce stats for the number of records in the
time period, the average record, and the min and max records. */

// need to use a namespace, not inner classes, so we can pass the auxiliary
// classes to the templated base classes
namespace perfmon_sampler {
    struct stats_t {
        int count;
        double sum, min, max;
        stats_t() : count(0), sum(0),
            min(std::numeric_limits<double>::max()),
            max(std::numeric_limits<double>::min())
            { }
        void record(double v) {
            count++;
            sum += v;
            if (count) {
                min = std::min(min, v);
                max = std::max(max, v);
            } else {
                min = max = v;
            }
        }
        void aggregate(const stats_t &s) {
            count += s.count;
            sum += s.sum;
            if (s.count) {
                min = std::min(min, s.min);
                max = std::max(max, s.max);
            }
        }
    };
}

class perfmon_sampler_t
    : public perfmon_perthread_t<perfmon_sampler::stats_t>
{
    typedef perfmon_sampler::stats_t stats_t;
    struct thread_info_t {
        stats_t current_stats, last_stats;
        int current_interval;
    } thread_data[MAX_THREADS];

    void get_thread_stat(stats_t *);
    stats_t combine_stats(stats_t *);
    void output_stat(const stats_t&, perfmon_stats_t *);

    void update(ticks_t now);

    std::string name;
    ticks_t length;
    bool include_rate;
  public:
    perfmon_sampler_t(std::string name, ticks_t length, bool include_rate = false, bool internal = true);
    void record(double value);
};

/* Tracks the mean and standard deviation of a sequence value in constant space
 * & time.
 */

// One-pass variance calculation algorithm/datastructure taken from
// http://www.cs.berkeley.edu/~mhoemmen/cs194/Tutorials/variance.pdf
struct stddev_t {
    stddev_t();
    stddev_t(size_t datapoints, float mean, float variance);

    void add(float value);
    size_t datapoints() const;
    float mean() const;
    float standard_deviation() const;
    float standard_variance() const;
    //stddev_t merge(const stddev_t &other);
    static stddev_t combine(size_t nelts, stddev_t *data);

  private:
    // N is the number of datapoints, M is the current mean, Q/N is
    // the standard variance, and sqrt(Q/N) is the standard
    // deviation. Read the paper for why it works or use algebra.
    //
    // (Note that this is a better scheme numerically than using the
    // classic calculator technique of storing sum(x), sum(x^2), n.)
    size_t N;
    float M, Q;
};

struct perfmon_stddev_t
    : public perfmon_perthread_t<stddev_t>
{
    // should be possible to make this a templated class if necessary
    explicit perfmon_stddev_t(std::string name, bool internal = true);
    void record(float value);

  protected:
    std::string name;

    void get_thread_stat(stddev_t *);
    stddev_t combine_stats(stddev_t *);
    void output_stat(const stddev_t&, perfmon_stats_t *);
  private:
    stddev_t thread_data[MAX_THREADS]; // TODO (rntz) should this be cache-line padded?
};

/* `perfmon_rate_monitor_t` keeps track of the number of times some event happens
per second. It is different from `perfmon_sampler_t` in that it does not associate
a number with each event, but you can record many events at once. For example, it
would be good for recording how fast bytes are sent over the network. */

class perfmon_rate_monitor_t
    : public perfmon_perthread_t<double>
{
private:
    struct thread_info_t {
        double current_count, last_count;
        int current_interval;
    } thread_data[MAX_THREADS];
    void update(ticks_t now);
    std::string name;
    ticks_t length;

    void get_thread_stat(double *);
    double combine_stats(double *);
    void output_stat(const double&, perfmon_stats_t *);
public:
    perfmon_rate_monitor_t(std::string name, ticks_t length, bool internal = true);
    void record(double value = 1.0);
};

/* perfmon_duration_sampler_t is a perfmon_t that monitors events that have a
 * starting and ending time. When something starts, call begin(); when
 * something ends, call end() with the same value as begin. It will produce
 * stats for the number of active events, the average length of an event, and
 * so on. If `global_full_perfmon` is false, it won't report any timing-related
 * stats because `get_ticks()` is rather slow.
 *
 * Frequently we're in the case
 * where we'd like to have a single slow perfmon up, but don't want the other
 * ones, perfmon_duration_sampler_t has an ignore_global_full_perfmon
 * field on it, which when true makes it run regardless of --full-perfmon flag
 * this can also be enable and disabled at runtime. */

struct perfmon_duration_sampler_t
    : public control_t
{

private:
    perfmon_counter_t active;
    perfmon_counter_t total;
    perfmon_sampler_t recent;
    bool ignore_global_full_perfmon;
public:
    perfmon_duration_sampler_t(std::string name, ticks_t length, bool internal = true, bool ignore_global_full_perfmon = false)
        : control_t(std::string("pm_") + name + "_toggle", name + " toggle on and off", true),
          active(name + "_active_count", internal), total(name + "_total", internal),
          recent(name, length, true, internal), ignore_global_full_perfmon(ignore_global_full_perfmon)
        { }
    void begin(ticks_t *v) {
        active++;
        total++;
        if (global_full_perfmon || ignore_global_full_perfmon) *v = get_ticks();
        else *v = 0;
    }
    void end(ticks_t *v) {
        active--;
        if (*v != 0) recent.record(ticks_to_secs(get_ticks() - *v));
    }

//Control interface used for enabling and disabling duration samplers at run time
public:
    std::string call(UNUSED int argc, UNUSED char **argv) {
        ignore_global_full_perfmon = !ignore_global_full_perfmon;
        if (ignore_global_full_perfmon) {
            return "Enabled\n";
        }
        else {
            return "Disabled\n";
        }
    }
};

/* perfmon_function_t is a perfmon for calling an arbitrary function to compute a stat. You should
not create such a perfmon at runtime; instead, declare it as a static variable and then construct
a perfmon_function_t::internal_function_t instance for it. This way things get called on the
right cores and if there are multiple internal_function_t instances the perfmon_function_t can
combine them by inserting commas. */
struct perfmon_function_t :
    public perfmon_t
{
public:
    class internal_function_t :
        public intrusive_list_node_t<internal_function_t>
    {
    public:
        internal_function_t(perfmon_function_t *p);
        virtual ~internal_function_t();
        virtual std::string compute_stat() = 0;
    private:
        perfmon_function_t *parent;
    };

private:
    friend class internal_function_t;
    std::string name;
    intrusive_list_t<internal_function_t> funs[MAX_THREADS];

public:
    perfmon_function_t(std::string name, bool internal = true)
        : perfmon_t(internal), name(name) {}
    ~perfmon_function_t() {}

    void *begin_stats();
    void visit_stats(void *data);
    void end_stats(void *data, perfmon_stats_t *dest);
};

struct block_pm_duration {
    ticks_t time;
    bool ended;
    perfmon_duration_sampler_t *pm;
    block_pm_duration(perfmon_duration_sampler_t *pm)
        : ended(false), pm(pm)
    {
        pm->begin(&time);
    }
    void end() {
        rassert(!ended);
        ended = true;
        pm->end(&time);
    }
    ~block_pm_duration() {
        if (!ended) end();
    }
};

#endif /* __PERFMON_HPP__ */
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "maemotoolchain.h"

#include "maemoglobal.h"
#include "maemomanager.h"
#include "qt4projectmanagerconstants.h"
#include "qtversionmanager.h"

#include <projectexplorer/gccparser.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/toolchainmanager.h>
#include <utils/environment.h>

#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>

namespace Qt4ProjectManager {
namespace Internal {

static const char *const MAEMO_QT_VERSION_KEY = "Qt4ProjectManager.Maemo.QtVersion";

// --------------------------------------------------------------------------
// MaemoToolChain
// --------------------------------------------------------------------------

MaemoToolChain::MaemoToolChain(bool autodetected) :
    ProjectExplorer::GccToolChain(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID), autodetected),
    m_qtVersionId(-1)
{
    updateId();
}

MaemoToolChain::MaemoToolChain(const MaemoToolChain &tc) :
    ProjectExplorer::GccToolChain(tc),
    m_qtVersionId(tc.m_qtVersionId)
{ }

MaemoToolChain::~MaemoToolChain()
{ }

QString MaemoToolChain::typeName() const
{
    return MaemoToolChainFactory::tr("Maemo GCC");
}

ProjectExplorer::Abi MaemoToolChain::targetAbi() const
{
    return m_targetAbi;
}

bool MaemoToolChain::isValid() const
{
    return GccToolChain::isValid() && m_qtVersionId >= 0 && m_targetAbi.isValid();
}

bool MaemoToolChain::canClone() const
{
    return false;
}

void MaemoToolChain::addToEnvironment(Utils::Environment &env) const
{
    QtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
    const QString maddeRoot = MaemoGlobal::maddeRoot(v);
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin").arg(maddeRoot)));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
                                                  .arg(MaemoGlobal::targetRoot(v))));

    // put this into environment to make pkg-config stuff work
    env.prependOrSet(QLatin1String("SYSROOT_DIR"), QDir::toNativeSeparators(sysroot()));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madbin")
        .arg(maddeRoot)));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madlib")
        .arg(maddeRoot)));
    env.prependOrSet(QLatin1String("PERL5LIB"),
        QDir::toNativeSeparators(QString("%1/madlib/perl5").arg(maddeRoot)));

    const QString manglePathsKey = QLatin1String("GCCWRAPPER_PATHMANGLE");
    if (!env.hasKey(manglePathsKey)) {
        const QStringList pathsToMangle = QStringList() << QLatin1String("/lib")
            << QLatin1String("/opt") << QLatin1String("/usr");
        env.set(manglePathsKey, QString());
        foreach (const QString &path, pathsToMangle)
            env.appendOrSet(manglePathsKey, path, QLatin1String(":"));
    }
}

QString MaemoToolChain::sysroot() const
{
    QtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
    if (!v)
        return QString();

    if (m_sysroot.isEmpty()) {
        QFile file(QDir::cleanPath(MaemoGlobal::targetRoot(v)) + QLatin1String("/information"));
        if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream stream(&file);
            while (!stream.atEnd()) {
                const QString &line = stream.readLine().trimmed();
                const QStringList &list = line.split(QLatin1Char(' '));
                if (list.count() > 1 && list.at(0) == QLatin1String("sysroot"))
                    m_sysroot = MaemoGlobal::maddeRoot(v) + QLatin1String("/sysroots/") + list.at(1);
            }
        }
    }
    return m_sysroot;
}

bool MaemoToolChain::operator ==(const ProjectExplorer::ToolChain &tc) const
{
    if (!ToolChain::operator ==(tc))
        return false;

    const MaemoToolChain *tcPtr = static_cast<const MaemoToolChain *>(&tc);
    return m_qtVersionId == tcPtr->m_qtVersionId;
}

ProjectExplorer::ToolChainConfigWidget *MaemoToolChain::configurationWidget()
{
    return new MaemoToolChainConfigWidget(this);
}

QVariantMap MaemoToolChain::toMap() const
{
    QVariantMap result = GccToolChain::toMap();
    result.insert(QLatin1String(MAEMO_QT_VERSION_KEY), m_qtVersionId);
    return result;
}

bool MaemoToolChain::fromMap(const QVariantMap &data)
{
    if (!GccToolChain::fromMap(data))
        return false;

    m_qtVersionId = data.value(QLatin1String(MAEMO_QT_VERSION_KEY), -1).toInt();

    return isValid();
}

void MaemoToolChain::setQtVersionId(int id)
{
    if (id < 0) {
        m_targetAbi = ProjectExplorer::Abi();
        m_qtVersionId = -1;
        updateId(); // Will trigger toolChainUpdated()!
        return;
    }

    QtVersion *version = QtVersionManager::instance()->version(id);
    Q_ASSERT(version);
    ProjectExplorer::Abi::OSFlavor flavour = ProjectExplorer::Abi::HarmattanLinuxFlavor;
    if (MaemoGlobal::isValidMaemo5QtVersion(version))
        flavour = ProjectExplorer::Abi::MaemoLinuxFlavor;
    else if (MaemoGlobal::isValidHarmattanQtVersion(version))
        flavour = ProjectExplorer::Abi::HarmattanLinuxFlavor;
    else if (MaemoGlobal::isValidMeegoQtVersion(version))
        flavour = ProjectExplorer::Abi::MeegoLinuxFlavor;
    else
        return;

    m_qtVersionId = id;

    Q_ASSERT(version->qtAbis().count() == 1);
    m_targetAbi = version->qtAbis().at(0);

    updateId(); // Will trigger toolChainUpdated()!
    setDisplayName(MaemoToolChainFactory::tr("Maemo GCC for %1").arg(version->displayName()));
}

int MaemoToolChain::qtVersionId() const
{
    return m_qtVersionId;
}

void MaemoToolChain::updateId()
{
    setId(QString::fromLatin1("%1:%2.%3").arg(Constants::MAEMO_TOOLCHAIN_ID)
          .arg(m_qtVersionId).arg(debuggerCommand()));
}

// --------------------------------------------------------------------------
// ToolChainConfigWidget
// --------------------------------------------------------------------------

MaemoToolChainConfigWidget::MaemoToolChainConfigWidget(MaemoToolChain *tc) :
    ProjectExplorer::ToolChainConfigWidget(tc)
{
    QVBoxLayout *layout = new QVBoxLayout(this);
    QLabel *label = new QLabel;
    QtVersion *v = QtVersionManager::instance()->version(tc->qtVersionId());
    Q_ASSERT(v);
    label->setText(tr("
"
                      "
Path to MADDE:	%1
"
                      "
Path to MADDE target:	%2
"
                      "
Debugger:%3
")
                   .arg(QDir::toNativeSeparators(MaemoGlobal::maddeRoot(v)),
                        QDir::toNativeSeparators(MaemoGlobal::targetRoot(v)),
                        QDir::toNativeSeparators(tc->debuggerCommand())));
    layout->addWidget(label);
}

void MaemoToolChainConfigWidget::apply()
{
    // nothing to do!
}

void MaemoToolChainConfigWidget::discard()
{
    // nothing to do!
}

bool MaemoToolChainConfigWidget::isDirty() const
{
    return false;
}

// --------------------------------------------------------------------------
// ToolChainFactory
// --------------------------------------------------------------------------

MaemoToolChainFactory::MaemoToolChainFactory() :
    ProjectExplorer::ToolChainFactory()
{ }

QString MaemoToolChainFactory::displayName() const
{
    return tr("Maemo GCC");
}

QString MaemoToolChainFactory::id() const
{
    return QLatin1String(Constants::MAEMO_TOOLCHAIN_ID);
}

QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::autoDetect()
{
    QList<ProjectExplorer::ToolChain *> result;

    QtVersionManager *vm = QtVersionManager::instance();
    connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
            this, SLOT(handleQtVersionChanges(QList<int>)));

    QList<int> versionList;
    foreach (QtVersion *v, vm->versions())
        versionList.append(v->uniqueId());

    return createToolChainList(versionList);
}

void MaemoToolChainFactory::handleQtVersionChanges(const QList<int> &changes)
{
    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
    QList<ProjectExplorer::ToolChain *> tcList = createToolChainList(changes);
    foreach (ProjectExplorer::ToolChain *tc, tcList)
        tcm->registerToolChain(tc);
}

QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::createToolChainList(const QList<int> &changes)
{
    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
    QtVersionManager *vm = QtVersionManager::instance();
    QList<ProjectExplorer::ToolChain *> result;

    foreach (int i, changes) {
        QtVersion *v = vm->version(i);
        if (!v) {
            // remove tool chain:
            QList<ProjectExplorer::ToolChain *> toRemove;
            foreach (ProjectExplorer::ToolChain *tc, tcm->toolChains()) {
                if (!tc->id().startsWith(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID)))
                    continue;
                MaemoToolChain *mTc = static_cast<MaemoToolChain *>(tc);
                if (mTc->qtVersionId() == i)
                    toRemove.append(mTc);
            }
            foreach (ProjectExplorer::ToolChain *tc, toRemove)
                tcm->deregisterToolChain(tc);
        } else if (v->supportsTargetId(Constants::MAEMO5_DEVICE_TARGET_ID)
                   || v->supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID)
                   || v->supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID)) {
            // add tool chain:
            MaemoToolChain *mTc = new MaemoToolChain(true);
            mTc->setQtVersionId(i);
            QString target = "Maemo 5";
            if (v->supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID))
                target = "Maemo 6";
            else if (v->supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID))
                target = "Meego";
            mTc->setDisplayName(tr("%1 GCC (%2)").arg(target).arg(MaemoGlobal::maddeRoot(v)));
            mTc->setCompilerPath(MaemoGlobal::targetRoot(v) + QLatin1String("/bin/gcc"));
            mTc->setDebuggerCommand(ProjectExplorer::ToolChainManager::instance()->defaultDebugger(v->qtAbis().at(0)));
            if (mTc->debuggerCommand().isEmpty())
                mTc->setDebuggerCommand(MaemoGlobal::targetRoot(v) + QLatin1String("/bin/gdb"));
            result.append(mTc);
        }
    }
    return result;
}

} // namespace Internal
} // namespace Qt4ProjectManager
<commit_msg>Maemo: Re-order some environment settings for extra safety.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "maemotoolchain.h"

#include "maemoglobal.h"
#include "maemomanager.h"
#include "qt4projectmanagerconstants.h"
#include "qtversionmanager.h"

#include <projectexplorer/gccparser.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/toolchainmanager.h>
#include <utils/environment.h>

#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>

namespace Qt4ProjectManager {
namespace Internal {

static const char *const MAEMO_QT_VERSION_KEY = "Qt4ProjectManager.Maemo.QtVersion";

// --------------------------------------------------------------------------
// MaemoToolChain
// --------------------------------------------------------------------------

MaemoToolChain::MaemoToolChain(bool autodetected) :
    ProjectExplorer::GccToolChain(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID), autodetected),
    m_qtVersionId(-1)
{
    updateId();
}

MaemoToolChain::MaemoToolChain(const MaemoToolChain &tc) :
    ProjectExplorer::GccToolChain(tc),
    m_qtVersionId(tc.m_qtVersionId)
{ }

MaemoToolChain::~MaemoToolChain()
{ }

QString MaemoToolChain::typeName() const
{
    return MaemoToolChainFactory::tr("Maemo GCC");
}

ProjectExplorer::Abi MaemoToolChain::targetAbi() const
{
    return m_targetAbi;
}

bool MaemoToolChain::isValid() const
{
    return GccToolChain::isValid() && m_qtVersionId >= 0 && m_targetAbi.isValid();
}

bool MaemoToolChain::canClone() const
{
    return false;
}

void MaemoToolChain::addToEnvironment(Utils::Environment &env) const
{
    QtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
    const QString maddeRoot = MaemoGlobal::maddeRoot(v);

    // put this into environment to make pkg-config stuff work
    env.prependOrSet(QLatin1String("SYSROOT_DIR"), QDir::toNativeSeparators(sysroot()));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madbin")
        .arg(maddeRoot)));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madlib")
        .arg(maddeRoot)));
    env.prependOrSet(QLatin1String("PERL5LIB"),
        QDir::toNativeSeparators(QString("%1/madlib/perl5").arg(maddeRoot)));

    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin").arg(maddeRoot)));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
                                                  .arg(MaemoGlobal::targetRoot(v))));

    const QString manglePathsKey = QLatin1String("GCCWRAPPER_PATHMANGLE");
    if (!env.hasKey(manglePathsKey)) {
        const QStringList pathsToMangle = QStringList() << QLatin1String("/lib")
            << QLatin1String("/opt") << QLatin1String("/usr");
        env.set(manglePathsKey, QString());
        foreach (const QString &path, pathsToMangle)
            env.appendOrSet(manglePathsKey, path, QLatin1String(":"));
    }
}

QString MaemoToolChain::sysroot() const
{
    QtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
    if (!v)
        return QString();

    if (m_sysroot.isEmpty()) {
        QFile file(QDir::cleanPath(MaemoGlobal::targetRoot(v)) + QLatin1String("/information"));
        if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream stream(&file);
            while (!stream.atEnd()) {
                const QString &line = stream.readLine().trimmed();
                const QStringList &list = line.split(QLatin1Char(' '));
                if (list.count() > 1 && list.at(0) == QLatin1String("sysroot"))
                    m_sysroot = MaemoGlobal::maddeRoot(v) + QLatin1String("/sysroots/") + list.at(1);
            }
        }
    }
    return m_sysroot;
}

bool MaemoToolChain::operator ==(const ProjectExplorer::ToolChain &tc) const
{
    if (!ToolChain::operator ==(tc))
        return false;

    const MaemoToolChain *tcPtr = static_cast<const MaemoToolChain *>(&tc);
    return m_qtVersionId == tcPtr->m_qtVersionId;
}

ProjectExplorer::ToolChainConfigWidget *MaemoToolChain::configurationWidget()
{
    return new MaemoToolChainConfigWidget(this);
}

QVariantMap MaemoToolChain::toMap() const
{
    QVariantMap result = GccToolChain::toMap();
    result.insert(QLatin1String(MAEMO_QT_VERSION_KEY), m_qtVersionId);
    return result;
}

bool MaemoToolChain::fromMap(const QVariantMap &data)
{
    if (!GccToolChain::fromMap(data))
        return false;

    m_qtVersionId = data.value(QLatin1String(MAEMO_QT_VERSION_KEY), -1).toInt();

    return isValid();
}

void MaemoToolChain::setQtVersionId(int id)
{
    if (id < 0) {
        m_targetAbi = ProjectExplorer::Abi();
        m_qtVersionId = -1;
        updateId(); // Will trigger toolChainUpdated()!
        return;
    }

    QtVersion *version = QtVersionManager::instance()->version(id);
    Q_ASSERT(version);
    ProjectExplorer::Abi::OSFlavor flavour = ProjectExplorer::Abi::HarmattanLinuxFlavor;
    if (MaemoGlobal::isValidMaemo5QtVersion(version))
        flavour = ProjectExplorer::Abi::MaemoLinuxFlavor;
    else if (MaemoGlobal::isValidHarmattanQtVersion(version))
        flavour = ProjectExplorer::Abi::HarmattanLinuxFlavor;
    else if (MaemoGlobal::isValidMeegoQtVersion(version))
        flavour = ProjectExplorer::Abi::MeegoLinuxFlavor;
    else
        return;

    m_qtVersionId = id;

    Q_ASSERT(version->qtAbis().count() == 1);
    m_targetAbi = version->qtAbis().at(0);

    updateId(); // Will trigger toolChainUpdated()!
    setDisplayName(MaemoToolChainFactory::tr("Maemo GCC for %1").arg(version->displayName()));
}

int MaemoToolChain::qtVersionId() const
{
    return m_qtVersionId;
}

void MaemoToolChain::updateId()
{
    setId(QString::fromLatin1("%1:%2.%3").arg(Constants::MAEMO_TOOLCHAIN_ID)
          .arg(m_qtVersionId).arg(debuggerCommand()));
}

// --------------------------------------------------------------------------
// ToolChainConfigWidget
// --------------------------------------------------------------------------

MaemoToolChainConfigWidget::MaemoToolChainConfigWidget(MaemoToolChain *tc) :
    ProjectExplorer::ToolChainConfigWidget(tc)
{
    QVBoxLayout *layout = new QVBoxLayout(this);
    QLabel *label = new QLabel;
    QtVersion *v = QtVersionManager::instance()->version(tc->qtVersionId());
    Q_ASSERT(v);
    label->setText(tr("
"
                      "
Path to MADDE:	%1
"
                      "
Path to MADDE target:	%2
"
                      "
Debugger:%3
")
                   .arg(QDir::toNativeSeparators(MaemoGlobal::maddeRoot(v)),
                        QDir::toNativeSeparators(MaemoGlobal::targetRoot(v)),
                        QDir::toNativeSeparators(tc->debuggerCommand())));
    layout->addWidget(label);
}

void MaemoToolChainConfigWidget::apply()
{
    // nothing to do!
}

void MaemoToolChainConfigWidget::discard()
{
    // nothing to do!
}

bool MaemoToolChainConfigWidget::isDirty() const
{
    return false;
}

// --------------------------------------------------------------------------
// ToolChainFactory
// --------------------------------------------------------------------------

MaemoToolChainFactory::MaemoToolChainFactory() :
    ProjectExplorer::ToolChainFactory()
{ }

QString MaemoToolChainFactory::displayName() const
{
    return tr("Maemo GCC");
}

QString MaemoToolChainFactory::id() const
{
    return QLatin1String(Constants::MAEMO_TOOLCHAIN_ID);
}

QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::autoDetect()
{
    QList<ProjectExplorer::ToolChain *> result;

    QtVersionManager *vm = QtVersionManager::instance();
    connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
            this, SLOT(handleQtVersionChanges(QList<int>)));

    QList<int> versionList;
    foreach (QtVersion *v, vm->versions())
        versionList.append(v->uniqueId());

    return createToolChainList(versionList);
}

void MaemoToolChainFactory::handleQtVersionChanges(const QList<int> &changes)
{
    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
    QList<ProjectExplorer::ToolChain *> tcList = createToolChainList(changes);
    foreach (ProjectExplorer::ToolChain *tc, tcList)
        tcm->registerToolChain(tc);
}

QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::createToolChainList(const QList<int> &changes)
{
    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
    QtVersionManager *vm = QtVersionManager::instance();
    QList<ProjectExplorer::ToolChain *> result;

    foreach (int i, changes) {
        QtVersion *v = vm->version(i);
        if (!v) {
            // remove tool chain:
            QList<ProjectExplorer::ToolChain *> toRemove;
            foreach (ProjectExplorer::ToolChain *tc, tcm->toolChains()) {
                if (!tc->id().startsWith(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID)))
                    continue;
                MaemoToolChain *mTc = static_cast<MaemoToolChain *>(tc);
                if (mTc->qtVersionId() == i)
                    toRemove.append(mTc);
            }
            foreach (ProjectExplorer::ToolChain *tc, toRemove)
                tcm->deregisterToolChain(tc);
        } else if (v->supportsTargetId(Constants::MAEMO5_DEVICE_TARGET_ID)
                   || v->supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID)
                   || v->supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID)) {
            // add tool chain:
            MaemoToolChain *mTc = new MaemoToolChain(true);
            mTc->setQtVersionId(i);
            QString target = "Maemo 5";
            if (v->supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID))
                target = "Maemo 6";
            else if (v->supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID))
                target = "Meego";
            mTc->setDisplayName(tr("%1 GCC (%2)").arg(target).arg(MaemoGlobal::maddeRoot(v)));
            mTc->setCompilerPath(MaemoGlobal::targetRoot(v) + QLatin1String("/bin/gcc"));
            mTc->setDebuggerCommand(ProjectExplorer::ToolChainManager::instance()->defaultDebugger(v->qtAbis().at(0)));
            if (mTc->debuggerCommand().isEmpty())
                mTc->setDebuggerCommand(MaemoGlobal::targetRoot(v) + QLatin1String("/bin/gdb"));
            result.append(mTc);
        }
    }
    return result;
}

} // namespace Internal
} // namespace Qt4ProjectManager
<|endoftext|>


<commit_before>#include <Common.h>
#include <Network/CommonNetwork.h>
#include <Network/GamePacketNew.h>
#include <Logging/Logger.h>
#include <Network/PacketContainer.h>
#include <Exd/ExdDataGenerated.h>

#include "Zone/TerritoryMgr.h"
#include "Zone/InstanceContent.h"

#include "Network/GameConnection.h"
#include "Network/PacketWrappers/ServerNoticePacket.h"
#include "Network/PacketWrappers/PlayerStateFlagsPacket.h"

#include "Framework.h"
#include "Session.h"

extern Core::Framework g_fw;

using namespace Core::Common;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;

void Core::Network::GameConnection::cfDutyInfoRequest( const Packets::FFXIVARR_PACKET_RAW& inPacket,
                                                       Entity::Player& player )
{
  auto dutyInfoPacket = makeZonePacket< FFXIVIpcCFDutyInfo >( player.getId() );
  auto penaltyMinutes = player.getCFPenaltyMinutes();
  if( penaltyMinutes > 255 )
  {
    // cap it since it's uint8_t in packets
    penaltyMinutes = 255;
  }
  dutyInfoPacket->data().penaltyTime = penaltyMinutes;
  queueOutPacket( dutyInfoPacket );

  auto inNeedsPacket = makeZonePacket< FFXIVIpcCFPlayerInNeed >( player.getId() );
  queueOutPacket( inNeedsPacket );

}

void Core::Network::GameConnection::cfRegisterDuty( const Packets::FFXIVARR_PACKET_RAW& inPacket,
                                                    Entity::Player& player )
{
  Packets::FFXIVARR_PACKET_RAW copy = inPacket;
  auto pTeriMgr = g_fw.get< TerritoryMgr >();
  auto pExdData = g_fw.get< Data::ExdDataGenerated >();

  std::vector< uint16_t > selectedContent;

  for( uint32_t offset = 0x1E; offset <= 0x26; offset += 0x2 )
  {
    auto id = *reinterpret_cast< uint16_t* >( &copy.data[ offset ] );
    if( id == 0 )
      break;

    player.sendDebug( "got contentId: " + std::to_string( id ) );

    selectedContent.push_back( id );
  }

  // todo: rand bias problem, will do for now tho
  auto index = std::rand() % selectedContent.size();
  auto contentId = selectedContent.at( index );

  player.sendDebug( "Duty register request for contentid: " + std::to_string( contentId ) );

  // let's cancel it because otherwise you can't register it again
  auto cfCancelPacket = makeZonePacket< FFXIVIpcCFNotify >( player.getId() );
  cfCancelPacket->data().state1 = 3;
  cfCancelPacket->data().state2 = 1; // Your registration is withdrawn.
  queueOutPacket( cfCancelPacket );

  auto cfCondition = pExdData->get< Core::Data::ContentFinderCondition >( contentId );
  if( !cfCondition )
    return;

  auto instance = pTeriMgr->createInstanceContent( cfCondition->instanceContent );
  if( !instance )
    return;

  auto pInstance = instance->getAsInstanceContent();
a  pInstance->bindPlayer( player.getId() );

  player.sendDebug( "Created instance with id: " + std::to_string( instance->getGuId() ) );

  player.setInstance( instance );
}

void Core::Network::GameConnection::cfRegisterRoulette( const Packets::FFXIVARR_PACKET_RAW& inPacket,
                                                        Entity::Player& player )
{
  auto cfCancelPacket = makeZonePacket< FFXIVIpcCFNotify >( player.getId() );
  cfCancelPacket->data().state1 = 3;
  cfCancelPacket->data().state2 = 1; // Your registration is withdrawn.
  queueOutPacket( cfCancelPacket );

  player.sendDebug( "Roulette register" );
}

void Core::Network::GameConnection::cfDutyAccepted( const Packets::FFXIVARR_PACKET_RAW& inPacket,
                                                    Entity::Player& player )
{
  player.sendDebug( "TODO: Duty accept" );
}
<commit_msg>Build fix<commit_after>#include <Common.h>
#include <Network/CommonNetwork.h>
#include <Network/GamePacketNew.h>
#include <Logging/Logger.h>
#include <Network/PacketContainer.h>
#include <Exd/ExdDataGenerated.h>

#include "Zone/TerritoryMgr.h"
#include "Zone/InstanceContent.h"

#include "Network/GameConnection.h"
#include "Network/PacketWrappers/ServerNoticePacket.h"
#include "Network/PacketWrappers/PlayerStateFlagsPacket.h"

#include "Framework.h"
#include "Session.h"

extern Core::Framework g_fw;

using namespace Core::Common;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;

void Core::Network::GameConnection::cfDutyInfoRequest( const Packets::FFXIVARR_PACKET_RAW& inPacket,
                                                       Entity::Player& player )
{
  auto dutyInfoPacket = makeZonePacket< FFXIVIpcCFDutyInfo >( player.getId() );
  auto penaltyMinutes = player.getCFPenaltyMinutes();
  if( penaltyMinutes > 255 )
  {
    // cap it since it's uint8_t in packets
    penaltyMinutes = 255;
  }
  dutyInfoPacket->data().penaltyTime = penaltyMinutes;
  queueOutPacket( dutyInfoPacket );

  auto inNeedsPacket = makeZonePacket< FFXIVIpcCFPlayerInNeed >( player.getId() );
  queueOutPacket( inNeedsPacket );

}

void Core::Network::GameConnection::cfRegisterDuty( const Packets::FFXIVARR_PACKET_RAW& inPacket,
                                                    Entity::Player& player )
{
  Packets::FFXIVARR_PACKET_RAW copy = inPacket;
  auto pTeriMgr = g_fw.get< TerritoryMgr >();
  auto pExdData = g_fw.get< Data::ExdDataGenerated >();

  std::vector< uint16_t > selectedContent;

  for( uint32_t offset = 0x1E; offset <= 0x26; offset += 0x2 )
  {
    auto id = *reinterpret_cast< uint16_t* >( &copy.data[ offset ] );
    if( id == 0 )
      break;

    player.sendDebug( "got contentId: " + std::to_string( id ) );

    selectedContent.push_back( id );
  }

  // todo: rand bias problem, will do for now tho
  auto index = std::rand() % selectedContent.size();
  auto contentId = selectedContent.at( index );

  player.sendDebug( "Duty register request for contentid: " + std::to_string( contentId ) );

  // let's cancel it because otherwise you can't register it again
  auto cfCancelPacket = makeZonePacket< FFXIVIpcCFNotify >( player.getId() );
  cfCancelPacket->data().state1 = 3;
  cfCancelPacket->data().state2 = 1; // Your registration is withdrawn.
  queueOutPacket( cfCancelPacket );

  auto cfCondition = pExdData->get< Core::Data::ContentFinderCondition >( contentId );
  if( !cfCondition )
    return;

  auto instance = pTeriMgr->createInstanceContent( cfCondition->instanceContent );
  if( !instance )
    return;

  auto pInstance = instance->getAsInstanceContent();
  pInstance->bindPlayer( player.getId() );

  player.sendDebug( "Created instance with id: " + std::to_string( instance->getGuId() ) );

  player.setInstance( instance );
}

void Core::Network::GameConnection::cfRegisterRoulette( const Packets::FFXIVARR_PACKET_RAW& inPacket,
                                                        Entity::Player& player )
{
  auto cfCancelPacket = makeZonePacket< FFXIVIpcCFNotify >( player.getId() );
  cfCancelPacket->data().state1 = 3;
  cfCancelPacket->data().state2 = 1; // Your registration is withdrawn.
  queueOutPacket( cfCancelPacket );

  player.sendDebug( "Roulette register" );
}

void Core::Network::GameConnection::cfDutyAccepted( const Packets::FFXIVARR_PACKET_RAW& inPacket,
                                                    Entity::Player& player )
{
  player.sendDebug( "TODO: Duty accept" );
}
<|endoftext|>


<commit_before>#ifndef STAN__MATH__ERROR_HANDLING__MATRIX__CHECK_UNIT_VECTOR_HPP
#define STAN__MATH__ERROR_HANDLING__MATRIX__CHECK_UNIT_VECTOR_HPP

#include <sstream>
#include <stan/math/matrix/Eigen.hpp>
#include <stan/math/error_handling/dom_err.hpp>
#include <stan/math/error_handling/matrix/constraint_tolerance.hpp>

namespace stan {
  namespace math {

    /**
     * Return true if the specified vector is unit vector.
     *
     *
The test that the values sum to 1 is done to within the
     * tolerance specified by CONSTRAINT_TOLERANCE.
     *
     * @param function
     * @param theta Vector to test.
     * @param name
     * @param result
     * @return true if the vector is a unit vector.
     */
    template <typename T_prob, typename T_result>
    bool check_unit_vector(const char* function,
                           const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
                           const char* name,
                           T_result* result) {
      typedef typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type size_t;
      if (theta.size() == 0) {
        std::string message(name);
        message += " is not a valid unit vector. %1% elements in the vector.";
        return dom_err(function,0,name,
                       message.c_str(),"",
                       result);
      }
      T_prob ssq = theta.squaredNorm();
      if (!(fabs(1.0 - ssq) <= CONSTRAINT_TOLERANCE)) {
        std::stringstream msg;
        msg << "in function check_unit_vector(%1%), ";
        msg << name << " is not a valid unit vector.";
        msg << " The sum of the squares of the elements should be 1, but is "
            << ssq;
        std::string tmp(msg.str());
        return dom_err(function,ssq,name,
                       tmp.c_str(),"",
                       result);
      }
      return true;
    }

    template <typename T>
    inline bool check_unit_vector(const char* function,
                                  const Eigen::Matrix<T,Eigen::Dynamic,1>& theta,
                                  const char* name,
                                  T* result = 0) {
      return check_unit_vector<T,T>(function,theta,name,result);
    }

  }
}
#endif
<commit_msg>added doc in code for check_unit_vector<commit_after>#ifndef STAN__MATH__ERROR_HANDLING__MATRIX__CHECK_UNIT_VECTOR_HPP
#define STAN__MATH__ERROR_HANDLING__MATRIX__CHECK_UNIT_VECTOR_HPP

#include <sstream>
#include <stan/math/matrix/Eigen.hpp>
#include <stan/math/error_handling/dom_err.hpp>
#include <stan/math/error_handling/matrix/constraint_tolerance.hpp>

namespace stan {
  namespace math {

    /**
     * Return true if the specified vector is unit vector.
     *
     *
The test that the values sum to 1 is done to within the
     * tolerance specified by CONSTRAINT_TOLERANCE.
     *
     * @param function
     * @param theta Vector to test.
     * @param name
     * @param result
     * @return true if the vector is a unit vector.
     * @return throws if any element in theta is nan
     */
    template <typename T_prob, typename T_result>
    bool check_unit_vector(const char* function,
                           const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
                           const char* name,
                           T_result* result) {
      typedef typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type size_t;
      if (theta.size() == 0) {
        std::string message(name);
        message += " is not a valid unit vector. %1% elements in the vector.";
        return dom_err(function,0,name,
                       message.c_str(),"",
                       result);
      }
      T_prob ssq = theta.squaredNorm();
      if (!(fabs(1.0 - ssq) <= CONSTRAINT_TOLERANCE)) {
        std::stringstream msg;
        msg << "in function check_unit_vector(%1%), ";
        msg << name << " is not a valid unit vector.";
        msg << " The sum of the squares of the elements should be 1, but is "
            << ssq;
        std::string tmp(msg.str());
        return dom_err(function,ssq,name,
                       tmp.c_str(),"",
                       result);
      }
      return true;
    }

    template <typename T>
    inline bool check_unit_vector(const char* function,
                                  const Eigen::Matrix<T,Eigen::Dynamic,1>& theta,
                                  const char* name,
                                  T* result = 0) {
      return check_unit_vector<T,T>(function,theta,name,result);
    }

  }
}
#endif
<|endoftext|>


<commit_before>#ifndef STAN__MATH__ERROR_HANDLING__MATRIX__CHECK_UNIT_VECTOR_HPP
#define STAN__MATH__ERROR_HANDLING__MATRIX__CHECK_UNIT_VECTOR_HPP

#include <sstream>
#include <stan/math/matrix/Eigen.hpp>
#include <stan/math/error_handling/dom_err.hpp>
#include <stan/math/error_handling/matrix/constraint_tolerance.hpp>

namespace stan {
  namespace math {

    /**
     * Return true if the specified vector is unit vector.
     *
     *
The test that the values sum to 1 is done to within the
     * tolerance specified by CONSTRAINT_TOLERANCE.
     *
     * @param function
     * @param theta Vector to test.
     * @param name
     * @param result
     * @return true if the vector is a unit vector.
     */
    template <typename T_prob, typename T_result>
    bool check_unit_vector(const char* function,
                           const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
                           const char* name,
                           T_result* result) {
      typedef typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type size_t;
      if (theta.size() == 0) {
        std::string message(name);
        message += " is not a valid unit vector. %1% elements in the vector.";
        return dom_err(function,0,name,
                       message.c_str(),"",
                       result);
      }
      T_prob ssq = theta.squaredNorm();
      if (fabs(1.0 - ssq) > CONSTRAINT_TOLERANCE) {
        std::stringstream msg;
        msg << "in function check_unit_vector(%1%), ";
        msg << name << " is not a valid unit vector.";
        msg << " The sum of the squares of the elements should be 1, but is "
            << ssq;
        std::string tmp(msg.str());
        return dom_err(function,ssq,name,
                       tmp.c_str(),"",
                       result);
      }
      return true;
    }

    template <typename T>
    inline bool check_unit_vector(const char* function,
                                  const Eigen::Matrix<T,Eigen::Dynamic,1>& theta,
                                  const char* name,
                                  T* result = 0) {
      return check_unit_vector<T,T>(function,theta,name,result);
    }

  }
}
#endif
<commit_msg>fixed check_unit_vector<commit_after>#ifndef STAN__MATH__ERROR_HANDLING__MATRIX__CHECK_UNIT_VECTOR_HPP
#define STAN__MATH__ERROR_HANDLING__MATRIX__CHECK_UNIT_VECTOR_HPP

#include <sstream>
#include <stan/math/matrix/Eigen.hpp>
#include <stan/math/error_handling/dom_err.hpp>
#include <stan/math/error_handling/matrix/constraint_tolerance.hpp>

namespace stan {
  namespace math {

    /**
     * Return true if the specified vector is unit vector.
     *
     *
The test that the values sum to 1 is done to within the
     * tolerance specified by CONSTRAINT_TOLERANCE.
     *
     * @param function
     * @param theta Vector to test.
     * @param name
     * @param result
     * @return true if the vector is a unit vector.
     */
    template <typename T_prob, typename T_result>
    bool check_unit_vector(const char* function,
                           const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
                           const char* name,
                           T_result* result) {
      typedef typename Eigen::Matrix<T_prob,Eigen::Dynamic,1>::size_type size_t;
      if (theta.size() == 0) {
        std::string message(name);
        message += " is not a valid unit vector. %1% elements in the vector.";
        return dom_err(function,0,name,
                       message.c_str(),"",
                       result);
      }
      T_prob ssq = theta.squaredNorm();
      if (!(fabs(1.0 - ssq) <= CONSTRAINT_TOLERANCE)) {
        std::stringstream msg;
        msg << "in function check_unit_vector(%1%), ";
        msg << name << " is not a valid unit vector.";
        msg << " The sum of the squares of the elements should be 1, but is "
            << ssq;
        std::string tmp(msg.str());
        return dom_err(function,ssq,name,
                       tmp.c_str(),"",
                       result);
      }
      return true;
    }

    template <typename T>
    inline bool check_unit_vector(const char* function,
                                  const Eigen::Matrix<T,Eigen::Dynamic,1>& theta,
                                  const char* name,
                                  T* result = 0) {
      return check_unit_vector<T,T>(function,theta,name,result);
    }

  }
}
#endif
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by FThauer FHammer   *
 *   f.thauer@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <boost/asio.hpp>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <qapplication.h>
#include <QtGui>
#include <QtCore>

#ifdef __APPLE__
	#include <QMacStyle>
#endif

#include <curl/curl.h>

#include "session.h"
#include "startwindowimpl.h"
#include "configfile.h"
#include "startsplash.h"
#include "game_defs.h"
#include <net/socket_startup.h>
#include <third_party/qtsingleapplication/qtsingleapplication.h>

#ifdef _MSC_VER
	#ifdef _DEBUG
		#define _CRTDBG_MAP_ALLOC
		#include <crtdbg.h>

		#define ENABLE_LEAK_CHECK() \
			{ \
				int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); \
				tmpFlag |= _CRTDBG_LEAK_CHECK_DF; \
				_CrtSetDbgFlag(tmpFlag); \
			}
	#endif
#endif

#ifndef ENABLE_LEAK_CHECK
	#define ENABLE_LEAK_CHECK()
#endif

//Uncomment this for RELEASE on Linux/Unix/BSD (static Qt only)
//#include <QtPlugin>
//Q_IMPORT_PLUGIN(qjpeg)
//Q_IMPORT_PLUGIN(qgif)

#ifdef _WIN32 // Always use static Qt on Windows.
#include <QtPlugin>
Q_IMPORT_PLUGIN(qjpeg)
Q_IMPORT_PLUGIN(qgif)
#endif

using namespace std;

class startWindowImpl;
class Game;

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

	//ENABLE_LEAK_CHECK();

	//_CrtSetBreakAlloc(49937);
	socket_startup();
	curl_global_init(CURL_GLOBAL_NOTHING);

	/////// can be removed for non-qt-guis ////////////
	QtSingleApplication a( argc, argv );

	if (a.sendMessage("Wake up!")) {
		return 0;
	 }

#ifdef __APPLE__
	// The following needs to be done directly after the application is created.
	QDir dir(QApplication::applicationDirPath());
	dir.cdUp();
	dir.cd("plugins");
	QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif

	//create defaultconfig
	ConfigFile *myConfig = new ConfigFile(argv[0], false);

	// set PlastiqueStyle even for mac-version to prevent artefacts on styled widgets
	a.setStyle(new QPlastiqueStyle);

	QString	myAppDataPath = QString::fromUtf8(myConfig->readConfigString("AppDataDir").c_str());
	//set QApplication default font

	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/n019003l.pfb");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/VeraBd.ttf");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/c059013l.pfb");

#ifdef _WIN32
	QString font1String("font-family: \"Arial\";");
	a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 12px; }");
#else
// 	#ifdef __APPLE__
// 		QString font1String("font-family: \"Lucida Grande\";");
// 	#else
	QString font1String("font-family: \"Nimbus Sans L\";");
// 	#endif
	a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 12px; }");
#endif
	a.setStyleSheet("QDialogButtonBox, QMessageBox { dialogbuttonbox-buttons-have-icons: 1; dialog-ok-icon: url(:/gfx/dialog_ok_apply.png); dialog-cancel-icon: url(:/gfx/dialog_close.png); dialog-close-icon: url(:/gfx/dialog_close.png); dialog-yes-icon: url(:/gfx/dialog_ok_apply.png); dialog-no-icon: url(:/gfx/dialog_close.png) }");

	QPixmap *pixmap = new QPixmap(myAppDataPath + "gfx/gui/misc/welcomepokerth.png");
	StartSplash splash(*pixmap);
	if(!myConfig->readConfigInt("DisableSplashScreenOnStartup")) {
		splash.show();
		splash.showMessage(QString("Version %1").arg(POKERTH_BETA_RELEASE_STRING), 0x0042, QColor(153,213,0));
	}

	//Set translations
	QTranslator qtTranslator;
        qtTranslator.load(QString(myAppDataPath +"translations/qt_") + QString::fromStdString(myConfig->readConfigString("Language")));
        a.installTranslator(&qtTranslator);

	QTranslator translator;
	translator.load(QString(myAppDataPath +"translations/pokerth_") + QString::fromStdString(myConfig->readConfigString("Language")));
	a.installTranslator(&translator);

	qRegisterMetaType<unsigned>("unsigned");
	qRegisterMetaType<boost::shared_ptr<Game> >("boost::shared_ptr<Game>");
	qRegisterMetaType<ServerStats>("ServerStats");
        qRegisterMetaType<DenyGameInvitationReason>("DenyGameInvitationReason");
	///////////////////////////////////////////////////

        startWindowImpl mainWin(myConfig);
                a.setActivationWindow(&mainWin, true);

	int retVal = a.exec();

	curl_global_cleanup();
	socket_cleanup();

	return retVal;

}
<commit_msg>mac font fix<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by FThauer FHammer   *
 *   f.thauer@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <boost/asio.hpp>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <qapplication.h>
#include <QtGui>
#include <QtCore>

#ifdef __APPLE__
	#include <QMacStyle>
#endif

#include <curl/curl.h>

#include "session.h"
#include "startwindowimpl.h"
#include "configfile.h"
#include "startsplash.h"
#include "game_defs.h"
#include <net/socket_startup.h>
#include <third_party/qtsingleapplication/qtsingleapplication.h>

#ifdef _MSC_VER
	#ifdef _DEBUG
		#define _CRTDBG_MAP_ALLOC
		#include <crtdbg.h>

		#define ENABLE_LEAK_CHECK() \
			{ \
				int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); \
				tmpFlag |= _CRTDBG_LEAK_CHECK_DF; \
				_CrtSetDbgFlag(tmpFlag); \
			}
	#endif
#endif

#ifndef ENABLE_LEAK_CHECK
	#define ENABLE_LEAK_CHECK()
#endif

//Uncomment this for RELEASE on Linux/Unix/BSD (static Qt only)
//#include <QtPlugin>
//Q_IMPORT_PLUGIN(qjpeg)
//Q_IMPORT_PLUGIN(qgif)

#ifdef _WIN32 // Always use static Qt on Windows.
#include <QtPlugin>
Q_IMPORT_PLUGIN(qjpeg)
Q_IMPORT_PLUGIN(qgif)
#endif

using namespace std;

class startWindowImpl;
class Game;

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

	//ENABLE_LEAK_CHECK();

	//_CrtSetBreakAlloc(49937);
	socket_startup();
	curl_global_init(CURL_GLOBAL_NOTHING);

	/////// can be removed for non-qt-guis ////////////
	QtSingleApplication a( argc, argv );

	if (a.sendMessage("Wake up!")) {
		return 0;
	 }

#ifdef __APPLE__
	// The following needs to be done directly after the application is created.
	QDir dir(QApplication::applicationDirPath());
	dir.cdUp();
	dir.cd("plugins");
	QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif

	//create defaultconfig
	ConfigFile *myConfig = new ConfigFile(argv[0], false);

	// set PlastiqueStyle even for mac-version to prevent artefacts on styled widgets
	a.setStyle(new QPlastiqueStyle);

	QString	myAppDataPath = QString::fromUtf8(myConfig->readConfigString("AppDataDir").c_str());
	//set QApplication default font

	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/n019003l.pfb");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/VeraBd.ttf");
	QFontDatabase::addApplicationFont (myAppDataPath +"fonts/c059013l.pfb");

#ifdef _WIN32
	QString font1String("font-family: \"Arial\";");
	a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 12px; }");
#else
// 		QString font1String("font-family: \"Lucida Grande\";");
	QString font1String("font-family: \"Nimbus Sans L\";");

        #ifdef __APPLE__
            a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 11px; }");
        #else
            a.setStyleSheet("QApplication, QWidget, QDialog { " + font1String + " font-size: 12px; }");
        #endif
#endif
	a.setStyleSheet("QDialogButtonBox, QMessageBox { dialogbuttonbox-buttons-have-icons: 1; dialog-ok-icon: url(:/gfx/dialog_ok_apply.png); dialog-cancel-icon: url(:/gfx/dialog_close.png); dialog-close-icon: url(:/gfx/dialog_close.png); dialog-yes-icon: url(:/gfx/dialog_ok_apply.png); dialog-no-icon: url(:/gfx/dialog_close.png) }");

	QPixmap *pixmap = new QPixmap(myAppDataPath + "gfx/gui/misc/welcomepokerth.png");
	StartSplash splash(*pixmap);
	if(!myConfig->readConfigInt("DisableSplashScreenOnStartup")) {
		splash.show();
		splash.showMessage(QString("Version %1").arg(POKERTH_BETA_RELEASE_STRING), 0x0042, QColor(153,213,0));
	}

	//Set translations
	QTranslator qtTranslator;
        qtTranslator.load(QString(myAppDataPath +"translations/qt_") + QString::fromStdString(myConfig->readConfigString("Language")));
        a.installTranslator(&qtTranslator);

	QTranslator translator;
	translator.load(QString(myAppDataPath +"translations/pokerth_") + QString::fromStdString(myConfig->readConfigString("Language")));
	a.installTranslator(&translator);

	qRegisterMetaType<unsigned>("unsigned");
	qRegisterMetaType<boost::shared_ptr<Game> >("boost::shared_ptr<Game>");
	qRegisterMetaType<ServerStats>("ServerStats");
        qRegisterMetaType<DenyGameInvitationReason>("DenyGameInvitationReason");
	///////////////////////////////////////////////////

        startWindowImpl mainWin(myConfig);
                a.setActivationWindow(&mainWin, true);

	int retVal = a.exec();

	curl_global_cleanup();
	socket_cleanup();

	return retVal;

}
<|endoftext|>