<commit_before>#include <QCoreApplication>
#include <QDirIterator>
#include <QTimer>
#include <QtMath>
#include "afisynclogger.h"
#include "fileutils.h"
#include "global.h"
#include "installer.h"
#include "mod.h"
#include "modadapter.h"
#include "repository.h"
#include "settingsmodel.h"

const unsigned Mod::COMPLETION_WAIT_DURATION = 0;

Mod::Mod(const QString& name, const QString& key, ISync* sync):
    SyncItem(name),
    key_(key),
    sync_(sync),
    updateTimer_(nullptr),
    waitTime_(0),
    totalWanted_(-1),
    totalWantedDone_(-1)
{
    LOG << "key = " << key;
    setStatus(SyncStatus::STARTING);
    //Enables non lagging UI
    moveToThread(Global::workerThread);
    qRegisterMetaType<QVector<int>>("QVector<int>"); //TODO: Remove, QML ?
    QMetaObject::invokeMethod(this, &Mod::threadConstructor, Qt::QueuedConnection);
}

Mod::~Mod()
{
    LOG << "name = " << name() << " Thread: " << QThread::currentThread()->objectName();
}

void Mod::threadConstructor()
{
    updateTicked();
    updateTimer_ = new QTimer(this);
    updateTimer_->setTimerType(Qt::VeryCoarseTimer);
    updateTimer_->setInterval(1000);
    connect(updateTimer_, &QTimer::timeout, this, &Mod::update);
    connect(dynamic_cast<QObject*>(sync_), SIGNAL(initCompleted()), this, SLOT(repositoryChanged()));
}

QString Mod::path() const
{
    return SettingsModel::modDownloadPath() + "/" + name();
}

void Mod::init()
{
    updateTicked();
    repositoryChanged();
    update();
    LOG << "name = " << name() << " key = " << key() << " Completed";
}

void Mod::update()
{
    updateStatus();
    updateProgress();
}

//Removes mod which has same name but different key.
void Mod::removeConflicting() const
{
    for (const QString& syncKey : sync_->folderKeys())
    {
        QString syncPath = sync_->folderPath(syncKey);

        if (path().toLower() == syncPath.toLower() && syncKey != key_)
        {
            //Downloading into same folder but the key is different!
            LOG << "Removing conflicting (" << syncKey << ", " << syncPath << ") for (" << key_ << ", " << path() << ").";
            sync_->removeFolder(syncKey);
            return;
        }
    }
}

//Starts sync directory. If directory does not exist
//folder will be created. If path is incorrect
//folder will be re-created correctly.
//If mod is not in sync it will be added to it.
void Mod::start()
{
    LOG << "name = " << name();

    if (!sync_->folderExists(key_))
    {
        removeConflicting();
        //Add folder
        sync_->addFolder(key_, name());
    }
    //Sanity checks
    const QString error = sync_->folderError(key_);
    if (!error.isEmpty())
    {
        LOG << "name = " << name() << " Re-adding directory. error = " << error;
        //Disagreement between Sync and AFISync
        sync_->removeFolder(key_);
        sync_->addFolder(key_, name());
        setProcessCompletion(true);
    }
    //Do the actual starting
    sync_->setFolderPaused(key_, false);
    startUpdates();
}

void Mod::moveFiles()
{
    QMetaObject::invokeMethod(this, &Mod::moveFilesSlot, Qt::QueuedConnection);
}

void Mod::moveFilesSlot()
{
    deleteExtraFiles();
    if (sync_->folderExists(key_))
    {
        sync_->setFolderPath(key_, SettingsModel::modDownloadPath());
    }
}

void Mod::setProcessCompletion(const bool value)
{
    SettingsModel::setProcessed(name(), !value ? key_ : "");
    LOG << "Process (completion) set to " << value << " for " << name();
}

bool Mod::getProcessCompletion() const
{
    return SettingsModel::processed(name()) != key_;
}

qint64 Mod::totalWanted() const
{
    return totalWanted_;
}

qint64 Mod::totalWantedDone() const
{
    return totalWantedDone_;
}

void Mod::updateProgress()
{
    if (!active() || !sync_->folderExists(key_))
    {
        totalWanted_ =  -1;
        totalWantedDone_ = -1;
        return;
    }

    totalWanted_ = sync_->folderTotalWanted(key_);
    totalWantedDone_ = sync_->folderTotalWantedDone(key_);
}

bool Mod::stop()
{
    LOG << name();
    //TODO: Remove? Might be too defensive
    if (!sync_->folderExists(key_))
    {
        LOG_ERROR << "Folder" << name() << "does not exist.";
        return false;
    }

    LOG << "Stopping mod transfer. name = " << name();
    sync_->setFolderPaused(key_, true);
    stopUpdatesSlot();
    update();

    return true;
}

void Mod::deleteExtraFiles()
{
    LOG << "name = " << name();
    if (!ticked())
    {
        LOG << "Mod " << name()  << " is inactive, doing nothing.";
        return;
    }

    QSet<QString> localFiles;
    QSet<QString> remoteFiles = sync_->folderFilesUpper(key_);

    QDir dir(SettingsModel::modDownloadPath() + "/" + name());
    QDirIterator it(dir.absolutePath(), QDir::Files, QDirIterator::Subdirectories);
    while (it.hasNext())
    {
        localFiles.insert(it.next().toUpper());
    }
    //Fail safe if there is torrent without files.
    if (remoteFiles.size() == 0)
    {
        LOG_ERROR << "Not deleting extra files because torrent contains 0 files.";
        return; //Would delete everything otherwise
    }

    QSet<QString> extraFiles = localFiles - remoteFiles;
    for (const QString& path : extraFiles)
    {
        LOG << "Deleting extra file " << path << " from mod " << name();
        FileUtils::rmCi(path);
    }
    FileUtils::safeRemoveEmptyDirs(dir.absolutePath());
    LOG << "Completed name = " << name();
}

bool Mod::ticked()
{
    return ticked_;
}

void Mod::updateTicked()
{
    if (!optional() && !reposInactive())
    {
        ticked_ = true;
        return;
    }

    for (ModAdapter* adp : modAdapters())
    {
        if (adp->ticked())
        {
            ticked_ = true;
            return;
        }
    }
    ticked_ = false;
}

//If all repositories this mod is included in are disabled then stop the
//download.
void Mod::repositoryChanged()
{
    Q_ASSERT(QThread::currentThread() == Global::workerThread);

    if (!sync_->ready())
    {
        return;
    }
    if (reposInactive() || !ticked())
    {
        // No checking for paused state because torrent might have been
        // paused by auto management (queued for example).
        if (sync_->folderExists(key_))
        {
            LOG << "All repositories inactive or mod unchecked. Stopping " << name();
            stop();
        }
        return;
    }
    //At least one repo active and mod checked
    if (!sync_->folderExists(key_) || sync_->folderPaused(key_))
    {
        LOG << "Starting mod transfer. name = " << name();
        start();
    }
    updateTicked();
}

void Mod::removeModAdapter(ModAdapter* modAdapter)
{
    Q_ASSERT(QThread::currentThread() == Global::workerThread);

    adapters_.removeAll(modAdapter);
    if (adapters_.isEmpty())
    {
        deleteLater();
    }
}

void Mod::removeModAdapter(Repository* repository)
{
    QList<ModAdapter*> modAdapters = adapters_;
    for (ModAdapter* modAdapter : modAdapters)
    {
        if (modAdapter->repo() == repository)
        {
            delete modAdapter;
        }
    }
}

QSet<Repository*> Mod::repositories() const
{
    QSet<Repository*> retVal;
    for (ModAdapter* modAdapter : adapters_)
    {
        retVal.insert(modAdapter->repo());
    }
    return retVal;
}

QString Mod::key() const
{
    return key_;
}

void Mod::startUpdates()
{
    QMetaObject::invokeMethod(this, &Mod::startUpdatesSlot, Qt::QueuedConnection);
}

void Mod::startUpdatesSlot()
{
    if (sync_->ready())
    {
        updateTimer_->start();
    }
    else
    {
        connect(dynamic_cast<QObject*>(sync_), SIGNAL(initCompleted()), updateTimer_, SLOT(start()));
    }
}

//This should always be run in UI Thread
void Mod::stopUpdates()
{
    LOG << name();
    //Updates need to be stopped before object destruction, hence blocking.
    QMetaObject::invokeMethod(this, &Mod::stopUpdatesSlot, Qt::BlockingQueuedConnection);
}

void Mod::stopUpdatesSlot()
{
    updateTimer_->stop();
}

bool Mod::selected()
{
    for (ModAdapter* adp : modAdapters())
    {
        if (adp->selected())
        {
            return true;
        }
    }
    return false;
}

//Returns true only if all adapters are optional
bool Mod::optional()
{
    bool rVal = true;
    for (ModAdapter* adp : modAdapters())
    {
        rVal = rVal && adp->optional();
    }
    return rVal;
}

QList<ModAdapter*> Mod::modAdapters()
{
    adaptersMutex_.lock();
    QList<ModAdapter*> retVal = adapters_;
    adaptersMutex_.unlock();
    return retVal;
}

void Mod::appendModAdapter(ModAdapter* adapter)
{
    adaptersMutex_.lock();
    adapters_.append(adapter);
    int size = adapters_.size();
    adaptersMutex_.unlock();

    if (size == 1)
    {
        //First repository added -> initialize mod.
        if (sync_->ready())
        {
            LOG << "name = " << name() << " Calling init directly";
            QMetaObject::invokeMethod(this, &Mod::init, Qt::QueuedConnection);
        }
        else
        {
            connect(dynamic_cast<QObject*>(sync_), SIGNAL(initCompleted()), this, SLOT(init()));
            LOG << "name = " << name() << " initCompleted connection created";
        }
        return;
    }
}

void Mod::updateStatus()
{
    if (!ticked() || reposInactive())
    {
        setStatus(SyncStatus::INACTIVE);
    }
    else if (!sync_->folderExists(key_))
    {
        setStatus(SyncStatus::ERRORED);
    }
    else if (sync_->folderMovingFiles(key_))
    {
        setStatus(SyncStatus::MOVING_FILES);
    }
    else if (sync_->folderQueued(key_))
    {
        setStatus(SyncStatus::QUEUED);
    }
    else if (sync_->folderCheckingPatches(key_))
    {
        setStatus(SyncStatus::CHECKING_PATCHES);
    }
    else if (sync_->folderChecking(key_))
    {
        setStatus(SyncStatus::CHECKING);
    }
    else if (sync_->folderDownloadingPatches(key_))
    {
        setStatus(SyncStatus::DOWNLOADING_PATCHES);
    }
    else if (sync_->folderDownloading(key_))
    {
        if (statusStr() != SyncStatus::DOWNLOADING)
        {
            setStatus(SyncStatus::DOWNLOADING);
            //Heavy operation -> only set when entering downloading state.
            setProcessCompletion(true);
        }
    }
    //Wait for ready just in case
    else if (statusStr() == SyncStatus::WAITING)
    {
        ++waitTime_;
        if (waitTime_ > COMPLETION_WAIT_DURATION)
        {
            waitTime_ = 0;
            if (getProcessCompletion())
            {
                processCompletion();
                setProcessCompletion(false);
            }
            setStatus(SyncStatus::READY);
        }
    }
    else if (statusStr() == SyncStatus::READY || statusStr() == SyncStatus::READY_PAUSED) {}
    else if (sync_->folderReady(key_))
    {
        setStatus(SyncStatus::WAITING);
    }
    else
    {
        //New block for error initialization
        const QString error = sync_->folderError(key_);
        if (error != QString())
        {
            setStatus(SyncStatus::ERRORED + error);
        }
        else if (sync_->folderPaused(key_))
        {
            if (statusStr() == SyncStatus::READY)
            {
                setStatus(SyncStatus::READY_PAUSED);
            }
            else
            {
                setStatus(SyncStatus::PAUSED);
            }
        }
        else if (sync_->folderExtractingPatch(key_))
        {
            setStatus(SyncStatus::EXTRACTING_PATCH);
        }
        else if (sync_->folderPatching(key_))
        {
            setStatus(SyncStatus::PATCHING);
        }
        else if (sync_->folderNoPeers(key_))
        {
            setStatus(SyncStatus::NO_PEERS);
        }
        else
        {
            LOG << "ERROR: Unable to determine mod state. name = " << name();
            setStatus(SyncStatus::ERRORED);
        }
    }

}

