<commit_before>#pragma once

#include "detail/function_traits.hpp"
#include "detail/traits.hpp"
#include "detail/utils.hpp"
#include "detail/container_service.hpp"
#include "detail/invoke.hpp"

#include <unordered_map>
#include <memory>
#include <type_traits>
#include <tuple>
#include <algorithm>
#include <vector>

namespace kgr {

struct ForkService;

struct Container {
private:
	template<typename Condition, typename T = int> using enable_if = detail::enable_if_t<Condition::value, T>;
	template<typename Condition, typename T = int> using disable_if = detail::enable_if_t<!Condition::value, T>;
	template<typename T> using decay = typename std::decay<T>::type;
	template<typename T> using is_single = std::is_base_of<Single, decay<T>>;
	template<typename T> using is_container_service = std::integral_constant<bool, std::is_same<T, ContainerService>::value || std::is_same<T, ForkService>::value>;
	template<typename T> using is_base_of_container_service = std::is_base_of<detail::ContainerServiceBase, T>;
	template<typename T> using parent_types = typename decay<T>::ParentTypes;
	template<int S, typename T> using tuple_element_t = typename std::tuple_element<S, T>::type;
	template<typename Tuple, int n> using tuple_seq_minus = typename detail::seq_gen<std::tuple_size<Tuple>::value - n>::type;
	template<typename T> using instance_ptr = std::unique_ptr<T, void(*)(void*)>;
	template<template<typename> class Map, typename T> using service_map_t = typename Map<T>::Service;
	template<typename T> using is_invoke_call = typename std::is_base_of<detail::InvokeCallTag, T>::type;
	template<typename T> using has_autocall = typename std::is_base_of<detail::AutocallTag, T>::type;
	using instance_cont = std::vector<instance_ptr<void>>;
	using service_cont = std::unordered_map<detail::type_id_t, void*>;

	template<typename T>
	static void deleter(void* i) {
		delete static_cast<T*>(i);
	}

	template<typename T, typename C = T, typename... Args, enable_if<std::is_constructible<T, Args...>> = 0>
	static instance_ptr<C> makeInstancePtr(Args&&... args) {
		return instance_ptr<T>{new T(std::forward<Args>(args)...), &Container::deleter<C>};
	}

	template<typename T, typename C = T, typename... Args, disable_if<std::is_constructible<T, Args...>> = 0>
	static instance_ptr<C> makeInstancePtr(Args&&... args) {
		return instance_ptr<T>{new T{std::forward<Args>(args)...}, &Container::deleter<C>};
	}

public:
	Container() = default;
	Container(const Container &) = delete;
	Container& operator=(const Container &) = delete;
	Container(Container&&) = default;
	Container& operator=(Container&&) = default;
	virtual ~Container() = default;

	template<typename T, enable_if<is_single<decay<T>>> = 0>
	void instance(T&& service) {
		save_instance(std::forward<T>(service));
	}

	template<typename T, typename... Args, enable_if<is_single<T>> = 0>
	void instance(Args&& ...args) {
		save_new_instance<T>(std::forward<Args>(args)...);
	}

	template<typename T, typename... Args>
	ServiceType<T> service(Args&& ...args) {
		return get_service<T>(std::forward<Args>(args)...).forward();
	}

	template<template<typename> class Map, typename U, typename ...Args>
	detail::function_result_t<decay<U>> invoke(U&& function, Args&&... args) {
		return invoke<Map>(tuple_seq_minus<detail::function_arguments_t<decay<U>>, sizeof...(Args)>{}, std::forward<U>(function), std::forward<Args>(args)...);
	}

	template<typename... Services, typename U, typename ...Args>
	detail::function_result_t<decay<U>> invoke(U&& function, Args&&... args) {
		return std::forward<U>(function)(service<Services>()..., std::forward<Args>(args)...);
	}

	inline void clear() {
		_instances.clear();
		_services.clear();
	}

	inline Container fork() {
		return Container{_services};
	}

	inline void merge(Container&& other) {
		_instances.insert(_instances.end(), std::make_move_iterator(other._instances.begin()), std::make_move_iterator(other._instances.end()));
		_services.insert(other._services.begin(), other._services.end());
	}

private:
	Container(service_cont& services) : _services{services} {};

	///////////////////////
	//   save instance   //
	///////////////////////

	template<typename T, typename... Args, enable_if<is_single<T>> = 0, disable_if<std::is_abstract<T>> = 0>
	T& save_new_instance(Args&&... args) {
		return save_instance(make_service_instance<T>(std::forward<Args>(args)...));
	}

	template<typename T, typename... Args, enable_if<is_single<T>> = 0, enable_if<std::is_abstract<T>> = 0>
	T& save_new_instance(Args&&...) {
		throw std::out_of_range{"No instance found for the requested abstract service"};
	}

	template<typename T, enable_if<detail::has_overrides<decay<T>>> = 0>
	T& save_instance(T&& service) {
		return save_instance(std::forward<T>(service), detail::tuple_seq<parent_types<T>>{});
	}

	template<typename T, disable_if<detail::has_overrides<decay<T>>> = 0>
	T& save_instance(T&& service) {
		using U = decay<T>;
		return save_instance_helper<U>(makeInstancePtr<U>(std::move(service)));
	}

	template<typename T, int... S>
	T& save_instance(T&& service, detail::seq<S...>) {
		using U = decay<T>;
		return save_instance_helper<U, tuple_element_t<S, parent_types<U>>...>(makeInstancePtr<U>(std::move(service)));
	}

	template<typename T>
	T& save_instance_helper(instance_ptr<T> service) {
		auto& serviceRef = *service;

		_services[detail::type_id<T>] = service.get();
		_instances.emplace_back(std::move(service));

		return serviceRef;
	}

	template<typename T, typename Override, typename... Others>
	T& save_instance_helper(instance_ptr<T> service) {
		auto overrideService = makeInstancePtr<detail::ServiceOverride<T, Override>, Override>(*service);

		_services[detail::type_id<Override>] = overrideService.get();
		_instances.emplace_back(std::move(overrideService));

		return save_instance_helper<T, Others...>(std::move(service));
	}

	///////////////////////
	//    get service    //
	///////////////////////

	template<typename T, typename... Args, disable_if<is_single<T>> = 0, disable_if<is_base_of_container_service<T>> = 0>
	T get_service(Args&&... args) {
		return make_service_instance<T>(std::forward<Args>(args)...);
	}

	template<typename T, enable_if<is_container_service<T>> = 0>
	T get_service() {
		return T{*this};
	}

	template<typename T, enable_if<is_base_of_container_service<T>> = 0, disable_if<is_container_service<T>> = 0>
	T get_service() {
		return T{*dynamic_cast<typename T::Type*>(this)};
	}

	template<typename T, enable_if<is_single<T>> = 0, disable_if<is_base_of_container_service<T>> = 0>
	T& get_service() {
		if (auto&& service = _services[detail::type_id<T>]) {
			return *static_cast<T*>(service);
		} else {
			return save_new_instance<T>();
		}
	}

	///////////////////////
	//   make instance   //
	///////////////////////

	template<typename T, typename... Args>
	T make_service_instance(Args&&... args) {
		T service = invoke_raw(&T::construct, std::forward<Args>(args)...);
		invoke_service(service);
		return service;
	}

	///////////////////////
	//      invoke       //
	///////////////////////

	template<typename U, typename ...Args, int... S>
	detail::function_result_t<decay<U>> invoke(detail::seq<S...>, U&& function, Args&&... args) {
		return std::forward<U>(function)(get_service<decay<detail::function_argument_t<S, decay<U>>>>()..., std::forward<Args>(args)...);
	}

	template<template<typename> class Map, typename U, typename ...Args, int... S>
	detail::function_result_t<decay<U>> invoke(detail::seq<S...>, U&& function, Args&&... args) {
		return std::forward<U>(function)(service<service_map_t<Map, detail::function_argument_t<S, decay<U>>>>()..., std::forward<Args>(args)...);
	}

	template<typename U, typename ...Args, enable_if<is_invoke_call<decay<U>>> = 0>
	detail::function_result_t<decay<U>> invoke(U&& function, Args&&... args) {
		using V = decay<U>;
		return invoke(detail::tuple_seq<typename V::Params>{}, std::forward<U>(function), std::forward<Args>(args)...);
	}

	template<typename U, typename ...Args, int... S, enable_if<is_invoke_call<decay<U>>> = 0>
	detail::function_result_t<decay<U>> invoke(detail::seq<S...>, U&& function, Args&&... args) {
		using V = decay<U>;
		return invoke<tuple_element_t<S, typename V::Params>...>(std::forward<U>(function), std::forward<Args>(args)...);
	}

	template<typename U, typename ...Args, disable_if<is_invoke_call<decay<U>>> = 0>
	detail::function_result_t<decay<U>> invoke_raw(U&& function, Args&&... args) {
		return invoke(tuple_seq_minus<detail::function_arguments_t<decay<U>>, sizeof...(Args)>{}, std::forward<U>(function), std::forward<Args>(args)...);
	}

	///////////////////////
	//     autocall      //
	///////////////////////

	// This function starts the iteration (invoke_service_helper)
	template<typename T, enable_if<detail::has_invoke<decay<T>>> = 0>
	void invoke_service(T&& service) {
		using U = decay<T>;
		invoke_service_helper<typename U::invoke>(std::forward<T>(service));
	}

	// This function is the iteration for invoke_service
	template<typename Method, typename T, enable_if<detail::has_next<Method>> = 0>
	void invoke_service_helper(T&& service) {
		do_invoke_service<Method>(std::forward<T>(service));
		invoke_service_helper<typename Method::Next>(std::forward<T>(service));
	}

	// This is the last iteration of invoke_service
	template<typename Method, typename T, disable_if<detail::has_next<Method>> = 0>
	void invoke_service_helper(T&&) {}

	// This function is the do_invoke_service when <Method> is actually the class kgr::Invoke<...>
	// This serves the purpose of handling the new autocall syntax when the parameters are explicitly listed
	template<typename Method, typename T, enable_if<is_invoke_call<Method>> = 0>
	void do_invoke_service(T&& service) {
		do_invoke_service<Method>(detail::tuple_seq<typename Method::Params>{}, std::forward<T>(service));
	}

	// This function is a helper for do_invoke_service when <Method> is actually the class kgr::Invoke<...>
	template<typename Method, typename T, int... S>
	void do_invoke_service(detail::seq<S...>, T&& service) {
		using U = decay<T>;
		do_invoke_service(
			detail::tuple_seq<detail::function_arguments_t<typename Method::value_type>>{},
			std::forward<T>(service),
			&U::template autocall<Method, tuple_element_t<S, typename Method::Params>...>
		);
	}

	// This function is the do_invoke_service handling the new syntax for autocall
	template<typename Method, typename T, disable_if<is_invoke_call<Method>> = 0, enable_if<has_autocall<decay<T>>> = 0>
	void do_invoke_service(T&& service) {
		using U = decay<T>;
		do_invoke_service(detail::tuple_seq<std::tuple<ContainerService>>{}, std::forward<T>(service), &U::template autocall<Method, U::template Map>);
	}

	// This function is the do_invoke_service with the old syntax
	template<typename Method, typename T, disable_if<is_invoke_call<Method>> = 0, disable_if<has_autocall<decay<T>>> = 0>
	void do_invoke_service(T&& service) {
		do_invoke_service(detail::tuple_seq<detail::function_arguments_t<typename Method::value_type>>{}, std::forward<T>(service), Method::value);
	}

