<commit_before>#include "widget.h"

void MainWindow::CreateTrayIcon()
{
    QMenu* pTrayIconMenu = new QMenu(this);
    pTrayIconMenu->addAction(m_pOpenAction);
    pTrayIconMenu->addSeparator();
    pTrayIconMenu->addAction(m_pPostponeAction);
    pTrayIconMenu->addSeparator();
    pTrayIconMenu->addAction(m_pQuitAction);

    if(m_pTrayIcon)
    {
        m_pTrayIcon->setContextMenu(pTrayIconMenu);
    }
}

void MainWindow::SetTrayIcon(QString strIcon)
{
    if(strIcon != m_strSetTrayIcon && m_pTrayIcon)
    {
        QIcon icon(strIcon);
        m_pTrayIcon->setIcon(icon);
        m_pTrayIcon->setVisible(true);

        m_strSetTrayIcon = strIcon;
    }
}

void MainWindow::LoadSettings()
{
    m_pAppSettings = new QSettings(QCoreApplication::organizationName(), QCoreApplication::applicationName(), this);
    qDebug() << QCoreApplication::organizationName() << QCoreApplication::applicationName();

    UserTimeSettings::SetWorkTime_s(m_pAppSettings->value("work_time", UserTimeSettings::WorkTime_s()).toInt());
    UserTimeSettings::SetRestTime_s(m_pAppSettings->value("rest_time", UserTimeSettings::RestTime_s()).toInt());
    UserTimeSettings::SetToleranceTime_s(m_pAppSettings->value("tolerance_time", UserTimeSettings::ToleranceTime_s()).toInt());

    m_pOnTopAction->setChecked(m_pAppSettings->value("always_on_top", false).toBool());
    SetOnTop(m_pOnTopAction->isChecked());

    m_pOnStartUpAction->setChecked(m_pAppSettings->value("run_on_startup", false).toBool());
}

void MainWindow::CreateLayout()
{
    QVBoxLayout* pTimeLayout = new QVBoxLayout;

    // work spin box
    QHBoxLayout* pWorkLayout = new QHBoxLayout;
    QLabel* pWorkLabel = new QLabel(tr("Work time [mins]"));
    QSpinBox* pSpinWorkTime_s = new QSpinBox(this); // TODO - má tu být this? Nemá tu být některý child?
    pSpinWorkTime_s->setValue(UserTimeSettings::WorkTime_s() / 60);
    pSpinWorkTime_s->setMaximum(999);
    connect(pSpinWorkTime_s, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](const int &nNewValue) {
        UserTimeSettings::SetWorkTime_s(nNewValue * 60);
        m_pAppSettings->setValue("work_time", UserTimeSettings::WorkTime_s());
    });
    pWorkLayout->addWidget(pWorkLabel);
    pWorkLayout->addWidget(pSpinWorkTime_s);

    // rest spin box
    QHBoxLayout* pRestLayout = new QHBoxLayout;
    QLabel* pRestLabel = new QLabel(tr("Rest time [mins]"));
    QSpinBox* pSpinRestTime_s = new QSpinBox(this);
    pSpinRestTime_s->setValue(UserTimeSettings::RestTime_s() / 60);
    pSpinRestTime_s->setMaximum(999);
    connect(pSpinRestTime_s, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](const int &nNewValue) {
       UserTimeSettings::SetRestTime_s(nNewValue * 60);
       m_pAppSettings->setValue("rest_time", UserTimeSettings::RestTime_s());
    });
    pRestLayout->addWidget(pRestLabel);
    pRestLayout->addWidget(pSpinRestTime_s);

    // tolerance spin box
    QHBoxLayout* pToleranceLayout = new QHBoxLayout;
    QLabel* pToleranceLabel = new QLabel(tr("Tolerance time [s]"));
    QSpinBox* pSpinToleranceTime_s = new QSpinBox(this);
    pSpinToleranceTime_s->setValue(UserTimeSettings::ToleranceTime_s());
    pSpinToleranceTime_s->setMaximum(999);
    connect(pSpinToleranceTime_s, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](const int &nNewValue) {
       UserTimeSettings::SetToleranceTime_s(nNewValue);
       m_pAppSettings->setValue("tolerance_time", UserTimeSettings::ToleranceTime_s());

    });
    pToleranceLayout->addWidget(pToleranceLabel);
    pToleranceLayout->addWidget(pSpinToleranceTime_s);

    // add all to vertical layout
    pTimeLayout->addLayout(pWorkLayout);
    pTimeLayout->addLayout(pRestLayout);
    pTimeLayout->addLayout(pToleranceLayout);

    // add label with info
    m_pLabel = new QLabel;

    QVBoxLayout* pMainLayout = new QVBoxLayout;
    pMainLayout->addLayout(pTimeLayout);

    m_pPassedToleranceBar = new QProgressBar(this);
    m_pPassedToleranceBar->setMaximum(0);
    m_pPassedToleranceBar->setMaximum(UserTimeSettings::ToleranceTime_s() * 1000);
    m_pPassedToleranceBar->setTextVisible(false);

    pMainLayout->addWidget(m_pPassedToleranceBar);
    pMainLayout->addWidget(m_pLabel);

    QWidget* pWidget = new QWidget(this);
    pWidget->setLayout(pMainLayout);
    this->setCentralWidget(pWidget);
}

void MainWindow::CreateActions()
{
    m_pOpenAction = new QAction(tr("&Open"), this);
    connect(m_pOpenAction, &QAction::triggered, this, &MainWindow::OpenWindow);

    m_pPostponeAction = new QAction(tr("&Add 5 mins"), this);
    m_pPostponeAction->setCheckable(true);
    connect(m_pPostponeAction, &QAction::triggered, this, &MainWindow::PostponeTheBreak);

    m_pAboutAction = new QAction(tr("A&bout..."), this);
    connect(m_pAboutAction, &QAction::triggered, qApp, &QApplication::aboutQt); // NOTE - change to about App

    m_pQuitAction = new QAction(tr("Really &quit"), this);
    connect(m_pQuitAction, &QAction::triggered, qApp, &QCoreApplication::quit);

    m_pOnTopAction = new QAction(tr("Always on &top"), this);
    m_pOnTopAction->setCheckable(true);
    connect(m_pOnTopAction, &QAction::triggered, [&](bool bOnTop) {
        m_pAppSettings->setValue("always_on_top", bOnTop);
        SetOnTop(bOnTop);
    });

    m_pOnStartUpAction = new QAction(tr("Run on &startup"), this);
    m_pOnStartUpAction->setCheckable(true);
    connect(m_pOnStartUpAction, &QAction::triggered, [&](bool bRunOnStartUp) {
        m_pAppSettings->setValue("run_on_startup", bRunOnStartUp);
        SetOnStartUp(bRunOnStartUp);
    });
}

void MainWindow::CreateMenu()
{
    m_pAppMenu = menuBar()->addMenu(tr("&App"));
    m_pAppMenu->addAction(m_pPostponeAction);
    m_pAppMenu->addSeparator();
    m_pAppMenu->addAction(m_pAboutAction);
    m_pAppMenu->addSeparator();
    m_pAppMenu->addAction(m_pQuitAction);

    m_pOptionsMenu = menuBar()->addMenu(tr("&Options"));
    m_pOptionsMenu->addAction(m_pOnTopAction);
    m_pOptionsMenu->addAction(m_pOnStartUpAction);
}

void MainWindow::OpenWindow()
{
    this->setWindowState(this->windowState() & ~Qt::WindowMinimized);
    this->show();
    this->activateWindow();
}

void MainWindow::PostponeTheBreak()
{
    m_pPostponeAction->setEnabled(false);
    m_nExtraWorkTime_ms = UserTimeSettings::ExtraWorkTime_s() * 1000;
}

void MainWindow::SetOnTop(bool bOnTop)
{
    if(bOnTop)
    {
        this->setWindowFlags(Qt::WindowStaysOnTopHint);
    }
    else
    {
        this->setWindowFlags(this->windowFlags() & (~Qt::WindowStaysOnTopHint));
    }
    this->show();
    this->activateWindow();
}

void MainWindow::SetOnStartUp(bool bRunOnStartUp)
{
    QSettings oSettings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    if (bRunOnStartUp)
    {
        const QString strNativeBinPath = QDir::toNativeSeparators(qApp->applicationFilePath());
        oSettings.setValue(QCoreApplication::applicationName(), strNativeBinPath);
    }
    else
    {
        oSettings.remove(QCoreApplication::applicationName());
    }
}

void MainWindow::SetIconByTime()
{
    int nWorkTime_ms = UserTimeSettings::WorkTime_s() * 1000 + m_nExtraWorkTime_ms;
    if(m_pLastUserInput->UserActiveTime_ms() > nWorkTime_ms)
    {
        SetTrayIcon(":/stop_icon.png");
    }
    else if(m_pLastUserInput->UserActiveTime_ms() < nWorkTime_ms &&  m_pLastUserInput->UserActiveTime_ms() > (nWorkTime_ms - UserTimeSettings::WarningTime_s()) * 1000)
    {
        SetTrayIcon(":/ready_icon.png");
    }
    else if(m_pLastUserInput->UserIdleTime_ms() > UserTimeSettings::RestTime_s())
    {
        SetTrayIcon(":/go_icon.png");
    }
}