void Mod::forceCheck()
{
    sync_->disableQueue(key_);
    check();
}

QString Mod::progressStr()
{
    if (!ticked() || statusStr() == SyncStatus::STARTING)
        return "???";

    return toProgressStr(totalWanted_, totalWantedDone_);
}

QString Mod::bytesToMegasCeilStr(const qint64 bytes)
{
    if (bytes == 0)
        return QString::number(0);

    return QString::number(1 + ((bytes - 1) / Constants::MEGA_DIVIDER));  // Ceil division
}

QString Mod::toProgressStr(const qint64 totalWanted, qint64 totalWantedDone)
{
    if (totalWanted < 0 || totalWantedDone < 0)
        return "???";

    // Do not ceil to 100 %
    if (totalWantedDone < totalWanted)
    {
        totalWantedDone = totalWantedDone > Constants::MEGA_DIVIDER ? totalWantedDone - Constants::MEGA_DIVIDER : 0;
    }
    return QString("%1 / %2").arg(bytesToMegasCeilStr(totalWantedDone)).arg(bytesToMegasCeilStr(totalWanted));
}

void Mod::processCompletion()
{
    deleteExtraFiles();
    Installer::install(this);
}

void Mod::check()
{
    sync_->checkFolder(key_);
    // Process completion when checking is done
    setProcessCompletion(true);
}

void Mod::checkboxClicked()
{
    QMetaObject::invokeMethod(this, &Mod::checkboxClickedSlot, Qt::QueuedConnection);
}

void Mod::checkboxClickedSlot()
{
    updateTicked();
    //Below cmd will start the download if repository is active.
    repositoryChanged();
}

bool Mod::reposInactive()
{
    for (Repository* repo : repositories())
    {
        if (repo->statusStr() != SyncStatus::INACTIVE)
        {
            return false;
        }
    }
    return true;
}
<commit_msg>Fixed erroring when adding a mod on fly<commit_after>#include <QCoreApplication>
#include <QDirIterator>
#include <QTimer>
#include <QtMath>
#include "afisynclogger.h"
#include "fileutils.h"
#include "global.h"
#include "installer.h"
#include "mod.h"
#include "modadapter.h"
#include "repository.h"
#include "settingsmodel.h"

const unsigned Mod::COMPLETION_WAIT_DURATION = 0;

Mod::Mod(const QString& name, const QString& key, ISync* sync):
    SyncItem(name),
    key_(key),
    sync_(sync),
    updateTimer_(nullptr),
    waitTime_(0),
    totalWanted_(-1),
    totalWantedDone_(-1)
{
    LOG << "key = " << key;
    setStatus(SyncStatus::STARTING);
    //Enables non lagging UI
    moveToThread(Global::workerThread);
    qRegisterMetaType<QVector<int>>("QVector<int>"); //TODO: Remove, QML ?
    QMetaObject::invokeMethod(this, &Mod::threadConstructor, Qt::QueuedConnection);
}

Mod::~Mod()
{
    LOG << "name = " << name() << " Thread: " << QThread::currentThread()->objectName();
}

void Mod::threadConstructor()
{
    updateTicked();
    updateTimer_ = new QTimer(this);
    updateTimer_->setTimerType(Qt::VeryCoarseTimer);
    updateTimer_->setInterval(1000);
    connect(updateTimer_, &QTimer::timeout, this, &Mod::update);
    connect(dynamic_cast<QObject*>(sync_), SIGNAL(initCompleted()), this, SLOT(repositoryChanged()));
}

QString Mod::path() const
{
    return SettingsModel::modDownloadPath() + "/" + name();
}

void Mod::init()
{
    updateTicked();
    repositoryChanged();
    update();
    LOG << "name = " << name() << " key = " << key() << " Completed";
}

void Mod::update()
{
    updateStatus();
    updateProgress();
}

//Removes mod which has same name but different key.
void Mod::removeConflicting() const
{
    for (const QString& syncKey : sync_->folderKeys())
    {
        QString syncPath = sync_->folderPath(syncKey);

        if (path().toLower() == syncPath.toLower() && syncKey != key_)
        {
            //Downloading into same folder but the key is different!
            LOG << "Removing conflicting (" << syncKey << ", " << syncPath << ") for (" << key_ << ", " << path() << ").";
            sync_->removeFolder(syncKey);
            return;
        }
    }
}

//Starts sync directory. If directory does not exist
//folder will be created. If path is incorrect
//folder will be re-created correctly.
//If mod is not in sync it will be added to it.
void Mod::start()
{
    LOG << "name = " << name();

    if (!sync_->folderExists(key_))
    {
        removeConflicting();
        //Add folder
        sync_->addFolder(key_, name());
    }
    //Sanity checks
    const QString error = sync_->folderError(key_);
    if (!error.isEmpty())
    {
        LOG << "name = " << name() << " Re-adding directory. error = " << error;
        //Disagreement between Sync and AFISync
        sync_->removeFolder(key_);
        sync_->addFolder(key_, name());
        setProcessCompletion(true);
    }
    //Do the actual starting
    sync_->setFolderPaused(key_, false);
    startUpdates();
}

void Mod::moveFiles()
{
    QMetaObject::invokeMethod(this, &Mod::moveFilesSlot, Qt::QueuedConnection);
}

void Mod::moveFilesSlot()
{
    deleteExtraFiles();
    if (sync_->folderExists(key_))
    {
        sync_->setFolderPath(key_, SettingsModel::modDownloadPath());
    }
}

void Mod::setProcessCompletion(const bool value)
{
    SettingsModel::setProcessed(name(), !value ? key_ : "");
    LOG << "Process (completion) set to " << value << " for " << name();
}

bool Mod::getProcessCompletion() const
{
    return SettingsModel::processed(name()) != key_;
}

qint64 Mod::totalWanted() const
{
    return totalWanted_;
}

qint64 Mod::totalWantedDone() const
{
    return totalWantedDone_;
}

void Mod::updateProgress()
{
    if (!active() || !sync_->folderExists(key_))
    {
        totalWanted_ =  -1;
        totalWantedDone_ = -1;
        return;
    }

    totalWanted_ = sync_->folderTotalWanted(key_);
    totalWantedDone_ = sync_->folderTotalWantedDone(key_);
}

bool Mod::stop()
{
    LOG << name();
    //TODO: Remove? Might be too defensive
    if (!sync_->folderExists(key_))
    {
        LOG_ERROR << "Folder" << name() << "does not exist.";
        return false;
    }

    LOG << "Stopping mod transfer. name = " << name();
    sync_->setFolderPaused(key_, true);
    stopUpdatesSlot();
    update();

    return true;
}

void Mod::deleteExtraFiles()
{
    LOG << "name = " << name();
    if (!ticked())
    {
        LOG << "Mod " << name()  << " is inactive, doing nothing.";
        return;
    }

    QSet<QString> localFiles;
    QSet<QString> remoteFiles = sync_->folderFilesUpper(key_);

    QDir dir(SettingsModel::modDownloadPath() + "/" + name());
    QDirIterator it(dir.absolutePath(), QDir::Files, QDirIterator::Subdirectories);
    while (it.hasNext())
    {
        localFiles.insert(it.next().toUpper());
    }
    //Fail safe if there is torrent without files.
    if (remoteFiles.size() == 0)
    {
        LOG_ERROR << "Not deleting extra files because torrent contains 0 files.";
        return; //Would delete everything otherwise
    }

    QSet<QString> extraFiles = localFiles - remoteFiles;
    for (const QString& path : extraFiles)
    {
        LOG << "Deleting extra file " << path << " from mod " << name();
        FileUtils::rmCi(path);
    }
    FileUtils::safeRemoveEmptyDirs(dir.absolutePath());
    LOG << "Completed name = " << name();
}

bool Mod::ticked()
{
    return ticked_;
}

void Mod::updateTicked()
{
    if (!optional() && !reposInactive())
    {
        ticked_ = true;
        return;
    }

    for (ModAdapter* adp : modAdapters())
    {
        if (adp->ticked())
        {
            ticked_ = true;
            return;
        }
    }
    ticked_ = false;
}

//If all repositories this mod is included in are disabled then stop the
//download.
void Mod::repositoryChanged()
{
    Q_ASSERT(QThread::currentThread() == Global::workerThread);

    if (!sync_->ready())
    {
        return;
    }
    if (reposInactive() || !ticked())
    {
        // No checking for paused state because torrent might have been
        // paused by auto management (queued for example).
        if (sync_->folderExists(key_))
        {
            LOG << "All repositories inactive or mod unchecked. Stopping " << name();
            stop();
        }
        return;
    }
    //At least one repo active and mod checked
    if (!sync_->folderExists(key_) || sync_->folderPaused(key_))
    {
        LOG << "Starting mod transfer. name = " << name();
        start();
    }
    updateTicked();
}

void Mod::removeModAdapter(ModAdapter* modAdapter)
{
    Q_ASSERT(QThread::currentThread() == Global::workerThread);

    adapters_.removeAll(modAdapter);
    if (adapters_.isEmpty())
    {
        deleteLater();
        return;
    }
    QMetaObject::invokeMethod(this, &Mod::repositoryChanged, Qt::QueuedConnection);
}

void Mod::removeModAdapter(Repository* repository)
{
    QList<ModAdapter*> modAdapters = adapters_;
    for (ModAdapter* modAdapter : modAdapters)
    {
        if (modAdapter->repo() == repository)
        {
            delete modAdapter;
        }
    }
}

QSet<Repository*> Mod::repositories() const
{
    QSet<Repository*> retVal;
    for (ModAdapter* modAdapter : adapters_)
    {
        retVal.insert(modAdapter->repo());
    }
    return retVal;
}

QString Mod::key() const
{
    return key_;
}

void Mod::startUpdates()
{
    QMetaObject::invokeMethod(this, &Mod::startUpdatesSlot, Qt::QueuedConnection);
}

void Mod::startUpdatesSlot()
{
    if (sync_->ready())
    {
        updateTimer_->start();
    }
    else
    {
        connect(dynamic_cast<QObject*>(sync_), SIGNAL(initCompleted()), updateTimer_, SLOT(start()));
    }
}

//This should always be run in UI Thread
void Mod::stopUpdates()
{
    LOG << name();
    //Updates need to be stopped before object destruction, hence blocking.
    QMetaObject::invokeMethod(this, &Mod::stopUpdatesSlot, Qt::BlockingQueuedConnection);
}

void Mod::stopUpdatesSlot()
{
    updateTimer_->stop();
}

bool Mod::selected()
{
    for (ModAdapter* adp : modAdapters())
    {
        if (adp->selected())
        {
            return true;
        }
    }
    return false;
}

//Returns true only if all adapters are optional
bool Mod::optional()
{
    bool rVal = true;
    for (ModAdapter* adp : modAdapters())
    {
        rVal = rVal && adp->optional();
    }
    return rVal;
}

QList<ModAdapter*> Mod::modAdapters()
{
    adaptersMutex_.lock();
    QList<ModAdapter*> retVal = adapters_;
    adaptersMutex_.unlock();
    return retVal;
}

void Mod::appendModAdapter(ModAdapter* adapter)
{
    adaptersMutex_.lock();
    adapters_.append(adapter);
    int size = adapters_.size();
    adaptersMutex_.unlock();

    if (size == 1)
    {
        //First repository added -> initialize mod.
        if (sync_->ready())
        {
            LOG << "name = " << name() << " Calling init directly";
            QMetaObject::invokeMethod(this, &Mod::init, Qt::QueuedConnection);
        }
        else
        {
            connect(dynamic_cast<QObject*>(sync_), SIGNAL(initCompleted()), this, SLOT(init()));
            LOG << "name = " << name() << " initCompleted connection created";
        }
        return;
    }
    QMetaObject::invokeMethod(this, &Mod::repositoryChanged, Qt::QueuedConnection);
}