	// This function is the do_invoke_service that take the method to invoke as parameter.
	template<typename T, typename F, int... S>
	void do_invoke_service(detail::seq<S...>, T&& service, F&& function) {
		invoke_raw([&service, &function](detail::function_argument_t<S, decay<F>>... args){
			(std::forward<T>(service).*std::forward<F>(function))(std::forward<detail::function_argument_t<S, decay<F>>>(args)...);
		});
	}

	template<typename T, disable_if<detail::has_invoke<decay<T>>> = 0>
	void invoke_service(T&&) {}

	///////////////////////
	//     instances     //
	///////////////////////

	instance_cont _instances;
	service_cont _services;
};

}  // namespace kgr
<commit_msg>clarify comments<commit_after>#pragma once

#include "detail/function_traits.hpp"
#include "detail/traits.hpp"
#include "detail/utils.hpp"
#include "detail/container_service.hpp"
#include "detail/invoke.hpp"

#include <unordered_map>
#include <memory>
#include <type_traits>
#include <tuple>
#include <algorithm>
#include <vector>

namespace kgr {

struct ForkService;

struct Container {
private:
	template<typename Condition, typename T = int> using enable_if = detail::enable_if_t<Condition::value, T>;
	template<typename Condition, typename T = int> using disable_if = detail::enable_if_t<!Condition::value, T>;
	template<typename T> using decay = typename std::decay<T>::type;
	template<typename T> using is_single = std::is_base_of<Single, decay<T>>;
	template<typename T> using is_container_service = std::integral_constant<bool, std::is_same<T, ContainerService>::value || std::is_same<T, ForkService>::value>;
	template<typename T> using is_base_of_container_service = std::is_base_of<detail::ContainerServiceBase, T>;
	template<typename T> using parent_types = typename decay<T>::ParentTypes;
	template<int S, typename T> using tuple_element_t = typename std::tuple_element<S, T>::type;
	template<typename Tuple, int n> using tuple_seq_minus = typename detail::seq_gen<std::tuple_size<Tuple>::value - n>::type;
	template<typename T> using instance_ptr = std::unique_ptr<T, void(*)(void*)>;
	template<template<typename> class Map, typename T> using service_map_t = typename Map<T>::Service;
	template<typename T> using is_invoke_call = typename std::is_base_of<detail::InvokeCallTag, T>::type;
	template<typename T> using has_autocall = typename std::is_base_of<detail::AutocallTag, T>::type;
	using instance_cont = std::vector<instance_ptr<void>>;
	using service_cont = std::unordered_map<detail::type_id_t, void*>;

	template<typename T>
	static void deleter(void* i) {
		delete static_cast<T*>(i);
	}

	template<typename T, typename C = T, typename... Args, enable_if<std::is_constructible<T, Args...>> = 0>
	static instance_ptr<C> makeInstancePtr(Args&&... args) {
		return instance_ptr<T>{new T(std::forward<Args>(args)...), &Container::deleter<C>};
	}

	template<typename T, typename C = T, typename... Args, disable_if<std::is_constructible<T, Args...>> = 0>
	static instance_ptr<C> makeInstancePtr(Args&&... args) {
		return instance_ptr<T>{new T{std::forward<Args>(args)...}, &Container::deleter<C>};
	}

public:
	Container() = default;
	Container(const Container &) = delete;
	Container& operator=(const Container &) = delete;
	Container(Container&&) = default;
	Container& operator=(Container&&) = default;
	virtual ~Container() = default;

	template<typename T, enable_if<is_single<decay<T>>> = 0>
	void instance(T&& service) {
		save_instance(std::forward<T>(service));
	}

	template<typename T, typename... Args, enable_if<is_single<T>> = 0>
	void instance(Args&& ...args) {
		save_new_instance<T>(std::forward<Args>(args)...);
	}

	template<typename T, typename... Args>
	ServiceType<T> service(Args&& ...args) {
		return get_service<T>(std::forward<Args>(args)...).forward();
	}

	template<template<typename> class Map, typename U, typename ...Args>
	detail::function_result_t<decay<U>> invoke(U&& function, Args&&... args) {
		return invoke<Map>(tuple_seq_minus<detail::function_arguments_t<decay<U>>, sizeof...(Args)>{}, std::forward<U>(function), std::forward<Args>(args)...);
	}

	template<typename... Services, typename U, typename ...Args>
	detail::function_result_t<decay<U>> invoke(U&& function, Args&&... args) {
		return std::forward<U>(function)(service<Services>()..., std::forward<Args>(args)...);
	}

	inline void clear() {
		_instances.clear();
		_services.clear();
	}

	inline Container fork() {
		return Container{_services};
	}

	inline void merge(Container&& other) {
		_instances.insert(_instances.end(), std::make_move_iterator(other._instances.begin()), std::make_move_iterator(other._instances.end()));
		_services.insert(other._services.begin(), other._services.end());
	}

private:
	Container(service_cont& services) : _services{services} {};

	///////////////////////
	//   save instance   //
	///////////////////////

	template<typename T, typename... Args, enable_if<is_single<T>> = 0, disable_if<std::is_abstract<T>> = 0>
	T& save_new_instance(Args&&... args) {
		return save_instance(make_service_instance<T>(std::forward<Args>(args)...));
	}

	template<typename T, typename... Args, enable_if<is_single<T>> = 0, enable_if<std::is_abstract<T>> = 0>
	T& save_new_instance(Args&&...) {
		throw std::out_of_range{"No instance found for the requested abstract service"};
	}

	template<typename T, enable_if<detail::has_overrides<decay<T>>> = 0>
	T& save_instance(T&& service) {
		return save_instance(std::forward<T>(service), detail::tuple_seq<parent_types<T>>{});
	}

	template<typename T, disable_if<detail::has_overrides<decay<T>>> = 0>
	T& save_instance(T&& service) {
		using U = decay<T>;
		return save_instance_helper<U>(makeInstancePtr<U>(std::move(service)));
	}

	template<typename T, int... S>
	T& save_instance(T&& service, detail::seq<S...>) {
		using U = decay<T>;
		return save_instance_helper<U, tuple_element_t<S, parent_types<U>>...>(makeInstancePtr<U>(std::move(service)));
	}

	template<typename T>
	T& save_instance_helper(instance_ptr<T> service) {
		auto& serviceRef = *service;

		_services[detail::type_id<T>] = service.get();
		_instances.emplace_back(std::move(service));

		return serviceRef;
	}

	template<typename T, typename Override, typename... Others>
	T& save_instance_helper(instance_ptr<T> service) {
		auto overrideService = makeInstancePtr<detail::ServiceOverride<T, Override>, Override>(*service);

		_services[detail::type_id<Override>] = overrideService.get();
		_instances.emplace_back(std::move(overrideService));

		return save_instance_helper<T, Others...>(std::move(service));
	}

	///////////////////////
	//    get service    //
	///////////////////////

	template<typename T, typename... Args, disable_if<is_single<T>> = 0, disable_if<is_base_of_container_service<T>> = 0>
	T get_service(Args&&... args) {
		return make_service_instance<T>(std::forward<Args>(args)...);
	}

	template<typename T, enable_if<is_container_service<T>> = 0>
	T get_service() {
		return T{*this};
	}

	template<typename T, enable_if<is_base_of_container_service<T>> = 0, disable_if<is_container_service<T>> = 0>
	T get_service() {
		return T{*dynamic_cast<typename T::Type*>(this)};
	}

	template<typename T, enable_if<is_single<T>> = 0, disable_if<is_base_of_container_service<T>> = 0>
	T& get_service() {
		if (auto&& service = _services[detail::type_id<T>]) {
			return *static_cast<T*>(service);
		} else {
			return save_new_instance<T>();
		}
	}

	///////////////////////
	//   make instance   //
	///////////////////////

	template<typename T, typename... Args>
	T make_service_instance(Args&&... args) {
		T service = invoke_raw(&T::construct, std::forward<Args>(args)...);
		invoke_service(service);
		return service;
	}

	///////////////////////
	//      invoke       //
	///////////////////////

	template<typename U, typename ...Args, int... S>
	detail::function_result_t<decay<U>> invoke(detail::seq<S...>, U&& function, Args&&... args) {
		return std::forward<U>(function)(get_service<decay<detail::function_argument_t<S, decay<U>>>>()..., std::forward<Args>(args)...);
	}

	template<template<typename> class Map, typename U, typename ...Args, int... S>
	detail::function_result_t<decay<U>> invoke(detail::seq<S...>, U&& function, Args&&... args) {
		return std::forward<U>(function)(service<service_map_t<Map, detail::function_argument_t<S, decay<U>>>>()..., std::forward<Args>(args)...);
	}

	template<typename U, typename ...Args, enable_if<is_invoke_call<decay<U>>> = 0>
	detail::function_result_t<decay<U>> invoke(U&& function, Args&&... args) {
		using V = decay<U>;
		return invoke(detail::tuple_seq<typename V::Params>{}, std::forward<U>(function), std::forward<Args>(args)...);
	}

	template<typename U, typename ...Args, int... S, enable_if<is_invoke_call<decay<U>>> = 0>
	detail::function_result_t<decay<U>> invoke(detail::seq<S...>, U&& function, Args&&... args) {
		using V = decay<U>;
		return invoke<tuple_element_t<S, typename V::Params>...>(std::forward<U>(function), std::forward<Args>(args)...);
	}

	template<typename U, typename ...Args, disable_if<is_invoke_call<decay<U>>> = 0>
	detail::function_result_t<decay<U>> invoke_raw(U&& function, Args&&... args) {
		return invoke(tuple_seq_minus<detail::function_arguments_t<decay<U>>, sizeof...(Args)>{}, std::forward<U>(function), std::forward<Args>(args)...);
	}

	///////////////////////
	//     autocall      //
	///////////////////////

	// This function starts the iteration (invoke_service_helper)
	template<typename T, enable_if<detail::has_invoke<decay<T>>> = 0>
	void invoke_service(T&& service) {
		using U = decay<T>;
		invoke_service_helper<typename U::invoke>(std::forward<T>(service));
	}

	// This function is the iteration for invoke_service
	template<typename Method, typename T, enable_if<detail::has_next<Method>> = 0>
	void invoke_service_helper(T&& service) {
		do_invoke_service<Method>(std::forward<T>(service));
		invoke_service_helper<typename Method::Next>(std::forward<T>(service));
	}

	// This is the last iteration of invoke_service
	template<typename Method, typename T, disable_if<detail::has_next<Method>> = 0>
	void invoke_service_helper(T&&) {}

	// This function is the do_invoke_service when <Method> is kgr::Invoke with parameters explicitly listed.
	template<typename Method, typename T, enable_if<is_invoke_call<Method>> = 0>
	void do_invoke_service(T&& service) {
		do_invoke_service<Method>(detail::tuple_seq<typename Method::Params>{}, std::forward<T>(service));
	}

	// This function is a helper for do_invoke_service when <Method> is kgr::Invoke with parameters explicitly listed.
	template<typename Method, typename T, int... S>
	void do_invoke_service(detail::seq<S...>, T&& service) {
		using U = decay<T>;
		do_invoke_service(
			detail::tuple_seq<detail::function_arguments_t<typename Method::value_type>>{},
			std::forward<T>(service),
			&U::template autocall<Method, tuple_element_t<S, typename Method::Params>...>
		);
	}