MainWindow::MainWindow(QMainWindow *parent) : QMainWindow(parent)
{
    m_pLastUserInput = new UserInputWatcher(new SystemInput());

    m_pTrayIcon = new QSystemTrayIcon(this);

    CreateActions();
    CreateTrayIcon();
    SetTrayIcon(":/go_icon.png");

    LoadSettings();
    CreateLayout();
    CreateMenu();

    if(QSystemTrayIcon::isSystemTrayAvailable())
    {
        qDebug() << "tray is avaible";
    }

    connect(m_pTrayIcon, &QSystemTrayIcon::activated, [&](QSystemTrayIcon::ActivationReason eReason) {
        qDebug() << eReason;
        switch (eReason) {
        case QSystemTrayIcon::DoubleClick:
        case QSystemTrayIcon::Trigger:
            OpenWindow();
            break;
        default:
            break;
        }
    });

    connect(&m_oBeepTimer, &QTimer::timeout, [&]() {
        int nWorkTime_ms = UserTimeSettings::WorkTime_s() * 1000 + m_nExtraWorkTime_ms;
        if(m_pLastUserInput->UserActiveTime_ms() > nWorkTime_ms && m_pLastUserInput->PassedTolerance_ms() > 0)
        {
            QApplication::beep();
        }
    });

    connect(&m_oTimer, &QTimer::timeout, [&]() {

        SetIconByTime();
        m_pLastUserInput->UpdateLastUserInput();

        m_pPassedToleranceBar->setValue(m_pLastUserInput->PassedTolerance_ms() > m_pPassedToleranceBar->maximum() ? m_pPassedToleranceBar->maximum() : m_pLastUserInput->PassedTolerance_ms());

        m_pLabel->setText(QString("User idle time\t\t%1\nUser active time\t\t%2")
                          .arg(TimeFormat::GetMinsAndSeconds(m_pLastUserInput->UserIdleTime_ms()))
                          .arg(TimeFormat::GetMinsAndSeconds(m_pLastUserInput->UserActiveTime_ms())));

        m_pTrayIcon->setToolTip(QString(tr("Work time is %1 mins")).arg(TimeFormat::GetMins(m_pLastUserInput->UserActiveTime_ms())));

    });

    connect(m_pLastUserInput, &UserInputWatcher::NewWorkPeriod, [&]() {
        m_pPostponeAction->setEnabled(true);
        m_nExtraWorkTime_ms = 0;
    });

    m_oTimer.start(100);
    m_oBeepTimer.start(1100);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(m_pTrayIcon->isVisible())
    {
        hide();
        event->ignore();
    }
}
<commit_msg>fix in unchecking action after break time<commit_after>#include "widget.h"

void MainWindow::CreateTrayIcon()
{
    QMenu* pTrayIconMenu = new QMenu(this);
    pTrayIconMenu->addAction(m_pOpenAction);
    pTrayIconMenu->addSeparator();
    pTrayIconMenu->addAction(m_pPostponeAction);
    pTrayIconMenu->addSeparator();
    pTrayIconMenu->addAction(m_pQuitAction);

    if(m_pTrayIcon)
    {
        m_pTrayIcon->setContextMenu(pTrayIconMenu);
    }
}

void MainWindow::SetTrayIcon(QString strIcon)
{
    if(strIcon != m_strSetTrayIcon && m_pTrayIcon)
    {
        QIcon icon(strIcon);
        m_pTrayIcon->setIcon(icon);
        m_pTrayIcon->setVisible(true);

        m_strSetTrayIcon = strIcon;
    }
}

void MainWindow::LoadSettings()
{
    m_pAppSettings = new QSettings(QCoreApplication::organizationName(), QCoreApplication::applicationName(), this);
    qDebug() << QCoreApplication::organizationName() << QCoreApplication::applicationName();

    UserTimeSettings::SetWorkTime_s(m_pAppSettings->value("work_time", UserTimeSettings::WorkTime_s()).toInt());
    UserTimeSettings::SetRestTime_s(m_pAppSettings->value("rest_time", UserTimeSettings::RestTime_s()).toInt());
    UserTimeSettings::SetToleranceTime_s(m_pAppSettings->value("tolerance_time", UserTimeSettings::ToleranceTime_s()).toInt());

    m_pOnTopAction->setChecked(m_pAppSettings->value("always_on_top", false).toBool());
    SetOnTop(m_pOnTopAction->isChecked());

    m_pOnStartUpAction->setChecked(m_pAppSettings->value("run_on_startup", false).toBool());
}

void MainWindow::CreateLayout()
{
    QVBoxLayout* pTimeLayout = new QVBoxLayout;

    // work spin box
    QHBoxLayout* pWorkLayout = new QHBoxLayout;
    QLabel* pWorkLabel = new QLabel(tr("Work time [mins]"));
    QSpinBox* pSpinWorkTime_s = new QSpinBox(this); // TODO - má tu být this? Nemá tu být některý child?
    pSpinWorkTime_s->setValue(UserTimeSettings::WorkTime_s() / 60);
    pSpinWorkTime_s->setMaximum(999);
    connect(pSpinWorkTime_s, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](const int &nNewValue) {
        UserTimeSettings::SetWorkTime_s(nNewValue * 60);
        m_pAppSettings->setValue("work_time", UserTimeSettings::WorkTime_s());
    });
    pWorkLayout->addWidget(pWorkLabel);
    pWorkLayout->addWidget(pSpinWorkTime_s);

    // rest spin box
    QHBoxLayout* pRestLayout = new QHBoxLayout;
    QLabel* pRestLabel = new QLabel(tr("Rest time [mins]"));
    QSpinBox* pSpinRestTime_s = new QSpinBox(this);
    pSpinRestTime_s->setValue(UserTimeSettings::RestTime_s() / 60);
    pSpinRestTime_s->setMaximum(999);
    connect(pSpinRestTime_s, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](const int &nNewValue) {
       UserTimeSettings::SetRestTime_s(nNewValue * 60);
       m_pAppSettings->setValue("rest_time", UserTimeSettings::RestTime_s());
    });
    pRestLayout->addWidget(pRestLabel);
    pRestLayout->addWidget(pSpinRestTime_s);

    // tolerance spin box
    QHBoxLayout* pToleranceLayout = new QHBoxLayout;
    QLabel* pToleranceLabel = new QLabel(tr("Tolerance time [s]"));
    QSpinBox* pSpinToleranceTime_s = new QSpinBox(this);
    pSpinToleranceTime_s->setValue(UserTimeSettings::ToleranceTime_s());
    pSpinToleranceTime_s->setMaximum(999);
    connect(pSpinToleranceTime_s, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](const int &nNewValue) {
       UserTimeSettings::SetToleranceTime_s(nNewValue);
       m_pAppSettings->setValue("tolerance_time", UserTimeSettings::ToleranceTime_s());

    });
    pToleranceLayout->addWidget(pToleranceLabel);
    pToleranceLayout->addWidget(pSpinToleranceTime_s);

    // add all to vertical layout
    pTimeLayout->addLayout(pWorkLayout);
    pTimeLayout->addLayout(pRestLayout);
    pTimeLayout->addLayout(pToleranceLayout);

    // add label with info
    m_pLabel = new QLabel;

    QVBoxLayout* pMainLayout = new QVBoxLayout;
    pMainLayout->addLayout(pTimeLayout);

    m_pPassedToleranceBar = new QProgressBar(this);
    m_pPassedToleranceBar->setMaximum(0);
    m_pPassedToleranceBar->setMaximum(UserTimeSettings::ToleranceTime_s() * 1000);
    m_pPassedToleranceBar->setTextVisible(false);

    pMainLayout->addWidget(m_pPassedToleranceBar);
    pMainLayout->addWidget(m_pLabel);

    QWidget* pWidget = new QWidget(this);
    pWidget->setLayout(pMainLayout);
    this->setCentralWidget(pWidget);
}

void MainWindow::CreateActions()
{
    m_pOpenAction = new QAction(tr("&Open"), this);
    connect(m_pOpenAction, &QAction::triggered, this, &MainWindow::OpenWindow);

    m_pPostponeAction = new QAction(tr("&Add 5 mins"), this);
    m_pPostponeAction->setCheckable(true);
    connect(m_pPostponeAction, &QAction::triggered, this, &MainWindow::PostponeTheBreak);

    m_pAboutAction = new QAction(tr("A&bout..."), this);
    connect(m_pAboutAction, &QAction::triggered, qApp, &QApplication::aboutQt); // NOTE - change to about App

    m_pQuitAction = new QAction(tr("Really &quit"), this);
    connect(m_pQuitAction, &QAction::triggered, qApp, &QCoreApplication::quit);

    m_pOnTopAction = new QAction(tr("Always on &top"), this);
    m_pOnTopAction->setCheckable(true);
    connect(m_pOnTopAction, &QAction::triggered, [&](bool bOnTop) {
        m_pAppSettings->setValue("always_on_top", bOnTop);
        SetOnTop(bOnTop);
    });

    m_pOnStartUpAction = new QAction(tr("Run on &startup"), this);
    m_pOnStartUpAction->setCheckable(true);
    connect(m_pOnStartUpAction, &QAction::triggered, [&](bool bRunOnStartUp) {
        m_pAppSettings->setValue("run_on_startup", bRunOnStartUp);
        SetOnStartUp(bRunOnStartUp);
    });
}

void MainWindow::CreateMenu()
{
    m_pAppMenu = menuBar()->addMenu(tr("&App"));
    m_pAppMenu->addAction(m_pPostponeAction);
    m_pAppMenu->addSeparator();
    m_pAppMenu->addAction(m_pAboutAction);
    m_pAppMenu->addSeparator();
    m_pAppMenu->addAction(m_pQuitAction);

    m_pOptionsMenu = menuBar()->addMenu(tr("&Options"));
    m_pOptionsMenu->addAction(m_pOnTopAction);
    m_pOptionsMenu->addAction(m_pOnStartUpAction);
}

void MainWindow::OpenWindow()
{
    this->setWindowState(this->windowState() & ~Qt::WindowMinimized);
    this->show();
    this->activateWindow();
}

void MainWindow::PostponeTheBreak()
{
    m_pPostponeAction->setEnabled(false);
    m_nExtraWorkTime_ms = UserTimeSettings::ExtraWorkTime_s() * 1000;
}

void MainWindow::SetOnTop(bool bOnTop)
{
    if(bOnTop)
    {
        this->setWindowFlags(Qt::WindowStaysOnTopHint);
    }
    else
    {
        this->setWindowFlags(this->windowFlags() & (~Qt::WindowStaysOnTopHint));
    }
    this->show();
    this->activateWindow();
}

void MainWindow::SetOnStartUp(bool bRunOnStartUp)
{
    QSettings oSettings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    if (bRunOnStartUp)
    {
        const QString strNativeBinPath = QDir::toNativeSeparators(qApp->applicationFilePath());
        oSettings.setValue(QCoreApplication::applicationName(), strNativeBinPath);
    }
    else
    {
        oSettings.remove(QCoreApplication::applicationName());
    }
}

void MainWindow::SetIconByTime()
{
    int nWorkTime_ms = UserTimeSettings::WorkTime_s() * 1000 + m_nExtraWorkTime_ms;
    if(m_pLastUserInput->UserActiveTime_ms() > nWorkTime_ms)
    {
        SetTrayIcon(":/stop_icon.png");
    }
    else if(m_pLastUserInput->UserActiveTime_ms() < nWorkTime_ms &&  m_pLastUserInput->UserActiveTime_ms() > (nWorkTime_ms - UserTimeSettings::WarningTime_s()) * 1000)
    {
        SetTrayIcon(":/ready_icon.png");
    }
    else if(m_pLastUserInput->UserIdleTime_ms() > UserTimeSettings::RestTime_s())
    {
        SetTrayIcon(":/go_icon.png");
    }
}

