<commit_before>

#include "../lib_graphs/defs.h"

#include "DebugPrinter.h"

#include "AuctionDefs.h"

#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

const size_t __num_nodes = 9;
const size_t __num_edges = 36;
Edge __edges[__num_edges] = {
  Edge(_a, _b), Edge(_a, _c), Edge(_a, _d), Edge(_a, _e), Edge(_a, _f), Edge(_a, _g), Edge(_a, _h), Edge(_a, _i),
  Edge(_b, _c), Edge(_b, _d), Edge(_b, _e), Edge(_b, _f), Edge(_b, _g), Edge(_b, _h), Edge(_b, _i),
  Edge(_c, _d), Edge(_c, _e), Edge(_c, _f), Edge(_c, _g), Edge(_c, _h), Edge(_c, _i),
  Edge(_d, _e), Edge(_d, _f), Edge(_d, _g), Edge(_d, _h), Edge(_d, _i),
  Edge(_e, _f), Edge(_e, _g), Edge(_e, _h), Edge(_e, _i),
  Edge(_f, _g), Edge(_f, _h), Edge(_f, _i),
  Edge(_g, _h), Edge(_g, _i),
  Edge(_h, _i)
};
int __weights[__num_edges] = {
    4,       8,       11,      8,      7,        4,       2,      9,
    14,      10,      2,       1,      6,        7,       4,
    8,       11,      8,       7,      4,        2,
    9,       14,      10,      2,      1,
    6,       7,       4,       8,
    11,      8,       7,
    4,       2,
    9 };
Loc __locations[__num_nodes] = {
    Loc(7, 0), Loc(15, 15), Loc(30, 15), Loc(45, 15),
    Loc(60, 0), Loc(45, -15), Loc(30, -15), Loc(15, -15), Loc(22, 0)
};
//Loc __locations[__num_nodes] = {
//    Loc(0.5, 0), Loc(1, 1), Loc(2, 1), Loc(3, 1),
//    Loc(4, 0), Loc(3, -1), Loc(2, -1), Loc(1, -1), Loc(1.5, 0)
//};

std::string pathToString(Loc path[], const size_t pathSize)
{
  std::stringstream ss;
  size_t i;

  // Cycle through all but last one
  for (i = 0; i < pathSize - 1; i++)
    ss << path[i].first << "," << path[i].second << ":";

  // Finish with last one
  ss << path[i].first << "," << path[i].second;

  return ss.str();
}

template<typename U, typename V>
std::string pairToString(std::pair<U,V> pair)
{
  std::stringstream ss;
  ss << pair.first << "," << pair.second;
  return ss.str();
}

std::string bidToString(Bid bid)
{
  return pairToString(bid);
}

Bid bidFromString(std::string str)
{
  Bid bid;
  std::vector<std::string> strs;
  boost::split(strs, str, boost::is_any_of(","));
  bid = std::make_pair(
      boost::lexical_cast<Vertex>(strs[0]),
      boost::lexical_cast<mbogo_weight_t>(strs[1]));
  return bid;
}

std::string winningBidToString(WinningBid bid)
{
  std::stringstream ss;
  ss << bid.winner << "," << bid.target << "," << bid.bid;
  return ss.str();
}

WinningBid winningBidFromString(std::string str)
{
  WinningBid bid;
  std::vector<std::string> strs;
  boost::split(strs, str, boost::is_any_of(","));
  bid.winner = boost::lexical_cast<int>(strs[0]);
  bid.target = boost::lexical_cast<Vertex>(strs[1]);
  bid.bid    = boost::lexical_cast<mbogo_weight_t>(strs[2]);
  return bid;
}

int getBidder(std::string bidHeader)
{
  int bidder;

  std::vector<std::string> strs;
  boost::split(strs, bidHeader, boost::is_any_of("_V"));
  bidder = boost::lexical_cast<int>(strs.back());

  return bidder;
}

std::string getVar(std::string header, const int id)
{
  std::stringstream ss;
  ss << header << id;
  return ss.str();
}

std::string getBidVar(const int id)
{
  return getVar(MVAR_BID_HEADER, id);
}

std::string getPathVar(int id)
{
  return getVar(MVAR_PATH_HEADER, id);
}

std::string getPathVarVal(std::string sPath)
{
  std::stringstream ss;
  ss << MVAR_PATH << "=" << sPath;
  return ss.str();
}

<commit_msg>Moved sample locs even further apart<commit_after>

#include "../lib_graphs/defs.h"

#include "DebugPrinter.h"

#include "AuctionDefs.h"

#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

const size_t __num_nodes = 9;
const size_t __num_edges = 36;
Edge __edges[__num_edges] = {
  Edge(_a, _b), Edge(_a, _c), Edge(_a, _d), Edge(_a, _e), Edge(_a, _f), Edge(_a, _g), Edge(_a, _h), Edge(_a, _i),
  Edge(_b, _c), Edge(_b, _d), Edge(_b, _e), Edge(_b, _f), Edge(_b, _g), Edge(_b, _h), Edge(_b, _i),
  Edge(_c, _d), Edge(_c, _e), Edge(_c, _f), Edge(_c, _g), Edge(_c, _h), Edge(_c, _i),
  Edge(_d, _e), Edge(_d, _f), Edge(_d, _g), Edge(_d, _h), Edge(_d, _i),
  Edge(_e, _f), Edge(_e, _g), Edge(_e, _h), Edge(_e, _i),
  Edge(_f, _g), Edge(_f, _h), Edge(_f, _i),
  Edge(_g, _h), Edge(_g, _i),
  Edge(_h, _i)
};
int __weights[__num_edges] = {
    4,       8,       11,      8,      7,        4,       2,      9,
    14,      10,      2,       1,      6,        7,       4,
    8,       11,      8,       7,      4,        2,
    9,       14,      10,      2,      1,
    6,       7,       4,       8,
    11,      8,       7,
    4,       2,
    9 };
Loc __locations[__num_nodes] = {
    Loc(25, 0), Loc(50, 50), Loc(100, 50), Loc(150, 50),
    Loc(200, 0), Loc(150, -50), Loc(100, -50), Loc(50, -50), Loc(75, 0)
};
//Loc __locations[__num_nodes] = {
//    Loc(0.5, 0), Loc(1, 1), Loc(2, 1), Loc(3, 1),
//    Loc(4, 0), Loc(3, -1), Loc(2, -1), Loc(1, -1), Loc(1.5, 0)
//};

std::string pathToString(Loc path[], const size_t pathSize)
{
  std::stringstream ss;
  size_t i;

  // Cycle through all but last one
  for (i = 0; i < pathSize - 1; i++)
    ss << path[i].first << "," << path[i].second << ":";

  // Finish with last one
  ss << path[i].first << "," << path[i].second;

  return ss.str();
}

template<typename U, typename V>
std::string pairToString(std::pair<U,V> pair)
{
  std::stringstream ss;
  ss << pair.first << "," << pair.second;
  return ss.str();
}

std::string bidToString(Bid bid)
{
  return pairToString(bid);
}

Bid bidFromString(std::string str)
{
  Bid bid;
  std::vector<std::string> strs;
  boost::split(strs, str, boost::is_any_of(","));
  bid = std::make_pair(
      boost::lexical_cast<Vertex>(strs[0]),
      boost::lexical_cast<mbogo_weight_t>(strs[1]));
  return bid;
}

std::string winningBidToString(WinningBid bid)
{
  std::stringstream ss;
  ss << bid.winner << "," << bid.target << "," << bid.bid;
  return ss.str();
}

WinningBid winningBidFromString(std::string str)
{
  WinningBid bid;
  std::vector<std::string> strs;
  boost::split(strs, str, boost::is_any_of(","));
  bid.winner = boost::lexical_cast<int>(strs[0]);
  bid.target = boost::lexical_cast<Vertex>(strs[1]);
  bid.bid    = boost::lexical_cast<mbogo_weight_t>(strs[2]);
  return bid;
}

int getBidder(std::string bidHeader)
{
  int bidder;

  std::vector<std::string> strs;
  boost::split(strs, bidHeader, boost::is_any_of("_V"));
  bidder = boost::lexical_cast<int>(strs.back());

  return bidder;
}

std::string getVar(std::string header, const int id)
{
  std::stringstream ss;
  ss << header << id;
  return ss.str();
}

std::string getBidVar(const int id)
{
  return getVar(MVAR_BID_HEADER, id);
}

std::string getPathVar(int id)
{
  return getVar(MVAR_PATH_HEADER, id);
}

std::string getPathVarVal(std::string sPath)
{
  std::stringstream ss;
  ss << MVAR_PATH << "=" << sPath;
  return ss.str();
}

<|endoftext|>


<commit_before>// Copyright (c) 2011-2018 The Bitcoin Core developers
// Copyright (c) 2014-2017 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/addresstablemodel.h>

#include <qt/guiutil.h>
#include <qt/walletmodel.h>

#include <base58.h>
#include <wallet/wallet.h>

#include <QFont>
#include <QDebug>

const QString AddressTableModel::Send = "S";
const QString AddressTableModel::Receive = "R";

struct AddressTableEntry
{
    enum Type {
        Sending,
        Receiving,
        Hidden /* QSortFilterProxyModel will filter these out */
    };

    Type type;
    QString label;
    QString address;

    AddressTableEntry() {}
    AddressTableEntry(Type _type, const QString &_label, const QString &_address):
        type(_type), label(_label), address(_address) {}
};

struct AddressTableEntryLessThan
{
    bool operator()(const AddressTableEntry &a, const AddressTableEntry &b) const
    {
        return a.address < b.address;
    }
    bool operator()(const AddressTableEntry &a, const QString &b) const
    {
        return a.address < b;
    }
    bool operator()(const QString &a, const AddressTableEntry &b) const
    {
        return a < b.address;
    }
};

