<commit_before>/*
 This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

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

For more information, please refer to <http://unlicense.org>
*/

#include "Daemon.hh"

Daemon::Daemon(const std::string &path)
    : _local(path, DomainSocket::SERVER), _run(false)
{
}

Daemon::~Daemon(void)
{
    for (DomainSocket* client : _clients)
    {
        delete client;
    }
}

void Daemon::start(void)
{
    _run = true;
    while (_run)
    {
        handleSockets();
    }
    std::cout << "Server shutdown" << std::endl;
}

void Daemon::handleSockets(void)
{
    fd_set              readfds;
    fd_set              writefds;
    int                 fd_max;
    struct timeval      tv;

    fd_max = initSelect(&tv, &readfds, &writefds);
    if (::select(fd_max, &readfds, NULL, NULL, &tv) == -1)
    {
        throw std::runtime_error(std::string("Select Error : ") + ::strerror(errno));
    }
    else
    {
        // If something to read on stdin
        if (FD_ISSET(0, &readfds))
            eventTerminal();
        // If new client connect
        if (FD_ISSET(_local.fd(), &readfds))
            eventServer();
        // Check clients's socket
        eventClients(&readfds, &writefds);
    }

}

int Daemon::initSelect(struct timeval *tv, fd_set *readfds, fd_set *writefds)
{
    int     fd_max = _local.fd();

    // Timeout 100 ms
    tv->tv_sec = 0;
    tv->tv_usec = 100;

    // Initialize bits field for select
    FD_ZERO(readfds);
    FD_SET(_local.fd(), readfds);
    FD_SET(0, readfds);
    if (writefds != NULL)
    {
        FD_ZERO(writefds);
        FD_SET(_local.fd(), writefds);
    }
    for (DomainSocket *client : _clients)
    {
        FD_SET(client->fd(), readfds);
        if (writefds != NULL)
            FD_SET(client->fd(), writefds);
        // Check if client's fd is greater than actual fd_max
        fd_max = (fd_max < client->fd()) ? client->fd() : fd_max;
    }
    return fd_max + 1;
}

void Daemon::eventTerminal(void)
{
    std::string     msg;

    std::cin >> msg;
    if (msg == "exit")
    {
        _run = false;
    }
}

void Daemon::eventServer(void)
{
    DomainSocket    *client;

    try
    {
        client = _local.acceptClient();
        _clients.push_back(client);
    }
    catch (std::runtime_error &e)
    {
        std::cout << e.what() << std::endl;
    }
}

void Daemon::eventClients(fd_set *readfds, fd_set *writefds)
{
    std::string         msg;

    for (std::vector<DomainSocket*>::iterator it = _clients.begin(); it < _clients.end(); ++it)
    {
        // Something to write on client socket
        if (FD_ISSET((*it)->fd(), writefds))
        {
            if (_msgs.size())
            {
                try
                {
                    (*it)->sendMsg(_msgs.back());
                    _msgs.pop_back();
                }
                catch (std::runtime_error &e)
                {
                    std::cout << e.what() << std::endl;
                }
            }
        }
        // Something to read on client socket
        if (FD_ISSET((*it)->fd(), readfds))
        {
            try
            {
                _msgs.push_back((*it)->recvMsg());
            }
            catch (DomainSocket::Disconnected &e)
            {
                delete (*it);
                _clients.erase(it);
                it = _clients.begin();
            }
            catch (std::runtime_error &e)
            {
                std::cout << e.what() << std::endl;
            }
        }
    }
}

int main(int ac, char **av)
{
    if (ac != 2)
    {
        std::cout << "Usage : " << av[0] << " <socket_path>" << std::endl;
        return 1;
    }

    try
    {
        Daemon      d(av[1]);

        d.start();
    }
    catch (std::runtime_error &e)
    {

    }

    return 0;
}
<commit_msg>C++98 compatibility<commit_after>/*
 This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

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

For more information, please refer to <http://unlicense.org>
*/

#include "Daemon.hh"

Daemon::Daemon(const std::string &path)
    : _local(path, DomainSocket::SERVER), _run(false)
{
}

Daemon::~Daemon(void)
{
    for (DomainSocket::iterator it = _clients.begin; it < _clients.end(); ++it)
    {
        delete *it;
    }
}

void Daemon::start(void)
{
    _run = true;
    while (_run)
    {
        handleSockets();
    }
    std::cout << "Server shutdown" << std::endl;
}

void Daemon::handleSockets(void)
{
    fd_set              readfds;
    fd_set              writefds;
    int                 fd_max;
    struct timeval      tv;

    fd_max = initSelect(&tv, &readfds, &writefds);
    if (::select(fd_max, &readfds, NULL, NULL, &tv) == -1)
    {
        throw std::runtime_error(std::string("Select Error : ") + ::strerror(errno));
    }
    else
    {
        // If something to read on stdin
        if (FD_ISSET(0, &readfds))
            eventTerminal();
        // If new client connect
        if (FD_ISSET(_local.fd(), &readfds))
            eventServer();
        // Check clients's socket
        eventClients(&readfds, &writefds);
    }

}

int Daemon::initSelect(struct timeval *tv, fd_set *readfds, fd_set *writefds)
{
    int     fd_max = _local.fd();

    // Timeout 100 ms
    tv->tv_sec = 0;
    tv->tv_usec = 100;

    // Initialize bits field for select
    FD_ZERO(readfds);
    FD_SET(_local.fd(), readfds);
    FD_SET(0, readfds);
    if (writefds != NULL)
    {
        FD_ZERO(writefds);
        FD_SET(_local.fd(), writefds);
    }
    for (DomainSocket *client : _clients)
    {
        FD_SET(client->fd(), readfds);
        if (writefds != NULL)
            FD_SET(client->fd(), writefds);
        // Check if client's fd is greater than actual fd_max
        fd_max = (fd_max < client->fd()) ? client->fd() : fd_max;
    }
    return fd_max + 1;
}

void Daemon::eventTerminal(void)
{
    std::string     msg;

    std::cin >> msg;
    if (msg == "exit")
    {
        _run = false;
    }
}

void Daemon::eventServer(void)
{
    DomainSocket    *client;

    try
    {
        client = _local.acceptClient();
        _clients.push_back(client);
    }
    catch (std::runtime_error &e)
    {
        std::cout << e.what() << std::endl;
    }
}

void Daemon::eventClients(fd_set *readfds, fd_set *writefds)
{
    std::string         msg;

    for (std::vector<DomainSocket*>::iterator it = _clients.begin(); it < _clients.end(); ++it)
    {
        // Something to write on client socket
        if (FD_ISSET((*it)->fd(), writefds))
        {
            if (_msgs.size())
            {
                try
                {
                    (*it)->sendMsg(_msgs.back());
                    _msgs.pop_back();
                }
                catch (std::runtime_error &e)
                {
                    std::cout << e.what() << std::endl;
                }
            }
        }
        // Something to read on client socket
        if (FD_ISSET((*it)->fd(), readfds))
        {
            try
            {
                _msgs.push_back((*it)->recvMsg());
            }
            catch (DomainSocket::Disconnected &e)
            {
                delete (*it);
                _clients.erase(it);
                it = _clients.begin();
            }
            catch (std::runtime_error &e)
            {
                std::cout << e.what() << std::endl;
            }
        }
    }
}

int main(int ac, char **av)
{
    if (ac != 2)
    {
        std::cout << "Usage : " << av[0] << " <socket_path>" << std::endl;
        return 1;
    }

    try
    {
        Daemon      d(av[1]);

        d.start();
    }
    catch (std::runtime_error &e)
    {

    }

    return 0;
}
<|endoftext|>


<commit_before>#include "Dialog.h"
/*
#define WINDOW_WIDTH 976
#define WINDOW_HEIGHT 840

#define CAM_WIDTH 720
#define CAM_HEIGHT 720
*/

Dialog::Dialog(const std::string &title, const cv::Size &ptWindowSize, const cv::Size &ptCamSize, int flags/* = CV_WINDOW_AUTOSIZE*/)
	: windowSize(ptWindowSize), camSize(ptCamSize)
{
	cv::Size windowSizeDefault = cv::Size((double)camSize.width / 0.7, (double)camSize.width / 0.7);

	if (windowSize != cv::Size(0, 0)) {
		double scale = (double)windowSize.width / (double)windowSizeDefault.width;
		camSize = cv::Size((double)camSize.width * scale, (double)windowSize.height * scale);
	}
	else {
		windowSize = cv::Size((double)camSize.width / 0.7, (double)camSize.width / 0.7);
	}
	fontScale = (double)windowSize.height / 1024;
    m_title = title;
	m_bMainCamEnabled = true;
    int baseLine;

	m_buttonHeight = cv::getTextSize("Ajig6", cv::FONT_HERSHEY_DUPLEX, fontScale, 1, &baseLine).height * 2;

	/*
    m_buttonHeight = cv::getTextSize("Ajig6", cv::FONT_HERSHEY_DUPLEX, fontScale, 1, &baseLine).height * 2;

	cv::namedWindow(m_title, CV_WINDOW_AUTOSIZE);
	//cvSetWindowProperty(m_title.c_str(), CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
	cv::moveWindow(m_title, 0, 0);
	cv::setMouseCallback(m_title, [](int event, int x, int y, int flags, void* self) {
		for (auto pListener : ((Dialog*)self)->m_EventListeners){
			if (pListener->OnMouseEvent(event, (float)x / ((Dialog*)self)->camSize.x, (float)y / ((Dialog*)self)->camSize.y, flags)) {
				return; // event was handled
			}
		}

		((Dialog*)self)->mouseX = x;
		((Dialog*)self)->mouseY = y;
		if (event == cv::EVENT_LBUTTONUP){
			((Dialog*)self)->mouseClicked(x, y);
		}
	}, this);
*/

	display_empty = cv::Mat(windowSize, CV_8UC3, cv::Scalar(0));
	display = cv::Mat(windowSize, CV_8UC3, cv::Scalar(0));
	cam1_roi = display(cv::Rect(0, 0, camSize.width, camSize.height)); // region of interest
	int cam2_width = windowSize.width - camSize.width;
	cam2_roi = display(cv::Rect(windowSize - cv::Size(cam2_width, cam2_width), cv::Size(cam2_width, cam2_width)));
	//cam_area = cv::Mat(CAM_HEIGHT, CAM_WIDTH, CV_8UC3);
	Start();

};
Dialog::~Dialog(){
	WaitForStop();
}
void Dialog::ShowImage(const cv::Mat &image, bool main) {
	if (!m_bMainCamEnabled && main) return;
	boost::mutex::scoped_lock lock(display_mutex); //allow one command at a time
	image.copyTo(main ? cam1_area : cam2_area);
	//	resize(image, cam_area, cv::Size(CAM_WIDTH, CAM_HEIGHT));//resize image
	//resize(image, display, cv::Size(WINDOW_WIDTH, WINDOW_HEIGHT));//resize image
}

int Dialog::createButton(const std::string& bar_name, char shortcut, std::function<void()> const & on_change){
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	m_buttons.push_back(std::make_tuple(bar_name, shortcut, on_change));
	return 0;
};

void Dialog::clearButtons() {
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	m_buttons.clear();
}

