<commit_before>#include <silicium/async_process.hpp>
#include <silicium/http/generate_response.hpp>
#include <silicium/http/receive_request.hpp>
#include <silicium/asio/tcp_acceptor.hpp>
#include <silicium/asio/writing_observable.hpp>
#include <silicium/sink/iterator_sink.hpp>
#include <silicium/absolute_path.hpp>
#include <silicium/asio/socket_source.hpp>
#include <silicium/html.hpp>
#include <iostream>
#include <array>
#include <boost/program_options.hpp>
#include <boost/asio/spawn.hpp>

namespace
{
	template <class YieldContext>
	void respond(boost::asio::ip::tcp::socket &client, Si::memory_range status, Si::memory_range status_text, Si::memory_range content, YieldContext yield)
	{
		boost::system::error_code error;
		auto const remote_endpoint = client.remote_endpoint(error);
		if (!!error)
		{
			std::cerr << "Client disconnected\n";
			return;
		}
		std::vector<char> response;
		auto const response_sink = Si::make_container_sink(response);
		Si::http::generate_status_line(response_sink, "HTTP/1.1", status, status_text);
		Si::http::generate_header(response_sink, "Content-Length", boost::lexical_cast<Si::noexcept_string>(content.size()));
		Si::http::generate_header(response_sink, "Content-Type", "text/html");
		Si::http::finish_headers(response_sink);
		Si::append(response_sink, content);
		boost::asio::async_write(client, boost::asio::buffer(response), yield[error]);
		if (!!error)
		{
			std::cerr << "Could not respond to " << remote_endpoint << ": " << error << '\n';
			return;
		}
		client.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
		if (!!error)
		{
			std::cerr << "Could not shutdown connection to " << remote_endpoint << ": " << error << '\n';
		}
	}

	SILICIUM_USE_RESULT
	bool handle_error(boost::system::error_code error, char const *message)
	{
		if (error)
		{
			std::cerr << message << ": " << error << '\n';
			return true;
		}
		return false;
	}

	enum class output_chunk_result
	{
		more,
		finished
	};

	SILICIUM_USE_RESULT
	output_chunk_result handle_output_chunk(Si::native_file_descriptor readable_output)
	{
		std::array<char, 8192> read_buffer;
		ssize_t const read_result = read(readable_output, read_buffer.data(), read_buffer.size());
		if (read_result < 0)
		{
			int errno_ = errno;
			boost::system::error_code error(errno_, boost::system::get_system_category());
			std::cerr << "Reading the output of the process failed with " << error << '\n';
			return output_chunk_result::finished;
		}
		if (read_result == 0)
		{
			//end of output
			return output_chunk_result::finished;
		}
		std::cerr.write(read_buffer.data(), read_result);
		return output_chunk_result::more;
	}

	enum class clone_result
	{
		success,
		failure
	};

	SILICIUM_USE_RESULT
	clone_result clone(
		std::string const &repository,
		Si::absolute_path const &repository_cache)
	{
		Si::async_process_parameters parameters;
		parameters.executable = *Si::absolute_path::create("/usr/bin/git");
		parameters.arguments.emplace_back("clone");
		parameters.arguments.emplace_back(repository.c_str());
		parameters.arguments.emplace_back(repository_cache.c_str());
		parameters.current_path = repository_cache;
		auto output = Si::make_pipe().get();
		auto input = Si::make_pipe().get();
		Si::error_or<Si::async_process> maybe_process = Si::launch_process(parameters, input.read.handle, output.write.handle, output.write.handle);
		if (handle_error(maybe_process.error(), "Could not create git process"))
		{
			return clone_result::failure;
		}
		input.read.close();
		output.write.close();
		Si::async_process &process = maybe_process.get();
		for (bool more = true; more;)
		{
			switch (handle_output_chunk(output.read.handle))
			{
			case output_chunk_result::more:
				break;

			case output_chunk_result::finished:
				more = false;
				break;
			}
		}
		int const result = process.wait_for_exit().get();
		if (result != 0)
		{
			std::cerr << "Git clone failed\n";
			return clone_result::failure;
		}

		return clone_result::success;
	}

	enum class build_trigger_result
	{
		success,
		failure
	};

	SILICIUM_USE_RESULT
	build_trigger_result trigger_build(
		std::string const &repository,
		Si::absolute_path const &repository_cache)
	{
		if (handle_error(Si::create_directories(repository_cache), "Could not create repository cache directory"))
		{
			return build_trigger_result::failure;
		}

		if (!Si::file_exists(repository_cache / Si::relative_path(".git")))
		{
			std::cerr << "The cache does not exist. Doing an initial clone of " << repository << "\n";
			switch (clone(repository, repository_cache))
			{
			case clone_result::success:
				std::cerr << "Created initial clone of the repository\n";
				break;

			case clone_result::failure:
				return build_trigger_result::failure;
			}
		}

		return build_trigger_result::success;
	}

	template <class YieldContext>
	void serve_web_client(
		boost::asio::ip::tcp::socket &client,
		std::string const &repository,
		Si::absolute_path const &repository_cache,
		YieldContext yield)
	{
		Si::asio::basic_socket_source<YieldContext> receiver(client, yield);
		Si::optional<Si::http::request> maybe_request;
		boost::system::error_code error;
		auto const remote_endpoint = client.remote_endpoint(error);
		if (!!error)
		{
			std::cerr << "Client disconnected\n";
			return;
		}

		//TODO: do this without an exception
		try
		{
			//TODO: virtualize_source should not be necessary here
			maybe_request = Si::http::parse_request(Si::virtualize_source(Si::ref_source(receiver)));
		}
		catch (boost::system::system_error const &ex)
		{
			std::cerr << "Error when receiving request from " << remote_endpoint << ": " << ex.code() << '\n';
			return;
		}

		if (!maybe_request)
		{
			return respond(client, Si::make_c_str_range("400"), Si::make_c_str_range("Bad Request"), Si::make_c_str_range("the server could not parse the request"), yield);
		}

		Si::http::request const &request = *maybe_request;
		if (request.method != "POST" && request.method != "GET")
		{
			return respond(client, Si::make_c_str_range("405"), Si::make_c_str_range("Method Not Allowed"), Si::make_c_str_range("this HTTP method is not supported by this server"), yield);
		}

		if (request.path != "/")
		{
			return respond(client, Si::make_c_str_range("404"), Si::make_c_str_range("Not Found"), Si::make_c_str_range("unknown path"), yield);
		}

		std::vector<char> page;
		auto html = Si::html::make_generator(Si::make_container_sink(page));
		html("html", [&]
		{
			html("head", [&]
			{
				html("title", [&]
				{
					html.write("Silicium build tester");
				});
			});
			html("body", [&]
			{
				if (request.method == "POST")
				{
					switch (trigger_build(repository, repository_cache))
					{
					case build_trigger_result::success:
						html.write("build success");
						break;

					case build_trigger_result::failure:
						html.write("build failure");
						break;
					}
				}
				html("form",
					[&]
				{
					html.attribute("action", "/");
					html.attribute("method", "POST");
				},
					[&]
				{
					html("input",
						[&]
					{
						html.attribute("type", "submit");
						html.attribute("value", "Trigger build");
					},
						[&]
					{
					});
				});
			});

		});
		return respond(client, Si::make_c_str_range("200"), Si::make_c_str_range("OK"), Si::make_memory_range(page), yield);
	}

	void handle_client(
		std::shared_ptr<boost::asio::ip::tcp::socket> client,
		std::string const &repository,
		Si::absolute_path const &repository_cache)
	{
		assert(client);
		auto on_exit = []()
		{
		};
		boost::asio::spawn(
			on_exit,
			[client = std::move(client), &repository, &repository_cache](boost::asio::basic_yield_context<decltype(on_exit) &> yield)
			{
				serve_web_client(*client, repository, repository_cache, yield);
			}
		);
	}

	std::shared_ptr<boost::asio::ip::tcp::socket> async_accept(boost::asio::ip::tcp::acceptor &acceptor, boost::asio::yield_context yield)
	{
		auto client = std::make_shared<boost::asio::ip::tcp::socket>(acceptor.get_io_service());
		acceptor.async_accept(*client, yield);
		return client;
	}
}

int main(int argc, char **argv)
{
	std::string repository;
	std::string cache;
	boost::uint16_t listen_port = 8080;

	boost::program_options::options_description options("options");
	options.add_options()
		("help,h", "produce help message")
		("repository,r", boost::program_options::value(&repository), "the Git URI to clone from")
		("cache,c", boost::program_options::value(&cache), "the directory to use as a cache for the repository")
		("port,p", boost::program_options::value(&listen_port), "the port to listen on for HTTP requests")
		;
	boost::program_options::positional_options_description positional;
	positional.add("repository", 1);
	positional.add("cache", 1);
	boost::program_options::variables_map variables;
	try
	{
		boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(options).positional(positional).run(), variables);
		boost::program_options::notify(variables);
	}
	catch (boost::program_options::error const &ex)
	{
		std::cerr << options << '\n';
		std::cerr << ex.what() << '\n';
		return 1;
	}

	if (variables.count("help"))
	{
		std::cerr << options << '\n';
		return 0;
	}

	if (repository.empty() || cache.empty())
	{
		std::cerr << options << '\n';
		std::cerr << "Missing option\n";
		return 1;
	}

	Si::absolute_path const absolute_cache = *Si::absolute_path::create(boost::filesystem::absolute(cache));

	boost::asio::io_service io;
	boost::asio::spawn(io, [&io, listen_port, &repository, &absolute_cache](boost::asio::yield_context yield)
	{
		boost::asio::ip::tcp::acceptor acceptor(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), listen_port));
		for (;;)
		{
			std::shared_ptr<boost::asio::ip::tcp::socket> client = async_accept(acceptor, yield);
			handle_client(std::move(client), repository, absolute_cache);
		}
	});
	io.run();
}
<commit_msg>avoid an unnecessary copy of the response content<commit_after>#include <silicium/async_process.hpp>
#include <silicium/http/generate_response.hpp>
#include <silicium/http/receive_request.hpp>
#include <silicium/asio/tcp_acceptor.hpp>
#include <silicium/asio/writing_observable.hpp>
#include <silicium/sink/iterator_sink.hpp>
#include <silicium/absolute_path.hpp>
#include <silicium/asio/socket_source.hpp>
#include <silicium/html.hpp>
#include <iostream>
#include <array>
#include <boost/program_options.hpp>
#include <boost/asio/spawn.hpp>