/* Determine address type from address purpose */
static AddressTableEntry::Type translateTransactionType(const QString &strPurpose, bool isMine)
{
    AddressTableEntry::Type addressType = AddressTableEntry::Hidden;
    // "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
    if (strPurpose == "send")
        addressType = AddressTableEntry::Sending;
    else if (strPurpose == "receive")
        addressType = AddressTableEntry::Receiving;
    else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
        addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
    return addressType;
}

// Private implementation
class AddressTablePriv
{
public:
    CWallet *wallet;
    QList<AddressTableEntry> cachedAddressTable;
    AddressTableModel *parent;

    AddressTablePriv(CWallet *_wallet, AddressTableModel *_parent):
        wallet(_wallet), parent(_parent) {}

    void refreshAddressTable()
    {
        cachedAddressTable.clear();
        {
            LOCK(wallet->cs_wallet);
            for (const std::pair<CTxDestination, CAddressBookData>& item : wallet->mapAddressBook)
            {
                const CTxDestination& address = item.first;
                bool fMine = IsMine(*wallet, address);
                AddressTableEntry::Type addressType = translateTransactionType(
                        QString::fromStdString(item.second.purpose), fMine);
                const std::string& strName = item.second.name;
                cachedAddressTable.append(AddressTableEntry(addressType,
                                  QString::fromStdString(strName),
                                  QString::fromStdString(EncodeDestination(address))));
            }
        }
        // qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order
        // Even though the map is already sorted this re-sorting step is needed because the originating map
        // is sorted by binary address, not by base58() address.
        qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
    }

    void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
    {
        // Find address / label in model
        QList<AddressTableEntry>::iterator lower = qLowerBound(
            cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
        QList<AddressTableEntry>::iterator upper = qUpperBound(
            cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
        int lowerIndex = (lower - cachedAddressTable.begin());
        int upperIndex = (upper - cachedAddressTable.begin());
        bool inModel = (lower != upper);
        AddressTableEntry::Type newEntryType = translateTransactionType(purpose, isMine);

        switch(status)
        {
        case CT_NEW:
            if(inModel)
            {
                qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_NEW, but entry is already in model";
                break;
            }
            parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
            cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address));
            parent->endInsertRows();
            break;
        case CT_UPDATED:
            if(!inModel)
            {
                qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_UPDATED, but entry is not in model";
                break;
            }
            lower->type = newEntryType;
            lower->label = label;
            parent->emitDataChanged(lowerIndex);
            break;
        case CT_DELETED:
            if(!inModel)
            {
                qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_DELETED, but entry is not in model";
                break;
            }
            parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
            cachedAddressTable.erase(lower, upper);
            parent->endRemoveRows();
            break;
        }
    }

    int size()
    {
        return cachedAddressTable.size();
    }

    AddressTableEntry *index(int idx)
    {
        if(idx >= 0 && idx < cachedAddressTable.size())
        {
            return &cachedAddressTable[idx];
        }
        else
        {
            return 0;
        }
    }
};

AddressTableModel::AddressTableModel(CWallet *_wallet, WalletModel *parent) :
    QAbstractTableModel(parent),walletModel(parent),wallet(_wallet),priv(0)
{
    columns << tr("Label") << tr("Address");
    priv = new AddressTablePriv(wallet, this);
    priv->refreshAddressTable();
}

AddressTableModel::~AddressTableModel()
{
    delete priv;
}

int AddressTableModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return priv->size();
}

int AddressTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return columns.length();
}

QVariant AddressTableModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();

    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());

    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        switch(index.column())
        {
        case Label:
            if(rec->label.isEmpty() && role == Qt::DisplayRole)
            {
                return tr("(no label)");
            }
            else
            {
                return rec->label;
            }
        case Address:
            return rec->address;
        }
    }
    else if (role == Qt::FontRole)
    {
        QFont font;
        if(index.column() == Address)
        {
            font = GUIUtil::fixedPitchFont();
        }
        return font;
    }
    else if (role == TypeRole)
    {
        switch(rec->type)
        {
        case AddressTableEntry::Sending:
            return Send;
        case AddressTableEntry::Receiving:
            return Receive;
        default: break;
        }
    }
    return QVariant();
}

bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid())
        return false;
    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
    std::string strPurpose = (rec->type == AddressTableEntry::Sending ? "send" : "receive");
    editStatus = OK;

    if(role == Qt::EditRole)
    {
        LOCK(wallet->cs_wallet); /* For SetAddressBook / DelAddressBook */
        CTxDestination curAddress = DecodeDestination(rec->address.toStdString());
        if(index.column() == Label)
        {
            // Do nothing, if old label == new label
            if(rec->label == value.toString())
            {
                editStatus = NO_CHANGES;
                return false;
            }
            wallet->SetAddressBook(curAddress, value.toString().toStdString(), strPurpose);
        } else if(index.column() == Address) {
            CTxDestination newAddress = DecodeDestination(value.toString().toStdString());
            // Refuse to set invalid address, set error status and return false
            if(boost::get<CNoDestination>(&newAddress))
            {
                editStatus = INVALID_ADDRESS;
                return false;
            }
            // Do nothing, if old address == new address
            else if(newAddress == curAddress)
            {
                editStatus = NO_CHANGES;
                return false;
            }
            // Check for duplicate addresses to prevent accidental deletion of addresses, if you try
            // to paste an existing address over another address (with a different label)
            else if(wallet->mapAddressBook.count(newAddress))
            {
                editStatus = DUPLICATE_ADDRESS;
                return false;
            }
            // Double-check that we're not overwriting a receiving address
            else if(rec->type == AddressTableEntry::Sending)
            {
                // Remove old entry
                wallet->DelAddressBook(curAddress);
                // Add new entry with new address
                wallet->SetAddressBook(newAddress, rec->label.toStdString(), strPurpose);
            }
        }
        return true;
    }
    return false;
}

QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation == Qt::Horizontal)
    {
        if(role == Qt::DisplayRole && section < columns.size())
        {
            return columns[section];
        }
    }
    return QVariant();
}

Qt::ItemFlags AddressTableModel::flags(const QModelIndex &index) const
{
    if(!index.isValid())
        return 0;
    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());

    Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
    // Can edit address and label for sending addresses,
    // and only label for receiving addresses.
    if(rec->type == AddressTableEntry::Sending ||
      (rec->type == AddressTableEntry::Receiving && index.column()==Label))
    {
        retval |= Qt::ItemIsEditable;
    }
    return retval;
}

QModelIndex AddressTableModel::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    AddressTableEntry *data = priv->index(row);
    if(data)
    {
        return createIndex(row, column, priv->index(row));
    }
    else
    {
        return QModelIndex();
    }
}

void AddressTableModel::updateEntry(const QString &address,
        const QString &label, bool isMine, const QString &purpose, int status)
{
    // Update address book model from Chaincoin core
    priv->updateEntry(address, label, isMine, purpose, status);
}

QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address, const OutputType address_type)
{
    std::string strLabel = label.toStdString();
    std::string strAddress = address.toStdString();

    editStatus = OK;

    if(type == Send)
    {
        if(!walletModel->validateAddress(address))
        {
            editStatus = INVALID_ADDRESS;
            return QString();
        }
        // Check for duplicate addresses
        {
            LOCK(wallet->cs_wallet);
            if(wallet->mapAddressBook.count(DecodeDestination(strAddress)))
            {
                editStatus = DUPLICATE_ADDRESS;
                return QString();
            }
        }
    }
    else if(type == Receive)
    {
        // Generate a new address to associate with given label
        CPubKey newKey;
        if(!wallet->GetKeyFromPool(newKey))
        {
            WalletModel::UnlockContext ctx(walletModel->requestUnlock());
            if(!ctx.isValid())
            {
                // Unlock wallet failed or was cancelled
                editStatus = WALLET_UNLOCK_FAILURE;
                return QString();
            }
            if(!wallet->GetKeyFromPool(newKey))
            {
                editStatus = KEY_GENERATION_FAILURE;
                return QString();
            }
        }
        wallet->LearnRelatedScripts(newKey, address_type);
        strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type));
    }
    else
    {
        return QString();
    }

    // Add entry
    {
        LOCK(wallet->cs_wallet);
        wallet->SetAddressBook(DecodeDestination(strAddress), strLabel,
                               (type == Send ? "send" : "receive"));
    }
    return QString::fromStdString(strAddress);
}

bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent)
{
    Q_UNUSED(parent);
    AddressTableEntry *rec = priv->index(row);
    if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving)
    {
        // Can only remove one row at a time, and cannot remove rows not in model.
        // Also refuse to remove receiving addresses.
        return false;
    }
    {
        LOCK(wallet->cs_wallet);
        wallet->DelAddressBook(DecodeDestination(rec->address.toStdString()));
    }
    return true;
}

/* Look up label for address in address book, if not found return empty string.
 */
QString AddressTableModel::labelForAddress(const QString &address) const
{
    {
        LOCK(wallet->cs_wallet);
        CTxDestination destination = DecodeDestination(address.toStdString());
        std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(destination);
        if (mi != wallet->mapAddressBook.end())
        {
            return QString::fromStdString(mi->second.name);
        }
    }
    return QString();
}

int AddressTableModel::lookupAddress(const QString &address) const
{
    QModelIndexList lst = match(index(0, Address, QModelIndex()),
                                Qt::EditRole, address, 1, Qt::MatchExactly);
    if(lst.isEmpty())
    {
        return -1;
    }
    else
    {
        return lst.at(0).row();
    }
}

void AddressTableModel::emitDataChanged(int idx)
{
    Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
}
<commit_msg>Remove redundant locks<commit_after>// Copyright (c) 2011-2018 The Bitcoin Core developers
// Copyright (c) 2014-2017 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/addresstablemodel.h>

#include <qt/guiutil.h>
#include <qt/walletmodel.h>

#include <base58.h>
#include <wallet/wallet.h>

#include <QFont>
#include <QDebug>

const QString AddressTableModel::Send = "S";
const QString AddressTableModel::Receive = "R";

struct AddressTableEntry
{
    enum Type {
        Sending,
        Receiving,
        Hidden /* QSortFilterProxyModel will filter these out */
    };

