<commit_before>/**
 * @file multi_wrapper_impls.hpp
 *
 * @brief Implementations of methods or functions requiring the definitions of
 * multiple CUDA entity proxy classes. In some cases these are declared in the
 * individual proxy class files, with the other classes forward-declared.
 */
#pragma once
#ifndef MULTI_WRAPPER_IMPLS_HPP_
#define MULTI_WRAPPER_IMPLS_HPP_

#include <cuda/api/stream.hpp>
#include <cuda/api/device.hpp>
#include <cuda/api/event.hpp>
#include <cuda/api/pointer.hpp>
#include <cuda/api/array.hpp>

namespace cuda {

namespace array {

namespace detail {

template<typename T, bool AssumedCurrent>
cudaArray* allocate(device_t<AssumedCurrent>& device, array::dimensions_t<3> dimensions)
{
	device::current::scoped_override_t<AssumedCurrent> set_device_for_this_scope(device.id());
	return allocate_on_current_device<T>(dimensions);
}

template<typename T, bool AssumedCurrent>
cudaArray* allocate(device_t<AssumedCurrent>& device, array::dimensions_t<2> dimensions)
{
	device::current::scoped_override_t<AssumedCurrent> set_device_for_this_scope(device.id());
	return allocate_on_current_device<T>(dimensions);
}

} // namespace detail

} // namespace array

namespace event {

/**
 * @brief creates a new execution stream on a device.
 *
 * @note The CUDA API runtime defaults to creating
 * which you synchronize on by busy-waiting. This function does
 * the same for compatibility.
 *
 * @param device The device on which to create the new stream
 * @param uses_blocking_sync When synchronizing on this new evet,
 * shall a thread busy-wait for it, or
 * @param records_timing Can this event be used to record time
 * values (e.g. duration between events)
 * @param interprocess Can multiple processes work with the constructed
 * event?
 * @return The constructed event proxy class
 */
template <bool DeviceAssumedCurrent>
inline event_t create(
	device_t<DeviceAssumedCurrent>  device,
	bool                            uses_blocking_sync,
	bool                            records_timing,
	bool                            interprocess)
{
	auto device_id = device.id();
		// Yes, we need the ID explicitly even on the current device,
		// because event_t's don't have an implicit device ID.
	return event::detail::create(device_id , uses_blocking_sync, records_timing, interprocess);
}

} // namespace event

// device_t methods

template <bool AssumedCurrent>
inline void device_t<AssumedCurrent>::synchronize(event_t& event)
{
	return synchronize_event(event.id());
}

template <bool AssumedCurrent>
inline void device_t<AssumedCurrent>::synchronize(stream_t<detail::do_not_assume_device_is_current>& stream)
{
	return synchronize_stream(stream.id());
}

template <bool AssumedCurrent>
inline stream_t<AssumedCurrent> device_t<AssumedCurrent>::default_stream() const noexcept
{
	// TODO: Perhaps support not-knowing our ID here as well, somehow?
	return stream_t<AssumedCurrent>(id(), stream::default_stream_id);
}

template <bool AssumedCurrent>
inline stream_t<detail::do_not_assume_device_is_current>
device_t<AssumedCurrent>::create_stream(
	bool                will_synchronize_with_default_stream,
	stream::priority_t  priority)
{
	device::current::scoped_override_t<AssumedCurrent> set_device_for_this_scope(id_);
	constexpr const auto take_ownership = true;
	return stream::detail::wrap(id(), stream::detail::create_on_current_device(
		will_synchronize_with_default_stream, priority), take_ownership);
}

namespace detail {

} // namespace detail

template <bool AssumedCurrent>
template <typename KernelFunction, typename ... KernelParameters>
void device_t<AssumedCurrent>::launch(
	bool thread_block_cooperativity,
	const KernelFunction& kernel_function, launch_configuration_t launch_configuration,
	KernelParameters ... parameters)
{
	return default_stream().enqueue.kernel_launch(
		thread_block_cooperativity, kernel_function, launch_configuration, parameters...);
}

template <bool AssumedCurrent>
inline event_t device_t<AssumedCurrent>::create_event(
	bool          uses_blocking_sync,
	bool          records_timing,
	bool          interprocess)
{
	// The current implementation of event::create is not super-smart,
	// but it's probably not worth it trying to improve just this function
	return event::create<AssumedCurrent>(*this, uses_blocking_sync, records_timing, interprocess);
}

// event_t methods

inline device_t<detail::do_not_assume_device_is_current>
event_t::device() const { return cuda::device::get(device_id_); }

void event_t::record(stream_t<>& stream)
{
	// Note:
	// TODO: Perhaps check the device ID here, rather than
	// have the Runtime API call fail?
	event::detail::enqueue(stream.id(), id_);
}

void event_t::fire(stream_t<>& stream) {
	record(stream);
	stream.synchronize();
}

// stream_t methods

template <bool AssumesDeviceIsCurrent>
inline device_t<detail::do_not_assume_device_is_current>
stream_t<AssumesDeviceIsCurrent>::device() const { return cuda::device::get(device_id_); }

template <bool AssumesDeviceIsCurrent>
inline void stream_t<AssumesDeviceIsCurrent>::enqueue_t::wait(const event_t& event_)
{
#ifndef NDEBUG
	if (event_.device_id() != device_id_) {
		throw std::invalid_argument("Attempt to have a stream on CUDA device "
			+ std::to_string(device_id_) + " wait for an event on another device ("
			"device " + std::to_string(event_.device_id()) + ")");
	}
#endif

	// Required by the CUDA runtime API; the flags value is
	// currently unused
	constexpr const unsigned int  flags = 0;

	auto status = cudaStreamWaitEvent(stream_id_, event_.id(), flags);
	throw_if_error(status,
		std::string("Failed scheduling a wait for event ") + cuda::detail::ptr_as_hex(event_.id())
		+ " on stream " + cuda::detail::ptr_as_hex(stream_id_)
		+ " on CUDA device " + std::to_string(device_id_));

}

template <bool AssumesDeviceIsCurrent>
inline event_t& stream_t<AssumesDeviceIsCurrent>::enqueue_t::event(event_t& existing_event)
{
#ifndef NDEBUG
	if (existing_event.device_id() != device_id_) {
		throw std::invalid_argument("Attempt to have a stream on CUDA device "
			+ std::to_string(device_id_) + " wait for an event on another device ("
			"device " + std::to_string(existing_event.device_id()) + ")");
	}
#endif
	auto status = cudaEventRecord(existing_event.id(), stream_id_);
	throw_if_error(status,
		"Failed scheduling event " + cuda::detail::ptr_as_hex(existing_event.id()) + " to occur"
		+ " on stream " + cuda::detail::ptr_as_hex(stream_id_)
		+ " on CUDA device " + std::to_string(device_id_));
	return existing_event;
}

template <bool AssumesDeviceIsCurrent>
inline event_t stream_t<AssumesDeviceIsCurrent>::enqueue_t::event(
    bool          uses_blocking_sync,
    bool          records_timing,
    bool          interprocess)
{
	event_t ev { event::detail::create(device_id_, uses_blocking_sync, records_timing, interprocess) };
	// Note that, at this point, the event is not associated with this enqueue object's stream.
	this->event(ev);
	return ev;
}

namespace memory {

template <typename T>
inline device_t<cuda::detail::do_not_assume_device_is_current>
pointer_t<T>::device() const
{
	return cuda::device::get(attributes().device);
}

namespace async {

template <bool StreamIsOnCurrentDevice>
inline void copy(void *destination, const void *source, size_t num_bytes, stream_t<StreamIsOnCurrentDevice>& stream)
{
	detail::copy(destination, source, num_bytes, stream.id());
}

template <typename T, size_t NumDimensions, bool StreamIsOnCurrentDevice>
inline void copy(array_t<T, NumDimensions>& destination, const void *source, stream_t<StreamIsOnCurrentDevice>& stream) {
	detail::copy(destination, source, stream.id());
}

template <typename T, size_t NumDimensions, bool StreamIsOnCurrentDevice>
inline void copy(void* destination, const array_t<T, NumDimensions>& source, stream_t<StreamIsOnCurrentDevice>& stream) {
	detail::copy(destination, source, stream.id());
}

template <typename T, bool StreamIsOnCurrentDevice>
inline void copy_single(T& destination, const T& source, stream_t<StreamIsOnCurrentDevice>& stream)
{
	detail::copy(&destination, &source, sizeof(T), stream.id());
}

} // namespace async

namespace device {

template <bool AssumedCurrent>
inline void* allocate(cuda::device_t<AssumedCurrent>& device, size_t size_in_bytes)
{
	return memory::device::allocate(device.id(), size_in_bytes);
}

namespace async {

template <bool StreamIsOnCurrentDevice>
inline void set(void* start, int byte_value, size_t num_bytes, stream_t<StreamIsOnCurrentDevice>& stream)
{
	detail::set(start, byte_value, num_bytes, stream.id());
}

template <bool StreamIsOnCurrentDevice>
inline void zero(void* start, size_t num_bytes, stream_t<StreamIsOnCurrentDevice>& stream)
{
	detail::zero(start, num_bytes, stream.id());
}

} // namespace async

} // namespace device

namespace managed {

namespace async {

template <bool DestinationIsCurrentDevice>
inline void prefetch(
	const void*                                  managed_ptr,
	size_t                                       num_bytes,
	cuda::device_t<DestinationIsCurrentDevice>&  destination,
	cuda::stream_t<DestinationIsCurrentDevice>&  stream_id)
{
	detail::prefetch(managed_ptr, num_bytes, destination.id(), stream_id.id());
}

} // namespace async

template <bool AssumedCurrent>
inline void* allocate(
	cuda::device_t<AssumedCurrent>&  device,
	size_t                           num_bytes,
	initial_visibility_t             initial_visibility)
{
	return detail::allocate(device.id(), num_bytes, initial_visibility);
}

} // namespace managed

namespace mapped {

template <bool AssumedCurrent>
inline region_pair allocate(
	cuda::device_t<AssumedCurrent>&  device,
	size_t                           size_in_bytes,
	region_pair::allocation_options  options)
{
	return cuda::memory::mapped::allocate(device.id(), size_in_bytes, options);
}

} // namespace mapped

} // namespace memory

/**
 * @brief Sets a device function's preference of either having more L1 cache or
 * more shared memory space when executing on some device
 *
 * @param device_id the CUDA device for execution on which the preference is set
 * @param preference value to set for the device function (more cache, more L1 or make the equal)
 */
void device_function_t::cache_preference(
	device_t<detail::do_not_assume_device_is_current>& device,
	multiprocessor_cache_preference_t preference)
{
	device::current::scoped_override_t<> set_device_for_this_context(device.id());
	cache_preference(preference);
}

void device_function_t::opt_in_to_extra_dynamic_memory(
	cuda::memory::shared::size_t maximum_shared_memory_required_by_kernel,
	device_t<detail::do_not_assume_device_is_current>& device)
{
	device::current::scoped_override_t<> set_device_for_this_context(device.id());
	opt_in_to_extra_dynamic_memory(maximum_shared_memory_required_by_kernel);
}

void device_function_t::set_shared_mem_to_l1_cache_fraction(
	unsigned shared_mem_percentage,
	device_t<detail::do_not_assume_device_is_current>& device)
{
	device::current::scoped_override_t<> set_device_for_this_context(device.id());
	set_shared_mem_to_l1_cache_fraction(shared_mem_percentage);
}

namespace device_function {

inline grid::dimension_t maximum_active_blocks_per_multiprocessor(
	device_t<>                device,
	const device_function_t&  device_function,
	grid::block_dimension_t    num_threads_per_block,
	memory::shared::size_t      dynamic_shared_memory_per_block,
	bool                      disable_caching_override)
{
	device::current::scoped_override_t<> set_device_for_this_context(device.id());
	int result;
	unsigned int flags = disable_caching_override ?
		cudaOccupancyDisableCachingOverride : cudaOccupancyDefault;
	auto status = cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(
		&result, device_function.ptr(), num_threads_per_block,
		dynamic_shared_memory_per_block, flags);
	throw_if_error(status, "Failed calculating the maximum occupancy "
		"of device function blocks per multiprocessor");
	return result;
}

} // namespace device_function

namespace stream {

template <bool AssumeDeviceIsCurrent>
inline stream_t<> create(
	device_t<AssumeDeviceIsCurrent>&  device,
	bool                              synchronizes_with_default_stream,
	priority_t                        priority)
{
	auto device_id = device.id();
	return detail::create(device_id, synchronizes_with_default_stream, priority);
}

} // namespace stream

} // namespace cuda

