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

#include <log4cplus/ndc.h>
#include <log4cplus/internal/internal.h>
#include <utility>
#include <algorithm>

namespace log4cplus
{

///////////////////////////////////////////////////////////////////////////////
// log4cplus::DiagnosticContext ctors
///////////////////////////////////////////////////////////////////////////////

namespace
{

static
void
init_full_message (log4cplus::tstring & fullMessage,
    log4cplus::tstring const & message, DiagnosticContext const * parent)
{
    if (parent)
    {
        fullMessage.reserve (parent->fullMessage.size () + 1
            + message.size ());
        fullMessage = parent->fullMessage;
        fullMessage += LOG4CPLUS_TEXT(" ");
        fullMessage += message;
    }
    else
        fullMessage = message;
}

} // namespace

DiagnosticContext::DiagnosticContext(const log4cplus::tstring& message_,
                                     DiagnosticContext const * parent)
    : message(message_)
    , fullMessage()
{
    init_full_message (fullMessage, message, parent);
}

DiagnosticContext::DiagnosticContext(tchar const * message_,
                                     DiagnosticContext const * parent)
    : message(message_)
    , fullMessage()
{
    init_full_message (fullMessage, message, parent);
}

DiagnosticContext::DiagnosticContext(const log4cplus::tstring& message_)
    : message(message_)
    , fullMessage(message)
{
}

DiagnosticContext::DiagnosticContext(tchar const * message_)
    : message(message_)
    , fullMessage(message)
{
}

DiagnosticContext::DiagnosticContext (DiagnosticContext const & other)
    : message (other.message)
    , fullMessage (other.fullMessage)
{ }

DiagnosticContext & DiagnosticContext::operator = (
    DiagnosticContext const & other)
{
    DiagnosticContext (other).swap (*this);
    return *this;
}

#if defined (LOG4CPLUS_HAVE_RVALUE_REFS)
DiagnosticContext::DiagnosticContext (DiagnosticContext && other)
    : message (std::move (other.message))
    , fullMessage (std::move (other.fullMessage))
{ }

DiagnosticContext &
DiagnosticContext::operator = (DiagnosticContext && other)
{
    DiagnosticContext (std::move (other)).swap (*this);
    return *this;
}

#endif

void
DiagnosticContext::swap (DiagnosticContext & other)
{
    using std::swap;
    swap (message, other.message);
    swap (fullMessage, other.fullMessage);
}

///////////////////////////////////////////////////////////////////////////////
// log4cplus::NDC ctor and dtor
///////////////////////////////////////////////////////////////////////////////

NDC::NDC()
{ }

NDC::~NDC()
{ }

///////////////////////////////////////////////////////////////////////////////
// log4cplus::NDC public methods
///////////////////////////////////////////////////////////////////////////////

void
NDC::clear()
{
    DiagnosticContextStack* ptr = getPtr();
    DiagnosticContextStack ().swap (*ptr);
}

DiagnosticContextStack
NDC::cloneStack() const
{
    DiagnosticContextStack* ptr = getPtr();
    return DiagnosticContextStack(*ptr);
}

void
NDC::inherit(const DiagnosticContextStack& stack)
{
    DiagnosticContextStack* ptr = getPtr();
    DiagnosticContextStack (stack).swap (*ptr);
}

log4cplus::tstring const &
NDC::get() const
{
    DiagnosticContextStack* ptr = getPtr();
    if(!ptr->empty())
        return ptr->back().fullMessage;
    else
        return internal::empty_str;
}

std::size_t
NDC::getDepth() const
{
    DiagnosticContextStack* ptr = getPtr();
    return ptr->size();
}

log4cplus::tstring
NDC::pop()
{
    DiagnosticContextStack* ptr = getPtr();
    if(!ptr->empty())
    {
        tstring message;
        message.swap (ptr->back ().message);
        ptr->pop_back();
        return message;
    }
    else
        return log4cplus::tstring ();
}

void
NDC::pop_void ()
{
    DiagnosticContextStack* ptr = getPtr ();
    if (! ptr->empty ())
        ptr->pop_back ();
}

log4cplus::tstring const &
NDC::peek() const
{
    DiagnosticContextStack* ptr = getPtr();
    if(!ptr->empty())
        return ptr->back().message;
    else
        return internal::empty_str;
}

void
NDC::push(const log4cplus::tstring& message)
{
    push_worker (message);
}

void
NDC::push(tchar const * message)
{
    push_worker (message);
}

template <typename StringType>
void
NDC::push_worker (StringType const & message)
{
    DiagnosticContextStack* ptr = getPtr();
    if (ptr->empty())
        ptr->push_back( DiagnosticContext(message, NULL) );
    else
    {
        DiagnosticContext const & dc = ptr->back();
        ptr->push_back( DiagnosticContext(message, &dc) );
    }
}

void
NDC::remove()
{
    DiagnosticContextStack* ptr = getPtr();
    DiagnosticContextStack ().swap (*ptr);
}

void
NDC::setMaxDepth(std::size_t maxDepth)
{
    DiagnosticContextStack* ptr = getPtr();
    while(maxDepth < ptr->size())
        ptr->pop_back();
}

DiagnosticContextStack* NDC::getPtr()
{
    internal::per_thread_data * ptd = internal::get_ptd ();
    return &ptd->ndc_dcs;
}

//
//
//

NDCContextCreator::NDCContextCreator(const log4cplus::tstring& msg)
{
    getNDC().push(msg);
}

NDCContextCreator::NDCContextCreator(tchar const * msg)
{
    getNDC().push(msg);
}

NDCContextCreator::~NDCContextCreator()
{
    getNDC().pop_void();
}

} // namespace log4cplus
<commit_msg>ndc.cxx: Implement remove() in terms of clear().<commit_after>// Module:  Log4CPLUS
// File:    ndc.cxx
// Created: 6/2001
// Author:  Tad E. Smith
//
//
// Copyright 2001-2015 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <log4cplus/ndc.h>
#include <log4cplus/internal/internal.h>
#include <utility>
#include <algorithm>

namespace log4cplus
{

///////////////////////////////////////////////////////////////////////////////
// log4cplus::DiagnosticContext ctors
///////////////////////////////////////////////////////////////////////////////

namespace
{

static
void
init_full_message (log4cplus::tstring & fullMessage,
    log4cplus::tstring const & message, DiagnosticContext const * parent)
{
    if (parent)
    {
        fullMessage.reserve (parent->fullMessage.size () + 1
            + message.size ());
        fullMessage = parent->fullMessage;
        fullMessage += LOG4CPLUS_TEXT(" ");
        fullMessage += message;
    }
    else
        fullMessage = message;
}

} // namespace

DiagnosticContext::DiagnosticContext(const log4cplus::tstring& message_,
                                     DiagnosticContext const * parent)
    : message(message_)
    , fullMessage()
{
    init_full_message (fullMessage, message, parent);
}

DiagnosticContext::DiagnosticContext(tchar const * message_,
                                     DiagnosticContext const * parent)
    : message(message_)
    , fullMessage()
{
    init_full_message (fullMessage, message, parent);
}

DiagnosticContext::DiagnosticContext(const log4cplus::tstring& message_)
    : message(message_)
    , fullMessage(message)
{
}

DiagnosticContext::DiagnosticContext(tchar const * message_)
    : message(message_)
    , fullMessage(message)
{
}

DiagnosticContext::DiagnosticContext (DiagnosticContext const & other)
    : message (other.message)
    , fullMessage (other.fullMessage)
{ }

DiagnosticContext & DiagnosticContext::operator = (
    DiagnosticContext const & other)
{
    DiagnosticContext (other).swap (*this);
    return *this;
}

#if defined (LOG4CPLUS_HAVE_RVALUE_REFS)
DiagnosticContext::DiagnosticContext (DiagnosticContext && other)
    : message (std::move (other.message))
    , fullMessage (std::move (other.fullMessage))
{ }

DiagnosticContext &
DiagnosticContext::operator = (DiagnosticContext && other)
{
    DiagnosticContext (std::move (other)).swap (*this);
    return *this;
}

#endif

void
DiagnosticContext::swap (DiagnosticContext & other)
{
    using std::swap;
    swap (message, other.message);
    swap (fullMessage, other.fullMessage);
}

///////////////////////////////////////////////////////////////////////////////
// log4cplus::NDC ctor and dtor
///////////////////////////////////////////////////////////////////////////////

NDC::NDC()
{ }

NDC::~NDC()
{ }

///////////////////////////////////////////////////////////////////////////////
// log4cplus::NDC public methods
///////////////////////////////////////////////////////////////////////////////

void
NDC::clear()
{
    DiagnosticContextStack* ptr = getPtr();
    DiagnosticContextStack ().swap (*ptr);
}

void
NDC::remove()
{
    clear();
}

DiagnosticContextStack
NDC::cloneStack() const
{
    DiagnosticContextStack* ptr = getPtr();
    return DiagnosticContextStack(*ptr);
}

void
NDC::inherit(const DiagnosticContextStack& stack)
{
    DiagnosticContextStack* ptr = getPtr();
    DiagnosticContextStack (stack).swap (*ptr);
}

log4cplus::tstring const &
NDC::get() const
{
    DiagnosticContextStack* ptr = getPtr();
    if(!ptr->empty())
        return ptr->back().fullMessage;
    else
        return internal::empty_str;
}

std::size_t
NDC::getDepth() const
{
    DiagnosticContextStack* ptr = getPtr();
    return ptr->size();
}

log4cplus::tstring
NDC::pop()
{
    DiagnosticContextStack* ptr = getPtr();
    if(!ptr->empty())
    {
        tstring message;
        message.swap (ptr->back ().message);
        ptr->pop_back();
        return message;
    }
    else
        return log4cplus::tstring ();
}

void
NDC::pop_void ()
{
    DiagnosticContextStack* ptr = getPtr ();
    if (! ptr->empty ())
        ptr->pop_back ();
}

log4cplus::tstring const &
NDC::peek() const
{
    DiagnosticContextStack* ptr = getPtr();
    if(!ptr->empty())
        return ptr->back().message;
    else
        return internal::empty_str;
}

void
NDC::push(const log4cplus::tstring& message)
{
    push_worker (message);
}

void
NDC::push(tchar const * message)
{
    push_worker (message);
}

template <typename StringType>
void
NDC::push_worker (StringType const & message)
{
    DiagnosticContextStack* ptr = getPtr();
    if (ptr->empty())
        ptr->push_back( DiagnosticContext(message, NULL) );
    else
    {
        DiagnosticContext const & dc = ptr->back();
        ptr->push_back( DiagnosticContext(message, &dc) );
    }
}

void
NDC::setMaxDepth(std::size_t maxDepth)
{
    DiagnosticContextStack* ptr = getPtr();
    while(maxDepth < ptr->size())
        ptr->pop_back();
}

DiagnosticContextStack* NDC::getPtr()
{
    internal::per_thread_data * ptd = internal::get_ptd ();
    return &ptd->ndc_dcs;
}

//
//
//

NDCContextCreator::NDCContextCreator(const log4cplus::tstring& msg)
{
    getNDC().push(msg);
}

NDCContextCreator::NDCContextCreator(tchar const * msg)
{
    getNDC().push(msg);
}

NDCContextCreator::~NDCContextCreator()
{
    getNDC().pop_void();
}

} // namespace log4cplus
<|endoftext|>