    Type type;
    QString label;
    QString address;

    AddressTableEntry() {}
    AddressTableEntry(Type _type, const QString &_label, const QString &_address):
        type(_type), label(_label), address(_address) {}
};

struct AddressTableEntryLessThan
{
    bool operator()(const AddressTableEntry &a, const AddressTableEntry &b) const
    {
        return a.address < b.address;
    }
    bool operator()(const AddressTableEntry &a, const QString &b) const
    {
        return a.address < b;
    }
    bool operator()(const QString &a, const AddressTableEntry &b) const
    {
        return a < b.address;
    }
};

/* Determine address type from address purpose */
static AddressTableEntry::Type translateTransactionType(const QString &strPurpose, bool isMine)
{
    AddressTableEntry::Type addressType = AddressTableEntry::Hidden;
    // "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
    if (strPurpose == "send")
        addressType = AddressTableEntry::Sending;
    else if (strPurpose == "receive")
        addressType = AddressTableEntry::Receiving;
    else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
        addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
    return addressType;
}

// Private implementation
class AddressTablePriv
{
public:
    CWallet *wallet;
    QList<AddressTableEntry> cachedAddressTable;
    AddressTableModel *parent;

    AddressTablePriv(CWallet *_wallet, AddressTableModel *_parent):
        wallet(_wallet), parent(_parent) {}

    void refreshAddressTable()
    {
        cachedAddressTable.clear();
        {
            LOCK(wallet->cs_wallet);
            for (const std::pair<CTxDestination, CAddressBookData>& item : wallet->mapAddressBook)
            {
                const CTxDestination& address = item.first;
                bool fMine = IsMine(*wallet, address);
                AddressTableEntry::Type addressType = translateTransactionType(
                        QString::fromStdString(item.second.purpose), fMine);
                const std::string& strName = item.second.name;
                cachedAddressTable.append(AddressTableEntry(addressType,
                                  QString::fromStdString(strName),
                                  QString::fromStdString(EncodeDestination(address))));
            }
        }
        // qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order
        // Even though the map is already sorted this re-sorting step is needed because the originating map
        // is sorted by binary address, not by base58() address.
        qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
    }

    void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
    {
        // Find address / label in model
        QList<AddressTableEntry>::iterator lower = qLowerBound(
            cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
        QList<AddressTableEntry>::iterator upper = qUpperBound(
            cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
        int lowerIndex = (lower - cachedAddressTable.begin());
        int upperIndex = (upper - cachedAddressTable.begin());
        bool inModel = (lower != upper);
        AddressTableEntry::Type newEntryType = translateTransactionType(purpose, isMine);

        switch(status)
        {
        case CT_NEW:
            if(inModel)
            {
                qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_NEW, but entry is already in model";
                break;
            }
            parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
            cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address));
            parent->endInsertRows();
            break;
        case CT_UPDATED:
            if(!inModel)
            {
                qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_UPDATED, but entry is not in model";
                break;
            }
            lower->type = newEntryType;
            lower->label = label;
            parent->emitDataChanged(lowerIndex);
            break;
        case CT_DELETED:
            if(!inModel)
            {
                qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_DELETED, but entry is not in model";
                break;
            }
            parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
            cachedAddressTable.erase(lower, upper);
            parent->endRemoveRows();
            break;
        }
    }

    int size()
    {
        return cachedAddressTable.size();
    }

    AddressTableEntry *index(int idx)
    {
        if(idx >= 0 && idx < cachedAddressTable.size())
        {
            return &cachedAddressTable[idx];
        }
        else
        {
            return 0;
        }
    }
};

AddressTableModel::AddressTableModel(CWallet *_wallet, WalletModel *parent) :
    QAbstractTableModel(parent),walletModel(parent),wallet(_wallet),priv(0)
{
    columns << tr("Label") << tr("Address");
    priv = new AddressTablePriv(wallet, this);
    priv->refreshAddressTable();
}

AddressTableModel::~AddressTableModel()
{
    delete priv;
}

int AddressTableModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return priv->size();
}

int AddressTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return columns.length();
}

QVariant AddressTableModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();

    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());

    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        switch(index.column())
        {
        case Label:
            if(rec->label.isEmpty() && role == Qt::DisplayRole)
            {
                return tr("(no label)");
            }
            else
            {
                return rec->label;
            }
        case Address:
            return rec->address;
        }
    }
    else if (role == Qt::FontRole)
    {
        QFont font;
        if(index.column() == Address)
        {
            font = GUIUtil::fixedPitchFont();
        }
        return font;
    }
    else if (role == TypeRole)
    {
        switch(rec->type)
        {
        case AddressTableEntry::Sending:
            return Send;
        case AddressTableEntry::Receiving:
            return Receive;
        default: break;
        }
    }
    return QVariant();
}

bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid())
        return false;
    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
    std::string strPurpose = (rec->type == AddressTableEntry::Sending ? "send" : "receive");
    editStatus = OK;

    if(role == Qt::EditRole)
    {
        LOCK(wallet->cs_wallet); /* For SetAddressBook / DelAddressBook */
        CTxDestination curAddress = DecodeDestination(rec->address.toStdString());
        if(index.column() == Label)
        {
            // Do nothing, if old label == new label
            if(rec->label == value.toString())
            {
                editStatus = NO_CHANGES;
                return false;
            }
            wallet->SetAddressBook(curAddress, value.toString().toStdString(), strPurpose);
        } else if(index.column() == Address) {
            CTxDestination newAddress = DecodeDestination(value.toString().toStdString());
            // Refuse to set invalid address, set error status and return false
            if(boost::get<CNoDestination>(&newAddress))
            {
                editStatus = INVALID_ADDRESS;
                return false;
            }
            // Do nothing, if old address == new address
            else if(newAddress == curAddress)
            {
                editStatus = NO_CHANGES;
                return false;
            }
            // Check for duplicate addresses to prevent accidental deletion of addresses, if you try
            // to paste an existing address over another address (with a different label)
            else if(wallet->mapAddressBook.count(newAddress))
            {
                editStatus = DUPLICATE_ADDRESS;
                return false;
            }
            // Double-check that we're not overwriting a receiving address
            else if(rec->type == AddressTableEntry::Sending)
            {
                // Remove old entry
                wallet->DelAddressBook(curAddress);
                // Add new entry with new address
                wallet->SetAddressBook(newAddress, rec->label.toStdString(), strPurpose);
            }
        }
        return true;
    }
    return false;
}

QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation == Qt::Horizontal)
    {
        if(role == Qt::DisplayRole && section < columns.size())
        {
            return columns[section];
        }
    }
    return QVariant();
}

Qt::ItemFlags AddressTableModel::flags(const QModelIndex &index) const
{
    if(!index.isValid())
        return 0;
    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());

    Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
    // Can edit address and label for sending addresses,
    // and only label for receiving addresses.
    if(rec->type == AddressTableEntry::Sending ||
      (rec->type == AddressTableEntry::Receiving && index.column()==Label))
    {
        retval |= Qt::ItemIsEditable;
    }
    return retval;
}

QModelIndex AddressTableModel::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    AddressTableEntry *data = priv->index(row);
    if(data)
    {
        return createIndex(row, column, priv->index(row));
    }
    else
    {
        return QModelIndex();
    }
}

void AddressTableModel::updateEntry(const QString &address,
        const QString &label, bool isMine, const QString &purpose, int status)
{
    // Update address book model from Chaincoin core
    priv->updateEntry(address, label, isMine, purpose, status);
}

QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address, const OutputType address_type)
{
    std::string strLabel = label.toStdString();
    std::string strAddress = address.toStdString();

    editStatus = OK;

    if(type == Send)
    {
        if(!walletModel->validateAddress(address))
        {
            editStatus = INVALID_ADDRESS;
            return QString();
        }
        // Check for duplicate addresses
        {
            LOCK(wallet->cs_wallet);
            if(wallet->mapAddressBook.count(DecodeDestination(strAddress)))
            {
                editStatus = DUPLICATE_ADDRESS;
                return QString();
            }
        }
    }
    else if(type == Receive)
    {
        // Generate a new address to associate with given label
        CPubKey newKey;
        if(!wallet->GetKeyFromPool(newKey))
        {
            WalletModel::UnlockContext ctx(walletModel->requestUnlock());
            if(!ctx.isValid())
            {
                // Unlock wallet failed or was cancelled
                editStatus = WALLET_UNLOCK_FAILURE;
                return QString();
            }
            if(!wallet->GetKeyFromPool(newKey))
            {
                editStatus = KEY_GENERATION_FAILURE;
                return QString();
            }
        }
        wallet->LearnRelatedScripts(newKey, address_type);
        strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type));
    }
    else
    {
        return QString();
    }

    // Add entry
    wallet->SetAddressBook(DecodeDestination(strAddress), strLabel,
                           (type == Send ? "send" : "receive"));
    return QString::fromStdString(strAddress);
}

bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent)
{
    Q_UNUSED(parent);
    AddressTableEntry *rec = priv->index(row);
    if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving)
    {
        // Can only remove one row at a time, and cannot remove rows not in model.
        // Also refuse to remove receiving addresses.
        return false;
    }
    wallet->DelAddressBook(DecodeDestination(rec->address.toStdString()));
    return true;
}

/* Look up label for address in address book, if not found return empty string.
 */
QString AddressTableModel::labelForAddress(const QString &address) const
{
    {
        LOCK(wallet->cs_wallet);
        CTxDestination destination = DecodeDestination(address.toStdString());
        std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(destination);
        if (mi != wallet->mapAddressBook.end())
        {
            return QString::fromStdString(mi->second.name);
        }
    }
    return QString();
}

int AddressTableModel::lookupAddress(const QString &address) const
{
    QModelIndexList lst = match(index(0, Address, QModelIndex()),
                                Qt::EditRole, address, 1, Qt::MatchExactly);
    if(lst.isEmpty())
    {
        return -1;
    }
    else
    {
        return lst.at(0).row();
    }
}