#endif // MULTI_WRAPPER_IMPLS_HPP_
<commit_msg>Fixes #140: Added `inline` to some function definitions in `multi_wrapper_impls.hpp`.<commit_after>/**
 * @file multi_wrapper_impls.hpp
 *
 * @brief Implementations of methods or functions requiring the definitions of
 * multiple CUDA entity proxy classes. In some cases these are declared in the
 * individual proxy class files, with the other classes forward-declared.
 */
#pragma once
#ifndef MULTI_WRAPPER_IMPLS_HPP_
#define MULTI_WRAPPER_IMPLS_HPP_

#include <cuda/api/stream.hpp>
#include <cuda/api/device.hpp>
#include <cuda/api/event.hpp>
#include <cuda/api/pointer.hpp>
#include <cuda/api/array.hpp>

namespace cuda {

namespace array {

namespace detail {

template<typename T, bool AssumedCurrent>
cudaArray* allocate(device_t<AssumedCurrent>& device, array::dimensions_t<3> dimensions)
{
	device::current::scoped_override_t<AssumedCurrent> set_device_for_this_scope(device.id());
	return allocate_on_current_device<T>(dimensions);
}

template<typename T, bool AssumedCurrent>
cudaArray* allocate(device_t<AssumedCurrent>& device, array::dimensions_t<2> dimensions)
{
	device::current::scoped_override_t<AssumedCurrent> set_device_for_this_scope(device.id());
	return allocate_on_current_device<T>(dimensions);
}

} // namespace detail

} // namespace array

namespace event {

/**
 * @brief creates a new execution stream on a device.
 *
 * @note The CUDA API runtime defaults to creating
 * which you synchronize on by busy-waiting. This function does
 * the same for compatibility.
 *
 * @param device The device on which to create the new stream
 * @param uses_blocking_sync When synchronizing on this new evet,
 * shall a thread busy-wait for it, or
 * @param records_timing Can this event be used to record time
 * values (e.g. duration between events)
 * @param interprocess Can multiple processes work with the constructed
 * event?
 * @return The constructed event proxy class
 */
template <bool DeviceAssumedCurrent>
inline event_t create(
	device_t<DeviceAssumedCurrent>  device,
	bool                            uses_blocking_sync,
	bool                            records_timing,
	bool                            interprocess)
{
	auto device_id = device.id();
		// Yes, we need the ID explicitly even on the current device,
		// because event_t's don't have an implicit device ID.
	return event::detail::create(device_id , uses_blocking_sync, records_timing, interprocess);
}

} // namespace event

// device_t methods

template <bool AssumedCurrent>
inline void device_t<AssumedCurrent>::synchronize(event_t& event)
{
	return synchronize_event(event.id());
}

template <bool AssumedCurrent>
inline void device_t<AssumedCurrent>::synchronize(stream_t<detail::do_not_assume_device_is_current>& stream)
{
	return synchronize_stream(stream.id());
}

template <bool AssumedCurrent>
inline stream_t<AssumedCurrent> device_t<AssumedCurrent>::default_stream() const noexcept
{
	// TODO: Perhaps support not-knowing our ID here as well, somehow?
	return stream_t<AssumedCurrent>(id(), stream::default_stream_id);
}

template <bool AssumedCurrent>
inline stream_t<detail::do_not_assume_device_is_current>
device_t<AssumedCurrent>::create_stream(
	bool                will_synchronize_with_default_stream,
	stream::priority_t  priority)
{
	device::current::scoped_override_t<AssumedCurrent> set_device_for_this_scope(id_);
	constexpr const auto take_ownership = true;
	return stream::detail::wrap(id(), stream::detail::create_on_current_device(
		will_synchronize_with_default_stream, priority), take_ownership);
}

namespace detail {

} // namespace detail

template <bool AssumedCurrent>
template <typename KernelFunction, typename ... KernelParameters>
void device_t<AssumedCurrent>::launch(
	bool thread_block_cooperativity,
	const KernelFunction& kernel_function, launch_configuration_t launch_configuration,
	KernelParameters ... parameters)
{
	return default_stream().enqueue.kernel_launch(
		thread_block_cooperativity, kernel_function, launch_configuration, parameters...);
}

template <bool AssumedCurrent>
inline event_t device_t<AssumedCurrent>::create_event(
	bool          uses_blocking_sync,
	bool          records_timing,
	bool          interprocess)
{
	// The current implementation of event::create is not super-smart,
	// but it's probably not worth it trying to improve just this function
	return event::create<AssumedCurrent>(*this, uses_blocking_sync, records_timing, interprocess);
}

// event_t methods

inline device_t<detail::do_not_assume_device_is_current>
event_t::device() const { return cuda::device::get(device_id_); }

inline void event_t::record(stream_t<>& stream)
{
	// Note:
	// TODO: Perhaps check the device ID here, rather than
	// have the Runtime API call fail?
	event::detail::enqueue(stream.id(), id_);
}

inline void event_t::fire(stream_t<>& stream) {
	record(stream);
	stream.synchronize();
}

// stream_t methods

template <bool AssumesDeviceIsCurrent>
inline device_t<detail::do_not_assume_device_is_current>
stream_t<AssumesDeviceIsCurrent>::device() const { return cuda::device::get(device_id_); }

template <bool AssumesDeviceIsCurrent>
inline void stream_t<AssumesDeviceIsCurrent>::enqueue_t::wait(const event_t& event_)
{
#ifndef NDEBUG
	if (event_.device_id() != device_id_) {
		throw std::invalid_argument("Attempt to have a stream on CUDA device "
			+ std::to_string(device_id_) + " wait for an event on another device ("
			"device " + std::to_string(event_.device_id()) + ")");
	}
#endif

	// Required by the CUDA runtime API; the flags value is
	// currently unused
	constexpr const unsigned int  flags = 0;

	auto status = cudaStreamWaitEvent(stream_id_, event_.id(), flags);
	throw_if_error(status,
		std::string("Failed scheduling a wait for event ") + cuda::detail::ptr_as_hex(event_.id())
		+ " on stream " + cuda::detail::ptr_as_hex(stream_id_)
		+ " on CUDA device " + std::to_string(device_id_));

}

template <bool AssumesDeviceIsCurrent>
inline event_t& stream_t<AssumesDeviceIsCurrent>::enqueue_t::event(event_t& existing_event)
{
#ifndef NDEBUG
	if (existing_event.device_id() != device_id_) {
		throw std::invalid_argument("Attempt to have a stream on CUDA device "
			+ std::to_string(device_id_) + " wait for an event on another device ("
			"device " + std::to_string(existing_event.device_id()) + ")");
	}
#endif
	auto status = cudaEventRecord(existing_event.id(), stream_id_);
	throw_if_error(status,
		"Failed scheduling event " + cuda::detail::ptr_as_hex(existing_event.id()) + " to occur"
		+ " on stream " + cuda::detail::ptr_as_hex(stream_id_)
		+ " on CUDA device " + std::to_string(device_id_));
	return existing_event;
}

template <bool AssumesDeviceIsCurrent>
inline event_t stream_t<AssumesDeviceIsCurrent>::enqueue_t::event(
    bool          uses_blocking_sync,
    bool          records_timing,
    bool          interprocess)
{
	event_t ev { event::detail::create(device_id_, uses_blocking_sync, records_timing, interprocess) };
	// Note that, at this point, the event is not associated with this enqueue object's stream.
	this->event(ev);
	return ev;
}

namespace memory {

template <typename T>
inline device_t<cuda::detail::do_not_assume_device_is_current>
pointer_t<T>::device() const
{
	return cuda::device::get(attributes().device);
}

namespace async {

template <bool StreamIsOnCurrentDevice>
inline void copy(void *destination, const void *source, size_t num_bytes, stream_t<StreamIsOnCurrentDevice>& stream)
{
	detail::copy(destination, source, num_bytes, stream.id());
}

template <typename T, size_t NumDimensions, bool StreamIsOnCurrentDevice>
inline void copy(array_t<T, NumDimensions>& destination, const void *source, stream_t<StreamIsOnCurrentDevice>& stream) {
	detail::copy(destination, source, stream.id());
}

template <typename T, size_t NumDimensions, bool StreamIsOnCurrentDevice>
inline void copy(void* destination, const array_t<T, NumDimensions>& source, stream_t<StreamIsOnCurrentDevice>& stream) {
	detail::copy(destination, source, stream.id());
}

template <typename T, bool StreamIsOnCurrentDevice>
inline void copy_single(T& destination, const T& source, stream_t<StreamIsOnCurrentDevice>& stream)
{
	detail::copy(&destination, &source, sizeof(T), stream.id());
}

} // namespace async

namespace device {

template <bool AssumedCurrent>
inline void* allocate(cuda::device_t<AssumedCurrent>& device, size_t size_in_bytes)
{
	return memory::device::allocate(device.id(), size_in_bytes);
}

namespace async {

template <bool StreamIsOnCurrentDevice>
inline void set(void* start, int byte_value, size_t num_bytes, stream_t<StreamIsOnCurrentDevice>& stream)
{
	detail::set(start, byte_value, num_bytes, stream.id());
}

template <bool StreamIsOnCurrentDevice>
inline void zero(void* start, size_t num_bytes, stream_t<StreamIsOnCurrentDevice>& stream)
{
	detail::zero(start, num_bytes, stream.id());
}

} // namespace async

} // namespace device

namespace managed {

namespace async {

template <bool DestinationIsCurrentDevice>
inline void prefetch(
	const void*                                  managed_ptr,
	size_t                                       num_bytes,
	cuda::device_t<DestinationIsCurrentDevice>&  destination,
	cuda::stream_t<DestinationIsCurrentDevice>&  stream_id)
{
	detail::prefetch(managed_ptr, num_bytes, destination.id(), stream_id.id());
}

} // namespace async

template <bool AssumedCurrent>
inline void* allocate(
	cuda::device_t<AssumedCurrent>&  device,
	size_t                           num_bytes,
	initial_visibility_t             initial_visibility)
{
	return detail::allocate(device.id(), num_bytes, initial_visibility);
}

} // namespace managed

namespace mapped {

template <bool AssumedCurrent>
inline region_pair allocate(
	cuda::device_t<AssumedCurrent>&  device,
	size_t                           size_in_bytes,
	region_pair::allocation_options  options)
{
	return cuda::memory::mapped::allocate(device.id(), size_in_bytes, options);
}

} // namespace mapped

} // namespace memory

/**
 * @brief Sets a device function's preference of either having more L1 cache or
 * more shared memory space when executing on some device
 *
 * @param device_id the CUDA device for execution on which the preference is set
 * @param preference value to set for the device function (more cache, more L1 or make the equal)
 */
inline void device_function_t::cache_preference(
	device_t<detail::do_not_assume_device_is_current>& device,
	multiprocessor_cache_preference_t preference)
{
	device::current::scoped_override_t<> set_device_for_this_context(device.id());
	cache_preference(preference);
}

inline void device_function_t::opt_in_to_extra_dynamic_memory(
	cuda::memory::shared::size_t maximum_shared_memory_required_by_kernel,
	device_t<detail::do_not_assume_device_is_current>& device)
{
	device::current::scoped_override_t<> set_device_for_this_context(device.id());
	opt_in_to_extra_dynamic_memory(maximum_shared_memory_required_by_kernel);
}

inline void device_function_t::set_shared_mem_to_l1_cache_fraction(
	unsigned shared_mem_percentage,
	device_t<detail::do_not_assume_device_is_current>& device)
{
	device::current::scoped_override_t<> set_device_for_this_context(device.id());
	set_shared_mem_to_l1_cache_fraction(shared_mem_percentage);
}

namespace device_function {

inline grid::dimension_t maximum_active_blocks_per_multiprocessor(
	device_t<>                device,
	const device_function_t&  device_function,
	grid::block_dimension_t    num_threads_per_block,
	memory::shared::size_t      dynamic_shared_memory_per_block,
	bool                      disable_caching_override)
{
	device::current::scoped_override_t<> set_device_for_this_context(device.id());
	int result;
	unsigned int flags = disable_caching_override ?
		cudaOccupancyDisableCachingOverride : cudaOccupancyDefault;
	auto status = cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(
		&result, device_function.ptr(), num_threads_per_block,
		dynamic_shared_memory_per_block, flags);
	throw_if_error(status, "Failed calculating the maximum occupancy "
		"of device function blocks per multiprocessor");
	return result;
}

} // namespace device_function

namespace stream {

template <bool AssumeDeviceIsCurrent>
inline stream_t<> create(
	device_t<AssumeDeviceIsCurrent>&  device,
	bool                              synchronizes_with_default_stream,
	priority_t                        priority)
{
	auto device_id = device.id();
	return detail::create(device_id, synchronizes_with_default_stream, priority);
}

} // namespace stream

} // namespace cuda