void Dialog::ClearDisplay() {
//	boost::mutex::scoped_lock lock(mutex); //allow one command at a time
//	display_empty.copyTo(display);
}
void Dialog::putText(const std::string &text, cv::Point pos, double fontScale, cv::Scalar color) {
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time

	if (pos.x < 0) pos.x = display.size().width + pos.x;
	if (pos.y < 0) pos.y = display.size().height + pos.y;
	std::string key = std::to_string(pos.x) + "_" + std::to_string(pos.y);
	m_texts[key] = std::make_tuple(pos, text, fontScale, color);
	//cv::putText(display, text, pos, cv::FONT_HERSHEY_DUPLEX, fontScale, color);
}

int Dialog::Draw() {
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	//cv::Mat image;
	//background.copyTo(image);
    //int window_width = image.cols;
    //int window_height = image.rows;
    //cv::Mat image = cv::Mat::zeros( window_height, window_width, CV_8UC3 );
	//cam_area.copyTo(display_roi);
	cv::Mat main_roi = m_bCam1Active ? cam1_roi : cam2_roi;
	cv::Mat sec_roi = !m_bCam1Active ? cam1_roi : cam2_roi;
	if (m_bMainCamEnabled && cam1_area.size().height > 0) {
		resize(cam1_area, main_roi, main_roi.size());//resize image
	}
	if (cam2_area.size().height > 0) {
		resize(cam2_area, sec_roi, sec_roi.size());//resize image
	}

    int i = 0;
    for (const auto& button : m_buttons) {
		cv::putText(display, std::get<0>(button), cv::Point(30, (++i)*m_buttonHeight), cv::FONT_HERSHEY_DUPLEX, fontScale, cv::Scalar(255, 255, 255));

    }
	for (const auto& text : m_texts) {
		cv::putText(display, std::get<1>(text.second), std::get<0>(text.second), cv::FONT_HERSHEY_DUPLEX, std::get<2>(text.second), std::get<3>(text.second));

	}

	cv::imshow(m_title, display);
	display_empty.copyTo(display);

	return 0;
};
void Dialog::KeyPressed(int key){
	if (key == '-') return;
	for (auto btn : m_buttons){
		if(std::get<1>(btn) == key){
			std::get<2>(btn)();
			return;
		}
	}
}

void Dialog::mouseClicked(int x, int y) {
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	unsigned int index = (int)(round((float)y / m_buttonHeight) - 1);
    if (index < m_buttons.size()){
        auto button = m_buttons[index];
		std::get<2>(button)();
        m_close = true;
    }

}
void Dialog::Run(){
	cv::namedWindow(m_title, CV_WINDOW_AUTOSIZE);
	//cvSetWindowProperty(m_title.c_str(), CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
	cv::moveWindow(m_title, 0, 0);
	cv::setMouseCallback(m_title, [](int event, int x, int y, int flags, void* self) {
		bool bMainArea = x < ((Dialog*)self)->camSize.width && y < ((Dialog*)self)->camSize.height;
		cv::Point scaled;
		cv::Point offset;
		cv::Size size;
		cv::Size target;

		if (bMainArea) {
			((Dialog*)self)->cam1_roi.locateROI(size, offset);
			size = ((Dialog*)self)->cam1_roi.size();
			target = ((Dialog*)self)->cam1_area.size();
		}
		else {
			((Dialog*)self)->cam2_roi.locateROI(size, offset);
			size = ((Dialog*)self)->cam2_roi.size();
			target = ((Dialog*)self)->cam2_area.size();
		}
		scaled.x = (double)(x - offset.x) / size.width * target.width;
		scaled.y = (double)(y - offset.y) / size.height * target.height;
		for (auto pListener : ((Dialog*)self)->m_EventListeners){
			if (pListener->OnMouseEvent(event, scaled.x, scaled.y, flags, bMainArea)) {
				return; // event was handled
			}
		}

		((Dialog*)self)->mouseX = x;
		((Dialog*)self)->mouseY = y;
		if (event == cv::EVENT_LBUTTONUP){
			((Dialog*)self)->mouseClicked(x, y);
		}
	}, this);

	while (!stop_thread) {
		try {
			Draw();
			int key = cv::waitKey(10);
			KeyPressed(key);
		}
		catch (std::exception &e) {
			std::cout << "Dialog::Run, error: " << e.what() << std::endl;
		}
		//std::this_thread::sleep_for(std::chrono::milliseconds(10));
	}
	cv::waitKey(0);
}
<commit_msg>thread safety<commit_after>#include "Dialog.h"
/*
#define WINDOW_WIDTH 976
#define WINDOW_HEIGHT 840

#define CAM_WIDTH 720
#define CAM_HEIGHT 720
*/

Dialog::Dialog(const std::string &title, const cv::Size &ptWindowSize, const cv::Size &ptCamSize, int flags/* = CV_WINDOW_AUTOSIZE*/)
	: windowSize(ptWindowSize), camSize(ptCamSize)
{
	cv::Size windowSizeDefault = cv::Size((double)camSize.width / 0.7, (double)camSize.width / 0.7);

	if (windowSize != cv::Size(0, 0)) {
		double scale = (double)windowSize.width / (double)windowSizeDefault.width;
		camSize = cv::Size((double)camSize.width * scale, (double)windowSize.height * scale);
	}
	else {
		windowSize = cv::Size((double)camSize.width / 0.7, (double)camSize.width / 0.7);
	}
	fontScale = (double)windowSize.height / 1024;
    m_title = title;
	m_bMainCamEnabled = true;
    int baseLine;

	m_buttonHeight = cv::getTextSize("Ajig6", cv::FONT_HERSHEY_DUPLEX, fontScale, 1, &baseLine).height * 2;

	/*
    m_buttonHeight = cv::getTextSize("Ajig6", cv::FONT_HERSHEY_DUPLEX, fontScale, 1, &baseLine).height * 2;

	cv::namedWindow(m_title, CV_WINDOW_AUTOSIZE);
	//cvSetWindowProperty(m_title.c_str(), CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
	cv::moveWindow(m_title, 0, 0);
	cv::setMouseCallback(m_title, [](int event, int x, int y, int flags, void* self) {
		for (auto pListener : ((Dialog*)self)->m_EventListeners){
			if (pListener->OnMouseEvent(event, (float)x / ((Dialog*)self)->camSize.x, (float)y / ((Dialog*)self)->camSize.y, flags)) {
				return; // event was handled
			}
		}

		((Dialog*)self)->mouseX = x;
		((Dialog*)self)->mouseY = y;
		if (event == cv::EVENT_LBUTTONUP){
			((Dialog*)self)->mouseClicked(x, y);
		}
	}, this);
*/

	display_empty = cv::Mat(windowSize, CV_8UC3, cv::Scalar(0));
	display = cv::Mat(windowSize, CV_8UC3, cv::Scalar(0));
	cam1_roi = display(cv::Rect(0, 0, camSize.width, camSize.height)); // region of interest
	int cam2_width = windowSize.width - camSize.width;
	cam2_roi = display(cv::Rect(windowSize - cv::Size(cam2_width, cam2_width), cv::Size(cam2_width, cam2_width)));
	//cam_area = cv::Mat(CAM_HEIGHT, CAM_WIDTH, CV_8UC3);
	Start();

};
Dialog::~Dialog(){
	WaitForStop();
}
void Dialog::ShowImage(const cv::Mat &image, bool main) {
	if (!m_bMainCamEnabled && main) return;
	boost::mutex::scoped_lock lock(display_mutex); //allow one command at a time
	image.copyTo(main ? cam1_area : cam2_area);
	//	resize(image, cam_area, cv::Size(CAM_WIDTH, CAM_HEIGHT));//resize image
	//resize(image, display, cv::Size(WINDOW_WIDTH, WINDOW_HEIGHT));//resize image
}

int Dialog::createButton(const std::string& bar_name, char shortcut, std::function<void()> const & on_change){
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	m_buttons.push_back(std::make_tuple(bar_name, shortcut, on_change));
	return 0;
};

void Dialog::clearButtons() {
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	m_buttons.clear();
}

void Dialog::ClearDisplay() {
//	boost::mutex::scoped_lock lock(mutex); //allow one command at a time
//	display_empty.copyTo(display);
}
void Dialog::putText(const std::string &text, cv::Point pos, double fontScale, cv::Scalar color) {
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time

	if (pos.x < 0) pos.x = display.size().width + pos.x;
	if (pos.y < 0) pos.y = display.size().height + pos.y;
	std::string key = std::to_string(pos.x) + "_" + std::to_string(pos.y);
	m_texts[key] = std::make_tuple(pos, text, fontScale, color);
	//cv::putText(display, text, pos, cv::FONT_HERSHEY_DUPLEX, fontScale, color);
}

int Dialog::Draw() {
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	//cv::Mat image;
	//background.copyTo(image);
    //int window_width = image.cols;
    //int window_height = image.rows;
    //cv::Mat image = cv::Mat::zeros( window_height, window_width, CV_8UC3 );
	//cam_area.copyTo(display_roi);
	cv::Mat main_roi = m_bCam1Active ? cam1_roi : cam2_roi;
	cv::Mat sec_roi = !m_bCam1Active ? cam1_roi : cam2_roi;
	if (m_bMainCamEnabled && cam1_area.size().height > 0) {
		resize(cam1_area, main_roi, main_roi.size());//resize image
	}
	if (cam2_area.size().height > 0) {
		resize(cam2_area, sec_roi, sec_roi.size());//resize image
	}

    int i = 0;
    for (const auto& button : m_buttons) {
		cv::putText(display, std::get<0>(button), cv::Point(30, (++i)*m_buttonHeight), cv::FONT_HERSHEY_DUPLEX, fontScale, cv::Scalar(255, 255, 255));

    }
	for (const auto& text : m_texts) {
		cv::putText(display, std::get<1>(text.second), std::get<0>(text.second), cv::FONT_HERSHEY_DUPLEX, std::get<2>(text.second), std::get<3>(text.second));

	}

	cv::imshow(m_title, display);
	display_empty.copyTo(display);

	return 0;
};
void Dialog::KeyPressed(int key){

	if (key == '-') return;
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	for (auto btn : m_buttons){
		if(std::get<1>(btn) == key){
			std::get<2>(btn)();
			return;
		}
	}
}

void Dialog::mouseClicked(int x, int y) {
	boost::mutex::scoped_lock lock(click_mutex); //allow one command at a time
	unsigned int index = (int)(round((float)y / m_buttonHeight) - 1);
    if (index < m_buttons.size()){
        auto button = m_buttons[index];
		std::get<2>(button)();
        m_close = true;
    }

}
void Dialog::Run(){
	cv::namedWindow(m_title, CV_WINDOW_AUTOSIZE);
	//cvSetWindowProperty(m_title.c_str(), CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
	cv::moveWindow(m_title, 0, 0);
	cv::setMouseCallback(m_title, [](int event, int x, int y, int flags, void* self) {
		bool bMainArea = x < ((Dialog*)self)->camSize.width && y < ((Dialog*)self)->camSize.height;
		cv::Point scaled;
		cv::Point offset;
		cv::Size size;
		cv::Size target;

		if (bMainArea) {
			((Dialog*)self)->cam1_roi.locateROI(size, offset);
			size = ((Dialog*)self)->cam1_roi.size();
			target = ((Dialog*)self)->cam1_area.size();
		}
		else {
			((Dialog*)self)->cam2_roi.locateROI(size, offset);
			size = ((Dialog*)self)->cam2_roi.size();
			target = ((Dialog*)self)->cam2_area.size();
		}
		scaled.x = (double)(x - offset.x) / size.width * target.width;
		scaled.y = (double)(y - offset.y) / size.height * target.height;
		for (auto pListener : ((Dialog*)self)->m_EventListeners){
			if (pListener->OnMouseEvent(event, scaled.x, scaled.y, flags, bMainArea)) {
				return; // event was handled
			}
		}

		((Dialog*)self)->mouseX = x;
		((Dialog*)self)->mouseY = y;
		if (event == cv::EVENT_LBUTTONUP){
			((Dialog*)self)->mouseClicked(x, y);
		}
	}, this);

	while (!stop_thread) {
		try {
			Draw();
			int key = cv::waitKey(10);
			KeyPressed(key);
		}
		catch (std::exception &e) {
			std::cout << "Dialog::Run, error: " << e.what() << std::endl;
		}
		//std::this_thread::sleep_for(std::chrono::milliseconds(10));
	}
	cv::waitKey(0);
}
<|endoftext|>