MainWindow::MainWindow(QMainWindow *parent) : QMainWindow(parent)
{
    m_pLastUserInput = new UserInputWatcher(new SystemInput());

    m_pTrayIcon = new QSystemTrayIcon(this);

    CreateActions();
    CreateTrayIcon();
    SetTrayIcon(":/go_icon.png");

    LoadSettings();
    CreateLayout();
    CreateMenu();

    if(QSystemTrayIcon::isSystemTrayAvailable())
    {
        qDebug() << "tray is avaible";
    }

    connect(m_pTrayIcon, &QSystemTrayIcon::activated, [&](QSystemTrayIcon::ActivationReason eReason) {
        qDebug() << eReason;
        switch (eReason) {
        case QSystemTrayIcon::DoubleClick:
        case QSystemTrayIcon::Trigger:
            OpenWindow();
            break;
        default:
            break;
        }
    });

    connect(&m_oBeepTimer, &QTimer::timeout, [&]() {
        int nWorkTime_ms = UserTimeSettings::WorkTime_s() * 1000 + m_nExtraWorkTime_ms;
        if(m_pLastUserInput->UserActiveTime_ms() > nWorkTime_ms && m_pLastUserInput->PassedTolerance_ms() > 0)
        {
            QApplication::beep();
        }
    });

    connect(&m_oTimer, &QTimer::timeout, [&]() {

        SetIconByTime();
        m_pLastUserInput->UpdateLastUserInput();

        m_pPassedToleranceBar->setValue(m_pLastUserInput->PassedTolerance_ms() > m_pPassedToleranceBar->maximum() ? m_pPassedToleranceBar->maximum() : m_pLastUserInput->PassedTolerance_ms());

        m_pLabel->setText(QString("User idle time\t\t%1\nUser active time\t\t%2")
                          .arg(TimeFormat::GetMinsAndSeconds(m_pLastUserInput->UserIdleTime_ms()))
                          .arg(TimeFormat::GetMinsAndSeconds(m_pLastUserInput->UserActiveTime_ms())));

        m_pTrayIcon->setToolTip(QString(tr("Work time is %1 mins")).arg(TimeFormat::GetMins(m_pLastUserInput->UserActiveTime_ms())));

    });

    connect(m_pLastUserInput, &UserInputWatcher::NewWorkPeriod, [&]() {
        m_pPostponeAction->setEnabled(true);
        m_pPostponeAction->setChecked(false);
        m_nExtraWorkTime_ms = 0;
    });

    m_oTimer.start(100);
    m_oBeepTimer.start(1100);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(m_pTrayIcon->isVisible())
    {
        hide();
        event->ignore();
    }
}
<|endoftext|>


<commit_before>#include "stdafx.h"

#include "UIControlSystem.h"
#include "UIControl.h"

#include "Core.h"
#include "Applications/ApplicationBase.h"
#include "Render/RenderWorld.h"

#include "PropertyReaders.h"

#include "Input/InputSystem.h"
#include "Input/InputSubscriber.h"

namespace SDK
{
	namespace UI
	{
		UIControlSystem g_ui_system;

		class UIControlSystem::UI_InputSubscriber : public InputSubscriber
		{
		private:
			UIControlSystem& m_system;

		public:
			UI_InputSubscriber(UIControlSystem& i_system)
				: m_system(i_system)
			{
				InputSystem::Instance().SetUISubscriber(this);
			}
			virtual ~UI_InputSubscriber()
			{
				InputSystem::Instance().SetUISubscriber(nullptr);
			}

			virtual bool KeyPressed(const KeyEvent& i_evt) override
			{
				return false;
			}
			virtual bool KeyReleased(const KeyEvent& i_evt) override
			{
				return false;
			}

			virtual bool MouseMoved(const MouseEvent& i_evt) override
			{
				return false;
			}
			virtual bool MousePressed(const MouseEvent& i_evt) override
			{
				return false;
			}
			virtual bool MouseReleased(const MouseEvent& i_evt) override
			{
				auto& controls = g_ui_system.m_controls;
				for (auto& control : controls)
				{
					if (control.second == nullptr)
						continue;
					if (control.second->IsHited({ i_evt.m_x, i_evt.m_y }))
					{
						// TODO: need to return true/false based on HandleMessage result
						g_ui_system.GetMessageDispatcher().HandleMessage(UIEvent{ UIEventType::ButtonPressed }, control.second->GetName());
						return true;
					}
				}
				return false;
			}
		};

		namespace detail { extern void RegisterBaseUITypes(UIControlSystem&); }

		UIControlSystem::UIControlSystem()
			: m_current_scheme(INVALID_UISCHEME_HANDLER)
		{
			detail::RegisterBaseUITypes(*this);
		}

		UIControlSystem::~UIControlSystem()
		{
			for (auto& control : m_controls)
			{
				if (control.second == nullptr)
					continue;
				control.second->SetParent(INVALID_UI_HANDLER);
			}
			m_controls.clear();
		}

		UIControlHandler UIControlSystem::GetHandlerTo(UIControl* ip_pointer) const
		{
			auto it = std::find_if(m_controls.begin(), m_controls.end(), [ip_pointer](const UIControlPair& control)
			{
				return control.second != nullptr && control.second.get() == ip_pointer;
			});
			if (it == m_controls.end())
				return INVALID_UI_HANDLER;
			return it->first;
		}

		UIControl* UIControlSystem::AccessControl(UIControlHandler i_handler) const
		{
			if (!IsValid(i_handler, m_controls))
				return nullptr;

			return m_controls[i_handler.index].second.get();
		}

		void UIControlSystem::Update(float i_elapsed_time)
		{
			if (m_current_scheme == INVALID_UISCHEME_HANDLER)
				return;

			UIScheme& current = m_schemes[m_current_scheme.index];

			for (auto& handler : current.m_handlers)
			{
				auto& control = m_controls[handler.index];
				if (control.second == nullptr)
					continue;
				// control is updated from parent
				if (control.second->GetParent() != INVALID_UI_HANDLER)
					continue;
				control.second->Update(i_elapsed_time);
			}
		}

		void UIControlSystem::Draw()
		{
			if (m_current_scheme == INVALID_UISCHEME_HANDLER)
				return;

			UIScheme& current = m_schemes[m_current_scheme.index];

			for (auto& handler : current.m_handlers)
			{
				auto& control = m_controls[handler.index];
				if (control.second == nullptr)
					continue;
				// control is updated from parent
				if (control.second->GetParent() != INVALID_UI_HANDLER)
					continue;
				control.second->Draw();
			}

			auto& render_world = Core::GetApplication()->GetRenderWorld();
			render_world.Submit({Render::ProjectionType::Orthographic, Matrix4f::IDENTITY, Matrix4f::IDENTITY });
		}

		void UIControlSystem::SetInputSystem(InputSystem& i_input_system)
		{
			static UI_InputSubscriber g_subscriber(*this);
		}

		void UIControlSystem::OnResize(const IRect& i_new_size)
		{
			for (auto& control : m_controls)
			{
				if (control.second == nullptr)
					continue;
				control.second->OnResize(i_new_size);
			}
		}

		void UIControlSystem::RemoveControl(UIControlHandler i_handler)
		{
			if (!IsValid(i_handler, m_controls))
				return;

			m_controls[i_handler.index].second.release();
			m_controls[i_handler.index].first.index = -1;
		}

		void AddControlElement(UIControlSystem::UIScheme& o_scheme, const PropertyElement::iterator<PropertyElement>& i_it, UIControlHandler i_parent = INVALID_UI_HANDLER)
		{
			// type of control
			auto type = i_it.element_name();
			const PropertyElement& element = *i_it;
			UIControlSystem::UIControlAccessor<UIControl> accessor = g_ui_system.GetFactory().Create(type);

			if (!accessor.IsValid())
				return;

			if (i_parent != INVALID_UI_HANDLER)
				accessor.GetActual()->SetParent(i_parent);

			o_scheme.AddControl(accessor.GetHandler());

			const auto end = element.end<PropertyElement>();
			for (auto it = element.begin<PropertyElement>(); it != end; ++it)
				AddControlElement(o_scheme, it, accessor.GetHandler());
		}

		UISchemeHandler UIControlSystem::LoadScheme(const std::string& i_file_name)
		{
			PropretyReader<(int)ReaderType::SDKFormat> reader;
			PropertyElement root = reader.Parse(i_file_name);

			std::string scheme_name = root.GetValue<std::string>("name");
			const size_t hash = Utilities::hash_function(scheme_name);

			// validate scheme name and existance in UISystem
			{
				if (scheme_name.empty())
				{
					assert(false && "Scheme name is empty");
					return INVALID_UISCHEME_HANDLER;
				}

				UISchemeHandler test_handler = FindScheme(Utilities::hash_function(scheme_name));
				if (test_handler != INVALID_UISCHEME_HANDLER)
				{
					assert(false && "Scheme with same name already exist");
					return INVALID_UISCHEME_HANDLER;
				}
			}

			UISchemeHandler scheme_handler{ static_cast<int>(m_schemes.size()), 0 };
			// find empty slot
			{
				for (size_t i = 0; i < m_schemes.size(); ++i)
				{
					auto& scheme = m_schemes[i];
					if (scheme.m_handler.index == -1)
					{
						scheme_handler = { static_cast<int>(i), scheme.m_handler.generation + 1 };
						break;
					}
				}
			}

			UIScheme scheme(scheme_name, hash, scheme_handler);

			const auto end = root.end<PropertyElement>();
			for (auto it = root.begin<PropertyElement>(); it != end; ++it)
				AddControlElement(scheme, it);

			// free slots not found -> push back new
			if (scheme_handler.index == m_schemes.size())
				m_schemes.push_back(scheme);
			else
				m_schemes[scheme_handler.index] = scheme;

			return scheme_handler;
		}

		UISchemeHandler UIControlSystem::FindScheme(size_t i_hash)
		{
			auto it = std::find_if(m_schemes.begin(), m_schemes.end(), [i_hash](const UIScheme& scheme)
			{
				return scheme.GetHandler().index != -1 && scheme.GetHash() == i_hash;
			});
			if (it == m_schemes.end())
				return INVALID_UISCHEME_HANDLER;
			else
				return it->GetHandler();
		}

		void UIControlSystem::SetActiveScheme(const std::string& i_scheme_name)
		{
			m_current_scheme = FindScheme(Utilities::hash_function(i_scheme_name));
		}