<commit_before>
// LightSample.cpp :  α׷  Ŭ  մϴ.
//

#include "stdafx.h"
#include "resource.h"		//  ȣԴϴ.
#include "D3DView.h"
#include "TopPanel.h"
#include "Controller.h"
#include <MMSystem.h>

class CLightSampleApp : public CWinApp
{
public:
	CLightSampleApp();
	virtual BOOL InitInstance();
	DECLARE_MESSAGE_MAP()
};

extern CLightSampleApp theApp;

// CLightSampleDlg ȭ
class CLightSampleDlg : public CDialogEx
{
public:
	CLightSampleDlg(CWnd* pParent = NULL);	// ǥ Դϴ.

	enum { IDD = IDD_LIGHTSAMPLE_DIALOG };

	void MainLoop();

protected:
	HICON m_hIcon;
	CD3DView *m_view;
	bool m_loop;

	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV Դϴ.

	//  ޽  Լ
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedOk();
	afx_msg void OnBnClickedCancel();
};

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CLightSampleApp

BEGIN_MESSAGE_MAP(CLightSampleApp, CWinApp)
	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()

// CLightSampleApp

CLightSampleApp::CLightSampleApp()
{
	// ٽ
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
}

CLightSampleApp theApp;

// CLightSampleApp ʱȭ

BOOL CLightSampleApp::InitInstance()
{
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();
	AfxEnableControlContainer();

	CLightSampleDlg *dlg = new CLightSampleDlg();
	dlg->Create(CLightSampleDlg::IDD);
	m_pMainWnd = dlg;

	dlg->ShowWindow(SW_SHOW);
	dlg->MainLoop();

	delete dlg;
	return FALSE;
}

// CLightSampleDlg ȭ

CLightSampleDlg::CLightSampleDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CLightSampleDlg::IDD, pParent)
,	m_loop(true)
,	m_view(NULL)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CLightSampleDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CLightSampleDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &CLightSampleDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDCANCEL, &CLightSampleDlg::OnBnClickedCancel)
END_MESSAGE_MAP()

// CLightSampleDlg ޽ ó

BOOL CLightSampleDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// ý ޴ "..." ޴ ׸ ߰մϴ.

	// IDM_ABOUTBOX ý   ־ մϴ.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	SetIcon(m_hIcon, TRUE);			// ū  մϴ.
	SetIcon(m_hIcon, FALSE);		//   մϴ.

	MoveWindow(CRect(0,0,REAL_WINDOW_WIDTH,REAL_WINDOW_HEIGHT));

	// Create Main Model View
	m_view = new CD3DView();
	m_view->Create(NULL, _T("CView"), WS_CHILDWINDOW,
		CRect(0,0, VIEW_WIDTH, VIEW_HEIGHT), this, 0);

	// Create Direct
	graphic::cRenderer::Get()->CreateDirectX(
		m_view->GetSafeHwnd(), VIEW_WIDTH, VIEW_HEIGHT);

	m_view->Init();
	cController::Get()->Init();
	m_view->ShowWindow(SW_SHOW);

	// TopPanel .
	{
		const int PANEL_WIDTH = 420;
		const int PANEL_HEIGHT = 600;

		CTopPanel *dlg = new CTopPanel();
		const CString StrClassName = AfxRegisterWndClass( CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
			LoadCursor(NULL, IDC_ARROW), (HBRUSH)GetStockObject(COLOR_BTNFACE+1),
			LoadIcon(NULL, IDI_APPLICATION) );

		dlg->CreateEx(0, StrClassName, L"Top Panel",
			WS_POPUP | WS_CAPTION | WS_SYSMENU | MFS_THICKFRAME,
			CRect(0, 0, PANEL_WIDTH, PANEL_HEIGHT), this );

		dlg->Init();

		// TopPanel Positioning
		{
			CRect panelR;
			dlg->GetWindowRect(panelR);

			const int screenCX = GetSystemMetrics(SM_CXSCREEN);
			const int screenCY = GetSystemMetrics(SM_CYSCREEN);
			int x = screenCX/2 - REAL_WINDOW_WIDTH/2 + REAL_WINDOW_WIDTH - panelR.Width()/2;
			const int y = screenCY/2 - REAL_WINDOW_HEIGHT/2;

			if ((x+panelR.Width()) > screenCX)
				x = screenCX - panelR.Width();

			dlg->MoveWindow(x, y, panelR.Width(), panelR.Height());

			// Main Dialog RePositioning
			int px = screenCX/2 - REAL_WINDOW_WIDTH/2 - panelR.Width()/2;
			px = max(0, px);
			MoveWindow(px, y, REAL_WINDOW_WIDTH,REAL_WINDOW_HEIGHT);
		}

		dlg->ShowWindow(SW_SHOW);
	}

	return TRUE;  // Ŀ Ʈѿ   TRUE ȯմϴ.
}

void CLightSampleDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

void CLightSampleDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // ׸⸦  ̽ ؽƮԴϴ.

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Ŭ̾Ʈ 簢   ϴ.
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		//  ׸ϴ.
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

// ڰ ּȭ â  ȿ Ŀ ǥõǵ ýۿ
//   Լ ȣմϴ.
HCURSOR CLightSampleDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CLightSampleDlg::OnBnClickedOk()
{
	CDialogEx::OnOK();
}

void CLightSampleDlg::OnBnClickedCancel()
{
	m_loop = false;
	CDialogEx::OnCancel();
}

void CLightSampleDlg::MainLoop()
{
	while (m_loop)
	{
		MSG msg;
		if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if (!GetMessage(&msg, NULL, 0, 0))
			{
				break;
			}
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}

		const int curT = timeGetTime();
		static int oldT = curT;
		const int elapseT = curT - oldT;
		const float t = elapseT * 0.001f;
		oldT = curT;

		if (m_view)
		{
			m_view->Update(t);
			m_view->Render();
		}

		Sleep(0);
	}
}
<commit_msg>update comment<commit_after>//
//
//    Ʈ
// http://www.directxtutorial.com/Lesson.aspx?lessonid=9-4-9
//

#include "stdafx.h"
#include "resource.h"		//  ȣԴϴ.
#include "D3DView.h"
#include "TopPanel.h"
#include "Controller.h"
#include <MMSystem.h>

class CLightSampleApp : public CWinApp
{
public:
	CLightSampleApp();
	virtual BOOL InitInstance();
	DECLARE_MESSAGE_MAP()
};

extern CLightSampleApp theApp;

// CLightSampleDlg ȭ
class CLightSampleDlg : public CDialogEx
{
public:
	CLightSampleDlg(CWnd* pParent = NULL);	// ǥ Դϴ.

	enum { IDD = IDD_LIGHTSAMPLE_DIALOG };

	void MainLoop();

protected:
	HICON m_hIcon;
	CD3DView *m_view;
	bool m_loop;

	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV Դϴ.

	//  ޽  Լ
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedOk();
	afx_msg void OnBnClickedCancel();
};

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CLightSampleApp

BEGIN_MESSAGE_MAP(CLightSampleApp, CWinApp)
	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()

// CLightSampleApp

CLightSampleApp::CLightSampleApp()
{
	// ٽ
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
}

CLightSampleApp theApp;

// CLightSampleApp ʱȭ

BOOL CLightSampleApp::InitInstance()
{
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();
	AfxEnableControlContainer();

	CLightSampleDlg *dlg = new CLightSampleDlg();
	dlg->Create(CLightSampleDlg::IDD);
	m_pMainWnd = dlg;

	dlg->ShowWindow(SW_SHOW);
	dlg->MainLoop();

	delete dlg;
	return FALSE;
}

// CLightSampleDlg ȭ

CLightSampleDlg::CLightSampleDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CLightSampleDlg::IDD, pParent)
,	m_loop(true)
,	m_view(NULL)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CLightSampleDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CLightSampleDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &CLightSampleDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDCANCEL, &CLightSampleDlg::OnBnClickedCancel)
END_MESSAGE_MAP()

// CLightSampleDlg ޽ ó

BOOL CLightSampleDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// ý ޴ "..." ޴ ׸ ߰մϴ.

	// IDM_ABOUTBOX ý   ־ մϴ.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	SetIcon(m_hIcon, TRUE);			// ū  մϴ.
	SetIcon(m_hIcon, FALSE);		//   մϴ.

	MoveWindow(CRect(0,0,REAL_WINDOW_WIDTH,REAL_WINDOW_HEIGHT));

	// Create Main Model View
	m_view = new CD3DView();
	m_view->Create(NULL, _T("CView"), WS_CHILDWINDOW,
		CRect(0,0, VIEW_WIDTH, VIEW_HEIGHT), this, 0);

	// Create Direct
	graphic::cRenderer::Get()->CreateDirectX(
		m_view->GetSafeHwnd(), VIEW_WIDTH, VIEW_HEIGHT);

	m_view->Init();
	cController::Get()->Init();
	m_view->ShowWindow(SW_SHOW);

	// TopPanel .
	{
		const int PANEL_WIDTH = 420;
		const int PANEL_HEIGHT = 600;

		CTopPanel *dlg = new CTopPanel();
		const CString StrClassName = AfxRegisterWndClass( CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
			LoadCursor(NULL, IDC_ARROW), (HBRUSH)GetStockObject(COLOR_BTNFACE+1),
			LoadIcon(NULL, IDI_APPLICATION) );

		dlg->CreateEx(0, StrClassName, L"Top Panel",
			WS_POPUP | WS_CAPTION | WS_SYSMENU | MFS_THICKFRAME,
			CRect(0, 0, PANEL_WIDTH, PANEL_HEIGHT), this );

		dlg->Init();

		// TopPanel Positioning
		{
			CRect panelR;
			dlg->GetWindowRect(panelR);

			const int screenCX = GetSystemMetrics(SM_CXSCREEN);
			const int screenCY = GetSystemMetrics(SM_CYSCREEN);
			int x = screenCX/2 - REAL_WINDOW_WIDTH/2 + REAL_WINDOW_WIDTH - panelR.Width()/2;
			const int y = screenCY/2 - REAL_WINDOW_HEIGHT/2;

			if ((x+panelR.Width()) > screenCX)
				x = screenCX - panelR.Width();

			dlg->MoveWindow(x, y, panelR.Width(), panelR.Height());

			// Main Dialog RePositioning
			int px = screenCX/2 - REAL_WINDOW_WIDTH/2 - panelR.Width()/2;
			px = max(0, px);
			MoveWindow(px, y, REAL_WINDOW_WIDTH,REAL_WINDOW_HEIGHT);
		}

		dlg->ShowWindow(SW_SHOW);
	}

	return TRUE;  // Ŀ Ʈѿ   TRUE ȯմϴ.
}

void CLightSampleDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

void CLightSampleDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // ׸⸦  ̽ ؽƮԴϴ.

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Ŭ̾Ʈ 簢   ϴ.
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		//  ׸ϴ.
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

// ڰ ּȭ â  ȿ Ŀ ǥõǵ ýۿ
//   Լ ȣմϴ.
HCURSOR CLightSampleDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CLightSampleDlg::OnBnClickedOk()
{
	CDialogEx::OnOK();
}