<commit_before>#ifndef __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__
#define __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__

#ifndef DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&);               \
  void operator=(const TypeName&)
#endif

#ifdef _DEBUG
#include "odbgstream.hpp"
#include "hrtext.hpp"
#include "iidstr.hpp"

#define DBGLOG(X) \
do { \
    wodbgstream wos; \
    wos << "["__FUNCTION__"] " << X << std::endl; \
} while(0)

// TODO(tomfinegan): replace the hard coded hr w/expansion of X
#define \
    HRLOG(X) L" {hr=" << X << "/" << std::hex << X << std::dec << \
    L" (" << hrtext(X) << L")}"

#define REFTIMETOSECONDS(X) (double(X) / 10000000.0f)

#else
#define DBGLOG(X)
#define REFTIMETOSECONDS(X)
#endif

// keep the compiler quiet about do/while(0)'s used in log macros
#pragma warning(disable:4127)

#define CHK(X, Y) \
do { \
    if (FAILED(X=(Y))) \
    { \
        DBGLOG(#Y << HRLOG(X)); \
    } \
} while (0)

#endif // __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__
<commit_msg>debugutil: explain CHK<commit_after>#ifndef __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__
#define __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__

#ifndef DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&);               \
  void operator=(const TypeName&)
#endif

#ifdef _DEBUG
#include "odbgstream.hpp"
#include "hrtext.hpp"
#include "iidstr.hpp"

#define DBGLOG(X) \
do { \
    wodbgstream wos; \
    wos << "["__FUNCTION__"] " << X << std::endl; \
} while(0)

// TODO(tomfinegan): replace the hard coded hr w/expansion of X
#define \
    HRLOG(X) L" {hr=" << X << "/" << std::hex << X << std::dec << \
    L" (" << hrtext(X) << L")}"

#define REFTIMETOSECONDS(X) (double(X) / 10000000.0f)

#else
#define DBGLOG(X)
#define REFTIMETOSECONDS(X)
#endif

// keep the compiler quiet about do/while(0)'s (constant conditional) used in
// log macros
#pragma warning(disable:4127)

// check the HRESULT for failure (<0), and log it if we're in debug mode
#define CHK(X, Y) \
do { \
    if (FAILED(X=(Y))) \
    { \
        DBGLOG(#Y << HRLOG(X)); \
    } \
} while (0)

#endif // __WEBMDSHOW_COMMON_DEBUGUTIL_HPP__
<|endoftext|>


<commit_before>// convert int array into int vector
/*
std::vector<int> intArrayToVector(int arr[]){
  std::vector<int> vec (arr, arr + sizeof(arr) / sizeof(int));
  return vec;
}
*/
<commit_msg>unneded file<commit_after><|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#define _USE_MATH_DEFINES
#include "QmitkToFRecorderWidget.h"

//QT headers
#include <qmessagebox.h>
#include <QComboBox>
#include <QLabel>
#include <QLayout>
#include <QGridLayout>
#include <QCheckBox>

//mitk headers
#include <mitkToFImageWriter.h>

//itk headers
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
#include <itksys/SystemTools.hxx>

struct QFileDialogArgs;
class QFileDialogPrivate;

const std::string QmitkToFRecorderWidget::VIEW_ID = "org.mitk.views.qmitktofrecorderwidget";

QmitkToFRecorderWidget::QmitkToFRecorderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
{
  this->m_ToFImageRecorder = NULL;
  this->m_ToFImageGrabber = NULL;
  this->m_RecordMode = mitk::ToFImageRecorder::PerFrames;

  this-> m_Controls = NULL;
  CreateQtPartControl(this);
}

QmitkToFRecorderWidget::~QmitkToFRecorderWidget()
{
}

void QmitkToFRecorderWidget::CreateQtPartControl(QWidget *parent)
{
  if (!m_Controls)
  {
    // create GUI widgets
    this->m_Controls = new Ui::QmitkToFRecorderWidgetControls;
    this->m_Controls->setupUi(parent);
    this->CreateConnections();
  }
}

void QmitkToFRecorderWidget::CreateConnections()
{
  if ( m_Controls )
  {
    connect( (QObject*)(m_Controls->m_PlayButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPlay()) );
    connect( (QObject*)(m_Controls->m_StopButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStop()) );
    connect( (QObject*)(m_Controls->m_StartRecordingButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStartRecorder()) );
    connect( (QObject*)(m_Controls->m_RecordModeComboBox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnChangeRecordModeComboBox(int)) );

    connect(this, SIGNAL(RecordingStopped()), this, SLOT(OnRecordingStopped()), Qt::BlockingQueuedConnection);
  }
}

void QmitkToFRecorderWidget::SetParameter(mitk::ToFImageGrabber* toFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder)
{
  this->m_ToFImageGrabber = toFImageGrabber;

  this->m_ToFImageRecorder = toFImageRecorder;

  this->m_StopRecordingCommand = CommandType::New();
  this->m_StopRecordingCommand->SetCallbackFunction(this, &QmitkToFRecorderWidget::StopRecordingCallback);
  this->m_ToFImageRecorder->RemoveAllObservers();
  this->m_ToFImageRecorder->AddObserver(itk::AbortEvent(), this->m_StopRecordingCommand);

  m_Controls->m_PlayButton->setChecked(false);
  m_Controls->m_PlayButton->setEnabled(true);
  m_Controls->m_StartRecordingButton->setChecked(false);
  m_Controls->m_RecorderGroupBox->setEnabled(true);
}

void QmitkToFRecorderWidget::StopRecordingCallback()
{
  emit RecordingStopped();
}

void QmitkToFRecorderWidget::ResetGUIToInitial()
{
  m_Controls->m_PlayButton->setChecked(false);
  m_Controls->m_PlayButton->setEnabled(true);
  m_Controls->m_RecorderGroupBox->setEnabled(false);
}

void QmitkToFRecorderWidget::OnRecordingStopped()
{
  m_Controls->m_StartRecordingButton->setChecked(false);
  m_Controls->m_RecorderGroupBox->setEnabled(true);
}

void QmitkToFRecorderWidget::OnStop()
{
  StopCamera();
  StopRecorder();

  ResetGUIToInitial();

  emit ToFCameraStopped();
}

void QmitkToFRecorderWidget::OnPlay()
{
  m_Controls->m_PlayButton->setChecked(true);
  m_Controls->m_PlayButton->setEnabled(false);
  m_Controls->m_RecorderGroupBox->setEnabled(true);
  this->repaint();

  StartCamera();

  emit ToFCameraStarted();
}

void QmitkToFRecorderWidget::StartCamera()
{
  bool ok = false;
  if (!m_ToFImageGrabber->IsCameraActive())
  {
    m_ToFImageGrabber->StartCamera();
  }
}

void QmitkToFRecorderWidget::StopCamera()
{
  if( m_ToFImageGrabber.IsNotNull() )
    m_ToFImageGrabber->StopCamera();
}

void QmitkToFRecorderWidget::StopRecorder()
{
  if( m_ToFImageRecorder.IsNotNull() )
  {
    this->m_ToFImageRecorder->StopRecording();
  }
}

void QmitkToFRecorderWidget::OnStartRecorder()
{
  m_Controls->m_StartRecordingButton->setChecked(true);
  m_Controls->m_RecorderGroupBox->setEnabled(false);
  this->repaint();

  int numOfFrames = m_Controls->m_NumOfFramesSpinBox->value();
  try
  {
    bool fileOK = true;
    bool distanceImageSelected = true;
    bool amplitudeImageSelected = true;
    bool intensityImageSelected = true;
    bool rgbImageSelected = false;
    bool rawDataSelected = false;

    QString tmpFileName("");
    QString selectedFilter("");
    QString imageFileName("");
    mitk::ToFImageWriter::ToFImageType tofImageType;
    tmpFileName = QmitkToFRecorderWidget::getSaveFileName(tofImageType,
      distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rgbImageSelected, rawDataSelected,
      NULL, "Save Image To...", imageFileName, "NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic);;Text (*.csv)", &selectedFilter);

    if (tmpFileName.isEmpty())
    {
      fileOK = false;
    }
    else
    {
      imageFileName = tmpFileName;
    }

    if (fileOK)
    {
      std::string dir = itksys::SystemTools::GetFilenamePath( imageFileName.toStdString() );
      std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( imageFileName.toStdString() );
      std::string extension = itksys::SystemTools::GetFilenameLastExtension( imageFileName.toStdString() );

      int integrationTime = this->m_ToFImageGrabber->GetIntegrationTime();
      int modulationFreq = this->m_ToFImageGrabber->GetModulationFrequency();

      QString integrationTimeStr;
      integrationTimeStr.setNum(integrationTime);
      QString modulationFreqStr;
      modulationFreqStr.setNum(modulationFreq);
      QString numOfFramesStr("");
      if (this->m_RecordMode == mitk::ToFImageRecorder::PerFrames)
      {
        numOfFramesStr.setNum(numOfFrames);
      }

      std::string distImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
        integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_DistanceImage");
      MITK_INFO << "Save distance data to: " << distImageFileName;

      std::string amplImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
        integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_AmplitudeImage");
      MITK_INFO << "Save amplitude data to: " << amplImageFileName;

      std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
        integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_IntensityImage");
      MITK_INFO << "Save intensity data to: " << intenImageFileName;

      std::string rgbImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
        integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_RGBImage");
      MITK_INFO << "Save intensity data to: " << rgbImageFileName;

      if (selectedFilter.compare("Text (*.csv)") == 0)
      {
        this->m_ToFImageRecorder->SetFileFormat(".csv");
      }
      else if (selectedFilter.compare("PIC Images - deprecated (*.pic)") == 0)
      {
        //default
        this->m_ToFImageRecorder->SetFileFormat(".pic");

        QMessageBox::warning(NULL, "Deprecated File Format!",
          "Please note that *.pic file format is deprecated and not longer supported! The suggested file format for images is *.nrrd!");
      }
      else if (selectedFilter.compare("NRRD Images (*.nrrd)") == 0)
      {
        this->m_ToFImageRecorder->SetFileFormat(".nrrd");
      }
      else
      {
        QMessageBox::warning(NULL, "Unsupported file format!", "Please specify one of the supported file formats *.nrrd, *.csv!");
        return;
      }

      numOfFrames = m_Controls->m_NumOfFramesSpinBox->value();
      this->m_ToFImageRecorder->SetDistanceImageFileName(distImageFileName);
      this->m_ToFImageRecorder->SetAmplitudeImageFileName(amplImageFileName);
      this->m_ToFImageRecorder->SetIntensityImageFileName(intenImageFileName);
      this->m_ToFImageRecorder->SetRGBImageFileName(rgbImageFileName);
      this->m_ToFImageRecorder->SetToFImageType(tofImageType);
      this->m_ToFImageRecorder->SetDistanceImageSelected(distanceImageSelected);
      this->m_ToFImageRecorder->SetAmplitudeImageSelected(amplitudeImageSelected);
      this->m_ToFImageRecorder->SetIntensityImageSelected(intensityImageSelected);
      this->m_ToFImageRecorder->SetRGBImageSelected(rgbImageSelected);
      this->m_ToFImageRecorder->SetRecordMode(this->m_RecordMode);
      this->m_ToFImageRecorder->SetNumOfFrames(numOfFrames);

      emit RecordingStarted();
      this->m_ToFImageRecorder->StartRecording();
    }
    else
    {
      this->OnRecordingStopped();
    }
  }
  catch(std::exception& e)
  {
    QMessageBox::critical(NULL, "Error", QString(e.what()));
    this->OnRecordingStopped();
  }
}

QString QmitkToFRecorderWidget::getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType,
                                     bool& distanceImageSelected,
                                     bool& amplitudeImageSelected,
                                     bool& intensityImageSelected,
                                     bool& rgbImageSelected,
                                     bool& rawDataSelected,
                                     QWidget *parent,
                                     const QString &caption,
                                     const QString &dir,
                                     const QString &filter,
                                     QString *selectedFilter,
                                     QFileDialog::Options options
                                     )
{
  QString selectedFileName = "";
  QComboBox* combo = new QComboBox;
  combo->addItem("3D");
  combo->addItem("2D + t");

  QHBoxLayout* checkBoxGroup = new QHBoxLayout();

  QCheckBox* distanceImageCheckBox = new QCheckBox;
  distanceImageCheckBox->setText("Distance image");
  distanceImageCheckBox->setChecked(true);
  QCheckBox* amplitudeImageCheckBox = new QCheckBox;
  amplitudeImageCheckBox->setText("Amplitude image");
  amplitudeImageCheckBox->setChecked(true);
  QCheckBox* intensityImageCheckBox = new QCheckBox;
  intensityImageCheckBox->setText("Intensity image");
  intensityImageCheckBox->setChecked(true);
  QCheckBox* rgbImageCheckBox = new QCheckBox;
  rgbImageCheckBox->setText("RGB image");
  rgbImageCheckBox->setChecked(false);
  QCheckBox* rawDataCheckBox = new QCheckBox;
  rawDataCheckBox->setText("Raw data");
  rawDataCheckBox->setChecked(false);
  rawDataCheckBox->setEnabled(false);

  checkBoxGroup->addWidget(distanceImageCheckBox);
  checkBoxGroup->addWidget(amplitudeImageCheckBox);
  checkBoxGroup->addWidget(intensityImageCheckBox);
  checkBoxGroup->addWidget(rgbImageCheckBox);
  checkBoxGroup->addWidget(rawDataCheckBox);

  QFileDialog* fileDialog = new QFileDialog(parent, caption, dir, filter);

  QLayout* layout = fileDialog->layout();
  QGridLayout* gridbox = qobject_cast<QGridLayout*>(layout);

  if (gridbox)
  {
    gridbox->addWidget(new QLabel("ToF-Image type:"));
    gridbox->addWidget(combo);
    int lastRow = gridbox->rowCount();
    gridbox->addLayout(checkBoxGroup, lastRow, 0, 1, -1);
  }

  fileDialog->setLayout(gridbox);
  fileDialog->setAcceptMode(QFileDialog::AcceptSave);

  if (selectedFilter)
  {
    fileDialog->selectNameFilter(*selectedFilter);
  }

  if (fileDialog->exec() == QDialog::Accepted)
  {
    if (selectedFilter)
    {
      *selectedFilter = fileDialog->selectedFilter();
    }

    if (combo->currentIndex() == 0)
    {
      tofImageType = mitk::ToFImageWriter::ToFImageType3D;
    }

    else
    {
      tofImageType = mitk::ToFImageWriter::ToFImageType2DPlusT;
    }

    distanceImageSelected = distanceImageCheckBox->isChecked();
    amplitudeImageSelected = amplitudeImageCheckBox->isChecked();
    intensityImageSelected = intensityImageCheckBox->isChecked();
    rgbImageSelected = rgbImageCheckBox->isChecked();
    rawDataSelected = rawDataCheckBox->isChecked();

    selectedFileName = fileDialog->selectedFiles().value(0);
  }

  delete fileDialog;
  return selectedFileName;
}

std::string QmitkToFRecorderWidget::prepareFilename(std::string dir,
                                                    std::string baseFilename,
                                                    std::string modulationFreq,
                                                    std::string integrationTime,
                                                    std::string numOfFrames,
                                                    std::string extension,
                                                    std::string imageType)
{
  std::string filenName("");
  filenName.append(dir);
  filenName.append("/");
  filenName.append(baseFilename);
  filenName.append("_MF");
  filenName.append(modulationFreq);
  filenName.append("_IT");
  filenName.append(integrationTime);
  filenName.append("_");
  filenName.append(numOfFrames);
  filenName.append("Images");
  filenName.append(imageType);
  filenName.append(extension);
  return filenName;
}

void QmitkToFRecorderWidget::OnChangeRecordModeComboBox(int index)
{
  if (index == 0)
  {
    this->m_RecordMode = mitk::ToFImageRecorder::PerFrames;
    m_Controls->m_NumOfFramesSpinBox->setEnabled(true);
  }
  else
  {
    this->m_RecordMode = mitk::ToFImageRecorder::Infinite;
    m_Controls->m_NumOfFramesSpinBox->setEnabled(false);
  }
}
<commit_msg>Adapted the recorder widget to automatically select all supported image types.<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#define _USE_MATH_DEFINES
#include "QmitkToFRecorderWidget.h"

//QT headers
#include <qmessagebox.h>
#include <QComboBox>
#include <QLabel>
#include <QLayout>
#include <QGridLayout>
#include <QCheckBox>

//mitk headers
#include <mitkToFImageWriter.h>

//itk headers
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
#include <itksys/SystemTools.hxx>

struct QFileDialogArgs;
class QFileDialogPrivate;

const std::string QmitkToFRecorderWidget::VIEW_ID = "org.mitk.views.qmitktofrecorderwidget";

QmitkToFRecorderWidget::QmitkToFRecorderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
{
  this->m_ToFImageRecorder = NULL;
  this->m_ToFImageGrabber = NULL;
  this->m_RecordMode = mitk::ToFImageRecorder::PerFrames;

  this-> m_Controls = NULL;
  CreateQtPartControl(this);
}

QmitkToFRecorderWidget::~QmitkToFRecorderWidget()
{
}

void QmitkToFRecorderWidget::CreateQtPartControl(QWidget *parent)
{
  if (!m_Controls)
  {
    // create GUI widgets
    this->m_Controls = new Ui::QmitkToFRecorderWidgetControls;
    this->m_Controls->setupUi(parent);
    this->CreateConnections();
  }
}

void QmitkToFRecorderWidget::CreateConnections()
{
  if ( m_Controls )
  {
    connect( (QObject*)(m_Controls->m_PlayButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPlay()) );
    connect( (QObject*)(m_Controls->m_StopButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStop()) );
    connect( (QObject*)(m_Controls->m_StartRecordingButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStartRecorder()) );
    connect( (QObject*)(m_Controls->m_RecordModeComboBox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnChangeRecordModeComboBox(int)) );

    connect(this, SIGNAL(RecordingStopped()), this, SLOT(OnRecordingStopped()), Qt::BlockingQueuedConnection);
  }
}

void QmitkToFRecorderWidget::SetParameter(mitk::ToFImageGrabber* toFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder)
{
  this->m_ToFImageGrabber = toFImageGrabber;

  this->m_ToFImageRecorder = toFImageRecorder;

  this->m_StopRecordingCommand = CommandType::New();
  this->m_StopRecordingCommand->SetCallbackFunction(this, &QmitkToFRecorderWidget::StopRecordingCallback);
  this->m_ToFImageRecorder->RemoveAllObservers();
  this->m_ToFImageRecorder->AddObserver(itk::AbortEvent(), this->m_StopRecordingCommand);

  m_Controls->m_PlayButton->setChecked(false);
  m_Controls->m_PlayButton->setEnabled(true);
  m_Controls->m_StartRecordingButton->setChecked(false);
  m_Controls->m_RecorderGroupBox->setEnabled(true);
}

void QmitkToFRecorderWidget::StopRecordingCallback()
{
  emit RecordingStopped();
}

void QmitkToFRecorderWidget::ResetGUIToInitial()
{
  m_Controls->m_PlayButton->setChecked(false);
  m_Controls->m_PlayButton->setEnabled(true);
  m_Controls->m_RecorderGroupBox->setEnabled(false);
}

void QmitkToFRecorderWidget::OnRecordingStopped()
{
  m_Controls->m_StartRecordingButton->setChecked(false);
  m_Controls->m_RecorderGroupBox->setEnabled(true);
}

void QmitkToFRecorderWidget::OnStop()
{
  StopCamera();
  StopRecorder();

  ResetGUIToInitial();

  emit ToFCameraStopped();
}

void QmitkToFRecorderWidget::OnPlay()
{
  m_Controls->m_PlayButton->setChecked(true);
  m_Controls->m_PlayButton->setEnabled(false);
  m_Controls->m_RecorderGroupBox->setEnabled(true);
  this->repaint();

  StartCamera();

  emit ToFCameraStarted();
}

void QmitkToFRecorderWidget::StartCamera()
{
  if (!m_ToFImageGrabber->IsCameraActive())
  {
    m_ToFImageGrabber->StartCamera();
  }
}

void QmitkToFRecorderWidget::StopCamera()
{
  if( m_ToFImageGrabber.IsNotNull() )
    m_ToFImageGrabber->StopCamera();
}

void QmitkToFRecorderWidget::StopRecorder()
{
  if( m_ToFImageRecorder.IsNotNull() )
  {
    this->m_ToFImageRecorder->StopRecording();
  }
}

void QmitkToFRecorderWidget::OnStartRecorder()
{
  m_Controls->m_StartRecordingButton->setChecked(true);
  m_Controls->m_RecorderGroupBox->setEnabled(false);
  this->repaint();

  int numOfFrames = m_Controls->m_NumOfFramesSpinBox->value();
  try
  {
    bool fileOK = true;
    bool distanceImageSelected = true;
    bool amplitudeImageSelected = false;
    bool intensityImageSelected = false;
    bool rgbImageSelected = false;
    bool rawDataSelected = false;

    //Set check boxes in dialog according to device properties
    m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasAmplitudeImage",amplitudeImageSelected);
    m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasIntensityImage",intensityImageSelected);
    m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasRGBImage",rgbImageSelected);

    QString tmpFileName("");
    QString selectedFilter("");
    QString imageFileName("");
    mitk::ToFImageWriter::ToFImageType tofImageType;
    tmpFileName = QmitkToFRecorderWidget::getSaveFileName(tofImageType,
      distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rgbImageSelected, rawDataSelected,
      NULL, "Save Image To...", imageFileName, "NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic);;Text (*.csv)", &selectedFilter);

    if (tmpFileName.isEmpty())
    {
      fileOK = false;
    }
    else
    {
      imageFileName = tmpFileName;
    }

    if (fileOK)
    {
      std::string dir = itksys::SystemTools::GetFilenamePath( imageFileName.toStdString() );
      std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( imageFileName.toStdString() );
      std::string extension = itksys::SystemTools::GetFilenameLastExtension( imageFileName.toStdString() );

      int integrationTime = this->m_ToFImageGrabber->GetIntegrationTime();
      int modulationFreq = this->m_ToFImageGrabber->GetModulationFrequency();

      QString integrationTimeStr;
      integrationTimeStr.setNum(integrationTime);
      QString modulationFreqStr;
      modulationFreqStr.setNum(modulationFreq);
      QString numOfFramesStr("");
      if (this->m_RecordMode == mitk::ToFImageRecorder::PerFrames)
      {
        numOfFramesStr.setNum(numOfFrames);
      }

      std::string distImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
        integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_DistanceImage");
      MITK_INFO << "Save distance data to: " << distImageFileName;

      std::string amplImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
        integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_AmplitudeImage");
      MITK_INFO << "Save amplitude data to: " << amplImageFileName;

      std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
        integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_IntensityImage");
      MITK_INFO << "Save intensity data to: " << intenImageFileName;

      std::string rgbImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
        integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_RGBImage");
      MITK_INFO << "Save intensity data to: " << rgbImageFileName;

      if (selectedFilter.compare("Text (*.csv)") == 0)
      {
        this->m_ToFImageRecorder->SetFileFormat(".csv");
      }
      else if (selectedFilter.compare("PIC Images - deprecated (*.pic)") == 0)
      {
        //default
        this->m_ToFImageRecorder->SetFileFormat(".pic");

        QMessageBox::warning(NULL, "Deprecated File Format!",
          "Please note that *.pic file format is deprecated and not longer supported! The suggested file format for images is *.nrrd!");
      }
      else if (selectedFilter.compare("NRRD Images (*.nrrd)") == 0)
      {
        this->m_ToFImageRecorder->SetFileFormat(".nrrd");
      }
      else
      {
        QMessageBox::warning(NULL, "Unsupported file format!", "Please specify one of the supported file formats *.nrrd, *.csv!");
        return;
      }

      numOfFrames = m_Controls->m_NumOfFramesSpinBox->value();
      this->m_ToFImageRecorder->SetDistanceImageFileName(distImageFileName);
      this->m_ToFImageRecorder->SetAmplitudeImageFileName(amplImageFileName);
      this->m_ToFImageRecorder->SetIntensityImageFileName(intenImageFileName);
      this->m_ToFImageRecorder->SetRGBImageFileName(rgbImageFileName);
      this->m_ToFImageRecorder->SetToFImageType(tofImageType);
      this->m_ToFImageRecorder->SetDistanceImageSelected(distanceImageSelected);
      this->m_ToFImageRecorder->SetAmplitudeImageSelected(amplitudeImageSelected);
      this->m_ToFImageRecorder->SetIntensityImageSelected(intensityImageSelected);
      this->m_ToFImageRecorder->SetRGBImageSelected(rgbImageSelected);
      this->m_ToFImageRecorder->SetRecordMode(this->m_RecordMode);
      this->m_ToFImageRecorder->SetNumOfFrames(numOfFrames);

      emit RecordingStarted();
      this->m_ToFImageRecorder->StartRecording();
    }
    else
    {
      this->OnRecordingStopped();
    }
  }
  catch(std::exception& e)
  {
    QMessageBox::critical(NULL, "Error", QString(e.what()));
    this->OnRecordingStopped();
  }
}

QString QmitkToFRecorderWidget::getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType,
                                     bool& distanceImageSelected,
                                     bool& amplitudeImageSelected,
                                     bool& intensityImageSelected,
                                     bool& rgbImageSelected,
                                     bool& rawDataSelected,
                                     QWidget *parent,
                                     const QString &caption,
                                     const QString &dir,
                                     const QString &filter,
                                     QString *selectedFilter,
                                     QFileDialog::Options options
                                     )
{
  QString selectedFileName = "";
  QComboBox* combo = new QComboBox;
  combo->addItem("3D");
  combo->addItem("2D + t");

  QHBoxLayout* checkBoxGroup = new QHBoxLayout();

  QCheckBox* distanceImageCheckBox = new QCheckBox;
  distanceImageCheckBox->setText("Distance image");
  distanceImageCheckBox->setChecked(distanceImageSelected);
  QCheckBox* amplitudeImageCheckBox = new QCheckBox;
  amplitudeImageCheckBox->setText("Amplitude image");
  amplitudeImageCheckBox->setChecked(amplitudeImageSelected);
  QCheckBox* intensityImageCheckBox = new QCheckBox;
  intensityImageCheckBox->setText("Intensity image");
  intensityImageCheckBox->setChecked(intensityImageSelected);
  QCheckBox* rgbImageCheckBox = new QCheckBox;
  rgbImageCheckBox->setText("RGB image");
  rgbImageCheckBox->setChecked(rgbImageSelected);
  QCheckBox* rawDataCheckBox = new QCheckBox;
  rawDataCheckBox->setText("Raw data");
  rawDataCheckBox->setChecked(false);
  rawDataCheckBox->setEnabled(false);

  checkBoxGroup->addWidget(distanceImageCheckBox);
  checkBoxGroup->addWidget(amplitudeImageCheckBox);
  checkBoxGroup->addWidget(intensityImageCheckBox);
  checkBoxGroup->addWidget(rgbImageCheckBox);
  checkBoxGroup->addWidget(rawDataCheckBox);

  QFileDialog* fileDialog = new QFileDialog(parent, caption, dir, filter);

  QLayout* layout = fileDialog->layout();
  QGridLayout* gridbox = qobject_cast<QGridLayout*>(layout);

  if (gridbox)
  {
    gridbox->addWidget(new QLabel("ToF-Image type:"));
    gridbox->addWidget(combo);
    int lastRow = gridbox->rowCount();
    gridbox->addLayout(checkBoxGroup, lastRow, 0, 1, -1);
  }

  fileDialog->setLayout(gridbox);
  fileDialog->setAcceptMode(QFileDialog::AcceptSave);

  if (selectedFilter)
  {
    fileDialog->selectNameFilter(*selectedFilter);
  }

  if (fileDialog->exec() == QDialog::Accepted)
  {
    if (selectedFilter)
    {
      *selectedFilter = fileDialog->selectedFilter();
    }

    if (combo->currentIndex() == 0)
    {
      tofImageType = mitk::ToFImageWriter::ToFImageType3D;
    }

    else
    {
      tofImageType = mitk::ToFImageWriter::ToFImageType2DPlusT;
    }

    distanceImageSelected = distanceImageCheckBox->isChecked();
    amplitudeImageSelected = amplitudeImageCheckBox->isChecked();
    intensityImageSelected = intensityImageCheckBox->isChecked();
    rgbImageSelected = rgbImageCheckBox->isChecked();
    rawDataSelected = rawDataCheckBox->isChecked();

    selectedFileName = fileDialog->selectedFiles().value(0);
  }

  delete fileDialog;
  return selectedFileName;
}