#endif // MULTI_WRAPPER_IMPLS_HPP_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: strload.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:44:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_STRLOAD_HXX
#define SC_STRLOAD_HXX

#ifndef SC_SCRESID_HXX
#include "scresid.hxx"
#endif

#ifndef _TOOLS_RC_HXX //autogen
#include <tools/rc.hxx>
#endif

class ScRscStrLoader : public Resource
{
public:
    ScRscStrLoader( USHORT nRsc, USHORT nStrId ) :
        Resource( ScResId( nRsc ) ), theStr( ScResId( nStrId ) )
    {
        FreeResource();
    }

    const String& GetString() const { return theStr; }

private:
    String theStr;
};

#endif // SC_STRLOAD_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.1.1.1.942); FILE MERGED 2005/09/05 15:01:01 rt 1.1.1.1.942.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: strload.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 17:58:55 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_STRLOAD_HXX
#define SC_STRLOAD_HXX

#ifndef SC_SCRESID_HXX
#include "scresid.hxx"
#endif

#ifndef _TOOLS_RC_HXX //autogen
#include <tools/rc.hxx>
#endif

class ScRscStrLoader : public Resource
{
public:
    ScRscStrLoader( USHORT nRsc, USHORT nStrId ) :
        Resource( ScResId( nRsc ) ), theStr( ScResId( nStrId ) )
    {
        FreeResource();
    }

    const String& GetString() const { return theStr; }

private:
    String theStr;
};

#endif // SC_STRLOAD_HXX

<|endoftext|>


<commit_before>#include "Engine.h"
#include "Game.h"
#include "ObjectDummy.h"
#include "BodyRigid.h"
#include "BodyDummy.h"

#include "Physics.h"
#include "ShapeCapsule.h"
#include "ActorBase.h"
#include "Visualizer.h"
#include "sys/SysControl.h"

#ifdef MEMORY_INFO
#define new new(__FILE__, __LINE__)
#endif // MEMORY_INFO

using namespace MathLib;

/*
*/
#define ACTOR_BASE_IFPS             (1.0f / 60.0f)
#define ACTOR_BASE_CLAMP            89.9f
#define ACTOR_BASE_COLLISIONS       4

/*
*/

CActorBase::CActorBase()
{
	m_vUp = vec3(0.0f, 0.0f, 1.0f);
	m_pObject = new CObjectDummy();
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(1.0f, 1.0f);

	m_nFlush = 0;
	m_vPosition = Vec3_zero;
	m_vVelocity = Vec3_zero;
	m_fPhiAngle = 0.0f;			//б		άƽϵУֱYķX֮ļн
	m_fThetaAngle = 0.0f;			//λǣ뵱ǰ˳ʱ߹ĽǶ

	for (int i = 0; i < NUM_STATES; i++)
	{
		m_pStates[i] = 0;
		m_pTimes[i] = 0.0f;
	}

	m_pDummy->SetEnabled(1);
	m_pObject->SetBody(NULL);
	m_pObject->SetBody(m_pDummy);
	m_pShape->SetBody(NULL);
	m_pShape->SetBody(m_pDummy);

	m_pObject->SetWorldTransform(Get_Body_Transform());
	m_pShape->SetRestitution(0.0f);
	m_pShape->SetCollisionMask(2);

	SetEnabled(1);
	SetViewDirection(vec3(0.0f, 1.0f, 0.0f));
	SetCollision(1);
	SetCollisionRadius(0.3f);
	SetCollisionHeight(1.0f);
	SetFriction(2.0f);
	SetMinVelocity(2.0f);
	SetMaxVelocity(4.0f);
	SetAcceleration(8.0f);
	SetDamping(8.0f);
	SetJumping(1.5f);

	SetGround(0);
	SetCeiling(0);

}
CActorBase::~CActorBase()
{
	m_pDummy->SetObject(NULL);
	delete m_pObject;
	delete m_pDummy;
}

void CActorBase::SetEnabled(int enable)
{
	m_nEnable = enable;
	m_pDummy->SetEnabled(m_nEnable);
}
int CActorBase::IsEnabled() const
{
	return m_nEnable;
}
void CActorBase::Update(float ifps)
{
	if (!m_nEnable)
	{
		return;
	}
	// impulse
	vec3 impulse = vec3_zero;

	// ortho basis
	vec3 tangent, binormal;
	OrthoBasis(m_vUp, tangent, binormal);
	// current basis
	vec3 x = quat(m_vUp, -m_fPhiAngle) * binormal;
	vec3 y = Normalize(Cross(m_vUp, x));
	vec3 z = Normalize(Cross(x, y));
	// handle states
	Update_States(1, ifps);

	// old velocity
	float x_velocity = Dot(x, m_vVelocity);
	float y_velocity = Dot(y, m_vVelocity);
	float z_velocity = Dot(z, m_vVelocity);

	// movement
	if (m_pStates[STATE_FORWARD]) impulse += x;
	if (m_pStates[STATE_BACKWARD]) impulse -= x;
	if (m_pStates[STATE_MOVE_LEFT]) impulse += y;
	if (m_pStates[STATE_MOVE_RIGHT]) impulse -= y;
	impulse.normalize();
	// velocity
	if (m_pStates[STATE_RUN]) impulse *= m_fMaxVelocity;
	else impulse *= m_fMinVelocity;

	// jump
	if (m_pStates[STATE_JUMP] == STATE_BEGIN)
	{
		impulse += z * CMathCore::Sqrt(2.0f * 9.8f * m_fJumping) / (m_fAcceleration * ifps);
	}

	// rotate velocity
	if (GetGround())
	{
		m_vVelocity = x * x_velocity + y * y_velocity + z * z_velocity;
	}
	// time
	float time = ifps * g_Engine.pPhysics->GetScale();
	// target velocity
	float target_velocity = Length(vec2(Dot(x, impulse), Dot(y, impulse)));

	// penetration tolerance
	float penetration = g_Engine.pPhysics->GetPenetrationTolerance();
	float penetration_2 = penetration * 2.0f;

	// frozen linear velocity
	float frozen_velocity = g_Engine.pPhysics->GetFrozenLinearVelocity();

	// friction
	float friction = 0.0f;
	if (target_velocity < EPSILON)
	{
		friction = m_fFriction;
	}

	// clear collision flags
	if (GetCollision())
	{
		m_nGround = 0;
		m_nCeiling = 0;
	}

	// movement
	do
	{
		// adaptive time step
		float ifps = Min(time, ACTOR_BASE_IFPS);
		time -= ifps;
		// save old velocity
		float old_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));

		// integrate velocity
		m_vVelocity += impulse * (m_fAcceleration * ifps);
		m_vVelocity += g_Engine.pPhysics->GetGravity() * ifps;

		// damping
		float current_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));
		if (target_velocity < EPSILON || current_velocity > target_velocity)
		{
			m_vVelocity = (x * Dot(x, m_vVelocity) + y * Dot(y, m_vVelocity)) * CMathCore::Exp(-m_fDamping * ifps) + z * Dot(z, m_vVelocity);
		}

		// clamp maximum velocity
		current_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));

		if (current_velocity > old_velocity)
		{
			if (current_velocity > target_velocity)
			{
				m_vVelocity = (x * Dot(x, m_vVelocity) + y * Dot(y, m_vVelocity)) * target_velocity / current_velocity + z * Dot(z, m_vVelocity);
			}
		}
		// integrate position
		//m_vPosition += Vec3(m_vVelocity * ifps);
		if (GetCollision())
		{
			// get collision
			vec3 tangent, binormal;
			const Vec3 *caps = m_pShape->GetCaps();
			for (int i = 0; i < ACTOR_BASE_COLLISIONS; i++)
			{
				m_pDummy->SetTransform(Get_Body_Transform());
				m_pShape->GetCollision(m_vecContacts, 0.0f);

				if (m_vecContacts.Size() == 0) break;
				float inum_contacts = 1.0f / CMathCore::Itof(m_vecContacts.Size());
				for (int j = 0; j < m_vecContacts.Size(); j++)
				{
					const CShape::Contact &c = m_vecContacts[j];

					vec3 normalCollision = c.normal;
					if (is_frozen && c.depth < penetration_2)
					{
						m_vPosition += Vec3(z * (Max(c.depth - penetration, 0.0f) * inum_contacts * Dot(z, normalCollision)));
					}
					else
					{
						m_vPosition += Vec3(normalCollision * (Max(c.depth - penetration, 0.0f) * inum_contacts));
						is_frozen = 0;
					}
					float normal_velocity = Dot(normalCollision, m_vVelocity);
					if (normal_velocity < 0.0f)
					{
						m_vVelocity -= normalCollision * normal_velocity;
					}
					if (friction > EPSILON)
					{
						OrthoBasis(c.normal, tangent, binormal);
						float tangent_velocity = Dot(tangent, m_vVelocity);
						float binormal_velocity = Dot(binormal, m_vVelocity);
						if (CMathCore::Abs(tangent_velocity) > EPSILON || CMathCore::Abs(binormal_velocity) > EPSILON)
						{
							float friction_velocity = Clamp(Max(-normal_velocity, 0.0f) * friction * CMathCore::RSqrt(tangent_velocity * tangent_velocity + binormal_velocity * binormal_velocity), -1.0f, 1.0f);
							m_vVelocity -= tangent * tangent_velocity * friction_velocity;
							m_vVelocity -= binormal * binormal_velocity * friction_velocity;

						}
					}
					if (Dot(c.normal, m_vUp) > 0.5f && Dot(vec3(c.point - caps[0]), m_vUp) < 0.0f) m_nGround = 1;
					if (Dot(c.normal, m_vUp) < -0.5f && Dot(vec3(c.point - caps[1]), m_vUp) > 0.0f) m_nCeiling = 1;
				}
			}
		}

		m_vPosition += Vec3(m_vVelocity * ifps);
	} while (time > EPSILON);

	// current position
	m_pObject->SetWorldTransform(Get_Body_Transform());
	m_WorldBoundBox.Set(m_BoundBox, Translate(m_vPosition));
	m_WorldBoundSphere.Set(m_BoundSphere, Translate(m_vPosition));
}
/******************************************************************************\
*
* Parameters
*
\******************************************************************************/
/*
*/
void CActorBase::Update_Bounds()
{
	float radius = m_pShape->GetRadius();
	float hheight = m_pShape->GetHHeight();
	m_BoundBox.Set(vec3(-radius, -radius, 0.0f), vec3(radius, radius, (radius + hheight) * 2.0f));
	m_BoundSphere.Set(vec3(0.0f, 0.0f, radius + hheight), radius + hheight);

	m_WorldBoundBox.Set(m_BoundBox, Translate(m_vPosition));
	m_WorldBoundSphere.Set(m_BoundSphere, Translate(m_vPosition));
}
/*
*/
void CActorBase::SetIntersectionMask(int mask)
{
	m_pShape->SetIntersectionMask(mask);
}
int CActorBase::GetIntersectionMask() const
{
	return m_pShape->GetIntersectionMask();
}