void AddressTableModel::emitDataChanged(int idx)
{
    Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
}
<|endoftext|>


<commit_before>/***********************************************************************
 vallist.cpp - Implements utility functions for building value lists.
	This is internal functionality used within the library.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ 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.

 MySQL++ 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 MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "vallist.h"

#include "result.h"
#include "row.h"

using std::string;

namespace mysqlpp {

void
create_vector(size_t size, std::vector<bool>& v, bool t0, bool t1, bool t2,
		bool t3, bool t4, bool t5, bool t6, bool t7, bool t8, bool t9,
		bool ta, bool tb, bool tc)
{
	v.reserve(size);

	v.push_back(t0);
	if (size == 1) return;

	v.push_back(t1);
	if (size == 2) return;

	v.push_back(t2);
	if (size == 3) return;

	v.push_back(t3);
	if (size == 4) return;

	v.push_back(t4);
	if (size == 5) return;

	v.push_back(t5);
	if (size == 6) return;

	v.push_back(t6);
	if (size == 7) return;

	v.push_back(t7);
	if (size == 8) return;

	v.push_back(t8);
	if (size == 9) return;

	v.push_back(t9);
	if (size == 10) return;

	v.push_back(ta);
	if (size == 11) return;

	v.push_back(tb);
	if (size == 12) return;

	v.push_back(tc);
}

template <class Container>
void create_vector(const Container& c, std::vector<bool>& v,
		std::string s0, std::string s1, std::string s2, std::string s3,
		std::string s4, std::string s5, std::string s6, std::string s7,
		std::string s8, std::string s9, std::string sa, std::string sb,
		std::string sc)
{
	v.insert(v.begin(), c.size(), false);

	v[c.parent().field_num(s0)] = true;
	if (s1.empty()) return;

	v[c.parent().field_num(s1)] = true;
	if (s2.empty()) return;

	v[c.parent().field_num(s2)] = true;
	if (s3.empty()) return;

	v[c.parent().field_num(s3)] = true;
	if (s4.empty()) return;

	v[c.parent().field_num(s4)] = true;
	if (s5.empty()) return;

	v[c.parent().field_num(s5)] = true;
	if (s6.empty()) return;

	v[c.parent().field_num(s6)] = true;
	if (s7.empty()) return;

	v[c.parent().field_num(s7)] = true;
	if (s8.empty()) return;

	v[c.parent().field_num(s8)] = true;
	if (s9.empty()) return;

	v[c.parent().field_num(s9)] = true;
	if (sa.empty()) return;

	v[c.parent().field_num(sa)] = true;
	if (sb.empty()) return;

	v[c.parent().field_num(sb)] = true;
	if (sc.empty()) return;

	v[c.parent().field_num(sc)] = true;
}

// Instantiate above template.  Not sure why this is necessary.

template void
create_vector(const Row& c, std::vector<bool>& v, string s0,
		string s1, string s2, string s3, string s4, string s5,
		string s6, string s7, string s8, string s9, string sa,
		string sb, string sc);

} // end namespace mysqlpp

<commit_msg>Final (?) Doxygen warning squish<commit_after>/***********************************************************************
 vallist.cpp - Implements utility functions for building value lists.
	This is internal functionality used within the library.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ 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.

 MySQL++ 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 MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "vallist.h"

#include "result.h"
#include "row.h"

using std::string;

namespace mysqlpp {

void
create_vector(size_t size, std::vector<bool>& v, bool t0, bool t1, bool t2,
		bool t3, bool t4, bool t5, bool t6, bool t7, bool t8, bool t9,
		bool ta, bool tb, bool tc)
{
	v.reserve(size);

	v.push_back(t0);
	if (size == 1) return;

	v.push_back(t1);
	if (size == 2) return;

	v.push_back(t2);
	if (size == 3) return;

	v.push_back(t3);
	if (size == 4) return;

	v.push_back(t4);
	if (size == 5) return;

	v.push_back(t5);
	if (size == 6) return;

	v.push_back(t6);
	if (size == 7) return;

	v.push_back(t7);
	if (size == 8) return;

	v.push_back(t8);
	if (size == 9) return;

	v.push_back(t9);
	if (size == 10) return;

	v.push_back(ta);
	if (size == 11) return;

	v.push_back(tb);
	if (size == 12) return;

	v.push_back(tc);
}

template <class Container>
void create_vector(const Container& c, std::vector<bool>& v,
		std::string s0, std::string s1, std::string s2, std::string s3,
		std::string s4, std::string s5, std::string s6, std::string s7,
		std::string s8, std::string s9, std::string sa, std::string sb,
		std::string sc)
{
	v.insert(v.begin(), c.size(), false);

	v[c.parent().field_num(s0)] = true;
	if (s1.empty()) return;

	v[c.parent().field_num(s1)] = true;
	if (s2.empty()) return;

	v[c.parent().field_num(s2)] = true;
	if (s3.empty()) return;

	v[c.parent().field_num(s3)] = true;
	if (s4.empty()) return;

	v[c.parent().field_num(s4)] = true;
	if (s5.empty()) return;

	v[c.parent().field_num(s5)] = true;
	if (s6.empty()) return;

	v[c.parent().field_num(s6)] = true;
	if (s7.empty()) return;

	v[c.parent().field_num(s7)] = true;
	if (s8.empty()) return;

	v[c.parent().field_num(s8)] = true;
	if (s9.empty()) return;

	v[c.parent().field_num(s9)] = true;
	if (sa.empty()) return;

	v[c.parent().field_num(sa)] = true;
	if (sb.empty()) return;

	v[c.parent().field_num(sb)] = true;
	if (sc.empty()) return;

	v[c.parent().field_num(sc)] = true;
}

#if !defined(DOXYGEN_IGNORE)
// Instantiate above template.  Not sure why this is necessary.  Hide it
// from Doxygen, because we clearly cannot appease it by documenting it.
template void
create_vector(const Row& c, std::vector<bool>& v, string s0,
		string s1, string s2, string s3, string s4, string s5,
		string s6, string s7, string s8, string s9, string sa,
		string sb, string sc);
#endif

} // end namespace mysqlpp

<|endoftext|>


<commit_before>// BrainCloudClient.cpp
// BrainCloudLib
// Copyright 2016 bitHeads, Inc. All Rights Reserved.

#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

#include "braincloud/BrainCloudClient.h"

#include "braincloud/internal/Device.h"
#include "braincloud/internal/JsonUtil.h"
#include "braincloud/internal/URLRequestMethod.h"

namespace BrainCloud
{
    // Define all static member variables.
    bool BrainCloudClient::EnableSingletonMode = false;
    const char * BrainCloudClient::SingletonUseErrorMessage =
            "Singleton usage is disabled. If called by mistake, use your own variable that holds an instance of the bcWrapper/bcClient.";

    BrainCloudClient * BrainCloudClient::_instance = NULL;
    std::string BrainCloudClient::s_brainCloudClientVersion = "4.4.0";
    const char* BC_SERVER_URL = "https://sharedprod.braincloudservers.com/dispatcherv2";

    /**
     * Constructor
     */
    BrainCloudClient::BrainCloudClient() :
        _brainCloudComms(IBrainCloudComms::create(this)),
        _rttComms(new RTTComms(this)),
        _asyncMatchService(new BrainCloudAsyncMatch(this)),
        _authenticationService(new BrainCloudAuthentication(this)),
        _chatService(new BrainCloudChat(this)),
        _dataStreamService(new BrainCloudDataStream(this)),
        _entityService(new BrainCloudEntity(this)),
        _eventService(new BrainCloudEvent(this)),
        _fileService(new BrainCloudFile(this)),
        _friendService(new BrainCloudFriend(this)),
        _gamificationService(new BrainCloudGamification(this)),
        _globalAppService(new BrainCloudGlobalApp(this)),
        _globalEntityService(new BrainCloudGlobalEntity(this)),
        _globalStatisticsService(new BrainCloudGlobalStatistics(this)),
        _groupService(new BrainCloudGroup(this)),
        _identityService(new BrainCloudIdentity(this)),
        _lobbyService(new BrainCloudLobby(this)),
        _mailService(new BrainCloudMail(this)),
        _matchmakingService(new BrainCloudMatchmaking(this)),
        _messagingService(new BrainCloudMessaging(this)),
        _oneWayMatchService(new BrainCloudOneWayMatch(this)),
        _playbackStreamService(new BrainCloudPlaybackStream(this)),
        _playerStateService(new BrainCloudPlayerState(this)),
        _playerStatisticsService(new BrainCloudPlayerStatistics(this)),
        _playerStatisticsEventService(new BrainCloudPlayerStatisticsEvent(this)),
        _presenceService(new BrainCloudPresence(this)),
        _productService(new BrainCloudProduct(this)),
        _virtualCurrencyService(new BrainCloudVirtualCurrency(this)),
        _appStoreService(new BrainCloudAppStore(this)),
        _profanityService(new BrainCloudProfanity(this)),
        _pushNotificationService(new BrainCloudPushNotification(this)),
        _redemptionCodeService(new BrainCloudRedemptionCode(this)),
        _s3HandlingService(new BrainCloudS3Handling(this)),
        _scriptService(new BrainCloudScript(this)),
        _socialLeaderboardService(new BrainCloudSocialLeaderboard(this)),
        _steamService(new BrainCloudSteam(this)),
        _timeService(new BrainCloudTime(this)),
        _tournamentService(new BrainCloudTournament(this)),
        _customEntityService(new BrainCloudCustomEntity(this)),
        _itemCatalogService(new BrainCloudItemCatalog(this)),
        _userItemsService(new BrainCloudUserItems(this)),
        _releasePlatform(""),
        _appVersion(""),
        _timezoneOffset(0.0)
    {
        //needed this here otherwise out of scope compiler error
        _rttService = new BrainCloudRTT(_rttComms, this);
    }

    BrainCloudClient::~BrainCloudClient()
    {
        delete _rttService;
        delete _tournamentService;
        delete _customEntityService;
        delete _itemCatalogService;
        delete _timeService;
        delete _steamService;
        delete _socialLeaderboardService;
        delete _scriptService;
        delete _s3HandlingService;
        delete _redemptionCodeService;
        delete _pushNotificationService;
        delete _profanityService;
        delete _appStoreService;
        delete _virtualCurrencyService;
        delete _productService;
        delete _presenceService;
        delete _playerStatisticsEventService;
        delete _playerStatisticsService;
        delete _playerStateService;
        delete _playbackStreamService;
        delete _oneWayMatchService;
        delete _messagingService;
        delete _matchmakingService;
        delete _mailService;
        delete _lobbyService;
        delete _identityService;
        delete _groupService;
        delete _globalStatisticsService;
        delete _globalEntityService;
        delete _globalAppService;
        delete _gamificationService;
        delete _friendService;
        delete _fileService;
        delete _eventService;
        delete _entityService;
        delete _dataStreamService;
        delete _chatService;
        delete _authenticationService;
        delete _asyncMatchService;
        delete _rttComms;
        delete _brainCloudComms;
    }

    ////////////////////////////////////////////////////
    // Public Methods
    ////////////////////////////////////////////////////

    const char * BrainCloudClient::getSessionId() const {
        return(_brainCloudComms->getSessionId().c_str());
    }

    const char * BrainCloudClient::getRttConnectionId() const{
        return(_rttComms->getConnectionId().c_str());
    }

    void BrainCloudClient::initializeComms(const char * in_serverURL, const char * in_appId, const std::map<std::string, std::string>& in_secretMap)
    {
        if (_brainCloudComms)
        {
            // automatically upgrade any older clients using "dispatcher" url
            // to "dispatcherv2" endpoint. Comms supports this now and otherwise
            // the change is transparent to the client.
            const char * urlToUse = in_serverURL;
            std::string url = in_serverURL;
            if (url.find("dispatcherv2") == std::string::npos)
            {
                size_t index = url.find("dispatcher");
                if (index != std::string::npos)
                {
                    url = url.substr(0, index);
                    url += "dispatcherv2";
                    urlToUse = url.c_str();
                }
            }
            _brainCloudComms->initializeWithApps(urlToUse, in_appId, in_secretMap);
        }

        if (_rttComms)
        {
            _rttComms->initialize();
        }
    }

    void BrainCloudClient::initialize(const char * in_serverURL, const char * in_secretKey, const char * in_appId, const char * in_appVersion)
    {
        std::string error = "";
        if (in_serverURL == NULL || strlen(in_serverURL) <= 0)
            error = "serverURL was null or empty";
        else if (in_secretKey == NULL || strlen(in_secretKey) <= 0)
            error = "secretKey was null or empty";
        else if (in_appId == NULL || strlen(in_appId) <= 0)
            error = "appId was null or empty";
        else if (in_appVersion == NULL || strlen(in_appVersion) <= 0)
            error = "appVersion was null or empty";

        if (error.length() > 0)
        {
            std::cout << "ERROR | Failed to initialize brainCloud - " << error;
            return;
        }

        std::map<std::string, std::string> secretMap;
        secretMap[in_appId] = in_secretKey;

        initializeComms(in_serverURL, in_appId, secretMap);
        setupOSLocaleData();

        _releasePlatform = Device::getPlatformName();
        _appVersion = in_appVersion;
    }

    void BrainCloudClient::initialize(const char * in_secretKey, const char * in_appId, const char * in_appVersion)
    {
        initialize(BC_SERVER_URL, in_secretKey, in_appId, in_appVersion);
    }

    void BrainCloudClient::initializeWithApps(const char * in_serverURL, const char * in_defaultAppId, const std::map<std::string, std::string>& in_secretMap, const char * in_appVersion)
    {
        std::string error = "";
        if (in_serverURL == NULL || strlen(in_serverURL) <= 0)
            error = "serverURL was null or empty";
        else if (in_defaultAppId == NULL || strlen(in_defaultAppId) <= 0)
            error = "appId was null or empty";
        else if (in_appVersion == NULL || strlen(in_appVersion) <= 0)
            error = "appVersion was null or empty";
        else if (in_secretMap.find(in_defaultAppId) == in_secretMap.end())
            error = "not secretKey match for appid";

        if (error.length() > 0)
        {
            std::cout << "ERROR | Failed to initialize brainCloud - " << error;
            return;
        }

        initializeComms(in_serverURL, in_defaultAppId, in_secretMap);
        setupOSLocaleData();

        _releasePlatform = Device::getPlatformName();
        _appVersion = in_appVersion;
    }

    void BrainCloudClient::initializeWithApps(const char* in_defaultAppId, const std::map<std::string, std::string>& in_secretMap, const char* in_appVersion)
    {
        initializeWithApps(BC_SERVER_URL, in_defaultAppId, in_secretMap, in_appVersion);
    }

    void BrainCloudClient::initializeIdentity(const char * in_profileId, const char * in_anonymousId)
    {
        _authenticationService->initialize(in_profileId, in_anonymousId);
    }

    void BrainCloudClient::runCallbacks()
    {
        _brainCloudComms->runCallbacks();
        _lobbyService->runPingCallbacks();
        _rttComms->runCallbacks();
    }

    void BrainCloudClient::registerEventCallback(IEventCallback *in_eventCallback)
    {
        _brainCloudComms->registerEventCallback(in_eventCallback);
    }

    void BrainCloudClient::deregisterEventCallback()
    {
        _brainCloudComms->deregisterEventCallback();
    }

    void BrainCloudClient::registerRewardCallback(IRewardCallback *in_rewardCallback)
    {
        _brainCloudComms->registerRewardCallback(in_rewardCallback);
    }

    void BrainCloudClient::deregisterRewardCallback()
    {
        _brainCloudComms->deregisterRewardCallback();
    }

    void BrainCloudClient::registerFileUploadCallback(IFileUploadCallback * in_fileUploadCallback)
    {
        _brainCloudComms->registerFileUploadCallback(in_fileUploadCallback);
    }

    void BrainCloudClient::deregisterFileUploadCallback()
    {
        _brainCloudComms->deregisterFileUploadCallback();
    }

    void BrainCloudClient::registerGlobalErrorCallback(IGlobalErrorCallback * in_globalErrorCallback)
    {
        _brainCloudComms->registerGlobalErrorCallback(in_globalErrorCallback);
    }

    void BrainCloudClient::deregisterGlobalErrorCallback()
    {
        _brainCloudComms->deregisterGlobalErrorCallback();
    }

    void BrainCloudClient::registerNetworkErrorCallback(INetworkErrorCallback * in_networkErrorCallback)
    {
        _brainCloudComms->registerNetworkErrorCallback(in_networkErrorCallback);
    }

    void BrainCloudClient::deregisterNetworkErrorCallback()
    {
        _brainCloudComms->deregisterNetworkErrorCallback();
    }

    void BrainCloudClient::enableLogging(bool shouldEnable)
    {
        _brainCloudComms->enableLogging(shouldEnable);
        _lobbyService->enableLogging(shouldEnable);
        _rttComms->enableLogging(shouldEnable);
    }

    /**
     * Heart beat to keep session(s) current, and retrieve any pending events...
     */
    void BrainCloudClient::heartbeat()
    {
        _brainCloudComms->sendHeartbeat();
    }

    void BrainCloudClient::sendRequest(ServerCall * in_serviceMessage)
    {
        _brainCloudComms->addToQueue(in_serviceMessage);
    }

    void BrainCloudClient::resetCommunication()
    {
        _rttComms->resetCommunication();
        _brainCloudComms->resetCommunication();
        _brainCloudComms->setSessionId("");
        _authenticationService->setProfileId("");
    }

    void BrainCloudClient::shutdown()
    {
        _rttComms->shutdown();
        _brainCloudComms->shutdown();
        _brainCloudComms->setSessionId("");
        _authenticationService->setProfileId("");
    }

    bool BrainCloudClient::isAuthenticated()
    {
        return _brainCloudComms->isAuthenticated();
    }

    bool BrainCloudClient::isInitialized()
    {
        return _brainCloudComms->isInitialized() && _rttComms->isInitialized();
    }

    void BrainCloudClient::setImmediateRetryOnError(bool value)
    {
        _brainCloudComms->setImmediateRetryOnError(value);
    }

    /**
     * Retrieve the pointer to the singleton BrainCloudClient instance.
     */
    BrainCloudClient * BrainCloudClient::getInstance()
    {
        if(EnableSingletonMode == false) {
            throw std::invalid_argument(SingletonUseErrorMessage);
        }

        if (_instance == NULL) {
            _instance = new BrainCloudClient();
        }
        return _instance;
    }

    void BrainCloudClient::setHeartbeatInterval(int in_intervalInMilliseconds) {
        _brainCloudComms->setHeartbeatInterval(in_intervalInMilliseconds);
    }

    const std::vector<int> & BrainCloudClient::getPacketTimeouts()
    {
        return _brainCloudComms->getPacketTimeouts();
    }

    void BrainCloudClient::setPacketTimeouts(const std::vector<int> & in_packetTimeouts)
    {
        _brainCloudComms->setPacketTimeouts(in_packetTimeouts);
    }

    void BrainCloudClient::setPacketTimeoutsToDefault()
    {
        _brainCloudComms->setPacketTimeoutsToDefault();
    }

    void BrainCloudClient::setAuthenticationPacketTimeout(int in_timeoutSecs)
    {
        _brainCloudComms->setAuthenticationPacketTimeout(in_timeoutSecs);
    }

    int BrainCloudClient::getAuthenticationPacketTimeout()
    {
        return _brainCloudComms->getAuthenticationPacketTimeout();
    }

    void BrainCloudClient::setOldStyleStatusMessageErrorCallback(bool in_enabled)
    {
        _brainCloudComms->setOldStyleStatusMessageErrorCallback(in_enabled);
    }

    void BrainCloudClient::setErrorCallbackOn202Status(bool in_isError)
    {
        _brainCloudComms->setErrorCallbackOn202Status(in_isError);
    }

    int BrainCloudClient::getUploadLowTransferRateTimeout()
    {
        return _brainCloudComms->getUploadLowTransferRateTimeout();
    }

    void BrainCloudClient::setUploadLowTransferRateTimeout(int in_timeoutSecs)
    {
        _brainCloudComms->setUploadLowTransferRateTimeout(in_timeoutSecs);
    }

    int BrainCloudClient::getUploadLowTransferRateThreshold()
    {
        return _brainCloudComms->getUploadLowTransferRateThreshold();
    }

    void BrainCloudClient::setUploadLowTransferRateThreshold(int in_bytesPerSec)
    {
        _brainCloudComms->setUploadLowTransferRateThreshold(in_bytesPerSec);
    }

    void BrainCloudClient::enableNetworkErrorMessageCaching(bool in_enabled)
    {
        _brainCloudComms->enableNetworkErrorMessageCaching(in_enabled);
    }

    void BrainCloudClient::retryCachedMessages()
    {
        _brainCloudComms->retryCachedMessages();
    }

    void BrainCloudClient::flushCachedMessages(bool in_sendApiErrorCallbacks)
    {
        _brainCloudComms->flushCachedMessages(in_sendApiErrorCallbacks);
    }

    void BrainCloudClient::insertEndOfMessageBundleMarker()
    {
        _brainCloudComms->insertEndOfMessageBundleMarker();
    }

    ////////////////////////////////////////////////////
    // Private Methods
    ////////////////////////////////////////////////////
    void BrainCloudClient::setupOSLocaleData()
    {
        Device::getLocale(&_timezoneOffset, &_languageCode, &_countryCode);
    }
}  // end namespace
<commit_msg>Updated version<commit_after>// BrainCloudClient.cpp
// BrainCloudLib
// Copyright 2016 bitHeads, Inc. All Rights Reserved.