		void UIControlSystem::SetActiveScheme(UISchemeHandler i_scheme)
		{
			auto it = std::find_if(m_schemes.begin(), m_schemes.end(), [i_scheme](const UIScheme& scheme)
			{
				return scheme.GetHandler() == i_scheme;
			});
			if (it == m_schemes.end())
				m_current_scheme = INVALID_UISCHEME_HANDLER;
			else
				m_current_scheme = it->GetHandler();
		}

		void UIControlSystem::UnloadScheme(UISchemeHandler i_scheme)
		{
			if (i_scheme == INVALID_UISCHEME_HANDLER)
				return;

			UIScheme& current = m_schemes[i_scheme.index];

			for (auto& handler : current.m_handlers)
				RemoveControl(handler);

			if (m_current_scheme == current.m_handler)
				m_current_scheme = INVALID_UISCHEME_HANDLER;

			current.m_handler.index = -1;
		}

		void UIControlSystem::UnloadScheme(const std::string& i_scheme)
		{
			UnloadScheme(FindScheme(Utilities::hash_function(i_scheme)));
		}

		const UIControlSystem::UIScheme* UIControlSystem::AccessScheme(UISchemeHandler i_scheme) const
		{
			if (i_scheme.index == -1 || static_cast<int>(m_schemes.size()) <= i_scheme.index)
				return nullptr;

			return &m_schemes[i_scheme.index];
		}

	} // UI
} // SDK<commit_msg>[Core-UI] Load elements after it creation. Good practice...<commit_after>#include "stdafx.h"

#include "UIControlSystem.h"
#include "UIControl.h"

#include "Core.h"
#include "Applications/ApplicationBase.h"
#include "Render/RenderWorld.h"

#include "PropertyReaders.h"

#include "Input/InputSystem.h"
#include "Input/InputSubscriber.h"

namespace SDK
{
	namespace UI
	{
		UIControlSystem g_ui_system;

		class UIControlSystem::UI_InputSubscriber : public InputSubscriber
		{
		private:
			UIControlSystem& m_system;

		public:
			UI_InputSubscriber(UIControlSystem& i_system)
				: m_system(i_system)
			{
				InputSystem::Instance().SetUISubscriber(this);
			}
			virtual ~UI_InputSubscriber()
			{
				InputSystem::Instance().SetUISubscriber(nullptr);
			}

			virtual bool KeyPressed(const KeyEvent& i_evt) override
			{
				return false;
			}
			virtual bool KeyReleased(const KeyEvent& i_evt) override
			{
				return false;
			}

			virtual bool MouseMoved(const MouseEvent& i_evt) override
			{
				return false;
			}
			virtual bool MousePressed(const MouseEvent& i_evt) override
			{
				return false;
			}
			virtual bool MouseReleased(const MouseEvent& i_evt) override
			{
				auto& controls = g_ui_system.m_controls;
				for (auto& control : controls)
				{
					if (control.second == nullptr)
						continue;
					if (control.second->IsHited({ i_evt.m_x, i_evt.m_y }))
					{
						// TODO: need to return true/false based on HandleMessage result
						g_ui_system.GetMessageDispatcher().HandleMessage(UIEvent{ UIEventType::ButtonPressed }, control.second->GetName());
						return true;
					}
				}
				return false;
			}
		};

		namespace detail { extern void RegisterBaseUITypes(UIControlSystem&); }

		UIControlSystem::UIControlSystem()
			: m_current_scheme(INVALID_UISCHEME_HANDLER)
		{
			detail::RegisterBaseUITypes(*this);
		}

		UIControlSystem::~UIControlSystem()
		{
			for (auto& control : m_controls)
			{
				if (control.second == nullptr)
					continue;
				control.second->SetParent(INVALID_UI_HANDLER);
			}
			m_controls.clear();
		}

		UIControlHandler UIControlSystem::GetHandlerTo(UIControl* ip_pointer) const
		{
			auto it = std::find_if(m_controls.begin(), m_controls.end(), [ip_pointer](const UIControlPair& control)
			{
				return control.second != nullptr && control.second.get() == ip_pointer;
			});
			if (it == m_controls.end())
				return INVALID_UI_HANDLER;
			return it->first;
		}

		UIControl* UIControlSystem::AccessControl(UIControlHandler i_handler) const
		{
			if (!IsValid(i_handler, m_controls))
				return nullptr;

			return m_controls[i_handler.index].second.get();
		}

		void UIControlSystem::Update(float i_elapsed_time)
		{
			if (m_current_scheme == INVALID_UISCHEME_HANDLER)
				return;

			UIScheme& current = m_schemes[m_current_scheme.index];

			for (auto& handler : current.m_handlers)
			{
				auto& control = m_controls[handler.index];
				if (control.second == nullptr)
					continue;
				// control is updated from parent
				if (control.second->GetParent() != INVALID_UI_HANDLER)
					continue;
				control.second->Update(i_elapsed_time);
			}
		}

		void UIControlSystem::Draw()
		{
			if (m_current_scheme == INVALID_UISCHEME_HANDLER)
				return;

			UIScheme& current = m_schemes[m_current_scheme.index];

			for (auto& handler : current.m_handlers)
			{
				auto& control = m_controls[handler.index];
				if (control.second == nullptr)
					continue;
				// control is updated from parent
				if (control.second->GetParent() != INVALID_UI_HANDLER)
					continue;
				control.second->Draw();
			}

			auto& render_world = Core::GetApplication()->GetRenderWorld();
			render_world.Submit({Render::ProjectionType::Orthographic, Matrix4f::IDENTITY, Matrix4f::IDENTITY });
		}

		void UIControlSystem::SetInputSystem(InputSystem& i_input_system)
		{
			static UI_InputSubscriber g_subscriber(*this);
		}

		void UIControlSystem::OnResize(const IRect& i_new_size)
		{
			for (auto& control : m_controls)
			{
				if (control.second == nullptr)
					continue;
				control.second->OnResize(i_new_size);
			}
		}

		void UIControlSystem::RemoveControl(UIControlHandler i_handler)
		{
			if (!IsValid(i_handler, m_controls))
				return;

			m_controls[i_handler.index].second.release();
			m_controls[i_handler.index].first.index = -1;
		}

		void AddControlElement(UIControlSystem::UIScheme& o_scheme, const PropertyElement::iterator<PropertyElement>& i_it, UIControlHandler i_parent = INVALID_UI_HANDLER)
		{
			// type of control
			auto type = i_it.element_name();
			const PropertyElement& element = *i_it;
			UIControlSystem::UIControlAccessor<UIControl> accessor = g_ui_system.GetFactory().Create(type);

			if (!accessor.IsValid())
				return;

			accessor.GetActual()->Load(element);

			if (i_parent != INVALID_UI_HANDLER)
				accessor.GetActual()->SetParent(i_parent);

			o_scheme.AddControl(accessor.GetHandler());

			const auto end = element.end<PropertyElement>();
			for (auto it = element.begin<PropertyElement>(); it != end; ++it)
				AddControlElement(o_scheme, it, accessor.GetHandler());
		}

		UISchemeHandler UIControlSystem::LoadScheme(const std::string& i_file_name)
		{
			PropretyReader<(int)ReaderType::SDKFormat> reader;
			PropertyElement root = reader.Parse(i_file_name);

			std::string scheme_name = root.GetValue<std::string>("name");
			const size_t hash = Utilities::hash_function(scheme_name);

			// validate scheme name and existance in UISystem
			{
				if (scheme_name.empty())
				{
					assert(false && "Scheme name is empty");
					return INVALID_UISCHEME_HANDLER;
				}

				UISchemeHandler test_handler = FindScheme(Utilities::hash_function(scheme_name));
				if (test_handler != INVALID_UISCHEME_HANDLER)
				{
					assert(false && "Scheme with same name already exist");
					return INVALID_UISCHEME_HANDLER;
				}
			}

			UISchemeHandler scheme_handler{ static_cast<int>(m_schemes.size()), 0 };
			// find empty slot
			{
				for (size_t i = 0; i < m_schemes.size(); ++i)
				{
					auto& scheme = m_schemes[i];
					if (scheme.m_handler.index == -1)
					{
						scheme_handler = { static_cast<int>(i), scheme.m_handler.generation + 1 };
						break;
					}
				}
			}

			UIScheme scheme(scheme_name, hash, scheme_handler);

			const auto end = root.end<PropertyElement>();
			for (auto it = root.begin<PropertyElement>(); it != end; ++it)
				AddControlElement(scheme, it);

			// free slots not found -> push back new
			if (scheme_handler.index == m_schemes.size())
				m_schemes.push_back(scheme);
			else
				m_schemes[scheme_handler.index] = scheme;

			return scheme_handler;
		}

		UISchemeHandler UIControlSystem::FindScheme(size_t i_hash)
		{
			auto it = std::find_if(m_schemes.begin(), m_schemes.end(), [i_hash](const UIScheme& scheme)
			{
				return scheme.GetHandler().index != -1 && scheme.GetHash() == i_hash;
			});
			if (it == m_schemes.end())
				return INVALID_UISCHEME_HANDLER;
			else
				return it->GetHandler();
		}

		void UIControlSystem::SetActiveScheme(const std::string& i_scheme_name)
		{
			m_current_scheme = FindScheme(Utilities::hash_function(i_scheme_name));
		}

		void UIControlSystem::SetActiveScheme(UISchemeHandler i_scheme)
		{
			auto it = std::find_if(m_schemes.begin(), m_schemes.end(), [i_scheme](const UIScheme& scheme)
			{
				return scheme.GetHandler() == i_scheme;
			});
			if (it == m_schemes.end())
				m_current_scheme = INVALID_UISCHEME_HANDLER;
			else
				m_current_scheme = it->GetHandler();
		}

		void UIControlSystem::UnloadScheme(UISchemeHandler i_scheme)
		{
			if (i_scheme == INVALID_UISCHEME_HANDLER)
				return;

			UIScheme& current = m_schemes[i_scheme.index];

			for (auto& handler : current.m_handlers)
				RemoveControl(handler);

			if (m_current_scheme == current.m_handler)
				m_current_scheme = INVALID_UISCHEME_HANDLER;

			current.m_handler.index = -1;
		}

		void UIControlSystem::UnloadScheme(const std::string& i_scheme)
		{
			UnloadScheme(FindScheme(Utilities::hash_function(i_scheme)));
		}

		const UIControlSystem::UIScheme* UIControlSystem::AccessScheme(UISchemeHandler i_scheme) const
		{
			if (i_scheme.index == -1 || static_cast<int>(m_schemes.size()) <= i_scheme.index)
				return nullptr;

			return &m_schemes[i_scheme.index];
		}

	} // UI
} // SDK<|endoftext|>