std::string QmitkToFRecorderWidget::prepareFilename(std::string dir,
                                                    std::string baseFilename,
                                                    std::string modulationFreq,
                                                    std::string integrationTime,
                                                    std::string numOfFrames,
                                                    std::string extension,
                                                    std::string imageType)
{
  std::string filenName("");
  filenName.append(dir);
  filenName.append("/");
  filenName.append(baseFilename);
  filenName.append("_MF");
  filenName.append(modulationFreq);
  filenName.append("_IT");
  filenName.append(integrationTime);
  filenName.append("_");
  filenName.append(numOfFrames);
  filenName.append("Images");
  filenName.append(imageType);
  filenName.append(extension);
  return filenName;
}

void QmitkToFRecorderWidget::OnChangeRecordModeComboBox(int index)
{
  if (index == 0)
  {
    this->m_RecordMode = mitk::ToFImageRecorder::PerFrames;
    m_Controls->m_NumOfFramesSpinBox->setEnabled(true);
  }
  else
  {
    this->m_RecordMode = mitk::ToFImageRecorder::Infinite;
    m_Controls->m_NumOfFramesSpinBox->setEnabled(false);
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/external_tab_container.h"

#include "app/win_util.h"
#include "base/logging.h"
#include "base/win_util.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/load_notification_details.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/provisional_load_details.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/tab_contents/tab_contents_container.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/automation/automation_messages.h"

static const wchar_t kWindowObjectKey[] = L"ChromeWindowObject";

// TODO(sanjeevr): The external_accel_table_ and external_accel_entry_count_
// member variables are now obsolete and we don't use them.
// We need to remove them.
ExternalTabContainer::ExternalTabContainer(
    AutomationProvider* automation)
    : automation_(automation),
      tab_contents_(NULL),
      external_accel_table_(NULL),
      external_accel_entry_count_(0),
      tab_contents_container_(NULL),
      tab_handle_(0),
      ignore_next_load_notification_(false) {
}

ExternalTabContainer::~ExternalTabContainer() {
  Uninitialize(GetNativeView());
}

bool ExternalTabContainer::Init(Profile* profile,
                                HWND parent,
                                const gfx::Rect& bounds,
                                DWORD style) {
  if (IsWindow()) {
    NOTREACHED();
    return false;
  }

  set_window_style(WS_POPUP);
  views::WidgetWin::Init(NULL, bounds, true);
  if (!IsWindow()) {
    NOTREACHED();
    return false;
  }

  // We don't ever remove the prop because the lifetime of this object
  // is the same as the lifetime of the window
  SetProp(GetNativeView(), kWindowObjectKey, this);

  views::FocusManager* focus_manager =
      views::FocusManager::GetFocusManager(GetNativeView());
  focus_manager->AddKeystrokeListener(this);

  tab_contents_ = new TabContents(profile, NULL, MSG_ROUTING_NONE, NULL);
  tab_contents_->set_delegate(this);
  tab_contents_->render_view_host()->AllowExternalHostBindings();

  // Create a TabContentsContainer to handle focus cycling using Tab and
  // Shift-Tab.
  tab_contents_container_ = new TabContentsContainer;
  SetContentsView(tab_contents_container_);

  // Note that SetTabContents must be called after AddChildView is called
  tab_contents_container_->ChangeTabContents(tab_contents_);

  NavigationController* controller = &tab_contents_->controller();
  registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
                 Source<NavigationController>(controller));
  registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR,
                 Source<NavigationController>(controller));
  registrar_.Add(this, NotificationType::LOAD_STOP,
                 Source<NavigationController>(controller));
  NotificationService::current()->Notify(
      NotificationType::EXTERNAL_TAB_CREATED,
      Source<NavigationController>(controller),
      NotificationService::NoDetails());

  // We need WS_POPUP to be on the window during initialization, but
  // once initialized we apply the requested style which may or may not
  // include the popup bit.
  // Note that it's important to do this before we call SetParent since
  // during the SetParent call we will otherwise get a WA_ACTIVATE call
  // that causes us to steal the current focus.
  SetWindowLong(GWL_STYLE, (GetWindowLong(GWL_STYLE) & ~WS_POPUP) | style);

  // Now apply the parenting and style
  if (parent)
    SetParent(GetNativeView(), parent);

  ::ShowWindow(tab_contents_->GetNativeView(), SW_SHOWNA);
  return true;
}