	// This function is the do_invoke_service handling the new syntax for autocall
	template<typename Method, typename T, disable_if<is_invoke_call<Method>> = 0, enable_if<has_autocall<decay<T>>> = 0>
	void do_invoke_service(T&& service) {
		using U = decay<T>;
		do_invoke_service(detail::tuple_seq<std::tuple<ContainerService>>{}, std::forward<T>(service), &U::template autocall<Method, U::template Map>);
	}

	// This function is the do_invoke_service with the old syntax
	template<typename Method, typename T, disable_if<is_invoke_call<Method>> = 0, disable_if<has_autocall<decay<T>>> = 0>
	void do_invoke_service(T&& service) {
		do_invoke_service(detail::tuple_seq<detail::function_arguments_t<typename Method::value_type>>{}, std::forward<T>(service), Method::value);
	}

	// This function is the do_invoke_service that take the method to invoke as parameter.
	template<typename T, typename F, int... S>
	void do_invoke_service(detail::seq<S...>, T&& service, F&& function) {
		invoke_raw([&service, &function](detail::function_argument_t<S, decay<F>>... args){
			(std::forward<T>(service).*std::forward<F>(function))(std::forward<detail::function_argument_t<S, decay<F>>>(args)...);
		});
	}

	template<typename T, disable_if<detail::has_invoke<decay<T>>> = 0>
	void invoke_service(T&&) {}

	///////////////////////
	//     instances     //
	///////////////////////

	instance_cont _instances;
	service_cont _services;
};

}  // namespace kgr
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_ALLOCA

#include "libtorrent/config.hpp"

#ifdef TORRENT_WINDOWS

#include <malloc.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(_alloca(sizeof(t) * n));

#else

#include <alloca.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * n));

#endif

#endif

<commit_msg>alloca macro fix<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_ALLOCA

#include "libtorrent/config.hpp"

#ifdef TORRENT_WINDOWS

#include <malloc.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(_alloca(sizeof(t) * (n)));

#else

#include <alloca.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)));

#endif

#endif

<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_ALLOCA

#include "libtorrent/config.hpp"

#ifdef TORRENT_WINDOWS

#include <malloc.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(_alloca(sizeof(t) * (n)))

#else

#include <alloca.h>

#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)))

#endif

#endif

<commit_msg>another FreeBSD fix<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_ALLOCA

#include "libtorrent/config.hpp"

#if defined TORRENT_WINDOWS

#include <malloc.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(_alloca(sizeof(t) * (n)))

#elif defined TORRENT_BSD

#include <stdlib.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)))

#else

#include <alloca.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)))

#endif

#endif

<|endoftext|>


<commit_before>/*
 * rpiHomeApp.cpp

 *
 *  Created on: 19 sty 2015
 *      Author: paku
 */

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include "rpiHome.h"

using namespace std;

int get_cmd_line_params(rpiHome* thisRPiHome, int ac, char *av[]) {

	int period;

	// Declare the supported options.
	po::options_description desc("RPiHome options");
	desc.add_options()("help,h", "this help message")("daemon,d", "run in daemon mode (not implemented)")("logger,l", "log activity into the DB")("termo,t",
			"read and log temperature (1Wire DS18D20 temperature sensors only)")("verbose,v", "be verbose, enable stdio output messages.");

	po::variables_map vm;

	try {

		po::store(po::parse_command_line(ac, av, desc), vm);

		if (vm.count("help")) {
			cout << TITLE << endl << desc << endl;
			return SUCCESS_HELP_ONLY;
		}

		po::notify(vm);

	}

	catch (po::error& e) {
		cerr << "#STOP#" << endl << "Command line parser error: " << e.what() << endl << endl;
		cerr << desc << endl;
		return ERROR_IN_COMMAND_LINE;
	}

	//thisRPiHome->args.daemon=vm.count("daemon");

	thisRPiHome->args.verbose = vm.count("verbose");
	thisRPiHome->args.termo = vm.count("termo");
	thisRPiHome->args.logger = vm.count("logger");

	//show title in verbose mode
	if (thisRPiHome->args.verbose)
		cout << TITLE << endl;

	return SUCCESS;

}

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

	rpiHome* myRPiHome = new rpiHome();

	switch (get_cmd_line_params(myRPiHome, argc, argv)) {
	case SUCCESS:
		break;
	case SUCCESS_HELP_ONLY:
		return EXIT_SUCCESS;
		break;
	case ERROR_IN_COMMAND_LINE:
		return EXIT_FAILURE;
		break;
	case ERROR_UNHANDLED_EXCEPTION:
		return EXIT_FAILURE;
		break;
	default:
		return EXIT_FAILURE;
		break;
	}

	//init main object
	myRPiHome->init(MYSQL_SERVER, DB_USER, DB_PASS, DB_NAME);

	myRPiHome->setOutputPins();

	myRPiHome->getTemps();

	return EXIT_SUCCESS;
}

<commit_msg>UI text correction<commit_after>/*
 * rpiHomeApp.cpp

 *
 *  Created on: 19 sty 2015
 *      Author: paku
 */

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include "rpiHome.h"

using namespace std;

int get_cmd_line_params(rpiHome* thisRPiHome, int ac, char *av[]) {

	int period;

	// Declare the supported options.
	po::options_description desc("RPiHome options");
	desc.add_options()("help,h", "this help message")("daemon,d", "run in daemon mode (not implemented)")("logger,l", "log into the DB")("termo,t",
			"read and log temperature (1Wire DS18x20 temperature sensors only)")("verbose,v", "be verbose, enable stdio output messages.");

	po::variables_map vm;

	try {

		po::store(po::parse_command_line(ac, av, desc), vm);

		if (vm.count("help")) {
			cout << TITLE << endl << desc << endl;
			return SUCCESS_HELP_ONLY;
		}

		po::notify(vm);

	}

	catch (po::error& e) {
		cerr << "#STOP#" << endl << "Command line parser error: " << e.what() << endl << endl;
		cerr << desc << endl;
		return ERROR_IN_COMMAND_LINE;
	}

	//thisRPiHome->args.daemon=vm.count("daemon");

	thisRPiHome->args.verbose = vm.count("verbose");
	thisRPiHome->args.termo = vm.count("termo");
	thisRPiHome->args.logger = vm.count("logger");

	//show title in verbose mode
	if (thisRPiHome->args.verbose)
		cout << TITLE << endl;

	return SUCCESS;

}

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

	rpiHome* myRPiHome = new rpiHome();

	switch (get_cmd_line_params(myRPiHome, argc, argv)) {
	case SUCCESS:
		break;
	case SUCCESS_HELP_ONLY:
		return EXIT_SUCCESS;
		break;
	case ERROR_IN_COMMAND_LINE:
		return EXIT_FAILURE;
		break;
	case ERROR_UNHANDLED_EXCEPTION:
		return EXIT_FAILURE;
		break;
	default:
		return EXIT_FAILURE;
		break;
	}

	//init main object
	myRPiHome->init(MYSQL_SERVER, DB_USER, DB_PASS, DB_NAME);

	myRPiHome->setOutputPins();

	myRPiHome->getTemps();

	return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>// Copyright (c) 2019, Sergey Abbakumov
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "rst/preferences/memory_preferences_store.h"

#include <string>
#include <utility>

namespace rst {

MemoryPreferencesStore::MemoryPreferencesStore() = default;
MemoryPreferencesStore::~MemoryPreferencesStore() = default;

Nullable<const Value*> MemoryPreferencesStore::GetValue(
    const std::string_view path) const {
  return values_.FindKey(path);
}

void MemoryPreferencesStore::SetValue(const std::string_view path,
                                      Value&& value) {
  values_.SetKey(std::string(path), std::move(value));
}

}  // namespace rst
<commit_msg>MemoryPreferencesStore refactoring<commit_after>// Copyright (c) 2019, Sergey Abbakumov
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "rst/preferences/memory_preferences_store.h"

#include <utility>

namespace rst {

MemoryPreferencesStore::MemoryPreferencesStore() = default;
MemoryPreferencesStore::~MemoryPreferencesStore() = default;

Nullable<const Value*> MemoryPreferencesStore::GetValue(
    const std::string_view path) const {
  return values_.FindPath(path);
}

void MemoryPreferencesStore::SetValue(const std::string_view path,
                                      Value&& value) {
  values_.SetPath(path, std::move(value));
}

}  // namespace rst
<|endoftext|>


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

// Implementation of the sandbox2::ForkServer class.

#include "sandboxed_api/sandbox2/global_forkclient.h"

#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <syscall.h>
#include <unistd.h>

#include <csignal>
#include <cstdlib>
#include <string>
#include <vector>

#include <glog/logging.h>
#include "sandboxed_api/util/flag.h"
#include "absl/memory/memory.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "sandboxed_api/embed_file.h"
#include "sandboxed_api/sandbox2/comms.h"
#include "sandboxed_api/sandbox2/fork_client.h"
#include "sandboxed_api/sandbox2/forkserver_bin_embed.h"
#include "sandboxed_api/sandbox2/util.h"
#include "sandboxed_api/util/fileops.h"
#include "sandboxed_api/util/raw_logging.h"
#include "sandboxed_api/util/strerror.h"

namespace sandbox2 {

namespace file_util = ::sapi::file_util;

bool AbslParseFlag(absl::string_view text, GlobalForkserverStartModeSet* out,
                   std::string* error) {
  *out = {};
  if (text == "never") {
    return true;
  }
  for (absl::string_view mode : absl::StrSplit(text, ',')) {
    mode = absl::StripAsciiWhitespace(mode);
    if (mode == "ondemand") {
      *out |= GlobalForkserverStartMode::kOnDemand;
    } else {
      *error = absl::StrCat("Invalid forkserver start mode: ", mode);
      return false;
    }
  }
  return true;
}

namespace {
std::string ToString(GlobalForkserverStartMode mode) {
  switch (mode) {
    case GlobalForkserverStartMode::kOnDemand:
      return "ondemand";
    default:
      return "unknown";
  }
}
bool ValidateStartMode(const char*, const std::string& flag) {
  GlobalForkserverStartModeSet unused;
  std::string error;
  if (!AbslParseFlag(flag, &unused, &error)) {
    SAPI_RAW_LOG(ERROR, "%s", error.c_str());
    return false;
  }
  return true;
}
}  // namespace

std::string AbslUnparseFlag(GlobalForkserverStartModeSet in) {
  std::vector<std::string> str_modes;
  for (size_t i = 0; i < GlobalForkserverStartModeSet::kSize; ++i) {
    auto mode = static_cast<GlobalForkserverStartMode>(i);
    if (in.contains(mode)) {
      str_modes.push_back(ToString(mode));
    }
  }
  if (str_modes.empty()) {
    return "never";
  }
  return absl::StrJoin(str_modes, ",");
}

}  // namespace sandbox2

ABSL_FLAG(string, sandbox2_forkserver_start_mode, "ondemand",
          "When Sandbox2 Forkserver process should be started");
DEFINE_validator(sandbox2_forkserver_start_mode, &sandbox2::ValidateStartMode);