<commit_before>#include <random>
#include "epidemic.hpp"
#include "WattsStrogatzModel.hpp"
#include "MLCG.h"
#include "NegExp.h"
#include "tclap/ValueArg.h"

#define NEG_EXP_OFFSET 50

WARPED_REGISTER_POLYMORPHIC_SERIALIZABLE_CLASS(EpidemicEvent)

std::vector<std::shared_ptr<warped::Event> > Location::createInitialEvents() {

    std::vector<std::shared_ptr<warped::Event> > events;
    events.emplace_back(new EpidemicEvent {this->location_name_,
                    this->location_state_refresh_interval_, nullptr, DISEASE_UPDATE_TRIGGER});
    events.emplace_back(new EpidemicEvent {this->location_name_,
                    this->location_diffusion_trigger_interval_, nullptr, DIFFUSION_TRIGGER});
    return events;
}

std::vector<std::shared_ptr<warped::Event> > Location::receiveEvent(const warped::Event& event) {

    std::vector<std::shared_ptr<warped::Event> > events;
    auto epidemic_event = static_cast<const EpidemicEvent&>(event);
    auto timestamp = epidemic_event.loc_arrival_timestamp_;

    switch (epidemic_event.event_type_) {

        case event_type_t::DISEASE_UPDATE_TRIGGER: {
            disease_model_->reaction(state_->current_population_, timestamp);
            events.emplace_back(new EpidemicEvent {location_name_,
                                timestamp + location_state_refresh_interval_,
                                nullptr, DISEASE_UPDATE_TRIGGER});
        } break;

        case event_type_t::DIFFUSION_TRIGGER: {
            std::string selected_location = diffusion_network_->pickLocation();
            if (selected_location != "") {
                auto travel_time = diffusion_network_->travelTimeToLocation(selected_location);
                unsigned int person_count = state_->current_population_->size();
                if (person_count) {
                    unsigned int person_id = diffusion_network_->pickPerson(person_count);
                    auto map_iter = state_->current_population_->begin();
                    unsigned int temp_cnt = 0;
                    while (temp_cnt < person_id) {
                        map_iter++;
                        temp_cnt++;
                    }
                    std::shared_ptr<Person> person = map_iter->second;
                    events.emplace_back(new EpidemicEvent {selected_location,
                                            timestamp + travel_time, person, DIFFUSION});
                    state_->current_population_->erase(map_iter);
                }
            }
            events.emplace_back(new EpidemicEvent {location_name_,
                                timestamp + location_diffusion_trigger_interval_,
                                nullptr, DIFFUSION_TRIGGER});
        } break;

        case event_type_t::DIFFUSION: {
            std::shared_ptr<Person> person = std::make_shared<Person>(
                        epidemic_event.pid_, epidemic_event.susceptibility_,
                        epidemic_event.vaccination_status_, epidemic_event.infection_state_,
                        timestamp, epidemic_event.prev_state_change_timestamp_);
            state_->current_population_->insert(state_->current_population_->begin(),
                std::pair <unsigned long, std::shared_ptr<Person>> (epidemic_event.pid_, person));
        } break;

        default: {}
    }
    return events;
}

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

    unsigned int num_regions                        = 1000;
    unsigned int num_locations_per_region           = 1000;
    unsigned int num_persons_per_location           = 10000;
    unsigned int mean_travel_time_to_hub            = 300;
    unsigned int diffusion_seed                     = 101;
    unsigned int disease_seed                       = 90;
    unsigned int location_state_refresh_interval    = 50;
    unsigned int mean_location_diffusion_interval   = 200;

    TCLAP::ValueArg<unsigned int> num_regions_arg("n", "num-regions", "Number of regions",
                                                            false, num_regions, "unsigned int");
    TCLAP::ValueArg<unsigned int> num_locations_per_region_arg("l", "num-locations-per-region",
                "Number of locations per region", false, num_locations_per_region, "unsigned int");
    TCLAP::ValueArg<unsigned int> num_persons_per_location_arg("p", "num-persons-per-location",
                "Number of persons per location", false, num_persons_per_location, "unsigned int");
    TCLAP::ValueArg<unsigned int> mean_travel_time_to_hub_arg("t", "mean-travel-time-to-hub",
                        "Mean travel time to hub", false, mean_travel_time_to_hub, "unsigned int");
    TCLAP::ValueArg<unsigned int> diffusion_seed_arg("f", "diffusion-seed", "Diffusion seed",
                                                            false, diffusion_seed, "unsigned int");
    TCLAP::ValueArg<unsigned int> disease_seed_arg("s", "disease-seed", "Disease seed",
                                                            false, disease_seed, "unsigned int");
    TCLAP::ValueArg<unsigned int> location_state_refresh_interval_arg("r", "refresh-interval",
        "Location state refresh interval", false, location_state_refresh_interval, "unsigned int");
    TCLAP::ValueArg<unsigned int> mean_location_diffusion_interval_arg("i", "diffusion-interval",
        "Mean location diffusion interval", false, mean_location_diffusion_interval, "unsigned int");

    std::vector<TCLAP::Arg*> args = {   &num_regions_arg,
                                        &num_locations_per_region_arg,
                                        &num_persons_per_location_arg,
                                        &mean_travel_time_to_hub_arg,
                                        &diffusion_seed_arg,
                                        &disease_seed_arg,
                                        &location_state_refresh_interval_arg,
                                        &mean_location_diffusion_interval_arg
                                    };

    warped::Simulation epidemic_sim {"Epidemic Simulation", argc, argv, args};

    num_regions                      = num_regions_arg.getValue();
    num_locations_per_region         = num_locations_per_region_arg.getValue();
    num_persons_per_location         = num_persons_per_location_arg.getValue();
    mean_travel_time_to_hub          = mean_travel_time_to_hub_arg.getValue();
    diffusion_seed                   = diffusion_seed_arg.getValue();
    disease_seed                     = disease_seed_arg.getValue();
    location_state_refresh_interval  = location_state_refresh_interval_arg.getValue();
    mean_location_diffusion_interval = mean_location_diffusion_interval_arg.getValue();

    std::shared_ptr<MLCG> rng = std::make_shared<MLCG> ();
    NegativeExpntl travel_time_expo(mean_travel_time_to_hub, rng.get());
    NegativeExpntl diffusion_expo(mean_location_diffusion_interval, rng.get());

    // Diffusion model
    unsigned int k = 8;
    float beta = 0.1;

    // Disease model
    float transmissibility = 0.12;
    unsigned int latent_dwell_time = 200;
    float latent_infectivity = 0;
    unsigned int incubating_dwell_time = 400;
    float incubating_infectivity = 0.3;
    unsigned int infectious_dwell_time = 400;
    float infectious_infectivity = 1.0;
    unsigned int asympt_dwell_time = 200;
    float asympt_infectivity = 0.5;
    float prob_ulu = 0.2;
    float prob_ulv = 0.9;
    float prob_urv = 0.5;
    float prob_uiv = 0.1;
    float prob_uiu = 0.3;

    std::map<std::string, unsigned int> travel_map;
    std::vector<Location> objects;

    for (unsigned int region_id = 0; region_id < num_regions; region_id++) {
        std::string region_name = std::string("region_") + std::to_string(region_id);

        for (unsigned int location_id = 0; location_id < num_locations_per_region; location_id++) {
            std::string location_name = std::string("location_") + std::to_string(location_id);
            std::string location = region_name + std::string("-") + location_name;
            std::vector<std::shared_ptr<Person>> population;
            unsigned int travel_time_to_hub =
                            (unsigned int) travel_time_expo() + NEG_EXP_OFFSET;
            travel_map.insert(std::pair<std::string, unsigned int>(location, travel_time_to_hub));
            unsigned int location_diffusion_interval =
                            (unsigned int) diffusion_expo() + NEG_EXP_OFFSET;

            for (unsigned int person_id = 0; person_id < num_persons_per_location; person_id++) {
                unsigned long pid = region_id * location_id + person_id;

                std::default_random_engine gen;

                std::uniform_int_distribution<unsigned int> rand_susceptibility(0,10);
                double susceptibility = ((double)rand_susceptibility(gen))/10;

                std::uniform_int_distribution<unsigned int> rand_vaccination(0,1);
                bool vaccination_status = (bool) rand_vaccination(gen);

                std::uniform_int_distribution<unsigned int>
                            rand_infection(0, (unsigned int) MAX_INFECTION_STATE_NUM-1);
                infection_state_t state = (infection_state_t) rand_infection(gen);

                auto person = std::make_shared<Person> (    pid,
                                                            susceptibility,
                                                            vaccination_status,
                                                            state,
                                                            0,
                                                            0
                                                       );
                population.push_back(person);
            }
            objects.emplace_back(   location,
                                    transmissibility,
                                    latent_dwell_time,
                                    incubating_dwell_time,
                                    infectious_dwell_time,
                                    asympt_dwell_time,
                                    latent_infectivity,
                                    incubating_infectivity,
                                    infectious_infectivity,
                                    asympt_infectivity,
                                    prob_ulu,
                                    prob_ulv,
                                    prob_urv,
                                    prob_uiv,
                                    prob_uiu,
                                    location_state_refresh_interval,
                                    location_diffusion_interval,
                                    population,
                                    travel_time_to_hub,
                                    disease_seed,
                                    diffusion_seed
                                );

        }
    }

    // Create the Watts-Strogatz model
    auto ws = std::make_shared<WattsStrogatzModel>(k, beta, diffusion_seed);
    std::vector<std::string> nodes;
    for (auto& o : objects) {
        nodes.push_back(o.getLocationName());
    }
    ws->populateNodes(nodes);
    ws->mapNodes();

    // Create the travel map
    for (auto& o : objects) {
        std::vector<std::string> connections = ws->fetchNodeLinks(o.getLocationName());
        std::map<std::string, unsigned int> temp_travel_map;
        for (auto& link : connections) {
            auto travel_map_iter = travel_map.find(link);
            temp_travel_map.insert(std::pair<std::string, unsigned int>
                                (travel_map_iter->first, travel_map_iter->second));
        }
        o.populateTravelDistances(temp_travel_map);
    }

    std::vector<warped::SimulationObject*> object_pointers;
    for (auto& o : objects) {
        object_pointers.push_back(&o);
    }
    epidemic_sim.simulate(object_pointers);

    return 0;
}
<commit_msg>new version of config reader<commit_after>#include <fstream>
#include "epidemic.hpp"
#include "WattsStrogatzModel.hpp"
#include "tclap/ValueArg.h"

WARPED_REGISTER_POLYMORPHIC_SERIALIZABLE_CLASS(EpidemicEvent)