namespace
{
	template <class YieldContext>
	void respond(boost::asio::ip::tcp::socket &client, Si::memory_range status, Si::memory_range status_text, Si::memory_range content, YieldContext yield)
	{
		boost::system::error_code error;
		auto const remote_endpoint = client.remote_endpoint(error);
		if (!!error)
		{
			std::cerr << "Client disconnected\n";
			return;
		}

		std::vector<char> response;
		auto const response_sink = Si::make_container_sink(response);
		Si::http::generate_status_line(response_sink, "HTTP/1.1", status, status_text);
		Si::http::generate_header(response_sink, "Content-Length", boost::lexical_cast<Si::noexcept_string>(content.size()));
		Si::http::generate_header(response_sink, "Content-Type", "text/html");
		Si::http::finish_headers(response_sink);

		std::array<boost::asio::const_buffer, 2> const write_data =
		{{
			boost::asio::buffer(response),
			boost::asio::buffer(content.begin(), content.size())
		}};

		boost::asio::async_write(client, write_data, yield[error]);
		if (!!error)
		{
			std::cerr << "Could not respond to " << remote_endpoint << ": " << error << '\n';
			return;
		}
		client.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
		if (!!error)
		{
			std::cerr << "Could not shutdown connection to " << remote_endpoint << ": " << error << '\n';
		}
	}

	SILICIUM_USE_RESULT
	bool handle_error(boost::system::error_code error, char const *message)
	{
		if (error)
		{
			std::cerr << message << ": " << error << '\n';
			return true;
		}
		return false;
	}

	enum class output_chunk_result
	{
		more,
		finished
	};

	SILICIUM_USE_RESULT
	output_chunk_result handle_output_chunk(Si::native_file_descriptor readable_output)
	{
		std::array<char, 8192> read_buffer;
		ssize_t const read_result = read(readable_output, read_buffer.data(), read_buffer.size());
		if (read_result < 0)
		{
			int errno_ = errno;
			boost::system::error_code error(errno_, boost::system::get_system_category());
			std::cerr << "Reading the output of the process failed with " << error << '\n';
			return output_chunk_result::finished;
		}
		if (read_result == 0)
		{
			//end of output
			return output_chunk_result::finished;
		}
		std::cerr.write(read_buffer.data(), read_result);
		return output_chunk_result::more;
	}

	enum class clone_result
	{
		success,
		failure
	};

	SILICIUM_USE_RESULT
	clone_result clone(
		std::string const &repository,
		Si::absolute_path const &repository_cache)
	{
		Si::async_process_parameters parameters;
		parameters.executable = *Si::absolute_path::create("/usr/bin/git");
		parameters.arguments.emplace_back("clone");
		parameters.arguments.emplace_back(repository.c_str());
		parameters.arguments.emplace_back(repository_cache.c_str());
		parameters.current_path = repository_cache;
		auto output = Si::make_pipe().get();
		auto input = Si::make_pipe().get();
		Si::error_or<Si::async_process> maybe_process = Si::launch_process(parameters, input.read.handle, output.write.handle, output.write.handle);
		if (handle_error(maybe_process.error(), "Could not create git process"))
		{
			return clone_result::failure;
		}
		input.read.close();
		output.write.close();
		Si::async_process &process = maybe_process.get();
		for (bool more = true; more;)
		{
			switch (handle_output_chunk(output.read.handle))
			{
			case output_chunk_result::more:
				break;

			case output_chunk_result::finished:
				more = false;
				break;
			}
		}
		int const result = process.wait_for_exit().get();
		if (result != 0)
		{
			std::cerr << "Git clone failed\n";
			return clone_result::failure;
		}

		return clone_result::success;
	}

	enum class build_trigger_result
	{
		success,
		failure
	};

	SILICIUM_USE_RESULT
	build_trigger_result trigger_build(
		std::string const &repository,
		Si::absolute_path const &repository_cache)
	{
		if (handle_error(Si::create_directories(repository_cache), "Could not create repository cache directory"))
		{
			return build_trigger_result::failure;
		}

		if (!Si::file_exists(repository_cache / Si::relative_path(".git")))
		{
			std::cerr << "The cache does not exist. Doing an initial clone of " << repository << "\n";
			switch (clone(repository, repository_cache))
			{
			case clone_result::success:
				std::cerr << "Created initial clone of the repository\n";
				break;

			case clone_result::failure:
				return build_trigger_result::failure;
			}
		}

		return build_trigger_result::success;
	}

	template <class YieldContext>
	void serve_web_client(
		boost::asio::ip::tcp::socket &client,
		std::string const &repository,
		Si::absolute_path const &repository_cache,
		YieldContext yield)
	{
		Si::asio::basic_socket_source<YieldContext> receiver(client, yield);
		Si::optional<Si::http::request> maybe_request;
		boost::system::error_code error;
		auto const remote_endpoint = client.remote_endpoint(error);
		if (!!error)
		{
			std::cerr << "Client disconnected\n";
			return;
		}

		//TODO: do this without an exception
		try
		{
			//TODO: virtualize_source should not be necessary here
			maybe_request = Si::http::parse_request(Si::virtualize_source(Si::ref_source(receiver)));
		}
		catch (boost::system::system_error const &ex)
		{
			std::cerr << "Error when receiving request from " << remote_endpoint << ": " << ex.code() << '\n';
			return;
		}

		if (!maybe_request)
		{
			return respond(client, Si::make_c_str_range("400"), Si::make_c_str_range("Bad Request"), Si::make_c_str_range("the server could not parse the request"), yield);
		}

		Si::http::request const &request = *maybe_request;
		if (request.method != "POST" && request.method != "GET")
		{
			return respond(client, Si::make_c_str_range("405"), Si::make_c_str_range("Method Not Allowed"), Si::make_c_str_range("this HTTP method is not supported by this server"), yield);
		}

		if (request.path != "/")
		{
			return respond(client, Si::make_c_str_range("404"), Si::make_c_str_range("Not Found"), Si::make_c_str_range("unknown path"), yield);
		}

		std::vector<char> page;
		auto html = Si::html::make_generator(Si::make_container_sink(page));
		html("html", [&]
		{
			html("head", [&]
			{
				html("title", [&]
				{
					html.write("Silicium build tester");
				});
			});
			html("body", [&]
			{
				if (request.method == "POST")
				{
					switch (trigger_build(repository, repository_cache))
					{
					case build_trigger_result::success:
						html.write("build success");
						break;

					case build_trigger_result::failure:
						html.write("build failure");
						break;
					}
				}
				html("form",
					[&]
				{
					html.attribute("action", "/");
					html.attribute("method", "POST");
				},
					[&]
				{
					html("input",
						[&]
					{
						html.attribute("type", "submit");
						html.attribute("value", "Trigger build");
					},
						[&]
					{
					});
				});
			});

		});
		return respond(client, Si::make_c_str_range("200"), Si::make_c_str_range("OK"), Si::make_memory_range(page), yield);
	}

	void handle_client(
		std::shared_ptr<boost::asio::ip::tcp::socket> client,
		std::string const &repository,
		Si::absolute_path const &repository_cache)
	{
		assert(client);
		auto on_exit = []()
		{
		};
		boost::asio::spawn(
			on_exit,
			[client = std::move(client), &repository, &repository_cache](boost::asio::basic_yield_context<decltype(on_exit) &> yield)
			{
				serve_web_client(*client, repository, repository_cache, yield);
			}
		);
	}

	std::shared_ptr<boost::asio::ip::tcp::socket> async_accept(boost::asio::ip::tcp::acceptor &acceptor, boost::asio::yield_context yield)
	{
		auto client = std::make_shared<boost::asio::ip::tcp::socket>(acceptor.get_io_service());
		acceptor.async_accept(*client, yield);
		return client;
	}
}

int main(int argc, char **argv)
{
	std::string repository;
	std::string cache;
	boost::uint16_t listen_port = 8080;

	boost::program_options::options_description options("options");
	options.add_options()
		("help,h", "produce help message")
		("repository,r", boost::program_options::value(&repository), "the Git URI to clone from")
		("cache,c", boost::program_options::value(&cache), "the directory to use as a cache for the repository")
		("port,p", boost::program_options::value(&listen_port), "the port to listen on for HTTP requests")
		;
	boost::program_options::positional_options_description positional;
	positional.add("repository", 1);
	positional.add("cache", 1);
	boost::program_options::variables_map variables;
	try
	{
		boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(options).positional(positional).run(), variables);
		boost::program_options::notify(variables);
	}
	catch (boost::program_options::error const &ex)
	{
		std::cerr << options << '\n';
		std::cerr << ex.what() << '\n';
		return 1;
	}

	if (variables.count("help"))
	{
		std::cerr << options << '\n';
		return 0;
	}

	if (repository.empty() || cache.empty())
	{
		std::cerr << options << '\n';
		std::cerr << "Missing option\n";
		return 1;
	}

	Si::absolute_path const absolute_cache = *Si::absolute_path::create(boost::filesystem::absolute(cache));

	boost::asio::io_service io;
	boost::asio::spawn(io, [&io, listen_port, &repository, &absolute_cache](boost::asio::yield_context yield)
	{
		boost::asio::ip::tcp::acceptor acceptor(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), listen_port));
		for (;;)
		{
			std::shared_ptr<boost::asio::ip::tcp::socket> client = async_accept(acceptor, yield);
			handle_client(std::move(client), repository, absolute_cache);
		}
	});
	io.run();
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    QVTKWidget2.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

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