namespace sandbox2 {

namespace {

GlobalForkserverStartModeSet GetForkserverStartMode() {
  GlobalForkserverStartModeSet rv;
  std::string error;
  CHECK(AbslParseFlag(absl::GetFlag(FLAGS_sandbox2_forkserver_start_mode), &rv,
                      &error));
  return rv;
}

std::unique_ptr<GlobalForkClient> StartGlobalForkServer() {
  file_util::fileops::FDCloser exec_fd(
      sapi::EmbedFile::GetEmbedFileSingleton()->GetFdForFileToc(
          forkserver_bin_embed_create()));
  SAPI_RAW_CHECK(exec_fd.get() >= 0, "Getting FD for init binary failed");

  std::string proc_name = "S2-FORK-SERV";

  int sv[2];
  SAPI_RAW_CHECK(socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) != -1,
                 "creating socket pair");

  // Fork the fork-server, and clean-up the resources (close remote sockets).
  pid_t pid = util::ForkWithFlags(SIGCHLD);
  SAPI_RAW_PCHECK(pid != -1, "during fork");

  // Child.
  if (pid == 0) {
    // Move the comms FD to the proper, expected FD number.
    // The new FD will not be CLOEXEC, which is what we want.
    dup2(sv[0], Comms::kSandbox2ClientCommsFD);

    char* const args[] = {proc_name.data(), nullptr};
    char* const envp[] = {nullptr};
    syscall(__NR_execveat, exec_fd.get(), "", args, envp, AT_EMPTY_PATH);
    SAPI_RAW_PLOG(FATAL, "Could not launch forkserver binary");
    abort();
  }

  close(sv[0]);
  return absl::make_unique<GlobalForkClient>(sv[1], pid);
}

}  // namespace

absl::Mutex GlobalForkClient::instance_mutex_(absl::kConstInit);
GlobalForkClient* GlobalForkClient::instance_ = nullptr;

void GlobalForkClient::EnsureStarted(GlobalForkserverStartMode mode) {
  absl::MutexLock lock(&instance_mutex_);
  EnsureStartedLocked(mode);
}

void GlobalForkClient::EnsureStartedLocked(GlobalForkserverStartMode mode) {
  if (!instance_) {
    SAPI_RAW_CHECK(
        !getenv(kForkServerDisableEnv),
        absl::StrCat("Start of the Global Fork-Server prevented by the '",
                     kForkServerDisableEnv, "' environment variable present")
            .c_str());
    SAPI_RAW_CHECK(
        GetForkserverStartMode().contains(mode),
        "Start of the Global Fork-Server prevented by commandline flag");
    instance_ = StartGlobalForkServer().release();
  }
  SAPI_RAW_CHECK(instance_ != nullptr, "global fork client not initialized");
}

void GlobalForkClient::ForceStart() {
  absl::MutexLock lock(&GlobalForkClient::instance_mutex_);
  SAPI_RAW_CHECK(instance_ == nullptr,
                 "A force start requested when the Global Fork-Server was "
                 "already running");
  instance_ = StartGlobalForkServer().release();
}

void GlobalForkClient::Shutdown() {
  absl::MutexLock lock(&GlobalForkClient::instance_mutex_);
  delete instance_;
  instance_ = nullptr;
}

pid_t GlobalForkClient::SendRequest(const ForkRequest& request, int exec_fd,
                                    int comms_fd, int user_ns_fd,
                                    pid_t* init_pid) {
  absl::MutexLock lock(&GlobalForkClient::instance_mutex_);
  EnsureStartedLocked(GlobalForkserverStartMode::kOnDemand);
  pid_t pid = instance_->fork_client_.SendRequest(request, exec_fd, comms_fd,
                                                  user_ns_fd, init_pid);
  if (instance_->comms_.IsTerminated()) {
    LOG(ERROR) << "Global forkserver connection terminated";
  }
  return pid;
}

pid_t GlobalForkClient::GetPid() {
  absl::MutexLock lock(&instance_mutex_);
  EnsureStartedLocked(GlobalForkserverStartMode::kOnDemand);
  return instance_->fork_client_.pid();
}

bool GlobalForkClient::IsStarted() {
  absl::ReaderMutexLock lock(&instance_mutex_);
  return instance_ != nullptr;
}
}  // namespace sandbox2
<commit_msg>Fix restarting global forkserver<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Implementation of the sandbox2::ForkServer class.

#include "sandboxed_api/sandbox2/global_forkclient.h"

#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <syscall.h>
#include <unistd.h>

#include <csignal>
#include <cstdlib>
#include <string>
#include <vector>

#include <glog/logging.h>
#include "sandboxed_api/util/flag.h"
#include "absl/memory/memory.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "sandboxed_api/embed_file.h"
#include "sandboxed_api/sandbox2/comms.h"
#include "sandboxed_api/sandbox2/fork_client.h"
#include "sandboxed_api/sandbox2/forkserver_bin_embed.h"
#include "sandboxed_api/sandbox2/util.h"
#include "sandboxed_api/util/fileops.h"
#include "sandboxed_api/util/raw_logging.h"
#include "sandboxed_api/util/strerror.h"

namespace sandbox2 {

namespace file_util = ::sapi::file_util;

bool AbslParseFlag(absl::string_view text, GlobalForkserverStartModeSet* out,
                   std::string* error) {
  *out = {};
  if (text == "never") {
    return true;
  }
  for (absl::string_view mode : absl::StrSplit(text, ',')) {
    mode = absl::StripAsciiWhitespace(mode);
    if (mode == "ondemand") {
      *out |= GlobalForkserverStartMode::kOnDemand;
    } else {
      *error = absl::StrCat("Invalid forkserver start mode: ", mode);
      return false;
    }
  }
  return true;
}

namespace {
std::string ToString(GlobalForkserverStartMode mode) {
  switch (mode) {
    case GlobalForkserverStartMode::kOnDemand:
      return "ondemand";
    default:
      return "unknown";
  }
}
bool ValidateStartMode(const char*, const std::string& flag) {
  GlobalForkserverStartModeSet unused;
  std::string error;
  if (!AbslParseFlag(flag, &unused, &error)) {
    SAPI_RAW_LOG(ERROR, "%s", error.c_str());
    return false;
  }
  return true;
}
}  // namespace

std::string AbslUnparseFlag(GlobalForkserverStartModeSet in) {
  std::vector<std::string> str_modes;
  for (size_t i = 0; i < GlobalForkserverStartModeSet::kSize; ++i) {
    auto mode = static_cast<GlobalForkserverStartMode>(i);
    if (in.contains(mode)) {
      str_modes.push_back(ToString(mode));
    }
  }
  if (str_modes.empty()) {
    return "never";
  }
  return absl::StrJoin(str_modes, ",");
}

}  // namespace sandbox2

ABSL_FLAG(string, sandbox2_forkserver_start_mode, "ondemand",
          "When Sandbox2 Forkserver process should be started");
DEFINE_validator(sandbox2_forkserver_start_mode, &sandbox2::ValidateStartMode);

namespace sandbox2 {

namespace {

GlobalForkserverStartModeSet GetForkserverStartMode() {
  GlobalForkserverStartModeSet rv;
  std::string error;
  CHECK(AbslParseFlag(absl::GetFlag(FLAGS_sandbox2_forkserver_start_mode), &rv,
                      &error));
  return rv;
}

std::unique_ptr<GlobalForkClient> StartGlobalForkServer() {
  file_util::fileops::FDCloser exec_fd(
      sapi::EmbedFile::GetEmbedFileSingleton()->GetDupFdForFileToc(
          forkserver_bin_embed_create()));
  SAPI_RAW_CHECK(exec_fd.get() >= 0, "Getting FD for init binary failed");

  std::string proc_name = "S2-FORK-SERV";

  int sv[2];
  SAPI_RAW_CHECK(socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) != -1,
                 "creating socket pair");

  // Fork the fork-server, and clean-up the resources (close remote sockets).
  pid_t pid = util::ForkWithFlags(SIGCHLD);
  SAPI_RAW_PCHECK(pid != -1, "during fork");

  // Child.
  if (pid == 0) {
    // Move the comms FD to the proper, expected FD number.
    // The new FD will not be CLOEXEC, which is what we want.
    dup2(sv[0], Comms::kSandbox2ClientCommsFD);

    char* const args[] = {proc_name.data(), nullptr};
    char* const envp[] = {nullptr};
    syscall(__NR_execveat, exec_fd.get(), "", args, envp, AT_EMPTY_PATH);
    SAPI_RAW_PLOG(FATAL, "Could not launch forkserver binary");
    abort();
  }

  close(sv[0]);
  return absl::make_unique<GlobalForkClient>(sv[1], pid);
}

}  // namespace

absl::Mutex GlobalForkClient::instance_mutex_(absl::kConstInit);
GlobalForkClient* GlobalForkClient::instance_ = nullptr;

void GlobalForkClient::EnsureStarted(GlobalForkserverStartMode mode) {
  absl::MutexLock lock(&instance_mutex_);
  EnsureStartedLocked(mode);
}

void GlobalForkClient::EnsureStartedLocked(GlobalForkserverStartMode mode) {
  if (!instance_) {
    SAPI_RAW_CHECK(
        !getenv(kForkServerDisableEnv),
        absl::StrCat("Start of the Global Fork-Server prevented by the '",
                     kForkServerDisableEnv, "' environment variable present")
            .c_str());
    SAPI_RAW_CHECK(
        GetForkserverStartMode().contains(mode),
        "Start of the Global Fork-Server prevented by commandline flag");
    instance_ = StartGlobalForkServer().release();
  }
  SAPI_RAW_CHECK(instance_ != nullptr, "global fork client not initialized");
}

void GlobalForkClient::ForceStart() {
  absl::MutexLock lock(&GlobalForkClient::instance_mutex_);
  SAPI_RAW_CHECK(instance_ == nullptr,
                 "A force start requested when the Global Fork-Server was "
                 "already running");
  instance_ = StartGlobalForkServer().release();
}

void GlobalForkClient::Shutdown() {
  absl::MutexLock lock(&GlobalForkClient::instance_mutex_);
  delete instance_;
  instance_ = nullptr;
}

pid_t GlobalForkClient::SendRequest(const ForkRequest& request, int exec_fd,
                                    int comms_fd, int user_ns_fd,
                                    pid_t* init_pid) {
  absl::MutexLock lock(&GlobalForkClient::instance_mutex_);
  EnsureStartedLocked(GlobalForkserverStartMode::kOnDemand);
  pid_t pid = instance_->fork_client_.SendRequest(request, exec_fd, comms_fd,
                                                  user_ns_fd, init_pid);
  if (instance_->comms_.IsTerminated()) {
    LOG(ERROR) << "Global forkserver connection terminated";
  }
  return pid;
}

pid_t GlobalForkClient::GetPid() {
  absl::MutexLock lock(&instance_mutex_);
  EnsureStartedLocked(GlobalForkserverStartMode::kOnDemand);
  return instance_->fork_client_.pid();
}

bool GlobalForkClient::IsStarted() {
  absl::ReaderMutexLock lock(&instance_mutex_);
  return instance_ != nullptr;
}
}  // namespace sandbox2
<|endoftext|>


<commit_before><commit_msg>Deal with unencrypted HPI files.<commit_after><|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2012 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "renderwidget.h"

#include <QResizeEvent>
#include <QDebug>
#include <QVector3D>
#include <QMatrix4x4>

#include "manager.h"
#include "outputsurface.h"
#include "backend.h"

#include "shader.h"
#include "meshdata.h"

using namespace GluonGraphics;