std::vector<std::shared_ptr<warped::Event> > Location::createInitialEvents() {

    std::vector<std::shared_ptr<warped::Event> > events;
    events.emplace_back(new EpidemicEvent {this->location_name_,
                    this->location_state_refresh_interval_, nullptr, DISEASE_UPDATE_TRIGGER});
    events.emplace_back(new EpidemicEvent {this->location_name_,
                    this->location_diffusion_trigger_interval_, nullptr, DIFFUSION_TRIGGER});
    return events;
}

std::vector<std::shared_ptr<warped::Event> > Location::receiveEvent(const warped::Event& event) {

    std::vector<std::shared_ptr<warped::Event> > events;
    auto epidemic_event = static_cast<const EpidemicEvent&>(event);
    auto timestamp = epidemic_event.loc_arrival_timestamp_;

    switch (epidemic_event.event_type_) {

        case event_type_t::DISEASE_UPDATE_TRIGGER: {
            disease_model_->reaction(state_->current_population_, timestamp);
            events.emplace_back(new EpidemicEvent {location_name_,
                                timestamp + location_state_refresh_interval_,
                                nullptr, DISEASE_UPDATE_TRIGGER});
        } break;

        case event_type_t::DIFFUSION_TRIGGER: {
            std::string selected_location = diffusion_network_->pickLocation();
            if (selected_location != "") {
                auto travel_time = diffusion_network_->travelTimeToLocation(selected_location);
                unsigned int person_count = state_->current_population_->size();
                if (person_count) {
                    unsigned int person_id = diffusion_network_->pickPerson(person_count);
                    auto map_iter = state_->current_population_->begin();
                    unsigned int temp_cnt = 0;
                    while (temp_cnt < person_id) {
                        map_iter++;
                        temp_cnt++;
                    }
                    std::shared_ptr<Person> person = map_iter->second;
                    events.emplace_back(new EpidemicEvent {selected_location,
                                            timestamp + travel_time, person, DIFFUSION});
                    state_->current_population_->erase(map_iter);
                }
            }
            events.emplace_back(new EpidemicEvent {location_name_,
                                timestamp + location_diffusion_trigger_interval_,
                                nullptr, DIFFUSION_TRIGGER});
        } break;

        case event_type_t::DIFFUSION: {
            std::shared_ptr<Person> person = std::make_shared<Person>(
                        epidemic_event.pid_, epidemic_event.susceptibility_,
                        epidemic_event.vaccination_status_, epidemic_event.infection_state_,
                        timestamp, epidemic_event.prev_state_change_timestamp_);
            state_->current_population_->insert(state_->current_population_->begin(),
                std::pair <unsigned long, std::shared_ptr<Person>> (epidemic_event.pid_, person));
        } break;

        default: {}
    }
    return events;
}

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

    std::string config_filename = "model_5k.dat";
    TCLAP::ValueArg<std::string> config_arg("m", "model",
            "Epidemic model config", false, config_filename, "string");
    std::vector<TCLAP::Arg*> args = {&config_arg};

    warped::Simulation epidemic_sim {"Epidemic Simulation", argc, argv, args};

    config_filename = config_arg.getValue();

    std::ifstream config_stream;
    config_stream.open(config_filename);
    if (!config_stream.is_open()) {
        std::cerr << "Invalid configuration file - " << config_filename << std::endl;
        return 0;
    }

    std::string buffer;
    std::string delimiter = ",";
    size_t pos = 0;
    std::string token;

    // Diffusion model
    getline(config_stream, buffer);
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    unsigned int diffusion_seed = (unsigned int) std::stoul(token);
    buffer.erase(0, pos + delimiter.length());
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    unsigned int k = (unsigned int) std::stoul(token);
    buffer.erase(0, pos + delimiter.length());
    float beta = std::stof(buffer);

    // Disease model
    getline(config_stream, buffer);
    float transmissibility = std::stof(buffer);

    getline(config_stream, buffer);
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    unsigned int latent_dwell_time = (unsigned int) std::stoul(token);
    buffer.erase(0, pos + delimiter.length());
    float latent_infectivity = std::stof(buffer);

    getline(config_stream, buffer);
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    unsigned int incubating_dwell_time = (unsigned int) std::stoul(token);
    buffer.erase(0, pos + delimiter.length());
    float incubating_infectivity = std::stof(buffer);

    getline(config_stream, buffer);
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    unsigned int infectious_dwell_time = (unsigned int) std::stoul(token);
    buffer.erase(0, pos + delimiter.length());
    float infectious_infectivity = std::stof(buffer);

    getline(config_stream, buffer);
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    unsigned int asympt_dwell_time = (unsigned int) std::stoul(token);
    buffer.erase(0, pos + delimiter.length());
    float asympt_infectivity = std::stof(buffer);

    getline(config_stream, buffer);
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    float prob_ulu = stof(token);
    buffer.erase(0, pos + delimiter.length());
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    float prob_ulv = std::stof(token);
    buffer.erase(0, pos + delimiter.length());
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    float prob_urv = std::stof(token);
    buffer.erase(0, pos + delimiter.length());
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    float prob_uiv = std::stof(token);
    buffer.erase(0, pos + delimiter.length());
    float prob_uiu = std::stof(buffer);

    getline(config_stream, buffer);
    pos = buffer.find(delimiter);
    token = buffer.substr(0, pos);
    unsigned int location_state_refresh_interval = (unsigned int) stoul(token);
    buffer.erase(0, pos + delimiter.length());
    unsigned int disease_seed = (unsigned int) stoul(buffer);

    //Population
    getline(config_stream, buffer);
    unsigned int num_regions = (unsigned int) std::stoul(buffer);

    std::map<std::string, unsigned int> travel_map;
    std::vector<Location> objects;

    for (unsigned int region_id = 0; region_id < num_regions; region_id++) {

        getline(config_stream, buffer);
        pos = buffer.find(delimiter);
        std::string region_name = buffer.substr(0, pos);
        buffer.erase(0, pos + delimiter.length());
        unsigned int num_locations = (unsigned int) std::stoul(buffer);

        for (unsigned int location_id = 0; location_id < num_locations; location_id++) {

            getline(config_stream, buffer);
            pos = buffer.find(delimiter);
            std::string location_name = buffer.substr(0, pos);
            std::string location = region_name + location_name;
            std::cout << location << std::endl;
            buffer.erase(0, pos + delimiter.length());
            pos = buffer.find(delimiter);
            token = buffer.substr(0, pos);
            unsigned int travel_time_to_hub = (unsigned int) std::stoul(token);
            buffer.erase(0, pos + delimiter.length());
            pos = buffer.find(delimiter);
            token = buffer.substr(0, pos);
            unsigned int diffusion_interval = (unsigned int) std::stoul(token);
            buffer.erase(0, pos + delimiter.length());
            unsigned int num_persons = (unsigned int) std::stoul(buffer);

            std::vector<std::shared_ptr<Person>> population;
            travel_map.insert(std::pair<std::string, unsigned int>(location, travel_time_to_hub));

            for (unsigned int person_id = 0; person_id < num_persons; person_id++) {

                getline(config_stream, buffer);
                pos = buffer.find(delimiter);
                token = buffer.substr(0, pos);
                unsigned long pid = std::stoul(token);
                buffer.erase(0, pos + delimiter.length());
                pos = buffer.find(delimiter);
                token = buffer.substr(0, pos);
                double susceptibility = std::stod(buffer);
                buffer.erase(0, pos + delimiter.length());
                pos = buffer.find(delimiter);
                token = buffer.substr(0, pos);
                bool vaccination_status = (bool) std::stoi(token);
                buffer.erase(0, pos + delimiter.length());
                infection_state_t state = (infection_state_t) std::stoi(buffer);

                auto person = std::make_shared<Person> (    pid,
                                                            susceptibility,
                                                            vaccination_status,
                                                            state,
                                                            0,
                                                            0
                                                       );
                population.push_back(person);
            }
            objects.emplace_back(   location,
                                    transmissibility,
                                    latent_dwell_time,
                                    incubating_dwell_time,
                                    infectious_dwell_time,
                                    asympt_dwell_time,
                                    latent_infectivity,
                                    incubating_infectivity,
                                    infectious_infectivity,
                                    asympt_infectivity,
                                    prob_ulu,
                                    prob_ulv,
                                    prob_urv,
                                    prob_uiv,
                                    prob_uiu,
                                    location_state_refresh_interval,
                                    diffusion_interval,
                                    population,
                                    travel_time_to_hub,
                                    disease_seed,
                                    diffusion_seed
                                );
        }
    }
    config_stream.close();

    // Create the Watts-Strogatz model
    auto ws = std::make_shared<WattsStrogatzModel>(k, beta, diffusion_seed);
    std::vector<std::string> nodes;
    for (auto& o : objects) {
        nodes.push_back(o.getLocationName());
    }
    ws->populateNodes(nodes);
    ws->mapNodes();

    // Create the travel map
    for (auto& o : objects) {
        std::vector<std::string> connections = ws->fetchNodeLinks(o.getLocationName());
        std::map<std::string, unsigned int> temp_travel_map;
        for (auto& link : connections) {
            auto travel_map_iter = travel_map.find(link);
            temp_travel_map.insert(std::pair<std::string, unsigned int>
                                (travel_map_iter->first, travel_map_iter->second));
        }
        o.populateTravelDistances(temp_travel_map);
    }

    std::vector<warped::SimulationObject*> object_pointers;
    for (auto& o : objects) {
        object_pointers.push_back(&o);
    }
    epidemic_sim.simulate(object_pointers);

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011 by Jakub Lekstan <kuebzky@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <v8.h>
#include <node.h>
#include <Uri.h>
#include <string.h>