void CLightSampleDlg::OnBnClickedCancel()
{
	m_loop = false;
	CDialogEx::OnCancel();
}

void CLightSampleDlg::MainLoop()
{
	while (m_loop)
	{
		MSG msg;
		if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if (!GetMessage(&msg, NULL, 0, 0))
			{
				break;
			}
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}

		const int curT = timeGetTime();
		static int oldT = curT;
		const int elapseT = curT - oldT;
		const float t = elapseT * 0.001f;
		oldT = curT;

		if (m_view)
		{
			m_view->Update(t);
			m_view->Render();
		}

		Sleep(0);
	}
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>

#include "VisitorUtils.hpp"
#include "Variable.hpp"
#include "SemanticalException.hpp"

#include "tac/TacCompiler.hpp"
#include "tac/Program.hpp"

#include "ast/Program.hpp"

using namespace eddic;

class CompilerVisitor : public boost::static_visitor<> {
    private:
        StringPool& pool;
        tac::Program& program;

        std::shared_ptr<tac::Function> function;

    public:
        CompilerVisitor(StringPool& p, tac::Program& tacProgram) : pool(p), program(tacProgram) {}

        void operator()(ast::Program& p){
            program.context = p.Content->context;

            visit_each(*this, p.Content->blocks);
        }

        void operator()(ast::FunctionDeclaration& f){
            function = std::make_shared<tac::Function>(f.Content->context);

            //The entry basic block
            function->newBasicBlock();

            visit_each(*this, f.Content->instructions);

            program.functions.push_back(function);
        }

        void operator()(ast::GlobalVariableDeclaration&){
            //Nothing to compile, the global variable values are written using global contexts
        }

        void operator()(ast::GlobalArrayDeclaration&){
            //Nothing to compile, the global arrays are written using global contexts
        }

        void operator()(ast::ArrayDeclaration&){
            //Nothing to compile there, everything is done by the function context
        }

        void operator()(ast::If& if_){

        }

        void operator()(ast::Assignment& assignment){

        }

        void operator()(ast::ArrayAssignment& assignment){

        }

        void operator()(ast::VariableDeclaration& declaration){

        }

        void operator()(ast::Swap& swap){
            auto lhs_var = swap.Content->lhs_var;
            auto rhs_var = swap.Content->rhs_var;

            //We have the guarantee here that both variables are of the same type
            switch (lhs_var->type().base()) {
                case BaseType::INT:{
                    auto temp = swap.Content->context->newTemporary();

                    function->currentBasicBlock()->add(tac::Quadruple(temp, rhs_var));
                    function->currentBasicBlock()->add(tac::Quadruple(rhs_var, lhs_var));
                    function->currentBasicBlock()->add(tac::Quadruple(lhs_var, temp));

                    break;
                }
                case BaseType::STRING:{
  /*                  auto registerA = program.registers(EAX);

                    auto left = lhs_var->toStringOperand();
                    auto right = rhs_var->toStringOperand();

                    program.addInstruction(program.factory().createMove(left.first, registerA));
                    program.addInstruction(program.factory().createMove(right.first, left.first));
                    program.addInstruction(program.factory().createMove(registerA, right.first));

                    program.addInstruction(program.factory().createMove(left.second, registerA));
                    program.addInstruction(program.factory().createMove(right.second, left.second));
                    program.addInstruction(program.factory().createMove(registerA, right.second));
    */
                    break;
                }
                default:
                   throw SemanticalException("Variable of invalid type");
            }
        }

        void operator()(ast::While& while_){

        }

        void operator()(ast::For for_){

        }

        void operator()(ast::Foreach&){
            assert(false); //This node has been transformed into a for node
        }

        void operator()(ast::ForeachIn& foreach){

        }

        void operator()(ast::FunctionCall& functionCall){

        }

        void operator()(ast::Return& return_){

        }
};

void tac::TacCompiler::compile(ast::Program& program, StringPool& pool, tac::Program& tacProgram) const {
    CompilerVisitor visitor(pool, tacProgram);
    visitor(program);
}
<commit_msg>Compile string variables swap<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>

#include "VisitorUtils.hpp"
#include "Variable.hpp"
#include "SemanticalException.hpp"

#include "tac/TacCompiler.hpp"
#include "tac/Program.hpp"

#include "ast/Program.hpp"

using namespace eddic;

class CompilerVisitor : public boost::static_visitor<> {
    private:
        StringPool& pool;
        tac::Program& program;

        std::shared_ptr<tac::Function> function;

    public:
        CompilerVisitor(StringPool& p, tac::Program& tacProgram) : pool(p), program(tacProgram) {}

        void operator()(ast::Program& p){
            program.context = p.Content->context;

            visit_each(*this, p.Content->blocks);
        }

        void operator()(ast::FunctionDeclaration& f){
            function = std::make_shared<tac::Function>(f.Content->context);

            //The entry basic block
            function->newBasicBlock();

            visit_each(*this, f.Content->instructions);

            program.functions.push_back(function);
        }

        void operator()(ast::GlobalVariableDeclaration&){
            //Nothing to compile, the global variable values are written using global contexts
        }

        void operator()(ast::GlobalArrayDeclaration&){
            //Nothing to compile, the global arrays are written using global contexts
        }

        void operator()(ast::ArrayDeclaration&){
            //Nothing to compile there, everything is done by the function context
        }

        void operator()(ast::If& if_){

        }

        void operator()(ast::Assignment& assignment){

        }

        void operator()(ast::ArrayAssignment& assignment){

        }

        void operator()(ast::VariableDeclaration& declaration){

        }

        void operator()(ast::Swap& swap){
            auto lhs_var = swap.Content->lhs_var;
            auto rhs_var = swap.Content->rhs_var;

            //We have the guarantee here that both variables are of the same type
            switch (lhs_var->type().base()) {
                case BaseType::INT:{
                    auto temp = swap.Content->context->newTemporary();

                    function->currentBasicBlock()->add(tac::Quadruple(temp, rhs_var));
                    function->currentBasicBlock()->add(tac::Quadruple(rhs_var, lhs_var));
                    function->currentBasicBlock()->add(tac::Quadruple(lhs_var, temp));

                    break;
                }
                case BaseType::STRING:{
                    auto temp = swap.Content->context->newTemporary();

                    function->currentBasicBlock()->add(tac::Quadruple(temp, rhs_var));
                    function->currentBasicBlock()->add(tac::Quadruple(rhs_var, lhs_var));
                    function->currentBasicBlock()->add(tac::Quadruple(lhs_var, temp));

                    function->currentBasicBlock()->add(tac::Quadruple(temp, rhs_var, tac::Operator::DOT, 4));
                    function->currentBasicBlock()->add(tac::Quadruple(rhs_var, lhs_var, tac::Operator::DOT, 4));
                    function->currentBasicBlock()->add(tac::Quadruple(lhs_var, temp));

                    break;
                }
                default:
                   throw SemanticalException("Variable of invalid type");
            }
        }

        void operator()(ast::While& while_){

        }

        void operator()(ast::For for_){

        }

        void operator()(ast::Foreach&){
            assert(false); //This node has been transformed into a for node
        }

        void operator()(ast::ForeachIn& foreach){

        }

        void operator()(ast::FunctionCall& functionCall){

        }

        void operator()(ast::Return& return_){

        }
};