<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "Engine.h"
#include "Game.h"
#include "ObjectDummy.h"
#include "BodyRigid.h"
#include "BodyDummy.h"

#include "Physics.h"
#include "ShapeCapsule.h"
#include "ActorBase.h"
#include "Visualizer.h"
#include "sys/SysControl.h"

#ifdef MEMORY_INFO
#define new new(__FILE__, __LINE__)
#endif // MEMORY_INFO

using namespace MathLib;

/*
*/
#define ACTOR_BASE_IFPS             (1.0f / 60.0f)
#define ACTOR_BASE_CLAMP            89.9f
#define ACTOR_BASE_COLLISIONS       4

/*
*/

CActorBase::CActorBase()
{
	m_vUp = vec3(0.0f, 0.0f, 1.0f);
	m_pObject = new CObjectDummy();
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(1.0f, 1.0f);

	m_nFlush = 0;
	m_vPosition = Vec3_zero;
	m_vVelocity = Vec3_zero;
	m_fPhiAngle = 0.0f;			//б		άƽϵУֱYķX֮ļн
	m_fThetaAngle = 0.0f;			//λǣ뵱ǰ˳ʱ߹ĽǶ

	for (int i = 0; i < NUM_STATES; i++)
	{
		m_pStates[i] = 0;
		m_pTimes[i] = 0.0f;
	}

	m_pDummy->SetEnabled(1);
	m_pObject->SetBody(NULL);
	m_pObject->SetBody(m_pDummy);
	m_pShape->SetBody(NULL);
	m_pShape->SetBody(m_pDummy);

	m_pObject->SetWorldTransform(Get_Body_Transform());
	m_pShape->SetRestitution(0.0f);
	m_pShape->SetCollisionMask(2);

	SetEnabled(1);
	SetViewDirection(vec3(0.0f, 1.0f, 0.0f));
	SetCollision(1);
	SetCollisionRadius(0.3f);
	SetCollisionHeight(1.0f);
	SetFriction(2.0f);
	SetMinVelocity(2.0f);
	SetMaxVelocity(4.0f);
	SetAcceleration(8.0f);
	SetDamping(8.0f);
	SetJumping(1.5f);

	SetGround(0);
	SetCeiling(0);

}
CActorBase::~CActorBase()
{
	m_pDummy->SetObject(NULL);
	delete m_pObject;
	delete m_pDummy;
}

void CActorBase::SetEnabled(int enable)
{
	m_nEnable = enable;
	m_pDummy->SetEnabled(m_nEnable);
}
int CActorBase::IsEnabled() const
{
	return m_nEnable;
}
void CActorBase::Update(float ifps)
{
	if (!m_nEnable)
	{
		return;
	}
	// impulse
	vec3 impulse = vec3_zero;

	// ortho basis
	vec3 tangent, binormal;
	OrthoBasis(m_vUp, tangent, binormal);
	// current basis
	vec3 x = quat(m_vUp, -m_fPhiAngle) * binormal;
	vec3 y = Normalize(Cross(m_vUp, x));
	vec3 z = Normalize(Cross(x, y));
	// handle states
	Update_States(1, ifps);

	// old velocity
	float x_velocity = Dot(x, m_vVelocity);
	float y_velocity = Dot(y, m_vVelocity);
	float z_velocity = Dot(z, m_vVelocity);

	// movement
	if (m_pStates[STATE_FORWARD]) impulse += x;
	if (m_pStates[STATE_BACKWARD]) impulse -= x;
	if (m_pStates[STATE_MOVE_LEFT]) impulse += y;
	if (m_pStates[STATE_MOVE_RIGHT]) impulse -= y;
	impulse.normalize();
	// velocity
	if (m_pStates[STATE_RUN]) impulse *= m_fMaxVelocity;
	else impulse *= m_fMinVelocity;

	// jump
	if (m_pStates[STATE_JUMP] == STATE_BEGIN)
	{
		impulse += z * CMathCore::Sqrt(2.0f * 9.8f * m_fJumping) / (m_fAcceleration * ifps);
	}

	// rotate velocity
	if (GetGround())
	{
		m_vVelocity = x * x_velocity + y * y_velocity + z * z_velocity;
	}
	// time
	float time = ifps * g_Engine.pPhysics->GetScale();
	// target velocity
	float target_velocity = Length(vec2(Dot(x, impulse), Dot(y, impulse)));

	// penetration tolerance
	float penetration = g_Engine.pPhysics->GetPenetrationTolerance();
	float penetration_2 = penetration * 2.0f;

	// frozen linear velocity
	float frozen_velocity = g_Engine.pPhysics->GetFrozenLinearVelocity();

	// friction
	float friction = 0.0f;
	if (target_velocity < EPSILON)
	{
		friction = m_fFriction;
	}

	// clear collision flags
	if (GetCollision())
	{
		m_nGround = 0;
		m_nCeiling = 0;
	}

	// movement
	do
	{
		// adaptive time step
		float ifps = Min(time, ACTOR_BASE_IFPS);
		time -= ifps;
		// save old velocity
		float old_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));

		// integrate velocity
		m_vVelocity += impulse * (m_fAcceleration * ifps);
		m_vVelocity += g_Engine.pPhysics->GetGravity() * ifps;

		// damping
		float current_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));
		if (target_velocity < EPSILON || current_velocity > target_velocity)
		{
			m_vVelocity = (x * Dot(x, m_vVelocity) + y * Dot(y, m_vVelocity)) * CMathCore::Exp(-m_fDamping * ifps) + z * Dot(z, m_vVelocity);
		}

		// clamp maximum velocity
		current_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));

		if (current_velocity > old_velocity)
		{
			if (current_velocity > target_velocity)
			{
				m_vVelocity = (x * Dot(x, m_vVelocity) + y * Dot(y, m_vVelocity)) * target_velocity / current_velocity + z * Dot(z, m_vVelocity);
			}
		}
		// integrate position
		//m_vPosition += Vec3(m_vVelocity * ifps);
		if (GetCollision())
		{
			// get collision
			vec3 tangent, binormal;
			const Vec3 *caps = m_pShape->GetCaps();
			for (int i = 0; i < ACTOR_BASE_COLLISIONS; i++)
			{
				m_pDummy->SetTransform(Get_Body_Transform());
				m_pShape->GetCollision(m_vecContacts, 0.0f);

				if (m_vecContacts.Size() == 0) break;
				float inum_contacts = 1.0f / CMathCore::Itof(m_vecContacts.Size());
				for (int j = 0; j < m_vecContacts.Size(); j++)
				{
					const CShape::Contact &c = m_vecContacts[j];

					vec3 normalCollision = c.normal;
					if (is_frozen && c.depth < penetration_2)
					{
						m_vPosition += Vec3(z * (Max(c.depth - penetration, 0.0f) * inum_contacts * Dot(z, normalCollision)));
					}
					else
					{
						m_vPosition += Vec3(normalCollision * (Max(c.depth - penetration, 0.0f) * inum_contacts));
						is_frozen = 0;
					}
					float normal_velocity = Dot(normalCollision, m_vVelocity);
					if (normal_velocity < 0.0f)
					{
						m_vVelocity -= normalCollision * normal_velocity;
					}
					if (friction > EPSILON)
					{
						OrthoBasis(c.normal, tangent, binormal);
						float tangent_velocity = Dot(tangent, m_vVelocity);
						float binormal_velocity = Dot(binormal, m_vVelocity);
						if (CMathCore::Abs(tangent_velocity) > EPSILON || CMathCore::Abs(binormal_velocity) > EPSILON)
						{
							float friction_velocity = Clamp(Max(-normal_velocity, 0.0f) * friction * CMathCore::RSqrt(tangent_velocity * tangent_velocity + binormal_velocity * binormal_velocity), -1.0f, 1.0f);
							m_vVelocity -= tangent * tangent_velocity * friction_velocity;
							m_vVelocity -= binormal * binormal_velocity * friction_velocity;

						}
					}
					if (Dot(c.normal, m_vUp) > 0.5f && Dot(vec3(c.point - caps[0]), m_vUp) < 0.0f) m_nGround = 1;
					if (Dot(c.normal, m_vUp) < -0.5f && Dot(vec3(c.point - caps[1]), m_vUp) > 0.0f) m_nCeiling = 1;
				}
			}
		}

		m_vPosition += Vec3(m_vVelocity * ifps);
	} while (time > EPSILON);

	// current position
	m_pObject->SetWorldTransform(Get_Body_Transform());
	m_WorldBoundBox.Set(m_BoundBox, Translate(m_vPosition));
	m_WorldBoundSphere.Set(m_BoundSphere, Translate(m_vPosition));
}
/******************************************************************************\
*
* Parameters
*
\******************************************************************************/
/*
*/
void CActorBase::Update_Bounds()
{
	float radius = m_pShape->GetRadius();
	float hheight = m_pShape->GetHHeight();
	m_BoundBox.Set(vec3(-radius, -radius, 0.0f), vec3(radius, radius, (radius + hheight) * 2.0f));
	m_BoundSphere.Set(vec3(0.0f, 0.0f, radius + hheight), radius + hheight);

	m_WorldBoundBox.Set(m_BoundBox, Translate(m_vPosition));
	m_WorldBoundSphere.Set(m_BoundSphere, Translate(m_vPosition));
}
/*
*/
void CActorBase::SetIntersectionMask(int mask)
{
	m_pShape->SetIntersectionMask(mask);
}
int CActorBase::GetIntersectionMask() const
{
	return m_pShape->GetIntersectionMask();
}

/*
*/
void CActorBase::SetCollision(int c)
{
	m_nCollision = c;
}<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */
#include <memory>
#include <string>
#include <cstdint>

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "tests/utils/MockObjects.h"
#include "runtimes/cluster-controller-runtime/JoynrClusterControllerRuntime.h"
#include "joynr/tests/testProxy.h"
#include "joynr/Future.h"
#include "joynr/DispatcherUtils.h"
#include "joynr/LibjoynrSettings.h"
#include "joynr/PrivateCopyAssign.h"

using namespace ::testing;

using namespace joynr;

/*
  * This test tries to create two combined Runtimes and will test communication
  * between the two Runtimes via HttpReceiver
  *
  */

class End2EndPerformanceTest : public TestWithParam< std::tuple<std::string, std::string> > {
public:
    ADD_LOGGER(End2EndPerformanceTest);
    JoynrClusterControllerRuntime* runtime1;
    JoynrClusterControllerRuntime* runtime2;
    Settings *settings1;
    Settings *settings2;
    std::string baseUuid;
    std::string uuid;
    std::string domain;

    End2EndPerformanceTest() :
        runtime1(nullptr),
        runtime2(nullptr),
        settings1(new Settings(std::get<0>(GetParam()))),
        settings2(new Settings(std::get<1>(GetParam()))),
        baseUuid(util::createUuid()),
        uuid( "_" + baseUuid.substr(1, baseUuid.length()-2)),
        domain("cppEnd2EndPerformancesTestDomain" + uuid)
    {

        Settings integration1Settings{"test-resources/libjoynrSystemIntegration1.settings"};
        Settings::merge(integration1Settings, *settings1, false);
        runtime1 = new JoynrClusterControllerRuntime(nullptr, settings1);
        Settings integration2Settings{"test-resources/libjoynrSystemIntegration2.settings"};
        Settings::merge(integration2Settings, *settings2, false);
        runtime2 = new JoynrClusterControllerRuntime(nullptr, settings2);
    }

    void SetUp() {
        runtime1->start();
        runtime2->start();
    }

    void TearDown() {
        bool deleteChannel = true;
        runtime1->stop(deleteChannel);
        runtime2->stop(deleteChannel);

        // Remove participant id persistence file
        std::remove(LibjoynrSettings::DEFAULT_PARTICIPANT_IDS_PERSISTENCE_FILENAME().c_str());
    }