static v8::Handle<v8::Value> parse(const v8::Arguments& args){
    v8::HandleScope scope;

    if (args.Length() == 0 || !args[0]->IsString()) {
        v8::ThrowException(v8::Exception::TypeError(v8::String::New("First argument has to be string")));
    }

    v8::String::Utf8Value url (args[0]->ToString());

    if (url.length() == 0) {
        v8::ThrowException(v8::Exception::TypeError(v8::String::New("String mustn't be empty")));
    }

    UriParserStateA state;
    UriUriA uri;

    state.uri = &uri;

    if (uriParseUriA(&state, *url) != URI_SUCCESS) {
        return scope.Close(v8::Boolean::New(false));
    }

    v8::PropertyAttribute attrib = (v8::PropertyAttribute) (v8::ReadOnly | v8::DontDelete);
    v8::Local<v8::Object> data = v8::Object::New();
    v8::Local<v8::String> emptyString = v8::String::New("");
    v8::Local<v8::Array> emptyArray = v8::Array::New();
    v8::Local<v8::Object> emptyObject = v8::Object::New();

    int i, position, tmpPosition;
    int hostSlashPosition = 0;

    if (uri.scheme.first) {
        // +1 here because we need : after protocol
        data->Set(v8::String::New("protocol"), v8::String::New(uri.scheme.first, strlen(uri.scheme.first) - strlen(uri.scheme.afterLast) + 1), attrib);
    } else {
        data->Set(v8::String::New("protocol"), emptyString, attrib);
    }

    if (uri.userInfo.first) {
        char *auth = (char*) uri.userInfo.first;
        const char *delim = ":";
        auth[strlen(uri.userInfo.first) - strlen(uri.userInfo.afterLast)] = '\0';

        v8::Local<v8::Object> authData = v8::Object::New();
        authData->Set(v8::String::New("user"), v8::String::New(strtok(auth, delim))), attrib;
        authData->Set(v8::String::New("password"), v8::String::New(strtok(NULL, delim)), attrib);

        data->Set(v8::String::New("auth"), authData, attrib);
    } else {
        data->Set(v8::String::New("auth"), emptyObject, attrib);
    }

    if (uri.hostText.first) {
        //we need to find out is there anything after first / after host (or host:port)
        int tmpLength = strlen(uri.hostText.first);
        const char *tmp = strchr(uri.hostText.first, '/');
        hostSlashPosition = tmpLength - ((tmp - uri.hostText.first) + 1);

        data->Set(v8::String::New("hostname"), v8::String::New(uri.hostText.first, tmpLength - strlen(uri.hostText.afterLast)), attrib);
    } else {
        data->Set(v8::String::New("hostname"), emptyString, attrib);
    }

/*    UriIp4 ip4 = *uri.hostData.ip4;
    fprintf(stderr, "HOSTDATA4: %s\n", ip4.data);
    UriIp6 ip6 = *uri.hostData.ip6;
    fprintf(stderr, "HOSTDATA6: %s\n", ip6.data);*/

    if (uri.portText.first) {
        data->Set(v8::String::New("port"), v8::String::New(uri.portText.first, strlen(uri.portText.first) - strlen(uri.portText.afterLast)), attrib);
    } else {
        data->Set(v8::String::New("port"), v8::Integer::New(80), attrib);
    }

    if (uri.query.first) {
        char *query = (char*) uri.query.first;
        query[strlen(uri.query.first) - strlen(uri.query.afterLast)] = '\0';
        const char *amp = "&", *sum = "=";
        char *queryParamPtr, *queryParam = strtok_r(query, amp, &queryParamPtr), *queryParamKey, *queryParamValue;

        v8::Local<v8::Object> queryData = v8::Object::New();

        while (queryParam) {
            queryParamKey = strtok(queryParam, sum);
            queryParamValue = strtok(NULL, sum);
            queryParam = strtok_r(NULL, amp, &queryParamPtr);

            queryData->Set(v8::String::New(queryParamKey), v8::String::New(queryParamValue), attrib);
        }

        data->Set(v8::String::New("query"), queryData, attrib);
    } else {
        data->Set(v8::String::New("query"), emptyObject, attrib);
    }

    if (uri.fragment.first) {
        data->Set(v8::String::New("fragment"), v8::String::New(uri.fragment.first, strlen(uri.fragment.first) - strlen(uri.fragment.afterLast)), attrib);
    } else {
        data->Set(v8::String::New("fragment"), emptyString, attrib);
    }

    if (uri.pathHead && uri.pathHead->text.first && hostSlashPosition > 1) {
        UriPathSegmentA pathHead = *uri.pathHead;

        char *path = (char*) pathHead.text.first;

        position = strlen(pathHead.text.first);
        while (pathHead.next) {
            i++;
            pathHead = *pathHead.next;
        }

        tmpPosition = strlen(pathHead.text.afterLast);

        path[position - tmpPosition] = '\0';

        if (uri.absolutePath || uri.hostText.first) {
            path--;
        }

        data->Set(v8::String::New("pathname"), v8::String::New(path), attrib);
    } else {
        data->Set(v8::String::New("pathname"), v8::String::New("/"), attrib);
    }

/*    UriPathSegmentA pathHead = *uri.pathHead;

    if (pathHead.text.first) {
        i = 0;

        while (pathHead.next) {
            i++;
            pathHead = *pathHead.next;
        }

        pathHead = *uri.pathHead;
        i = 0;
        position = strlen(pathHead.text.afterLast);
        tmpPosition = position - 1;

        v8::Local<v8::Array> aPathHead = v8::Array::New(i + 1);

        aPathHead->Set(v8::Number::New(i), v8::String::New(pathHead.text.first, strlen(pathHead.text.first) - position));

        while (pathHead.next) {
            i++;
            pathHead = *pathHead.next;

            position = strlen(pathHead.text.afterLast);

            aPathHead->Set(v8::Number::New(i), v8::String::New(pathHead.text.first, tmpPosition - position));
            tmpPosition = position - 1;
        }

        data->Set(v8::String::New("pathHead"), aPathHead);
    } else {
        data->Set(v8::String::New("pathHead"), emptyArray);
    }*/

/*    UriPathSegmentA pathTail = *uri.pathTail;

    if (pathTail.text.first) {
        i = 0;

        while (pathTail.next) {
            i++;
            pathTail = *pathTail.next;
        }

        pathTail = *uri.pathTail;
        i = 0;
        position = strlen(pathTail.text.afterLast);
        tmpPosition = position - 1;

        v8::Local<v8::Array> aPathTail = v8::Array::New(i + 1);

        aPathTail->Set(v8::Number::New(i), v8::String::New(pathTail.text.first, strlen(pathTail.text.first) - position));

        while (pathTail.next) {
            i++;
            pathTail = *pathTail.next;

            position = strlen(pathTail.text.afterLast);

            aPathTail->Set(v8::Number::New(i), v8::String::New(pathTail.text.first, tmpPosition - position));
            tmpPosition = position - 1;
        }

        data->Set(v8::String::New("pathTail"), aPathTail);
    } else {
        data->Set(v8::String::New("pathTail"), emptyArray);
    }*/

//    data->Set(v8::String::New("absolutePath"), v8::Boolean::New(uri.absolutePath));
//    data->Set(v8::String::New("owner"), v8::Boolean::New(uri.owner));

    uriFreeUriMembersA(&uri);

    return scope.Close(data);
}

extern "C" void init (v8::Handle<v8::Object> target){
    v8::HandleScope scope;

    NODE_SET_METHOD(target, "parse", parse);
}

<commit_msg>Fixed segfaults, minor fixes<commit_after>/*
 * Copyright (C) 2011 by Jakub Lekstan <kuebzky@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <v8.h>
#include <node.h>
#include <Uri.h>
#include <string.h>

static v8::Handle<v8::Value> parse(const v8::Arguments& args){
    v8::HandleScope scope;

    if (args.Length() == 0 || !args[0]->IsString()) {
        v8::ThrowException(v8::Exception::TypeError(v8::String::New("First argument has to be string")));
    }

    v8::String::Utf8Value url (args[0]->ToString());

    if (url.length() == 0) {
        v8::ThrowException(v8::Exception::TypeError(v8::String::New("String mustn't be empty")));
    }

    UriParserStateA state;
    UriUriA uri;

    state.uri = &uri;

    if (uriParseUriA(&state, *url) != URI_SUCCESS) {
        return scope.Close(v8::Boolean::New(false));
    }

    v8::PropertyAttribute attrib = (v8::PropertyAttribute) (v8::ReadOnly | v8::DontDelete);
    v8::Local<v8::Object> data = v8::Object::New();
    v8::Local<v8::String> emptyString = v8::String::New("");
    v8::Local<v8::Array> emptyArray = v8::Array::New();
    v8::Local<v8::Object> emptyObject = v8::Object::New();

    int i, position, tmpPosition;

    if (uri.scheme.first) {
        // +1 here because we need : after protocol
        data->Set(v8::String::New("protocol"), v8::String::New(uri.scheme.first, strlen(uri.scheme.first) - strlen(uri.scheme.afterLast) + 1), attrib);
    } else {
        data->Set(v8::String::New("protocol"), emptyString, attrib);
    }

    if (uri.userInfo.first) {
        char *auth = (char*) uri.userInfo.first;
        const char *delim = ":";
        auth[strlen(uri.userInfo.first) - strlen(uri.userInfo.afterLast)] = '\0';

        v8::Local<v8::Object> authData = v8::Object::New();
        authData->Set(v8::String::New("user"), v8::String::New(strtok(auth, delim))), attrib;
        authData->Set(v8::String::New("password"), v8::String::New(strtok(NULL, delim)), attrib);

        data->Set(v8::String::New("auth"), authData, attrib);
    } else {
        data->Set(v8::String::New("auth"), emptyObject, attrib);
    }

    if (uri.hostText.first) {
        //we need to find out is there anything after first / after host (or host:port)
        int tmpLength = strlen(uri.hostText.first);

        data->Set(v8::String::New("hostname"), v8::String::New(uri.hostText.first, tmpLength - strlen(uri.hostText.afterLast)), attrib);
    } else {
        data->Set(v8::String::New("hostname"), emptyString, attrib);
    }

/*    UriIp4 ip4 = *uri.hostData.ip4;
    fprintf(stderr, "HOSTDATA4: %s\n", ip4.data);
    UriIp6 ip6 = *uri.hostData.ip6;
    fprintf(stderr, "HOSTDATA6: %s\n", ip6.data);*/

    if (uri.portText.first) {
        data->Set(v8::String::New("port"), v8::String::New(uri.portText.first, strlen(uri.portText.first) - strlen(uri.portText.afterLast)), attrib);
    } else {
        if (uri.hostText.first) {
            data->Set(v8::String::New("port"), v8::Integer::New(80), attrib);
        } else {
            data->Set(v8::String::New("port"), emptyString, attrib);
        }
    }

    if (uri.query.first) {
        char *query = (char*) uri.query.first;
        query[strlen(uri.query.first) - strlen(uri.query.afterLast)] = '\0';
        const char *amp = "&", *sum = "=";
        char *queryParamPtr, *queryParam = strtok_r(query, amp, &queryParamPtr), *queryParamKey, *queryParamValue;

        v8::Local<v8::Object> queryData = v8::Object::New();

        while (queryParam) {
            queryParamKey = strtok(queryParam, sum);
            queryParamValue = strtok(NULL, sum);
            queryParam = strtok_r(NULL, amp, &queryParamPtr);

            queryData->Set(v8::String::New(queryParamKey), queryParamValue ? v8::String::New(queryParamValue) : emptyString, attrib);
        }

        data->Set(v8::String::New("query"), queryData, attrib);
    } else {
        data->Set(v8::String::New("query"), emptyObject, attrib);
    }

    if (uri.fragment.first) {
        data->Set(v8::String::New("fragment"), v8::String::New(uri.fragment.first, strlen(uri.fragment.first) - strlen(uri.fragment.afterLast)), attrib);
    } else {
        data->Set(v8::String::New("fragment"), emptyString, attrib);
    }

    if (uri.pathHead && uri.pathHead->text.first) {
        UriPathSegmentA pathHead = *uri.pathHead;

        char *path = (char*) pathHead.text.first;

        position = strlen(pathHead.text.first);
        while (pathHead.next) {
            i++;
            pathHead = *pathHead.next;
        }

        tmpPosition = strlen(pathHead.text.afterLast);

        if ( (position - tmpPosition) > 0) {
            path[position - tmpPosition] = '\0';
        } else {
            path = (char *) "/";
        }

        if ((uri.absolutePath || uri.hostText.first) && strlen(path) > 1) {
            path--;
        }

        data->Set(v8::String::New("pathname"), v8::String::New(path), attrib);
    } else {
        data->Set(v8::String::New("pathname"), v8::String::New("/"), attrib);
    }