class RenderWidget::Private
{
    public:
        Private() : surface( 0 ) { }

        OutputSurface* surface;

        Shader* shader;
        MeshData* data;
};

RenderWidget::RenderWidget( QWidget* parent, Qt::WindowFlags f ) :
    QWidget( parent, f ), d( new Private )
{
    setAttribute( Qt::WA_PaintOnScreen );
    setAttribute( Qt::WA_OpaquePaintEvent );
}

RenderWidget::~RenderWidget()
{
    delete d->surface;
    delete d;
}

void RenderWidget::paintEvent( QPaintEvent* event )
{
    if( !d->surface )
    {
        if( !Manager::instance()->backend()->initialize( this ) )
            qFatal( Manager::instance()->backend()->errorString().toUtf8() );

        Manager::instance()->initialize();
        d->surface = Manager::instance()->backend()->createOutputSurface( this );
        d->surface->setSize( width(), height() );

        d->surface->createDebug();
    }

    d->surface->renderContents();
}

void RenderWidget::resizeEvent( QResizeEvent* event )
{
    if( d->surface )
        d->surface->setSize( event->size().width(), event->size().height() );
    QWidget::resizeEvent( event );
}

#include "renderwidget.moc"
<commit_msg>Graphics: Ensure we initialize everything as soon as possible.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2012 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "renderwidget.h"

#include <QResizeEvent>
#include <QDebug>
#include <QVector3D>
#include <QMatrix4x4>

#include "manager.h"
#include "outputsurface.h"
#include "backend.h"

#include "shader.h"
#include "meshdata.h"

using namespace GluonGraphics;

class RenderWidget::Private
{
    public:
        Private() : surface( 0 ) { }

        OutputSurface* surface;

        Shader* shader;
        MeshData* data;
};

RenderWidget::RenderWidget( QWidget* parent, Qt::WindowFlags f ) :
    QWidget( parent, f ), d( new Private )
{
    setAttribute( Qt::WA_PaintOnScreen );
    setAttribute( Qt::WA_OpaquePaintEvent );

    if( !Manager::instance()->backend()->initialize( this ) )
        qFatal( Manager::instance()->backend()->errorString().toUtf8() );
}

RenderWidget::~RenderWidget()
{
    delete d->surface;
    delete d;
}

void RenderWidget::paintEvent( QPaintEvent* event )
{
    if( !d->surface )
    {
        Manager::instance()->initialize();
        d->surface = Manager::instance()->backend()->createOutputSurface( this );
        d->surface->setSize( width(), height() );
    }

    d->surface->renderContents();
}

void RenderWidget::resizeEvent( QResizeEvent* event )
{
    if( d->surface )
        d->surface->setSize( event->size().width(), event->size().height() );
    QWidget::resizeEvent( event );
}

#include "renderwidget.moc"
<|endoftext|>


<commit_before>//
// Name:     app.cpp
// Purpose:  The application class for a wxWindows application.
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "vtlib/vtlib.h"
#include "vtlib/core/Terrain.h"
#include "../TerrainSceneWP.h"
#include "../Enviro.h"		// for g_App
#include "../Options.h"

#include "app.h"
#include "frame.h"
#include "StartupDlg.h"

static void Args(int argc, char **argv)
{
   return;
}

IMPLEMENT_APP(vtApp)

//
// Initialize the app object
//
bool vtApp::OnInit(void)
{
	Args(argc, argv);

	g_Options.Read("Enviro.ini");
	g_App.LoadTerrainDescriptions();

	//
	// Create and show the Startup Dialog
	//
	StartupDlg StartDlg(NULL, -1, "Enviro Startup", wxDefaultPosition);
	StartDlg.GetOptionsFrom(g_Options);
	StartDlg.CenterOnParent();
	int result = StartDlg.ShowModal();
	if (result == wxID_CANCEL)
		return FALSE;

	StartDlg.PutOptionsTo(g_Options);
	g_Options.Write();

	//
	// Create the main frame window
	//
	wxString title = "VTP Enviro ";
#if VTLIB_DSM
	title += "DSM";
#elif VTLIB_OSG
	title += "OSG";
#elif VTLIB_SGL
	title += "SGL";
#elif VTLIB_SSG
	title += "SSG";
#endif
	vtFrame *frame = new vtFrame(NULL, title,
		wxPoint(50, 50), wxSize(800, 600));

	vtGetScene()->Init();
	g_App.StartControlEngine(NULL);

	if (g_Options.m_bFullscreen)
		frame->SetFullScreen(true);

	return TRUE;
}

//
// ask the user to choose from a list of known terrain
//
bool AskForTerrainName(wxWindow *pParent, wxString &str)
{
    vtTerrain *pTerr;

	// count them
	int num = 0;
    for (pTerr = GetTerrainScene().m_pFirstTerrain; pTerr; pTerr=pTerr->GetNext())
		num++;

	// get their names
	wxString *choices = new wxString[num];
	num = 0;
	int first_idx = 0;
	for (pTerr = GetTerrainScene().m_pFirstTerrain; pTerr; pTerr=pTerr->GetNext())
	{
		choices[num] = (const char *)(pTerr->GetName());
		if (str == choices[num]) first_idx = num;
		num++;
	}

	if (!num)
	{
		wxMessageBox("No terrains found (datapath/Terrains/*.ini)");
		return false;
	}

	wxSingleChoiceDialog dlg(pParent, "Please choose a terrain",
		"Select Terrain", num, choices);
	dlg.SetSelection(first_idx);
	delete [] choices;
	if (dlg.ShowModal() == wxID_OK)
	{
		str = dlg.GetStringSelection();
		return true;
	}
	else
		return false;
}

<commit_msg>cosmetic change<commit_after>//
// Name:     app.cpp
// Purpose:  The application class for a wxWindows application.
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "vtlib/vtlib.h"
#include "vtlib/core/Terrain.h"
#include "../TerrainSceneWP.h"
#include "../Enviro.h"		// for g_App
#include "../Options.h"

#include "app.h"
#include "frame.h"
#include "StartupDlg.h"

static void Args(int argc, char **argv)
{
   return;
}

IMPLEMENT_APP(vtApp)

//
// Initialize the app object
//
bool vtApp::OnInit()
{
	Args(argc, argv);

	g_Options.Read("Enviro.ini");
	g_App.LoadTerrainDescriptions();

	//
	// Create and show the Startup Dialog
	//
	StartupDlg StartDlg(NULL, -1, "Enviro Startup", wxDefaultPosition);
	StartDlg.GetOptionsFrom(g_Options);
	StartDlg.CenterOnParent();
	int result = StartDlg.ShowModal();
	if (result == wxID_CANCEL)
		return FALSE;

	StartDlg.PutOptionsTo(g_Options);
	g_Options.Write();

	//
	// Create the main frame window
	//
	wxString title = "VTP Enviro ";
#if VTLIB_DSM
	title += "DSM";
#elif VTLIB_OSG
	title += "OSG";
#elif VTLIB_SGL
	title += "SGL";
#elif VTLIB_SSG
	title += "SSG";
#endif
	vtFrame *frame = new vtFrame(NULL, title,
		wxPoint(50, 50), wxSize(800, 600));

	vtGetScene()->Init();
	g_App.StartControlEngine(NULL);

	if (g_Options.m_bFullscreen)
		frame->SetFullScreen(true);

	return TRUE;
}

//
// ask the user to choose from a list of known terrain
//
bool AskForTerrainName(wxWindow *pParent, wxString &str)
{
    vtTerrain *pTerr;

	// count them
	int num = 0;
    for (pTerr = GetTerrainScene().m_pFirstTerrain; pTerr; pTerr=pTerr->GetNext())
		num++;

	// get their names
	wxString *choices = new wxString[num];
	num = 0;
	int first_idx = 0;
	for (pTerr = GetTerrainScene().m_pFirstTerrain; pTerr; pTerr=pTerr->GetNext())
	{
		choices[num] = (const char *)(pTerr->GetName());
		if (str == choices[num]) first_idx = num;
		num++;
	}

	if (!num)
	{
		wxMessageBox("No terrains found (datapath/Terrains/*.ini)");
		return false;
	}

	wxSingleChoiceDialog dlg(pParent, "Please choose a terrain",
		"Select Terrain", num, choices);
	dlg.SetSelection(first_idx);
	delete [] choices;
	if (dlg.ShowModal() == wxID_OK)
	{
		str = dlg.GetStringSelection();
		return true;
	}
	else
		return false;
}

<|endoftext|>


<commit_before>
#pragma XOD dirtieness disable

struct State {
};

{{ GENERATED_CODE }}

void evaluate(Context ctx) {
    auto x = getValue<input_IN>(ctx);
    emitValue<output_OUT>(ctx, abs(x));
}
<commit_msg>fix(stdlib): make `xod/math/abs` correctly handle values between -1 and 0 on esp8266<commit_after>
#pragma XOD dirtieness disable

struct State {
};

{{ GENERATED_CODE }}

void evaluate(Context ctx) {
    auto x = getValue<input_IN>(ctx);
    emitValue<output_OUT>(ctx, x > 0 ? x : -x);
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project.

    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

    This library is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 2.1 or 3 of the License.

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

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

#include "videowidget.h"
#include "x11renderer.h"

#ifndef Q_WS_QWS

#include "common.h"
#include "backend.h"
#include "mediaobject.h"
#include "message.h"
#include <QtGui/QPalette>
#include <QtGui/QApplication>
#include <QtGui/QPainter>
#include <X11/Xlib.h>
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <gst/interfaces/propertyprobe.h>

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace Gstreamer
{

class OverlayWidget : public QWidget
{
public:
    OverlayWidget(VideoWidget *videoWidget, X11Renderer *renderer) :
                  QWidget(videoWidget),
                  m_videoWidget(videoWidget),
                  m_renderer(renderer) { }
    void paintEvent(QPaintEvent *) {
        Phonon::State state = m_videoWidget->root() ? m_videoWidget->root()->state() : Phonon::LoadingState;
        if (state == Phonon::PlayingState || state == Phonon::PausedState) {
            m_renderer->windowExposed();
        } else {
            QPainter painter(this);
            painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
        }
    }
private:
    VideoWidget *m_videoWidget;
    X11Renderer *m_renderer;
};

X11Renderer::X11Renderer(VideoWidget *videoWidget)
        : AbstractRenderer(videoWidget)
{
    m_renderWidget = new OverlayWidget(videoWidget, this);
    videoWidget->backend()->logMessage("Creating X11 overlay renderer");
    QPalette palette;
    palette.setColor(QPalette::Background, Qt::black);
    m_videoWidget->setPalette(palette);
    m_videoWidget->setAutoFillBackground(true);
    m_renderWidget->setMouseTracking(true);
    m_videoSink = createVideoSink();
    aspectRatioChanged(videoWidget->aspectRatio());
    setOverlay();
}

X11Renderer::~X11Renderer()
{
    m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, false);
    m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, false);
    delete m_renderWidget;
}