void Mod::updateStatus()
{
    if (!ticked() || reposInactive())
    {
        setStatus(SyncStatus::INACTIVE);
    }
    else if (!sync_->folderExists(key_))
    {
        setStatus(SyncStatus::ERRORED);
    }
    else if (sync_->folderMovingFiles(key_))
    {
        setStatus(SyncStatus::MOVING_FILES);
    }
    else if (sync_->folderQueued(key_))
    {
        setStatus(SyncStatus::QUEUED);
    }
    else if (sync_->folderCheckingPatches(key_))
    {
        setStatus(SyncStatus::CHECKING_PATCHES);
    }
    else if (sync_->folderChecking(key_))
    {
        setStatus(SyncStatus::CHECKING);
    }
    else if (sync_->folderDownloadingPatches(key_))
    {
        setStatus(SyncStatus::DOWNLOADING_PATCHES);
    }
    else if (sync_->folderDownloading(key_))
    {
        if (statusStr() != SyncStatus::DOWNLOADING)
        {
            setStatus(SyncStatus::DOWNLOADING);
            //Heavy operation -> only set when entering downloading state.
            setProcessCompletion(true);
        }
    }
    //Wait for ready just in case
    else if (statusStr() == SyncStatus::WAITING)
    {
        ++waitTime_;
        if (waitTime_ > COMPLETION_WAIT_DURATION)
        {
            waitTime_ = 0;
            if (getProcessCompletion())
            {
                processCompletion();
                setProcessCompletion(false);
            }
            setStatus(SyncStatus::READY);
        }
    }
    else if (statusStr() == SyncStatus::READY || statusStr() == SyncStatus::READY_PAUSED) {}
    else if (sync_->folderReady(key_))
    {
        setStatus(SyncStatus::WAITING);
    }
    else
    {
        //New block for error initialization
        const QString error = sync_->folderError(key_);
        if (error != QString())
        {
            setStatus(SyncStatus::ERRORED + error);
        }
        else if (sync_->folderPaused(key_))
        {
            if (statusStr() == SyncStatus::READY)
            {
                setStatus(SyncStatus::READY_PAUSED);
            }
            else
            {
                setStatus(SyncStatus::PAUSED);
            }
        }
        else if (sync_->folderExtractingPatch(key_))
        {
            setStatus(SyncStatus::EXTRACTING_PATCH);
        }
        else if (sync_->folderPatching(key_))
        {
            setStatus(SyncStatus::PATCHING);
        }
        else if (sync_->folderNoPeers(key_))
        {
            setStatus(SyncStatus::NO_PEERS);
        }
        else
        {
            LOG << "ERROR: Unable to determine mod state. name = " << name();
            setStatus(SyncStatus::ERRORED);
        }
    }

}

void Mod::forceCheck()
{
    sync_->disableQueue(key_);
    check();
}

QString Mod::progressStr()
{
    if (!ticked() || statusStr() == SyncStatus::STARTING)
        return "???";

    return toProgressStr(totalWanted_, totalWantedDone_);
}

QString Mod::bytesToMegasCeilStr(const qint64 bytes)
{
    if (bytes == 0)
        return QString::number(0);

    return QString::number(1 + ((bytes - 1) / Constants::MEGA_DIVIDER));  // Ceil division
}

QString Mod::toProgressStr(const qint64 totalWanted, qint64 totalWantedDone)
{
    if (totalWanted < 0 || totalWantedDone < 0)
        return "???";

    // Do not ceil to 100 %
    if (totalWantedDone < totalWanted)
    {
        totalWantedDone = totalWantedDone > Constants::MEGA_DIVIDER ? totalWantedDone - Constants::MEGA_DIVIDER : 0;
    }
    return QString("%1 / %2").arg(bytesToMegasCeilStr(totalWantedDone)).arg(bytesToMegasCeilStr(totalWanted));
}

void Mod::processCompletion()
{
    deleteExtraFiles();
    Installer::install(this);
}

void Mod::check()
{
    sync_->checkFolder(key_);
    // Process completion when checking is done
    setProcessCompletion(true);
}

void Mod::checkboxClicked()
{
    QMetaObject::invokeMethod(this, &Mod::checkboxClickedSlot, Qt::QueuedConnection);
}

void Mod::checkboxClickedSlot()
{
    updateTicked();
    //Below cmd will start the download if repository is active.
    repositoryChanged();
}

bool Mod::reposInactive()
{
    for (Repository* repo : repositories())
    {
        if (repo->statusStr() != SyncStatus::INACTIVE)
        {
            return false;
        }
    }
    return true;
}
<|endoftext|>


<commit_before>#include "InputSystem.h"

InputSystem::InputSystem(void)
	: EntitySystem( SystemType::InputSystem, 1, ComponentType::Input )
{
}

InputSystem::~InputSystem(void)
{
}

void InputSystem::initialize()
{
	XInputFetcher* xif = new XInputFetcher();
	MessageLoopFetcher* milf = new MessageLoopFetcher();
	m_inputManager = new InputManager( milf, xif);

	InputControlFactory icf;
	Control* mbl = icf.create360controllerDigital( InputHelper::BTN_B );
	int mblIdx = m_inputManager->addControl(mbl);
	m_controlIdxs.push_back(mblIdx);
}

void InputSystem::processEntities( const vector<Entity*>& p_entities )
{
	m_inputManager->update();

	double pressness = m_inputManager->getControl(m_controlIdxs[0])->getStatus();
	bool pressed = false;
	if(pressness == 1.0f)
		pressed = true;

	if( p_entities.size() > 0 )
	{
		Input* inp =
			static_cast<Input*>(
			m_world->getComponentManager()->getComponent( p_entities[0],
			ComponentType::getTypeFor( ComponentType::Input ) ) );

		if( inp->m_bBtnPressed == true )
			int breakHere = 0;

		inp->m_bBtnPressed = true;
	}
}
<commit_msg>Fixef CRLF<commit_after>#include "InputSystem.h"

InputSystem::InputSystem(void)
	: EntitySystem( SystemType::InputSystem, 1, ComponentType::Input )
{
}

InputSystem::~InputSystem(void)
{
}

void InputSystem::initialize()
{
	XInputFetcher* xif = new XInputFetcher();
	MessageLoopFetcher* milf = new MessageLoopFetcher();
	m_inputManager = new InputManager( milf, xif);

	InputControlFactory icf;
	Control* mbl = icf.create360controllerDigital( InputHelper::BTN_B );
	int mblIdx = m_inputManager->addControl(mbl);
	m_controlIdxs.push_back(mblIdx);
}

void InputSystem::processEntities( const vector<Entity*>& p_entities )
{
	m_inputManager->update();

	double pressness = m_inputManager->getControl(m_controlIdxs[0])->getStatus();
	bool pressed = false;
	if(pressness == 1.0f)
		pressed = true;

	if( p_entities.size() > 0 )
	{
		Input* inp =
			static_cast<Input*>(
			m_world->getComponentManager()->getComponent( p_entities[0],
			ComponentType::getTypeFor( ComponentType::Input ) ) );

		if( inp->m_bBtnPressed == true )
			int breakHere = 0;

		inp->m_bBtnPressed = true;
	}
}
<|endoftext|>