/*    UriPathSegmentA pathHead = *uri.pathHead;

    if (pathHead.text.first) {
        i = 0;

        while (pathHead.next) {
            i++;
            pathHead = *pathHead.next;
        }

        pathHead = *uri.pathHead;
        i = 0;
        position = strlen(pathHead.text.afterLast);
        tmpPosition = position - 1;

        v8::Local<v8::Array> aPathHead = v8::Array::New(i + 1);

        aPathHead->Set(v8::Number::New(i), v8::String::New(pathHead.text.first, strlen(pathHead.text.first) - position));

        while (pathHead.next) {
            i++;
            pathHead = *pathHead.next;

            position = strlen(pathHead.text.afterLast);

            aPathHead->Set(v8::Number::New(i), v8::String::New(pathHead.text.first, tmpPosition - position));
            tmpPosition = position - 1;
        }

        data->Set(v8::String::New("pathHead"), aPathHead);
    } else {
        data->Set(v8::String::New("pathHead"), emptyArray);
    }*/

/*    UriPathSegmentA pathTail = *uri.pathTail;

    if (pathTail.text.first) {
        i = 0;

        while (pathTail.next) {
            i++;
            pathTail = *pathTail.next;
        }

        pathTail = *uri.pathTail;
        i = 0;
        position = strlen(pathTail.text.afterLast);
        tmpPosition = position - 1;

        v8::Local<v8::Array> aPathTail = v8::Array::New(i + 1);

        aPathTail->Set(v8::Number::New(i), v8::String::New(pathTail.text.first, strlen(pathTail.text.first) - position));

        while (pathTail.next) {
            i++;
            pathTail = *pathTail.next;

            position = strlen(pathTail.text.afterLast);

            aPathTail->Set(v8::Number::New(i), v8::String::New(pathTail.text.first, tmpPosition - position));
            tmpPosition = position - 1;
        }

        data->Set(v8::String::New("pathTail"), aPathTail);
    } else {
        data->Set(v8::String::New("pathTail"), emptyArray);
    }*/

//    data->Set(v8::String::New("absolutePath"), v8::Boolean::New(uri.absolutePath));
//    data->Set(v8::String::New("owner"), v8::Boolean::New(uri.owner));

    uriFreeUriMembersA(&uri);

    return scope.Close(data);
}

extern "C" void init (v8::Handle<v8::Object> target){
    v8::HandleScope scope;

    NODE_SET_METHOD(target, "parse", parse);
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: libxmlutil.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 19:36:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#if !defined INCLUDED_JVMFWK_LIBXMLUTIL_HXX
#define INCLUDED_JVMFWK_LIBXMLUTIL_HXX

#include "libxml/parser.h"
#include "libxml/xpath.h"
//#include "libxml/xpathinternals.h"
#include "rtl/ustring.hxx"
namespace jfw
{
class CXPathObjectPtr
{
    xmlXPathObject* _object;
    CXPathObjectPtr & operator = (const CXPathObjectPtr&);
    CXPathObjectPtr(const CXPathObjectPtr&);
public:
    CXPathObjectPtr();
    /** Takes ownership of xmlXPathObject
     */
    CXPathObjectPtr(xmlXPathObject* aObject);
    ~CXPathObjectPtr();
    /** Takes ownership of xmlXPathObject
     */
    CXPathObjectPtr & operator = (xmlXPathObject* pObj);
    xmlXPathObject* operator -> ();
    operator xmlXPathObject* ();
};

//===========================================================
class CXPathContextPtr
{
    xmlXPathContext* _object;

    CXPathContextPtr(const jfw::CXPathContextPtr&);
    CXPathContextPtr & operator = (const CXPathContextPtr&);
public:
    CXPathContextPtr();
    CXPathContextPtr(xmlXPathContextPtr aContext);
    CXPathContextPtr & operator = (xmlXPathContextPtr pObj);
    ~CXPathContextPtr();
    xmlXPathContext* operator -> ();
    operator xmlXPathContext* ();
};

//===========================================================
class CXmlDocPtr
{
    xmlDoc* _object;

    CXmlDocPtr(const CXmlDocPtr&);
    CXmlDocPtr & operator = (const CXmlDocPtr&);
public:
    CXmlDocPtr();
    CXmlDocPtr(xmlDoc* aDoc);
    /** Takes ownership of xmlDoc
     */
    CXmlDocPtr & operator = (xmlDoc* pObj);
    ~CXmlDocPtr();
    xmlDoc* operator -> ();
    operator xmlDoc* ();
};

//===========================================================
// class CXmlNsPtr
// {
//     xmlNs* _object;

//     CXmlNsPtr(const CXmlNsPtr&);
//     CXmlNsPtr & operator = (const CXmlNsPtr&);
// public:
//     CXmlNsPtr();
//     CXmlNsPtr(xmlNs* aDoc);
//     /** Takes ownership of xmlDoc
//      */
//     CXmlNsPtr & operator = (xmlNs* pObj);
//     ~CXmlNsPtr();
//     xmlNs* operator -> ();
//     operator xmlNs* ();
// };

//===========================================================
class CXmlCharPtr
{
    xmlChar* _object;

    CXmlCharPtr(const CXmlCharPtr&);
    CXmlCharPtr & operator = (const CXmlCharPtr&);
public:
    CXmlCharPtr();
    CXmlCharPtr(xmlChar* aDoc);
    ~CXmlCharPtr();
    CXmlCharPtr & operator = (xmlChar* pObj);
//    xmlChar* operator -> ();
    operator xmlChar* ();
    operator rtl::OUString ();
    operator rtl::OString ();
};

}
#endif
<commit_msg>INTEGRATION: CWS jl64 (1.3.80); FILE MERGED 2007/06/07 11:32:38 jl 1.3.80.2: #i76390# 2007/06/07 07:52:58 jl 1.3.80.1: #i76390# support of new bootstrap variable UNO_JAVA_JFW_INSTALL_DATA and UNO_JAVA_JFW_INSTALL_EXPIRE<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: libxmlutil.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2007-06-13 07:58:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#if !defined INCLUDED_JVMFWK_LIBXMLUTIL_HXX
#define INCLUDED_JVMFWK_LIBXMLUTIL_HXX

#include "libxml/parser.h"
#include "libxml/xpath.h"
//#include "libxml/xpathinternals.h"
#include "rtl/ustring.hxx"
namespace jfw
{
class CXPathObjectPtr
{
    xmlXPathObject* _object;
    CXPathObjectPtr & operator = (const CXPathObjectPtr&);
    CXPathObjectPtr(const CXPathObjectPtr&);
public:
    CXPathObjectPtr();
    /** Takes ownership of xmlXPathObject
     */
    CXPathObjectPtr(xmlXPathObject* aObject);
    ~CXPathObjectPtr();
    /** Takes ownership of xmlXPathObject
     */
    CXPathObjectPtr & operator = (xmlXPathObject* pObj);
    xmlXPathObject* operator -> ();
    operator xmlXPathObject* ();
};

//===========================================================
class CXPathContextPtr
{
    xmlXPathContext* _object;

    CXPathContextPtr(const jfw::CXPathContextPtr&);
    CXPathContextPtr & operator = (const CXPathContextPtr&);
public:
    CXPathContextPtr();
    CXPathContextPtr(xmlXPathContextPtr aContext);
    CXPathContextPtr & operator = (xmlXPathContextPtr pObj);
    ~CXPathContextPtr();
    xmlXPathContext* operator -> ();
    operator xmlXPathContext* ();
};

//===========================================================
class CXmlDocPtr
{
    xmlDoc* _object;

    CXmlDocPtr(const CXmlDocPtr&);

public:
    CXmlDocPtr & operator = (const CXmlDocPtr&);
    CXmlDocPtr();
    CXmlDocPtr(xmlDoc* aDoc);
    /** Takes ownership of xmlDoc
     */
    CXmlDocPtr & operator = (xmlDoc* pObj);
    ~CXmlDocPtr();
    xmlDoc* operator -> ();
    operator xmlDoc* ();
};

//===========================================================
// class CXmlNsPtr
// {
//     xmlNs* _object;

//     CXmlNsPtr(const CXmlNsPtr&);
//     CXmlNsPtr & operator = (const CXmlNsPtr&);
// public:
//     CXmlNsPtr();
//     CXmlNsPtr(xmlNs* aDoc);
//     /** Takes ownership of xmlDoc
//      */
//     CXmlNsPtr & operator = (xmlNs* pObj);
//     ~CXmlNsPtr();
//     xmlNs* operator -> ();
//     operator xmlNs* ();
// };

//===========================================================
class CXmlCharPtr
{
    xmlChar* _object;

    CXmlCharPtr(const CXmlCharPtr&);
    CXmlCharPtr & operator = (const CXmlCharPtr&);
public:
    CXmlCharPtr();
    CXmlCharPtr(xmlChar* aDoc);
    CXmlCharPtr(const ::rtl::OUString &);
    ~CXmlCharPtr();
    CXmlCharPtr & operator = (xmlChar* pObj);
//    xmlChar* operator -> ();
    operator xmlChar* ();
    operator ::rtl::OUString ();
    operator ::rtl::OString ();
};

}
#endif
<|endoftext|>