GstElement* X11Renderer::createVideoSink()
{
    GstElement *videoSink = gst_element_factory_make ("xvimagesink", NULL);
    if (videoSink) {
        // Check if the xv sink is usable
        if (gst_element_set_state(videoSink, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
            gst_object_unref(GST_OBJECT(videoSink));
            videoSink = 0;
        } else {
            // Note that this should not really be necessary as these are
            // default values, though under certain conditions values are retained
            // even between application instances. (reproducible on 0.10.16/Gutsy)
            g_object_set(G_OBJECT(videoSink), "brightness", 0, (const char*)NULL);
            g_object_set(G_OBJECT(videoSink), "contrast", 0, (const char*)NULL);
            g_object_set(G_OBJECT(videoSink), "hue", 0, (const char*)NULL);
            g_object_set(G_OBJECT(videoSink), "saturation", 0, (const char*)NULL);
        }
    }
    QByteArray tegraEnv = qgetenv("TEGRA_GST_OPENMAX");
    if(!tegraEnv.isEmpty())
    {
        videoSink = gst_element_factory_make ("nv_gl_videosink", NULL);
    }
    if (!videoSink)
        videoSink = gst_element_factory_make ("ximagesink", NULL);

    gst_object_ref (GST_OBJECT (videoSink)); //Take ownership
    gst_object_sink (GST_OBJECT (videoSink));

    return videoSink;
}

void X11Renderer::handleMediaNodeEvent(const MediaNodeEvent *event)
{
    switch (event->type()) {
    case MediaNodeEvent::SourceChanged:
        setOverlay(); // We need to do this whenever the pipeline is reset
        break;        // otherwise the videosink will open in its own window
    default:
        break;
    }
}

void X11Renderer::aspectRatioChanged(Phonon::VideoWidget::AspectRatio)
{
    if (m_renderWidget) {
        m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
    }
}

void X11Renderer::scaleModeChanged(Phonon::VideoWidget::ScaleMode)
{
    if (m_renderWidget) {
        m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
    }
}

void X11Renderer::movieSizeChanged(const QSize &movieSize)
{
    Q_UNUSED(movieSize);

    if (m_renderWidget) {
        m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
    }
}

bool X11Renderer::eventFilter(QEvent *e)
{
    if (e->type() == QEvent::Show) {
        // Setting these values ensures smooth resizing since it
        // will prevent the system from clearing the background
        m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, true);
        m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, true);
        setOverlay();
    } else if (e->type() == QEvent::Resize) {
        // This is a workaround for missing background repaints
        // when reducing window size
        m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
        windowExposed();
    }
    return false;
}

void X11Renderer::handlePaint(QPaintEvent *)
{
    QPainter painter(m_videoWidget);
    painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
}

void X11Renderer::setOverlay()
{
    if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
        WId windowId = m_renderWidget->winId();
        // Even if we have created a winId at this point, other X applications
        // need to be aware of it.
        QApplication::syncX();
        gst_x_overlay_set_xwindow_id ( GST_X_OVERLAY(m_videoSink) ,  windowId );
    }
    windowExposed();
    m_overlaySet = true;
}

void X11Renderer::windowExposed()
{
    QApplication::syncX();
    if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
        gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
}

}
} //namespace Phonon::Gstreamer

QT_END_NAMESPACE