void ExternalTabContainer::SetAccelerators(HACCEL accel_table,
                                           int accel_table_entry_count) {
  external_accel_table_ = accel_table;
  external_accel_entry_count_ = accel_table_entry_count;
}

void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) {
  // We just received an accelerator key that we had sent to external host
  // back. Since the external host was not interested in handling this, we
  // need to dispatch this message as if we had just peeked this out. (we
  // also need to call TranslateMessage to generate a WM_CHAR if needed).
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}

void ExternalTabContainer::SetInitialFocus(bool reverse) {
  DCHECK(tab_contents_);
  if (tab_contents_) {
    static_cast<TabContents*>(tab_contents_)->Focus();
    static_cast<TabContents*>(tab_contents_)->SetInitialFocus(reverse);
  }
}

// static
bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
  if (GetProp(window, kWindowObjectKey) != NULL)
    return true;

  return false;
}

// static
ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
    HWND tab_window) {
  HWND parent_window = ::GetParent(tab_window);
  if (!::IsWindow(parent_window)) {
    return NULL;
  }
  if (!IsExternalTabContainer(parent_window)) {
    return NULL;
  }
  ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>(
      GetProp(parent_window, kWindowObjectKey));
  return container;
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, TabContentsDelegate implementation:

void ExternalTabContainer::OpenURLFromTab(TabContents* source,
                           const GURL& url,
                           const GURL& referrer,
                           WindowOpenDisposition disposition,
                           PageTransition::Type transition) {
  switch (disposition) {
    case CURRENT_TAB:
    case SINGLETON_TAB:
    case NEW_FOREGROUND_TAB:
    case NEW_BACKGROUND_TAB:
    case NEW_WINDOW:
      if (automation_) {
        automation_->Send(new AutomationMsg_OpenURL(0, tab_handle_,
                                                    url, disposition));
      }
      break;
    default:
      break;
  }
}

void ExternalTabContainer::NavigationStateChanged(const TabContents* source,
                                                  unsigned changed_flags) {
  if (automation_) {
    automation_->Send(new AutomationMsg_NavigationStateChanged(0, tab_handle_,
                                                               changed_flags));
  }
}

void ExternalTabContainer::AddNewContents(TabContents* source,
                            TabContents* new_contents,
                            WindowOpenDisposition disposition,
                            const gfx::Rect& initial_pos,
                            bool user_gesture) {
  if (disposition == NEW_POPUP || disposition == NEW_WINDOW ||
      disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) {
    Browser::BuildPopupWindowHelper(source, new_contents, initial_pos,
                                    Browser::TYPE_POPUP,
                                    tab_contents_->profile(), true);
  } else {
    NOTREACHED();
  }
}

void ExternalTabContainer::ActivateContents(TabContents* contents) {
}

void ExternalTabContainer::LoadingStateChanged(TabContents* source) {
}

void ExternalTabContainer::CloseContents(TabContents* source) {
}

void ExternalTabContainer::MoveContents(TabContents* source,
                                        const gfx::Rect& pos) {
}

bool ExternalTabContainer::IsPopup(TabContents* source) {
  return false;
}

void ExternalTabContainer::URLStarredChanged(TabContents* source,
                                             bool starred) {
}

void ExternalTabContainer::UpdateTargetURL(TabContents* source,
                                           const GURL& url) {
  if (automation_) {
    std::wstring url_string = CA2W(url.spec().c_str());
    automation_->Send(
        new AutomationMsg_UpdateTargetUrl(0, tab_handle_, url_string));
  }
}

void ExternalTabContainer::ContentsZoomChange(bool zoom_in) {
}

void ExternalTabContainer::ToolbarSizeChanged(TabContents* source,
                                              bool finished) {
}

void ExternalTabContainer::ForwardMessageToExternalHost(
    const std::string& message, const std::string& origin,
    const std::string& target) {
  if (automation_) {
    automation_->Send(
        new AutomationMsg_ForwardMessageToExternalHost(0, tab_handle_,
            message, origin, target));
  }
}

ExtensionFunctionDispatcher* ExternalTabContainer::
    CreateExtensionFunctionDispatcher(RenderViewHost* render_view_host,
                                      const std::string& extension_id) {
  return new ExtensionFunctionDispatcher(render_view_host, NULL, extension_id);
}

bool ExternalTabContainer::TakeFocus(bool reverse) {
  if (automation_) {
    views::FocusManager* focus_manager =
        views::FocusManager::GetFocusManager(GetNativeView());
    DCHECK(focus_manager);
    if (focus_manager) {
      focus_manager->ClearFocus();
      automation_->Send(new AutomationMsg_TabbedOut(0, tab_handle_,
          win_util::IsShiftPressed()));
    }
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, NotificationObserver implementation:

void ExternalTabContainer::Observe(NotificationType type,
                                   const NotificationSource& source,
                                   const NotificationDetails& details) {
  if (!automation_)
    return;

  static const int kHttpClientErrorStart = 400;
  static const int kHttpServerErrorEnd = 510;

  switch (type.value) {
    case NotificationType::LOAD_STOP: {
        const LoadNotificationDetails* load =
            Details<LoadNotificationDetails>(details).ptr();
        if (load != NULL && PageTransition::IsMainFrame(load->origin())) {
          automation_->Send(new AutomationMsg_TabLoaded(0, tab_handle_,
                                                        load->url()));
        }
        break;
      }
    case NotificationType::NAV_ENTRY_COMMITTED: {
        if (ignore_next_load_notification_) {
          ignore_next_load_notification_ = false;
          return;
        }

        const NavigationController::LoadCommittedDetails* commit =
            Details<NavigationController::LoadCommittedDetails>(details).ptr();

        if (commit->http_status_code >= kHttpClientErrorStart &&
            commit->http_status_code <= kHttpServerErrorEnd) {
          automation_->Send(new AutomationMsg_NavigationFailed(
              0, tab_handle_, commit->http_status_code, commit->entry->url()));

          ignore_next_load_notification_ = true;
        } else {
          // When the previous entry index is invalid, it will be -1, which
          // will still make the computation come out right (navigating to the
          // 0th entry will be +1).
          automation_->Send(new AutomationMsg_DidNavigate(
              0, tab_handle_, commit->type,
              commit->previous_entry_index -
                  tab_contents_->controller().last_committed_entry_index(),
              commit->entry->url()));
        }
        break;
      }
    case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR: {
      const ProvisionalLoadDetails* load_details =
          Details<ProvisionalLoadDetails>(details).ptr();
      automation_->Send(new AutomationMsg_NavigationFailed(
          0, tab_handle_, load_details->error_code(), load_details->url()));

      ignore_next_load_notification_ = true;
      break;
    }
    default:
      NOTREACHED();
  }
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, views::WidgetWin overrides:

void ExternalTabContainer::OnDestroy() {
  Uninitialize(GetNativeView());
  WidgetWin::OnDestroy();
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, views::KeystrokeListener implementation:

bool ExternalTabContainer::ProcessKeyStroke(HWND window, UINT message,
                                            WPARAM wparam, LPARAM lparam) {
  if (!automation_) {
    return false;
  }
  if ((wparam == VK_TAB) && !win_util::IsCtrlPressed()) {
    // Tabs are handled separately (except if this is Ctrl-Tab or
    // Ctrl-Shift-Tab)
    return false;
  }

  unsigned int flags = HIWORD(lparam);
  bool alt = (flags & KF_ALTDOWN) != 0;
  if (!alt && (message == WM_SYSKEYUP || message == WM_KEYUP)) {
    // In case the Alt key is being released.
    alt = (wparam == VK_MENU);
  }

  if ((flags & KF_EXTENDED) || alt || (wparam >= VK_F1 && wparam <= VK_F24) ||
      wparam == VK_ESCAPE || wparam == VK_RETURN ||
      win_util::IsShiftPressed() || win_util::IsCtrlPressed()) {
    // If this is an extended key or if one or more of Alt, Shift and Control
    // are pressed, this might be an accelerator that the external host wants
    // to handle. If the host does not handle this accelerator, it will reflect
    // the accelerator back to us via the ProcessUnhandledAccelerator method.
    MSG msg = {0};
    msg.hwnd = window;
    msg.message = message;
    msg.wParam = wparam;
    msg.lParam = lparam;
    automation_->Send(new AutomationMsg_HandleAccelerator(0, tab_handle_, msg));
    return true;
  }

  return false;
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, private:

void ExternalTabContainer::Uninitialize(HWND window) {
  if (::IsWindow(window)) {
    views::FocusManager* focus_manager =
        views::FocusManager::GetFocusManager(window);
    if (focus_manager)
      focus_manager->RemoveKeystrokeListener(this);
  }

  if (tab_contents_) {
    NotificationService::current()->Notify(
        NotificationType::EXTERNAL_TAB_CLOSED,
        Source<NavigationController>(&tab_contents_->controller()),
        Details<ExternalTabContainer>(this));

    delete tab_contents_;
    tab_contents_ = NULL;
  }
}

<commit_msg>Rollin' back 17315. Looks to be breaking OpenPopupWindowWithPlugin in the UI Test on the builder.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/external_tab_container.h"

#include "app/win_util.h"
#include "base/logging.h"
#include "base/win_util.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/load_notification_details.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/provisional_load_details.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/tab_contents/tab_contents_container.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/automation/automation_messages.h"

static const wchar_t kWindowObjectKey[] = L"ChromeWindowObject";

// TODO(sanjeevr): The external_accel_table_ and external_accel_entry_count_
// member variables are now obsolete and we don't use them.
// We need to remove them.
ExternalTabContainer::ExternalTabContainer(
    AutomationProvider* automation)
    : automation_(automation),
      tab_contents_(NULL),
      external_accel_table_(NULL),
      external_accel_entry_count_(0),
      tab_contents_container_(NULL),
      tab_handle_(0),
      ignore_next_load_notification_(false) {
}

ExternalTabContainer::~ExternalTabContainer() {
  Uninitialize(GetNativeView());
}

bool ExternalTabContainer::Init(Profile* profile,
                                HWND parent,
                                const gfx::Rect& bounds,
                                DWORD style) {
  if (IsWindow()) {
    NOTREACHED();
    return false;
  }

  set_window_style(WS_POPUP);
  views::WidgetWin::Init(NULL, bounds, true);
  if (!IsWindow()) {
    NOTREACHED();
    return false;
  }

  // We don't ever remove the prop because the lifetime of this object
  // is the same as the lifetime of the window
  SetProp(GetNativeView(), kWindowObjectKey, this);

  views::FocusManager* focus_manager =
      views::FocusManager::GetFocusManager(GetNativeView());
  focus_manager->AddKeystrokeListener(this);

  tab_contents_ = new TabContents(profile, NULL, MSG_ROUTING_NONE, NULL);
  tab_contents_->set_delegate(this);
  tab_contents_->render_view_host()->AllowExternalHostBindings();

  // Create a TabContentsContainer to handle focus cycling using Tab and
  // Shift-Tab.
  tab_contents_container_ = new TabContentsContainer;
  SetContentsView(tab_contents_container_);

  // Note that SetTabContents must be called after AddChildView is called
  tab_contents_container_->ChangeTabContents(tab_contents_);

  NavigationController* controller = &tab_contents_->controller();
  registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
                 Source<NavigationController>(controller));
  registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR,
                 Source<NavigationController>(controller));
  registrar_.Add(this, NotificationType::LOAD_STOP,
                 Source<NavigationController>(controller));
  NotificationService::current()->Notify(
      NotificationType::EXTERNAL_TAB_CREATED,
      Source<NavigationController>(controller),
      NotificationService::NoDetails());

  // We need WS_POPUP to be on the window during initialization, but
  // once initialized we apply the requested style which may or may not
  // include the popup bit.
  // Note that it's important to do this before we call SetParent since
  // during the SetParent call we will otherwise get a WA_ACTIVATE call
  // that causes us to steal the current focus.
  SetWindowLong(GWL_STYLE, (GetWindowLong(GWL_STYLE) & ~WS_POPUP) | style);

  // Now apply the parenting and style
  if (parent)
    SetParent(GetNativeView(), parent);

  ::ShowWindow(tab_contents_->GetNativeView(), SW_SHOWNA);
  return true;
}

void ExternalTabContainer::SetAccelerators(HACCEL accel_table,
                                           int accel_table_entry_count) {
  external_accel_table_ = accel_table;
  external_accel_entry_count_ = accel_table_entry_count;
}

void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) {
  // We just received an accelerator key that we had sent to external host
  // back. Since the external host was not interested in handling this, we
  // need to dispatch this message as if we had just peeked this out. (we
  // also need to call TranslateMessage to generate a WM_CHAR if needed).
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}

void ExternalTabContainer::SetInitialFocus(bool reverse) {
  DCHECK(tab_contents_);
  if (tab_contents_) {
    static_cast<TabContents*>(tab_contents_)->Focus();
    static_cast<TabContents*>(tab_contents_)->SetInitialFocus(reverse);
  }
}

// static
bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
  if (GetProp(window, kWindowObjectKey) != NULL)
    return true;

  return false;
}

// static
ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
    HWND tab_window) {
  HWND parent_window = ::GetParent(tab_window);
  if (!::IsWindow(parent_window)) {
    return NULL;
  }
  if (!IsExternalTabContainer(parent_window)) {
    return NULL;
  }
  ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>(
      GetProp(parent_window, kWindowObjectKey));
  return container;
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, TabContentsDelegate implementation:

void ExternalTabContainer::OpenURLFromTab(TabContents* source,
                           const GURL& url,
                           const GURL& referrer,
                           WindowOpenDisposition disposition,
                           PageTransition::Type transition) {
  switch (disposition) {
    case CURRENT_TAB:
    case SINGLETON_TAB:
    case NEW_FOREGROUND_TAB:
    case NEW_BACKGROUND_TAB:
    case NEW_WINDOW:
      if (automation_) {
        automation_->Send(new AutomationMsg_OpenURL(0, tab_handle_,
                                                    url, disposition));
      }
      break;
    default:
      break;
  }
}

void ExternalTabContainer::NavigationStateChanged(const TabContents* source,
                                                  unsigned changed_flags) {
  if (automation_) {
    automation_->Send(new AutomationMsg_NavigationStateChanged(0, tab_handle_,
                                                               changed_flags));
  }
}

void ExternalTabContainer::AddNewContents(TabContents* source,
                            TabContents* new_contents,
                            WindowOpenDisposition disposition,
                            const gfx::Rect& initial_pos,
                            bool user_gesture) {
  if (disposition == NEW_POPUP || disposition == NEW_WINDOW) {
    Browser::BuildPopupWindowHelper(source, new_contents, initial_pos,
                                    Browser::TYPE_POPUP,
                                    tab_contents_->profile(), true);
  } else {
    NOTREACHED();
  }
}

void ExternalTabContainer::ActivateContents(TabContents* contents) {
}

void ExternalTabContainer::LoadingStateChanged(TabContents* source) {
}

void ExternalTabContainer::CloseContents(TabContents* source) {
}

void ExternalTabContainer::MoveContents(TabContents* source,
                                        const gfx::Rect& pos) {
}

bool ExternalTabContainer::IsPopup(TabContents* source) {
  return false;
}

void ExternalTabContainer::URLStarredChanged(TabContents* source,
                                             bool starred) {
}

void ExternalTabContainer::UpdateTargetURL(TabContents* source,
                                           const GURL& url) {
  if (automation_) {
    std::wstring url_string = CA2W(url.spec().c_str());
    automation_->Send(
        new AutomationMsg_UpdateTargetUrl(0, tab_handle_, url_string));
  }
}

void ExternalTabContainer::ContentsZoomChange(bool zoom_in) {
}

void ExternalTabContainer::ToolbarSizeChanged(TabContents* source,
                                              bool finished) {
}

void ExternalTabContainer::ForwardMessageToExternalHost(
    const std::string& message, const std::string& origin,
    const std::string& target) {
  if(automation_) {
    automation_->Send(
        new AutomationMsg_ForwardMessageToExternalHost(0, tab_handle_,
            message, origin, target));
  }
}

ExtensionFunctionDispatcher* ExternalTabContainer::
    CreateExtensionFunctionDispatcher(RenderViewHost* render_view_host,
                                      const std::string& extension_id) {
  return new ExtensionFunctionDispatcher(render_view_host, NULL, extension_id);
}

bool ExternalTabContainer::TakeFocus(bool reverse) {
  if (automation_) {
    views::FocusManager* focus_manager =
        views::FocusManager::GetFocusManager(GetNativeView());
    DCHECK(focus_manager);
    if (focus_manager) {
      focus_manager->ClearFocus();
      automation_->Send(new AutomationMsg_TabbedOut(0, tab_handle_,
          win_util::IsShiftPressed()));
    }
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, NotificationObserver implementation:

void ExternalTabContainer::Observe(NotificationType type,
                                   const NotificationSource& source,
                                   const NotificationDetails& details) {
  if (!automation_)
    return;

  static const int kHttpClientErrorStart = 400;
  static const int kHttpServerErrorEnd = 510;

  switch (type.value) {
    case NotificationType::LOAD_STOP: {
        const LoadNotificationDetails* load =
            Details<LoadNotificationDetails>(details).ptr();
        if (load != NULL && PageTransition::IsMainFrame(load->origin())) {
          automation_->Send(new AutomationMsg_TabLoaded(0, tab_handle_,
                                                        load->url()));
        }
        break;
      }
    case NotificationType::NAV_ENTRY_COMMITTED: {
        if (ignore_next_load_notification_) {
          ignore_next_load_notification_ = false;
          return;
        }

        const NavigationController::LoadCommittedDetails* commit =
            Details<NavigationController::LoadCommittedDetails>(details).ptr();

        if (commit->http_status_code >= kHttpClientErrorStart &&
            commit->http_status_code <= kHttpServerErrorEnd) {
          automation_->Send(new AutomationMsg_NavigationFailed(
              0, tab_handle_, commit->http_status_code, commit->entry->url()));

          ignore_next_load_notification_ = true;
        } else {
          // When the previous entry index is invalid, it will be -1, which
          // will still make the computation come out right (navigating to the
          // 0th entry will be +1).
          automation_->Send(new AutomationMsg_DidNavigate(
              0, tab_handle_, commit->type,
              commit->previous_entry_index -
                  tab_contents_->controller().last_committed_entry_index(),
              commit->entry->url()));
        }
        break;
      }
    case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR: {
      const ProvisionalLoadDetails* load_details =
          Details<ProvisionalLoadDetails>(details).ptr();
      automation_->Send(new AutomationMsg_NavigationFailed(
          0, tab_handle_, load_details->error_code(), load_details->url()));

      ignore_next_load_notification_ = true;
      break;
    }
    default:
      NOTREACHED();
  }
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, views::WidgetWin overrides:

void ExternalTabContainer::OnDestroy() {
  Uninitialize(GetNativeView());
  WidgetWin::OnDestroy();
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, views::KeystrokeListener implementation:

bool ExternalTabContainer::ProcessKeyStroke(HWND window, UINT message,
                                            WPARAM wparam, LPARAM lparam) {
  if (!automation_) {
    return false;
  }
  if ((wparam == VK_TAB) && !win_util::IsCtrlPressed()) {
    // Tabs are handled separately (except if this is Ctrl-Tab or
    // Ctrl-Shift-Tab)
    return false;
  }

  unsigned int flags = HIWORD(lparam);
  bool alt = (flags & KF_ALTDOWN) != 0;
  if (!alt && (message == WM_SYSKEYUP || message == WM_KEYUP)) {
    // In case the Alt key is being released.
    alt = (wparam == VK_MENU);
  }

  if ((flags & KF_EXTENDED) || alt || (wparam >= VK_F1 && wparam <= VK_F24) ||
      wparam == VK_ESCAPE || wparam == VK_RETURN ||
      win_util::IsShiftPressed() || win_util::IsCtrlPressed()) {
    // If this is an extended key or if one or more of Alt, Shift and Control
    // are pressed, this might be an accelerator that the external host wants
    // to handle. If the host does not handle this accelerator, it will reflect
    // the accelerator back to us via the ProcessUnhandledAccelerator method.
    MSG msg = {0};
    msg.hwnd = window;
    msg.message = message;
    msg.wParam = wparam;
    msg.lParam = lparam;
    automation_->Send(new AutomationMsg_HandleAccelerator(0, tab_handle_, msg));
    return true;
  }

  return false;
}

////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, private:

void ExternalTabContainer::Uninitialize(HWND window) {
  if (::IsWindow(window)) {
    views::FocusManager* focus_manager =
        views::FocusManager::GetFocusManager(window);
    if (focus_manager)
      focus_manager->RemoveKeystrokeListener(this);
  }

  if (tab_contents_) {
    NotificationService::current()->Notify(
        NotificationType::EXTERNAL_TAB_CLOSED,
        Source<NavigationController>(&tab_contents_->controller()),
        Details<ExternalTabContainer>(this));

    delete tab_contents_;
    tab_contents_ = NULL;
  }
}

<|endoftext|>


<commit_before>/*
Copyright (c) 2015-2021 Alternative Games Ltd / Turo Lamminen

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 <cstring>
#include <cassert>

#include <sys/stat.h>

#include <stdexcept>

#include "Utils.h"

#include <SDL.h>

struct FILEDeleter {
	void operator()(FILE *f) { fclose(f); }
};

static FILE *logFile;

void logInit() {
	assert(!logFile);

	char *logFilePath = SDL_GetPrefPath("", "SMAADemo");
	std::string logFileName(logFilePath);
	SDL_free(logFilePath);
	logFileName += "logfile.txt";
	logFile = fopen(logFileName.c_str(), "wb");
}

void logWrite(const char* message, ...) {
	va_list argp;
	va_start(argp, message);

	if (logFile) {
		vfprintf(logFile, message, argp);
	} else {
		// Write to console if opening log file failed
		vprintf(message, argp);
	}

	va_end(argp);
}

void logShutdown() {
	assert(logFile);

	fflush(logFile);
	fclose(logFile);
	logFile = nullptr;
}

void logFlush() {
	assert(logFile);

	fflush(logFile);
}

std::vector<char> readTextFile(std::string filename) {
	std::unique_ptr<FILE, FILEDeleter> file(fopen(filename.c_str(), "rb"));

	if (!file) {
		// TODO: better exception
		throw std::runtime_error("file not found " + filename);
	}

	int fd = fileno(file.get());
	if (fd < 0) {
		// TODO: better exception
		throw std::runtime_error("no fd");
	}

	struct stat statbuf;
	memset(&statbuf, 0, sizeof(struct stat));
	int retval = fstat(fd, &statbuf);
	if (retval < 0) {
		// TODO: better exception
		std::string msg = "fstat failed for \"" + filename + "\": " + strerror(errno);
		throw std::runtime_error(msg);
	}

	unsigned int filesize = static_cast<unsigned int>(statbuf.st_size);
	// ensure NUL -termination
	std::vector<char> buf(filesize + 1, '\0');

	size_t ret = fread(&buf[0], 1, filesize, file.get());
	if (ret != filesize)
	{
		// TODO: better exception
		throw std::runtime_error("fread failed");
	}

	return buf;
}

std::vector<char> readFile(std::string filename) {
	std::unique_ptr<FILE, FILEDeleter> file(fopen(filename.c_str(), "rb"));

	if (!file) {
		// TODO: better exception
		throw std::runtime_error("file not found " + filename);
	}

	int fd = fileno(file.get());
	if (fd < 0) {
		// TODO: better exception
		throw std::runtime_error("no fd");
	}

	struct stat statbuf;
	memset(&statbuf, 0, sizeof(struct stat));
	int retval = fstat(fd, &statbuf);
	if (retval < 0) {
		// TODO: better exception
		std::string msg = "fstat failed for \"" + filename + "\": " + strerror(errno);
		throw std::runtime_error(msg);
	}

	unsigned int filesize = static_cast<unsigned int>(statbuf.st_size);
	std::vector<char> buf(filesize, '\0');

	size_t ret = fread(&buf[0], 1, filesize, file.get());
	if (ret != filesize)
	{
		// TODO: better exception
		throw std::runtime_error("fread failed");
	}

	return buf;
}

void writeFile(const std::string &filename, const void *contents, size_t size) {
	std::unique_ptr<FILE, FILEDeleter> file(fopen(filename.c_str(), "wb"));

	fwrite(contents, 1, size, file.get());
}

bool fileExists(const std::string &filename) {
	std::unique_ptr<FILE, FILEDeleter> file(fopen(filename.c_str(), "rb"));

	if (file) {
		return true;
	} else {
		return false;
	}
}

int64_t getFileTimestamp(const std::string &filename) {
	struct stat statbuf;
	memset(&statbuf, 0, sizeof(struct stat));
	int retval = stat(filename.c_str(), &statbuf);
	if (retval < 0) {
		// TODO: better exception
		std::string msg = "fstat failed for \"" + filename + "\": " + strerror(errno);
		throw std::runtime_error(msg);
	}
	return statbuf.st_mtime;
}
<commit_msg>Alphabetize<commit_after>/*
Copyright (c) 2015-2021 Alternative Games Ltd / Turo Lamminen

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 <cassert>
#include <cstring>

#include <sys/stat.h>

#include <stdexcept>

#include "Utils.h"

#include <SDL.h>

struct FILEDeleter {
	void operator()(FILE *f) { fclose(f); }
};

static FILE *logFile;

void logInit() {
	assert(!logFile);

	char *logFilePath = SDL_GetPrefPath("", "SMAADemo");
	std::string logFileName(logFilePath);
	SDL_free(logFilePath);
	logFileName += "logfile.txt";
	logFile = fopen(logFileName.c_str(), "wb");
}

void logWrite(const char* message, ...) {
	va_list argp;
	va_start(argp, message);

	if (logFile) {
		vfprintf(logFile, message, argp);
	} else {
		// Write to console if opening log file failed
		vprintf(message, argp);
	}

	va_end(argp);
}

void logShutdown() {
	assert(logFile);

	fflush(logFile);
	fclose(logFile);
	logFile = nullptr;
}

void logFlush() {
	assert(logFile);

	fflush(logFile);
}

std::vector<char> readTextFile(std::string filename) {
	std::unique_ptr<FILE, FILEDeleter> file(fopen(filename.c_str(), "rb"));

	if (!file) {
		// TODO: better exception
		throw std::runtime_error("file not found " + filename);
	}

	int fd = fileno(file.get());
	if (fd < 0) {
		// TODO: better exception
		throw std::runtime_error("no fd");
	}

	struct stat statbuf;
	memset(&statbuf, 0, sizeof(struct stat));
	int retval = fstat(fd, &statbuf);
	if (retval < 0) {
		// TODO: better exception
		std::string msg = "fstat failed for \"" + filename + "\": " + strerror(errno);
		throw std::runtime_error(msg);
	}

	unsigned int filesize = static_cast<unsigned int>(statbuf.st_size);
	// ensure NUL -termination
	std::vector<char> buf(filesize + 1, '\0');

	size_t ret = fread(&buf[0], 1, filesize, file.get());
	if (ret != filesize)
	{
		// TODO: better exception
		throw std::runtime_error("fread failed");
	}

	return buf;
}

std::vector<char> readFile(std::string filename) {
	std::unique_ptr<FILE, FILEDeleter> file(fopen(filename.c_str(), "rb"));

	if (!file) {
		// TODO: better exception
		throw std::runtime_error("file not found " + filename);
	}

	int fd = fileno(file.get());
	if (fd < 0) {
		// TODO: better exception
		throw std::runtime_error("no fd");
	}

	struct stat statbuf;
	memset(&statbuf, 0, sizeof(struct stat));
	int retval = fstat(fd, &statbuf);
	if (retval < 0) {
		// TODO: better exception
		std::string msg = "fstat failed for \"" + filename + "\": " + strerror(errno);
		throw std::runtime_error(msg);
	}

	unsigned int filesize = static_cast<unsigned int>(statbuf.st_size);
	std::vector<char> buf(filesize, '\0');

	size_t ret = fread(&buf[0], 1, filesize, file.get());
	if (ret != filesize)
	{
		// TODO: better exception
		throw std::runtime_error("fread failed");
	}

	return buf;
}

void writeFile(const std::string &filename, const void *contents, size_t size) {
	std::unique_ptr<FILE, FILEDeleter> file(fopen(filename.c_str(), "wb"));

	fwrite(contents, 1, size, file.get());
}

bool fileExists(const std::string &filename) {
	std::unique_ptr<FILE, FILEDeleter> file(fopen(filename.c_str(), "rb"));

	if (file) {
		return true;
	} else {
		return false;
	}
}

int64_t getFileTimestamp(const std::string &filename) {
	struct stat statbuf;
	memset(&statbuf, 0, sizeof(struct stat));
	int retval = stat(filename.c_str(), &statbuf);
	if (retval < 0) {
		// TODO: better exception
		std::string msg = "fstat failed for \"" + filename + "\": " + strerror(errno);
		throw std::runtime_error(msg);
	}
	return statbuf.st_mtime;
}
<|endoftext|>


<commit_before>#include <stdexcept>

#include "ComponentRegistration.h"
#include "ComponentRegistry.h"
#include "ContainerActivator.h"
#include "CurrentLifetimeScope.h"
#include "DelegateActivator.h"
#include "IComponentRegistry.h"
#include "ILifetimeScope.h"
#include "LifetimeScope.h"
#include "ProvidedInstanceActivator.h"
#include "TypedService.h"
#include "Container.h"

namespace Hypodermic
{

    std::shared_ptr< IComponentRegistry > Container::componentRegistry()
    {
        return componentRegistry_;
    }

    std::shared_ptr< void > Container::resolveComponent(std::shared_ptr< IComponentRegistration > registration)
    {
        return rootLifetimeScope_->resolveComponent(registration);
    }

    std::shared_ptr< void > Container::getOrCreateInstance(std::shared_ptr< IComponentRegistration > registration)
    {
        return registration->activator()->activateInstance(shared_from_this());
    }

    void Container::initialize()
    {
        std::vector< std::shared_ptr< Service > > services;
        services.push_back(std::make_shared< TypedService >(typeid(ILifetimeScope)));
        services.push_back(std::make_shared< TypedService >(typeid(IComponentContext)));

        componentRegistry_ = std::make_shared< ComponentRegistry >();

        componentRegistry_->addRegistration(std::make_shared< ComponentRegistration >(
            LifetimeScope::selfRegistrationId,
            std::make_shared< DelegateActivator< LifetimeScope > >(
                typeid(LifetimeScope),
                [](IComponentContext&) -> LifetimeScope*
                {
                    throw std::logic_error("Self registration cannot be activated");
                }),
            std::make_shared< CurrentLifetimeScope >(),
            InstanceSharing::Shared,
            InstanceOwnership::ExternallyOwned,
            services,
            std::unordered_map< std::type_index, std::shared_ptr< ITypeCaster > >()));

        services.clear();
        services.push_back(std::make_shared< TypedService >(typeid(IContainer)));

        componentRegistry_->addRegistration(std::make_shared< ComponentRegistration >(
            LifetimeScope::selfRegistrationId,
            std::make_shared< ContainerActivator >(shared_from_this()),
            std::make_shared< CurrentLifetimeScope >(),
            InstanceSharing::None, // this instance will actually be shared, but this prevents shared pointer circular references
            InstanceOwnership::ExternallyOwned,
            services,
            std::unordered_map< std::type_index, std::shared_ptr< ITypeCaster > >()));

        rootLifetimeScope_ = std::make_shared< LifetimeScope >(componentRegistry_);
        rootLifetimeScope_->initialize();
    }

} // namespace Hypodermic
<commit_msg>Boost.Assign is prettier than push_backs<commit_after>#include <stdexcept>

#include <boost/assign.hpp>

#include "ComponentRegistration.h"
#include "ComponentRegistry.h"
#include "ContainerActivator.h"
#include "CurrentLifetimeScope.h"
#include "DelegateActivator.h"
#include "IComponentRegistry.h"
#include "ILifetimeScope.h"
#include "LifetimeScope.h"
#include "ProvidedInstanceActivator.h"
#include "TypedService.h"
#include "Container.h"

namespace Hypodermic
{

    std::shared_ptr< IComponentRegistry > Container::componentRegistry()
    {
        return componentRegistry_;
    }

    std::shared_ptr< void > Container::resolveComponent(std::shared_ptr< IComponentRegistration > registration)
    {
        return rootLifetimeScope_->resolveComponent(registration);
    }

    std::shared_ptr< void > Container::getOrCreateInstance(std::shared_ptr< IComponentRegistration > registration)
    {
        return registration->activator()->activateInstance(shared_from_this());
    }

    void Container::initialize()
    {
        using namespace boost::assign;

        std::vector< std::shared_ptr< Service > > services;
        services += std::make_shared< TypedService >(typeid(ILifetimeScope))
                  , std::make_shared< TypedService >(typeid(IComponentContext));

        componentRegistry_ = std::make_shared< ComponentRegistry >();

        componentRegistry_->addRegistration(std::make_shared< ComponentRegistration >(
            LifetimeScope::selfRegistrationId,
            std::make_shared< DelegateActivator< LifetimeScope > >(
                typeid(LifetimeScope),
                [](IComponentContext&) -> LifetimeScope*
                {
                    throw std::logic_error("Self registration cannot be activated");
                }),
            std::make_shared< CurrentLifetimeScope >(),
            InstanceSharing::Shared,
            InstanceOwnership::ExternallyOwned,
            services,
            std::unordered_map< std::type_index, std::shared_ptr< ITypeCaster > >()));

        services.clear();
        services += std::make_shared< TypedService >(typeid(IContainer));

        componentRegistry_->addRegistration(std::make_shared< ComponentRegistration >(
            LifetimeScope::selfRegistrationId,
            std::make_shared< ContainerActivator >(shared_from_this()),
            std::make_shared< CurrentLifetimeScope >(),
            InstanceSharing::None, // this instance will actually be shared, but this prevents shared pointer circular references
            InstanceOwnership::ExternallyOwned,
            services,
            std::unordered_map< std::type_index, std::shared_ptr< ITypeCaster > >()));

        rootLifetimeScope_ = std::make_shared< LifetimeScope >(componentRegistry_);
        rootLifetimeScope_->initialize();
    }

} // namespace Hypodermic
<|endoftext|>