    ~End2EndPerformanceTest(){
        delete runtime1;
        delete runtime2;
    }

private:
    DISALLOW_COPY_AND_ASSIGN(End2EndPerformanceTest);

};

INIT_LOGGER(End2EndPerformanceTest);

TEST_P(End2EndPerformanceTest, sendManyRequests) {

    types::ProviderQos providerQos;
    providerQos.setPriority(2);
    auto testProvider = std::make_shared<MockTestProvider>();

    runtime1->registerProvider<tests::testProvider>(domain, testProvider, providerQos);

    std::this_thread::sleep_for(std::chrono::seconds(2));

    ProxyBuilder<tests::testProxy>* testProxyBuilder = runtime2->createProxyBuilder<tests::testProxy>(domain);
    DiscoveryQos discoveryQos;
    discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::HIGHEST_PRIORITY);
    discoveryQos.setDiscoveryTimeout(1000);

    std::int64_t qosRoundTripTTL = 50000;

    // Send a message and expect to get a result
    std::shared_ptr<tests::testProxy> testProxy(testProxyBuilder
                                               ->setMessagingQos(MessagingQos(qosRoundTripTTL))
                                               ->setCached(false)
                                               ->setDiscoveryQos(discoveryQos)
                                               ->build());
    std::uint64_t startTime = DispatcherUtils::nowInMilliseconds();
    std::vector<std::shared_ptr<Future<int> > >testFutureList;
    int numberOfRequests = 150;
    int successfulRequests = 0;
    for (int i=0; i<numberOfRequests; i++){
        std::vector<int> list;
        list.push_back(2);
        list.push_back(4);
        list.push_back(8);
        list.push_back(i);
        testFutureList.push_back(testProxy->sumIntsAsync(list));
    }

    for (int i=0; i<numberOfRequests; i++){
        testFutureList.at(i)->wait();
        int expectedValue = 2+4+8+i;
        if (testFutureList.at(i)->isOk()) {
            successfulRequests++;
            int actualValue;
            testFutureList.at(i)->get(actualValue);
            EXPECT_EQ(expectedValue, actualValue);
        }
    }
    std::uint64_t stopTime = DispatcherUtils::nowInMilliseconds();
    //check if all Requests were successful
    EXPECT_EQ(numberOfRequests, successfulRequests);
    JOYNR_LOG_INFO(logger, "Required Time for 1000 Requests: {}",(stopTime - startTime));
    // to silence unused-variable compiler warnings
    std::ignore = startTime;
    std::ignore = stopTime;
    std::ignore = logger;
}
INSTANTIATE_TEST_CASE_P(Http,
        End2EndPerformanceTest,
        testing::Values(
            std::make_tuple("test-resources/HttpSystemIntegrationTest1.settings","test-resources/HttpSystemIntegrationTest2.settings")
        )
);

INSTANTIATE_TEST_CASE_P(MqttWithHttpBackend,
        End2EndPerformanceTest,
        testing::Values(
            std::make_tuple("test-resources/MqttWithHttpBackendSystemIntegrationTest1.settings","test-resources/MqttWithHttpBackendSystemIntegrationTest2.settings")
        )
);
<commit_msg>[C++] disable sendManyRequests test for HTTP<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */
#include <memory>
#include <string>
#include <cstdint>

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "tests/utils/MockObjects.h"
#include "runtimes/cluster-controller-runtime/JoynrClusterControllerRuntime.h"
#include "joynr/tests/testProxy.h"
#include "joynr/Future.h"
#include "joynr/DispatcherUtils.h"
#include "joynr/LibjoynrSettings.h"
#include "joynr/PrivateCopyAssign.h"

using namespace ::testing;

using namespace joynr;

/*
  * This test tries to create two combined Runtimes and will test communication
  * between the two Runtimes via HttpReceiver
  *
  */

class End2EndPerformanceTest : public TestWithParam< std::tuple<std::string, std::string> > {
public:
    ADD_LOGGER(End2EndPerformanceTest);
    JoynrClusterControllerRuntime* runtime1;
    JoynrClusterControllerRuntime* runtime2;
    Settings *settings1;
    Settings *settings2;
    std::string baseUuid;
    std::string uuid;
    std::string domain;

    End2EndPerformanceTest() :
        runtime1(nullptr),
        runtime2(nullptr),
        settings1(new Settings(std::get<0>(GetParam()))),
        settings2(new Settings(std::get<1>(GetParam()))),
        baseUuid(util::createUuid()),
        uuid( "_" + baseUuid.substr(1, baseUuid.length()-2)),
        domain("cppEnd2EndPerformancesTestDomain" + uuid)
    {

        Settings integration1Settings{"test-resources/libjoynrSystemIntegration1.settings"};
        Settings::merge(integration1Settings, *settings1, false);
        runtime1 = new JoynrClusterControllerRuntime(nullptr, settings1);
        Settings integration2Settings{"test-resources/libjoynrSystemIntegration2.settings"};
        Settings::merge(integration2Settings, *settings2, false);
        runtime2 = new JoynrClusterControllerRuntime(nullptr, settings2);
    }

    void SetUp() {
        runtime1->start();
        runtime2->start();
    }

    void TearDown() {
        bool deleteChannel = true;
        runtime1->stop(deleteChannel);
        runtime2->stop(deleteChannel);

        // Remove participant id persistence file
        std::remove(LibjoynrSettings::DEFAULT_PARTICIPANT_IDS_PERSISTENCE_FILENAME().c_str());
    }

    ~End2EndPerformanceTest(){
        delete runtime1;
        delete runtime2;
    }

private:
    DISALLOW_COPY_AND_ASSIGN(End2EndPerformanceTest);

};

INIT_LOGGER(End2EndPerformanceTest);

TEST_P(End2EndPerformanceTest, sendManyRequests) {

    types::ProviderQos providerQos;
    providerQos.setPriority(2);
    auto testProvider = std::make_shared<MockTestProvider>();

    runtime1->registerProvider<tests::testProvider>(domain, testProvider, providerQos);

    std::this_thread::sleep_for(std::chrono::seconds(2));

    ProxyBuilder<tests::testProxy>* testProxyBuilder = runtime2->createProxyBuilder<tests::testProxy>(domain);
    DiscoveryQos discoveryQos;
    discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::HIGHEST_PRIORITY);
    discoveryQos.setDiscoveryTimeout(1000);

    std::int64_t qosRoundTripTTL = 50000;

    // Send a message and expect to get a result
    std::shared_ptr<tests::testProxy> testProxy(testProxyBuilder
                                               ->setMessagingQos(MessagingQos(qosRoundTripTTL))
                                               ->setCached(false)
                                               ->setDiscoveryQos(discoveryQos)
                                               ->build());
    std::uint64_t startTime = DispatcherUtils::nowInMilliseconds();
    std::vector<std::shared_ptr<Future<int> > >testFutureList;
    int numberOfRequests = 150;
    int successfulRequests = 0;
    for (int i=0; i<numberOfRequests; i++){
        std::vector<int> list;
        list.push_back(2);
        list.push_back(4);
        list.push_back(8);
        list.push_back(i);
        testFutureList.push_back(testProxy->sumIntsAsync(list));
    }

    for (int i=0; i<numberOfRequests; i++){
        testFutureList.at(i)->wait();
        int expectedValue = 2+4+8+i;
        if (testFutureList.at(i)->isOk()) {
            successfulRequests++;
            int actualValue;
            testFutureList.at(i)->get(actualValue);
            EXPECT_EQ(expectedValue, actualValue);
        }
    }
    std::uint64_t stopTime = DispatcherUtils::nowInMilliseconds();
    //check if all Requests were successful
    EXPECT_EQ(numberOfRequests, successfulRequests);
    JOYNR_LOG_INFO(logger, "Required Time for 1000 Requests: {}",(stopTime - startTime));
    // to silence unused-variable compiler warnings
    std::ignore = startTime;
    std::ignore = stopTime;
    std::ignore = logger;
}
INSTANTIATE_TEST_CASE_P(DISABLED_Http,
        End2EndPerformanceTest,
        testing::Values(
            std::make_tuple("test-resources/HttpSystemIntegrationTest1.settings","test-resources/HttpSystemIntegrationTest2.settings")
        )
);

INSTANTIATE_TEST_CASE_P(MqttWithHttpBackend,
        End2EndPerformanceTest,
        testing::Values(
            std::make_tuple("test-resources/MqttWithHttpBackendSystemIntegrationTest1.settings","test-resources/MqttWithHttpBackendSystemIntegrationTest2.settings")
        )
);
<|endoftext|>


<commit_before>//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

#include <assert.h>
#include <dlfcn.h>
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>
#include <set>

// The name of the CoreCLR native runtime DLL.
#if defined(__APPLE__)
static const char * const coreClrDll = "libcoreclr.dylib";
#else
static const char * const coreClrDll = "libcoreclr.so";
#endif

// Windows types used by the ExecuteAssembly function
typedef unsigned int DWORD;
typedef const char16_t* LPCWSTR;
typedef const char* LPCSTR;
typedef int32_t HRESULT;

#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)

// Prototype of the ExecuteAssembly function from the libcoreclr.do
typedef HRESULT (*ExecuteAssemblyFunction)(
                    LPCSTR exePath,
                    LPCSTR coreClrPath,
                    LPCSTR appDomainFriendlyName,
                    int propertyCount,
                    LPCSTR* propertyKeys,
                    LPCSTR* propertyValues,
                    int argc,
                    LPCSTR* argv,
                    LPCSTR managedAssemblyPath,
                    LPCSTR entryPointAssemblyName,
                    LPCSTR entryPointTypeName,
                    LPCSTR entryPointMethodsName,
                    DWORD* exitCode);

// Display the command line options
void DisplayUsage()
{
    fprintf(
        stderr,
        "Usage: corerun [OPTIONS] assembly [ARGUMENTS]\n"
        "Execute the specified managed assembly with the passed in arguments\n\n"
        "Options:\n"
        "-c, --clr-path  path to the libcoreclr.so and the managed CLR assemblies\n");
}

// Get absolute path from the specified path.
// Return true in case of a success, false otherwise.
bool GetAbsolutePath(const char* path, std::string& absolutePath)
{
    bool result = false;

    char realPath[PATH_MAX];
    if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
    {
        absolutePath.assign(realPath);
        // The realpath should return canonicalized path without the trailing slash
        assert(absolutePath.back() != '/');

        result = true;
    }

    return result;
}

void GetDirectory(const char* path, std::string& directory)
{
    directory.assign(path);
    size_t lastSlash = directory.rfind('/');
    directory.erase(lastSlash);
}

// Parse the command line arguments
bool ParseArguments(
        const int argc,
        const char* argv[],
        const char** clrFilesPath,
        const char** managedAssemblyPath,
        int* managedAssemblyArgc,
        const char*** managedAssemblyArgv)
{
    bool success = false;

    *clrFilesPath = nullptr;
    *managedAssemblyPath = nullptr;
    *managedAssemblyArgv = nullptr;
    *managedAssemblyArgc = 0;

    // The command line must contain at least the current exe name and the managed assembly path
    if (argc >= 2)
    {
        for (int i = 1; i < argc; i++)
        {
            // Check for an option
            if (argv[i][0] == '-')
            {
                // Path to the libcoreclr.so and the managed CLR assemblies
                if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--clr-path") == 0)
                {
                    i++;
                    if (i < argc)
                    {
                        *clrFilesPath = argv[i];
                    }
                    else
                    {
                        fprintf(stderr, "Option %s: missing path\n", argv[i - 1]);
                        break;
                    }
                }
                else if (strcmp(argv[i], "--help") == 0)
                {
                    DisplayUsage();
                    break;
                }
                else
                {
                    fprintf(stderr, "Unknown option %s\n", argv[i]);
                    break;
                }
            }
            else
            {
                // First argument that is not an option is the managed assembly to execute
                *managedAssemblyPath = argv[i];

                int managedArgvOffset = (i + 1);
                *managedAssemblyArgc = argc - managedArgvOffset;
                if (*managedAssemblyArgc != 0)
                {
                    *managedAssemblyArgv = &argv[managedArgvOffset];
                }
                success = true;
                break;
            }
        }
    }
    else
    {
        DisplayUsage();
    }

    return success;
}