#ifdef _MSC_VER
// Disable warnings that Qt headers give.
#pragma warning(disable:4127)
#pragma warning(disable:4512)
#endif

#include "QVTKWidget2.h"
#include "vtkEventQtSlotConnect.h"

#include <QMouseEvent>
#include <QResizeEvent>
#include <QApplication>

#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkGenericOpenGLRenderWindow.h"
#include "QVTKInteractorAdapter.h"
#include "QVTKInteractor.h"

#if defined(VTK_USE_TDX) && defined(Q_WS_X11)
# include "vtkTDxUnixDevice.h"
#endif

QVTKWidget2::QVTKWidget2(QWidget* p, const QGLWidget* shareWidget, Qt::WindowFlags f)
  : QGLWidget(p, shareWidget, f), mRenWin(NULL)
{
  this->UseTDx=false;
  mIrenAdapter = new QVTKInteractorAdapter(this);
  mConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
  this->setMouseTracking(true);
  this->setAutoBufferSwap(false);
}

QVTKWidget2::QVTKWidget2(QGLContext* ctx, QWidget* p, const QGLWidget* shareWidget, Qt::WindowFlags f)
  : QGLWidget(ctx, p, shareWidget, f), mRenWin(NULL)
{
  this->UseTDx=false;
  mIrenAdapter = new QVTKInteractorAdapter(this);
  mConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
  this->setMouseTracking(true);
  this->setAutoBufferSwap(false);
}

QVTKWidget2::QVTKWidget2(const QGLFormat& fmt, QWidget* p, const QGLWidget* shareWidget, Qt::WindowFlags f)
  : QGLWidget(fmt, p, shareWidget, f), mRenWin(NULL)
{
  this->UseTDx=false;
  mIrenAdapter = new QVTKInteractorAdapter(this);
  mConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
  this->setMouseTracking(true);
  this->setAutoBufferSwap(false);
}

/*! destructor */

QVTKWidget2::~QVTKWidget2()
{
  // get rid of the VTK window
  this->SetRenderWindow(NULL);
}

// ----------------------------------------------------------------------------
void QVTKWidget2::SetUseTDx(bool useTDx)
{
  if(useTDx!=this->UseTDx)
    {
    this->UseTDx=useTDx;
    if(this->UseTDx)
      {
#if defined(VTK_USE_TDX) && defined(Q_WS_X11)
       QByteArray theSignal=
         QMetaObject::normalizedSignature("CreateDevice(vtkTDxDevice *)");
      if(QApplication::instance()->metaObject()->indexOfSignal(theSignal)!=-1)
        {
        QObject::connect(QApplication::instance(),
                         SIGNAL(CreateDevice(vtkTDxDevice *)),
                         this,
                         SLOT(setDevice(vtkTDxDevice *)));
        }
      else
        {
        vtkGenericWarningMacro("Missing signal CreateDevice on QApplication. 3DConnexion device will not work. Define it or derive your QApplication from QVTKApplication.");
        }
#endif
      }
    }
}

// ----------------------------------------------------------------------------
bool QVTKWidget2::GetUseTDx() const
{
  return this->UseTDx;
}

/*! get the render window
 */
vtkGenericOpenGLRenderWindow* QVTKWidget2::GetRenderWindow()
{
  if (!this->mRenWin)
    {
    // create a default vtk window
    vtkGenericOpenGLRenderWindow* win = vtkGenericOpenGLRenderWindow::New();
    this->SetRenderWindow(win);
    win->Delete();
    }

  return this->mRenWin;
}

/*! set the render window
  this will bind a VTK window with the Qt window
  it'll also replace an existing VTK window
*/
void QVTKWidget2::SetRenderWindow(vtkGenericOpenGLRenderWindow* w)
{
  // do nothing if we don't have to
  if(w == this->mRenWin)
    {
    return;
    }

  // unregister previous window
  if(this->mRenWin)
    {
    this->mRenWin->Finalize();
    this->mRenWin->SetMapped(0);
    mConnect->Disconnect(mRenWin, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent()));
    mConnect->Disconnect(mRenWin, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*)));
    mConnect->Disconnect(mRenWin, vtkCommand::WindowFrameEvent, this, SLOT(Frame()));
    mConnect->Disconnect(mRenWin, vtkCommand::StartEvent, this, SLOT(Start()));
    mConnect->Disconnect(mRenWin, vtkCommand::EndEvent, this, SLOT(End()));
    mConnect->Disconnect(mRenWin, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*)));
    mConnect->Disconnect(mRenWin, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*)));
    }

  // now set the window
  this->mRenWin = w;

  if(this->mRenWin)
    {
    this->SetMultiSamples(this->mRenWin->GetGlobalMaximumNumberOfMultiSamples());
    // if it is mapped somewhere else, unmap it
    this->mRenWin->Finalize();
    this->mRenWin->SetMapped(1);

    // tell the vtk window what the size of this window is
    this->mRenWin->SetSize(this->width(), this->height());
    this->mRenWin->SetPosition(this->x(), this->y());

    // if an interactor wasn't provided, we'll make one by default
    if(!this->mRenWin->GetInteractor())
      {
      // create a default interactor
      QVTKInteractor* iren = QVTKInteractor::New();
      iren->SetUseTDx(this->UseTDx);
      this->mRenWin->SetInteractor(iren);
      iren->Initialize();

      // now set the default style
      vtkInteractorStyle* s = vtkInteractorStyleTrackballCamera::New();
      iren->SetInteractorStyle(s);

      iren->Delete();
      s->Delete();
      }

    // tell the interactor the size of this window
    this->mRenWin->GetInteractor()->SetSize(this->width(), this->height());

    mConnect->Connect(mRenWin, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent()));
    mConnect->Connect(mRenWin, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*)));
    mConnect->Connect(mRenWin, vtkCommand::WindowFrameEvent, this, SLOT(Frame()));
    mConnect->Connect(mRenWin, vtkCommand::StartEvent, this, SLOT(Start()));
    mConnect->Connect(mRenWin, vtkCommand::EndEvent, this, SLOT(End()));
    mConnect->Connect(mRenWin, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*)));
    mConnect->Connect(mRenWin, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*)));
    }
}

/*! get the Qt/VTK interactor
 */
QVTKInteractor* QVTKWidget2::GetInteractor()
{
  return QVTKInteractor
    ::SafeDownCast(this->GetRenderWindow()->GetInteractor());
}

void QVTKWidget2::Start()
{
  makeCurrent();
  mRenWin->PushState();
  mRenWin->OpenGLInitState();
}

void QVTKWidget2::End()
{
  mRenWin->PopState();
}

void QVTKWidget2::initializeGL()
{
  if(!this->mRenWin)
    {
    return;
    }
  this->mRenWin->OpenGLInitContext();
}

/*! handle resize event
 */