<commit_before>/*
    This file is part of the kolab resource - the implementation of the
    Kolab storage format. See www.kolab.org for documentation on this.

    Copyright (c) 2004 Bo Thorsen <bo@sonofthor.dk>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "task.h"

#include <libkcal/todo.h>
#include <kdebug.h>

using namespace Kolab;

KCal::Todo* Task::xmlToTask( const QString& xml, const QString& tz )
{
  Task task( tz );
  task.load( xml );
  KCal::Todo* todo = new KCal::Todo();
  task.saveTo( todo );
  return todo;
}

QString Task::taskToXML( KCal::Todo* todo, const QString& tz )
{
  Task task( tz, todo );
  return task.saveXML();
}

Task::Task( const QString& tz, KCal::Todo* task )
  : Incidence( tz ), mPriority( 3 ), mPercentCompleted( 0 ),
    mStatus( KCal::Incidence::StatusNone ),
    mHasStartDate( false ), mHasDueDate( false ),
    mHasCompletedDate( false )
{
  if ( task )
    setFields( task );
}

Task::~Task()
{
}

void Task::setPriority( int priority )
{
  mPriority = priority;
}

int Task::priority() const
{
  return mPriority;
}

void Task::setPercentCompleted( int percent )
{
  mPercentCompleted = percent;
}

int Task::percentCompleted() const
{
  return mPercentCompleted;
}

void Task::setStatus( KCal::Incidence::Status status )
{
  mStatus = status;
}

KCal::Incidence::Status Task::status() const
{
  return mStatus;
}

void Task::setParent( const QString& parentUid )
{
  mParent = parentUid;
}

QString Task::parent() const
{
  return mParent;
}

void Task::setDueDate( const QDateTime& date )
{
  mDueDate = date;
  mHasDueDate = true;
}

QDateTime Task::dueDate() const
{
  return mDueDate;
}

void Task::setHasStartDate( bool v )
{
  mHasStartDate = v;
}

bool Task::hasStartDate() const
{
  return mHasStartDate;
}

bool Task::hasDueDate() const
{
  return mHasDueDate;
}

void Task::setCompletedDate( const QDateTime& date )
{
  mCompletedDate = date;
  mHasCompletedDate = true;
}

QDateTime Task::completedDate() const
{
  return mCompletedDate;
}

bool Task::hasCompletedDate() const
{
  return mHasCompletedDate;
}

bool Task::loadAttribute( QDomElement& element )
{
  QString tagName = element.tagName();

  if ( tagName == "priority" ) {
    bool ok;
    int priority = element.text().toInt( &ok );
    if ( !ok || priority < 0 || priority > 5 )
      priority = 3;
    setPriority( priority );
  } else if ( tagName == "completed" ) {
    bool ok;
    int percent = element.text().toInt( &ok );
    if ( !ok || percent < 0 || percent > 100 )
      percent = 0;
    setPercentCompleted( percent );
  } else if ( tagName == "status" ) {
    if ( element.text() == "in-progress" )
      setStatus( KCal::Incidence::StatusInProcess );
    else if ( element.text() == "completed" )
      setStatus( KCal::Incidence::StatusCompleted );
    else if ( element.text() == "waiting-on-someone-else" )
      setStatus( KCal::Incidence::StatusNeedsAction );
    else if ( element.text() == "deferred" )
      // Guessing a status here
      setStatus( KCal::Incidence::StatusCanceled );
    else
      // Default
      setStatus( KCal::Incidence::StatusNone );
  } else if ( tagName == "due-date" )
    setDueDate( stringToDateTime( element.text() ) );
  else if ( tagName == "parent" )
    setParent( element.text() );
  else if ( tagName == "x-completed-date" )
    setCompletedDate( stringToDateTime( element.text() ) );
  else if ( tagName == "start-date" ) {
    setHasStartDate( true );
    setStartDate( element.text() );
  } else
    return Incidence::loadAttribute( element );

  // We handled this
  return true;
}

bool Task::saveAttributes( QDomElement& element ) const
{
  // Save the base class elements
  Incidence::saveAttributes( element );

  writeString( element, "priority", QString::number( priority() ) );
  writeString( element, "completed", QString::number( percentCompleted() ) );

  switch( status() ) {
  case KCal::Incidence::StatusInProcess:
    writeString( element, "status", "in-progress" );
    break;
  case KCal::Incidence::StatusCompleted:
    writeString( element, "status", "completed" );
    break;
  case KCal::Incidence::StatusNeedsAction:
    writeString( element, "status", "waiting-on-someone-else" );
    break;
  case KCal::Incidence::StatusCanceled:
    writeString( element, "status", "deferred" );
    break;
  case KCal::Incidence::StatusNone:
    writeString( element, "status", "not-started" );
    break;
  case KCal::Incidence::StatusTentative:
  case KCal::Incidence::StatusConfirmed:
  case KCal::Incidence::StatusDraft:
  case KCal::Incidence::StatusFinal:
  case KCal::Incidence::StatusX:
    // All of these are saved as StatusNone.
    writeString( element, "status", "not-started" );
    break;
  }

  if ( hasDueDate() )
    writeString( element, "due-date", dateTimeToString( dueDate() ) );

  if ( !parent().isNull() )
    writeString( element, "parent", parent() );

  if ( hasCompletedDate() && percentCompleted() == 100)
    writeString( element, "x-completed-date", dateTimeToString( completedDate() ) );

  return true;
}

bool Task::loadXML( const QDomDocument& document )
{
  QDomElement top = document.documentElement();

  if ( top.tagName() != "task" ) {
    qWarning( "XML error: Top tag was %s instead of the expected task",
              top.tagName().ascii() );
    return false;
  }
  setHasStartDate( false ); // todo's don't necessarily have one

  for ( QDomNode n = top.firstChild(); !n.isNull(); n = n.nextSibling() ) {
    if ( n.isComment() )
      continue;
    if ( n.isElement() ) {
      QDomElement e = n.toElement();
      if ( !loadAttribute( e ) )
        // TODO: Unhandled tag - save for later storage
        kdDebug() << "Warning: Unhandled tag " << e.tagName() << endl;
    } else
      kdDebug() << "Node is not a comment or an element???" << endl;
  }

  return true;
}

QString Task::saveXML() const
{
  QDomDocument document = domTree();
  QDomElement element = document.createElement( "task" );
  element.setAttribute( "version", "1.0" );
  saveAttributes( element );
  if ( !hasStartDate() ) {
    // events and journals always have a start date, but tasks don't.
    // Remove the entry done by the inherited save above, because we
    // don't have one.
    QDomNodeList l = element.elementsByTagName( "start-date" );
    Q_ASSERT( l.count() == 1 );
    element.removeChild( l.item( 0 ) );
  }
  document.appendChild( element );
  return document.toString();
}

void Task::setFields( const KCal::Todo* task )
{
  Incidence::setFields( task );

  setPriority( task->priority() );
  setPercentCompleted( task->percentComplete() );
  setStatus( task->status() );
  setHasStartDate( task->hasStartDate() );

  if ( task->hasDueDate() )
    setDueDate( localToUTC( task->dtDue() ) );
  else
    mHasDueDate = false;
  if ( task->relatedTo() )
    setParent( task->relatedTo()->uid() );
  else
    setParent( QString::null );

  if ( task->hasCompletedDate() && task->percentComplete() == 100 )
    setCompletedDate( localToUTC( task->completed() ) );
  else
    mHasCompletedDate = false;
}

void Task::saveTo( KCal::Todo* task )
{
  Incidence::saveTo( task );

  task->setPriority( priority() );
  task->setPercentComplete( percentCompleted() );
  task->setStatus( status() );
  task->setHasStartDate( hasStartDate() );
  task->setHasDueDate( hasDueDate() );
  if ( hasDueDate() )
    task->setDtDue( utcToLocal( dueDate() ) );

  if ( !parent().isNull() )
    task->setRelatedToUid( parent() );

  if ( hasCompletedDate() && task->percentComplete() == 100 )
    task->setCompleted( utcToLocal( mCompletedDate ) );
}
<commit_msg>Priorities use a range 0-9, so don't reset if >5, but only if >9<commit_after>/*
    This file is part of the kolab resource - the implementation of the
    Kolab storage format. See www.kolab.org for documentation on this.

    Copyright (c) 2004 Bo Thorsen <bo@sonofthor.dk>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "task.h"

#include <libkcal/todo.h>
#include <kdebug.h>

using namespace Kolab;

KCal::Todo* Task::xmlToTask( const QString& xml, const QString& tz )
{
  Task task( tz );
  task.load( xml );
  KCal::Todo* todo = new KCal::Todo();
  task.saveTo( todo );
  return todo;
}

QString Task::taskToXML( KCal::Todo* todo, const QString& tz )
{
  Task task( tz, todo );
  return task.saveXML();
}

Task::Task( const QString& tz, KCal::Todo* task )
  : Incidence( tz ), mPriority( 5 ), mPercentCompleted( 0 ),
    mStatus( KCal::Incidence::StatusNone ),
    mHasStartDate( false ), mHasDueDate( false ),
    mHasCompletedDate( false )
{
  if ( task )
    setFields( task );
}

Task::~Task()
{
}

void Task::setPriority( int priority )
{
  mPriority = priority;
}

int Task::priority() const
{
  return mPriority;
}

void Task::setPercentCompleted( int percent )
{
  mPercentCompleted = percent;
}

int Task::percentCompleted() const
{
  return mPercentCompleted;
}

void Task::setStatus( KCal::Incidence::Status status )
{
  mStatus = status;
}

KCal::Incidence::Status Task::status() const
{
  return mStatus;
}

void Task::setParent( const QString& parentUid )
{
  mParent = parentUid;
}

QString Task::parent() const
{
  return mParent;
}

void Task::setDueDate( const QDateTime& date )
{
  mDueDate = date;
  mHasDueDate = true;
}

QDateTime Task::dueDate() const
{
  return mDueDate;
}

void Task::setHasStartDate( bool v )
{
  mHasStartDate = v;
}

bool Task::hasStartDate() const
{
  return mHasStartDate;
}

bool Task::hasDueDate() const
{
  return mHasDueDate;
}

void Task::setCompletedDate( const QDateTime& date )
{
  mCompletedDate = date;
  mHasCompletedDate = true;
}

QDateTime Task::completedDate() const
{
  return mCompletedDate;
}

bool Task::hasCompletedDate() const
{
  return mHasCompletedDate;
}

bool Task::loadAttribute( QDomElement& element )
{
  QString tagName = element.tagName();

  if ( tagName == "priority" ) {
    bool ok;
    int priority = element.text().toInt( &ok );
    if ( !ok || priority < 0 || priority > 9 )
      priority = 5;
    setPriority( priority );
  } else if ( tagName == "completed" ) {
    bool ok;
    int percent = element.text().toInt( &ok );
    if ( !ok || percent < 0 || percent > 100 )
      percent = 0;
    setPercentCompleted( percent );
  } else if ( tagName == "status" ) {
    if ( element.text() == "in-progress" )
      setStatus( KCal::Incidence::StatusInProcess );
    else if ( element.text() == "completed" )
      setStatus( KCal::Incidence::StatusCompleted );
    else if ( element.text() == "waiting-on-someone-else" )
      setStatus( KCal::Incidence::StatusNeedsAction );
    else if ( element.text() == "deferred" )
      // Guessing a status here
      setStatus( KCal::Incidence::StatusCanceled );
    else
      // Default
      setStatus( KCal::Incidence::StatusNone );
  } else if ( tagName == "due-date" )
    setDueDate( stringToDateTime( element.text() ) );
  else if ( tagName == "parent" )
    setParent( element.text() );
  else if ( tagName == "x-completed-date" )
    setCompletedDate( stringToDateTime( element.text() ) );
  else if ( tagName == "start-date" ) {
    setHasStartDate( true );
    setStartDate( element.text() );
  } else
    return Incidence::loadAttribute( element );

  // We handled this
  return true;
}

bool Task::saveAttributes( QDomElement& element ) const
{
  // Save the base class elements
  Incidence::saveAttributes( element );

  writeString( element, "priority", QString::number( priority() ) );
  writeString( element, "completed", QString::number( percentCompleted() ) );

  switch( status() ) {
  case KCal::Incidence::StatusInProcess:
    writeString( element, "status", "in-progress" );
    break;
  case KCal::Incidence::StatusCompleted:
    writeString( element, "status", "completed" );
    break;
  case KCal::Incidence::StatusNeedsAction:
    writeString( element, "status", "waiting-on-someone-else" );
    break;
  case KCal::Incidence::StatusCanceled:
    writeString( element, "status", "deferred" );
    break;
  case KCal::Incidence::StatusNone:
    writeString( element, "status", "not-started" );
    break;
  case KCal::Incidence::StatusTentative:
  case KCal::Incidence::StatusConfirmed:
  case KCal::Incidence::StatusDraft:
  case KCal::Incidence::StatusFinal:
  case KCal::Incidence::StatusX:
    // All of these are saved as StatusNone.
    writeString( element, "status", "not-started" );
    break;
  }

  if ( hasDueDate() )
    writeString( element, "due-date", dateTimeToString( dueDate() ) );

  if ( !parent().isNull() )
    writeString( element, "parent", parent() );

  if ( hasCompletedDate() && percentCompleted() == 100)
    writeString( element, "x-completed-date", dateTimeToString( completedDate() ) );

  return true;
}

bool Task::loadXML( const QDomDocument& document )
{
  QDomElement top = document.documentElement();

  if ( top.tagName() != "task" ) {
    qWarning( "XML error: Top tag was %s instead of the expected task",
              top.tagName().ascii() );
    return false;
  }
  setHasStartDate( false ); // todo's don't necessarily have one

  for ( QDomNode n = top.firstChild(); !n.isNull(); n = n.nextSibling() ) {
    if ( n.isComment() )
      continue;
    if ( n.isElement() ) {
      QDomElement e = n.toElement();
      if ( !loadAttribute( e ) )
        // TODO: Unhandled tag - save for later storage
        kdDebug() << "Warning: Unhandled tag " << e.tagName() << endl;
    } else
      kdDebug() << "Node is not a comment or an element???" << endl;
  }

  return true;
}

QString Task::saveXML() const
{
  QDomDocument document = domTree();
  QDomElement element = document.createElement( "task" );
  element.setAttribute( "version", "1.0" );
  saveAttributes( element );
  if ( !hasStartDate() ) {
    // events and journals always have a start date, but tasks don't.
    // Remove the entry done by the inherited save above, because we
    // don't have one.
    QDomNodeList l = element.elementsByTagName( "start-date" );
    Q_ASSERT( l.count() == 1 );
    element.removeChild( l.item( 0 ) );
  }
  document.appendChild( element );
  return document.toString();
}

void Task::setFields( const KCal::Todo* task )
{
  Incidence::setFields( task );

  setPriority( task->priority() );
  setPercentCompleted( task->percentComplete() );
  setStatus( task->status() );
  setHasStartDate( task->hasStartDate() );

  if ( task->hasDueDate() )
    setDueDate( localToUTC( task->dtDue() ) );
  else
    mHasDueDate = false;
  if ( task->relatedTo() )
    setParent( task->relatedTo()->uid() );
  else
    setParent( QString::null );

  if ( task->hasCompletedDate() && task->percentComplete() == 100 )
    setCompletedDate( localToUTC( task->completed() ) );
  else
    mHasCompletedDate = false;
}

void Task::saveTo( KCal::Todo* task )
{
  Incidence::saveTo( task );

  task->setPriority( priority() );
  task->setPercentComplete( percentCompleted() );
  task->setStatus( status() );
  task->setHasStartDate( hasStartDate() );
  task->setHasDueDate( hasDueDate() );
  if ( hasDueDate() )
    task->setDtDue( utcToLocal( dueDate() ) );

  if ( !parent().isNull() )
    task->setRelatedToUid( parent() );

  if ( hasCompletedDate() && task->percentComplete() == 100 )
    task->setCompleted( utcToLocal( mCompletedDate ) );
}
<|endoftext|>


<commit_before>#include "pch.h"
#include "AssemblyUILayer.h"
#include "GameManager.h"
#include "StageManager.h"
#include "DataManager.h"
#include "ResourceManager.h"
#include "InputManager.h"
#include "AssemblyLineLayer.h"
#include "EquipmentStatusLayer.h"
#include "AssemblyDisplayLayer.h"
#include "SkillLineLayer.h"
#include "ButtonLayer.h"
#include "IconLayer.h"

AssemblyUILayer::AssemblyUILayer()
{
	m_viewChangeRect.setRect(1235 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
}

AssemblyUILayer::~AssemblyUILayer()
{
}

bool AssemblyUILayer::init()
{
	if (!cocos2d::Layer::init())
	{
		return false;
	}
	m_IsStarted = false;

	m_AssemblyLineLayer = AssemblyLineLayer::create();
	m_StatusLayer = EquipmentStatusLayer::create();
	m_DisplayLayer = AssemblyDisplayLayer::create();
	m_SkillLineLayer = SkillLineLayer::create();

	m_AssemblyBackground = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_BACKGROUND);
	m_AssemblyFrame = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_FRAME);
	m_ViewChangeArrow = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_ARROW);
	m_EquipmentRect.setRect(190 * RESOLUTION, 40 * RESOLUTION, 390 * RESOLUTION, 580 * RESOLUTION);

	setUIProperties(m_AssemblyBackground, cocos2d::Point::ZERO, cocos2d::Point::ZERO, RESOLUTION, true, 0);
	setUIProperties(m_AssemblyFrame, cocos2d::Point::ZERO, cocos2d::Point::ZERO, RESOLUTION, true, 0);
	setUIProperties(m_ViewChangeArrow, cocos2d::Point(0.5, 0.5), cocos2d::Point(1055, 360), 1.0f, true, 1);
	assemblyLayerButtonInit();

	m_CurrentAssembly = ASSEMBLY_VIEW;

	this->addChild(m_AssemblyBackground);
	m_AssemblyBackground->addChild(m_AssemblyLineLayer);
	m_AssemblyBackground->addChild(m_DisplayLayer);
	m_AssemblyBackground->addChild(m_SkillLineLayer);
	this->addChild(m_AssemblyFrame);
	m_AssemblyFrame->addChild(m_ViewChangeArrow);
	m_AssemblyFrame->addChild(m_StatusLayer);
	return true;
}

void AssemblyUILayer::update(float dTime)
{
	MouseInfo mouseInput = GET_INPUT_MANAGER()->getMouseInfo();
	if (m_CurrentAssembly == ASSEMBLY_VIEW)
	{
		m_StatusLayer->update(dTime);
		if (m_EquipmentRect.containsPoint(mouseInput.m_MouseMove))
		{
			m_AssemblyLineLayer->updateEquipments(dTime);
			m_AssemblyLineLayer->containerScroll(mouseInput.m_ScollValue, mouseInput.m_MouseMove);
			GET_INPUT_MANAGER()->resetMouseWheel();

			if (mouseInput.m_MouseState == MS_LEFT_UP)
			{
				m_AssemblyLineLayer->updateClickIcon(mouseInput.m_MouseMove);
				m_AssemblyLineLayer->setClickedItem(mouseInput.m_MouseMove);
				GET_INPUT_MANAGER()->resetMouseState();
			}
			else if (mouseInput.m_DoubleClick)
			{
				m_AssemblyLineLayer->updateDoubleClickIcon(mouseInput.m_MouseMove);
				m_AssemblyLineLayer->setConfirmSet(mouseInput.m_MouseMove);
				m_DisplayLayer->update(dTime);
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}
		else
		{
			m_AssemblyLineLayer->hideLabelLayer();
			if (mouseInput.m_ScollValue < 0)
			{
				viewChange(SKILL_VIEW);
			}
			else if (mouseInput.m_ScollValue > 0)
			{
				GET_INPUT_MANAGER()->resetMouseWheel();
			}

			//meaningless double click error exception
			if (mouseInput.m_DoubleClick)
			{
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}

		//view change arrow
		if (m_viewChangeRect.containsPoint(mouseInput.m_MouseEnd[LEFT_CLICK_POINT]))
		{
			viewChange(SKILL_VIEW);
		}
	}
	else if (m_CurrentAssembly == SKILL_VIEW)
	{
		if (m_SkillRect.containsPoint(mouseInput.m_MouseMove))
		{
			if (mouseInput.m_DoubleClick)
			{
				m_DisplayLayer->update(dTime);
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}
		else
		{
			if (mouseInput.m_ScollValue > 0)
			{
				viewChange(ASSEMBLY_VIEW);
			}
			else if (mouseInput.m_ScollValue < 0)
			{
				GET_INPUT_MANAGER()->resetMouseWheel();
			}
		}

		//view change arrow
		if (m_viewChangeRect.containsPoint(mouseInput.m_MouseEnd[LEFT_CLICK_POINT]))
		{
			viewChange(ASSEMBLY_VIEW);
		}
		m_StatusLayer->update(dTime);
		m_SkillLineLayer->update(dTime);
		m_ButtonConfirm->update(dTime);
		m_ButtonCancel->update(dTime);
	}
}

void AssemblyUILayer::viewChange(AssemblyLayerType moveViewTo)
{
	if (m_AssemblyBackground->getNumberOfRunningActions() == 0)
	{
		cocos2d::ActionInterval* moveAction0;
		cocos2d::ActionInterval* moveAction1;
		if (moveViewTo == SKILL_VIEW)
		{
			moveAction0 = cocos2d::MoveTo::create(1.0f, cocos2d::Point(-830 * RESOLUTION, 0));
			moveAction1 = cocos2d::MoveTo::create(1.2f, cocos2d::Point(-830 * RESOLUTION, 0));
			m_viewChangeRect.setRect(20 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
			m_ViewChangeArrow->setRotation(180);
			m_ButtonConfirm->setButtonRect(cocos2d::Point(-830 * RESOLUTION, 0));
			m_ButtonCancel->setButtonRect(cocos2d::Point(-830 * RESOLUTION, 0));
			m_AssemblyLineLayer->setVisible(false);
			m_CurrentAssembly = SKILL_VIEW;
		}
		else
		{
			moveAction0 = cocos2d::MoveTo::create(1.0f, cocos2d::Point(0, 0));
			moveAction1 = cocos2d::MoveTo::create(1.2f, cocos2d::Point(0, 0));
			m_viewChangeRect.setRect(1235 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
			m_ViewChangeArrow->setRotation(0);
			m_ButtonConfirm->setButtonRect(cocos2d::Point(0 * RESOLUTION, 0));
			m_ButtonCancel->setButtonRect(cocos2d::Point(0 * RESOLUTION, 0));
			m_AssemblyLineLayer->setVisible(true);
			m_CurrentAssembly = ASSEMBLY_VIEW;
		}
		cocos2d::Action* action0 = cocos2d::EaseExponentialOut::create(moveAction0);
		cocos2d::Action* action1 = cocos2d::EaseExponentialOut::create(moveAction1);
		m_AssemblyFrame->runAction(action0);
		m_AssemblyBackground->runAction(action1);
	}
	GET_INPUT_MANAGER()->resetMousePoints();
	GET_INPUT_MANAGER()->resetMouseWheel();
}

void AssemblyUILayer::assemblyLayerButtonInit()
{
	m_ButtonConfirm = ButtonLayer::create();
	m_ButtonCancel = ButtonLayer::create();

	m_ButtonConfirm->setButtonProperties(BUTTON_ASSEMBLY, cocos2d::Point(0 * RESOLUTION, 0), cocos2d::Point(1670, 90), "Confirm");
	m_ButtonCancel->setButtonProperties(BUTTON_ASSEMBLY, cocos2d::Point(0 * RESOLUTION, 0), cocos2d::Point(1900, 90), "Cancel");

	m_ButtonConfirm->setButtonFunc(std::bind(&AssemblyUILayer::confirmAssembly, this));
	m_ButtonCancel->setButtonFunc(std::bind(&AssemblyUILayer::toTitleScene, this));

	m_AssemblyFrame->addChild(m_ButtonConfirm);
	m_AssemblyFrame->addChild(m_ButtonCancel);
}

void AssemblyUILayer::moveContainer(bool moveLeft, cocos2d::Node* container, cocos2d::Rect containerRect)
{
	if (moveLeft)
	{
		if (container->getBoundingBox().getMaxX() - 110 > containerRect.getMaxX())
		{
			container->setPosition(cocos2d::Point(container->getPosition().x - 15, container->getPosition().y));
		}
		GET_INPUT_MANAGER()->resetMouseWheel();
	}
	else
	{
		if (container->getBoundingBox().getMinX() * RESOLUTION - 15 < containerRect.getMinX())
		{
			container->setPosition(cocos2d::Point(container->getPosition().x + 15, container->getPosition().y));
		}
		GET_INPUT_MANAGER()->resetMouseWheel();
	}
}

void AssemblyUILayer::confirmAssembly()
{
	if (checkAssemblyComplete(m_AssemblyLineLayer->getConfirmSet()))
	{
		if (!m_IsStarted)
		{
			m_IsStarted = true;
			GET_DATA_MANAGER()->initWorldData();
			GET_INPUT_MANAGER()->resetMouseInfo();
			GET_GAME_MANAGER()->changeScene(GET_STAGE_MANAGER()->getGameScene(), GAME_SCENE);
			GET_STAGE_MANAGER()->start();
		}
	}
	else
	{
		//̿ϼ ޽ !
	}
}

void AssemblyUILayer::toTitleScene()
{
	//߿ Լ ٲٱ
	exit(0);
}

bool AssemblyUILayer::checkAssemblyComplete(ConfirmSet confirmSet)
{
// 	if (confirmSet.m_Head == HL_START || confirmSet.m_Engine == EL_START ||
// 		confirmSet.m_Armor == AL_START || confirmSet.m_Melee == ML_START ||
// 		confirmSet.m_Range == RL_START || confirmSet.m_Steam == SCL_START || confirmSet.m_Leg == LL_START)
// 	{
// 		return false;
// 	}
// 	else
// 	{
// 		return true;
// 	}
	return true;
}

<commit_msg>setCurClickedItem<commit_after>#include "pch.h"
#include "AssemblyUILayer.h"
#include "GameManager.h"
#include "StageManager.h"
#include "DataManager.h"
#include "ResourceManager.h"
#include "InputManager.h"
#include "AssemblyLineLayer.h"
#include "EquipmentStatusLayer.h"
#include "AssemblyDisplayLayer.h"
#include "SkillLineLayer.h"
#include "ButtonLayer.h"
#include "IconLayer.h"

AssemblyUILayer::AssemblyUILayer()
{
	m_viewChangeRect.setRect(1235 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
}

AssemblyUILayer::~AssemblyUILayer()
{
}

bool AssemblyUILayer::init()
{
	if (!cocos2d::Layer::init())
	{
		return false;
	}
	m_IsStarted = false;

	m_AssemblyLineLayer = AssemblyLineLayer::create();
	m_StatusLayer = EquipmentStatusLayer::create();
	m_DisplayLayer = AssemblyDisplayLayer::create();
	m_SkillLineLayer = SkillLineLayer::create();

	m_AssemblyBackground = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_BACKGROUND);
	m_AssemblyFrame = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_FRAME);
	m_ViewChangeArrow = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_ARROW);
	m_EquipmentRect.setRect(190 * RESOLUTION, 40 * RESOLUTION, 390 * RESOLUTION, 580 * RESOLUTION);

	setUIProperties(m_AssemblyBackground, cocos2d::Point::ZERO, cocos2d::Point::ZERO, RESOLUTION, true, 0);
	setUIProperties(m_AssemblyFrame, cocos2d::Point::ZERO, cocos2d::Point::ZERO, RESOLUTION, true, 0);
	setUIProperties(m_ViewChangeArrow, cocos2d::Point(0.5, 0.5), cocos2d::Point(1055, 360), 1.0f, true, 1);
	assemblyLayerButtonInit();

	m_CurrentAssembly = ASSEMBLY_VIEW;

	this->addChild(m_AssemblyBackground);
	m_AssemblyBackground->addChild(m_AssemblyLineLayer);
	m_AssemblyBackground->addChild(m_DisplayLayer);
	m_AssemblyBackground->addChild(m_SkillLineLayer);
	this->addChild(m_AssemblyFrame);
	m_AssemblyFrame->addChild(m_ViewChangeArrow);
	m_AssemblyFrame->addChild(m_StatusLayer);
	return true;
}

void AssemblyUILayer::update(float dTime)
{
	MouseInfo mouseInput = GET_INPUT_MANAGER()->getMouseInfo();
	if (m_CurrentAssembly == ASSEMBLY_VIEW)
	{
		m_StatusLayer->update(dTime);
		if (m_EquipmentRect.containsPoint(mouseInput.m_MouseMove))
		{
			m_AssemblyLineLayer->updateEquipments(dTime);
			m_AssemblyLineLayer->containerScroll(mouseInput.m_ScollValue, mouseInput.m_MouseMove);
			GET_INPUT_MANAGER()->resetMouseWheel();

			if (mouseInput.m_MouseState == MS_LEFT_UP)
			{
				m_AssemblyLineLayer->updateClickIcon(mouseInput.m_MouseMove);
				m_AssemblyLineLayer->setClickedItem(mouseInput.m_MouseMove);
				m_StatusLayer->setCurClickedItem(m_AssemblyLineLayer->getClickedItem());
				GET_INPUT_MANAGER()->resetMouseState();
			}
			else if (mouseInput.m_DoubleClick)
			{
				m_AssemblyLineLayer->updateDoubleClickIcon(mouseInput.m_MouseMove);
				m_AssemblyLineLayer->setConfirmSet(mouseInput.m_MouseMove);
				m_DisplayLayer->update(dTime);
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}
		else
		{
			m_AssemblyLineLayer->hideLabelLayer();
			if (mouseInput.m_ScollValue < 0)
			{
				viewChange(SKILL_VIEW);
			}
			else if (mouseInput.m_ScollValue > 0)
			{
				GET_INPUT_MANAGER()->resetMouseWheel();
			}

			//meaningless double click error exception
			if (mouseInput.m_DoubleClick)
			{
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}

		//view change arrow
		if (m_viewChangeRect.containsPoint(mouseInput.m_MouseEnd[LEFT_CLICK_POINT]))
		{
			viewChange(SKILL_VIEW);
		}
	}
	else if (m_CurrentAssembly == SKILL_VIEW)
	{
		if (m_SkillRect.containsPoint(mouseInput.m_MouseMove))
		{
			if (mouseInput.m_DoubleClick)
			{
				m_DisplayLayer->update(dTime);
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}
		else
		{
			if (mouseInput.m_ScollValue > 0)
			{
				viewChange(ASSEMBLY_VIEW);
			}
			else if (mouseInput.m_ScollValue < 0)
			{
				GET_INPUT_MANAGER()->resetMouseWheel();
			}
		}

		//view change arrow
		if (m_viewChangeRect.containsPoint(mouseInput.m_MouseEnd[LEFT_CLICK_POINT]))
		{
			viewChange(ASSEMBLY_VIEW);
		}
		m_StatusLayer->update(dTime);
		m_SkillLineLayer->update(dTime);
		m_ButtonConfirm->update(dTime);
		m_ButtonCancel->update(dTime);
	}
}

void AssemblyUILayer::viewChange(AssemblyLayerType moveViewTo)
{
	if (m_AssemblyBackground->getNumberOfRunningActions() == 0)
	{
		cocos2d::ActionInterval* moveAction0;
		cocos2d::ActionInterval* moveAction1;
		if (moveViewTo == SKILL_VIEW)
		{
			moveAction0 = cocos2d::MoveTo::create(1.0f, cocos2d::Point(-830 * RESOLUTION, 0));
			moveAction1 = cocos2d::MoveTo::create(1.2f, cocos2d::Point(-830 * RESOLUTION, 0));
			m_viewChangeRect.setRect(20 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
			m_ViewChangeArrow->setRotation(180);
			m_ButtonConfirm->setButtonRect(cocos2d::Point(-830 * RESOLUTION, 0));
			m_ButtonCancel->setButtonRect(cocos2d::Point(-830 * RESOLUTION, 0));
			m_AssemblyLineLayer->setVisible(false);
			m_CurrentAssembly = SKILL_VIEW;
		}
		else
		{
			moveAction0 = cocos2d::MoveTo::create(1.0f, cocos2d::Point(0, 0));
			moveAction1 = cocos2d::MoveTo::create(1.2f, cocos2d::Point(0, 0));
			m_viewChangeRect.setRect(1235 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
			m_ViewChangeArrow->setRotation(0);
			m_ButtonConfirm->setButtonRect(cocos2d::Point(0 * RESOLUTION, 0));
			m_ButtonCancel->setButtonRect(cocos2d::Point(0 * RESOLUTION, 0));
			m_AssemblyLineLayer->setVisible(true);
			m_CurrentAssembly = ASSEMBLY_VIEW;
		}
		cocos2d::Action* action0 = cocos2d::EaseExponentialOut::create(moveAction0);
		cocos2d::Action* action1 = cocos2d::EaseExponentialOut::create(moveAction1);
		m_AssemblyFrame->runAction(action0);
		m_AssemblyBackground->runAction(action1);
	}
	GET_INPUT_MANAGER()->resetMousePoints();
	GET_INPUT_MANAGER()->resetMouseWheel();
}

void AssemblyUILayer::assemblyLayerButtonInit()
{
	m_ButtonConfirm = ButtonLayer::create();
	m_ButtonCancel = ButtonLayer::create();

	m_ButtonConfirm->setButtonProperties(BUTTON_ASSEMBLY, cocos2d::Point(0 * RESOLUTION, 0), cocos2d::Point(1670, 90), "Confirm");
	m_ButtonCancel->setButtonProperties(BUTTON_ASSEMBLY, cocos2d::Point(0 * RESOLUTION, 0), cocos2d::Point(1900, 90), "Cancel");

	m_ButtonConfirm->setButtonFunc(std::bind(&AssemblyUILayer::confirmAssembly, this));
	m_ButtonCancel->setButtonFunc(std::bind(&AssemblyUILayer::toTitleScene, this));

	m_AssemblyFrame->addChild(m_ButtonConfirm);
	m_AssemblyFrame->addChild(m_ButtonCancel);
}

void AssemblyUILayer::moveContainer(bool moveLeft, cocos2d::Node* container, cocos2d::Rect containerRect)
{
	if (moveLeft)
	{
		if (container->getBoundingBox().getMaxX() - 110 > containerRect.getMaxX())
		{
			container->setPosition(cocos2d::Point(container->getPosition().x - 15, container->getPosition().y));
		}
		GET_INPUT_MANAGER()->resetMouseWheel();
	}
	else
	{
		if (container->getBoundingBox().getMinX() * RESOLUTION - 15 < containerRect.getMinX())
		{
			container->setPosition(cocos2d::Point(container->getPosition().x + 15, container->getPosition().y));
		}
		GET_INPUT_MANAGER()->resetMouseWheel();
	}
}

void AssemblyUILayer::confirmAssembly()
{
	if (checkAssemblyComplete(m_AssemblyLineLayer->getConfirmSet()))
	{
		if (!m_IsStarted)
		{
			m_IsStarted = true;
			GET_DATA_MANAGER()->initWorldData();
			GET_INPUT_MANAGER()->resetMouseInfo();
			GET_GAME_MANAGER()->changeScene(GET_STAGE_MANAGER()->getGameScene(), GAME_SCENE);
			GET_STAGE_MANAGER()->start();
		}
	}
	else
	{
		//̿ϼ ޽ !
	}
}

void AssemblyUILayer::toTitleScene()
{
	//߿ Լ ٲٱ
	exit(0);
}

bool AssemblyUILayer::checkAssemblyComplete(ConfirmSet confirmSet)
{
// 	if (confirmSet.m_Head == HL_START || confirmSet.m_Engine == EL_START ||
// 		confirmSet.m_Armor == AL_START || confirmSet.m_Melee == ML_START ||
// 		confirmSet.m_Range == RL_START || confirmSet.m_Steam == SCL_START || confirmSet.m_Leg == LL_START)
// 	{
// 		return false;
// 	}
// 	else
// 	{
// 		return true;
// 	}
	return true;
}

<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include "Runtime/RetroTypes.hpp"
#include "Runtime/GuiSys/CGuiTextSupport.hpp"

namespace urde {

class CDrawStringOptions {
  friend class CColorOverrideInstruction;
  friend class CFontRenderState;
  friend class CRasterFont;
  friend class CTextExecuteBuffer;
  friend class CBlockInstruction;
  friend class CWordInstruction;

  ETextDirection x0_direction = ETextDirection::Horizontal;
  std::vector<CTextColor> x4_colors;

public:
  CDrawStringOptions() { x4_colors.resize(16); }
};

} // namespace urde
<commit_msg>CDrawStringOptions: Resize vector within constructor<commit_after>#pragma once

#include <vector>
#include "Runtime/RetroTypes.hpp"
#include "Runtime/GuiSys/CGuiTextSupport.hpp"

namespace urde {

class CDrawStringOptions {
  friend class CColorOverrideInstruction;
  friend class CFontRenderState;
  friend class CRasterFont;
  friend class CTextExecuteBuffer;
  friend class CBlockInstruction;
  friend class CWordInstruction;

  ETextDirection x0_direction = ETextDirection::Horizontal;
  std::vector<CTextColor> x4_colors;

public:
  CDrawStringOptions() : x4_colors(16) {}
};

} // namespace urde
<|endoftext|>


<commit_before>#include <windows.h>
#include <winsock.h>
#include <string>
using std::string;
#include <iostream>
using std::cout; using std::endl; using std::cin;

namespace rsa
{
    const int WSVERS = MAKEWORD(2, 0);

    auto make_remote_address(char* arr[]) -> sockaddr_in
    {
        struct sockaddr_in address;
        memset(&address, 0, sizeof(address));
        address.sin_addr.s_addr = inet_addr(arr[1]);    //IP address
        address.sin_port = htons((u_short)atoi(arr[2]));//Port number
        address.sin_family = AF_INET;
        return address;
    }

    auto handle_user_input(int arguments_count) -> void
    {
        if (arguments_count != 3)
        {
            cout << "USAGE: client IP-address port" << endl;
            exit(1);
        }
    }

    auto setup_win_sock_api(WORD version_required) -> WSADATA
    {
        WSADATA wsadata;
        if (WSAStartup(WSVERS, &wsadata) != 0)
        {
            WSACleanup();
            cout << "WSAStartup failed\n";
            exit(1);
        }
        return wsadata;
    }

    //return the string received
    auto receive(SOCKET s) -> string
    {
        auto received = string();
        //receive char by char, end on an LF, ignore CR's
        for (auto ch = char(0); true; /* */)
        {
            if (0 >= recv(s, &ch, 1, 0)) { cout << "recv failed\n"; exit(1); }
            if (ch == '\n') break; else if (ch == '\r') continue; else received.push_back(ch);
        }
        return received;
    }
}//namespace rsa