void tac::TacCompiler::compile(ast::Program& program, StringPool& pool, tac::Program& tacProgram) const {
    CompilerVisitor visitor(pool, tacProgram);
    visitor(program);
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    MetaImageImporter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include <iostream>
#include <string>
#include <list>
#include <fstream>

int main(int argc, char **argv)
  {
  std::cout << "Importing your data into the MetaImage format"
    << std::endl
    << "  is merely of matter of making a text file that"
    << std::endl
    << "  contains some info about your data and that also"
    << std::endl
    << "  lists the file(s) that contain your data."
    << std::endl
    << std::endl
    << "This program helps you create that text file - we"
    << std::endl
    << "  designate these text files with the suffix '.mhd'"
    << std::endl
    << std::endl;

  std::string filename;
  std::cout << "What is the name of the '.mhd' file that you"
    << std::endl
    << "  want to create?   Please include '.mhd' at the end."
    << std::endl
    << "  -=> ";
  std::cin >> filename;
  std::cout << std::endl;

  std::ofstream fp;
  fp.open(filename.c_str());

  std::cout << "What is the dimensionality of your data (1, 2, 3, ...)?"
    << std::endl
    << "  -=> ";
  int nDims;
  std::cin >> nDims;
  if(nDims < 1)
    {
    std::cout << "...have a nice day" << std::endl;
    return 1;
    }
  std::cout << std::endl;
  fp << "NDims = " << nDims << std::endl;

  int i;
  int * dimSize = new int [nDims];
  std::cout << "Assuming dimension 0 is the 'x' dimension..." << std::endl;
  for(i = 0; i < nDims; i++)
    {
    std::cout << "  How large is dimension " << i << " -=> ";
    std::cin >> dimSize[i];
    if(dimSize[i]<1)
      {
      std::cout << "    ...we'll assume you meant 1..." << std::endl;
      dimSize[i] = 1;
      }
    }
  std::cout << std::endl;
  fp << "DimSize =";
  for(i = 0; i < nDims; i++)
    {
    fp << " " << dimSize[i];
    }
  fp << std::endl;

  float * pointSpacing = new float [nDims];
  std::cout << "Points in an image represent a measure in physical space."
    << std::endl
    << "   Measures in physical space are done using a particular"
    << std::endl
    << "   aperature spacing - that is, what is the spacing of the"
    << std::endl
    << "   points in your data...if you don't know/care, answer 1."
    << std::endl;
  for(i = 0; i < nDims; i++)
    {
    std::cout << "  What is the point spacing in dimension " << i << "? -=> ";
    std::cin >> pointSpacing[i];
    if(pointSpacing[i]<0.0000000000000001)
      {
      std::cout << "...we'll assume you meant 1..." << std::endl;
      pointSpacing[i] = 1;
      }
    }
  std::cout << std::endl;
  fp << "ElementSpacing =";
  for(i = 0; i < nDims; i++)
    {
    fp << " " << pointSpacing[i];
    }
  fp << std::endl;

  float * origin = new float [nDims];
  std::cout << "Images are taken of a particular location in space."
    << std::endl
    << "   That is, they have an origin in space...if you don't"
    << std::endl
    << "   know/care, answer 0 for each dimension."
    << std::endl;
  for(i = 0; i < nDims; i++)
    {
    std::cout << "  What is the origin in dimension " << i << "? -=> ";
    std::cin >> origin[i];
    }
  std::cout << std::endl;
  fp << "Position =";
  for(i = 0; i < nDims; i++)
    {
    fp << " " << origin[i];
    }
  fp << std::endl;

  bool byteOrderMSB = false;
  std::cout << "Is your data stored using MSB byte ordering?"
    << std::endl
    << "  Data written on a 'PC' is in 'Little-endian' byte order."
    << std::endl
    << "  Data from almost every other machine is in 'Big-endian'"
    << std::endl
    << "  byte order.  If your data was written on a 'PC', enter 0."
    << std::endl
    << "  Otherwise, if you data was written on a Mac/Sun/Other, enter 1."
    << std::endl
    << "  -=> ";
  std::cin >> byteOrderMSB;
  std::cout << std::endl;
  if(byteOrderMSB)
    {
    fp << "ElementByteOrderMSB = True" << std::endl;
    }
  else
    {
    fp << "ElementByteOrderMSB = False" << std::endl;
    }

  int nComps = 1;
  std::cout << "How many channels are stored at each point in your image?"
    << std::endl
    << "  For example, RGB images have 3 channels, and most medical"
    << std::endl
    << "  images have a single channel."
    << std::endl
    << "  -=> ";
  std::cin >> nComps;
  std::cout << std::endl;
  if(nComps<1)
    {
    nComps = 1;
    }
  if(nComps != 1)
    {
    fp << "ElementNumberOfChannels = " << nComps << std::endl;
    }

  int elementType;
  std::cout << "What is the 'type' of the elements in your data :"
    << std::endl
    << "  0 - signed char (one byte)" << std::endl
    << "  1 - unsigned char" << std::endl
    << "  2 - signed short (two byte)" << std::endl
    << "  3 - unsigned short" << std::endl
    << "  4 - signed int (four byte)" << std::endl
    << "  5 - unsigned int" << std::endl
    << "  6 - float (four byte)" << std::endl
    << "  7 - double (eight byte)" << std::endl
    << "  -=> ";
  std::cin >> elementType;
  std::cout << std::endl;
  switch(elementType)
    {
    case 0 : fp << "ElementType = MET_CHAR" << std::endl;
      break;
    case 1 : fp << "ElementType = MET_UCHAR" << std::endl;
      break;
    case 2 : fp << "ElementType = MET_SHORT" << std::endl;
      break;
    case 3 : fp << "ElementType = MET_USHORT" << std::endl;
      break;
    case 4 : fp << "ElementType = MET_INT" << std::endl;
      break;
    case 5 : fp << "ElementType = MET_UINT" << std::endl;
      break;
    case 6 : fp << "ElementType = MET_FLOAT" << std::endl;
      break;
    case 7 : fp << "ElementType = MET_DOUBLE" << std::endl;
      break;
    default: fp.close();
      std::cout << "...have a nice day." << std::endl;
    }

  int storage = 0;
  std::cout << "How is the data stored ?" << std::endl
    << "  0 - in one file" << std::endl
    << "  1 - in one file per slice (e.g., like dicom)" << std::endl
    << "  -=> ";
  std::cin >> storage;
  std::cout << std::endl;

  int headerSize = -1;
  std::cout << "Size of the header that must be skipped to"
    << std::endl
    << "  reach the data in the file(s)? Enter 0 to not skip"
    << std::endl
    << "  a header, -1 to have MetaImageReader automatically"
    << std::endl
    << "  calculate the headersize assuming the data is at"
    << std::endl
    << "  the end of the file, or enter the headersize"
    << std::endl
    << "  -=> ";
  std::cin >> headerSize;
  std::cout << std::endl;
  if(headerSize > 0 || headerSize == -1)
    {
    fp << "HeaderSize = " << headerSize << std::endl;
    }

  int storageList = 0;
  if(storage == 0)
    {
    std::string fname;
    std::cout << "Name of the file containing the data -=> ";
    std::cin >> fname;
    fp << "ElementDataFile = " << fname << std::endl;
    fp.close();
    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << "You're done!" << std::endl;
    std::cout << std::endl;
    }
  else
    {
    std::cout << "You've got two options when doing one file per slice:"
      << std::endl
      << "  0 - Listing the name of each slice in the .mhd file"
      << std::endl
      << "  1 - Specifying a 'fprintf' style string and min, max,"
      << std::endl
      << "        and step values for integers to be substituted"
      << std::endl
      << "        into that string to specify the numbered files"
      << std::endl
      << "        that are the slices.  For example, use data.%03d to"
      << std::endl
      << "        match data.000, data.001, data.002,...If you don't"
      << std::endl
      << "        know what we are talking about, choose option 0."
      << std::endl
      << "  -=> ";
    std::cin >> storageList;
    std::cout << std::endl;

    if(storageList == 0)
      {
      fp << "ElementDataFile = LIST" << std::endl;
      std::string str;
      for(i=0; i<dimSize[nDims-1]; i++)
        {
        std::cout << "Filename of slice " << i << " -=> ";
        std::cin >> str;
        fp << str << std::endl;
        str.erase();
        }
      fp.close();
      std::cout << std::endl;
      std::cout << std::endl;
      std::cout << "You're done!" << std::endl;
      std::cout << std::endl;
      }
    else
      {
      std::string storageListString;
      float storageListStringMin;
      float storageListStringMax;
      float storageListStringStep;
      std::cout << "Filename string -=> ";
      std::cin >> storageListString;
      std::cout << "  Min value to substitute into string -=> ";
      std::cin >> storageListStringMin;
      std::cout << "  Max value to substitute into string -=> ";
      std::cin >> storageListStringMax;
      std::cout << "  Step size to use to go from min to max -=> ";
      std::cin >> storageListStringStep;
      std::cout << std::endl;
      fp << "ElementDataFile = " << storageListString << " "
        << storageListStringMin << " " << storageListStringMax << " "
        << storageListStringStep << std::endl;
      fp.close();
      std::cout << std::endl;
      std::cout << std::endl;
      std::cout << "You're done!" << std::endl;
      std::cout << std::endl;
      }
    }

  return 0;
  }
<commit_msg>FIX: <fstream> must be the first header to be included.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    MetaImageImporter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include <fstream>
#include <iostream>
#include <string>
#include <list>

int main(int argc, char **argv)
  {
  std::cout << "Importing your data into the MetaImage format"
    << std::endl
    << "  is merely of matter of making a text file that"
    << std::endl
    << "  contains some info about your data and that also"
    << std::endl
    << "  lists the file(s) that contain your data."
    << std::endl
    << std::endl
    << "This program helps you create that text file - we"
    << std::endl
    << "  designate these text files with the suffix '.mhd'"
    << std::endl
    << std::endl;

  std::string filename;
  std::cout << "What is the name of the '.mhd' file that you"
    << std::endl
    << "  want to create?   Please include '.mhd' at the end."
    << std::endl
    << "  -=> ";
  std::cin >> filename;
  std::cout << std::endl;

  std::ofstream fp;
  fp.open(filename.c_str());

  std::cout << "What is the dimensionality of your data (1, 2, 3, ...)?"
    << std::endl
    << "  -=> ";
  int nDims;
  std::cin >> nDims;
  if(nDims < 1)
    {
    std::cout << "...have a nice day" << std::endl;
    return 1;
    }
  std::cout << std::endl;
  fp << "NDims = " << nDims << std::endl;

  int i;
  int * dimSize = new int [nDims];
  std::cout << "Assuming dimension 0 is the 'x' dimension..." << std::endl;
  for(i = 0; i < nDims; i++)
    {
    std::cout << "  How large is dimension " << i << " -=> ";
    std::cin >> dimSize[i];
    if(dimSize[i]<1)
      {
      std::cout << "    ...we'll assume you meant 1..." << std::endl;
      dimSize[i] = 1;
      }
    }
  std::cout << std::endl;
  fp << "DimSize =";
  for(i = 0; i < nDims; i++)
    {
    fp << " " << dimSize[i];
    }
  fp << std::endl;

  float * pointSpacing = new float [nDims];
  std::cout << "Points in an image represent a measure in physical space."
    << std::endl
    << "   Measures in physical space are done using a particular"
    << std::endl
    << "   aperature spacing - that is, what is the spacing of the"
    << std::endl
    << "   points in your data...if you don't know/care, answer 1."
    << std::endl;
  for(i = 0; i < nDims; i++)
    {
    std::cout << "  What is the point spacing in dimension " << i << "? -=> ";
    std::cin >> pointSpacing[i];
    if(pointSpacing[i]<0.0000000000000001)
      {
      std::cout << "...we'll assume you meant 1..." << std::endl;
      pointSpacing[i] = 1;
      }
    }
  std::cout << std::endl;
  fp << "ElementSpacing =";
  for(i = 0; i < nDims; i++)
    {
    fp << " " << pointSpacing[i];
    }
  fp << std::endl;

  float * origin = new float [nDims];
  std::cout << "Images are taken of a particular location in space."
    << std::endl
    << "   That is, they have an origin in space...if you don't"
    << std::endl
    << "   know/care, answer 0 for each dimension."
    << std::endl;
  for(i = 0; i < nDims; i++)
    {
    std::cout << "  What is the origin in dimension " << i << "? -=> ";
    std::cin >> origin[i];
    }
  std::cout << std::endl;
  fp << "Position =";
  for(i = 0; i < nDims; i++)
    {
    fp << " " << origin[i];
    }
  fp << std::endl;

  bool byteOrderMSB = false;
  std::cout << "Is your data stored using MSB byte ordering?"
    << std::endl
    << "  Data written on a 'PC' is in 'Little-endian' byte order."
    << std::endl
    << "  Data from almost every other machine is in 'Big-endian'"
    << std::endl
    << "  byte order.  If your data was written on a 'PC', enter 0."
    << std::endl
    << "  Otherwise, if you data was written on a Mac/Sun/Other, enter 1."
    << std::endl
    << "  -=> ";
  std::cin >> byteOrderMSB;
  std::cout << std::endl;
  if(byteOrderMSB)
    {
    fp << "ElementByteOrderMSB = True" << std::endl;
    }
  else
    {
    fp << "ElementByteOrderMSB = False" << std::endl;
    }

  int nComps = 1;
  std::cout << "How many channels are stored at each point in your image?"
    << std::endl
    << "  For example, RGB images have 3 channels, and most medical"
    << std::endl
    << "  images have a single channel."
    << std::endl
    << "  -=> ";
  std::cin >> nComps;
  std::cout << std::endl;
  if(nComps<1)
    {
    nComps = 1;
    }
  if(nComps != 1)
    {
    fp << "ElementNumberOfChannels = " << nComps << std::endl;
    }

  int elementType;
  std::cout << "What is the 'type' of the elements in your data :"
    << std::endl
    << "  0 - signed char (one byte)" << std::endl
    << "  1 - unsigned char" << std::endl
    << "  2 - signed short (two byte)" << std::endl
    << "  3 - unsigned short" << std::endl
    << "  4 - signed int (four byte)" << std::endl
    << "  5 - unsigned int" << std::endl
    << "  6 - float (four byte)" << std::endl
    << "  7 - double (eight byte)" << std::endl
    << "  -=> ";
  std::cin >> elementType;
  std::cout << std::endl;
  switch(elementType)
    {
    case 0 : fp << "ElementType = MET_CHAR" << std::endl;
      break;
    case 1 : fp << "ElementType = MET_UCHAR" << std::endl;
      break;
    case 2 : fp << "ElementType = MET_SHORT" << std::endl;
      break;
    case 3 : fp << "ElementType = MET_USHORT" << std::endl;
      break;
    case 4 : fp << "ElementType = MET_INT" << std::endl;
      break;
    case 5 : fp << "ElementType = MET_UINT" << std::endl;
      break;
    case 6 : fp << "ElementType = MET_FLOAT" << std::endl;
      break;
    case 7 : fp << "ElementType = MET_DOUBLE" << std::endl;
      break;
    default: fp.close();
      std::cout << "...have a nice day." << std::endl;
    }

  int storage = 0;
  std::cout << "How is the data stored ?" << std::endl
    << "  0 - in one file" << std::endl
    << "  1 - in one file per slice (e.g., like dicom)" << std::endl
    << "  -=> ";
  std::cin >> storage;
  std::cout << std::endl;

  int headerSize = -1;
  std::cout << "Size of the header that must be skipped to"
    << std::endl
    << "  reach the data in the file(s)? Enter 0 to not skip"
    << std::endl
    << "  a header, -1 to have MetaImageReader automatically"
    << std::endl
    << "  calculate the headersize assuming the data is at"
    << std::endl
    << "  the end of the file, or enter the headersize"
    << std::endl
    << "  -=> ";
  std::cin >> headerSize;
  std::cout << std::endl;
  if(headerSize > 0 || headerSize == -1)
    {
    fp << "HeaderSize = " << headerSize << std::endl;
    }

  int storageList = 0;
  if(storage == 0)
    {
    std::string fname;
    std::cout << "Name of the file containing the data -=> ";
    std::cin >> fname;
    fp << "ElementDataFile = " << fname << std::endl;
    fp.close();
    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << "You're done!" << std::endl;
    std::cout << std::endl;
    }
  else
    {
    std::cout << "You've got two options when doing one file per slice:"
      << std::endl
      << "  0 - Listing the name of each slice in the .mhd file"
      << std::endl
      << "  1 - Specifying a 'fprintf' style string and min, max,"
      << std::endl
      << "        and step values for integers to be substituted"
      << std::endl
      << "        into that string to specify the numbered files"
      << std::endl
      << "        that are the slices.  For example, use data.%03d to"
      << std::endl
      << "        match data.000, data.001, data.002,...If you don't"
      << std::endl
      << "        know what we are talking about, choose option 0."
      << std::endl
      << "  -=> ";
    std::cin >> storageList;
    std::cout << std::endl;

    if(storageList == 0)
      {
      fp << "ElementDataFile = LIST" << std::endl;
      std::string str;
      for(i=0; i<dimSize[nDims-1]; i++)
        {
        std::cout << "Filename of slice " << i << " -=> ";
        std::cin >> str;
        fp << str << std::endl;
        str.erase();
        }
      fp.close();
      std::cout << std::endl;
      std::cout << std::endl;
      std::cout << "You're done!" << std::endl;
      std::cout << std::endl;
      }
    else
      {
      std::string storageListString;
      float storageListStringMin;
      float storageListStringMax;
      float storageListStringStep;
      std::cout << "Filename string -=> ";
      std::cin >> storageListString;
      std::cout << "  Min value to substitute into string -=> ";
      std::cin >> storageListStringMin;
      std::cout << "  Max value to substitute into string -=> ";
      std::cin >> storageListStringMax;
      std::cout << "  Step size to use to go from min to max -=> ";
      std::cin >> storageListStringStep;
      std::cout << std::endl;
      fp << "ElementDataFile = " << storageListString << " "
        << storageListStringMin << " " << storageListStringMax << " "
        << storageListStringStep << std::endl;
      fp.close();
      std::cout << std::endl;
      std::cout << std::endl;
      std::cout << "You're done!" << std::endl;
      std::cout << std::endl;
      }
    }

  return 0;
  }
<|endoftext|>


<commit_before>/*
            This file is part of:
                NoahFrame
            https://github.com/ketoo/NoahGameFrame

   Copyright 2009 - 2018 NoahFrame(NoahGameFrame)

   File creator: lvsheng.huang

   NoahFrame is open-source software and you can redistribute it and/or modify
   it under the terms of the License; besides, anyone who use this file/software must include this copyright announcement.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "NFCActorModule.h"

NFCActorModule::NFCActorModule(NFIPluginManager* p)
	:mFramework(NF_ACTOR_THREAD_COUNT)
{
	pPluginManager = p;

    srand((unsigned)time(NULL));

    m_pMainActor = NF_SHARE_PTR<NFIActor>(NF_NEW NFCActor(mFramework, this));
}

NFCActorModule::~NFCActorModule()
{
	m_pMainActor.reset();
	m_pMainActor = nullptr;
}

bool NFCActorModule::Init()
{
    return true;
}

bool NFCActorModule::AfterInit()
{

    return true;
}

bool NFCActorModule::BeforeShut()
{
	mxActorMap.ClearAll();
    return true;
}

bool NFCActorModule::Shut()
{

    return true;
}

bool NFCActorModule::Execute()
{
	ExecuteEvent();
    return true;
}

int NFCActorModule::RequireActor()
{
	NF_SHARE_PTR<NFIActor> pActor = nullptr;
	if (mxActorPool.size() <= 0)
	{
		pActor = NF_SHARE_PTR<NFIActor>(NF_NEW NFCActor(mFramework, this));
		mxActorMap.AddElement(pActor->GetAddress().AsInteger(), pActor);

		return pActor->GetAddress().AsInteger();
	}

	std::map<int, int>::iterator it = mxActorPool.begin();
	int nActorID = it->first;
	mxActorPool.erase(it);

    return nActorID;
}

NF_SHARE_PTR<NFIActor> NFCActorModule::GetActor(const int nActorIndex)
{
	return mxActorMap.GetElement(nActorIndex);
}

bool NFCActorModule::HandlerEx(const NFIActorMessage & message, const int from)
{
	if (message.msgType != NFIActorMessage::ACTOR_MSG_TYPE_COMPONENT)
	{
		return mxQueue.Push(message);
	}

	return false;
}

bool NFCActorModule::ExecuteEvent()
{
	NFIActorMessage xMsg;
	bool bRet = false;
	bRet = mxQueue.TryPop(xMsg);
	while (bRet)
	{
		if (xMsg.msgType != NFIActorMessage::ACTOR_MSG_TYPE_COMPONENT && xMsg.xEndFuncptr != nullptr)
		{
			//Actor can be reused in ActorPool mode, so we don't release it.
			//>ReleaseActor(xMsg.nFormActor);
			ACTOR_PROCESS_FUNCTOR* pFun = xMsg.xEndFuncptr.get();
			pFun->operator()(xMsg.nFormActor, xMsg.nMsgID, xMsg.data);

			NF_SHARE_PTR<NFIActor> xActor = mxActorMap.GetElement(xMsg.nFormActor);
			if (xActor)
			{
				int nActorID = xActor->GetAddress().AsInteger();
				if (mxActorPool.find(nActorID) == mxActorPool.end())
				{
					mxActorPool.insert(std::pair<int, int>(nActorID, 0));
				}
			}
		}

		bRet = mxQueue.TryPop(xMsg);
	}

	return true;
}

bool NFCActorModule::SendMsgToActor(const int nActorIndex, const int nEventID, const std::string& strArg)
{
    NF_SHARE_PTR<NFIActor> pActor = GetActor(nActorIndex);
    if (nullptr != pActor)
    {
        NFIActorMessage xMessage;

		xMessage.msgType = NFIActorMessage::ACTOR_MSG_TYPE_COMPONENT;
        xMessage.data = strArg;
        xMessage.nMsgID = nEventID;
        xMessage.nFormActor = m_pMainActor->GetAddress().AsInteger();

        return mFramework.Send(xMessage, m_pMainActor->GetAddress(), pActor->GetAddress());
    }

    return false;
}

bool NFCActorModule::AddComponent(const int nActorIndex, NF_SHARE_PTR<NFIComponent> pComponent)
{
    NF_SHARE_PTR<NFIActor> pActor = GetActor(nActorIndex);
    if (nullptr != pActor)
    {
        pActor->AddComponent(pComponent);

        return true;
    }

    return false;
}

bool NFCActorModule::ReleaseActor(const int nActorIndex)
{
	return mxActorMap.RemoveElement(nActorIndex);
}

bool NFCActorModule::AddEndFunc(const int nActorIndex, const int nSubMsgID, ACTOR_PROCESS_FUNCTOR_PTR functorPtr)
{
    NF_SHARE_PTR<NFIActor> pActor = GetActor(nActorIndex);
    if (nullptr != pActor)
    {
		return pActor->AddEndFunc(nSubMsgID, functorPtr);
    }

    return false;
}<commit_msg>Update NFCActorModule.cpp<commit_after>/*
            This file is part of:
                NoahFrame
            https://github.com/ketoo/NoahGameFrame

   Copyright 2009 - 2018 NoahFrame(NoahGameFrame)

   File creator: lvsheng.huang

   NoahFrame is open-source software and you can redistribute it and/or modify
   it under the terms of the License; besides, anyone who use this file/software must include this copyright announcement.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "NFCActorModule.h"

NFCActorModule::NFCActorModule(NFIPluginManager* p)
	:mFramework(NF_ACTOR_THREAD_COUNT)
{
	pPluginManager = p;

    srand((unsigned)time(NULL));

    m_pMainActor = NF_SHARE_PTR<NFIActor>(NF_NEW NFCActor(mFramework, this));
}

NFCActorModule::~NFCActorModule()
{
	m_pMainActor.reset();
	m_pMainActor = nullptr;
}

bool NFCActorModule::Init()
{
    return true;
}

bool NFCActorModule::AfterInit()
{

    return true;
}

bool NFCActorModule::BeforeShut()
{
	mxActorMap.ClearAll();
    return true;
}

bool NFCActorModule::Shut()
{

    return true;
}

bool NFCActorModule::Execute()
{
	ExecuteEvent();
    return true;
}

int NFCActorModule::RequireActor()
{
	NF_SHARE_PTR<NFIActor> pActor = nullptr;
	if (mxActorPool.size() <= 0)
	{
		pActor = NF_SHARE_PTR<NFIActor>(NF_NEW NFCActor(mFramework, this));
		mxActorMap.AddElement(pActor->GetAddress().AsInteger(), pActor);

		return pActor->GetAddress().AsInteger();
	}

	std::map<int, int>::iterator it = mxActorPool.begin();
	int nActorID = it->first;
	mxActorPool.erase(it);

    return nActorID;
}

NF_SHARE_PTR<NFIActor> NFCActorModule::GetActor(const int nActorIndex)
{
	return mxActorMap.GetElement(nActorIndex);
}

bool NFCActorModule::HandlerEx(const NFIActorMessage & message, const int from)
{
	if (message.msgType != NFIActorMessage::ACTOR_MSG_TYPE_COMPONENT)
	{
		return mxQueue.Push(message);
	}

	return false;
}

bool NFCActorModule::ExecuteEvent()
{
	NFIActorMessage xMsg;
	bool bRet = false;
	bRet = mxQueue.TryPop(xMsg);
	while (bRet)
	{
		if (xMsg.msgType != NFIActorMessage::ACTOR_MSG_TYPE_COMPONENT && xMsg.xEndFuncptr != nullptr)
		{
			//Actor can be reused in ActorPool mode, so we don't release it.
			//>ReleaseActor(xMsg.nFormActor);
			ACTOR_PROCESS_FUNCTOR* pFun = xMsg.xEndFuncptr.get();
			pFun->operator()(xMsg.nFormActor, xMsg.nMsgID, xMsg.data);

			NF_SHARE_PTR<NFIActor> xActor = mxActorMap.GetElement(xMsg.nFormActor);
			if (xActor)
			{
				if (xActor->GetNumQueuedMessages() <= 0)
				{
					int nActorID = xActor->GetAddress().AsInteger();
					if (mxActorPool.find(nActorID) == mxActorPool.end())
					{
						mxActorPool.insert(std::pair<int, int>(nActorID, 0));
					}
				}
			}
		}

		bRet = mxQueue.TryPop(xMsg);
	}

	return true;
}

bool NFCActorModule::SendMsgToActor(const int nActorIndex, const int nEventID, const std::string& strArg)
{
    NF_SHARE_PTR<NFIActor> pActor = GetActor(nActorIndex);
    if (nullptr != pActor)
    {
        NFIActorMessage xMessage;

        xMessage.msgType = NFIActorMessage::ACTOR_MSG_TYPE_COMPONENT;
        xMessage.data = strArg;
        xMessage.nMsgID = nEventID;
        xMessage.nFormActor = m_pMainActor->GetAddress().AsInteger();

        return mFramework.Send(xMessage, m_pMainActor->GetAddress(), pActor->GetAddress());
    }

    return false;
}

bool NFCActorModule::AddComponent(const int nActorIndex, NF_SHARE_PTR<NFIComponent> pComponent)
{
    NF_SHARE_PTR<NFIActor> pActor = GetActor(nActorIndex);
    if (nullptr != pActor)
    {
        pActor->AddComponent(pComponent);

        return true;
    }

    return false;
}

bool NFCActorModule::ReleaseActor(const int nActorIndex)
{
	return mxActorMap.RemoveElement(nActorIndex);
}

bool NFCActorModule::AddEndFunc(const int nActorIndex, const int nSubMsgID, ACTOR_PROCESS_FUNCTOR_PTR functorPtr)
{
    NF_SHARE_PTR<NFIActor> pActor = GetActor(nActorIndex);
    if (nullptr != pActor)
    {
		return pActor->AddEndFunc(nSubMsgID, functorPtr);
    }

    return false;
}
<|endoftext|>


<commit_before>#include <zmqpp/zmqpp.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include <thread>
#include <set>
#include <SFML/Audio.hpp>
#include "utils.cc"

using namespace std;
using namespace zmqpp;

#define PIECES_PATH  "./pieces/list"

string address, port, tracker_ip, tracker_port;

void wake_up(socket &tracker) {
  set<string> pieces;
  ifstream i_file(PIECES_PATH);
  string line;
  while (getline(i_file, line)) {
    pieces.insert(line);
  }

  remove(PIECES_PATH);

  ofstream o_file(PIECES_PATH);

  message request;
  request << ADD << address << port << pieces.size();
  for (string piece : pieces) {
    o_file << piece << endl;
    request << piece;
  }

  tracker.send(request);

  i_file.close();
  o_file.close();
}

bool  share_file(socket &tracker, string &filename) {
  filename = "./files/" + filename;
  if (!file_exists(filename))
    return false;

  string command = "./totient_generator.sh " + filename + " " + tracker_ip + " " + tracker_port;
  cerr << string_color(command, BLUE) << endl;
  system(command.c_str());

  totient::entry totient_file(filename + ".totient");

  message request;

  request << ADD << address << port << totient_file.pieces.size();

  for (size_t i = 0; i < totient_file.pieces.size(); ++i)
    request << totient_file.pieces[i];

  tracker.send(request);

  return true;
}

bool download_file(socket &tracker, unordered_map<string, totient::entry> &downloads, string &filename,
      socket &download_t) {
  filename = "./totient/" + filename + ".totient";
  if (!file_exists(filename))
    return false;

  if (downloads.count(filename) == 0) {
    totient::entry entry(filename);
    downloads[filename] = entry;
  }

  message request;
  request << "push";

  download_t.send(request);

  return true;
}

void play_song(const string &filename) {

}

void download_thread(void * _ctx) {
  context *ctx= (context *)_ctx;
  socket cli(*(ctx), socket_type::dealer);
  cli.connect("inproc://download");

  while (true) {
    message request;
    cli.receive(request);
    string command;
    request >> command;
    if (command == "quit")
      break;

    else {
      cout << string_color("@@@ Received request in download thread", GREEN) << endl;
    }
  }
}

void play_thread(void *_ctx){
  sf::Music music;
  vector<string> playlist;

  context *ctx = (context*)_ctx;
  socket main(*(ctx), socket_type::dealer);
  main.connect("inproc://playlist");
  unsigned int pos = 0;

  poller pol;
  pol.add(main);
  //it = playlist.begin();
  while(true){
    //cout << "here" << endl;
    if (playlist.size() > 0 and pos < playlist.size()){
      string name = playlist[pos];
      //cout << name << endl << pos << endl << playlist.size() << endl;
      if (music.getStatus() == 0 and music.openFromFile("files/" + name)){
        music.play();
        pos++;
      }
    }

    if(pol.poll(10)){
      if(pol.has_input(main)){
        message incmsg;
        main.receive(incmsg);
        string command;
        incmsg >> command;
        if (command == "add"){
          string filename;
          incmsg >> filename;
          playlist.push_back(filename);
        } else if (command == "next"){
          music.stop();
        }
      }
    }
  }
}

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

  if (argc < 5) {
    cout << "Usage: " << argv[0] << "address port tracker_ip tracker_port";
    exit(1);
  }

  address = argv[1];
  port    = argv[2];
  tracker_ip = argv[3];
  tracker_port = argv[4];
  const string tracker_endpoint = string("tcp://") + tracker_ip + ":" + tracker_port;

  context ctx;
  socket tracker(ctx, socket_type::dealer);
  tracker.connect(tracker_endpoint);

  wake_up(tracker);

  // Peer state
  unordered_map<string, totient::entry> downloads;
  // End peer state

  socket download_t(ctx, socket_type::dealer);
  download_t.bind("inproc://download");
  socket playlist_t(ctx, socket_type::dealer);
  playlist_t.bind("inproc://playlist");

  thread download_task(download_thread, (void *) &ctx);
  thread playlist_task(play_thread, (void *) &ctx);

  while (true) {
    string command;

    cout << "Totient P2P file sharing." << endl;
    cin >> command;

    if ((command == "q") or (command == "quit"))
      break;

    string filename;
    if (command == "share") {
      cout << "Enter the name of the file that you want to share (must be in the files dir)" << endl;
      cin >> filename;
      if (share_file(tracker, filename))
        cout << string_color("The file was successfully shared", GREEN) << endl;
      else
        cout << string_color("The file does not exist", RED) << endl;
    } else if (command == "download") {
      cout << "Enter the name of the file that you want to download (must be in the totient dir)" << endl;
      cin >> filename;
      if (download_file(tracker, downloads, filename, download_t))
        cout << string_color("Download in process", GREEN) << endl;
      else
        cout << string_color("The file does not exist", RED) << endl;
    } else if (command == "add") {
      cout << "Enter the name of the file that you want to hear (must be in the files dir)" << endl;
      cin >> filename;
      message p_command;
      p_command << command << filename;
      playlist_t.send(p_command);
    } else if (command == "next"){
      message p_command;
      p_command << command;
      playlist_t.send(p_command);
    }
  }

  getchar();
  cout << "Bye bye" << endl;

  return 0;
}
<commit_msg>Full playback functionality<commit_after>#include <zmqpp/zmqpp.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include <thread>
#include <set>
#include <SFML/Audio.hpp>
#include "utils.cc"

using namespace std;
using namespace zmqpp;

#define PIECES_PATH  "./pieces/list"

string address, port, tracker_ip, tracker_port;

void wake_up(socket &tracker) {
  set<string> pieces;
  ifstream i_file(PIECES_PATH);
  string line;
  while (getline(i_file, line)) {
    pieces.insert(line);
  }

  remove(PIECES_PATH);

  ofstream o_file(PIECES_PATH);

  message request;
  request << ADD << address << port << pieces.size();
  for (string piece : pieces) {
    o_file << piece << endl;
    request << piece;
  }

  tracker.send(request);

  i_file.close();
  o_file.close();
}

bool  share_file(socket &tracker, string &filename) {
  filename = "./files/" + filename;
  if (!file_exists(filename))
    return false;

  string command = "./totient_generator.sh " + filename + " " + tracker_ip + " " + tracker_port;
  cerr << string_color(command, BLUE) << endl;
  system(command.c_str());

  totient::entry totient_file(filename + ".totient");

  message request;

  request << ADD << address << port << totient_file.pieces.size();

  for (size_t i = 0; i < totient_file.pieces.size(); ++i)
    request << totient_file.pieces[i];

  tracker.send(request);

  return true;
}

bool download_file(socket &tracker, unordered_map<string, totient::entry> &downloads, string &filename,
      socket &download_t) {
  filename = "./totient/" + filename + ".totient";
  if (!file_exists(filename))
    return false;

  if (downloads.count(filename) == 0) {
    totient::entry entry(filename);
    downloads[filename] = entry;
  }

  message request;
  request << "push";

  download_t.send(request);

  return true;
}

void play_song(const string &filename) {

}

void download_thread(void * _ctx) {
  context *ctx= (context *)_ctx;
  socket cli(*(ctx), socket_type::dealer);
  cli.connect("inproc://download");

  while (true) {
    message request;
    cli.receive(request);
    string command;
    request >> command;
    if (command == "quit")
      break;

    else {
      cout << string_color("@@@ Received request in download thread", GREEN) << endl;
    }
  }
}

void play_thread(void *_ctx){
  sf::Music music;
  vector<string> playlist;
  bool playflag = true;

  context *ctx = (context*)_ctx;
  socket main(*(ctx), socket_type::dealer);
  main.connect("inproc://playlist");
  int pos = 0;

  poller pol;
  pol.add(main);
  //it = playlist.begin();
  while(true){
    //cout << "here" << endl;
    //cout << pos << endl;
    if (playlist.size() > 0 and pos < playlist.size()){
      string name = playlist[pos];
      //cout << pos << endl;
      //cout << name << endl << pos << endl << playlist.size() << endl;
      if (music.getStatus() == 0 and music.openFromFile("files/" + name) and playflag){
        music.play();
        pos++;
      }
    }

    if(pol.poll(100)){
      if(pol.has_input(main)){
        message incmsg;
        main.receive(incmsg);
        string command;
        incmsg >> command;
        if (command == "add"){
          string filename;
          incmsg >> filename;
          playlist.push_back(filename);
        } else if (command == "next"){
          music.stop();
        } else if (command == "prev"){
          pos = pos - 2;
          if (pos < 0)
            pos = 0;
          music.stop();
          //cout << pos << endl;
        } else if (command == "stop" and playflag){
          playflag = false;
          pos--;
          if (pos < 0)
            pos = 0;
          music.stop();
        } else if(command == "play" and not playflag){
          playflag = "true";
        } else if(command == "del" and playlist.size() > 0){
          pos--;
          if (pos < 0)
            pos = 0;
          playlist.erase(playlist.begin() + pos);
          music.stop();
        }
      }
    }
  }
}

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

  if (argc < 5) {
    cout << "Usage: " << argv[0] << "address port tracker_ip tracker_port";
    exit(1);
  }

  address = argv[1];
  port    = argv[2];
  tracker_ip = argv[3];
  tracker_port = argv[4];
  const string tracker_endpoint = string("tcp://") + tracker_ip + ":" + tracker_port;

  context ctx;
  socket tracker(ctx, socket_type::dealer);
  tracker.connect(tracker_endpoint);

  wake_up(tracker);

  // Peer state
  unordered_map<string, totient::entry> downloads;
  // End peer state

  socket download_t(ctx, socket_type::dealer);
  download_t.bind("inproc://download");
  socket playlist_t(ctx, socket_type::dealer);
  playlist_t.bind("inproc://playlist");

  thread download_task(download_thread, (void *) &ctx);
  thread playlist_task(play_thread, (void *) &ctx);

  while (true) {
    string command;

    cout << "Totient P2P file sharing." << endl;
    cin >> command;

    if ((command == "q") or (command == "quit"))
      break;

    string filename;
    if (command == "share") {
      cout << "Enter the name of the file that you want to share (must be in the files dir)" << endl;
      cin >> filename;
      if (share_file(tracker, filename))
        cout << string_color("The file was successfully shared", GREEN) << endl;
      else
        cout << string_color("The file does not exist", RED) << endl;
    } else if (command == "download") {
      cout << "Enter the name of the file that you want to download (must be in the totient dir)" << endl;
      cin >> filename;
      if (download_file(tracker, downloads, filename, download_t))
        cout << string_color("Download in process", GREEN) << endl;
      else
        cout << string_color("The file does not exist", RED) << endl;
    } else if (command == "add") {
      cout << "Enter the name of the file that you want to hear (must be in the files dir)" << endl;
      cin >> filename;
      message p_command;
      p_command << command << filename;
      playlist_t.send(p_command);
    } else if (command == "next" or command == "prev" or command == "stop" or command == "play" or "del"){
      message p_command;
      p_command << command;
      playlist_t.send(p_command);
    }
  }

  download_task.detach();
  playlist_task.detach();
  download_task.~thread();
  playlist_task.~thread();
  cout << "Bye bye" << endl;

  return 0;
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2014-2016 Leosac

    This file is part of Leosac.

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

    Leosac 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "SysFSGPIOPin.hpp"
#include "tools/unixfs.hpp"
#include <fcntl.h>
#include <tools/log.hpp>
#include <unistd.h>

using namespace Leosac::Module::SysFsGpio;
using Leosac::Tools::UnixFs;

SysFsGpioPin::SysFsGpioPin(zmqpp::context &ctx, const std::string &name, int gpio_no,
                           Direction direction, InterruptMode interrupt_mode,
                           bool initial_value, SysFsGpioModule &module)
    : gpio_no_(gpio_no)
    , sock_(ctx, zmqpp::socket_type::rep)
    , name_(name)
    , direction_(direction)
    , initial_value_(initial_value)
    , module_(module)
    , path_cfg_(module.general_config())
    , next_update_time_(std::chrono::system_clock::time_point::max())
{
    sock_.bind("inproc://" + name);

    set_direction(direction);
    set_interrupt(interrupt_mode);
    std::string full_path = path_cfg_.value_path(gpio_no);

    if (direction == Direction::Out)
    {
        if (initial_value_)
            turn_on();
        else
            turn_off();
    }

    file_fd_ = open(full_path.c_str(), O_RDONLY | O_NONBLOCK);
    assert(file_fd_ != -1);
}

SysFsGpioPin::~SysFsGpioPin()
{
    if (direction_ == Direction::Out)
    {
        if (initial_value_)
            turn_on();
        else
            turn_off();
    }

    if (file_fd_ != -1 && ::close(file_fd_) != 0)
    {
        ERROR("fail to close fd " << file_fd_);
    }
    try
    {
        UnixFs::writeSysFsValue(module_.general_config().unexport_path(), gpio_no_);
    }
    catch (FsException &e)
    {
        ERROR("Error while unexporting GPIO: " << e.what());
    }
}

void SysFsGpioPin::set_direction(Direction dir)
{
    std::string direction = dir == Direction::In ? "in" : "out";
    UnixFs::writeSysFsValue(path_cfg_.direction_path(gpio_no_), direction);
}

void SysFsGpioPin::set_interrupt(InterruptMode mode)
{
    std::string value;
    if (mode == SysFsGpioPin::InterruptMode::None)
        value = "none";
    else if (mode == SysFsGpioPin::InterruptMode::Both)
        value = "both";
    else if (mode == SysFsGpioPin::InterruptMode::Falling)
        value = "falling";
    else if (mode == SysFsGpioPin::InterruptMode::Rising)
        value = "rising";
    else
        assert(0);
    UnixFs::writeSysFsValue(path_cfg_.edge_path(gpio_no_), value);
}

void SysFsGpioPin::handle_message()
{
    zmqpp::message_t msg;
    std::string frame1;
    sock_.receive(msg);

    msg >> frame1;
    bool ok = false;
    if (frame1 == "ON")
        ok = turn_on(&msg);
    else if (frame1 == "OFF")
        ok = turn_off();
    else if (frame1 == "TOGGLE")
        ok = toggle();
    sock_.send(ok ? "OK" : "KO");

    // publish new state.
    module_.publish_on_bus(zmqpp::message() << ("S_" + name_)
                                            << (read_value() ? "ON" : "OFF"));
}

bool SysFsGpioPin::turn_on(zmqpp::message *msg /* = nullptr */)
{
    DEBUG("Remaining = " << msg->remaining());
    if (msg && msg->remaining() == 1)
    {
        // ASSERT_LOG(msg->parts() == 2 && msg->remaining() == 1, "Invalid internal
        // message.");
        // optional parameter is present
        int64_t duration;
        *msg >> duration;
        next_update_time_ =
            std::chrono::system_clock::now() + std::chrono::milliseconds(duration);
    }
    UnixFs::writeSysFsValue(path_cfg_.value_path(gpio_no_), 1);
    return true;
}