#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

#include "braincloud/BrainCloudClient.h"

#include "braincloud/internal/Device.h"
#include "braincloud/internal/JsonUtil.h"
#include "braincloud/internal/URLRequestMethod.h"

namespace BrainCloud
{
    // Define all static member variables.
    bool BrainCloudClient::EnableSingletonMode = false;
    const char * BrainCloudClient::SingletonUseErrorMessage =
            "Singleton usage is disabled. If called by mistake, use your own variable that holds an instance of the bcWrapper/bcClient.";

    BrainCloudClient * BrainCloudClient::_instance = NULL;
    std::string BrainCloudClient::s_brainCloudClientVersion = "4.4.1";
    const char* BC_SERVER_URL = "https://sharedprod.braincloudservers.com/dispatcherv2";

    /**
     * Constructor
     */
    BrainCloudClient::BrainCloudClient() :
        _brainCloudComms(IBrainCloudComms::create(this)),
        _rttComms(new RTTComms(this)),
        _asyncMatchService(new BrainCloudAsyncMatch(this)),
        _authenticationService(new BrainCloudAuthentication(this)),
        _chatService(new BrainCloudChat(this)),
        _dataStreamService(new BrainCloudDataStream(this)),
        _entityService(new BrainCloudEntity(this)),
        _eventService(new BrainCloudEvent(this)),
        _fileService(new BrainCloudFile(this)),
        _friendService(new BrainCloudFriend(this)),
        _gamificationService(new BrainCloudGamification(this)),
        _globalAppService(new BrainCloudGlobalApp(this)),
        _globalEntityService(new BrainCloudGlobalEntity(this)),
        _globalStatisticsService(new BrainCloudGlobalStatistics(this)),
        _groupService(new BrainCloudGroup(this)),
        _identityService(new BrainCloudIdentity(this)),
        _lobbyService(new BrainCloudLobby(this)),
        _mailService(new BrainCloudMail(this)),
        _matchmakingService(new BrainCloudMatchmaking(this)),
        _messagingService(new BrainCloudMessaging(this)),
        _oneWayMatchService(new BrainCloudOneWayMatch(this)),
        _playbackStreamService(new BrainCloudPlaybackStream(this)),
        _playerStateService(new BrainCloudPlayerState(this)),
        _playerStatisticsService(new BrainCloudPlayerStatistics(this)),
        _playerStatisticsEventService(new BrainCloudPlayerStatisticsEvent(this)),
        _presenceService(new BrainCloudPresence(this)),
        _productService(new BrainCloudProduct(this)),
        _virtualCurrencyService(new BrainCloudVirtualCurrency(this)),
        _appStoreService(new BrainCloudAppStore(this)),
        _profanityService(new BrainCloudProfanity(this)),
        _pushNotificationService(new BrainCloudPushNotification(this)),
        _redemptionCodeService(new BrainCloudRedemptionCode(this)),
        _s3HandlingService(new BrainCloudS3Handling(this)),
        _scriptService(new BrainCloudScript(this)),
        _socialLeaderboardService(new BrainCloudSocialLeaderboard(this)),
        _steamService(new BrainCloudSteam(this)),
        _timeService(new BrainCloudTime(this)),
        _tournamentService(new BrainCloudTournament(this)),
        _customEntityService(new BrainCloudCustomEntity(this)),
        _itemCatalogService(new BrainCloudItemCatalog(this)),
        _userItemsService(new BrainCloudUserItems(this)),
        _releasePlatform(""),
        _appVersion(""),
        _timezoneOffset(0.0)
    {
        //needed this here otherwise out of scope compiler error
        _rttService = new BrainCloudRTT(_rttComms, this);
    }