auto main(int argc, char *argv[]) -> int
{
    rsa::handle_user_input(argc);
    auto wsa_data = rsa::setup_win_sock_api(rsa::WSVERS);
    auto remoteaddr = rsa::make_remote_address(argv);

    //CREATE CLIENT'S SOCKET
    auto s = socket(AF_INET, SOCK_STREAM, 0);
    if (s < 0)
    {
        cout << "socket failed\n";
        exit(1);
    }

    //CONNECT
    if (connect(s, (struct sockaddr *)&remoteaddr, sizeof(remoteaddr)) != 0)
    {
        cout << "connect failed\n";
        exit(1);
    }

    for (auto send_buffer = string{}; cin >> send_buffer; /* */)
    {
        if (send_buffer == ".") break; else send_buffer += "\r\n";

        //SEND
        auto bytes_sent = send(s, send_buffer.c_str(), send_buffer.size(), 0);
        if (bytes_sent < 0) { cout << "send failed\n"; exit(1); }

        //receive
        cout << rsa::receive(s) << endl;
    }

    closesocket(s);
    return 0;
}<commit_msg>rsa -> as3 , add send into as3 namespace<commit_after>#include <windows.h>
#include <winsock.h>
#include <string>
using std::string;
#include <iostream>
using std::cout; using std::endl; using std::cin;