bool SysFsGpioPin::turn_off()
{
    UnixFs::writeSysFsValue(path_cfg_.value_path(gpio_no_), 0);
    return true;
}

bool SysFsGpioPin::toggle()
{
    int v = UnixFs::readSysFsValue<int>(path_cfg_.value_path(gpio_no_));
    UnixFs::writeSysFsValue(path_cfg_.value_path(gpio_no_), v == 1 ? 0 : 1);
    return true;
}

bool SysFsGpioPin::read_value()
{
    return UnixFs::readSysFsValue<bool>(path_cfg_.value_path(gpio_no_));
}

void SysFsGpioPin::handle_interrupt()
{
    std::array<char, 64> buffer;
    ssize_t ret;

    // flush interrupt by reading.
    // if we fail we cant recover, this means hardware failure.
    ret = ::read(file_fd_, &buffer[0], buffer.size());
    ASSERT_LOG(ret >= 0, "Read failed on GPIO pin.");
    ret = ::lseek(file_fd_, 0, SEEK_SET);
    ASSERT_LOG(ret >= 0, "Lseek failed on GPIO pin.");

    module_.publish_on_bus(zmqpp::message() << "S_INT:" + name_);
}

void SysFsGpioPin::register_sockets(zmqpp::reactor *reactor)
{
    reactor->add(sock_, std::bind(&SysFsGpioPin::handle_message, this));
    if (direction_ == Direction::In)
        reactor->add(file_fd_, std::bind(&SysFsGpioPin::handle_interrupt, this),
                     zmqpp::poller::poll_pri);
}