    BrainCloudClient::~BrainCloudClient()
    {
        delete _rttService;
        delete _tournamentService;
        delete _customEntityService;
        delete _itemCatalogService;
        delete _timeService;
        delete _steamService;
        delete _socialLeaderboardService;
        delete _scriptService;
        delete _s3HandlingService;
        delete _redemptionCodeService;
        delete _pushNotificationService;
        delete _profanityService;
        delete _appStoreService;
        delete _virtualCurrencyService;
        delete _productService;
        delete _presenceService;
        delete _playerStatisticsEventService;
        delete _playerStatisticsService;
        delete _playerStateService;
        delete _playbackStreamService;
        delete _oneWayMatchService;
        delete _messagingService;
        delete _matchmakingService;
        delete _mailService;
        delete _lobbyService;
        delete _identityService;
        delete _groupService;
        delete _globalStatisticsService;
        delete _globalEntityService;
        delete _globalAppService;
        delete _gamificationService;
        delete _friendService;
        delete _fileService;
        delete _eventService;
        delete _entityService;
        delete _dataStreamService;
        delete _chatService;
        delete _authenticationService;
        delete _asyncMatchService;
        delete _rttComms;
        delete _brainCloudComms;
    }

    ////////////////////////////////////////////////////
    // Public Methods
    ////////////////////////////////////////////////////

    const char * BrainCloudClient::getSessionId() const {
        return(_brainCloudComms->getSessionId().c_str());
    }

    const char * BrainCloudClient::getRttConnectionId() const{
        return(_rttComms->getConnectionId().c_str());
    }

    void BrainCloudClient::initializeComms(const char * in_serverURL, const char * in_appId, const std::map<std::string, std::string>& in_secretMap)
    {
        if (_brainCloudComms)
        {
            // automatically upgrade any older clients using "dispatcher" url
            // to "dispatcherv2" endpoint. Comms supports this now and otherwise
            // the change is transparent to the client.
            const char * urlToUse = in_serverURL;
            std::string url = in_serverURL;
            if (url.find("dispatcherv2") == std::string::npos)
            {
                size_t index = url.find("dispatcher");
                if (index != std::string::npos)
                {
                    url = url.substr(0, index);
                    url += "dispatcherv2";
                    urlToUse = url.c_str();
                }
            }
            _brainCloudComms->initializeWithApps(urlToUse, in_appId, in_secretMap);
        }

        if (_rttComms)
        {
            _rttComms->initialize();
        }
    }

    void BrainCloudClient::initialize(const char * in_serverURL, const char * in_secretKey, const char * in_appId, const char * in_appVersion)
    {
        std::string error = "";
        if (in_serverURL == NULL || strlen(in_serverURL) <= 0)
            error = "serverURL was null or empty";
        else if (in_secretKey == NULL || strlen(in_secretKey) <= 0)
            error = "secretKey was null or empty";
        else if (in_appId == NULL || strlen(in_appId) <= 0)
            error = "appId was null or empty";
        else if (in_appVersion == NULL || strlen(in_appVersion) <= 0)
            error = "appVersion was null or empty";

        if (error.length() > 0)
        {
            std::cout << "ERROR | Failed to initialize brainCloud - " << error;
            return;
        }

        std::map<std::string, std::string> secretMap;
        secretMap[in_appId] = in_secretKey;

        initializeComms(in_serverURL, in_appId, secretMap);
        setupOSLocaleData();

        _releasePlatform = Device::getPlatformName();
        _appVersion = in_appVersion;
    }

    void BrainCloudClient::initialize(const char * in_secretKey, const char * in_appId, const char * in_appVersion)
    {
        initialize(BC_SERVER_URL, in_secretKey, in_appId, in_appVersion);
    }

    void BrainCloudClient::initializeWithApps(const char * in_serverURL, const char * in_defaultAppId, const std::map<std::string, std::string>& in_secretMap, const char * in_appVersion)
    {
        std::string error = "";
        if (in_serverURL == NULL || strlen(in_serverURL) <= 0)
            error = "serverURL was null or empty";
        else if (in_defaultAppId == NULL || strlen(in_defaultAppId) <= 0)
            error = "appId was null or empty";
        else if (in_appVersion == NULL || strlen(in_appVersion) <= 0)
            error = "appVersion was null or empty";
        else if (in_secretMap.find(in_defaultAppId) == in_secretMap.end())
            error = "not secretKey match for appid";

        if (error.length() > 0)
        {
            std::cout << "ERROR | Failed to initialize brainCloud - " << error;
            return;
        }

        initializeComms(in_serverURL, in_defaultAppId, in_secretMap);
        setupOSLocaleData();

        _releasePlatform = Device::getPlatformName();
        _appVersion = in_appVersion;
    }