namespace as3
{
    const int WSVERS = MAKEWORD(2, 0);

    auto make_remote_address(char* arr[]) -> sockaddr_in
    {
        struct sockaddr_in address;
        memset(&address, 0, sizeof(address));
        address.sin_addr.s_addr = inet_addr(arr[1]);    //IP address
        address.sin_port = htons((u_short)atoi(arr[2]));//Port number
        address.sin_family = AF_INET;
        return address;
    }

    auto handle_user_input(int arguments_count) -> void
    {
        if (arguments_count != 3)
        {
            cout << "USAGE: client IP-address port" << endl;
            exit(1);
        }
    }

    auto setup_win_sock_api(WORD version_required) -> WSADATA
    {
        WSADATA wsadata;
        if (WSAStartup(WSVERS, &wsadata) != 0)
        {
            WSACleanup();
            cout << "WSAStartup failed\n";
            exit(1);
        }
        return wsadata;
    }

    //return the string received
    auto receive(SOCKET s) -> string
    {
        auto received = string();
        //receive char by char, end on an LF, ignore CR's
        for (auto ch = char(0); true; /* */)
        {
            if (0 >= recv(s, &ch, 1, 0)) { cout << "recv failed\n"; exit(1); }
            if (ch == '\n') break; else if (ch == '\r') continue; else received.push_back(ch);
        }
        return received;
    }

    auto send(SOCKET sock, string const& send_buffer) -> void
    {
        auto bytes_sent = ::send(sock, send_buffer.c_str(), send_buffer.size(), 0);
        if (bytes_sent < 0) { cout << "send failed\n"; exit(1); }
    }
}//namespace rsa

auto main(int argc, char *argv[]) -> int
{
    as3::handle_user_input(argc);
    auto wsa_data = as3::setup_win_sock_api(as3::WSVERS);
    auto remoteaddr = as3::make_remote_address(argv);

    //CREATE CLIENT'S SOCKET
    auto s = socket(AF_INET, SOCK_STREAM, 0);
    if (s < 0)
    {
        cout << "socket failed\n";
        exit(1);
    }

    //CONNECT
    if (connect(s, (struct sockaddr *)&remoteaddr, sizeof(remoteaddr)) != 0)
    {
        cout << "connect failed\n";
        exit(1);
    }

    for (auto send_buffer = string{}; cin >> send_buffer; cout << as3::receive(s) << endl)
    {
        if (send_buffer == ".") break; else send_buffer += "\r\n";
        as3::send(s, send_buffer);
    }

    closesocket(s);
    return 0;
}<|endoftext|>