std::chrono::system_clock::time_point SysFsGpioPin::next_update() const
{
    return next_update_time_;
}

void SysFsGpioPin::update()
{
    DEBUG("Turning off SysFsGPIO pin.");
    turn_off();
    next_update_time_ = std::chrono::system_clock::time_point::max();
}
<commit_msg>[SYSFSGPIO] Fix segfault.<commit_after>/*
    Copyright (C) 2014-2016 Leosac

    This file is part of Leosac.

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

    Leosac 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "SysFSGPIOPin.hpp"
#include "tools/unixfs.hpp"
#include <fcntl.h>
#include <tools/log.hpp>
#include <unistd.h>

using namespace Leosac::Module::SysFsGpio;
using Leosac::Tools::UnixFs;

SysFsGpioPin::SysFsGpioPin(zmqpp::context &ctx, const std::string &name, int gpio_no,
                           Direction direction, InterruptMode interrupt_mode,
                           bool initial_value, SysFsGpioModule &module)
    : gpio_no_(gpio_no)
    , sock_(ctx, zmqpp::socket_type::rep)
    , name_(name)
    , direction_(direction)
    , initial_value_(initial_value)
    , module_(module)
    , path_cfg_(module.general_config())
    , next_update_time_(std::chrono::system_clock::time_point::max())
{
    sock_.bind("inproc://" + name);

    set_direction(direction);
    set_interrupt(interrupt_mode);
    std::string full_path = path_cfg_.value_path(gpio_no);

    if (direction == Direction::Out)
    {
        if (initial_value_)
            turn_on();
        else
            turn_off();
    }

    file_fd_ = open(full_path.c_str(), O_RDONLY | O_NONBLOCK);
    assert(file_fd_ != -1);
}

SysFsGpioPin::~SysFsGpioPin()
{
    if (direction_ == Direction::Out)
    {
        if (initial_value_)
            turn_on();
        else
            turn_off();
    }

    if (file_fd_ != -1 && ::close(file_fd_) != 0)
    {
        ERROR("fail to close fd " << file_fd_);
    }
    try
    {
        UnixFs::writeSysFsValue(module_.general_config().unexport_path(), gpio_no_);
    }
    catch (FsException &e)
    {
        ERROR("Error while unexporting GPIO: " << e.what());
    }
}

void SysFsGpioPin::set_direction(Direction dir)
{
    std::string direction = dir == Direction::In ? "in" : "out";
    UnixFs::writeSysFsValue(path_cfg_.direction_path(gpio_no_), direction);
}

void SysFsGpioPin::set_interrupt(InterruptMode mode)
{
    std::string value;
    if (mode == SysFsGpioPin::InterruptMode::None)
        value = "none";
    else if (mode == SysFsGpioPin::InterruptMode::Both)
        value = "both";
    else if (mode == SysFsGpioPin::InterruptMode::Falling)
        value = "falling";
    else if (mode == SysFsGpioPin::InterruptMode::Rising)
        value = "rising";
    else
        assert(0);
    UnixFs::writeSysFsValue(path_cfg_.edge_path(gpio_no_), value);
}

void SysFsGpioPin::handle_message()
{
    zmqpp::message_t msg;
    std::string frame1;
    sock_.receive(msg);

    msg >> frame1;
    bool ok = false;
    if (frame1 == "ON")
        ok = turn_on(&msg);
    else if (frame1 == "OFF")
        ok = turn_off();
    else if (frame1 == "TOGGLE")
        ok = toggle();
    sock_.send(ok ? "OK" : "KO");

    // publish new state.
    module_.publish_on_bus(zmqpp::message() << ("S_" + name_)
                                            << (read_value() ? "ON" : "OFF"));
}

bool SysFsGpioPin::turn_on(zmqpp::message *msg /* = nullptr */)
{
    if (msg && msg->remaining() == 1)
    {
        // ASSERT_LOG(msg->parts() == 2 && msg->remaining() == 1, "Invalid internal
        // message.");
        // optional parameter is present
        int64_t duration;
        *msg >> duration;
        next_update_time_ =
            std::chrono::system_clock::now() + std::chrono::milliseconds(duration);
    }
    else if (msg)
    {
        WARN("Called with unexpected number of arguments: " << msg->remaining());
    }

    UnixFs::writeSysFsValue(path_cfg_.value_path(gpio_no_), 1);
    return true;
}