#endif // Q_WS_QWS
<commit_msg>gst_x_overlay_set_xwindow_id is deprecated<commit_after>/*  This file is part of the KDE project.

    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

    This library is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 2.1 or 3 of the License.

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

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

#include "videowidget.h"
#include "x11renderer.h"

#ifndef Q_WS_QWS

#include "common.h"
#include "backend.h"
#include "mediaobject.h"
#include "message.h"
#include <QtGui/QPalette>
#include <QtGui/QApplication>
#include <QtGui/QPainter>
#include <X11/Xlib.h>
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <gst/interfaces/propertyprobe.h>

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace Gstreamer
{

class OverlayWidget : public QWidget
{
public:
    OverlayWidget(VideoWidget *videoWidget, X11Renderer *renderer) :
                  QWidget(videoWidget),
                  m_videoWidget(videoWidget),
                  m_renderer(renderer) { }
    void paintEvent(QPaintEvent *) {
        Phonon::State state = m_videoWidget->root() ? m_videoWidget->root()->state() : Phonon::LoadingState;
        if (state == Phonon::PlayingState || state == Phonon::PausedState) {
            m_renderer->windowExposed();
        } else {
            QPainter painter(this);
            painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
        }
    }
private:
    VideoWidget *m_videoWidget;
    X11Renderer *m_renderer;
};

X11Renderer::X11Renderer(VideoWidget *videoWidget)
        : AbstractRenderer(videoWidget)
{
    m_renderWidget = new OverlayWidget(videoWidget, this);
    videoWidget->backend()->logMessage("Creating X11 overlay renderer");
    QPalette palette;
    palette.setColor(QPalette::Background, Qt::black);
    m_videoWidget->setPalette(palette);
    m_videoWidget->setAutoFillBackground(true);
    m_renderWidget->setMouseTracking(true);
    m_videoSink = createVideoSink();
    aspectRatioChanged(videoWidget->aspectRatio());
    setOverlay();
}

X11Renderer::~X11Renderer()
{
    m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, false);
    m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, false);
    delete m_renderWidget;
}

GstElement* X11Renderer::createVideoSink()
{
    GstElement *videoSink = gst_element_factory_make ("xvimagesink", NULL);
    if (videoSink) {
        // Check if the xv sink is usable
        if (gst_element_set_state(videoSink, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
            gst_object_unref(GST_OBJECT(videoSink));
            videoSink = 0;
        } else {
            // Note that this should not really be necessary as these are
            // default values, though under certain conditions values are retained
            // even between application instances. (reproducible on 0.10.16/Gutsy)
            g_object_set(G_OBJECT(videoSink), "brightness", 0, (const char*)NULL);
            g_object_set(G_OBJECT(videoSink), "contrast", 0, (const char*)NULL);
            g_object_set(G_OBJECT(videoSink), "hue", 0, (const char*)NULL);
            g_object_set(G_OBJECT(videoSink), "saturation", 0, (const char*)NULL);
        }
    }
    QByteArray tegraEnv = qgetenv("TEGRA_GST_OPENMAX");
    if(!tegraEnv.isEmpty())
    {
        videoSink = gst_element_factory_make ("nv_gl_videosink", NULL);
    }
    if (!videoSink)
        videoSink = gst_element_factory_make ("ximagesink", NULL);

    gst_object_ref (GST_OBJECT (videoSink)); //Take ownership
    gst_object_sink (GST_OBJECT (videoSink));

    return videoSink;
}

void X11Renderer::handleMediaNodeEvent(const MediaNodeEvent *event)
{
    switch (event->type()) {
    case MediaNodeEvent::SourceChanged:
        setOverlay(); // We need to do this whenever the pipeline is reset
        break;        // otherwise the videosink will open in its own window
    default:
        break;
    }
}

void X11Renderer::aspectRatioChanged(Phonon::VideoWidget::AspectRatio)
{
    if (m_renderWidget) {
        m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
    }
}

void X11Renderer::scaleModeChanged(Phonon::VideoWidget::ScaleMode)
{
    if (m_renderWidget) {
        m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
    }
}

void X11Renderer::movieSizeChanged(const QSize &movieSize)
{
    Q_UNUSED(movieSize);

    if (m_renderWidget) {
        m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
    }
}

bool X11Renderer::eventFilter(QEvent *e)
{
    if (e->type() == QEvent::Show) {
        // Setting these values ensures smooth resizing since it
        // will prevent the system from clearing the background
        m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, true);
        m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, true);
        setOverlay();
    } else if (e->type() == QEvent::Resize) {
        // This is a workaround for missing background repaints
        // when reducing window size
        m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
        windowExposed();
    }
    return false;
}

void X11Renderer::handlePaint(QPaintEvent *)
{
    QPainter painter(m_videoWidget);
    painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
}

void X11Renderer::setOverlay()
{
    if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
        WId windowId = m_renderWidget->winId();
        // Even if we have created a winId at this point, other X applications
        // need to be aware of it.
        QApplication::syncX();
        gst_x_overlay_set_window_handle( GST_X_OVERLAY(m_videoSink), windowId );
    }
    windowExposed();
    m_overlaySet = true;
}

void X11Renderer::windowExposed()
{
    QApplication::syncX();
    if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
        gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
}

}
} //namespace Phonon::Gstreamer

QT_END_NAMESPACE

#endif // Q_WS_QWS
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <map>

#include "timer.h"
#include "crp.h"
#include "sampler.h"
#include "tdict.h"
Dict TD::dict_;
std::string TD::empty = "";
std::string TD::space = " ";

using namespace std;

void ShowTopWords(const map<WordID, int>& counts) {
  multimap<int, WordID> ms;
  for (map<WordID,int>::const_iterator it = counts.begin(); it != counts.end(); ++it)
    ms.insert(make_pair(it->second, it->first));
  int cc = 0;
  for (multimap<int, WordID>::reverse_iterator it = ms.rbegin(); it != ms.rend(); ++it) {
    cerr << it->first << ':' << TD::Convert(it->second) << " ";
    ++cc;
    if (cc==12) break;
  }
  cerr << endl;
}

int main(int argc, char** argv) {
  if (argc != 3) {
    cerr << "Usage: " << argv[0] << " num-classes num-samples\n";
    return 1;
  }
  const int num_classes = atoi(argv[1]);
  const int num_iterations = atoi(argv[2]);
  const int burnin_size = num_iterations * 0.666;
  if (num_classes < 2) {
    cerr << "Must request more than 1 class\n";
    return 1;
  }
  if (num_iterations < 5) {
    cerr << "Must request more than 5 iterations\n";
    return 1;
  }
  cerr << "CLASSES: " << num_classes << endl;
  char* buf = new char[800000];
  vector<vector<int> > wji;   // w[j][i] - observed word i of doc j
  vector<vector<int> > zji;   // z[j][i] - topic assignment for word i of doc j
  cerr << "READING DOCUMENTS\n";
  while(cin) {
    cin.getline(buf, 800000);
    if (buf[0] == 0) continue;
    wji.push_back(vector<WordID>());
    TD::ConvertSentence(buf, &wji.back());
  }
  cerr << "READ " << wji.size() << " DOCUMENTS\n";
  MT19937 rng;
  cerr << "INITIALIZING RANDOM TOPIC ASSIGNMENTS\n";
  zji.resize(wji.size());
  double beta = 0.01;
  double alpha = 0.001;
  vector<CRP<int> > dr(zji.size(), CRP<int>(beta)); // dr[i] describes the probability of using a topic in document i
  vector<CRP<int> > wr(num_classes, CRP<int>(alpha)); // wr[k] describes the probability of generating a word in topic k
      int random_topic = rng.next() * num_classes;
  for (int j = 0; j < zji.size(); ++j) {
    const size_t num_words = wji[j].size();
    vector<int>& zj = zji[j];
    const vector<int>& wj = wji[j];
    zj.resize(num_words);
    for (int i = 0; i < num_words; ++i) {
      if (random_topic == num_classes) { --random_topic; }
      zj[i] = random_topic;
      const int word = wj[i];
      dr[j].increment(random_topic);
      wr[random_topic].increment(word);
    }
  }
  cerr << "SAMPLING\n";
  vector<map<WordID, int> > t2w(num_classes);
  bool needline = false;
  Timer timer;
  SampleSet ss;
  ss.resize(num_classes);
  double total_time = 0;
  for (int iter = 0; iter < num_iterations; ++iter) {
    if (iter && iter % 10 == 0) {
      total_time += timer.Elapsed();
      timer.Reset();
      cerr << '.'; needline=true;
      prob_t lh = prob_t::One();
      for (int j = 0; j < zji.size(); ++j) {
        const size_t num_words = wji[j].size();
        vector<int>& zj = zji[j];
        const vector<int>& wj = wji[j];
        for (int i = 0; i < num_words; ++i) {
          const int word = wj[i];
          const int cur_topic = zj[i];
          lh *= dr[j].prob(cur_topic);
          lh *= wr[cur_topic].prob(word);
          if (iter > burnin_size) {
            ++t2w[cur_topic][word];
          }
        }
      }
      if (iter && iter % 200 == 0) { cerr << " [ITER=" << iter << " SEC/SAMPLE=" << (total_time / 200) << " LLH=" << log(lh) << "]\n"; needline=false; total_time=0; }
      //cerr << "ITERATION " << iter << " LOG LIKELIHOOD: " << log(lh) << endl;
    }
    for (int j = 0; j < zji.size(); ++j) {
      const size_t num_words = wji[j].size();
      vector<int>& zj = zji[j];
      const vector<int>& wj = wji[j];
      for (int i = 0; i < num_words; ++i) {
        const int word = wj[i];
        const int cur_topic = zj[i];
        dr[j].decrement(cur_topic);
        wr[cur_topic].decrement(word);

        for (int k = 0; k < num_classes; ++k) {
          ss[k]= dr[j].prob(k) * wr[k].prob(word);
        }
        const int new_topic = rng.SelectSample(ss);
        dr[j].increment(new_topic);
        wr[new_topic].increment(word);
        zj[i] = new_topic;
      }
    }
  }
  if (needline) cerr << endl;
#if 0
  for (int j = 0; j < zji.size(); ++j) {
    const size_t num_words = wji[j].size();
    vector<int>& zj = zji[j];
    const vector<int>& wj = wji[j];
    zj.resize(num_words);
    for (int i = 0; i < num_words; ++i) {
      cout << TD::Convert(wj[i]) << '(' << zj[i] << ") ";
    }
    cout << endl;
  }
#endif
  for (int i = 0; i < num_classes; ++i) {
    cerr << "---------------------------------\n";
    ShowTopWords(t2w[i]);
  }
  return 0;
}

<commit_msg>clean up<commit_after>#include <iostream>
#include <vector>
#include <map>

#include "timer.h"
#include "crp.h"
#include "sampler.h"
#include "tdict.h"
Dict TD::dict_;
std::string TD::empty = "";
std::string TD::space = " ";
const size_t MAX_DOC_LEN_CHARS = 1000000;

using namespace std;

void ShowTopWordsForTopic(const map<WordID, int>& counts) {
  multimap<int, WordID> ms;
  for (map<WordID,int>::const_iterator it = counts.begin(); it != counts.end(); ++it)
    ms.insert(make_pair(it->second, it->first));
  int cc = 0;
  for (multimap<int, WordID>::reverse_iterator it = ms.rbegin(); it != ms.rend(); ++it) {
    cerr << it->first << ':' << TD::Convert(it->second) << " ";
    ++cc;
    if (cc==12) break;
  }
  cerr << endl;
}

int main(int argc, char** argv) {
  if (argc != 3) {
    cerr << "Usage: " << argv[0] << " num-classes num-samples\n";
    return 1;
  }
  const int num_classes = atoi(argv[1]);
  const int num_iterations = atoi(argv[2]);
  const int burnin_size = num_iterations * 0.666;
  if (num_classes < 2) {
    cerr << "Must request more than 1 class\n";
    return 1;
  }
  if (num_iterations < 5) {
    cerr << "Must request more than 5 iterations\n";
    return 1;
  }
  cerr << "CLASSES: " << num_classes << endl;
  char* buf = new char[MAX_DOC_LEN_CHARS];
  vector<vector<int> > wji;   // w[j][i] - observed word i of doc j
  vector<vector<int> > zji;   // z[j][i] - topic assignment for word i of doc j
  cerr << "READING DOCUMENTS\n";
  while(cin) {
    cin.getline(buf, MAX_DOC_LEN_CHARS);
    if (buf[0] == 0) continue;
    wji.push_back(vector<WordID>());
    TD::ConvertSentence(buf, &wji.back());
  }
  cerr << "READ " << wji.size() << " DOCUMENTS\n";
  MT19937 rng;
  cerr << "INITIALIZING RANDOM TOPIC ASSIGNMENTS\n";
  zji.resize(wji.size());
  double beta = 0.01;
  double alpha = 0.001;
  vector<CRP<int> > dr(zji.size(), CRP<int>(beta)); // dr[i] describes the probability of using a topic in document i
  vector<CRP<int> > wr(num_classes, CRP<int>(alpha)); // wr[k] describes the probability of generating a word in topic k
      int random_topic = rng.next() * num_classes;
  for (int j = 0; j < zji.size(); ++j) {
    const size_t num_words = wji[j].size();
    vector<int>& zj = zji[j];
    const vector<int>& wj = wji[j];
    zj.resize(num_words);
    for (int i = 0; i < num_words; ++i) {
      if (random_topic == num_classes) { --random_topic; }
      zj[i] = random_topic;
      const int word = wj[i];
      dr[j].increment(random_topic);
      wr[random_topic].increment(word);
    }
  }
  cerr << "SAMPLING\n";
  vector<map<WordID, int> > t2w(num_classes);
  Timer timer;
  SampleSet ss;
  ss.resize(num_classes);
  double total_time = 0;
  for (int iter = 0; iter < num_iterations; ++iter) {
    cerr << '.';
    if (iter && iter % 10 == 0) {
      total_time += timer.Elapsed();
      timer.Reset();
      prob_t lh = prob_t::One();
      for (int j = 0; j < zji.size(); ++j) {
        const size_t num_words = wji[j].size();
        vector<int>& zj = zji[j];
        const vector<int>& wj = wji[j];
        for (int i = 0; i < num_words; ++i) {
          const int word = wj[i];
          const int cur_topic = zj[i];
          lh *= dr[j].prob(cur_topic);
          lh *= wr[cur_topic].prob(word);
          if (iter > burnin_size) {
            ++t2w[cur_topic][word];
          }
        }
      }
      if (iter && iter % 40 == 0) { cerr << " [ITER=" << iter << " SEC/SAMPLE=" << (total_time / 40) << " LLH=" << log(lh) << "]\n"; total_time=0; }
      //cerr << "ITERATION " << iter << " LOG LIKELIHOOD: " << log(lh) << endl;
    }
    for (int j = 0; j < zji.size(); ++j) {
      const size_t num_words = wji[j].size();
      vector<int>& zj = zji[j];
      const vector<int>& wj = wji[j];
      for (int i = 0; i < num_words; ++i) {
        const int word = wj[i];
        const int cur_topic = zj[i];
        dr[j].decrement(cur_topic);
        wr[cur_topic].decrement(word);

        for (int k = 0; k < num_classes; ++k) {
          ss[k]= dr[j].prob(k) * wr[k].prob(word);
        }
        const int new_topic = rng.SelectSample(ss);
        dr[j].increment(new_topic);
        wr[new_topic].increment(word);
        zj[i] = new_topic;
      }
    }
  }
  for (int i = 0; i < num_classes; ++i) {
    cerr << "---------------------------------\n";
    ShowTopWordsForTopic(t2w[i]);
  }
  return 0;
}

<|endoftext|>


<commit_before>// Config file test for MUON spectormeter
// Remember to define the directory and option
// gAlice->SetConfigFunction("Config('$HOME','box');");

void Config(char directory[100]="", char option[6]="param")
{
  //
  // Config file for MUON test
  //

  //=====================================================================
  //  Libraries required by geant321
  gSystem->Load("libgeant321.so");
  new TGeant3TGeo("C++ Interface to Geant3");
  //=======================================================================
  //  Create the output file
  Text_t filename[100];
  sprintf(filename,"%sgalice.root",directory);
  cout << ">>> Output file is " << filename << endl;
  cout << ">>> Config.C: Creating Run Loader ..."<<endl;
  AliRunLoader* rl=0x0;
  rl = AliRunLoader::Open(
	filename, AliConfig::GetDefaultEventFolderName(), "recreate");
  if (rl == 0x0) {
    gAlice->Fatal("Config.C","Can not instatiate the Run Loader");
    return;
  }
  rl->SetCompressionLevel(2);
  rl->SetNumberOfEventsPerFile(100);
  gAlice->SetRunLoader(rl);

  //AliLog::SetModuleDebugLevel("MUON", 1);

  //=======================================================================
  // Set External decayer
  TVirtualMCDecayer *decayer = new AliDecayerPythia();
  decayer->SetForceDecay(kAll);
  decayer->Init();
  gMC->SetExternalDecayer(decayer);

  //
  //=======================================================================
  // ******* GEANT STEERING parameters FOR ALICE SIMULATION *******
    gMC->SetProcess("DCAY",1);
    gMC->SetProcess("PAIR",1);
    gMC->SetProcess("COMP",1);
    gMC->SetProcess("PHOT",1);
    gMC->SetProcess("PFIS",0);
    gMC->SetProcess("DRAY",0);
    gMC->SetProcess("ANNI",1);
    gMC->SetProcess("BREM",1);
    gMC->SetProcess("MUNU",1);
    gMC->SetProcess("CKOV",1);
    gMC->SetProcess("HADR",1);
    gMC->SetProcess("LOSS",2);
    gMC->SetProcess("MULS",1);
    gMC->SetProcess("RAYL",1);

    Float_t cut = 1.e-3;        // 1MeV cut by default
    Float_t tofmax = 1.e10;

    gMC->SetCut("CUTGAM", cut);
    gMC->SetCut("CUTELE", cut);
    gMC->SetCut("CUTNEU", cut);
    gMC->SetCut("CUTHAD", cut);
    gMC->SetCut("CUTMUO", cut);
    gMC->SetCut("BCUTE",  cut);
    gMC->SetCut("BCUTM",  cut);
    gMC->SetCut("DCUTE",  cut);
    gMC->SetCut("DCUTM",  cut);
    gMC->SetCut("PPCUTM", cut);
    gMC->SetCut("TOFMAX", tofmax);
  //
  //=======================================================================
  // ************* STEERING parameters FOR ALICE SIMULATION **************
  // Chamber positions
  // From AliMUONConstants class we get :
  //   Position Z (along beam) of the chambers (in cm)
  //        (from AliMUONConstants class):
  //    533.5,  546.5,  678.5, 693.5,  964.0, 986.0, 1251.5, 1278.5,
  //   1416.5, 1443.5,  1610, 1625.,  1710., 1725.
  //   Internal Radius (in cm)
  //     36.4,  46.2,  66.0,  80.,  80., 100., 100.
  //   External Radius (in cm)
  //    183.,  245.,  395.,  560., 563., 850., 900.
  //=======================================================================
  if (!strcmp(option,"box")) {
    AliGenBox * gener = new AliGenBox(1);
    gener->SetMomentumRange(20.,20.1);
    gener->SetPhiRange(0., 360.);
    gener->SetThetaRange(171.000,178.001);
    gener->SetPart(13);           // Muons
    gener->SetOrigin(0.,0., 0.);  //vertex position
    gener->SetSigma(0.0, 0.0, 0.0);         //Sigma in (X,Y,Z) (cm) on IP position
  }
  if (!strcmp(option,"gun")) {
    //*********************************************
    // Example for Fixed Particle Gun             *
    //*********************************************
    AliGenFixed *gener = new AliGenFixed(ntracks);
    gener->SetMomentum(10);
    gener->SetPhiRange(0.);
    gener->SetThetaRange(0.);
    gener->SetOrigin(30,30,1200);//vertex position
    gener->SetPart(13);          //GEANT particle type  13 is muons
  }
  if (!strcmp(option,"scan")) {
    AliGenScan *gener = new AliGenScan(-1);
    gener->SetMomentumRange(10,10);
    gener->SetPhiRange(0, 0);
    gener->SetThetaRange(-180, -180);
    //vertex position
    //gener->SetSigma(1,1,0);           //Sigma in (X,Y,Z) (cm) on IP position
    gener->SetPart(kRootino);
    gener->SetRange(100, -300., 300., 100, -300., 300., 1, 2000, 2000);
  }
  if (!strcmp(option,"param")) {
    //*******************************************************
    // Example for J/psi or Upsilon Production from  Parameterisation *
    //*******************************************************
    AliGenParam *gener = new AliGenParam(1, AliGenMUONlib::kUpsilon);
    gener->SetMomentumRange(0,999);
    gener->SetPtRange(0,100.);
    gener->SetPhiRange(0., 360.);
    gener->SetCutOnChild(1);
    gener->SetChildPhiRange(0.,360.);
    gener->SetChildThetaRange(171.0,178.0);
    gener->SetOrigin(0,0,0);          //vertex position    gener->SetSigma(0,0,0);           //Sigma in (X,Y,Z) (cm) on IP position
    gener->SetForceDecay(kDiMuon);
    gener->SetTrackingFlag(1);
    gener->Init();
  }
  //=============================================================
  // Field (L3 0.4 T)
  AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k4kG);
  gAlice->SetField(field);

  //=================== Alice BODY parameters =============================
  AliBODY *BODY = new AliBODY("BODY","Alice envelop");
  //=================== ABSO parameters ============================
  AliABSO *ABSO = new AliABSOv0("ABSO", "Muon Absorber");
  //=================== DIPO parameters ============================
  AliDIPO *DIPO = new AliDIPOv2("DIPO", "Dipole version 2");
  //================== HALL parameters ============================
  AliHALL *HALL = new AliHALL("HALL", "Alice Hall");
  //=================== PIPE parameters ============================
  AliPIPE *PIPE = new AliPIPEv0("PIPE", "Beam Pipe");
  //=================== SHIL parameters ============================
  AliSHIL *SHIL = new AliSHILv2("SHIL", "Shielding Version 2");
  //=================== MUON Subsystem ===========================
  cout << ">>> Config.C: Creating AliMUONv1 ..."<<endl;

  // New MUONv1 version (geometry defined via builders)
  AliMUON *MUON = new AliMUONv1("MUON", "default");
  //AliMUON *MUON = new AliMUONv1("MUON", "FactoryV3"); // New segmentation slats
  //AliMUON *MUON = new AliMUONv1("MUON", "FactoryV4"); // New segmentation trigger
  // If align = true, the detection elements transformations
  // are taken from the input files and not from the code
  //MUON->SetAlign(true);
  MUON->AddGeometryBuilder(new AliMUONSt1GeometryBuilderV2(MUON));
  MUON->AddGeometryBuilder(new AliMUONSt2GeometryBuilderV2(MUON));
  MUON->AddGeometryBuilder(new AliMUONSlatGeometryBuilder(MUON));
  MUON->AddGeometryBuilder(new AliMUONTriggerGeometryBuilder(MUON));
}

Float_t EtaToTheta(Float_t arg){
  return (180./TMath::Pi())*2.*atan(exp(-arg));
}
<commit_msg>Updated comments about alignment.<commit_after>// Config file test for MUON spectormeter
// Remember to define the directory and option
// gAlice->SetConfigFunction("Config('$HOME','box');");

void Config(char directory[100]="", char option[6]="param")
{
  //
  // Config file for MUON test
  //

  //=====================================================================
  //  Libraries required by geant321
  gSystem->Load("libgeant321.so");
  new TGeant3TGeo("C++ Interface to Geant3");
  //=======================================================================
  //  Create the output file
  Text_t filename[100];
  sprintf(filename,"%sgalice.root",directory);
  cout << ">>> Output file is " << filename << endl;
  cout << ">>> Config.C: Creating Run Loader ..."<<endl;
  AliRunLoader* rl=0x0;
  rl = AliRunLoader::Open(
	filename, AliConfig::GetDefaultEventFolderName(), "recreate");
  if (rl == 0x0) {
    gAlice->Fatal("Config.C","Can not instatiate the Run Loader");
    return;
  }
  rl->SetCompressionLevel(2);
  rl->SetNumberOfEventsPerFile(100);
  gAlice->SetRunLoader(rl);

  //AliLog::SetModuleDebugLevel("MUON", 1);

  //=======================================================================
  // Set External decayer
  TVirtualMCDecayer *decayer = new AliDecayerPythia();
  decayer->SetForceDecay(kAll);
  decayer->Init();
  gMC->SetExternalDecayer(decayer);

  //
  //=======================================================================
  // ******* GEANT STEERING parameters FOR ALICE SIMULATION *******
    gMC->SetProcess("DCAY",1);
    gMC->SetProcess("PAIR",1);
    gMC->SetProcess("COMP",1);
    gMC->SetProcess("PHOT",1);
    gMC->SetProcess("PFIS",0);
    gMC->SetProcess("DRAY",0);
    gMC->SetProcess("ANNI",1);
    gMC->SetProcess("BREM",1);
    gMC->SetProcess("MUNU",1);
    gMC->SetProcess("CKOV",1);
    gMC->SetProcess("HADR",1);
    gMC->SetProcess("LOSS",2);
    gMC->SetProcess("MULS",1);
    gMC->SetProcess("RAYL",1);

    Float_t cut = 1.e-3;        // 1MeV cut by default
    Float_t tofmax = 1.e10;

    gMC->SetCut("CUTGAM", cut);
    gMC->SetCut("CUTELE", cut);
    gMC->SetCut("CUTNEU", cut);
    gMC->SetCut("CUTHAD", cut);
    gMC->SetCut("CUTMUO", cut);
    gMC->SetCut("BCUTE",  cut);
    gMC->SetCut("BCUTM",  cut);
    gMC->SetCut("DCUTE",  cut);
    gMC->SetCut("DCUTM",  cut);
    gMC->SetCut("PPCUTM", cut);
    gMC->SetCut("TOFMAX", tofmax);
  //
  //=======================================================================
  // ************* STEERING parameters FOR ALICE SIMULATION **************
  // Chamber positions
  // From AliMUONConstants class we get :
  //   Position Z (along beam) of the chambers (in cm)
  //        (from AliMUONConstants class):
  //    533.5,  546.5,  678.5, 693.5,  964.0, 986.0, 1251.5, 1278.5,
  //   1416.5, 1443.5,  1610, 1625.,  1710., 1725.
  //   Internal Radius (in cm)
  //     36.4,  46.2,  66.0,  80.,  80., 100., 100.
  //   External Radius (in cm)
  //    183.,  245.,  395.,  560., 563., 850., 900.
  //=======================================================================
  if (!strcmp(option,"box")) {
    AliGenBox * gener = new AliGenBox(1);
    gener->SetMomentumRange(20.,20.1);
    gener->SetPhiRange(0., 360.);
    gener->SetThetaRange(171.000,178.001);
    gener->SetPart(13);           // Muons
    gener->SetOrigin(0.,0., 0.);  //vertex position
    gener->SetSigma(0.0, 0.0, 0.0);         //Sigma in (X,Y,Z) (cm) on IP position
  }
  if (!strcmp(option,"gun")) {
    //*********************************************
    // Example for Fixed Particle Gun             *
    //*********************************************
    AliGenFixed *gener = new AliGenFixed(ntracks);
    gener->SetMomentum(10);
    gener->SetPhiRange(0.);
    gener->SetThetaRange(0.);
    gener->SetOrigin(30,30,1200);//vertex position
    gener->SetPart(13);          //GEANT particle type  13 is muons
  }
  if (!strcmp(option,"scan")) {
    AliGenScan *gener = new AliGenScan(-1);
    gener->SetMomentumRange(10,10);
    gener->SetPhiRange(0, 0);
    gener->SetThetaRange(-180, -180);
    //vertex position
    //gener->SetSigma(1,1,0);           //Sigma in (X,Y,Z) (cm) on IP position
    gener->SetPart(kRootino);
    gener->SetRange(100, -300., 300., 100, -300., 300., 1, 2000, 2000);
  }
  if (!strcmp(option,"param")) {
    //*******************************************************
    // Example for J/psi or Upsilon Production from  Parameterisation *
    //*******************************************************
    AliGenParam *gener = new AliGenParam(1, AliGenMUONlib::kUpsilon);
    gener->SetMomentumRange(0,999);
    gener->SetPtRange(0,100.);
    gener->SetPhiRange(0., 360.);
    gener->SetCutOnChild(1);
    gener->SetChildPhiRange(0.,360.);
    gener->SetChildThetaRange(171.0,178.0);
    gener->SetOrigin(0,0,0);          //vertex position    gener->SetSigma(0,0,0);           //Sigma in (X,Y,Z) (cm) on IP position
    gener->SetForceDecay(kDiMuon);
    gener->SetTrackingFlag(1);
    gener->Init();
  }
  //=============================================================
  // Field (L3 0.4 T)
  AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k4kG);
  gAlice->SetField(field);

  //=================== Alice BODY parameters =============================
  AliBODY *BODY = new AliBODY("BODY","Alice envelop");
  //=================== ABSO parameters ============================
  AliABSO *ABSO = new AliABSOv0("ABSO", "Muon Absorber");
  //=================== DIPO parameters ============================
  AliDIPO *DIPO = new AliDIPOv2("DIPO", "Dipole version 2");
  //================== HALL parameters ============================
  AliHALL *HALL = new AliHALL("HALL", "Alice Hall");
  //=================== PIPE parameters ============================
  AliPIPE *PIPE = new AliPIPEv0("PIPE", "Beam Pipe");
  //=================== SHIL parameters ============================
  AliSHIL *SHIL = new AliSHILv2("SHIL", "Shielding Version 2");
  //=================== MUON Subsystem ===========================
  cout << ">>> Config.C: Creating AliMUONv1 ..."<<endl;

  // New MUONv1 version (geometry defined via builders)
  AliMUON *MUON = new AliMUONv1("MUON", "default");
  //AliMUON *MUON = new AliMUONv1("MUON", "FactoryV3"); // New segmentation slats
  //AliMUON *MUON = new AliMUONv1("MUON", "FactoryV4"); // New segmentation trigger
  // If SetAlign, the detection elements transformations
  // are taken from the input file and not from the code
  // MUON->SetAlign("transform.dat");
  MUON->AddGeometryBuilder(new AliMUONSt1GeometryBuilderV2(MUON));
  MUON->AddGeometryBuilder(new AliMUONSt2GeometryBuilderV2(MUON));
  MUON->AddGeometryBuilder(new AliMUONSlatGeometryBuilder(MUON));
  MUON->AddGeometryBuilder(new AliMUONTriggerGeometryBuilder(MUON));
}

Float_t EtaToTheta(Float_t arg){
  return (180./TMath::Pi())*2.*atan(exp(-arg));
}
<|endoftext|>