    void BrainCloudClient::initializeWithApps(const char* in_defaultAppId, const std::map<std::string, std::string>& in_secretMap, const char* in_appVersion)
    {
        initializeWithApps(BC_SERVER_URL, in_defaultAppId, in_secretMap, in_appVersion);
    }

    void BrainCloudClient::initializeIdentity(const char * in_profileId, const char * in_anonymousId)
    {
        _authenticationService->initialize(in_profileId, in_anonymousId);
    }

    void BrainCloudClient::runCallbacks()
    {
        _brainCloudComms->runCallbacks();
        _lobbyService->runPingCallbacks();
        _rttComms->runCallbacks();
    }

    void BrainCloudClient::registerEventCallback(IEventCallback *in_eventCallback)
    {
        _brainCloudComms->registerEventCallback(in_eventCallback);
    }

    void BrainCloudClient::deregisterEventCallback()
    {
        _brainCloudComms->deregisterEventCallback();
    }

    void BrainCloudClient::registerRewardCallback(IRewardCallback *in_rewardCallback)
    {
        _brainCloudComms->registerRewardCallback(in_rewardCallback);
    }

    void BrainCloudClient::deregisterRewardCallback()
    {
        _brainCloudComms->deregisterRewardCallback();
    }

    void BrainCloudClient::registerFileUploadCallback(IFileUploadCallback * in_fileUploadCallback)
    {
        _brainCloudComms->registerFileUploadCallback(in_fileUploadCallback);
    }

    void BrainCloudClient::deregisterFileUploadCallback()
    {
        _brainCloudComms->deregisterFileUploadCallback();
    }

    void BrainCloudClient::registerGlobalErrorCallback(IGlobalErrorCallback * in_globalErrorCallback)
    {
        _brainCloudComms->registerGlobalErrorCallback(in_globalErrorCallback);
    }

    void BrainCloudClient::deregisterGlobalErrorCallback()
    {
        _brainCloudComms->deregisterGlobalErrorCallback();
    }

    void BrainCloudClient::registerNetworkErrorCallback(INetworkErrorCallback * in_networkErrorCallback)
    {
        _brainCloudComms->registerNetworkErrorCallback(in_networkErrorCallback);
    }

    void BrainCloudClient::deregisterNetworkErrorCallback()
    {
        _brainCloudComms->deregisterNetworkErrorCallback();
    }

    void BrainCloudClient::enableLogging(bool shouldEnable)
    {
        _brainCloudComms->enableLogging(shouldEnable);
        _lobbyService->enableLogging(shouldEnable);
        _rttComms->enableLogging(shouldEnable);
    }

    /**
     * Heart beat to keep session(s) current, and retrieve any pending events...
     */
    void BrainCloudClient::heartbeat()
    {
        _brainCloudComms->sendHeartbeat();
    }

    void BrainCloudClient::sendRequest(ServerCall * in_serviceMessage)
    {
        _brainCloudComms->addToQueue(in_serviceMessage);
    }

    void BrainCloudClient::resetCommunication()
    {
        _rttComms->resetCommunication();
        _brainCloudComms->resetCommunication();
        _brainCloudComms->setSessionId("");
        _authenticationService->setProfileId("");
    }

    void BrainCloudClient::shutdown()
    {
        _rttComms->shutdown();
        _brainCloudComms->shutdown();
        _brainCloudComms->setSessionId("");
        _authenticationService->setProfileId("");
    }

    bool BrainCloudClient::isAuthenticated()
    {
        return _brainCloudComms->isAuthenticated();
    }

    bool BrainCloudClient::isInitialized()
    {
        return _brainCloudComms->isInitialized() && _rttComms->isInitialized();
    }

    void BrainCloudClient::setImmediateRetryOnError(bool value)
    {
        _brainCloudComms->setImmediateRetryOnError(value);
    }

    /**
     * Retrieve the pointer to the singleton BrainCloudClient instance.
     */
    BrainCloudClient * BrainCloudClient::getInstance()
    {
        if(EnableSingletonMode == false) {
            throw std::invalid_argument(SingletonUseErrorMessage);
        }

        if (_instance == NULL) {
            _instance = new BrainCloudClient();
        }
        return _instance;
    }

    void BrainCloudClient::setHeartbeatInterval(int in_intervalInMilliseconds) {
        _brainCloudComms->setHeartbeatInterval(in_intervalInMilliseconds);
    }

    const std::vector<int> & BrainCloudClient::getPacketTimeouts()
    {
        return _brainCloudComms->getPacketTimeouts();
    }

    void BrainCloudClient::setPacketTimeouts(const std::vector<int> & in_packetTimeouts)
    {
        _brainCloudComms->setPacketTimeouts(in_packetTimeouts);
    }

    void BrainCloudClient::setPacketTimeoutsToDefault()
    {
        _brainCloudComms->setPacketTimeoutsToDefault();
    }

    void BrainCloudClient::setAuthenticationPacketTimeout(int in_timeoutSecs)
    {
        _brainCloudComms->setAuthenticationPacketTimeout(in_timeoutSecs);
    }

    int BrainCloudClient::getAuthenticationPacketTimeout()
    {
        return _brainCloudComms->getAuthenticationPacketTimeout();
    }

    void BrainCloudClient::setOldStyleStatusMessageErrorCallback(bool in_enabled)
    {
        _brainCloudComms->setOldStyleStatusMessageErrorCallback(in_enabled);
    }

    void BrainCloudClient::setErrorCallbackOn202Status(bool in_isError)
    {
        _brainCloudComms->setErrorCallbackOn202Status(in_isError);
    }

    int BrainCloudClient::getUploadLowTransferRateTimeout()
    {
        return _brainCloudComms->getUploadLowTransferRateTimeout();
    }

    void BrainCloudClient::setUploadLowTransferRateTimeout(int in_timeoutSecs)
    {
        _brainCloudComms->setUploadLowTransferRateTimeout(in_timeoutSecs);
    }

    int BrainCloudClient::getUploadLowTransferRateThreshold()
    {
        return _brainCloudComms->getUploadLowTransferRateThreshold();
    }

    void BrainCloudClient::setUploadLowTransferRateThreshold(int in_bytesPerSec)
    {
        _brainCloudComms->setUploadLowTransferRateThreshold(in_bytesPerSec);
    }

    void BrainCloudClient::enableNetworkErrorMessageCaching(bool in_enabled)
    {
        _brainCloudComms->enableNetworkErrorMessageCaching(in_enabled);
    }

    void BrainCloudClient::retryCachedMessages()
    {
        _brainCloudComms->retryCachedMessages();
    }

    void BrainCloudClient::flushCachedMessages(bool in_sendApiErrorCallbacks)
    {
        _brainCloudComms->flushCachedMessages(in_sendApiErrorCallbacks);
    }

    void BrainCloudClient::insertEndOfMessageBundleMarker()
    {
        _brainCloudComms->insertEndOfMessageBundleMarker();
    }

    ////////////////////////////////////////////////////
    // Private Methods
    ////////////////////////////////////////////////////
    void BrainCloudClient::setupOSLocaleData()
    {
        Device::getLocale(&_timezoneOffset, &_languageCode, &_countryCode);
    }
}  // end namespace
<|endoftext|>


<commit_before>/**	@file	CollisionManager.cpp
	@author	Philip Abbet

	Implementation of the class 'Athena::Physics::CollisionManager'
*/

#include <Athena-Physics/CollisionManager.h>
#include <Athena-Physics/Body.h>
#include <Athena-Physics/GhostObject.h>
#include <Athena-Physics/Conversions.h>

using namespace Athena;
using namespace Athena::Physics;
using namespace Athena::Entities;
using namespace Athena::Signals;
using namespace std;

/********************************** STATIC ATTRIBUTES **********************************/

CollisionManager CollisionManager::DefaultManager;
CollisionManager* CollisionManager::_CurrentManager = 0;

/***************************** CONSTRUCTION / DESTRUCTION ******************************/

CollisionManager::CollisionManager()
: m_pFilter(0)
{
    unsigned int offset = 0;
    for (unsigned int i = 0; i < NB_GROUPS; ++i)
    {
        m_indexedPairs[i] = &m_collisionPairs[offset];
        offset += NB_GROUPS - i;
    }
}

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

CollisionManager::~CollisionManager()
{
}

/*********************** IMPLEMENTATION OF btOverlapFilterCallback *********************/

bool CollisionManager::needBroadphaseCollision(btBroadphaseProxy* pProxy1,
                                               btBroadphaseProxy* pProxy2) const
{
    tCollisionGroup group1 = getGroupOfCollisionObject((btCollisionObject*) pProxy1->m_clientObject);
    tCollisionGroup group2 = getGroupOfCollisionObject((btCollisionObject*) pProxy2->m_clientObject);

    if ((group1 == -1) || (group2 == -1))
        return true;

    tPairState state;

    if (group1 <= group2)
        state = m_indexedPairs[group1][group2];
    else
        state = m_indexedPairs[group2][group1];

    return (state != PAIR_DISABLED);
}

/************************************* METHODS ****************************************/

void CollisionManager::enableCollision(tCollisionGroup group1, tCollisionGroup group2,
                                       bool bEnableFilter)
{
    tPairState* pState;

    if (group1 <= group2)
        pState = &m_indexedPairs[group1][group2];
    else
        pState = &m_indexedPairs[group2][group1];

    *pState = (bEnableFilter ? PAIR_ENABLED_WITH_FILTER : PAIR_ENABLED);
}

/********************************* STATIC METHODS **************************************/