bool SysFsGpioPin::turn_off()
{
    UnixFs::writeSysFsValue(path_cfg_.value_path(gpio_no_), 0);
    return true;
}

bool SysFsGpioPin::toggle()
{
    int v = UnixFs::readSysFsValue<int>(path_cfg_.value_path(gpio_no_));
    UnixFs::writeSysFsValue(path_cfg_.value_path(gpio_no_), v == 1 ? 0 : 1);
    return true;
}

bool SysFsGpioPin::read_value()
{
    return UnixFs::readSysFsValue<bool>(path_cfg_.value_path(gpio_no_));
}

void SysFsGpioPin::handle_interrupt()
{
    std::array<char, 64> buffer;
    ssize_t ret;

    // flush interrupt by reading.
    // if we fail we cant recover, this means hardware failure.
    ret = ::read(file_fd_, &buffer[0], buffer.size());
    ASSERT_LOG(ret >= 0, "Read failed on GPIO pin.");
    ret = ::lseek(file_fd_, 0, SEEK_SET);
    ASSERT_LOG(ret >= 0, "Lseek failed on GPIO pin.");

    module_.publish_on_bus(zmqpp::message() << "S_INT:" + name_);
}

void SysFsGpioPin::register_sockets(zmqpp::reactor *reactor)
{
    reactor->add(sock_, std::bind(&SysFsGpioPin::handle_message, this));
    if (direction_ == Direction::In)
        reactor->add(file_fd_, std::bind(&SysFsGpioPin::handle_interrupt, this),
                     zmqpp::poller::poll_pri);
}