// Add all *.dll, *.ni.dll, *.exe, and *.ni.exe files from the specified directory
// to the tpaList string;
void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList)
{
    const char * const tpaExtensions[] = {
                ".ni.dll",		// Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
                ".dll",
                ".ni.exe",
                ".exe",
                };

    DIR* dir = opendir(directory);
    if (dir == nullptr)
    {
        return;
    }

    std::set<std::string> addedAssemblies;

    // Walk the directory for each extension separately so that we first get files with .ni.dll extension,
    // then files with .dll extension, etc.
    for (int extIndex = 0; extIndex < sizeof(tpaExtensions) / sizeof(tpaExtensions[0]); extIndex++)
    {
        const char* ext = tpaExtensions[extIndex];
        int extLength = strlen(ext);

        struct dirent* entry;

        // For all entries in the directory
        while ((entry = readdir(dir)) != nullptr)
        {
            // We are interested in files only
            if (entry->d_type != DT_REG)
            {
                continue;
            }

            std::string filename(entry->d_name);

            // Check if the extension matches the one we are looking for
            int extPos = filename.length() - extLength;
            if ((extPos <= 0) || (filename.compare(extPos, extLength, ext) != 0))
            {
                continue;
            }

            std::string filenameWithoutExt(filename.substr(0, extPos));

            // Make sure if we have an assembly with multiple extensions present,
            // we insert only one version of it.
            if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end())
            {
                addedAssemblies.insert(filenameWithoutExt);

                tpaList.append(directory);
                tpaList.append("/");
                tpaList.append(filename);
                tpaList.append(":");
            }
        }

        // Rewind the directory stream to be able to iterate over it for the next extension
        rewinddir(dir);
    }

    closedir(dir);
}

//
// Execute the specified managed assembly.
//
// Parameters:
//  currentExePath          - Path of the current executable
//  clrFilesAbsolutePath    - Absolute path of a folder where the libcoreclr.so and CLR managed assemblies are stored
//  managedAssemblyPath     - Path to the managed assembly to execute
//  managedAssemblyArgc     - Number of arguments passed to the executed assembly
//  managedAssemblyArgv     - Array of arguments passed to the executed assembly
//
// Returns:
//  ExitCode of the assembly
//
int ExecuteManagedAssembly(
            const char* currentExeAbsolutePath,
            const char* clrFilesAbsolutePath,
            const char* managedAssemblyAbsolutePath,
            int managedAssemblyArgc,
            const char** managedAssemblyArgv)
{
    // Indicates failure
    int exitCode = -1;

    std::string coreClrDllPath(clrFilesAbsolutePath);
    coreClrDllPath.append("/");
    coreClrDllPath.append(coreClrDll);

    if (coreClrDllPath.length() >= PATH_MAX)
    {
        fprintf(stderr, "Absolute path to libcoreclr.so too long\n");
        return -1;
    }

    // Get just the path component of the managed assembly path
    std::string appPath;
    GetDirectory(managedAssemblyAbsolutePath, appPath);

    std::string nativeDllSearchDirs(appPath);
    nativeDllSearchDirs.append(":");
    nativeDllSearchDirs.append(clrFilesAbsolutePath);

    std::string tpaList;
    AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList);

    void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_GLOBAL);
    if (coreclrLib != nullptr)
    {
        ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly");
        if (executeAssembly != nullptr)
        {
            // Allowed property names:
            // APPBASE
            // - The base path of the application from which the exe and other assemblies will be loaded
            //
            // TRUSTED_PLATFORM_ASSEMBLIES
            // - The list of complete paths to each of the fully trusted assemblies
            //
            // APP_PATHS
            // - The list of paths which will be probed by the assembly loader
            //
            // APP_NI_PATHS
            // - The list of additional paths that the assembly loader will probe for ngen images
            //
            // NATIVE_DLL_SEARCH_DIRECTORIES
            // - The list of paths that will be probed for native DLLs called by PInvoke
            //
            const char *propertyKeys[] = {
                "TRUSTED_PLATFORM_ASSEMBLIES",
                "APP_PATHS",
                "APP_NI_PATHS",
                "NATIVE_DLL_SEARCH_DIRECTORIES"
            };
            const char *propertyValues[] = {
                // TRUSTED_PLATFORM_ASSEMBLIES
                tpaList.c_str(),
                // APP_PATHS
                appPath.c_str(),
                // APP_NI_PATHS
                appPath.c_str(),
                // NATIVE_DLL_SEARCH_DIRECTORIES
                nativeDllSearchDirs.c_str()
            };

            HRESULT st = executeAssembly(
                            currentExeAbsolutePath,
                            coreClrDllPath.c_str(),
                            "unixcorerun",
                            sizeof(propertyKeys) / sizeof(propertyKeys[0]),
                            propertyKeys,
                            propertyValues,
                            managedAssemblyArgc,
                            managedAssemblyArgv,
                            managedAssemblyAbsolutePath,
                            NULL,
                            NULL,
                            NULL,
                            (DWORD*)&exitCode);

            if (!SUCCEEDED(st))
            {
                fprintf(stderr, "ExecuteAssembly failed - status: 0x%08x\n", st);
            }
        }
        else
        {
            fprintf(stderr, "Function ExecuteAssembly not found in the libcoreclr.so\n");
        }

        if (dlclose(coreclrLib) != 0)
        {
            fprintf(stderr, "Warning - dlclose failed\n");
        }
    }
    else
    {
        char* error = dlerror();
        fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error);
    }

    return exitCode;
}

int main(const int argc, const char* argv[])
{
    const char* clrFilesPath;
    const char* managedAssemblyPath;
    const char** managedAssemblyArgv;
    int managedAssemblyArgc;

    if (!ParseArguments(
            argc,
            argv,
            &clrFilesPath,
            &managedAssemblyPath,
            &managedAssemblyArgc,
            &managedAssemblyArgv))
    {
        // Invalid command line
        return -1;
    }

    // Check if the specified managed assembly file exists
    struct stat sb;
    if (stat(managedAssemblyPath, &sb) == -1)
    {
        perror("Managed assembly not found");
        return -1;
    }

    // Verify that the managed assembly path points to a file
    if (!S_ISREG(sb.st_mode))
    {
        fprintf(stderr, "The specified managed assembly is not a file\n");
        return -1;
    }

    // Convert the specified path to CLR files to an absolute path since the libcoreclr.so
    // requires it.
    std::string clrFilesAbsolutePath;
    std::string clrFilesRelativePath;

    if (clrFilesPath == nullptr)
    {
        // There was no CLR files path specified, use the folder of the corerun
        GetDirectory(argv[0], clrFilesRelativePath);
        clrFilesPath = clrFilesRelativePath.c_str();

        // TODO: consider using an env variable (if defined) as a fall-back.
        // The windows version of the corerun uses core_root env variable
    }

    if (!GetAbsolutePath(clrFilesPath, clrFilesAbsolutePath))
    {
        perror("Failed to convert CLR files path to absolute path");
        return -1;
    }

    std::string managedAssemblyAbsolutePath;
    if (!GetAbsolutePath(managedAssemblyPath, managedAssemblyAbsolutePath))
    {
        perror("Failed to convert managed assembly path to absolute path");
        return -1;
    }

    int exitCode = ExecuteManagedAssembly(
                            argv[0],
                            clrFilesAbsolutePath.c_str(),
                            managedAssemblyAbsolutePath.c_str(),
                            managedAssemblyArgc,
                            managedAssemblyArgv);
    return exitCode;
}
<commit_msg>Fix handling of links and non-Linux file systems in Unix corerun<commit_after>//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

#include <assert.h>
#include <dlfcn.h>
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>
#include <set>

// The name of the CoreCLR native runtime DLL.
#if defined(__APPLE__)
static const char * const coreClrDll = "libcoreclr.dylib";
#else
static const char * const coreClrDll = "libcoreclr.so";
#endif

// Windows types used by the ExecuteAssembly function
typedef unsigned int DWORD;
typedef const char16_t* LPCWSTR;
typedef const char* LPCSTR;
typedef int32_t HRESULT;

#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)

// Prototype of the ExecuteAssembly function from the libcoreclr.do
typedef HRESULT (*ExecuteAssemblyFunction)(
                    LPCSTR exePath,
                    LPCSTR coreClrPath,
                    LPCSTR appDomainFriendlyName,
                    int propertyCount,
                    LPCSTR* propertyKeys,
                    LPCSTR* propertyValues,
                    int argc,
                    LPCSTR* argv,
                    LPCSTR managedAssemblyPath,
                    LPCSTR entryPointAssemblyName,
                    LPCSTR entryPointTypeName,
                    LPCSTR entryPointMethodsName,
                    DWORD* exitCode);

// Display the command line options
void DisplayUsage()
{
    fprintf(
        stderr,
        "Usage: corerun [OPTIONS] assembly [ARGUMENTS]\n"
        "Execute the specified managed assembly with the passed in arguments\n\n"
        "Options:\n"
        "-c, --clr-path  path to the libcoreclr.so and the managed CLR assemblies\n");
}

// Get absolute path from the specified path.
// Return true in case of a success, false otherwise.
bool GetAbsolutePath(const char* path, std::string& absolutePath)
{
    bool result = false;

    char realPath[PATH_MAX];
    if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
    {
        absolutePath.assign(realPath);
        // The realpath should return canonicalized path without the trailing slash
        assert(absolutePath.back() != '/');

        result = true;
    }

    return result;
}

void GetDirectory(const char* path, std::string& directory)
{
    directory.assign(path);
    size_t lastSlash = directory.rfind('/');
    directory.erase(lastSlash);
}

// Parse the command line arguments
bool ParseArguments(
        const int argc,
        const char* argv[],
        const char** clrFilesPath,
        const char** managedAssemblyPath,
        int* managedAssemblyArgc,
        const char*** managedAssemblyArgv)
{
    bool success = false;

    *clrFilesPath = nullptr;
    *managedAssemblyPath = nullptr;
    *managedAssemblyArgv = nullptr;
    *managedAssemblyArgc = 0;

    // The command line must contain at least the current exe name and the managed assembly path
    if (argc >= 2)
    {
        for (int i = 1; i < argc; i++)
        {
            // Check for an option
            if (argv[i][0] == '-')
            {
                // Path to the libcoreclr.so and the managed CLR assemblies
                if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--clr-path") == 0)
                {
                    i++;
                    if (i < argc)
                    {
                        *clrFilesPath = argv[i];
                    }
                    else
                    {
                        fprintf(stderr, "Option %s: missing path\n", argv[i - 1]);
                        break;
                    }
                }
                else if (strcmp(argv[i], "--help") == 0)
                {
                    DisplayUsage();
                    break;
                }
                else
                {
                    fprintf(stderr, "Unknown option %s\n", argv[i]);
                    break;
                }
            }
            else
            {
                // First argument that is not an option is the managed assembly to execute
                *managedAssemblyPath = argv[i];

                int managedArgvOffset = (i + 1);
                *managedAssemblyArgc = argc - managedArgvOffset;
                if (*managedAssemblyArgc != 0)
                {
                    *managedAssemblyArgv = &argv[managedArgvOffset];
                }
                success = true;
                break;
            }
        }
    }
    else
    {
        DisplayUsage();
    }

    return success;
}