<commit_before>/***************************************************************************
    begin                : Wed Jun 16 2004
    copyright            : (C) 2004 by Richard Dale
    email                : Richard_Dale@tipitina.demon.co.uk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "qyotosmokebinding.h"
#include "qyoto.h"
#include "virtualmethodcall.h"

#include <cstdlib>

QyotoSmokeBinding::QyotoSmokeBinding(Smoke *s, QHash<int, char*> *classname) : SmokeBinding(s), _classname(classname) {}

void
QyotoSmokeBinding::deleted(Smoke::Index classId, void *ptr)
{
	void * obj = (*GetInstance)(ptr, true);
	if (obj == 0) {
		return;
	}

	smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)(obj);

	if (do_debug & qtdb_gc) {
		printf("%p->~%s()\n", ptr, smoke->className(classId));
		fflush(stdout);
	}

	if (o == 0 || o->ptr == 0) {
		(*FreeGCHandle)(obj);
		return;
	}
	unmapPointer(o, o->classId, 0);
	(*SetSmokeObject)(obj, 0);
	free_smokeqyoto_object(o);
	(*FreeGCHandle)(obj);
}

bool
QyotoSmokeBinding::callMethod(Smoke::Index method, void *ptr, Smoke::Stack args, bool isAbstract)
{
	// don't call anything if the application has already terminated
	if (application_terminated) return false;
	void * obj = (*GetInstance)(ptr, false);

	if (obj == 0 && !isAbstract) {
		return false;
	}

	Smoke::Method & meth = smoke->methods[method];
	QByteArray signature(smoke->methodNames[meth.name]);
	signature += "(";

	for (int i = 0; i < meth.numArgs; i++) {
		if (i != 0) signature += ", ";
		signature += smoke->types[smoke->argumentList[meth.args + i]].name;
	}

	signature += ")";
	if (meth.flags & Smoke::mf_const) {
		signature += " const";
	}

	if (obj == 0) {
		printf(	"Fatal error: C# instance has been wrongly GC'd for virtual %p->%s::%s call\n",
					ptr,
					smoke->classes[smoke->methods[method].classId].className,
					(const char *) signature );
			std::exit(1);
	}
		if (do_debug & qtdb_virtual) {
		printf(	"virtual %p->%s::%s called\n",
					ptr,
					smoke->classes[smoke->methods[method].classId].className,
					(const char *) signature );
		fflush(stdout);
	}

	if (strcmp(signature, "qt_metacall(QMetaObject::Call, int, void**)") == 0) {
		QMetaObject::Call _c = (QMetaObject::Call)args[1].s_int;
		int _id = args[2].s_int;
		void** _o = (void**)args[3].s_voidp;

		args[0].s_int = qt_metacall(obj, _c, _id, _o);

		(*FreeGCHandle)(obj);
		return true;
	}
	void * overridenMethod = (*OverridenMethod)(obj, (const char *) signature);
	if (overridenMethod == 0) {
		(*FreeGCHandle)(obj);
		return false;
	}

	VirtualMethodCall c(smoke, method, args, obj, overridenMethod);
	c.next();
	return true;
}

char*
QyotoSmokeBinding::className(Smoke::Index classId)
{
	return _classname->value((int) classId);
}
<commit_msg>- Required by gcc later that qt 4.3.x<commit_after>/***************************************************************************
    begin                : Wed Jun 16 2004
    copyright            : (C) 2004 by Richard Dale
    email                : Richard_Dale@tipitina.demon.co.uk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdlib.h>
#include "qyotosmokebinding.h"
#include "qyoto.h"
#include "virtualmethodcall.h"

#include <cstdlib>

QyotoSmokeBinding::QyotoSmokeBinding(Smoke *s, QHash<int, char*> *classname) : SmokeBinding(s), _classname(classname) {}

void
QyotoSmokeBinding::deleted(Smoke::Index classId, void *ptr)
{
	void * obj = (*GetInstance)(ptr, true);
	if (obj == 0) {
		return;
	}

	smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)(obj);

	if (do_debug & qtdb_gc) {
		printf("%p->~%s()\n", ptr, smoke->className(classId));
		fflush(stdout);
	}

	if (o == 0 || o->ptr == 0) {
		(*FreeGCHandle)(obj);
		return;
	}
	unmapPointer(o, o->classId, 0);
	(*SetSmokeObject)(obj, 0);
	free_smokeqyoto_object(o);
	(*FreeGCHandle)(obj);
}

bool
QyotoSmokeBinding::callMethod(Smoke::Index method, void *ptr, Smoke::Stack args, bool isAbstract)
{
	// don't call anything if the application has already terminated
	if (application_terminated) return false;
	void * obj = (*GetInstance)(ptr, false);

	if (obj == 0 && !isAbstract) {
		return false;
	}

	Smoke::Method & meth = smoke->methods[method];
	QByteArray signature(smoke->methodNames[meth.name]);
	signature += "(";

	for (int i = 0; i < meth.numArgs; i++) {
		if (i != 0) signature += ", ";
		signature += smoke->types[smoke->argumentList[meth.args + i]].name;
	}

	signature += ")";
	if (meth.flags & Smoke::mf_const) {
		signature += " const";
	}

	if (obj == 0) {
		printf(	"Fatal error: C# instance has been wrongly GC'd for virtual %p->%s::%s call\n",
					ptr,
					smoke->classes[smoke->methods[method].classId].className,
					(const char *) signature );
			std::exit(1);
	}
		if (do_debug & qtdb_virtual) {
		printf(	"virtual %p->%s::%s called\n",
					ptr,
					smoke->classes[smoke->methods[method].classId].className,
					(const char *) signature );
		fflush(stdout);
	}

	if (strcmp(signature, "qt_metacall(QMetaObject::Call, int, void**)") == 0) {
		QMetaObject::Call _c = (QMetaObject::Call)args[1].s_int;
		int _id = args[2].s_int;
		void** _o = (void**)args[3].s_voidp;

		args[0].s_int = qt_metacall(obj, _c, _id, _o);

		(*FreeGCHandle)(obj);
		return true;
	}
	void * overridenMethod = (*OverridenMethod)(obj, (const char *) signature);
	if (overridenMethod == 0) {
		(*FreeGCHandle)(obj);
		return false;
	}

	VirtualMethodCall c(smoke, method, args, obj, overridenMethod);
	c.next();
	return true;
}

char*
QyotoSmokeBinding::className(Smoke::Index classId)
{
	return _classname->value((int) classId);
}
<|endoftext|>


<commit_before>/**************************************************************************\
**
**  tStorm.cpp: Functions for class tStorm.
**
**  A tStorm object generates random storms assuming an exponential
**  distribution of rainfall intensity, storm duration, and time to the
**  next storm. It is essentially an implementation of the model of
**  P. Eagleson, 1978b, Water Resources Research. Its services include
**  reading the necessary parameters from a tInputFile, generating a new
**  storm, and reporting its various values.
**
**  $Id: tStorm.cpp,v 1.18 2000-05-10 19:46:11 gtucker Exp $
\**************************************************************************/

#include <math.h>
#include <string.h>
#include "../Mathutil/mathutil.h"
#include "tStorm.h"

/**************************************************************************\
**
**  tStorm::tStorm:  Constructor for storms. The default constructor
**                   assigns a value of unity to storm depth, duration,
**                   and interstorm duration. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( int optvar )
{
   optVariable = optvar;
   optSinVar = 0;
   pMean = 1.0;
   stdurMean = 1.0;
   istdurMean = 1.0;
   p = 1.0;
   stdur = 1.0;
   istdur = 1.0;
   endtm = 1.0e9;
   //srand( 0 );
}

/**************************************************************************\
**
**  tStorm::tStorm:  The constructor that's really used assigns values for
**                   mean storm depth, duration, and interstorm duration,
**                   initializes current depth, etc, to the mean values,
**                   and initializes the random number generator. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( double mp, double ms, double mis, unsigned sd, int optvar, double et )
{
   optVariable = optvar;
   optSinVar = 0;
   pMean = mp;
   stdurMean = ms;
   istdurMean = mis;
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;
   seed = sd;
   endtm = et;
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::tStorm
**
**  Alternative constructor that reads parameters directly from a tInputFile
**  object. Reads option for variable storms (normally this is "yes"---that's
**  the point of these objects---but a user may wish to switch off variation
**  as a test), mean values for rainfall intensity, duration, and interstorm
**  period, and a random seed to initialize the random number generator.
**    Also reads an option for long-term sinusoidal variations in the mean
**  values, and if the option is selected, reads the relevant parameters.
**  Variables p0, stdur0, and istdur0 are the mean values of the means;
**  pdev, stdurdev, and istdurdev are the range of variation (e.g., if pMean
**  were to fluctuate between 5 and 10, p0 would be 7.5 and pdev 2.5).
**
**  Modifications:
**   - 3/00 initialization now includes creation of ".storm" file for storm
**     history (GT)
**
\**************************************************************************/
tStorm::tStorm( tInputFile &infile )
{
   // Read + set parameters for storm intensity, duration, and spacing
   optVariable = infile.ReadItem( optVariable, "OPTVAR" );
   pMean = infile.ReadItem( pMean, "PMEAN" );
   stdurMean = infile.ReadItem( stdurMean, "STDUR" );
   istdurMean = infile.ReadItem( istdurMean, "ISTDUR" );
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;

   endtm = infile.ReadItem( endtm, "RUNTIME" );
   double help;

   help = infile.ReadItem( help, "OPTREADINPUT" );
   if(help>0){
      help = infile.ReadItem( help, "INPUTTIME" );
      endtm += help;
   }

   // Handle option for sinuidoil variation in means
   optSinVar = infile.ReadItem( optSinVar, "OPTSINVAR" );
   if( optSinVar )
   {
      p0 = pMean;
      stdur0 = stdurMean;
      istdur0 = istdurMean;
      twoPiLam = (2.0*PI)/(infile.ReadItem( twoPiLam, "PERIOD" ));
      pdev = infile.ReadItem( pdev, "MAXPMEAN" ) - pMean;
      if( pdev<0 ) cerr << "Warning: MAXPMEAN < PMEAN !";
      else if( pdev > pMean ) cerr << "Warning: MINPMEAN < 0 !";
      stdurdev = infile.ReadItem( stdurdev, "MAXSTDURMN" ) - stdurMean;
      if( stdurdev<0 ) cerr << "Warning: MAXSTDURMN < STDURMN !";
      else if( stdurdev > stdurMean ) cerr << "Warning: MINSTDURMN < 0 !";
      istdurdev = infile.ReadItem( istdurdev, "MAXISTDURMN" ) - istdurMean;
      if( istdurdev<0 ) cerr << "Warning: MAXISTDURMN < ISTDURMN !";
      else if( istdurdev > istdurMean ) cerr << "Warning: MINISTDURMN < 0 !";
   }

   // If variable storms used, create a file for writing them
   if( optVariable )
   {
      char fname[87];
      infile.ReadItem( fname, "OUTFILENAME" );
      strcat( fname, ".storm" );
      stormfile.open( fname );
      if( !stormfile.good() )
          cerr << "Warning: unable to create storm data file '"
               << fname << "'\n";
   }

   // Read and initialize seed for random number generation
   seed = infile.ReadItem( seed, "SEED" );
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::GenerateStorm
**
**  Generates a new storm by drawing new values of p, stdur, and istdur from
**  an exponential distribution and updating the random seed.
**    If the minp parameter is greater than zero, the function will keep
**  picking storms until it finds one with p>minp. The total elapsed time,
**  including the rejected storms and their associated interstorm periods,
**  is stored istdur.
**
**  Inputs:      minp -- minimum value of rainfall rate p (default 0)
**               mind -- minimum storm depth to produce runoff (default 0)
**               tm -- current time in simulation
**  Members updated:  p, stdur, istdur take on new random values (if optVar)
**                    pMean, stdurMean, istdurMean adjusted (if optSinVar)
**  Assumptions:  pMean > 0
**
**  Modifications:
**   - changed AND to OR in while loop, GT 5/99
**   - added to while loop an additional check to see if time has run out,
**     NG 2/00
**   - added output of time, storm intensity, & duration to ".storm" file
**     GT 3/00
**
\**************************************************************************/
void tStorm::GenerateStorm( double tm, double minp, double mind )
{
   // If option for sinusoidal variation is on, adjust the means
   // Also set values for current storm to the means, in case option for
   // random storms is off.
   if( optSinVar )
   {
      double sinfn = sin( tm*twoPiLam );
      pMean = p0 + pdev*sinfn;
      //cout << "pMean = " << pMean << endl;
      stdurMean = stdur0 + stdurdev*sinfn;
      istdurMean = istdur0 + istdurdev*sinfn;
      p = pMean;
      stdur = stdurMean;
      istdur = istdurMean;
   }

   // If option for random storms is on, pick a storm at random.
   // Keep picking and accumulating time until the storm depth or intensity
   // is greater than the minimum value needed to produce runoff.

   if( optVariable )
   {
      stdur = 0;
      istdur = 0;
      do
      {
         p = pMean*ExpDev( &seed );
         istdur += istdurMean*ExpDev( &seed ) + stdur;
         stdur = stdurMean*ExpDev( &seed );
         //cout << "P " << p << "  ST " << stdur << "  IST " << istdur
         //     << "  DP " << p*stdur << " minp " << minp << " mind " <<mind <<
         //            endl;
         //srand( seed );
      } while( (p<=minp || (p*stdur)<=mind) && (tm+istdur+stdur<endtm) );
      stormfile << tm << " " << p << " " << stdur << endl;
   }
}

/**************************************************************************\
**
**  tStorm::ExpDev:  Finds a random number with an exponential distribution
**                   (adapted from Numerical Recipes).
**
\**************************************************************************/
double tStorm::ExpDev( long *idum )
{
    double dum;

    do
        dum = ran3( idum );
    while( dum==0.0 );
    return -log(dum);
}

/**************************************************************************\
**
**  tStorm "get" routines: return various variables
**
\**************************************************************************/

double tStorm::getStormDuration() { return stdur; }
double tStorm::interstormDur() { return istdur; }
double tStorm::getRainrate() { return p; }
double tStorm::getMeanStormDur() const {return stdurMean;}
double tStorm::getMeanInterstormDur() const {return istdurMean;}
double tStorm::getMeanPrecip() const {return pMean;}

/**************************************************************************\
**
**  GammaDev
**
**  Returns a random variable drawn from a Gamma distribution with parameter m.
**
**  (Note: not actually called; provided for future use).
**
\**************************************************************************/
double tStorm::GammaDev(double m, long * idum)
{
  double x, y,z, c,t,b,u,w,v;

  if (m<1)
    {
      c = 1/m;
      t = 0.07 + 0.75*sqrt(1-m);
      b = 1 + exp(-t)*m/t;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum);
          w = ran3(idum);
          v = b *u;
          if (v<=1)
            {
              x  = t * pow(v, c);
              accept = ((w<=((2-x)/(2+x))) || (w<=exp(-x)));
            }
          else
            {
              x = -log(c*t*(b-v));
              y = x/t;
              accept = (((w*(m + y - m*y)) <= 1) || (w<= ( pow(y, (m-1)))));
            }
        }
    }
  else
    {
      b = m-1;
      c = 3*m - 0.75;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum); v = ran3(idum);
          w = u* ( 1-u);
          y = sqrt(c/w) * (u - 0.5);
          x = b + y;
          if ( x>= 0)
            {
              z = 64*( pow(w,3))*v*v;
              accept = (z <= ( 1 - 2*y*y/x)) || ( log(z) <= (2*(b*log(x/b) - y)));
            }
        }
    }
  return x;
}