void CollisionManager::customNearCallback(btBroadphasePair& collisionPair,
                                          btCollisionDispatcher& dispatcher,
                                          const btDispatcherInfo& dispatchInfo)
{
    if (CollisionManager::_CurrentManager)
    {
        tCollisionGroup group1, group2;

        PhysicalComponent* pComponent1 = getComponentOfCollisionObject((btCollisionObject*) collisionPair.m_pProxy0->m_clientObject, group1);
        PhysicalComponent* pComponent2 = getComponentOfCollisionObject((btCollisionObject*) collisionPair.m_pProxy1->m_clientObject, group2);

        if ((group1 == -1) || (group2 == -1))
        {
            dispatcher.defaultNearCallback(collisionPair, dispatcher, dispatchInfo);
            return;
        }

        tPairState state;

        if (group1 <= group2)
            state = CollisionManager::_CurrentManager->m_indexedPairs[group1][group2];
        else
            state = CollisionManager::_CurrentManager->m_indexedPairs[group2][group1];

        assert(state != PAIR_DISABLED);

        bool bContinue = (state == PAIR_ENABLED) || !CollisionManager::_CurrentManager->m_pFilter ||
                         CollisionManager::_CurrentManager->m_pFilter->needsCollision(pComponent1, pComponent2);

        if (bContinue)
            dispatcher.defaultNearCallback(collisionPair, dispatcher, dispatchInfo);
    }
}

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

tCollisionGroup CollisionManager::getGroupOfCollisionObject(btCollisionObject* pObject)
{
    btRigidBody* pRigidBody = btRigidBody::upcast(pObject);
    if (pRigidBody)
        return static_cast<Body*>(pRigidBody->getUserPointer())->getCollisionGroup();

    btGhostObject* pGhostObject = btGhostObject::upcast(pObject);
    if (pGhostObject)
        return static_cast<GhostObject*>(pGhostObject->getUserPointer())->getCollisionGroup();

    return -1;
}

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

PhysicalComponent* CollisionManager::getComponentOfCollisionObject(btCollisionObject* pObject,
                                                                   tCollisionGroup &group)
{
    btRigidBody* pRigidBody = btRigidBody::upcast(pObject);
    if (pRigidBody)
    {
        Body* pBody = static_cast<Body*>(pRigidBody->getUserPointer());
        group = pBody->getCollisionGroup();
        return pBody;
    }

    btGhostObject* pGhostObject = btGhostObject::upcast(pObject);
    if (pGhostObject)
    {
        GhostObject* pGhost = static_cast<GhostObject*>(pGhostObject->getUserPointer());
        group = pGhost->getCollisionGroup();
        return pGhost;
    }

    group = -1;
    return 0;
}
<commit_msg>Bugfix: incorrect indexing in the internal collision pairs array<commit_after>/**	@file	CollisionManager.cpp
	@author	Philip Abbet

	Implementation of the class 'Athena::Physics::CollisionManager'
*/

#include <Athena-Physics/CollisionManager.h>
#include <Athena-Physics/Body.h>
#include <Athena-Physics/GhostObject.h>
#include <Athena-Physics/Conversions.h>

using namespace Athena;
using namespace Athena::Physics;
using namespace Athena::Entities;
using namespace Athena::Signals;
using namespace std;

/********************************** STATIC ATTRIBUTES **********************************/

CollisionManager CollisionManager::DefaultManager;
CollisionManager* CollisionManager::_CurrentManager = 0;

/***************************** CONSTRUCTION / DESTRUCTION ******************************/

CollisionManager::CollisionManager()
: m_pFilter(0)
{
    unsigned int offset = 0;
    for (unsigned int i = 0; i < NB_GROUPS; ++i)
    {
        m_indexedPairs[i] = &m_collisionPairs[offset];
        offset += NB_GROUPS - i;
    }
}

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

CollisionManager::~CollisionManager()
{
}

/*********************** IMPLEMENTATION OF btOverlapFilterCallback *********************/

bool CollisionManager::needBroadphaseCollision(btBroadphaseProxy* pProxy1,
                                               btBroadphaseProxy* pProxy2) const
{
    tCollisionGroup group1 = getGroupOfCollisionObject((btCollisionObject*) pProxy1->m_clientObject);
    tCollisionGroup group2 = getGroupOfCollisionObject((btCollisionObject*) pProxy2->m_clientObject);

    if ((group1 == -1) || (group2 == -1))
        return true;

    tPairState state;

    if (group1 <= group2)
        state = m_indexedPairs[1 << group1][1 << group2];
    else
        state = m_indexedPairs[1 << group2][1 << group1];

    return (state != PAIR_DISABLED);
}

/************************************* METHODS ****************************************/

void CollisionManager::enableCollision(tCollisionGroup group1, tCollisionGroup group2,
                                       bool bEnableFilter)
{
    tPairState* pState;

    if (group1 <= group2)
        pState = &m_indexedPairs[1 << group1][1 << group2];
    else
        pState = &m_indexedPairs[1 << group2][1 << group1];

    *pState = (bEnableFilter ? PAIR_ENABLED_WITH_FILTER : PAIR_ENABLED);
}

/********************************* STATIC METHODS **************************************/

void CollisionManager::customNearCallback(btBroadphasePair& collisionPair,
                                          btCollisionDispatcher& dispatcher,
                                          const btDispatcherInfo& dispatchInfo)
{
    if (CollisionManager::_CurrentManager)
    {
        tCollisionGroup group1, group2;

        PhysicalComponent* pComponent1 = getComponentOfCollisionObject((btCollisionObject*) collisionPair.m_pProxy0->m_clientObject, group1);
        PhysicalComponent* pComponent2 = getComponentOfCollisionObject((btCollisionObject*) collisionPair.m_pProxy1->m_clientObject, group2);

        if ((group1 == -1) || (group2 == -1))
        {
            dispatcher.defaultNearCallback(collisionPair, dispatcher, dispatchInfo);
            return;
        }

        tPairState state;

        if (group1 <= group2)
            state = CollisionManager::_CurrentManager->m_indexedPairs[1 << group1][1 << group2];
        else
            state = CollisionManager::_CurrentManager->m_indexedPairs[1 << group2][1 << group1];

        assert(state != PAIR_DISABLED);

        bool bContinue = (state == PAIR_ENABLED) || !CollisionManager::_CurrentManager->m_pFilter ||
                         CollisionManager::_CurrentManager->m_pFilter->needsCollision(pComponent1, pComponent2);

        if (bContinue)
            dispatcher.defaultNearCallback(collisionPair, dispatcher, dispatchInfo);
    }
}

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

tCollisionGroup CollisionManager::getGroupOfCollisionObject(btCollisionObject* pObject)
{
    btRigidBody* pRigidBody = btRigidBody::upcast(pObject);
    if (pRigidBody)
        return static_cast<Body*>(pRigidBody->getUserPointer())->getCollisionGroup();

    btGhostObject* pGhostObject = btGhostObject::upcast(pObject);
    if (pGhostObject)
        return static_cast<GhostObject*>(pGhostObject->getUserPointer())->getCollisionGroup();

    return -1;
}

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

PhysicalComponent* CollisionManager::getComponentOfCollisionObject(btCollisionObject* pObject,
                                                                   tCollisionGroup &group)
{
    btRigidBody* pRigidBody = btRigidBody::upcast(pObject);
    if (pRigidBody)
    {
        Body* pBody = static_cast<Body*>(pRigidBody->getUserPointer());
        group = pBody->getCollisionGroup();
        return pBody;
    }

    btGhostObject* pGhostObject = btGhostObject::upcast(pObject);
    if (pGhostObject)
    {
        GhostObject* pGhost = static_cast<GhostObject*>(pGhostObject->getUserPointer());
        group = pGhost->getCollisionGroup();
        return pGhost;
    }

    group = -1;
    return 0;
}
<|endoftext|>


<commit_before>/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 *
 *  libtest
 *
 *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
 *
 *  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 3 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <libtest/common.h>

#include <curl/curl.h>

namespace libtest {
namespace http {

#define YATL_USERAGENT "YATL/1.0"

extern "C" size_t
  http_get_result_callback(void *ptr, size_t size, size_t nmemb, void *data)
  {
    size_t body_size= size * nmemb;

    vchar_t *_body= (vchar_t*)data;

    _body->get().resize(size * nmemb);
    memcpy(&(_body)[0], ptr, _body->get().size());

    return _body->get().size();
  }

bool GET::execute()
{
  if (HAVE_LIBCURL)
  {
    CURL *curl= curl_easy_init();;

    curl_easy_setopt(curl, CURLOPT_URL, url().c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_result_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&_body);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, YATL_USERAGENT);

    CURLcode retref= curl_easy_perform(curl);

    curl_easy_cleanup(curl);

    return retref == CURLE_OK;
  }

  return false;
}

bool POST::execute()
{
  if (HAVE_LIBCURL)
  {
    CURL *curl= curl_easy_init();;
    curl_easy_cleanup(curl);
  }
  return false;
}

} // namespace http
} // namespace libtest
<commit_msg>Fix curl reference via include<commit_after>/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 *
 *  libtest
 *
 *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
 *
 *  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 3 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <libtest/common.h>

#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif

namespace libtest {
namespace http {

#define YATL_USERAGENT "YATL/1.0"

extern "C" size_t
  http_get_result_callback(void *ptr, size_t size, size_t nmemb, void *data)
  {
    size_t body_size= size * nmemb;

    vchar_t *_body= (vchar_t*)data;

    _body->get().resize(size * nmemb);
    memcpy(&(_body)[0], ptr, _body->get().size());

    return _body->get().size();
  }

bool GET::execute()
{
  if (HAVE_LIBCURL)
  {
    CURL *curl= curl_easy_init();;

    curl_easy_setopt(curl, CURLOPT_URL, url().c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_result_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&_body);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, YATL_USERAGENT);

    CURLcode retref= curl_easy_perform(curl);

    curl_easy_cleanup(curl);

    return retref == CURLE_OK;
  }

  return false;
}

bool POST::execute()
{
  if (HAVE_LIBCURL)
  {
    CURL *curl= curl_easy_init();;
    curl_easy_cleanup(curl);
  }
  return false;
}

} // namespace http
} // namespace libtest
<|endoftext|>