std::chrono::system_clock::time_point SysFsGpioPin::next_update() const
{
    return next_update_time_;
}

void SysFsGpioPin::update()
{
    DEBUG("Turning off SysFsGPIO pin.");
    turn_off();
    next_update_time_ = std::chrono::system_clock::time_point::max();
}
<|endoftext|>


<commit_before>///
/// @file  phi.cpp
///
/// Copyright (C) 2013 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "pi_bsearch.h"
#include "isqrt.h"

#include <primesieve/soe/PrimeSieve.h>
#include <stdint.h>
#include <vector>
#include <limits>

#ifdef _OPENMP
  #include <omp.h>
  #include "to_omp_threads.h"
#endif

/// Results of phi(x, a) are cached for x < PHI_CACHE_LIMIT
/// @pre PHI_CACHE_LIMIT <= 32767
///
#define PHI_CACHE_LIMIT 32767

/// Avoids slow 64-bit division if possible
#define FAST_DIV(x, y) ((x <= std::numeric_limits<uint32_t>::max()) \
    ? static_cast<uint32_t>(x) / (y) : (x) / (y))

namespace primecount {

/// This class is used to calculate phi(x, a) using the recursive
/// formula: phi(x, a) = phi(x, a - 1) - phi(x / primes_[a], a - 1).
/// This implementation is based on an algorithm from Tomas Oliveira e
/// Silva [1]. I have added a cache to my implementation in which
/// results of phi(x, a) are stored if x is small. This cache speeds
/// up the calculations by at least 3 orders of magnitude near 10^15.
/// For PHI_CACHE_LIMIT = 32767 the memory usage of the cache is < 200
/// megabytes per thread.
///
/// [1] Tomas Oliveira e Silva, "Computing pi(x): the combinatorial method",
///     Revista do DETUA, vol. 4, no. 6, pp. 759-768, March 2006
///
class PhiCache {
public:
  PhiCache(const std::vector<int32_t>& primes)
    : primes_(primes)
  {
    PrimeSieve ps;
    int size = ps.countPrimes(0, PHI_CACHE_LIMIT);
    cache_.resize(size);
  }

  template<int64_t SIGN> int64_t phi(int64_t x, int64_t a)
  {
    int64_t sum = x * SIGN;
    if (a > 0)
    {
      int64_t iters = pi_bsearch(primes_.begin(), primes_.begin() + a, isqrt(x));
      sum += (a - iters) * -SIGN;

      for (int64_t a2 = 0; a2 < iters; a2++)
      {
        // x2 = x / primes_[a2]
        int64_t x2 = FAST_DIV(x, primes_[a2]);

        if (x2 < PHI_CACHE_LIMIT && validIndexes(a2, x2) &&
            cache_[a2][x2] != 0)
        {
          // phi(x2, a2) is cached
          sum += cache_[a2][x2] * -SIGN;
        }
        else
        {
          // phi(x2, a2) is not cached, calculate recursively
          int64_t phiResult = phi<-SIGN>(x2, a2);
          // cache phi(x2, a2)
          if (x2 < PHI_CACHE_LIMIT)
          {
            if (!validIndexes(a2, x2))
              cache_[a2].resize(x2 + 1, 0);
            cache_[a2][x2] = static_cast<int16_t>(phiResult * -SIGN);
          }
          sum += phiResult;
        }
      }
    }
    return sum;
  }
private:
  /// First a primes needed to calculate phi(x, a)
  const std::vector<int32_t>& primes_;
  /// Cache of phi(x, a) results with x < PHI_CACHE_LIMIT
  std::vector<std::vector<int16_t> > cache_;

  bool validIndexes(int64_t a2, int64_t x2) const
  {
    return x2 < static_cast<int64_t>(cache_[a2].size());
  }
};

/// Partial sieve function (a.k.a. Legendre-sum).
/// phi(x, a) counts the numbers <= x that are not divisible
/// by any of the first a primes.
///
int64_t phi(int64_t x, int64_t a, int threads)
{
  if (x < 1) return 0;
  if (a < 1) return x;

  std::vector<int32_t> primes;
  PrimeSieve ps;
  ps.generate_N_Primes(a, &primes);

  int iters = pi_bsearch(primes.begin(), primes.begin() + a, isqrt(x));
  PhiCache cache(primes);
  int64_t sum = x - a + iters;

#ifdef _OPENMP
  threads = to_omp_threads(threads);
  #pragma omp parallel for firstprivate(cache) reduction(+: sum) \
      num_threads(threads) schedule(dynamic, 16)
#endif
  for (int i = 0; i < iters; i++)
    sum += cache.phi<-1>(x / primes[i], i);

  return sum;
}

} // namespace primecount
<commit_msg>Minor speed up on Haswell CPUs<commit_after>///
/// @file  phi.cpp
///
/// Copyright (C) 2013 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "pi_bsearch.h"
#include "isqrt.h"

#include <primesieve/soe/PrimeSieve.h>
#include <stdint.h>
#include <vector>
#include <limits>

#ifdef _OPENMP
  #include <omp.h>
  #include "to_omp_threads.h"
#endif

/// Results of phi(x, a) are cached for x < PHI_CACHE_LIMIT
/// @pre PHI_CACHE_LIMIT <= 32767
///
#define PHI_CACHE_LIMIT 32767

/// Avoids slow 64-bit division if possible
#define FAST_DIV(x, y) ((x <= std::numeric_limits<uint32_t>::max()) \
    ? static_cast<uint32_t>(x) / (y) : (x) / (y))

namespace primecount {

/// This class is used to calculate phi(x, a) using the recursive
/// formula: phi(x, a) = phi(x, a - 1) - phi(x / primes_[a], a - 1).
/// This implementation is based on an algorithm from Tomas Oliveira e
/// Silva [1]. I have added a cache to my implementation in which
/// results of phi(x, a) are stored if x is small. This cache speeds
/// up the calculations by at least 3 orders of magnitude near 10^15.
/// For PHI_CACHE_LIMIT = 32767 the memory usage of the cache is < 200
/// megabytes per thread.
///
/// [1] Tomas Oliveira e Silva, "Computing pi(x): the combinatorial method",
///     Revista do DETUA, vol. 4, no. 6, pp. 759-768, March 2006
///
class PhiCache {
public:
  PhiCache(const std::vector<int32_t>& primes)
    : primes_(primes)
  {
    PrimeSieve ps;
    int size = ps.countPrimes(0, PHI_CACHE_LIMIT);
    cache_.resize(size);
  }

  template<int64_t SIGN> int64_t phi(int64_t x, int64_t a)
  {
    int64_t sum = x * SIGN;
    if (a > 0)
    {
      int64_t iters = pi_bsearch(primes_.begin(), primes_.begin() + a, isqrt(x));
      sum += (a - iters) * -SIGN;

      for (int64_t a2 = 0; a2 < iters; a2++)
      {
        // x2 = x / primes_[a2]
        int64_t x2 = FAST_DIV(x, primes_[a2]);

        if (x2 < PHI_CACHE_LIMIT && validIndexes(a2, x2) &&
            cache_[a2][x2] != 0)
        {
          // phi(x2, a2) is cached
          sum += cache_[a2][x2] * -SIGN;
        }
        else
        {
          // phi(x2, a2) is not cached, calculate recursively
          int64_t phiResult = phi<-SIGN>(x2, a2);
          // cache phi(x2, a2)
          if (x2 < PHI_CACHE_LIMIT)
          {
            if (!validIndexes(a2, x2))
              cache_[a2].resize(x2 + 1, 0);
            cache_[a2][x2] = static_cast<int16_t>(phiResult * -SIGN);
          }
          sum += phiResult;
        }
      }
    }
    return sum;
  }
private:
  /// First a primes needed to calculate phi(x, a)
  const std::vector<int32_t>& primes_;
  /// Cache of phi(x, a) results with x < PHI_CACHE_LIMIT
  std::vector<std::vector<int16_t> > cache_;

  bool validIndexes(int64_t a2, int64_t x2) const
  {
    return x2 < static_cast<int64_t>(cache_[a2].size());
  }
};

/// Partial sieve function (a.k.a. Legendre-sum).
/// phi(x, a) counts the numbers <= x that are not divisible
/// by any of the first a primes.
///
int64_t phi(int64_t x, int64_t a, int threads)
{
  if (x < 1) return 0;
  if (a < 1) return x;

  std::vector<int32_t> primes;
  PrimeSieve ps;
  ps.generate_N_Primes(a, &primes);

  int iters = pi_bsearch(primes.begin(), primes.begin() + a, isqrt(x));
  PhiCache cache(primes);
  int64_t sum = x - a + iters;

#ifdef _OPENMP
  threads = to_omp_threads(threads);
  #pragma omp parallel for firstprivate(cache) reduction(+: sum) \
      num_threads(threads) schedule(dynamic)
#endif
  for (int i = 0; i < iters; i++)
    sum += cache.phi<-1>(x / primes[i], i);

  return sum;
}

} // namespace primecount
<|endoftext|>