// Add all *.dll, *.ni.dll, *.exe, and *.ni.exe files from the specified directory
// to the tpaList string;
void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList)
{
    const char * const tpaExtensions[] = {
                ".ni.dll",		// Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
                ".dll",
                ".ni.exe",
                ".exe",
                };

    DIR* dir = opendir(directory);
    if (dir == nullptr)
    {
        return;
    }

    std::set<std::string> addedAssemblies;

    // Walk the directory for each extension separately so that we first get files with .ni.dll extension,
    // then files with .dll extension, etc.
    for (int extIndex = 0; extIndex < sizeof(tpaExtensions) / sizeof(tpaExtensions[0]); extIndex++)
    {
        const char* ext = tpaExtensions[extIndex];
        int extLength = strlen(ext);

        struct dirent* entry;

        // For all entries in the directory
        while ((entry = readdir(dir)) != nullptr)
        {
            // We are interested in files only
            switch (entry->d_type)
            {
            case DT_REG:
                break;

            // Handle symlinks and file systems that do not support d_type
            case DT_LNK:
            case DT_UNKNOWN:
                {
                    std::string fullFilename;

                    fullFilename.append(directory);
                    fullFilename.append("/");
                    fullFilename.append(entry->d_name);

                    struct stat sb;
                    if (stat(fullFilename.c_str(), &sb) == -1)
                    {
                        continue;
                    }

                    if (!S_ISREG(sb.st_mode))
                    {
                        continue;
                    }
                }
                break;

            default:
                continue;
            }

            std::string filename(entry->d_name);

            // Check if the extension matches the one we are looking for
            int extPos = filename.length() - extLength;
            if ((extPos <= 0) || (filename.compare(extPos, extLength, ext) != 0))
            {
                continue;
            }

            std::string filenameWithoutExt(filename.substr(0, extPos));

            // Make sure if we have an assembly with multiple extensions present,
            // we insert only one version of it.
            if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end())
            {
                addedAssemblies.insert(filenameWithoutExt);

                tpaList.append(directory);
                tpaList.append("/");
                tpaList.append(filename);
                tpaList.append(":");
            }
        }

        // Rewind the directory stream to be able to iterate over it for the next extension
        rewinddir(dir);
    }

    closedir(dir);
}

//
// Execute the specified managed assembly.
//
// Parameters:
//  currentExePath          - Path of the current executable
//  clrFilesAbsolutePath    - Absolute path of a folder where the libcoreclr.so and CLR managed assemblies are stored
//  managedAssemblyPath     - Path to the managed assembly to execute
//  managedAssemblyArgc     - Number of arguments passed to the executed assembly
//  managedAssemblyArgv     - Array of arguments passed to the executed assembly
//
// Returns:
//  ExitCode of the assembly
//
int ExecuteManagedAssembly(
            const char* currentExeAbsolutePath,
            const char* clrFilesAbsolutePath,
            const char* managedAssemblyAbsolutePath,
            int managedAssemblyArgc,
            const char** managedAssemblyArgv)
{
    // Indicates failure
    int exitCode = -1;

    std::string coreClrDllPath(clrFilesAbsolutePath);
    coreClrDllPath.append("/");
    coreClrDllPath.append(coreClrDll);

    if (coreClrDllPath.length() >= PATH_MAX)
    {
        fprintf(stderr, "Absolute path to libcoreclr.so too long\n");
        return -1;
    }

    // Get just the path component of the managed assembly path
    std::string appPath;
    GetDirectory(managedAssemblyAbsolutePath, appPath);

    std::string nativeDllSearchDirs(appPath);
    nativeDllSearchDirs.append(":");
    nativeDllSearchDirs.append(clrFilesAbsolutePath);

    std::string tpaList;
    AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList);

    void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_GLOBAL);
    if (coreclrLib != nullptr)
    {
        ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly");
        if (executeAssembly != nullptr)
        {
            // Allowed property names:
            // APPBASE
            // - The base path of the application from which the exe and other assemblies will be loaded
            //
            // TRUSTED_PLATFORM_ASSEMBLIES
            // - The list of complete paths to each of the fully trusted assemblies
            //
            // APP_PATHS
            // - The list of paths which will be probed by the assembly loader
            //
            // APP_NI_PATHS
            // - The list of additional paths that the assembly loader will probe for ngen images
            //
            // NATIVE_DLL_SEARCH_DIRECTORIES
            // - The list of paths that will be probed for native DLLs called by PInvoke
            //
            const char *propertyKeys[] = {
                "TRUSTED_PLATFORM_ASSEMBLIES",
                "APP_PATHS",
                "APP_NI_PATHS",
                "NATIVE_DLL_SEARCH_DIRECTORIES"
            };
            const char *propertyValues[] = {
                // TRUSTED_PLATFORM_ASSEMBLIES
                tpaList.c_str(),
                // APP_PATHS
                appPath.c_str(),
                // APP_NI_PATHS
                appPath.c_str(),
                // NATIVE_DLL_SEARCH_DIRECTORIES
                nativeDllSearchDirs.c_str()
            };

            HRESULT st = executeAssembly(
                            currentExeAbsolutePath,
                            coreClrDllPath.c_str(),
                            "unixcorerun",
                            sizeof(propertyKeys) / sizeof(propertyKeys[0]),
                            propertyKeys,
                            propertyValues,
                            managedAssemblyArgc,
                            managedAssemblyArgv,
                            managedAssemblyAbsolutePath,
                            NULL,
                            NULL,
                            NULL,
                            (DWORD*)&exitCode);

            if (!SUCCEEDED(st))
            {
                fprintf(stderr, "ExecuteAssembly failed - status: 0x%08x\n", st);
            }
        }
        else
        {
            fprintf(stderr, "Function ExecuteAssembly not found in the libcoreclr.so\n");
        }

        if (dlclose(coreclrLib) != 0)
        {
            fprintf(stderr, "Warning - dlclose failed\n");
        }
    }
    else
    {
        char* error = dlerror();
        fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error);
    }

    return exitCode;
}

int main(const int argc, const char* argv[])
{
    const char* clrFilesPath;
    const char* managedAssemblyPath;
    const char** managedAssemblyArgv;
    int managedAssemblyArgc;

    if (!ParseArguments(
            argc,
            argv,
            &clrFilesPath,
            &managedAssemblyPath,
            &managedAssemblyArgc,
            &managedAssemblyArgv))
    {
        // Invalid command line
        return -1;
    }

    // Check if the specified managed assembly file exists
    struct stat sb;
    if (stat(managedAssemblyPath, &sb) == -1)
    {
        perror("Managed assembly not found");
        return -1;
    }

    // Verify that the managed assembly path points to a file
    if (!S_ISREG(sb.st_mode))
    {
        fprintf(stderr, "The specified managed assembly is not a file\n");
        return -1;
    }

    // Convert the specified path to CLR files to an absolute path since the libcoreclr.so
    // requires it.
    std::string clrFilesAbsolutePath;
    std::string clrFilesRelativePath;

    if (clrFilesPath == nullptr)
    {
        // There was no CLR files path specified, use the folder of the corerun
        GetDirectory(argv[0], clrFilesRelativePath);
        clrFilesPath = clrFilesRelativePath.c_str();

        // TODO: consider using an env variable (if defined) as a fall-back.
        // The windows version of the corerun uses core_root env variable
    }

    if (!GetAbsolutePath(clrFilesPath, clrFilesAbsolutePath))
    {
        perror("Failed to convert CLR files path to absolute path");
        return -1;
    }

    std::string managedAssemblyAbsolutePath;
    if (!GetAbsolutePath(managedAssemblyPath, managedAssemblyAbsolutePath))
    {
        perror("Failed to convert managed assembly path to absolute path");
        return -1;
    }

    int exitCode = ExecuteManagedAssembly(
                            argv[0],
                            clrFilesAbsolutePath.c_str(),
                            managedAssemblyAbsolutePath.c_str(),
                            managedAssemblyArgc,
                            managedAssemblyArgv);
    return exitCode;
}
<|endoftext|>


<commit_before>#define __CL_ENABLE_EXCEPTIONS
#if defined CL_CONTEXT_OFFLINE_DEVICES_AMD
#pragma OPENCL EXTENSION CL_CONTEXT_OFFLINE_DEVICES_AMD : enable
#endif

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include "CL/cl.hpp"
#include <string>
using namespace std;
const char* kernel_code = "__kernel void hello(__global char* string)"
"{string[0] = 'H';"
"string[1] = 'e';"
"string[2] = 'l';"
"string[3] = 'l';"
"string[4] = 'o';"
"string[5] = ',';"
"string[6] = ' ';"
"string[7] = 'W';"
"string[8] = 'o';"
"string[9] = 'r';"
"string[10] = 'l';"
"string[11] = 'd';"
"string[12] = '!';"
"string[13] = '\0';}";

bool buildme(cl::Device& dev, cl::Context& ctx, const char* src)
{
  cout << "\n\nBuilding!\n";
  cout << "Name:\t" << dev.getInfo<CL_DEVICE_NAME>() << endl;
  cout << "Ver:\t" << dev.getInfo<CL_DEVICE_VERSION>() << endl;
  cout << "vendor:\t" << dev.getInfo<CL_DEVICE_VENDOR>() << endl;
  cout << "Type:\t" << dev.getInfo<CL_DEVICE_TYPE>() << endl;
  cout << "Driver:\t" <<dev.getInfo<CL_DRIVER_VERSION>() << endl;

  cl::Program::Sources source(1,std::make_pair(src, strlen(src)));
  cl::Program program = cl::Program(ctx, source);
  try {
    program.build(std::vector<cl::Device>{dev});
  }
  catch (...) {
    cl_int buildErr = CL_SUCCESS;
    auto buildInfo = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(dev);
    cout << buildInfo << endl;
    //for (auto &pair : buildInfo) {
     // std::cerr << pair.second << std::endl << std::endl;
    //}
    return false;
  }
  return false;
}

int main(void)
{
  cl_int err = CL_SUCCESS;
  try {
    std::vector<cl::Platform> platforms;
    cl::Platform::get(&platforms);
    if (platforms.size() == 0) {
      std::cout << "No platforms!\n";
      return -1;
    }
    // Print number of platforms and list of platforms
    std::cout << "Platform available: " << platforms.size() << std::endl;
    std::string platformVendor;
    for (unsigned int i = 0; i < platforms.size(); ++i) {
      platforms[i].getInfo((cl_platform_info)CL_PLATFORM_VENDOR, &platformVendor);
      std::cout << "---\nPlatform is by: " << platformVendor << std::endl;
      string extensions;
      platforms[i].getInfo(CL_PLATFORM_EXTENSIONS, &extensions);
      cout << "Supported Extensions: " << extensions << endl;
      if (strstr(extensions.c_str(), "cl_amd_offline_devices")) {
        std::cout << "amd_offline supported" <<std::endl;
        cl_context_properties properties[] =
        {
          CL_CONTEXT_OFFLINE_DEVICES_AMD,(cl_context_properties) 1,
          CL_CONTEXT_PLATFORM,(cl_context_properties)(platforms[i])(),
          0
        };
        cl::Context context(CL_DEVICE_TYPE_ALL, properties);
        std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
        // Print number of devices and list of devices
        std::cout << "Available Devices: " << devices.size() << std::endl;
        cl::Device* tahiti_device = nullptr;
        for (unsigned int i = 0; i < devices.size(); ++i) {
          std::cout << "Device #" << i << ": " << devices[i].getInfo<CL_DEVICE_NAME>() << std::endl;
          if(devices[i].getInfo<CL_DEVICE_NAME>() == "Tahiti"){
           tahiti_device = &devices[i];
          }
        }
        if(tahiti_device != nullptr){
          buildme(*tahiti_device,context,kernel_code);
        }
      }
    }
  }
  catch (cl::Error err) {
    std::cerr << "ERROR: "<< err.what() << "(" << err.err() << ")" << std::endl;
    return 1;
  }
  return 0;
}
<commit_msg>working on compiler<commit_after>#define __CL_ENABLE_EXCEPTIONS
#if defined CL_CONTEXT_OFFLINE_DEVICES_AMD
#pragma OPENCL EXTENSION CL_CONTEXT_OFFLINE_DEVICES_AMD : enable
#endif

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include "CL/cl.hpp"
#include <string>
using namespace std;
const char* kernel_code = "__kernel void hello(__global char* string)"
"{double gg = 12.0;"
"string[0] = 'H';"
"string[1] = 'e';"
"string[2] = 'l';"
"string[3] = 'l';"
"string[4] = 'o';"
"string[5] = ',';"
"string[6] = ' ';"
"string[7] = 'W';"
"string[8] = 'o';"
"string[9] = 'r';"
"string[10] = 'l';"
"string[11] = 'd';"
"string[12] = '!';"
"string[13] = 0;}";