void QVTKWidget2::resizeGL(int w, int h)
{
  if(!this->mRenWin)
    {
    return;
    }

  this->mRenWin->SetSize(w,h);

  // and update the interactor
  if(this->mRenWin->GetInteractor())
    {
    QResizeEvent e(QSize(w,h), QSize());
    mIrenAdapter->ProcessEvent(&e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::moveEvent(QMoveEvent* e)
{
  QWidget::moveEvent(e);

  if(!this->mRenWin)
    {
    return;
    }

  this->mRenWin->SetPosition(this->x(), this->y());
}

/*! handle paint event
 */
void QVTKWidget2::paintGL()
{
  vtkRenderWindowInteractor* iren = NULL;
  if(this->mRenWin)
    {
    iren = this->mRenWin->GetInteractor();
    }

  if(!iren || !iren->GetEnabled())
    {
    return;
    }

  iren->Render();
}

/*! handle touch events
 */
bool QVTKWidget2::event(QEvent* e)
{
  if(e->type() == QEvent::TouchBegin ||
          e->type() == QEvent::TouchUpdate ||
          e->type() == QEvent::TouchEnd)
    {
    if(this->mRenWin)
      {
      mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
      if (e->isAccepted())
        {
        return true;
        }
      }
    }
  return QObject::event(e);
}

/*! handle mouse press event
 */
void QVTKWidget2::mousePressEvent(QMouseEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }

}

/*! handle mouse move event
 */
void QVTKWidget2::mouseMoveEvent(QMouseEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle enter event
 */
void QVTKWidget2::enterEvent(QEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle leave event
 */
void QVTKWidget2::leaveEvent(QEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle mouse release event
 */
void QVTKWidget2::mouseReleaseEvent(QMouseEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle key press event
 */
void QVTKWidget2::keyPressEvent(QKeyEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle key release event
 */
void QVTKWidget2::keyReleaseEvent(QKeyEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::wheelEvent(QWheelEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::contextMenuEvent(QContextMenuEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::dragEnterEvent(QDragEnterEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::dragMoveEvent(QDragMoveEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::dragLeaveEvent(QDragLeaveEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::dropEvent(QDropEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

bool QVTKWidget2::focusNextPrevChild(bool)
{
  return false;
}

#ifdef VTK_USE_TDX
// Description:
// Receive notification of the creation of the TDxDevice
void QVTKWidget2::setDevice(vtkTDxDevice *device)
{
#ifdef Q_WS_X11
  if(this->GetInteractor()->GetDevice()!=device)
    {
    this->GetInteractor()->SetDevice(device);
    }
#else
  (void)device; // to avoid warnings.
#endif
}
#endif

void QVTKWidget2::MakeCurrent()
{
  this->makeCurrent();
}

void QVTKWidget2::IsCurrent(vtkObject*, unsigned long, void*, void* call_data)
{
  bool* ptr = reinterpret_cast<bool*>(call_data);
  *ptr = QGLContext::currentContext() == this->context();
}

void QVTKWidget2::IsDirect(vtkObject*, unsigned long, void*, void* call_data)
{
  int* ptr = reinterpret_cast<int*>(call_data);
  *ptr = this->context()->format().directRendering();
}

void QVTKWidget2::SupportsOpenGL(vtkObject*, unsigned long, void*, void* call_data)
{
  int* ptr = reinterpret_cast<int*>(call_data);
  *ptr = QGLFormat::hasOpenGL();
}

void QVTKWidget2::Frame()
{
  if(mRenWin->GetSwapBuffers())
    this->swapBuffers();

  // This callback will call swapBuffers() for us
  // because sometimes VTK does a render without coming through this paintGL()

  // if you want paintGL to always be called for each time VTK renders
  // 1. turn off EnableRender on the interactor,
  // 2. turn off SwapBuffers on the render window,
  // 3. add an observer for the RenderEvent coming from the interactor
  // 4. implement the callback on the observer to call updateGL() on this widget
  // 5. overload QVTKWidget2::paintGL() to call mRenWin->Render() instead iren->Render()

}

void QVTKWidget2::SetMultiSamples(int multiSamples)
{
  QGLFormat newform = this->format();
  newform.setSamples(multiSamples);
  this->setFormat(newform);
  if(this->mRenWin)
    {
    this->mRenWin->SetMultiSamples(multiSamples);
    }
}

int QVTKWidget2::GetMultiSamples() const
{
  return this->format().samples();
}

void QVTKWidget2::setAutoBufferSwap(bool f)
{
  QGLWidget::setAutoBufferSwap(f);
}

bool QVTKWidget2::autoBufferSwap() const
{
  return QGLWidget::autoBufferSwap();
}
<commit_msg>QVTKWidget2: call the direct parent class<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    QVTKWidget2.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

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

#ifdef _MSC_VER
// Disable warnings that Qt headers give.
#pragma warning(disable:4127)
#pragma warning(disable:4512)
#endif

#include "QVTKWidget2.h"
#include "vtkEventQtSlotConnect.h"

#include <QMouseEvent>
#include <QResizeEvent>
#include <QApplication>

#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkGenericOpenGLRenderWindow.h"
#include "QVTKInteractorAdapter.h"
#include "QVTKInteractor.h"

#if defined(VTK_USE_TDX) && defined(Q_WS_X11)
# include "vtkTDxUnixDevice.h"
#endif

QVTKWidget2::QVTKWidget2(QWidget* p, const QGLWidget* shareWidget, Qt::WindowFlags f)
  : QGLWidget(p, shareWidget, f), mRenWin(NULL)
{
  this->UseTDx=false;
  mIrenAdapter = new QVTKInteractorAdapter(this);
  mConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
  this->setMouseTracking(true);
  this->setAutoBufferSwap(false);
}

QVTKWidget2::QVTKWidget2(QGLContext* ctx, QWidget* p, const QGLWidget* shareWidget, Qt::WindowFlags f)
  : QGLWidget(ctx, p, shareWidget, f), mRenWin(NULL)
{
  this->UseTDx=false;
  mIrenAdapter = new QVTKInteractorAdapter(this);
  mConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
  this->setMouseTracking(true);
  this->setAutoBufferSwap(false);
}

QVTKWidget2::QVTKWidget2(const QGLFormat& fmt, QWidget* p, const QGLWidget* shareWidget, Qt::WindowFlags f)
  : QGLWidget(fmt, p, shareWidget, f), mRenWin(NULL)
{
  this->UseTDx=false;
  mIrenAdapter = new QVTKInteractorAdapter(this);
  mConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
  this->setMouseTracking(true);
  this->setAutoBufferSwap(false);
}

/*! destructor */

QVTKWidget2::~QVTKWidget2()
{
  // get rid of the VTK window
  this->SetRenderWindow(NULL);
}

// ----------------------------------------------------------------------------
void QVTKWidget2::SetUseTDx(bool useTDx)
{
  if(useTDx!=this->UseTDx)
    {
    this->UseTDx=useTDx;
    if(this->UseTDx)
      {
#if defined(VTK_USE_TDX) && defined(Q_WS_X11)
       QByteArray theSignal=
         QMetaObject::normalizedSignature("CreateDevice(vtkTDxDevice *)");
      if(QApplication::instance()->metaObject()->indexOfSignal(theSignal)!=-1)
        {
        QObject::connect(QApplication::instance(),
                         SIGNAL(CreateDevice(vtkTDxDevice *)),
                         this,
                         SLOT(setDevice(vtkTDxDevice *)));
        }
      else
        {
        vtkGenericWarningMacro("Missing signal CreateDevice on QApplication. 3DConnexion device will not work. Define it or derive your QApplication from QVTKApplication.");
        }
#endif
      }
    }
}

// ----------------------------------------------------------------------------
bool QVTKWidget2::GetUseTDx() const
{
  return this->UseTDx;
}

/*! get the render window
 */
vtkGenericOpenGLRenderWindow* QVTKWidget2::GetRenderWindow()
{
  if (!this->mRenWin)
    {
    // create a default vtk window
    vtkGenericOpenGLRenderWindow* win = vtkGenericOpenGLRenderWindow::New();
    this->SetRenderWindow(win);
    win->Delete();
    }

  return this->mRenWin;
}

/*! set the render window
  this will bind a VTK window with the Qt window
  it'll also replace an existing VTK window
*/
void QVTKWidget2::SetRenderWindow(vtkGenericOpenGLRenderWindow* w)
{
  // do nothing if we don't have to
  if(w == this->mRenWin)
    {
    return;
    }

  // unregister previous window
  if(this->mRenWin)
    {
    this->mRenWin->Finalize();
    this->mRenWin->SetMapped(0);
    mConnect->Disconnect(mRenWin, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent()));
    mConnect->Disconnect(mRenWin, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*)));
    mConnect->Disconnect(mRenWin, vtkCommand::WindowFrameEvent, this, SLOT(Frame()));
    mConnect->Disconnect(mRenWin, vtkCommand::StartEvent, this, SLOT(Start()));
    mConnect->Disconnect(mRenWin, vtkCommand::EndEvent, this, SLOT(End()));
    mConnect->Disconnect(mRenWin, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*)));
    mConnect->Disconnect(mRenWin, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*)));
    }

  // now set the window
  this->mRenWin = w;

  if(this->mRenWin)
    {
    this->SetMultiSamples(this->mRenWin->GetGlobalMaximumNumberOfMultiSamples());
    // if it is mapped somewhere else, unmap it
    this->mRenWin->Finalize();
    this->mRenWin->SetMapped(1);

    // tell the vtk window what the size of this window is
    this->mRenWin->SetSize(this->width(), this->height());
    this->mRenWin->SetPosition(this->x(), this->y());

    // if an interactor wasn't provided, we'll make one by default
    if(!this->mRenWin->GetInteractor())
      {
      // create a default interactor
      QVTKInteractor* iren = QVTKInteractor::New();
      iren->SetUseTDx(this->UseTDx);
      this->mRenWin->SetInteractor(iren);
      iren->Initialize();

      // now set the default style
      vtkInteractorStyle* s = vtkInteractorStyleTrackballCamera::New();
      iren->SetInteractorStyle(s);

      iren->Delete();
      s->Delete();
      }

    // tell the interactor the size of this window
    this->mRenWin->GetInteractor()->SetSize(this->width(), this->height());

    mConnect->Connect(mRenWin, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent()));
    mConnect->Connect(mRenWin, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*)));
    mConnect->Connect(mRenWin, vtkCommand::WindowFrameEvent, this, SLOT(Frame()));
    mConnect->Connect(mRenWin, vtkCommand::StartEvent, this, SLOT(Start()));
    mConnect->Connect(mRenWin, vtkCommand::EndEvent, this, SLOT(End()));
    mConnect->Connect(mRenWin, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*)));
    mConnect->Connect(mRenWin, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*)));
    }
}

/*! get the Qt/VTK interactor
 */
QVTKInteractor* QVTKWidget2::GetInteractor()
{
  return QVTKInteractor
    ::SafeDownCast(this->GetRenderWindow()->GetInteractor());
}

void QVTKWidget2::Start()
{
  makeCurrent();
  mRenWin->PushState();
  mRenWin->OpenGLInitState();
}

void QVTKWidget2::End()
{
  mRenWin->PopState();
}

void QVTKWidget2::initializeGL()
{
  if(!this->mRenWin)
    {
    return;
    }
  this->mRenWin->OpenGLInitContext();
}

/*! handle resize event
 */