<commit_msg>changed output to storm file from current time to interstorm duration<commit_after>/**************************************************************************\
**
**  tStorm.cpp: Functions for class tStorm.
**
**  A tStorm object generates random storms assuming an exponential
**  distribution of rainfall intensity, storm duration, and time to the
**  next storm. It is essentially an implementation of the model of
**  P. Eagleson, 1978b, Water Resources Research. Its services include
**  reading the necessary parameters from a tInputFile, generating a new
**  storm, and reporting its various values.
**
**  $Id: tStorm.cpp,v 1.19 2001-06-24 12:41:02 gtucker Exp $
\**************************************************************************/

#include <math.h>
#include <string.h>
#include "../Mathutil/mathutil.h"
#include "tStorm.h"

/**************************************************************************\
**
**  tStorm::tStorm:  Constructor for storms. The default constructor
**                   assigns a value of unity to storm depth, duration,
**                   and interstorm duration. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( int optvar )
{
   optVariable = optvar;
   optSinVar = 0;
   pMean = 1.0;
   stdurMean = 1.0;
   istdurMean = 1.0;
   p = 1.0;
   stdur = 1.0;
   istdur = 1.0;
   endtm = 1.0e9;
   //srand( 0 );
}

/**************************************************************************\
**
**  tStorm::tStorm:  The constructor that's really used assigns values for
**                   mean storm depth, duration, and interstorm duration,
**                   initializes current depth, etc, to the mean values,
**                   and initializes the random number generator. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( double mp, double ms, double mis, unsigned sd, int optvar, double et )
{
   optVariable = optvar;
   optSinVar = 0;
   pMean = mp;
   stdurMean = ms;
   istdurMean = mis;
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;
   seed = sd;
   endtm = et;
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::tStorm
**
**  Alternative constructor that reads parameters directly from a tInputFile
**  object. Reads option for variable storms (normally this is "yes"---that's
**  the point of these objects---but a user may wish to switch off variation
**  as a test), mean values for rainfall intensity, duration, and interstorm
**  period, and a random seed to initialize the random number generator.
**    Also reads an option for long-term sinusoidal variations in the mean
**  values, and if the option is selected, reads the relevant parameters.
**  Variables p0, stdur0, and istdur0 are the mean values of the means;
**  pdev, stdurdev, and istdurdev are the range of variation (e.g., if pMean
**  were to fluctuate between 5 and 10, p0 would be 7.5 and pdev 2.5).
**
**  Modifications:
**   - 3/00 initialization now includes creation of ".storm" file for storm
**     history (GT)
**
\**************************************************************************/
tStorm::tStorm( tInputFile &infile )
{
   // Read + set parameters for storm intensity, duration, and spacing
   optVariable = infile.ReadItem( optVariable, "OPTVAR" );
   pMean = infile.ReadItem( pMean, "PMEAN" );
   stdurMean = infile.ReadItem( stdurMean, "STDUR" );
   istdurMean = infile.ReadItem( istdurMean, "ISTDUR" );
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;

   endtm = infile.ReadItem( endtm, "RUNTIME" );
   double help;

   help = infile.ReadItem( help, "OPTREADINPUT" );
   if(help>0){
      help = infile.ReadItem( help, "INPUTTIME" );
      endtm += help;
   }

   // Handle option for sinuidoil variation in means
   optSinVar = infile.ReadItem( optSinVar, "OPTSINVAR" );
   if( optSinVar )
   {
      p0 = pMean;
      stdur0 = stdurMean;
      istdur0 = istdurMean;
      twoPiLam = (2.0*PI)/(infile.ReadItem( twoPiLam, "PERIOD" ));
      pdev = infile.ReadItem( pdev, "MAXPMEAN" ) - pMean;
      if( pdev<0 ) cerr << "Warning: MAXPMEAN < PMEAN !";
      else if( pdev > pMean ) cerr << "Warning: MINPMEAN < 0 !";
      stdurdev = infile.ReadItem( stdurdev, "MAXSTDURMN" ) - stdurMean;
      if( stdurdev<0 ) cerr << "Warning: MAXSTDURMN < STDURMN !";
      else if( stdurdev > stdurMean ) cerr << "Warning: MINSTDURMN < 0 !";
      istdurdev = infile.ReadItem( istdurdev, "MAXISTDURMN" ) - istdurMean;
      if( istdurdev<0 ) cerr << "Warning: MAXISTDURMN < ISTDURMN !";
      else if( istdurdev > istdurMean ) cerr << "Warning: MINISTDURMN < 0 !";
   }

   // If variable storms used, create a file for writing them
   if( optVariable )
   {
      char fname[87];
      infile.ReadItem( fname, "OUTFILENAME" );
      strcat( fname, ".storm" );
      stormfile.open( fname );
      if( !stormfile.good() )
          cerr << "Warning: unable to create storm data file '"
               << fname << "'\n";
   }

   // Read and initialize seed for random number generation
   seed = infile.ReadItem( seed, "SEED" );
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::GenerateStorm
**
**  Generates a new storm by drawing new values of p, stdur, and istdur from
**  an exponential distribution and updating the random seed.
**    If the minp parameter is greater than zero, the function will keep
**  picking storms until it finds one with p>minp. The total elapsed time,
**  including the rejected storms and their associated interstorm periods,
**  is stored istdur.
**
**  Inputs:      minp -- minimum value of rainfall rate p (default 0)
**               mind -- minimum storm depth to produce runoff (default 0)
**               tm -- current time in simulation
**  Members updated:  p, stdur, istdur take on new random values (if optVar)
**                    pMean, stdurMean, istdurMean adjusted (if optSinVar)
**  Assumptions:  pMean > 0
**
**  Modifications:
**   - changed AND to OR in while loop, GT 5/99
**   - added to while loop an additional check to see if time has run out,
**     NG 2/00
**   - added output of time, storm intensity, & duration to ".storm" file
**     GT 3/00
**
\**************************************************************************/
void tStorm::GenerateStorm( double tm, double minp, double mind )
{
   // If option for sinusoidal variation is on, adjust the means
   // Also set values for current storm to the means, in case option for
   // random storms is off.
   if( optSinVar )
   {
      double sinfn = sin( tm*twoPiLam );
      pMean = p0 + pdev*sinfn;
      //cout << "pMean = " << pMean << endl;
      stdurMean = stdur0 + stdurdev*sinfn;
      istdurMean = istdur0 + istdurdev*sinfn;
      p = pMean;
      stdur = stdurMean;
      istdur = istdurMean;
   }

   // If option for random storms is on, pick a storm at random.
   // Keep picking and accumulating time until the storm depth or intensity
   // is greater than the minimum value needed to produce runoff.

   if( optVariable )
   {
      stdur = 0;
      istdur = 0;
      do
      {
         p = pMean*ExpDev( &seed );
         istdur += istdurMean*ExpDev( &seed ) + stdur;
         stdur = stdurMean*ExpDev( &seed );
         //cout << "P " << p << "  ST " << stdur << "  IST " << istdur
         //     << "  DP " << p*stdur << " minp " << minp << " mind " <<mind <<
         //            endl;
         //srand( seed );
      } while( (p<=minp || (p*stdur)<=mind) && (tm+istdur+stdur<endtm) );
      stormfile << istdur << " " << p << " " << stdur << endl;
   }
}

/**************************************************************************\
**
**  tStorm::ExpDev:  Finds a random number with an exponential distribution
**                   (adapted from Numerical Recipes).
**
\**************************************************************************/
double tStorm::ExpDev( long *idum )
{
    double dum;

    do
        dum = ran3( idum );
    while( dum==0.0 );
    return -log(dum);
}

/**************************************************************************\
**
**  tStorm "get" routines: return various variables
**
\**************************************************************************/

double tStorm::getStormDuration() { return stdur; }
double tStorm::interstormDur() { return istdur; }
double tStorm::getRainrate() { return p; }
double tStorm::getMeanStormDur() const {return stdurMean;}
double tStorm::getMeanInterstormDur() const {return istdurMean;}
double tStorm::getMeanPrecip() const {return pMean;}

/**************************************************************************\
**
**  GammaDev
**
**  Returns a random variable drawn from a Gamma distribution with parameter m.
**
**  (Note: not actually called; provided for future use).
**
\**************************************************************************/
double tStorm::GammaDev(double m, long * idum)
{
  double x, y,z, c,t,b,u,w,v;

  if (m<1)
    {
      c = 1/m;
      t = 0.07 + 0.75*sqrt(1-m);
      b = 1 + exp(-t)*m/t;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum);
          w = ran3(idum);
          v = b *u;
          if (v<=1)
            {
              x  = t * pow(v, c);
              accept = ((w<=((2-x)/(2+x))) || (w<=exp(-x)));
            }
          else
            {
              x = -log(c*t*(b-v));
              y = x/t;
              accept = (((w*(m + y - m*y)) <= 1) || (w<= ( pow(y, (m-1)))));
            }
        }
    }
  else
    {
      b = m-1;
      c = 3*m - 0.75;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum); v = ran3(idum);
          w = u* ( 1-u);
          y = sqrt(c/w) * (u - 0.5);
          x = b + y;
          if ( x>= 0)
            {
              z = 64*( pow(w,3))*v*v;
              accept = (z <= ( 1 - 2*y*y/x)) || ( log(z) <= (2*(b*log(x/b) - y)));
            }
        }
    }
  return x;
}

<|endoftext|>