bool buildme(cl::Device& dev, cl::Context& ctx, const char* src)
{
  cout << "\n\nBuilding!\n";
  cout << "Name:\t" << dev.getInfo<CL_DEVICE_NAME>() << endl;
  cout << "Ver:\t" << dev.getInfo<CL_DEVICE_VERSION>() << endl;
  cout << "vendor:\t" << dev.getInfo<CL_DEVICE_VENDOR>() << endl;
  cout << "Type:\t" << dev.getInfo<CL_DEVICE_TYPE>() << endl;
  cout << "Driver:\t" <<dev.getInfo<CL_DRIVER_VERSION>() << endl;

  cl::Program::Sources source(1,std::make_pair(src, strlen(src)));
  cl::Program program = cl::Program(ctx, source);
/*
  try{
   auto  err = clBuildProgram(src, 1, dev,"-cl-std=CL1.2", NULL, NULL);
     if (err != CL_SUCCESS)
      // show_build_log(src_prog, n_devices, devices, err);
     }
  }catch (...){
  }
*/

  try {
    program.build(std::vector<cl::Device>{dev},"\0-cl-std=CL1.2 -x clc");
  }
  catch (...) {
    cl_int buildErr = CL_SUCCESS;
    auto buildInfo = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(dev);
    cout << "build failed\n" << buildInfo << endl;
    //for (auto &pair : buildInfo) {
     // std::cerr << pair.second << std::endl << std::endl;
    //}
    return false;
  }
  cout << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(dev);
  cout << "\nBuilt?" <<endl;
  return false;
}

int main(void)
{
  cl_int err = CL_SUCCESS;
  try {
    std::vector<cl::Platform> platforms;
    cl::Platform::get(&platforms);
    if (platforms.size() == 0) {
      std::cout << "No platforms!\n";
      return -1;
    }
    // Print number of platforms and list of platforms
    std::cout << "Platform available: " << platforms.size() << std::endl;
    std::string platformVendor;
    for (unsigned int i = 0; i < platforms.size(); ++i) {
      platforms[i].getInfo((cl_platform_info)CL_PLATFORM_VENDOR, &platformVendor);
      std::cout << "---\nPlatform is by: " << platformVendor << std::endl;
      string extensions;
      platforms[i].getInfo(CL_PLATFORM_EXTENSIONS, &extensions);
      cout << "Supported Extensions: " << extensions << endl;
      if (strstr(extensions.c_str(), "cl_amd_offline_devices")) {
        std::cout << "amd_offline supported" <<std::endl;
        cl_context_properties properties[] =
        {
          CL_CONTEXT_OFFLINE_DEVICES_AMD,(cl_context_properties) 1,
          CL_CONTEXT_PLATFORM,(cl_context_properties)(platforms[i])(),
          0
        };
        cl::Context context(CL_DEVICE_TYPE_ALL, properties);
        std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
        // Print number of devices and list of devices
        std::cout << "Available Devices: " << devices.size() << std::endl;
        cl::Device* tahiti_device = nullptr;
        for (unsigned int i = 0; i < devices.size(); ++i) {
          std::cout << "Device #" << i << ": " << devices[i].getInfo<CL_DEVICE_NAME>() << std::endl;
          if(devices[i].getInfo<CL_DEVICE_NAME>() == "Tonga"){
           tahiti_device = &devices[i];
          }
        }
        if(tahiti_device != nullptr){
          buildme(*tahiti_device,context,kernel_code);
        }
      }
    }
  }
  catch (cl::Error err) {
    std::cerr << "ERROR: "<< err.what() << "(" << err.err() << ")" << std::endl;
    return 1;
  }
  return 0;
}
<|endoftext|>


<commit_before>//============================================================================
// Name        : InputManager.cpp
// Author      : Duarte Peixinho
// Version     :
// Copyright   : ;)
// Description : Input Manager
//============================================================================

#include <Pyros3D/Core/InputManager/InputManager.h>

namespace p3d {

    uint32 InputManager::mouseX = 0;
    uint32 InputManager::mouseY = 0;

    std::map<uint32, Gallant::Signal1<Event::Input::Info> > InputManager::EventsMapPressed;
    std::map<uint32, Gallant::Signal1<Event::Input::Info> > InputManager::EventsMapReleased;
    Gallant::Signal1<Event::Input::Info> InputManager::MouseWheelEvents;
    Gallant::Signal1<Event::Input::Info> InputManager::MouseMoveEvents;
    Gallant::Signal1<Event::Input::Info> InputManager::CharacterEnteredPress;
    Gallant::Signal1<Event::Input::Info> InputManager::CharacterEnteredRelease;
    uchar InputManager::Code;

    // Joypad
    std::map <uint32, std::map<uint32, Gallant::Signal1<Event::Input::Info> > > InputManager::JoyPadPressed;
    std::map <uint32, std::map<uint32, Gallant::Signal1<Event::Input::Info> > > InputManager::JoyPadReleased;
    std::map <uint32, std::map<uint32, Gallant::Signal1<Event::Input::Info> > > InputManager::JoyPadMove;

    void InputManager::JoypadButtonPressed(const uint32& joypadID, const uint32& button)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnPress;
        m.Input = button;
        JoyPadPressed[joypadID][button](m);
    }
    void InputManager::JoypadButtonReleased(const uint32& joypadID, const uint32& button)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnRelease;
        m.Input = button;
        JoyPadReleased[joypadID][button](m);
    }
    void InputManager::JoypadMove(const uint32& joypadID, const uint32& axis, const f32 &value)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnMove;
        m.Input = axis;
		m.Value=value;
        JoyPadMove[joypadID][axis](m);
    }

    void InputManager::SetMousePosition(const uint32& mousex, const uint32& mousey)
    {
        mouseX = mousex;
        mouseY = mousey;

        Event::Input::Info m;
        m.Type = Event::Type::OnMove;
        m.Input = Event::Input::Mouse::Move;
		m.Value=Vec2(mouseX, mouseY);
        MouseMoveEvents(m);
    }
    void InputManager::SetMouseWheel(const f32& delta)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnMove;
        m.Input = Event::Input::Mouse::Wheel;
		m.Value=delta;
        MouseWheelEvents(m);
    }
    Vec2 InputManager::GetMousePosition()
    {
        return Vec2(mouseX, mouseY);
    }
    void InputManager::MousePressed(const uint32& e)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnPress;
        m.Input = e;
        EventsMapPressed[e](m);
    }
    void InputManager::MouseReleased(const uint32& e)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnRelease;
        m.Input = e;
        EventsMapReleased[e](m);
    }

    void InputManager::KeyPressed(const uint32& e)
    {

        Event::Input::Info k;
        k.Type = Event::Type::OnPress;
        k.Input = e;

        EventsMapPressed[e](k);

    }
    void InputManager::KeyReleased(const uint32& e)
    {

        Event::Input::Info k;
        k.Type = Event::Type::OnRelease;
        k.Input = e;

        EventsMapReleased[e](k);
    }

    void InputManager::CharEntered(const uint32& e)
    {
#if !defined(ANDROID) && !defined(EMSCRIPTEN)
        // Could be on Pressed or Released, there is nothing different from them
        Code = e;
        Event::Input::Info kPress;
        kPress.Type = Event::Type::OnPress;
        kPress.Input = e;
        EventsMapPressed[Event::Input::Keyboard::OtherKeyboardEvents::CharacterEnter](kPress);

        Event::Input::Info kRelease;
        kRelease.Type = Event::Type::OnRelease;
        kRelease.Input = e;
        EventsMapReleased[Event::Input::Keyboard::OtherKeyboardEvents::CharacterEnter](kRelease);
#endif
    }
};
<commit_msg>InputManager Updated so every event has a value<commit_after>//============================================================================
// Name        : InputManager.cpp
// Author      : Duarte Peixinho
// Version     :
// Copyright   : ;)
// Description : Input Manager
//============================================================================

#include <Pyros3D/Core/InputManager/InputManager.h>

namespace p3d {

    uint32 InputManager::mouseX = 0;
    uint32 InputManager::mouseY = 0;

    std::map<uint32, Gallant::Signal1<Event::Input::Info> > InputManager::EventsMapPressed;
    std::map<uint32, Gallant::Signal1<Event::Input::Info> > InputManager::EventsMapReleased;
    Gallant::Signal1<Event::Input::Info> InputManager::MouseWheelEvents;
    Gallant::Signal1<Event::Input::Info> InputManager::MouseMoveEvents;
    Gallant::Signal1<Event::Input::Info> InputManager::CharacterEnteredPress;
    Gallant::Signal1<Event::Input::Info> InputManager::CharacterEnteredRelease;
    uchar InputManager::Code;

    // Joypad
    std::map <uint32, std::map<uint32, Gallant::Signal1<Event::Input::Info> > > InputManager::JoyPadPressed;
    std::map <uint32, std::map<uint32, Gallant::Signal1<Event::Input::Info> > > InputManager::JoyPadReleased;
    std::map <uint32, std::map<uint32, Gallant::Signal1<Event::Input::Info> > > InputManager::JoyPadMove;

    void InputManager::JoypadButtonPressed(const uint32& joypadID, const uint32& button)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnPress;
        m.Input = button;
		m.Value = button;
        JoyPadPressed[joypadID][button](m);
    }
    void InputManager::JoypadButtonReleased(const uint32& joypadID, const uint32& button)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnRelease;
        m.Input = button;
		m.Value = button;
        JoyPadReleased[joypadID][button](m);
    }
    void InputManager::JoypadMove(const uint32& joypadID, const uint32& axis, const f32 &value)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnMove;
        m.Input = axis;
		m.Value=value;
        JoyPadMove[joypadID][axis](m);
    }

    void InputManager::SetMousePosition(const uint32& mousex, const uint32& mousey)
    {
        mouseX = mousex;
        mouseY = mousey;

        Event::Input::Info m;
        m.Type = Event::Type::OnMove;
        m.Input = Event::Input::Mouse::Move;
		m.Value=Vec2(mouseX, mouseY);
        MouseMoveEvents(m);
    }
    void InputManager::SetMouseWheel(const f32& delta)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnMove;
        m.Input = Event::Input::Mouse::Wheel;
		m.Value=delta;
        MouseWheelEvents(m);
    }
    Vec2 InputManager::GetMousePosition()
    {
        return Vec2(mouseX, mouseY);
    }
    void InputManager::MousePressed(const uint32& e)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnPress;
        m.Input = e;
		m.Value = e;
        EventsMapPressed[e](m);
    }
    void InputManager::MouseReleased(const uint32& e)
    {
        Event::Input::Info m;
        m.Type = Event::Type::OnRelease;
        m.Input = e;
		m.Value = e;
        EventsMapReleased[e](m);
    }

    void InputManager::KeyPressed(const uint32& e)
    {

        Event::Input::Info k;
        k.Type = Event::Type::OnPress;
        k.Input = e;
        k.Value = e;
        EventsMapPressed[e](k);

    }
    void InputManager::KeyReleased(const uint32& e)
    {

        Event::Input::Info k;
        k.Type = Event::Type::OnRelease;
        k.Input = e;
		k.Value = e;
        EventsMapReleased[e](k);
    }

    void InputManager::CharEntered(const uint32& e)
    {
#if !defined(ANDROID) && !defined(EMSCRIPTEN)
        // Could be on Pressed or Released, there is nothing different from them
        Code = e;
        Event::Input::Info kPress;
        kPress.Type = Event::Type::OnPress;
        kPress.Input = e;
		kPress.Value = e;
        EventsMapPressed[Event::Input::Keyboard::OtherKeyboardEvents::CharacterEnter](kPress);

        Event::Input::Info kRelease;
        kRelease.Type = Event::Type::OnRelease;
        kRelease.Input = e;
		kRelease.Value = e;
        EventsMapReleased[Event::Input::Keyboard::OtherKeyboardEvents::CharacterEnter](kRelease);
#endif
    }
};
<|endoftext|>