void QVTKWidget2::resizeGL(int w, int h)
{
  if(!this->mRenWin)
    {
    return;
    }

  this->mRenWin->SetSize(w,h);

  // and update the interactor
  if(this->mRenWin->GetInteractor())
    {
    QResizeEvent e(QSize(w,h), QSize());
    mIrenAdapter->ProcessEvent(&e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::moveEvent(QMoveEvent* e)
{
  QWidget::moveEvent(e);

  if(!this->mRenWin)
    {
    return;
    }

  this->mRenWin->SetPosition(this->x(), this->y());
}

/*! handle paint event
 */
void QVTKWidget2::paintGL()
{
  vtkRenderWindowInteractor* iren = NULL;
  if(this->mRenWin)
    {
    iren = this->mRenWin->GetInteractor();
    }

  if(!iren || !iren->GetEnabled())
    {
    return;
    }

  iren->Render();
}

/*! handle touch events
 */
bool QVTKWidget2::event(QEvent* e)
{
  if(e->type() == QEvent::TouchBegin ||
          e->type() == QEvent::TouchUpdate ||
          e->type() == QEvent::TouchEnd)
    {
    if(this->mRenWin)
      {
      mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
      if (e->isAccepted())
        {
        return true;
        }
      }
    }
  return QGLWidget::event(e);
}

/*! handle mouse press event
 */
void QVTKWidget2::mousePressEvent(QMouseEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }

}

/*! handle mouse move event
 */
void QVTKWidget2::mouseMoveEvent(QMouseEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle enter event
 */
void QVTKWidget2::enterEvent(QEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle leave event
 */
void QVTKWidget2::leaveEvent(QEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle mouse release event
 */
void QVTKWidget2::mouseReleaseEvent(QMouseEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle key press event
 */
void QVTKWidget2::keyPressEvent(QKeyEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

/*! handle key release event
 */
void QVTKWidget2::keyReleaseEvent(QKeyEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::wheelEvent(QWheelEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::contextMenuEvent(QContextMenuEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::dragEnterEvent(QDragEnterEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::dragMoveEvent(QDragMoveEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::dragLeaveEvent(QDragLeaveEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

void QVTKWidget2::dropEvent(QDropEvent* e)
{
  if(this->mRenWin)
    {
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
    }
}

bool QVTKWidget2::focusNextPrevChild(bool)
{
  return false;
}

#ifdef VTK_USE_TDX
// Description:
// Receive notification of the creation of the TDxDevice
void QVTKWidget2::setDevice(vtkTDxDevice *device)
{
#ifdef Q_WS_X11
  if(this->GetInteractor()->GetDevice()!=device)
    {
    this->GetInteractor()->SetDevice(device);
    }
#else
  (void)device; // to avoid warnings.
#endif
}
#endif

void QVTKWidget2::MakeCurrent()
{
  this->makeCurrent();
}

void QVTKWidget2::IsCurrent(vtkObject*, unsigned long, void*, void* call_data)
{
  bool* ptr = reinterpret_cast<bool*>(call_data);
  *ptr = QGLContext::currentContext() == this->context();
}

void QVTKWidget2::IsDirect(vtkObject*, unsigned long, void*, void* call_data)
{
  int* ptr = reinterpret_cast<int*>(call_data);
  *ptr = this->context()->format().directRendering();
}

void QVTKWidget2::SupportsOpenGL(vtkObject*, unsigned long, void*, void* call_data)
{
  int* ptr = reinterpret_cast<int*>(call_data);
  *ptr = QGLFormat::hasOpenGL();
}

void QVTKWidget2::Frame()
{
  if(mRenWin->GetSwapBuffers())
    this->swapBuffers();

  // This callback will call swapBuffers() for us
  // because sometimes VTK does a render without coming through this paintGL()

  // if you want paintGL to always be called for each time VTK renders
  // 1. turn off EnableRender on the interactor,
  // 2. turn off SwapBuffers on the render window,
  // 3. add an observer for the RenderEvent coming from the interactor
  // 4. implement the callback on the observer to call updateGL() on this widget
  // 5. overload QVTKWidget2::paintGL() to call mRenWin->Render() instead iren->Render()

}

void QVTKWidget2::SetMultiSamples(int multiSamples)
{
  QGLFormat newform = this->format();
  newform.setSamples(multiSamples);
  this->setFormat(newform);
  if(this->mRenWin)
    {
    this->mRenWin->SetMultiSamples(multiSamples);
    }
}

int QVTKWidget2::GetMultiSamples() const
{
  return this->format().samples();
}

void QVTKWidget2::setAutoBufferSwap(bool f)
{
  QGLWidget::setAutoBufferSwap(f);
}

bool QVTKWidget2::autoBufferSwap() const
{
  return QGLWidget::autoBufferSwap();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */
#include <sstream>
#include <map>
#include "halDefs.h"
#include "hal.h"

using namespace std;
using namespace hal;

const hal_index_t hal::NULL_INDEX = static_cast<hal_index_t>(-1);

/** C++ version of strtok */
vector<string> hal::chopString(const string& inString,
                               const string& separator)
{
  vector<string> outVector;
  string::size_type start = 0;
  string::size_type end = 0;

  while ((end = inString.find(separator, start)) != string::npos)
  {
    // todo: filter out empty strings
    outVector.push_back (inString.substr (start, end-start));
    start = end + separator.size();
  }
  if (start < inString.length())
  {
    outVector.push_back(inString.substr(start, string::npos));
  }
  return outVector;
}

void hal::reverseComplement(std::string& s)
{
  if (!s.empty())
  {
    size_t j = s.length() - 1;
    size_t i = 0;
    char buf;
    do
    {
      while (j > 0 && s[j] == '-')
      {
        --j;
      }
      while (i < s.length() - 1 && s[i] == '-')
      {
        ++i;
      }

      if (i >= j || s[i] == '-' || s[j] == '-')
      {
        if (i == j && s[i] != '-')
        {
          s[i] = reverseComplement(s[i]);
        }
        break;
      }

      buf = reverseComplement(s[i]);
      s[i] = reverseComplement(s[j]);
      s[j] = buf;

      ++i;
      --j;
    } while (true);
  }
}

static size_t lcaRecursive(const Genome* genome,
                           const set<const Genome*>& inputSet,
                           map<const Genome*, size_t>& table)
{
  size_t score = 0;
  if (inputSet.find(genome) != inputSet.end())
  {
    score = 1;
  }
  for (hal_size_t i = 0; i < genome->getNumChildren(); ++i)
  {
    score += lcaRecursive(genome->getChild(i), inputSet, table);
  }
  table.insert(pair<const Genome*, size_t>(genome, score));
  return score;
}

const Genome* hal::getLowestCommonAncestor(const set<const Genome*>& inputSet)
{
  if (inputSet.empty())
     return NULL;
  // dumb algorithm but it's friday and i'm too tired to think
  const Genome* root = *inputSet.begin();
  while (root->getParent() != NULL)
  {
     root = root->getParent();
  }
  map<const Genome*, size_t> table;
  lcaRecursive(root, inputSet, table);
  const Genome* lca = root;
  bool found = false;
  while (!found)
  {
    found = true;
    hal_size_t score = table.find(lca)->second;
    for (hal_size_t i = 0; found && i < lca->getNumChildren(); ++i)
    {
      if (table.find(lca->getChild(i))->second == score)
      {
        lca = lca->getChild(i);
        found = false;
      }
    }
  }
  return lca;
}

static bool spanningRecursive(const Genome* genome, set<const Genome*>& outputSet,
                              bool below = false)
{
  bool above = false;
  if (outputSet.find(genome) != outputSet.end())
  {
    below = true;
    above = true;
  }
  hal_size_t numChildren = genome->getNumChildren();
  for (hal_size_t i = 0; i < numChildren; ++i)
  {
    bool childAbove = spanningRecursive(genome->getChild(i), outputSet, below);
    above = above || childAbove;
  }

  if (above && below)
  {
    outputSet.insert(genome);
  }
  return above;
}

void hal::getGenomesInSpanningTree(const set<const Genome*>& inputSet,
                              set<const Genome*>& outputSet)
{
  const Genome* lca = getLowestCommonAncestor(inputSet);
  if (lca== NULL)
     return;
  outputSet = inputSet;
  outputSet.insert(lca);
  spanningRecursive(lca, outputSet);
}

void hal::getGenomesInSubTree(const Genome* root,
                              set<const Genome*>& outputSet)
{
  outputSet.insert(root);
  hal_size_t numChildren = root->getNumChildren();
  for (hal_size_t i = 0; i < numChildren; ++i)
  {
    getGenomesInSubTree(root->getChild(i), outputSet);
  }
}
<commit_msg>change spanning tree code in halcommon to use names instead of genome pointers when possible to avoid opening genomes that arent retunred<commit_after>/*
 * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */
#include <sstream>
#include <map>
#include "halDefs.h"
#include "hal.h"

using namespace std;
using namespace hal;

const hal_index_t hal::NULL_INDEX = static_cast<hal_index_t>(-1);

/** C++ version of strtok */
vector<string> hal::chopString(const string& inString,
                               const string& separator)
{
  vector<string> outVector;
  string::size_type start = 0;
  string::size_type end = 0;

  while ((end = inString.find(separator, start)) != string::npos)
  {
    // todo: filter out empty strings
    outVector.push_back (inString.substr (start, end-start));
    start = end + separator.size();
  }
  if (start < inString.length())
  {
    outVector.push_back(inString.substr(start, string::npos));
  }
  return outVector;
}

void hal::reverseComplement(std::string& s)
{
  if (!s.empty())
  {
    size_t j = s.length() - 1;
    size_t i = 0;
    char buf;
    do
    {
      while (j > 0 && s[j] == '-')
      {
        --j;
      }
      while (i < s.length() - 1 && s[i] == '-')
      {
        ++i;
      }

      if (i >= j || s[i] == '-' || s[j] == '-')
      {
        if (i == j && s[i] != '-')
        {
          s[i] = reverseComplement(s[i]);
        }
        break;
      }

      buf = reverseComplement(s[i]);
      s[i] = reverseComplement(s[j]);
      s[j] = buf;

      ++i;
      --j;
    } while (true);
  }
}

// we now work with names instead of Genome*s to avoid expensive openGenome
// function
static size_t lcaRecursive(const Alignment* alignment,
                           const string& genome,
                           const set<string>& inputSet,
                           map<string, size_t>& table)
{
  size_t score = 0;
  if (inputSet.find(genome) != inputSet.end())
  {
    score = 1;
  }
  vector<string> childs = alignment->getChildNames(genome);
  for (hal_size_t i = 0; i < childs.size(); ++i)
  {
    score += lcaRecursive(alignment, childs[i], inputSet, table);
  }
  table.insert(pair<string, size_t>(genome, score));
  return score;
}

const Genome* hal::getLowestCommonAncestor(const set<const Genome*>& inputSet)
{
  if (inputSet.empty())
     return NULL;

  const Alignment* alignment = (*inputSet.begin())->getAlignment();
  set<string> inputNames;
  for (set<const Genome*>::iterator i = inputSet.begin(); i != inputSet.end();
       ++i)
  {
    inputNames.insert((*i)->getName());
  }

  // dumb algorithm but it's friday and i'm too tired to think
  string root = alignment->getRootName();
  map<string, size_t> table;
  lcaRecursive(alignment, root, inputNames, table);
  string lca = root;
  bool found = false;
  while (!found)
  {
    found = true;
    hal_size_t score = table.find(lca)->second;
    vector<string> childs = alignment->getChildNames(lca);

    for (hal_size_t i = 0; found && i < childs.size(); ++i)
    {
      if (table.find(childs[i])->second == score)
      {
        lca = childs[i];
        found = false;
      }
    }
  }
  return alignment->openGenome(lca);
}

// we now work with names instead of Genome*s to avoid expensive openGenome
// function
static bool spanningRecursive(const Alignment* alignment,
                              const string& genome,
                              set<const Genome*>& outputSet,
                              set<string>& outputNames,
                              bool below = false)
{
  bool above = false;
  if (outputNames.find(genome) != outputNames.end())
  {
    below = true;
    above = true;
  }
  vector<string> childs = alignment->getChildNames(genome);
  for (hal_size_t i = 0; i < childs.size(); ++i)
  {
    bool childAbove = spanningRecursive(alignment, childs[i], outputSet,
                                        outputNames, below);
    above = above || childAbove;
  }

  if (above && below)
  {
    outputSet.insert(alignment->openGenome(genome));
    outputNames.insert(genome);
  }
  return above;
}

void hal::getGenomesInSpanningTree(const set<const Genome*>& inputSet,
                              set<const Genome*>& outputSet)
{
  const Genome* lca = getLowestCommonAncestor(inputSet);
  if (lca== NULL)
     return;
  outputSet = inputSet;
  outputSet.insert(lca);
  set<string> outputNames;
  for (set<const Genome*>::iterator i = outputSet.begin(); i != outputSet.end();
       ++i)
  {
    outputNames.insert((*i)->getName());
  }
  spanningRecursive(lca->getAlignment(), lca->getName(), outputSet, outputNames);
}

void hal::getGenomesInSubTree(const Genome* root,
                              set<const Genome*>& outputSet)
{
  outputSet.insert(root);
  hal_size_t numChildren = root->getNumChildren();
  for (hal_size_t i = 0; i < numChildren; ++i)
  {
    getGenomesInSubTree(root->getChild(i), outputSet);
  }
}
<|endoftext|>


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

Program:   BlueBerry Platform
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

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

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

#ifdef __MINGW32__
// We need to inlclude winbase.h here in order to declare
// atomic intrinsics like InterlockedIncrement correctly.
// Otherwhise, they would be declared wrong within qatomic_windows.h .
#include <windows.h>
#endif

#include "berryQtPlatformLogModel.h"

#include "berryPlatform.h"
#include "event/berryPlatformEvents.h"

#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>

#include <Poco/Message.h>
#include "berryLog.h"
#include <QTimer>

namespace berry {

const QString QtPlatformLogModel::Error = QString("Error");
const QString QtPlatformLogModel::Warn = QString("Warn");
const QString QtPlatformLogModel::Fatal = QString("Fatal");
const QString QtPlatformLogModel::Info = QString("Info");
const QString QtPlatformLogModel::Debug = QString("Debug");

void QtPlatformLogModel::slotFlushLogEntries()
{
  m_Mutex.lock();
  std::list<ExtendedLogMessage> *tmp=m_Active;
  m_Active=m_Pending; m_Pending=tmp;
  m_Mutex.unlock();

  int num = static_cast<int>(m_Pending->size());

  if (num > 0)
  {
    int row = static_cast<int>(m_Entries.size());
    this->beginInsertRows(QModelIndex(), row, row+num-1);
    do {
      m_Entries.push_back(m_Pending->front());
      m_Pending->pop_front();
    } while(--num);
    this->endInsertRows();
  }
}

void QtPlatformLogModel::addLogEntry(const mbilog::LogMessage &msg)
{
  m_Mutex.lock();
  mbilog::BackendCout::FormatSmart(msg);
  m_Active->push_back(ExtendedLogMessage(msg));
  m_Mutex.unlock();

  emit signalFlushLogEntries();
}

void
QtPlatformLogModel::addLogEntry(const PlatformEvent& event)
{
  const Poco::Message& entry = Poco::RefAnyCast<const Poco::Message>(*event.GetData());
  mbilog::LogMessage msg(mbilog::Info,"n/a",-1,"n/a");
  msg.message += entry.getText();
  msg.category = "BlueBerry."+entry.getSource();
  msg.moduleName = "n/a";
  addLogEntry(msg);
}

QtPlatformLogModel::QtPlatformLogModel(QObject* parent) : QAbstractTableModel(parent)
{
  m_Active=new std::list<ExtendedLogMessage>;
  m_Pending=new std::list<ExtendedLogMessage>;
  connect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ), Qt::QueuedConnection );
  Platform::GetEvents().logged += PlatformEventDelegate(this, &QtPlatformLogModel::addLogEntry);
  myBackend = new QtLogBackend(this);
}

QtPlatformLogModel::~QtPlatformLogModel()
{
  disconnect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ));

  // dont delete and unregister backend, only deactivate it to avoid thread syncronization issues cause mbilog::UnregisterBackend is not threadsafe
  // will be fixed.
  //  delete myBackend;
  //  delete m_Active;
  //  delete m_Pending;
  m_Mutex.lock();
  myBackend->Deactivate();
  m_Mutex.unlock();
}

// QT Binding

int
QtPlatformLogModel::rowCount(const QModelIndex&) const
{
  return static_cast<int>(m_Entries.size());
}

int
QtPlatformLogModel::columnCount(const QModelIndex&) const
{
  return 8;
}
          /*
  struct LogEntry {
    LogEntry(const std::string& msg, const std::string& src, std::time_t t)
    : message(msg.c_str()), moduleName(src.c_str()),time(std::clock())
    {
    }

    QString message;
    clock_t time;

    QString level;
    QString filePath;
    QString lineNumber;
    QString moduleName;
    QString category;
    QString function;

    LogEntry(const mbilog::LogMessage &msg)
    {
      message = msg.message.c_str();

      filePath = msg.filePath;

      std::stringstream out;
      out << msg.lineNumber;
      lineNumber = out.str().c_str();

      moduleName = msg.moduleName;
      category = msg.category.c_str();
      function = msg.functionName;

      time=std::clock();
    }
  };        */

QVariant
QtPlatformLogModel::data(const QModelIndex& index, int role) const
{
  const ExtendedLogMessage *msg = &m_Entries[index.row()];
  if (role == Qt::DisplayRole)
  {
    switch (index.column()) {

      case 0: {
        std::stringstream ss;
        std::locale C("C");
        ss.imbue(C);
        ss << std::setw(7) << std::setprecision(3) << std::fixed << ((double)msg->time)/CLOCKS_PER_SEC;
        return QVariant(QString(ss.str().c_str()));
      }

      case 1:
        {
          switch(msg->message.level)
          {
            default:
            case mbilog::Info:
              return QVariant(Info);

            case mbilog::Warn:
              return QVariant(Warn);

            case mbilog::Error:
              return QVariant(Error);

            case mbilog::Fatal:
              return QVariant(Fatal);

            case mbilog::Debug:
              return QVariant(Debug);
          }
        }

      case 2:
        return QVariant(QString(msg->message.message.c_str()));

      case 3:
        return QVariant(QString(msg->message.category.c_str()));

      case 4:
        return QVariant(QString(msg->message.moduleName));

      case 5:
        return QVariant(QString(msg->message.functionName));

      case 6:
        return QVariant(QString(msg->message.filePath));

      case 7:
      {
        std::stringstream out;
        std::locale C("C");
        out.imbue(C);
        out << msg->message.lineNumber;
        return QVariant(QString(out.str().c_str()));
      }
    }
  }

  return QVariant();
}

QVariant
QtPlatformLogModel::headerData(int section, Qt::Orientation orientation, int role) const
{
  if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
  {
    switch (section) {
    case 0: return QVariant("Time");
    case 1: return QVariant("Level");
    case 2: return QVariant("Message");
    case 3: return QVariant("Category");
    case 4: return QVariant("Module");
    case 5: return QVariant("Function");
    case 6: return QVariant("File");
    case 7: return QVariant("Line");
    }
  }

  return QVariant();
}

}
<commit_msg>COMP: commented out call of formatting method which is not static any more<commit_after>/*=========================================================================

Program:   BlueBerry Platform
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

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

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

#ifdef __MINGW32__
// We need to inlclude winbase.h here in order to declare
// atomic intrinsics like InterlockedIncrement correctly.
// Otherwhise, they would be declared wrong within qatomic_windows.h .
#include <windows.h>
#endif

#include "berryQtPlatformLogModel.h"

#include "berryPlatform.h"
#include "event/berryPlatformEvents.h"

#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>

#include <Poco/Message.h>
#include "berryLog.h"
#include <QTimer>

namespace berry {

const QString QtPlatformLogModel::Error = QString("Error");
const QString QtPlatformLogModel::Warn = QString("Warn");
const QString QtPlatformLogModel::Fatal = QString("Fatal");
const QString QtPlatformLogModel::Info = QString("Info");
const QString QtPlatformLogModel::Debug = QString("Debug");

void QtPlatformLogModel::slotFlushLogEntries()
{
  m_Mutex.lock();
  std::list<ExtendedLogMessage> *tmp=m_Active;
  m_Active=m_Pending; m_Pending=tmp;
  m_Mutex.unlock();

  int num = static_cast<int>(m_Pending->size());

  if (num > 0)
  {
    int row = static_cast<int>(m_Entries.size());
    this->beginInsertRows(QModelIndex(), row, row+num-1);
    do {
      m_Entries.push_back(m_Pending->front());
      m_Pending->pop_front();
    } while(--num);
    this->endInsertRows();
  }
}

void QtPlatformLogModel::addLogEntry(const mbilog::LogMessage &msg)
{
  m_Mutex.lock();
  //mbilog::BackendCout::FormatSmart(msg); FormatSmart is not static any more. So commented out this statement. Todo: fix
  m_Active->push_back(ExtendedLogMessage(msg));
  m_Mutex.unlock();

  emit signalFlushLogEntries();
}

void
QtPlatformLogModel::addLogEntry(const PlatformEvent& event)
{
  const Poco::Message& entry = Poco::RefAnyCast<const Poco::Message>(*event.GetData());
  mbilog::LogMessage msg(mbilog::Info,"n/a",-1,"n/a");
  msg.message += entry.getText();
  msg.category = "BlueBerry."+entry.getSource();
  msg.moduleName = "n/a";
  addLogEntry(msg);
}

QtPlatformLogModel::QtPlatformLogModel(QObject* parent) : QAbstractTableModel(parent)
{
  m_Active=new std::list<ExtendedLogMessage>;
  m_Pending=new std::list<ExtendedLogMessage>;
  connect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ), Qt::QueuedConnection );
  Platform::GetEvents().logged += PlatformEventDelegate(this, &QtPlatformLogModel::addLogEntry);
  myBackend = new QtLogBackend(this);
}

QtPlatformLogModel::~QtPlatformLogModel()
{
  disconnect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ));

  // dont delete and unregister backend, only deactivate it to avoid thread syncronization issues cause mbilog::UnregisterBackend is not threadsafe
  // will be fixed.
  //  delete myBackend;
  //  delete m_Active;
  //  delete m_Pending;
  m_Mutex.lock();
  myBackend->Deactivate();
  m_Mutex.unlock();
}

// QT Binding

int
QtPlatformLogModel::rowCount(const QModelIndex&) const
{
  return static_cast<int>(m_Entries.size());
}

int
QtPlatformLogModel::columnCount(const QModelIndex&) const
{
  return 8;
}
          /*
  struct LogEntry {
    LogEntry(const std::string& msg, const std::string& src, std::time_t t)
    : message(msg.c_str()), moduleName(src.c_str()),time(std::clock())
    {
    }

    QString message;
    clock_t time;

    QString level;
    QString filePath;
    QString lineNumber;
    QString moduleName;
    QString category;
    QString function;

    LogEntry(const mbilog::LogMessage &msg)
    {
      message = msg.message.c_str();

      filePath = msg.filePath;

      std::stringstream out;
      out << msg.lineNumber;
      lineNumber = out.str().c_str();

      moduleName = msg.moduleName;
      category = msg.category.c_str();
      function = msg.functionName;

      time=std::clock();
    }
  };        */

QVariant
QtPlatformLogModel::data(const QModelIndex& index, int role) const
{
  const ExtendedLogMessage *msg = &m_Entries[index.row()];
  if (role == Qt::DisplayRole)
  {
    switch (index.column()) {

      case 0: {
        std::stringstream ss;
        std::locale C("C");
        ss.imbue(C);
        ss << std::setw(7) << std::setprecision(3) << std::fixed << ((double)msg->time)/CLOCKS_PER_SEC;
        return QVariant(QString(ss.str().c_str()));
      }

      case 1:
        {
          switch(msg->message.level)
          {
            default:
            case mbilog::Info:
              return QVariant(Info);

            case mbilog::Warn:
              return QVariant(Warn);

            case mbilog::Error:
              return QVariant(Error);

            case mbilog::Fatal:
              return QVariant(Fatal);

            case mbilog::Debug:
              return QVariant(Debug);
          }
        }

      case 2:
        return QVariant(QString(msg->message.message.c_str()));

      case 3:
        return QVariant(QString(msg->message.category.c_str()));

      case 4:
        return QVariant(QString(msg->message.moduleName));

      case 5:
        return QVariant(QString(msg->message.functionName));

      case 6:
        return QVariant(QString(msg->message.filePath));

      case 7:
      {
        std::stringstream out;
        std::locale C("C");
        out.imbue(C);
        out << msg->message.lineNumber;
        return QVariant(QString(out.str().c_str()));
      }
    }
  }

  return QVariant();
}

QVariant
QtPlatformLogModel::headerData(int section, Qt::Orientation orientation, int role) const
{
  if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
  {
    switch (section) {
    case 0: return QVariant("Time");
    case 1: return QVariant("Level");
    case 2: return QVariant("Message");
    case 3: return QVariant("Category");
    case 4: return QVariant("Module");
    case 5: return QVariant("Function");
    case 6: return QVariant("File");
    case 7: return QVariant("Line");
    }
  }

  return QVariant();
}

}
<|endoftext|>


<commit_before>//
//  GridZoneSwitch.cpp
//  Created by Matt Kaufmann on 02/12/14.
//

#include "ExampleGame/Components/Switches/GridZoneSwitch.h"
#include "ExampleGame/Messages/Declarations.h"
#include "Vajra/Common/Objects/Object.h"

GridZoneSwitch::GridZoneSwitch() : BaseSwitch() {
	this->init();
}

GridZoneSwitch::GridZoneSwitch(Object* object_) : BaseSwitch(object_) {
	this->init();
}

GridZoneSwitch::~GridZoneSwitch() {
	this->destroy();
}

void GridZoneSwitch::init() {
	this->requiredOccupants = 1;
	this->activateWhenUnitsInZone = true;

	this->addSubscriptionToMessageType(MESSAGE_TYPE_GRID_ZONE_ENTERED, this->GetTypeId(), true);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_GRID_ZONE_EXITED, this->GetTypeId(), true);
}

void GridZoneSwitch::destroy() {
	this->removeSubscriptionToAllMessageTypes(this->GetTypeId());

	this->occupants.clear();
}

void GridZoneSwitch::SetSwitchType(std::string typeStr) {
	BaseSwitch::SetSwitchType(typeStr);
}

void GridZoneSwitch::SetResetTime(float t) {
	BaseSwitch::SetResetTime(t);
}

void GridZoneSwitch::SetRequiredOccupants(unsigned int num) {
	this->requiredOccupants = num;
}

void GridZoneSwitch::SetActivateWhenUnitsInZone(bool b) {
	this->activateWhenUnitsInZone = b;
}

void GridZoneSwitch::HandleMessage(MessageChunk messageChunk) {
	BaseSwitch::HandleMessage(messageChunk);

	switch (messageChunk->GetMessageType()) {
		case MESSAGE_TYPE_GRID_ZONE_ENTERED:
			this->onUnitEnteredZone(messageChunk->messageData.iv1.x);
			break;

		case MESSAGE_TYPE_GRID_ZONE_EXITED:
			this->onUnitExitedZone(messageChunk->messageData.iv1.x);
			break;
	}
}

bool GridZoneSwitch::isConditionMet() {
	return this->occupants.size() >= this->requiredOccupants;
}

bool GridZoneSwitch::doesObjectCountAsOccupant(ObjectIdType /*id*/) {
	return true;
}

void GridZoneSwitch::onUnitEnteredZone(ObjectIdType id) {
	auto it = std::find(this->occupants.begin(), this->occupants.end(), id);
	if (it == this->occupants.end()) {
		if (this->doesObjectCountAsOccupant(id)) {
			this->occupants.push_back(id);

			if (this->occupants.size() >= this->requiredOccupants) {
				this->setConditionState(this->activateWhenUnitsInZone);
			}
		}
	}
	else {
		FRAMEWORK->GetLogger()->dbglog("Object %d is already in zone: %d", id, this->GetObject()->GetId());
	}
}

void GridZoneSwitch::onUnitExitedZone(ObjectIdType id) {
	auto it = std::find(this->occupants.begin(), this->occupants.end(), id);
	if (it != this->occupants.end()) {
		this->occupants.erase(it);

		if (this->occupants.size() < this->requiredOccupants) {
			this->setConditionState(!this->activateWhenUnitsInZone);
		}
	}
}

void GridZoneSwitch::SetDecalType(std::string decalType) {
	this->setDecalType(decalType);
}
<commit_msg>Added a dbglog which will notify the user if the game attempts to remove an object from a zone that it isn't in<commit_after>//
//  GridZoneSwitch.cpp
//  Created by Matt Kaufmann on 02/12/14.
//

#include "ExampleGame/Components/Switches/GridZoneSwitch.h"
#include "ExampleGame/Messages/Declarations.h"
#include "Vajra/Common/Objects/Object.h"

GridZoneSwitch::GridZoneSwitch() : BaseSwitch() {
	this->init();
}

GridZoneSwitch::GridZoneSwitch(Object* object_) : BaseSwitch(object_) {
	this->init();
}

GridZoneSwitch::~GridZoneSwitch() {
	this->destroy();
}

void GridZoneSwitch::init() {
	this->requiredOccupants = 1;
	this->activateWhenUnitsInZone = true;

	this->addSubscriptionToMessageType(MESSAGE_TYPE_GRID_ZONE_ENTERED, this->GetTypeId(), true);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_GRID_ZONE_EXITED, this->GetTypeId(), true);
}

void GridZoneSwitch::destroy() {
	this->removeSubscriptionToAllMessageTypes(this->GetTypeId());

	this->occupants.clear();
}

void GridZoneSwitch::SetSwitchType(std::string typeStr) {
	BaseSwitch::SetSwitchType(typeStr);
}

void GridZoneSwitch::SetResetTime(float t) {
	BaseSwitch::SetResetTime(t);
}

void GridZoneSwitch::SetRequiredOccupants(unsigned int num) {
	this->requiredOccupants = num;
}

void GridZoneSwitch::SetActivateWhenUnitsInZone(bool b) {
	this->activateWhenUnitsInZone = b;
}

void GridZoneSwitch::HandleMessage(MessageChunk messageChunk) {
	BaseSwitch::HandleMessage(messageChunk);

	switch (messageChunk->GetMessageType()) {
		case MESSAGE_TYPE_GRID_ZONE_ENTERED:
			this->onUnitEnteredZone(messageChunk->messageData.iv1.x);
			break;

		case MESSAGE_TYPE_GRID_ZONE_EXITED:
			this->onUnitExitedZone(messageChunk->messageData.iv1.x);
			break;
	}
}

bool GridZoneSwitch::isConditionMet() {
	return this->occupants.size() >= this->requiredOccupants;
}

bool GridZoneSwitch::doesObjectCountAsOccupant(ObjectIdType /*id*/) {
	return true;
}

void GridZoneSwitch::onUnitEnteredZone(ObjectIdType id) {
	auto it = std::find(this->occupants.begin(), this->occupants.end(), id);
	if (it == this->occupants.end()) {
		if (this->doesObjectCountAsOccupant(id)) {
			this->occupants.push_back(id);

			if (this->occupants.size() >= this->requiredOccupants) {
				this->setConditionState(this->activateWhenUnitsInZone);
			}
		}
	}
	else {
		FRAMEWORK->GetLogger()->dbglog("\nObject %d is already in zone: %d", id, this->GetObject()->GetId());
	}
}

void GridZoneSwitch::onUnitExitedZone(ObjectIdType id) {
	auto it = std::find(this->occupants.begin(), this->occupants.end(), id);
	if (it != this->occupants.end()) {
		this->occupants.erase(it);

		if (this->occupants.size() < this->requiredOccupants) {
			this->setConditionState(!this->activateWhenUnitsInZone);
		}
	}
	else {
		FRAMEWORK->GetLogger()->dbglog("\nObject %d is not in grid zone: %d", id, this->GetObject()->GetId());
	}
}

void GridZoneSwitch::SetDecalType(std::string decalType) {
	this->setDecalType(decalType);
}
<|endoftext|>


<commit_before>// Copyright 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ozone/wayland/display_poll_thread.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <wayland-client.h>

#include "base/bind.h"
#include "ozone/wayland/display.h"

namespace ozonewayland {
const int MAX_EVENTS = 16;
// os-compatibility
extern "C" {
int osEpollCreateCloExec(void);

static int setCloExecOrClose(int fd) {
  long flags;

  if (fd == -1)
    return -1;

  flags = fcntl(fd, F_GETFD);
  if (flags == -1)
    goto err;

  if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
    goto err;

  return fd;

  err:
    close(fd);
    return -1;
}

int osEpollCreateCloExec(void) {
  int fd;

#ifdef EPOLL_CLOEXEC
  fd = epoll_create1(EPOLL_CLOEXEC);
  if (fd >= 0)
    return fd;
  if (errno != EINVAL)
    return -1;
#endif

  fd = epoll_create(1);
  return setCloExecOrClose(fd);
}
}  // os-compatibility

WaylandDisplayPollThread::WaylandDisplayPollThread(wl_display* display)
    : base::Thread("WaylandDisplayPollThread"),
      display_(display),
      polling_(true, false),
      stop_polling_(true, false) {
  DCHECK(display_);
}

WaylandDisplayPollThread::~WaylandDisplayPollThread() {
  DCHECK(!polling_.IsSignaled());
  Stop();
}

void WaylandDisplayPollThread::StartProcessingEvents() {
  DCHECK(!polling_.IsSignaled());
  base::Thread::Options options;
  options.message_loop_type = base::MessageLoop::TYPE_IO;
  StartWithOptions(options);
  SetPriority(base::kThreadPriority_Background);
  message_loop_proxy()->PostTask(FROM_HERE, base::Bind(
      &WaylandDisplayPollThread::DisplayRun, this));
}

void WaylandDisplayPollThread::StopProcessingEvents() {
  if (polling_.IsSignaled())
    stop_polling_.Signal();
}

void  WaylandDisplayPollThread::DisplayRun(WaylandDisplayPollThread* data) {
  struct epoll_event ep[MAX_EVENTS];
  int i, ret, count = 0;
  uint32_t event = 0;
  bool epoll_err = false;
  unsigned display_fd = wl_display_get_fd(data->display_);
  int epoll_fd = osEpollCreateCloExec();
  if (epoll_fd < 0 ) {
    LOG(ERROR) << "Epoll creation failed.";
    return;
  }

  ep[0].events = EPOLLIN;
  ep[0].data.ptr = 0;
  if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, display_fd, &ep[0]) < 0) {
    close(epoll_fd);
    LOG(ERROR) << "epoll_ctl Add failed";
    return;
  }

  // Set the signal state. This is used to query from other threads (i.e.
  // StopProcessingEvents on Main thread), if this thread is still polling.
  data->polling_.Signal();

  // Adopted from:
  // http://cgit.freedesktop.org/wayland/weston/tree/clients/window.c#n5531.
  while (1) {
    wl_display_dispatch_pending(data->display_);
    // StopProcessingEvents has been called or we have been asked to stop
    // polling. Break from the loop.
    if (data->stop_polling_.IsSignaled())
      break;

    count = epoll_wait(epoll_fd, ep, MAX_EVENTS, -1);
    // Break if epoll wait returned value less than 0 and we aren't interrupted
    // by a signal.
    if (count < 0 && errno != EINTR) {
      LOG(ERROR) << "epoll_wait returned an error." << errno;
      epoll_err = true;
      break;
    }

    for (i = 0; i < count; i++) {
      event = ep[i].events;
      // We can have cases where EPOLLIN and EPOLLHUP are both set for
      // example. Don't break if both flags are set.
      if ((event & EPOLLERR || event & EPOLLHUP) &&
             !(event & EPOLLIN)) {
        epoll_err = true;
        break;
      }

      if (event & EPOLLIN) {
        ret = wl_display_dispatch(data->display_);
        if (ret == -1) {
          LOG(ERROR) << "wl_display_dispatch failed with an error." << errno;
          epoll_err = true;
          break;
        }
      }
    }

    if (epoll_err)
      break;
  }

  close(epoll_fd);
  data->polling_.Reset();
  data->stop_polling_.Reset();
}

}  // namespace ozonewayland
<commit_msg>Gardening: Fix popups.<commit_after>// Copyright 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ozone/wayland/display_poll_thread.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <wayland-client.h>

#include "base/bind.h"
#include "ozone/wayland/display.h"

namespace ozonewayland {
const int MAX_EVENTS = 16;
// os-compatibility
extern "C" {
int osEpollCreateCloExec(void);

static int setCloExecOrClose(int fd) {
  long flags;

  if (fd == -1)
    return -1;

  flags = fcntl(fd, F_GETFD);
  if (flags == -1)
    goto err;

  if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
    goto err;

  return fd;

  err:
    close(fd);
    return -1;
}

int osEpollCreateCloExec(void) {
  int fd;

#ifdef EPOLL_CLOEXEC
  fd = epoll_create1(EPOLL_CLOEXEC);
  if (fd >= 0)
    return fd;
  if (errno != EINVAL)
    return -1;
#endif

  fd = epoll_create(1);
  return setCloExecOrClose(fd);
}
}  // os-compatibility

WaylandDisplayPollThread::WaylandDisplayPollThread(wl_display* display)
    : base::Thread("WaylandDisplayPollThread"),
      display_(display),
      polling_(true, false),
      stop_polling_(true, false) {
  DCHECK(display_);
}

WaylandDisplayPollThread::~WaylandDisplayPollThread() {
  DCHECK(!polling_.IsSignaled());
  Stop();
}

void WaylandDisplayPollThread::StartProcessingEvents() {
  DCHECK(!polling_.IsSignaled());
  base::Thread::Options options;
  options.message_loop_type = base::MessageLoop::TYPE_IO;
  StartWithOptions(options);
  SetPriority(base::kThreadPriority_Background);
  message_loop_proxy()->PostTask(FROM_HERE, base::Bind(
      &WaylandDisplayPollThread::DisplayRun, this));
}

void WaylandDisplayPollThread::StopProcessingEvents() {
  if (polling_.IsSignaled())
    stop_polling_.Signal();
}

void  WaylandDisplayPollThread::DisplayRun(WaylandDisplayPollThread* data) {
  struct epoll_event ep[MAX_EVENTS];
  int i, ret, count = 0;
  uint32_t event = 0;
  bool epoll_err = false;
  unsigned display_fd = wl_display_get_fd(data->display_);
  int epoll_fd = osEpollCreateCloExec();
  if (epoll_fd < 0 ) {
    LOG(ERROR) << "Epoll creation failed.";
    return;
  }

  ep[0].events = EPOLLIN;
  ep[0].data.ptr = 0;
  if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, display_fd, &ep[0]) < 0) {
    close(epoll_fd);
    LOG(ERROR) << "epoll_ctl Add failed";
    return;
  }

  // Set the signal state. This is used to query from other threads (i.e.
  // StopProcessingEvents on Main thread), if this thread is still polling.
  data->polling_.Signal();

  // Adopted from:
  // http://cgit.freedesktop.org/wayland/weston/tree/clients/window.c#n5531.
  while (1) {
    wl_display_dispatch_pending(data->display_);
    ret = wl_display_flush(data->display_);
    if (ret < 0 && errno == EAGAIN) {
      ep[0].events = EPOLLIN | EPOLLERR | EPOLLHUP;
      epoll_ctl(epoll_fd, EPOLL_CTL_MOD, display_fd, &ep[0]);
    } else if (ret < 0) {
      epoll_err = true;
      break;
    }
    // StopProcessingEvents has been called or we have been asked to stop
    // polling. Break from the loop.
    if (data->stop_polling_.IsSignaled())
      break;

    count = epoll_wait(epoll_fd, ep, MAX_EVENTS, -1);
    // Break if epoll wait returned value less than 0 and we aren't interrupted
    // by a signal.
    if (count < 0 && errno != EINTR) {
      LOG(ERROR) << "epoll_wait returned an error." << errno;
      epoll_err = true;
      break;
    }

    for (i = 0; i < count; i++) {
      event = ep[i].events;
      // We can have cases where EPOLLIN and EPOLLHUP are both set for
      // example. Don't break if both flags are set.
      if ((event & EPOLLERR || event & EPOLLHUP) &&
             !(event & EPOLLIN)) {
        epoll_err = true;
        break;
      }

      if (event & EPOLLIN) {
        ret = wl_display_dispatch(data->display_);
        if (ret == -1) {
          LOG(ERROR) << "wl_display_dispatch failed with an error." << errno;
          epoll_err = true;
          break;
        }
      }
    }

    if (epoll_err)
      break;
  }

  close(epoll_fd);
  data->polling_.Reset();
  data->stop_polling_.Reset();
}

}  // namespace ozonewayland
<|endoftext|>