<commit_before>/**
 * Implements generally useful functions.
 *
 * @file
 */

#include <type_traits> /* std::underlying_type */
#include <charconv>    /* std::from_chars() */
#include <cctype>      /* std::isspace() */
#include <string>

#include <cstdio>      /* snprintf() */

#ifndef _POWERDXX_UTILITY_HPP_
#define _POWERDXX_UTILITY_HPP_

/**
 * A collection of generally useful functions.
 */
namespace utility {

/**
 * Like sizeof(), but it returns the number of elements an array consists
 * of instead of the number of bytes.
 *
 * @tparam T,Count
 *	The type and number of array elements
 * @return
 *	The number of array entries
 */
template <typename T, size_t Count>
constexpr size_t countof(T (&)[Count]) { return Count; }

/**
 * This is a safeguard against accidentally using sprintf().
 *
 * Using it triggers a static_assert(), preventing compilation.
 *
 * @tparam Args
 *	Catch all arguments
 */
template <typename... Args>
inline void sprintf(Args...) {
	/* Assert depends on Args so it can only be determined if
	 * the function is actually instantiated. */
	static_assert(sizeof...(Args) && false,
	              "Use of sprintf() is unsafe, use sprintf_safe() instead");
}

/**
 * A wrapper around snprintf() that automatically pulls in the
 * destination buffer size.
 *
 * @tparam Size
 *	The destination buffer size
 * @tparam Args
 *	The types of the arguments
 * @param dst
 *	A reference to the destination buffer
 * @param format
 *	A printf style formatting string
 * @param args
 *	The printf arguments
 * @return
 *	The number of characters in the resulting string, regardless of the
 *	available space
 */
template <size_t Size, typename... Args>
inline int sprintf_safe(char (& dst)[Size], char const * const format,
                   Args const... args) {
	return snprintf(dst, Size, format, args...);
}

/**
 * Casts an enum to its underlying value.
 *
 * @tparam ET,VT
 *	The enum and value type
 * @param op
 *	The operand to convert
 * @return
 *	The integer representation of the operand
 */
template <class ET, typename VT = typename std::underlying_type<ET>::type>
constexpr VT to_value(ET const op) {
	return static_cast<VT>(op);
}

/**
 * A formatting wrapper around string literals.
 *
 * Overloads operator (), which treats the string as a printf formatting
 * string, the arguments represent the data to format.
 *
 * In combination with the literal _fmt, it can be used like this:
 *
 * ~~~ c++
 * std::cout << "%-15.15s %#018p\n"_fmt("Address:", this);
 * ~~~
 *
 * @tparam BufSize
 *	The buffer size for formatting, resulting strings cannot
 *	grow beyond `BufSize - 1`
 */
template <size_t BufSize>
class Formatter {
	private:
	/**
	 * Pointer to the string literal.
	 */
	char const * const fmt;

	public:
	/**
	 * Construct from string literal.
	 */
	constexpr Formatter(char const * const fmt) : fmt{fmt} {}

	/**
	 * Returns a formatted string.
	 *
	 * @tparam ArgTs
	 *	Variadic argument types
	 * @param args
	 *	Variadic arguments
	 * @return
	 *	An std::string formatted according to fmt
	 */
	template <typename... ArgTs>
	std::string operator ()(ArgTs const &... args) const {
		char buf[BufSize];
		auto count = sprintf_safe(buf, this->fmt, args...);
		if (count < 0) {
			/* encoding error */
			return {};
		} else if (static_cast<size_t>(count) >= BufSize) {
			/* does not fit into buffer */
			return {buf, BufSize - 1};
		}
		return {buf, static_cast<size_t>(count)};
	}
};

/**
 * Contains literal operators.
 */
namespace literals {
/**
 * Literal to convert a string literal to a Formatter instance.
 *
 * @param fmt
 *	A printf style format string
 * @return
 *	A Formatter instance
 */
constexpr Formatter<16384> operator "" _fmt(char const * const fmt, size_t const) {
	return {fmt};
}
} /* namespace literals */

/**
 * A simple value container only allowing += and copy assignment.
 *
 * @tparam T
 *	The value type
 */
template <typename T>
class Sum {
	private:
	/**
	 * The sum of values accumulated.
	 */
	T value;

	public:
	/**
	 * Construct from an initial value.
	 *
	 * @param value
	 *	The initial value
	 */
	explicit constexpr Sum(T const & value) : value{value} {}

	/**
	 * Default construct.
	 */
	constexpr Sum() : Sum{0} {}

	/**
	 * Returns the current sum of values.
	 *
	 * @return
	 *	The sum of values by const reference
	 */
	constexpr operator T const &() const {
		return this->value;
	}

	/**
	 * Add a value to the sum.
	 *
	 * @param value
	 *	The value to add to the current sum
	 * @return
	 *	A self reference
	 */
	constexpr Sum & operator +=(T const & value) {
		this->value += value;
		return *this;
	}
};

/**
 * A simple value container that provides the minimum of assigned values.
 *
 * @tparam T
 *	The value type
 */
template <typename T>
class Min {
	private:
	/**
	 * The minimum of the assigned values.
	 */
	T value;

	public:
	/**
	 * Construct from an initial value.
	 *
	 * @param value
	 *	The initial value
	 */
	explicit constexpr Min(T const & value) : value{value} {}

	/**
	 * Returns the current minimum.
	 *
	 * @return
	 *	The minimum by const reference
	 */
	constexpr operator T const &() const {
		return this->value;
	}

	/**
	 * Assign a new value, if it is less than the current value.
	 *
	 * @param value
	 *	The value to assign
	 * @return
	 *	A self reference
	 */
	constexpr Min & operator =(T const & value) {
		this->value = this->value <= value ? this->value : value;
		return *this;
	}
};

/**
 * A simple value container that provides the maximum of assigned values.
 *
 * @tparam T
 *	The value type
 */
template <typename T>
class Max {
	private:
	/**
	 * The maximum of the assigned values.
	 */
	T value;

	public:
	/**
	 * Construct from an initial value.
	 *
	 * @param value
	 *	The initial value
	 */
	explicit constexpr Max(T const & value) : value{value} {}

	/**
	 * Returns the current maximum.
	 *
	 * @return
	 *	The maximum by const reference
	 */
	constexpr operator T const &() const {
		return this->value;
	}

	/**
	 * Assign a new value, if it is greater than the current value.
	 *
	 * @param value
	 *	The value to assign
	 * @return
	 *	A self reference
	 */
	constexpr Max & operator =(T const & value) {
		this->value = this->value >= value ? this->value : value;
		return *this;
	}
};

/**
 * A functor for reading numerical values from a string or character
 * array.
 */
struct FromChars {
	/**
	 * The next character to read.
	 */
	char const * it;

	/**
	 * The first character of the same array that may not be read,
	 * this should usually point to a terminating zero or behind
	 * a buffer.
	 */
	char const * const end;

	/**
	 * Retrieve an integral or floating point value from the array.
	 *
	 * The operation may fail for multiple reasons:
	 *
	 * - No more characters left to read, in that case the functor
	 *   will equal false
	 * - The given characters do not represent a valid value, in
	 *   that case the functor will equal true
	 *
	 * @tparam T
	 *	The value type to retrieve
	 * @param dst
	 *	The lvalue to assign to
	 * @retval true
	 *	The numerical value was successfully read from the array
	 * @retval false
	 *	The numerical value could not be read from the array
	 */
	template <typename T>
	[[nodiscard]] bool operator ()(T & dst) {
		if (!this->it) {
			return false;
		}
		auto [p, ec] = std::from_chars(this->it, this->end, dst);
		if (this->it == p) {
			return false;
		}
		for (; p != this->end && std::isspace(*p); ++p);
		this->it = p;
		return true;
	}

	/**
	 * Check if unread characters remain.
	 *
	 * @retval false
	 *	All characters have been read
	 * @retval true
	 *	Characters remain to be read
	 */
	operator bool() const {
		return this->it && this->end != this->it && *this->it;
	}

	/**
	 * Range based constructor.
	 *
	 * @param start,end
	 *	The character array range
	 */
	FromChars(char const * const start, char const * const end) :
	    it{start}, end{end} {
		for (; this->it != end && std::isspace(*this->it); ++this->it);
	}

	/**
	 * Construct from a character array.
	 *
	 * @tparam CountV
	 *	The number of characters
	 * @param str
	 *	Tha character array to parse from
	 * @param terminator
	 *	Indicates whether the character array has a terminating
	 *	null character.
	 */
	template <size_t CountV>
	FromChars(char const (& str)[CountV], bool terminator = true) :
	    FromChars{str, str + CountV - terminator} {}

	/**
	 * Construct functor from a string.
	 *
	 * Note that changing the string during the lifetime of the
	 * functor may silently invalidate the functor's state and
	 * thus invoke undefined behaviour.
	 *
	 * @param str
	 *	The string to parse from
	 */
	FromChars(std::string const & str) :
	    FromChars{str.data(), str.data() + str.size()} {}
};

} /* namespace utility */

#endif /* _POWERDXX_UTILITY_HPP_ */
<commit_msg>Fix typos<commit_after>/**
 * Implements generally useful functions.
 *
 * @file
 */

#include <type_traits> /* std::underlying_type */
#include <charconv>    /* std::from_chars() */
#include <cctype>      /* std::isspace() */
#include <string>

#include <cstdio>      /* snprintf() */

#ifndef _POWERDXX_UTILITY_HPP_
#define _POWERDXX_UTILITY_HPP_

/**
 * A collection of generally useful functions.
 */
namespace utility {

/**
 * Like sizeof(), but it returns the number of elements an array consists
 * of instead of the number of bytes.
 *
 * @tparam T,Count
 *	The type and number of array elements
 * @return
 *	The number of array entries
 */
template <typename T, size_t Count>
constexpr size_t countof(T (&)[Count]) { return Count; }

/**
 * This is a safeguard against accidentally using sprintf().
 *
 * Using it triggers a static_assert(), preventing compilation.
 *
 * @tparam Args
 *	Catch all arguments
 */
template <typename... Args>
inline void sprintf(Args...) {
	/* Assert depends on Args so it can only be determined if
	 * the function is actually instantiated. */
	static_assert(sizeof...(Args) && false,
	              "Use of sprintf() is unsafe, use sprintf_safe() instead");
}

/**
 * A wrapper around snprintf() that automatically pulls in the
 * destination buffer size.
 *
 * @tparam Size
 *	The destination buffer size
 * @tparam Args
 *	The types of the arguments
 * @param dst
 *	A reference to the destination buffer
 * @param format
 *	A printf style formatting string
 * @param args
 *	The printf arguments
 * @return
 *	The number of characters in the resulting string, regardless of the
 *	available space
 */
template <size_t Size, typename... Args>
inline int sprintf_safe(char (& dst)[Size], char const * const format,
                   Args const... args) {
	return snprintf(dst, Size, format, args...);
}

/**
 * Casts an enum to its underlying value.
 *
 * @tparam ET,VT
 *	The enum and value type
 * @param op
 *	The operand to convert
 * @return
 *	The integer representation of the operand
 */
template <class ET, typename VT = typename std::underlying_type<ET>::type>
constexpr VT to_value(ET const op) {
	return static_cast<VT>(op);
}

/**
 * A formatting wrapper around string literals.
 *
 * Overloads operator (), which treats the string as a printf formatting
 * string, the arguments represent the data to format.
 *
 * In combination with the literal _fmt, it can be used like this:
 *
 * ~~~ c++
 * std::cout << "%-15.15s %#018p\n"_fmt("Address:", this);
 * ~~~
 *
 * @tparam BufSize
 *	The buffer size for formatting, resulting strings cannot
 *	grow beyond `BufSize - 1`
 */
template <size_t BufSize>
class Formatter {
	private:
	/**
	 * Pointer to the string literal.
	 */
	char const * const fmt;

	public:
	/**
	 * Construct from string literal.
	 */
	constexpr Formatter(char const * const fmt) : fmt{fmt} {}

	/**
	 * Returns a formatted string.
	 *
	 * @tparam ArgTs
	 *	Variadic argument types
	 * @param args
	 *	Variadic arguments
	 * @return
	 *	An std::string formatted according to fmt
	 */
	template <typename... ArgTs>
	std::string operator ()(ArgTs const &... args) const {
		char buf[BufSize];
		auto count = sprintf_safe(buf, this->fmt, args...);
		if (count < 0) {
			/* encoding error */
			return {};
		} else if (static_cast<size_t>(count) >= BufSize) {
			/* does not fit into buffer */
			return {buf, BufSize - 1};
		}
		return {buf, static_cast<size_t>(count)};
	}
};

/**
 * Contains literal operators.
 */
namespace literals {
/**
 * Literal to convert a string literal to a Formatter instance.
 *
 * @param fmt
 *	A printf style format string
 * @return
 *	A Formatter instance
 */
constexpr Formatter<16384> operator "" _fmt(char const * const fmt, size_t const) {
	return {fmt};
}
} /* namespace literals */

/**
 * A simple value container only allowing += and copy assignment.
 *
 * @tparam T
 *	The value type
 */
template <typename T>
class Sum {
	private:
	/**
	 * The sum of values accumulated.
	 */
	T value;

	public:
	/**
	 * Construct from an initial value.
	 *
	 * @param value
	 *	The initial value
	 */
	explicit constexpr Sum(T const & value) : value{value} {}

	/**
	 * Default construct.
	 */
	constexpr Sum() : Sum{0} {}

	/**
	 * Returns the current sum of values.
	 *
	 * @return
	 *	The sum of values by const reference
	 */
	constexpr operator T const &() const {
		return this->value;
	}

	/**
	 * Add a value to the sum.
	 *
	 * @param value
	 *	The value to add to the current sum
	 * @return
	 *	A self reference
	 */
	constexpr Sum & operator +=(T const & value) {
		this->value += value;
		return *this;
	}
};

/**
 * A simple value container that provides the minimum of assigned values.
 *
 * @tparam T
 *	The value type
 */
template <typename T>
class Min {
	private:
	/**
	 * The minimum of the assigned values.
	 */
	T value;

	public:
	/**
	 * Construct from an initial value.
	 *
	 * @param value
	 *	The initial value
	 */
	explicit constexpr Min(T const & value) : value{value} {}

	/**
	 * Returns the current minimum.
	 *
	 * @return
	 *	The minimum by const reference
	 */
	constexpr operator T const &() const {
		return this->value;
	}

	/**
	 * Assign a new value, if it is less than the current value.
	 *
	 * @param value
	 *	The value to assign
	 * @return
	 *	A self reference
	 */
	constexpr Min & operator =(T const & value) {
		this->value = this->value <= value ? this->value : value;
		return *this;
	}
};

/**
 * A simple value container that provides the maximum of assigned values.
 *
 * @tparam T
 *	The value type
 */
template <typename T>
class Max {
	private:
	/**
	 * The maximum of the assigned values.
	 */
	T value;

	public:
	/**
	 * Construct from an initial value.
	 *
	 * @param value
	 *	The initial value
	 */
	explicit constexpr Max(T const & value) : value{value} {}

	/**
	 * Returns the current maximum.
	 *
	 * @return
	 *	The maximum by const reference
	 */
	constexpr operator T const &() const {
		return this->value;
	}

	/**
	 * Assign a new value, if it is greater than the current value.
	 *
	 * @param value
	 *	The value to assign
	 * @return
	 *	A self reference
	 */
	constexpr Max & operator =(T const & value) {
		this->value = this->value >= value ? this->value : value;
		return *this;
	}
};

/**
 * A functor for reading numerical values from a string or character
 * array.
 */
struct FromChars {
	/**
	 * The next character to read.
	 */
	char const * it;

	/**
	 * The first character of the same array that may not be read,
	 * this should usually point to a terminating zero or behind
	 * a buffer.
	 */
	char const * const end;

	/**
	 * Retrieve an integral or floating point value from the array.
	 *
	 * The operation may fail for multiple reasons:
	 *
	 * - No more characters left to read, in that case the functor
	 *   will equal false
	 * - The given characters do not represent a valid value, in
	 *   that case the functor will equal true
	 *
	 * @tparam T
	 *	The value type to retrieve
	 * @param dst
	 *	The lvalue to assign to
	 * @retval true
	 *	The numerical value was successfully read from the array
	 * @retval false
	 *	The numerical value could not be read from the array
	 */
	template <typename T>
	[[nodiscard]] bool operator ()(T & dst) {
		if (!this->it) {
			return false;
		}
		auto [p, ec] = std::from_chars(this->it, this->end, dst);
		if (this->it == p) {
			return false;
		}
		for (; p != this->end && std::isspace(*p); ++p);
		this->it = p;
		return true;
	}

	/**
	 * Check if unread characters remain.
	 *
	 * @retval false
	 *	All characters have been read
	 * @retval true
	 *	Characters remain to be read
	 */
	operator bool() const {
		return this->it && this->end != this->it && *this->it;
	}

	/**
	 * Range based constructor.
	 *
	 * @param start,end
	 *	The character array range
	 */
	FromChars(char const * const start, char const * const end) :
	    it{start}, end{end} {
		for (; this->it != end && std::isspace(*this->it); ++this->it);
	}

	/**
	 * Construct from a character array.
	 *
	 * @tparam CountV
	 *	The number of characters
	 * @param str
	 *	The character array to parse from
	 * @param terminator
	 *	Indicates whether the character array has a terminating
	 *	null character.
	 */
	template <size_t CountV>
	FromChars(char const (& str)[CountV], bool const terminator = true) :
	    FromChars{str, str + CountV - terminator} {}

	/**
	 * Construct functor from a string.
	 *
	 * Note that changing the string during the lifetime of the
	 * functor may silently invalidate the functor's state and
	 * thus invoke undefined behaviour.
	 *
	 * @param str
	 *	The string to parse from
	 */
	FromChars(std::string const & str) :
	    FromChars{str.data(), str.data() + str.size()} {}
};

} /* namespace utility */

#endif /* _POWERDXX_UTILITY_HPP_ */
<|endoftext|>


<commit_before>#ifndef UTILITY_HPP
#define UTILITY_HPP
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <unordered_map>
#include <limits>
#include <typeinfo>
#include <random>
#include <utility>
#include <functional>
#include <thread>
#include "MDL/mdl_file.hpp"
#include "vector.hpp"
#include "SDL2/SDL.h"

namespace tz
{
	namespace consts
	{
		/// 3.14159...
		constexpr double pi = 4 * std::atan(1);
		/// 2.17...
		constexpr double e = std::exp(1);
	}
	namespace literals
	{
		/**
		* Convert a mass in metric kilograms (kg) to imperial pounds (lb).
		*/
		inline long double operator""_lb(long double mass)
		{
			return mass * 0.45359237;
		}
		/**
		* Convert a mass in metric kilograms(kg) to imperial stone (st).
		*/
		inline long double operator""_st(long double mass)
		{
			using namespace tz::literals;
			return operator""_lb(mass * 14.0);
		}
		/**
		* Convert an angle in degrees to an angle in radians.
		* i.e: 180_deg = π
		*/
		inline long double operator""_deg(long double angle)
		{
			return angle * tz::consts::pi / 180.0;
		}
		/**
		* Convert an angle in radians to an angle in degrees.
		* i.e: π_rad = 180
		*/
		inline long double operator""_rad(long double angle)
		{
			return angle * 180.0 / tz::consts::pi;
		}
	}
	namespace util
	{
		/**
		 * Given a container, find the size, in bytes, of an element in the container.
		 * @tparam Container - Container type.
		 * @param element_list - Container of elements.
		 * @return
		 */
		template<typename Container>
		constexpr std::size_t sizeof_element(Container element_list);

		namespace cast
		{
			/**
			* Convert anything that can be converted into an std::string, into an std::string.
			*/
			template <typename T>
			inline std::string to_string(T&& obj);
			/**
			* Convert an std::string to any value, if it can.
			*/
			template <typename T>
			inline T from_string(const std::string& s);
		}

		/**
		* Perform processing on std::strings with these utility functions.
		*/
		namespace string
		{
			inline std::string to_lower(std::string data);
			inline std::string to_upper(std::string data);
			inline bool begins_with(const std::string& what, const std::string& with_what);
			inline bool ends_with(const std::string& what, const std::string& with_what);
			inline bool contains(const std::string& what, char withwhat);
			inline std::vector<std::string> split_string(const std::string& s, const std::string& delim);
			inline std::vector<std::string> split_string(const std::string& s, char delim);
			inline std::string replace_all_char(const std::string& str, char toreplace, const std::string& replacewith);
			inline std::string replace_all(std::string str, const std::string& to_replace, const std::string& replace_with);
			inline std::string substring(const std::string& str, std::size_t begin, std::size_t end);
			inline std::string format(const std::vector<std::string>& split);
			inline std::vector<std::string> deformat(const std::string& str);
			template<typename T>
			inline Vector3<T> vectorise_list_3(const std::vector<std::string>& list);
			template<typename T>
			inline std::vector<std::string> devectorise_list_3(Vector3<T> v);
		}

		/**
		* Log to the console variadically.
		* Like printf, but without the formatting and with type-safety.
		*/
		namespace log
		{
			inline void silent();
			template<typename FirstArg, typename... Args>
			inline void silent(FirstArg arg, Args... args);
			template<typename FirstArg = void, typename... Args>
			inline void message(FirstArg arg, Args... args);
			template<typename FirstArg = void, typename... Args>
			inline void warning(FirstArg arg, Args... args);
			template<typename FirstArg = void, typename... Args>
			inline void error(FirstArg arg, Args... args);
		}

		namespace scheduler
		{
			/**
			* Invokes std::functions synchronously (pretty much just runs a function for you) or asynchronously (runs the function in another thread as to not impede current processing).
			* You may well find this incredibly useful, however it does contain some overhead and therefore is not recommended for small, menial tasks.
			* For smaller and simpler tasks, it is highly recommended that you instead use tz::util::scheduler::[a]sync_delayed_functor(TrivialFunctor), in command.hpp.
			*/
			template<class ReturnType, class... Args>
			inline void sync_delayed_function(unsigned int milliseconds_delay, std::function<ReturnType(Args...)> f, Args... args);
			template<class ReturnType, class... Args>
			inline void async_delayed_function(unsigned int milliseconds_delay, std::function<ReturnType(Args...)> f, Args... args);
		}
			template<typename Number = int>
			inline Number random();
	}
}

/**
* Generate a random number using any of the C++ standard library random engines.
* Using default template arguments yields implementation-defined behaviour, but normally is a linear-congruentional engine.
*/
template<typename Engine = std::default_random_engine, typename EngineResultType = std::default_random_engine::result_type>
class Random
{
public:
	Random<Engine, EngineResultType>(EngineResultType seed = std::random_device()());
	Random<Engine, EngineResultType>(const Random<Engine, EngineResultType>& copy);
	Random<Engine, EngineResultType>(Random<Engine, EngineResultType>&& move) = default;
	~Random<Engine, EngineResultType>() = default;
	Random<Engine, EngineResultType>& operator=(const Random<Engine, EngineResultType>& rhs) = default;

	const EngineResultType& get_seed() const;
	const Engine& get_engine() const;
	int next_int(int min = 0, int max = std::numeric_limits<int>::max());
	float next_float(float min = 0, float max = std::numeric_limits<float>::max());
	template <typename Number = int>
	inline Number operator()(Number min = Number(), Number max = std::numeric_limits<Number>::max());
private:
	const EngineResultType seed;
	Engine random_engine;
};

/**
* Template specialisation of Random, using the C++ mersenne-twister functionality.
* More expensive than a linear-congruentional approach, but does provide higher-quality pseudorandomness.
*/
using MersenneTwister = Random<std::mt19937, std::mt19937::result_type>;

/**
 * Wrapper for a function with variadic arguments. Unlike TrivialFunctor, cannot be inserted into a CommandExecutor.
 */
template<typename FunctorT>
class Functor
{
public:
	Functor(FunctorT functor);
	template<typename... FunctorParameters>
	void operator()(FunctorParameters... parameters);
private:
	FunctorT functor;
};
#include "utility.inl"
#endif<commit_msg>utility.hpp completely documented now I think. It was horrific<commit_after>#ifndef UTILITY_HPP
#define UTILITY_HPP
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <unordered_map>
#include <limits>
#include <typeinfo>
#include <random>
#include <utility>
#include <functional>
#include <thread>
#include "MDL/mdl_file.hpp"
#include "vector.hpp"
#include "SDL2/SDL.h"

namespace tz
{
	namespace consts
	{
		/// 3.14159...
		constexpr double pi = 4 * std::atan(1);
		/// 2.17...
		constexpr double e = std::exp(1);
	}
	namespace literals
	{
		/**
		* Convert a mass in metric kilograms (kg) to imperial pounds (lb).
		*/
		inline long double operator""_lb(long double mass)
		{
			return mass * 0.45359237;
		}
		/**
		* Convert a mass in metric kilograms(kg) to imperial stone (st).
		*/
		inline long double operator""_st(long double mass)
		{
			using namespace tz::literals;
			return operator""_lb(mass * 14.0);
		}
		/**
		* Convert an angle in degrees to an angle in radians.
		* i.e: 180_deg = π
		*/
		inline long double operator""_deg(long double angle)
		{
			return angle * tz::consts::pi / 180.0;
		}
		/**
		* Convert an angle in radians to an angle in degrees.
		* i.e: π_rad = 180
		*/
		inline long double operator""_rad(long double angle)
		{
			return angle * 180.0 / tz::consts::pi;
		}
	}
	namespace util
	{
		/**
		 * Given a container, find the size, in bytes, of an element in the container.
		 * @tparam Container - Container type.
		 * @param element_list - Container of elements.
		 * @return
		 */
		template<typename Container>
		constexpr std::size_t sizeof_element(Container element_list);

		namespace cast
		{
			/**
			 * (Attempt to) Convert an object to a std::string.
			 * @tparam T - Type of the object to convert
			 * @param obj - The object to convert
			 * @return - The object, converted to a string
			 */
			template <typename T>
			inline std::string to_string(T&& obj);
			/**
			 * (Attempt to) Convert an std::string to an object of specified type.
			 * @tparam T - Type of the object to convert to
			 * @param s - The object to convert to
			 * @return - The object that the string was converted to
			 */
			template <typename T>
			inline T from_string(const std::string& s);
		}

		/**
		* Perform processing on std::strings with these utility functions.
		*/
		namespace string
		{
		    /**
		     * Convert the input string to lower-case.
		     * @param data - The string to convert to lower-case
		     * @return - data, in lower-case
		     */
			inline std::string to_lower(std::string data);
            /**
             * Convert the input string to upper-case.
             * @param data - The string to convert to upper-case
             * @return - data, in upper-case
             */
			inline std::string to_upper(std::string data);
			/**
			 * Query whether an existing string begins with another.
			 * @param what - The string to query
			 * @param with_what - The prefix to equate
			 * @return - True if with starts with with_what. False otherwise
			 */
			inline bool begins_with(const std::string& what, const std::string& with_what);
            /**
             * Query whether an existing string ends with another.
             * @param what - The string to query
             * @param with_what - The suffix to equate
             * @return - True if with ends with with_what. False otherwise
             */
			inline bool ends_with(const std::string& what, const std::string& with_what);
			/**
			 * Query whether an existing string contains another substring.
			 * @param what - The string to query
			 * @param withwhat - The substring to query for containment
			 * @return - True if what contains the substring withwhat. False otherwise
			 */
			inline bool contains(const std::string& what, char withwhat);
			/**
			 * Split an existing string with a specified delimiter.
			 * @param s - The string to perform on
			 * @param delim - The delimiter to use
			 * @return - Container of strings, split from the source string via the specified delimiter
			 */
			inline std::vector<std::string> split_string(const std::string& s, const std::string& delim);
            /**
             * Split an existing string with a specified delimiter.
             * @param s - The string to perform on
             * @param delim - The delimiter to use
             * @return - Container of strings, split from the source string via the specified delimiter
             */
			inline std::vector<std::string> split_string(const std::string& s, char delim);
			/**
			 * Replace all instances of a character in a specified string with a replacement string.
			 * @param str - The specified string
			 * @param toreplace - The character to be replaced
			 * @param replacewith - The replacement string
			 * @return - The edited source string
			 */
			inline std::string replace_all_char(const std::string& str, char toreplace, const std::string& replacewith);
			/**
			 * Replace all instances of a string in a specified string with a replacement string.
			 * @param str - The specified string
			 * @param to_replace - The string to be replaced
			 * @param replace_with - The replacement string
			 * @return - The edited source string
			 */
			inline std::string replace_all(std::string str, const std::string& to_replace, const std::string& replace_with);
			/**
			 * Construct a substring from an existing string between two indices.
			 * @param str - The source string
			 * @param begin - The first index
			 * @param end - The second index
			 * @return - The substring
			 */
			inline std::string substring(const std::string& str, std::size_t begin, std::size_t end);
			/**
			 * Emplace all elements of a container of strings within the following string:
			 * [element0, element1, etc...]
			 * @param split - The container of strings to format
			 * @return - The formatted container of strings
			 */
			inline std::string format(const std::vector<std::string>& split);
			/**
			 * Given a formatted string, extract all the elements contained within the formatted string.
			 * @param str - The formatted string
			 * @return - Container of the strings in the formatted string
			 */
			inline std::vector<std::string> deformat(const std::string& str);
			/**
			 * Convert the first three elements of a container of strings into the type T, and place into a 3-dimensional Vector.
			 * @tparam T - The type to store into the 3-dimensional Vector
			 * @param list - The container of strings
			 * @return - The resultant 3-dimensional Vector
			 */
			template<typename T>
			inline Vector3<T> vectorise_list_3(const std::vector<std::string>& list);
			/**
			 * Given a 3-dimensional Vector containing types T, convert them into a string and place within a container.
			 * @tparam T - Type of the elements in the 3-dimensional Vector
			 * @param v - The 3-dimensional Vector to extract from
			 * @return - The resultant container of strings
			 */
			template<typename T>
			inline std::vector<std::string> devectorise_list_3(Vector3<T> v);
		}

		/**
		* Log to the console variadically.
		* Like printf, but without the formatting and with type-safety.
		*/
		namespace log
		{
		    /// Base-case for log::silent, log::message, log::warning and log::error.
			inline void silent();
			/**
			 * Essentially a printf but without formatting. Prints the parameters to the standard output.
			 * @tparam FirstArg - Type of the first argument
			 * @tparam Args - Type of the remaining arguments
			 * @param arg - The first argument
			 * @param args - The remaining arguments
			 */
			template<typename FirstArg, typename... Args>
			inline void silent(FirstArg arg, Args... args);
			/**
			 * Print the parameters with Topaz-formatting to the standard output.
			 * Output: [Message]: parameters
			 * @tparam FirstArg - Type of the first argument
			 * @tparam Args - Type of the remaining arguments
			 * @param arg - The first argument
			 * @param args - The remaining arguments
			 */
			template<typename FirstArg = void, typename... Args>
			inline void message(FirstArg arg, Args... args);
            /**
             * Print the parameters with Topaz-formatting to the standard output.
             * Output: [Warning]: parameters
             * @tparam FirstArg - Type of the first argument
             * @tparam Args - Type of the remaining arguments
             * @param arg - The first argument
             * @param args - The remaining arguments
             */
			template<typename FirstArg = void, typename... Args>
			inline void warning(FirstArg arg, Args... args);
            /**
             * Print the parameters with Topaz-formatting to the standard output.
             * Output: [Error]: parameters
             * @tparam FirstArg - Type of the first argument
             * @tparam Args - Type of the remaining arguments
             * @param arg - The first argument
             * @param args - The remaining arguments
             */
			template<typename FirstArg = void, typename... Args>
			inline void error(FirstArg arg, Args... args);
		}

		namespace scheduler
		{
			/**
			 * Invokes a function synchronously with specified arguments after a specified delay.
			 * @tparam ReturnType - Return type of the function
			 * @tparam Args - Argument types of the function
			 * @param milliseconds_delay - Number of milliseconds to elapse before executing the function.
			 * @param f - The function to execute
			 * @param args - Arguments to emplace into the function invocation
			 */
			template<class ReturnType, class... Args>
			inline void sync_delayed_function(unsigned int milliseconds_delay, std::function<ReturnType(Args...)> f, Args... args);
            /**
             * Invokes a function asynchronously with specified arguments after a specified delay.
             * @tparam ReturnType - Return type of the function
             * @tparam Args - Argument types of the function
             * @param milliseconds_delay - Number of milliseconds to elapse before executing the function.
             * @param f - The function to execute
             * @param args - Arguments to emplace into the function invocation
             */
			template<class ReturnType, class... Args>
			inline void async_delayed_function(unsigned int milliseconds_delay, std::function<ReturnType(Args...)> f, Args... args);
		}

		/**
		 * Generate a random number.
		 * @tparam Number - Type of the number
		 * @return - The random number generated
		 */
		template<typename Number = int>
        inline Number random();
	}
}

/**
 * Object to generate random numbers with a given RNG-engine.
 * @tparam Engine - Random engine device
 * @tparam EngineResultType - Return type of the engine's productions
 */
template<typename Engine = std::default_random_engine, typename EngineResultType = std::default_random_engine::result_type>
class Random
{
public:
    /**
     * Generate a Random from a seed.
     * @param seed - The seed for the RNG engine
     */
	Random<Engine, EngineResultType>(EngineResultType seed = std::random_device()());
	/**
	 * Construct a Random from an existing, using their seed and engine.
	 * @param copy - Random object to copy the seed and engine from.
	 */
	Random<Engine, EngineResultType>(const Random<Engine, EngineResultType>& copy);

	/**
	 * Get the value of the seed to this engine.
	 * @return - The seed value
	 */
	const EngineResultType& get_seed() const;
	/**
	 * Read-only access to the underlying random engine.
	 * @return - The random engine being used
	 */
	const Engine& get_engine() const;
	/**
	 * Generate a random signed integer between specified limits.
	 * @param min - The minimum result of the integer
	 * @param max - The maximum result of the integer
	 * @return
	 */
	int next_int(int min = 0, int max = std::numeric_limits<int>::max());
    /**
     * Generate a random float between specified limits.
     * @param min - The minimum result of the float
     * @param max - The maximum result of the float
     * @return
     */
	float next_float(float min = 0, float max = std::numeric_limits<float>::max());
    /**
     * Generate a random number between specified limits.
     * @tparam Number - The type of value to generate
     * @param min - The minimum result of the number
     * @param max - The maximum result of the number
     * @return
     */
	template <typename Number = int>
	inline Number operator()(Number min = Number(), Number max = std::numeric_limits<Number>::max());
private:
    /// Stores the seed used for this Random object.
	const EngineResultType seed;
    /// Stores the underlying RNG engine for this Random object.
	Engine random_engine;
};

/**
* Template specialisation of Random, using the C++ mersenne-twister functionality.
* More expensive than a linear-congruentional approach, but does provide higher-quality pseudorandomness.
*/
using MersenneTwister = Random<std::mt19937, std::mt19937::result_type>;

/**
 * Wrapper for a Functor, using variadic arguments.
 * @tparam FunctorT - Type of the functor
 */
template<typename FunctorT>
class Functor
{
public:
    /**
     * Generate a Functor directly from a callable type.
     * @param functor - The functor value
     */
	Functor(FunctorT functor);
	/**
	 * Execute the functor, providing all parameter values
	 * @tparam FunctorParameters - Types of the functor parameters
	 * @param parameters - Values of the functor parameters
	 */
	template<typename... FunctorParameters>
	void operator()(FunctorParameters... parameters);
private:
    /// The underlying functor.
	FunctorT functor;
};
#include "utility.inl"
#endif<|endoftext|>


<commit_before>// Copyright (c) 2012 Hewlett-Packard Development Company, L.P. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <v8_webgl.h>
#include "canvas.h"
#include "console.h"
#include "webgl_rendering_context.h"

namespace v8_webgl {

static Factory* s_factory = 0;
static v8::Persistent<v8::ObjectTemplate> s_global;

v8::Persistent<v8::ObjectTemplate> Initialize(Factory* factory) {
  if (!s_global.IsEmpty())
    return s_global;

  s_factory = factory;

  v8::HandleScope scope;
  v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
  s_global = v8::Persistent<v8::ObjectTemplate>::New(global);

  Console::Initialize(s_global);
  Canvas::Initialize(s_global);
  WebGLRenderingContext::Initialize(s_global);
  //XXX initialize webgl classes with global

  return s_global;
}

void Uninitialize() {
  if (s_global.IsEmpty())
    return;
  s_global.Dispose();
  s_global.Clear();

  delete s_factory;
  s_factory = 0;

  Console::Uninitialize();
  Canvas::Uninitialize();
  WebGLRenderingContext::Uninitialize();
  //XXX uninitialize webgl classes

  v8::V8::Dispose();
}

Factory* GetFactory() {
  return s_factory;
}

}
<commit_msg>Try to GC everything when shutting down.<commit_after>// Copyright (c) 2012 Hewlett-Packard Development Company, L.P. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <v8_webgl.h>
#include "canvas.h"
#include "console.h"
#include "webgl_rendering_context.h"

namespace v8_webgl {

static Factory* s_factory = 0;
static v8::Persistent<v8::ObjectTemplate> s_global;

v8::Persistent<v8::ObjectTemplate> Initialize(Factory* factory) {
  if (!s_global.IsEmpty())
    return s_global;

  s_factory = factory;

  v8::HandleScope scope;
  v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
  s_global = v8::Persistent<v8::ObjectTemplate>::New(global);

  Console::Initialize(s_global);
  Canvas::Initialize(s_global);
  WebGLRenderingContext::Initialize(s_global);
  //XXX initialize webgl classes with global

  return s_global;
}

void Uninitialize() {
  if (s_global.IsEmpty())
    return;
  s_global.Dispose();
  s_global.Clear();

  delete s_factory;
  s_factory = 0;

  Console::Uninitialize();
  Canvas::Uninitialize();
  WebGLRenderingContext::Uninitialize();
  //XXX uninitialize webgl classes

  // Run GC until everything is freed
  while (!v8::V8::IdleNotification()) {}
  v8::V8::Dispose();
}

Factory* GetFactory() {
  return s_factory;
}

}
<|endoftext|>


<commit_before>/* FMINST -- simple FM instrument

   p0 = start time
   p1 = duration
   p2 = amp *
   p3 = frequency of carrier (Hz or oct.pc **)
   p4 = frequency of modulator (Hz or oct.pct)
   p5 = FM index low point
   p6 = FM index high point
   p7 = pan (in percent-to-left form: 0-1) [optional; default is 0]
   p8 = reference to wavetable [optional; if missing, must use gen 2 ***]
   p9 = index guide [optional; if missing, must use gen 3 ****]

   p2 (amplitude), p3 (carrier freq), p4 (modulator freq), p5 (index low),
   p6 (index high), p7 (pan) and p9 (index guide) can receive dynamic updates
   from a table or real-time control source.

   * If an old-style gen table 1 is present, its values will be multiplied
   by p2 (amp), even if the latter is dynamic.

   ** oct.pc format generally will not work as you expect for p3 and p4
   (osc freq) if the pfield changes dynamically.  Use Hz instead in that case.

   *** If p8 is missing, you must use an old-style gen table 2 for the
   oscillator waveform.

   **** If p9 is missing, you must use an old-style gen table 3 for the
   index guide function.

                                                rev for v4, JGG, 7/12/04
*/
#include <stdlib.h>
#include <stdio.h>
#include <ugens.h>
#include <Instrument.h>
#include <PField.h>
#include <Option.h>		// for fastUpdate
#include "FMINST.h"
#include <rt.h>
#include <rtdefs.h>

#define AMP_GEN_SLOT     1
#define WAVET_GEN_SLOT   2
#define INDEX_GEN_SLOT   3

FMINST::FMINST() : Instrument()
{
	indexenv = NULL;
	branch = 0;
}

FMINST::~FMINST()
{
	delete carosc;
	delete modosc;
}

// In fastUpdate mode, we skip doupdate() entirely, instead updating only amp,
// and only from a table.  The table can be a makegen or a PField table.  PField
// tables must be "flattened" using copytable if they are compound (e.g. passed
// through a PField filter or multiplied by a constant).  We use p[ampindex] as
// an amp multiplier, unless using a PField table, in which case there is no amp
// multiplier -- the p[ampindex] value is the first table value.   -JGG

void FMINST::initamp(float dur, double p[], int ampindex, int ampgenslot)
{
	fastUpdate = Option::fastUpdate();
	if (fastUpdate) {
		// Prefer PField table, otherwise makegen
		int tablen = 0;
		amptable = (double *) getPFieldTable(ampindex, &tablen);
		if (amptable)
			ampmult = 1.0f;
		else {
			ampmult = p[ampindex];
			amptable = floc(ampgenslot);
			if (amptable)
				tablen = fsize(ampgenslot);
		}
		if (amptable)
			tableset(SR, dur, tablen, amptabs);
		else
			amp = ampmult;
	}
	else {
		// NB: ampmult never used, first amp set in doupdate
		amptable = floc(ampgenslot);
		if (amptable) {
			int tablen = fsize(ampgenslot);
			tableset(SR, dur, tablen, amptabs);
		}
	}
}

int FMINST::init(double p[], int n_args)
{
	nargs = n_args;
	float outskip = p[0];
	float dur = p[1];

	if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;
	if (outputChannels() > 2)
		return die("FMINST", "Can't handle more than 2 output channels.");

	carfreqraw = p[3];
	if (carfreqraw < 15.0)
		carfreq = cpspch(carfreqraw);
	else
		carfreq = carfreqraw;

	modfreqraw = p[4];
	if (modfreqraw < 15.0)
		modfreq = cpspch(modfreqraw);
	else
		modfreq = modfreqraw;

	double *wavetable = NULL;
	int tablelen = 0;
	if (n_args > 8) {      // handle table coming in as optional p8 TablePField
		wavetable = (double *) getPFieldTable(8, &tablelen);
	}
	if (wavetable == NULL) {
		wavetable = floc(WAVET_GEN_SLOT);
		if (wavetable == NULL)
			return die("FMINST", "Either use the wavetable pfield (p8) or make "
                    "an old-style gen function in slot %d.", WAVET_GEN_SLOT);
		tablelen = fsize(WAVET_GEN_SLOT);
	}
	if (tablelen > 32767)
		return die("FMINST", "wavetable must have fewer than 32768 samples.");

	carosc = new Ooscili(SR, carfreq, wavetable, tablelen);
	modosc = new Ooscili(SR, modfreq, wavetable, tablelen);

	if (n_args < 10) {		// no p9 guide PField, must use gen table
		indexenv = floc(INDEX_GEN_SLOT);
		if (indexenv == NULL)
			return die("FMINST", "Either use the index guide pfield (p9) or make "
                    "an old-style gen function in slot %d.", INDEX_GEN_SLOT);
		int len = fsize(INDEX_GEN_SLOT);
		tableset(SR, dur, len, indtabs);
	}

	initamp(dur, p, 2, 1);
	if (fastUpdate) {
		minindex = p[5];
		indexdiff = p[6] - minindex;
		pan = p[7];
	}

	return nSamps();
}

void FMINST::doupdate()
{
   double p[10];
   update(p, 10);

	amp = p[2];
	if (amptable)
		amp *= tablei(currentFrame(), amptable, amptabs);

	if (p[3] != carfreqraw) {
		carfreqraw = p[3];
		if (carfreqraw < 15.0)
			carfreq = cpspch(carfreqraw);
		else
			carfreq = carfreqraw;
	}
	if (p[4] != modfreqraw) {
		modfreqraw = p[4];
		if (modfreqraw < 15.0)
			modfreq = cpspch(modfreqraw);
		else
			modfreq = modfreqraw;
		modosc->setfreq(modfreq);
	}

	minindex = p[5];
	float maxindex = p[6];
	if (minindex > maxindex) {		// swap if wrong order
		float tmp = minindex;
		minindex = maxindex;
		maxindex = tmp;
	}
	float guide;
	if (nargs > 9)			// guide pfield is present
		guide = p[9];
	else                 // backward-compatible gen table
		guide = tablei(currentFrame(), indexenv, indtabs);
	float index = minindex + ((maxindex - minindex) * guide);
	peakdev = index * modfreq;

	pan = p[7];
}

int FMINST::run()
{
	const int nframes = framesToRun();
	for (int i = 0; i < nframes; i++) {
		if (--branch <= 0) {
			if (fastUpdate) {
				if (amptable)
					amp = ampmult * tablei(currentFrame(), amptable, amptabs);
				float guide = tablei(currentFrame(), indexenv, indtabs);
				peakdev = modfreq * (minindex + (indexdiff * guide));
			}
			else
				doupdate();
			branch = getSkip();
		}

		float out[2];

		float modsig = modosc->next() * peakdev;
		carosc->setfreq(carfreq + modsig);
		out[0] = carosc->next() * amp;

		if (outputChannels() == 2) {
			out[1] = (1.0 - pan) * out[0];
			out[0] *= pan;
		}

		rtaddout(out);
		increment();
	}
	return framesToRun();
}

Instrument *makeFMINST()
{
	FMINST *inst;

	inst = new FMINST();
	inst->set_bus_config("FMINST");

	return inst;
}

void rtprofile()
{
	RT_INTRO("FMINST",makeFMINST);
}

<commit_msg>BGG:  removed tablelen restriction (no longer valid), 1/12/2011<commit_after>/* FMINST -- simple FM instrument

   p0 = start time
   p1 = duration
   p2 = amp *
   p3 = frequency of carrier (Hz or oct.pc **)
   p4 = frequency of modulator (Hz or oct.pct)
   p5 = FM index low point
   p6 = FM index high point
   p7 = pan (in percent-to-left form: 0-1) [optional; default is 0]
   p8 = reference to wavetable [optional; if missing, must use gen 2 ***]
   p9 = index guide [optional; if missing, must use gen 3 ****]

   p2 (amplitude), p3 (carrier freq), p4 (modulator freq), p5 (index low),
   p6 (index high), p7 (pan) and p9 (index guide) can receive dynamic updates
   from a table or real-time control source.

   * If an old-style gen table 1 is present, its values will be multiplied
   by p2 (amp), even if the latter is dynamic.

   ** oct.pc format generally will not work as you expect for p3 and p4
   (osc freq) if the pfield changes dynamically.  Use Hz instead in that case.

   *** If p8 is missing, you must use an old-style gen table 2 for the
   oscillator waveform.

   **** If p9 is missing, you must use an old-style gen table 3 for the
   index guide function.

                                                rev for v4, JGG, 7/12/04
*/
#include <stdlib.h>
#include <stdio.h>
#include <ugens.h>
#include <Instrument.h>
#include <PField.h>
#include <Option.h>		// for fastUpdate
#include "FMINST.h"
#include <rt.h>
#include <rtdefs.h>

#define AMP_GEN_SLOT     1
#define WAVET_GEN_SLOT   2
#define INDEX_GEN_SLOT   3

FMINST::FMINST() : Instrument()
{
	indexenv = NULL;
	branch = 0;
}

FMINST::~FMINST()
{
	delete carosc;
	delete modosc;
}

// In fastUpdate mode, we skip doupdate() entirely, instead updating only amp,
// and only from a table.  The table can be a makegen or a PField table.  PField
// tables must be "flattened" using copytable if they are compound (e.g. passed
// through a PField filter or multiplied by a constant).  We use p[ampindex] as
// an amp multiplier, unless using a PField table, in which case there is no amp
// multiplier -- the p[ampindex] value is the first table value.   -JGG

void FMINST::initamp(float dur, double p[], int ampindex, int ampgenslot)
{
	fastUpdate = Option::fastUpdate();
	if (fastUpdate) {
		// Prefer PField table, otherwise makegen
		int tablen = 0;
		amptable = (double *) getPFieldTable(ampindex, &tablen);
		if (amptable)
			ampmult = 1.0f;
		else {
			ampmult = p[ampindex];
			amptable = floc(ampgenslot);
			if (amptable)
				tablen = fsize(ampgenslot);
		}
		if (amptable)
			tableset(SR, dur, tablen, amptabs);
		else
			amp = ampmult;
	}
	else {
		// NB: ampmult never used, first amp set in doupdate
		amptable = floc(ampgenslot);
		if (amptable) {
			int tablen = fsize(ampgenslot);
			tableset(SR, dur, tablen, amptabs);
		}
	}
}

int FMINST::init(double p[], int n_args)
{
	nargs = n_args;
	float outskip = p[0];
	float dur = p[1];

	if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;
	if (outputChannels() > 2)
		return die("FMINST", "Can't handle more than 2 output channels.");

	carfreqraw = p[3];
	if (carfreqraw < 15.0)
		carfreq = cpspch(carfreqraw);
	else
		carfreq = carfreqraw;

	modfreqraw = p[4];
	if (modfreqraw < 15.0)
		modfreq = cpspch(modfreqraw);
	else
		modfreq = modfreqraw;

	double *wavetable = NULL;
	int tablelen = 0;
	if (n_args > 8) {      // handle table coming in as optional p8 TablePField
		wavetable = (double *) getPFieldTable(8, &tablelen);
	}
	if (wavetable == NULL) {
		wavetable = floc(WAVET_GEN_SLOT);
		if (wavetable == NULL)
			return die("FMINST", "Either use the wavetable pfield (p8) or make "
                    "an old-style gen function in slot %d.", WAVET_GEN_SLOT);
		tablelen = fsize(WAVET_GEN_SLOT);
	}

	carosc = new Ooscili(SR, carfreq, wavetable, tablelen);
	modosc = new Ooscili(SR, modfreq, wavetable, tablelen);

	if (n_args < 10) {		// no p9 guide PField, must use gen table
		indexenv = floc(INDEX_GEN_SLOT);
		if (indexenv == NULL)
			return die("FMINST", "Either use the index guide pfield (p9) or make "
                    "an old-style gen function in slot %d.", INDEX_GEN_SLOT);
		int len = fsize(INDEX_GEN_SLOT);
		tableset(SR, dur, len, indtabs);
	}

	initamp(dur, p, 2, 1);
	if (fastUpdate) {
		minindex = p[5];
		indexdiff = p[6] - minindex;
		pan = p[7];
	}

	return nSamps();
}

void FMINST::doupdate()
{
   double p[10];
   update(p, 10);

	amp = p[2];
	if (amptable)
		amp *= tablei(currentFrame(), amptable, amptabs);

	if (p[3] != carfreqraw) {
		carfreqraw = p[3];
		if (carfreqraw < 15.0)
			carfreq = cpspch(carfreqraw);
		else
			carfreq = carfreqraw;
	}
	if (p[4] != modfreqraw) {
		modfreqraw = p[4];
		if (modfreqraw < 15.0)
			modfreq = cpspch(modfreqraw);
		else
			modfreq = modfreqraw;
		modosc->setfreq(modfreq);
	}

	minindex = p[5];
	float maxindex = p[6];
	if (minindex > maxindex) {		// swap if wrong order
		float tmp = minindex;
		minindex = maxindex;
		maxindex = tmp;
	}
	float guide;
	if (nargs > 9)			// guide pfield is present
		guide = p[9];
	else                 // backward-compatible gen table
		guide = tablei(currentFrame(), indexenv, indtabs);
	float index = minindex + ((maxindex - minindex) * guide);
	peakdev = index * modfreq;

	pan = p[7];
}

int FMINST::run()
{
	const int nframes = framesToRun();
	for (int i = 0; i < nframes; i++) {
		if (--branch <= 0) {
			if (fastUpdate) {
				if (amptable)
					amp = ampmult * tablei(currentFrame(), amptable, amptabs);
				float guide = tablei(currentFrame(), indexenv, indtabs);
				peakdev = modfreq * (minindex + (indexdiff * guide));
			}
			else
				doupdate();
			branch = getSkip();
		}

		float out[2];

		float modsig = modosc->next() * peakdev;
		carosc->setfreq(carfreq + modsig);
		out[0] = carosc->next() * amp;

		if (outputChannels() == 2) {
			out[1] = (1.0 - pan) * out[0];
			out[0] *= pan;
		}

		rtaddout(out);
		increment();
	}
	return framesToRun();
}

Instrument *makeFMINST()
{
	FMINST *inst;

	inst = new FMINST();
	inst->set_bus_config("FMINST");

	return inst;
}

void rtprofile()
{
	RT_INTRO("FMINST",makeFMINST);
}

<|endoftext|>


<commit_before>#include "chimera/visitor.h"

#include <algorithm>
#include <iostream>
#include <string>
#include <boost/algorithm/string/join.hpp>

using namespace chimera;
using namespace clang;
using boost::algorithm::join;

chimera::Visitor::Visitor(clang::CompilerInstance *ci,
                          std::unique_ptr<CompiledConfiguration> cc)
: context_(&(ci->getASTContext()))
, config_(std::move(cc))
{
    // Do nothing.
}

bool chimera::Visitor::VisitDecl(Decl *decl)
{
    if (!decl->isCanonicalDecl())
        return true;

    if (!IsEnclosed(decl))
        return true;

    if (isa<CXXRecordDecl>(decl))
        GenerateCXXRecord(cast<CXXRecordDecl>(decl));

    return true;
}

void chimera::Visitor::GenerateCXXRecord(CXXRecordDecl *const decl)
{
    if (!decl->hasDefinition())
        return;

    const YAML::Node &node = config_->GetDeclaration(decl);

    std::cout
        << "::boost::python::class_<"
        << decl->getQualifiedNameAsString();

    const YAML::Node &noncopyable_node = node["noncopyable"];
    if (const bool noncopyable = noncopyable_node && noncopyable_node.as<bool>(false))
        std::cout << ", ::boost::python::noncopyable";

    if (const YAML::Node &held_type_node = node["held_type"])
        std::cout << ", " << held_type_node.as<std::string>();

    std::vector<std::string> base_names;

    if (const YAML::Node &bases_node = node["bases"])
        base_names = bases_node.as<std::vector<std::string> >();
    else
        base_names = GetBaseClassNames(decl);

    if (!base_names.empty())
    {
        std::cout << ", ::boost::python::bases<"
                  << join(base_names, ", ") << " >";
    }

    std::cout << " >\n";

    for (CXXMethodDecl *method_decl : decl->methods())
    {
        if (isa<CXXConversionDecl>(method_decl))
            ; // do nothing
        else if (isa<CXXDestructorDecl>(method_decl))
            ; // do nothing
        else if (isa<CXXConstructorDecl>(method_decl))
            ; // TODO: Wrap constructors.
        else if (method_decl->isOverloadedOperator())
            ; // TODO: Wrap overloaded operators.
        else if (method_decl->isStatic())
            ; // TODO: Wrap static functions
        else
            GenerateCXXMethod(decl, method_decl);
    }
}

void chimera::Visitor::GenerateCXXMethod(
    CXXRecordDecl *class_decl, CXXMethodDecl *decl)
{
    decl = decl->getCanonicalDecl();

    const QualType pointer_type = context_->getMemberPointerType(
        decl->getType(), class_decl->getTypeForDecl());
    const Type *return_type = decl->getReturnType().getTypePtr();

    const YAML::Node &node = config_->GetDeclaration(decl);
    const YAML::Node &rvp_node = node["return_value_policy"];

    if (!rvp_node)
    {
        if (return_type->isReferenceType())
        {
            std::cerr
                << "Warning: Skipped method '"
                << decl->getQualifiedNameAsString()
                << "' because it returns a reference and no"
                   "  'return_value_policy' was specified.\n";
            return;
        }
        else if (return_type->isPointerType())
        {
            std::cerr
                << "Warning: Skipped method '"
                << decl->getQualifiedNameAsString()
                << "' because it returns a pointer and no"
                   "  'return_value_policy' was specified.\n";
            return;
        }

        // TODO: Check if return_type is non-copyable.
    }

    std::cout
        << ".def(\"" << decl->getNameAsString() << "\""
        << ", static_cast<" << pointer_type.getAsString() << ">(&"
        << decl->getQualifiedNameAsString() << ")";

    if (rvp_node)
    {
        std::cout << ", boost::python::return_value_policy<"
                  << rvp_node.as<std::string>() << " >";
    }

    const auto params = GetParameterNames(decl);
    if (!params.empty())
    {
        // TODO: Supress any default parameters that occur after the first
        // non-default to default transition. This can only occur if evaluating
        // the default value of one or more parameters failed.

        std::vector<std::string> python_args;
        for (const auto &param : params)
        {
            std::stringstream python_arg;
            python_arg << "boost::python::arg(\"" << param.first << "\")";

            if (!param.second.empty())
                python_arg << " = " << param.second;

            python_args.push_back(python_arg.str());
        }

        std::cout << ", (" << join(python_args, ", ") << ")";
    }

    std::cout << ")\n";
}

std::vector<std::string> chimera::Visitor::GetBaseClassNames(
    CXXRecordDecl *decl) const
{
    std::vector<std::string> base_names;

    for (CXXBaseSpecifier &base_decl : decl->bases())
    {
        if (base_decl.getAccessSpecifier() != AS_public)
            continue;

        // TODO: Filter out transitive base classes.

        CXXRecordDecl *const base_record_decl
          = base_decl.getType()->getAsCXXRecordDecl();
        base_names.push_back(base_record_decl->getQualifiedNameAsString());
    }

    return base_names;
}

std::vector<std::pair<std::string, std::string>>
    chimera::Visitor::GetParameterNames(clang::CXXMethodDecl *decl) const
{
    std::vector<std::pair<std::string, std::string>> params;

    for (ParmVarDecl *param_decl : decl->params())
    {
        const std::string param_name = param_decl->getNameAsString();
        const Type *param_type = param_decl->getType().getTypePtr();
        std::string param_value;

        if (param_decl->hasDefaultArg())
        {
            Expr *default_expr = param_decl->getDefaultArg();
            Expr::EvalResult result;
            bool success;

            if (param_type->isReferenceType())
                success = default_expr->EvaluateAsLValue(result, *context_);
            else
                success = default_expr->EvaluateAsRValue(result, *context_);

            if (success)
            {
                param_value = result.Val.getAsString(
                    *context_, param_decl->getType());
            }
            else if (default_expr->hasNonTrivialCall(*context_))
            {
                // TODO: How do we print the decl with argument + return types?
                std::cerr
                  << "Warning: Unable to evaluate non-trivial call in default"
                     "  value for parameter"
                  << " '" << param_name << "' of method"
                  << " '" << decl->getQualifiedNameAsString() << "'.\n";
            }
            else
            {
                // TODO: How do we print the decl with argument + return types?
                std::cerr
                  << "Warning: Failed to evaluate default value for parameter"
                  << " '" << param_name << "' of method"
                  << " '" << decl->getQualifiedNameAsString() << "'.\n";
            }
        }

        params.push_back(std::make_pair(param_name, param_value));
    }

    return params;
}

bool chimera::Visitor::IsEnclosed(Decl *decl) const
{
    // Filter over the namespaces and only traverse ones that are enclosed
    // by one of the configuration namespaces.
    for (const auto &it : config_->GetNamespaces())
    {
        if (decl->getDeclContext() && it->Encloses(decl->getDeclContext()))
        {
            return true;
        }
    }
    return false;
}
<commit_msg>Another TODO.<commit_after>#include "chimera/visitor.h"

#include <algorithm>
#include <iostream>
#include <string>
#include <boost/algorithm/string/join.hpp>

using namespace chimera;
using namespace clang;
using boost::algorithm::join;

chimera::Visitor::Visitor(clang::CompilerInstance *ci,
                          std::unique_ptr<CompiledConfiguration> cc)
: context_(&(ci->getASTContext()))
, config_(std::move(cc))
{
    // Do nothing.
}

bool chimera::Visitor::VisitDecl(Decl *decl)
{
    if (!decl->isCanonicalDecl())
        return true;

    if (!IsEnclosed(decl))
        return true;

    if (isa<CXXRecordDecl>(decl))
        GenerateCXXRecord(cast<CXXRecordDecl>(decl));

    return true;
}

void chimera::Visitor::GenerateCXXRecord(CXXRecordDecl *const decl)
{
    if (!decl->hasDefinition())
        return;

    const YAML::Node &node = config_->GetDeclaration(decl);

    std::cout
        << "::boost::python::class_<"
        << decl->getQualifiedNameAsString();

    const YAML::Node &noncopyable_node = node["noncopyable"];
    if (const bool noncopyable = noncopyable_node && noncopyable_node.as<bool>(false))
        std::cout << ", ::boost::python::noncopyable";

    if (const YAML::Node &held_type_node = node["held_type"])
        std::cout << ", " << held_type_node.as<std::string>();

    std::vector<std::string> base_names;

    if (const YAML::Node &bases_node = node["bases"])
        base_names = bases_node.as<std::vector<std::string> >();
    else
        base_names = GetBaseClassNames(decl);

    if (!base_names.empty())
    {
        std::cout << ", ::boost::python::bases<"
                  << join(base_names, ", ") << " >";
    }

    std::cout << " >\n";

    for (CXXMethodDecl *method_decl : decl->methods())
    {
        if (isa<CXXConversionDecl>(method_decl))
            ; // do nothing
        else if (isa<CXXDestructorDecl>(method_decl))
            ; // do nothing
        else if (isa<CXXConstructorDecl>(method_decl))
            ; // TODO: Wrap constructors.
        else if (method_decl->isOverloadedOperator())
            ; // TODO: Wrap overloaded operators.
        else if (method_decl->isStatic())
            ; // TODO: Wrap static functions
        else
            GenerateCXXMethod(decl, method_decl);
    }
}

void chimera::Visitor::GenerateCXXMethod(
    CXXRecordDecl *class_decl, CXXMethodDecl *decl)
{
    decl = decl->getCanonicalDecl();

    const QualType pointer_type = context_->getMemberPointerType(
        decl->getType(), class_decl->getTypeForDecl());
    const Type *return_type = decl->getReturnType().getTypePtr();

    const YAML::Node &node = config_->GetDeclaration(decl);
    const YAML::Node &rvp_node = node["return_value_policy"];

    if (!rvp_node)
    {
        if (return_type->isReferenceType())
        {
            std::cerr
                << "Warning: Skipped method '"
                << decl->getQualifiedNameAsString()
                << "' because it returns a reference and no"
                   "  'return_value_policy' was specified.\n";
            return;
        }
        else if (return_type->isPointerType())
        {
            std::cerr
                << "Warning: Skipped method '"
                << decl->getQualifiedNameAsString()
                << "' because it returns a pointer and no"
                   "  'return_value_policy' was specified.\n";
            return;
        }

        // TODO: Check if return_type is non-copyable.
    }

    std::cout
        << ".def(\"" << decl->getNameAsString() << "\""
        << ", static_cast<" << pointer_type.getAsString() << ">(&"
        << decl->getQualifiedNameAsString() << ")";

    if (rvp_node)
    {
        std::cout << ", boost::python::return_value_policy<"
                  << rvp_node.as<std::string>() << " >";
    }

    const auto params = GetParameterNames(decl);
    if (!params.empty())
    {
        // TODO: Supress any default parameters that occur after the first
        // non-default to default transition. This can only occur if evaluating
        // the default value of one or more parameters failed.

        // TODO: Assign names to unnamed arguments.

        std::vector<std::string> python_args;
        for (const auto &param : params)
        {
            std::stringstream python_arg;
            python_arg << "boost::python::arg(\"" << param.first << "\")";

            if (!param.second.empty())
                python_arg << " = " << param.second;

            python_args.push_back(python_arg.str());
        }

        std::cout << ", (" << join(python_args, ", ") << ")";
    }

    std::cout << ")\n";
}

std::vector<std::string> chimera::Visitor::GetBaseClassNames(
    CXXRecordDecl *decl) const
{
    std::vector<std::string> base_names;

    for (CXXBaseSpecifier &base_decl : decl->bases())
    {
        if (base_decl.getAccessSpecifier() != AS_public)
            continue;

        // TODO: Filter out transitive base classes.

        CXXRecordDecl *const base_record_decl
          = base_decl.getType()->getAsCXXRecordDecl();
        base_names.push_back(base_record_decl->getQualifiedNameAsString());
    }

    return base_names;
}

std::vector<std::pair<std::string, std::string>>
    chimera::Visitor::GetParameterNames(clang::CXXMethodDecl *decl) const
{
    std::vector<std::pair<std::string, std::string>> params;

    for (ParmVarDecl *param_decl : decl->params())
    {
        const std::string param_name = param_decl->getNameAsString();
        const Type *param_type = param_decl->getType().getTypePtr();
        std::string param_value;

        if (param_decl->hasDefaultArg())
        {
            Expr *default_expr = param_decl->getDefaultArg();
            Expr::EvalResult result;
            bool success;

            if (param_type->isReferenceType())
                success = default_expr->EvaluateAsLValue(result, *context_);
            else
                success = default_expr->EvaluateAsRValue(result, *context_);

            if (success)
            {
                param_value = result.Val.getAsString(
                    *context_, param_decl->getType());
            }
            else if (default_expr->hasNonTrivialCall(*context_))
            {
                // TODO: How do we print the decl with argument + return types?
                std::cerr
                  << "Warning: Unable to evaluate non-trivial call in default"
                     "  value for parameter"
                  << " '" << param_name << "' of method"
                  << " '" << decl->getQualifiedNameAsString() << "'.\n";
            }
            else
            {
                // TODO: How do we print the decl with argument + return types?
                std::cerr
                  << "Warning: Failed to evaluate default value for parameter"
                  << " '" << param_name << "' of method"
                  << " '" << decl->getQualifiedNameAsString() << "'.\n";
            }
        }

        params.push_back(std::make_pair(param_name, param_value));
    }

    return params;
}

bool chimera::Visitor::IsEnclosed(Decl *decl) const
{
    // Filter over the namespaces and only traverse ones that are enclosed
    // by one of the configuration namespaces.
    for (const auto &it : config_->GetNamespaces())
    {
        if (decl->getDeclContext() && it->Encloses(decl->getDeclContext()))
        {
            return true;
        }
    }
    return false;
}
<|endoftext|>


<commit_before>#include "EntityManager.h"
#include "Kernel.h"
#include "StateManager.h"

EntityManager::EntityManager(GameStateManager *gsm) : mStateManager(gsm) {
  ASSERT(gsm != NULL);
  entityNumber = EID_MIN;
  entityCount = 0;
}

void EntityManager::DeleteEntity(EID id) {
  deadEntities.insert(id);
  entityCount -= 1;
}

unsigned int EntityManager::GetEntityCount() { return entityCount; }

void EntityManager::DispatchEvent(const Event *event) {
  for (auto i = componentsRegistered.begin(); i != componentsRegistered.end();
       i++) {
    i->second->HandleEvent(event);
  }
}

void EntityManager::BroadcastEvent(const Event *event) {
  // Send to state
  mStateManager->HandleEvent(event);
  for (auto i = componentsRegistered.begin(); i != componentsRegistered.end();
       i++) {
    i->second->BroadcastEvent(event);
  }
}

void EntityManager::Cleanup() {
  if (deadEntities.empty()) {
    return;
  }

  for (auto i = deadEntities.begin(); i != deadEntities.end(); i++) {
    EID id = *i;

    // Let all entities know that this entity is about to be deleted
    Event event(id, EID_ALLOBJS, Event::MSG::ENTITY_DELETED, "[DELETED]");
    BroadcastEvent(&event);

    for (auto i = componentsRegistered.begin(); i != componentsRegistered.end();
         i++) {
      i->second->DeleteComponent(id);
    }

    if (EIDToName.find(id) != EIDToName.end()) {
      std::string entityName = EIDToName[id];
      EIDToName.erase(id);
      nameToEID.erase(entityName);
    }

    reclaimedEIDs.push_back(id);
  }

  deadEntities.clear();
}

void EntityManager::RegisterComponentManager(BaseComponentManager *manager,
                                             int order) {
  if (componentsRegistered.find(order) != componentsRegistered.end()) {
    std::stringstream ss;
    ss << "Couldn't register component with order: '" << order
       << "' order id already taken.";
    throw Exception(ss.str());
  }

  // Assert that this order not already taken
  ASSERT(componentsRegistered.find(order) == componentsRegistered.end());

  componentsRegistered[order] = manager;
}

EID EntityManager::NewEntity(const std::string &entityName) {
  EID newEntityID = 0;

  // First check if there are any reclaimed eids to use
  if (!reclaimedEIDs.empty()) {
    newEntityID = reclaimedEIDs.back();
    reclaimedEIDs.pop_back();
  }
  // If there are no old eids to use, make a new one
  else {
    entityNumber++;
    newEntityID = entityNumber;
  }

  MapNameToEID(newEntityID, entityName);
  // Increment number of living entities
  entityCount++;

  return newEntityID;
}

void EntityManager::MapNameToEID(EID eid, const std::string &entityName) {
  if (entityName != "") {
    // Stop if in debug mode, this shouldn't happen
    ASSERT(nameToEID.find(entityName) == nameToEID.end());
    // Defensive programming if not in debug mode
    if (nameToEID.find(entityName) == nameToEID.end()) {
      nameToEID[entityName] = eid;
      EIDToName[eid] = entityName;
    }
  }
}

void EntityManager::ClearAllEntities() {
  for (EID i = EID_MIN; i < entityNumber; i++) {
    DeleteEntity(i);
  }
}

void EntityManager::ClearAllReservedEntities() {
  for (EID i = 0; i < EID_MIN; i++) {
    DeleteEntity(i);
  }
}

void EntityManager::ClearNameMappings() {
  nameToEID.clear();
  EIDToName.clear();
}

EID EntityManager::GetEIDFromName(const std::string &name) const {
  std::map<std::string, EID>::const_iterator i = nameToEID.find(name);
  if (i == nameToEID.end()) {
    return 0;
  }

  return i->second;
}

void EntityManager::SetParent(EID child, EID parent) {
  for (auto i = componentsRegistered.begin(); i != componentsRegistered.end();
       i++) {
    i->second->SetParent(child, parent);
  }
}

void EntityManager::ActivateAllEntities() {}

void EntityManager::ActivateAllEntitiesExcept(std::vector<EID> entities) {}

void EntityManager::DeactivateAllEntitiesExcept(std::vector<EID> entities) {}

void EntityManager::DeactivateAllEntities() {}

void EntityManager::Activate(std::vector<EID> entities) {
  for (auto i = entities.begin(); i != entities.end(); i++) {
    for (auto comp = componentsRegistered.begin();
         comp != componentsRegistered.end(); comp++) {
      comp->second->ActivateComponent(*i);
    }
  }
}

void EntityManager::Deactivate(std::vector<EID> entities) {
  for (auto i = entities.begin(); i != entities.end(); i++) {
    for (auto comp = componentsRegistered.begin();
         comp != componentsRegistered.end(); comp++) {
      comp->second->DeactivateComponent(*i);
    }
  }
}
<commit_msg>Fixed EntityManager not deleting final entity<commit_after>#include "EntityManager.h"
#include "Kernel.h"
#include "StateManager.h"

EntityManager::EntityManager(GameStateManager *gsm) : mStateManager(gsm) {
  ASSERT(gsm != NULL);
  entityNumber = EID_MIN;
  entityCount = 0;
}

void EntityManager::DeleteEntity(EID id) {
  deadEntities.insert(id);
  entityCount -= 1;
}

unsigned int EntityManager::GetEntityCount() { return entityCount; }

void EntityManager::DispatchEvent(const Event *event) {
  for (auto i = componentsRegistered.begin(); i != componentsRegistered.end();
       i++) {
    i->second->HandleEvent(event);
  }
}

void EntityManager::BroadcastEvent(const Event *event) {
  // Send to state
  mStateManager->HandleEvent(event);
  for (auto i = componentsRegistered.begin(); i != componentsRegistered.end();
       i++) {
    i->second->BroadcastEvent(event);
  }
}

void EntityManager::Cleanup() {
  if (deadEntities.empty()) {
    return;
  }

  for (auto i = deadEntities.begin(); i != deadEntities.end(); i++) {
    EID id = *i;

    // Let all entities know that this entity is about to be deleted
    Event event(id, EID_ALLOBJS, Event::MSG::ENTITY_DELETED, "[DELETED]");
    BroadcastEvent(&event);

    for (auto i = componentsRegistered.begin(); i != componentsRegistered.end();
         i++) {
      i->second->DeleteComponent(id);
    }

    if (EIDToName.find(id) != EIDToName.end()) {
      std::string entityName = EIDToName[id];
      EIDToName.erase(id);
      nameToEID.erase(entityName);
    }

    reclaimedEIDs.push_back(id);
  }

  deadEntities.clear();
}

void EntityManager::RegisterComponentManager(BaseComponentManager *manager,
                                             int order) {
  if (componentsRegistered.find(order) != componentsRegistered.end()) {
    std::stringstream ss;
    ss << "Couldn't register component with order: '" << order
       << "' order id already taken.";
    throw Exception(ss.str());
  }

  // Assert that this order not already taken
  ASSERT(componentsRegistered.find(order) == componentsRegistered.end());

  componentsRegistered[order] = manager;
}

EID EntityManager::NewEntity(const std::string &entityName) {
  EID newEntityID = 0;

  // First check if there are any reclaimed eids to use
  if (!reclaimedEIDs.empty()) {
    newEntityID = reclaimedEIDs.back();
    reclaimedEIDs.pop_back();
  }
  // If there are no old eids to use, make a new one
  else {
    entityNumber++;
    newEntityID = entityNumber;
  }

  MapNameToEID(newEntityID, entityName);
  // Increment number of living entities
  entityCount++;

  return newEntityID;
}

void EntityManager::MapNameToEID(EID eid, const std::string &entityName) {
  if (entityName != "") {
    // Stop if in debug mode, this shouldn't happen
    ASSERT(nameToEID.find(entityName) == nameToEID.end());
    // Defensive programming if not in debug mode
    if (nameToEID.find(entityName) == nameToEID.end()) {
      nameToEID[entityName] = eid;
      EIDToName[eid] = entityName;
    }
  }
}

void EntityManager::ClearAllEntities() {
	//inclusive, entityNumber is the highest eid in use
  for (EID i = EID_MIN; i <= entityNumber; i++) {
    DeleteEntity(i);
  }
}

void EntityManager::ClearAllReservedEntities() {
  for (EID i = 0; i < EID_MIN; i++) {
    DeleteEntity(i);
  }
}

void EntityManager::ClearNameMappings() {
  nameToEID.clear();
  EIDToName.clear();
}

EID EntityManager::GetEIDFromName(const std::string &name) const {
  std::map<std::string, EID>::const_iterator i = nameToEID.find(name);
  if (i == nameToEID.end()) {
    return 0;
  }

  return i->second;
}

void EntityManager::SetParent(EID child, EID parent) {
  for (auto i = componentsRegistered.begin(); i != componentsRegistered.end();
       i++) {
    i->second->SetParent(child, parent);
  }
}

void EntityManager::ActivateAllEntities() {}

void EntityManager::ActivateAllEntitiesExcept(std::vector<EID> entities) {}

void EntityManager::DeactivateAllEntitiesExcept(std::vector<EID> entities) {}

void EntityManager::DeactivateAllEntities() {}

void EntityManager::Activate(std::vector<EID> entities) {
  for (auto i = entities.begin(); i != entities.end(); i++) {
    for (auto comp = componentsRegistered.begin();
         comp != componentsRegistered.end(); comp++) {
      comp->second->ActivateComponent(*i);
    }
  }
}

void EntityManager::Deactivate(std::vector<EID> entities) {
  for (auto i = entities.begin(); i != entities.end(); i++) {
    for (auto comp = componentsRegistered.begin();
         comp != componentsRegistered.end(); comp++) {
      comp->second->DeactivateComponent(*i);
    }
  }
}
<|endoftext|>


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

  Program:   Visualization Library
  Module:    vlDSRead.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include "vlDSRead.hh"
#include "vlPolyR.hh"
#include "vlSPtsR.hh"
#include "vlSGridR.hh"
#include "vlUGridR.hh"

vlDataSetReader::vlDataSetReader()
{
}

vlDataSetReader::~vlDataSetReader()
{
}

// Description:
// Specify file name of vl data file to read.
void vlDataSetReader::SetFilename(char *name)
{
  this->Reader.SetFilename(name);
}
char *vlDataSetReader::GetFilename()
{
  return this->Reader.GetFilename();
}

// Description:
// Get the type of file (ASCII or BINARY)
int vlDataSetReader::GetFileType()
{
  return this->Reader.GetFileType();
}

// Description:
// Set the name of the scalar data to extract. If not specified, first
// scalar data encountered is extracted.
void vlDataSetReader::SetScalarsName(char *name)
{
  this->Reader.SetScalarsName(name);
}
char *vlDataSetReader::GetScalarsName()
{
  return this->Reader.GetScalarsName();
}

// Description:
// Set the name of the vector data to extract. If not specified, first
// vector data encountered is extracted.
void vlDataSetReader::SetVectorsName(char *name)
{
  this->Reader.SetVectorsName(name);
}
char *vlDataSetReader::GetVectorsName()
{
  return this->Reader.GetVectorsName();
}

// Description:
// Set the name of the tensor data to extract. If not specified, first
// tensor data encountered is extracted.
void vlDataSetReader::SetTensorsName(char *name)
{
  this->Reader.SetTensorsName(name);
}
char *vlDataSetReader::GetTensorsName()
{
  return this->Reader.GetTensorsName();
}

// Description:
// Set the name of the normal data to extract. If not specified, first
// normal data encountered is extracted.
void vlDataSetReader::SetNormalsName(char *name)
{
  this->Reader.SetNormalsName(name);
}
char *vlDataSetReader::GetNormalsName()
{
  return this->Reader.GetNormalsName();
}

// Description:
// Set the name of the texture coordinate data to extract. If not specified,
// first texture coordinate data encountered is extracted.
void vlDataSetReader::SetTCoordsName(char *name)
{
  this->Reader.SetTCoordsName(name);
}
char *vlDataSetReader::GetTCoordsName()
{
  return this->Reader.GetTCoordsName();
}

// Description:
// Set the name of the lookup table data to extract. If not specified, uses
// lookup table named by scalar. Otherwise, this specification supersedes.
void vlDataSetReader::SetLookupTableName(char *name)
{
  this->Reader.SetLookupTableName(name);
}
char *vlDataSetReader::GetLookupTableName()
{
  return this->Reader.GetLookupTableName();
}

void vlDataSetReader::Execute()
{
  FILE *fp;
  int retStat;
  char line[257];
  vlDataSet *reader;

  vlDebugMacro(<<"Reading vl dataset...");
  this->Initialize();
  if ( this->Debug ) this->Reader.DebugOn();
  else this->Reader.DebugOff();

  if ( !(fp=this->Reader.OpenVLFile()) || !this->Reader.ReadHeader(fp) )
      return;
//
// Determine dataset type
//
  if ( (retStat=fscanf(fp,"%256s",line)) == EOF || retStat < 1 )
    {
    vlErrorMacro(<< "Premature EOF reading dataset keyword");
    return;
    }

  if ( !strncmp(this->Reader.LowerCase(line),"dataset",(unsigned long)7) )
    {
//
// See if type is recognized.
//
    if ( (retStat=fscanf(fp,"%256s",line)) == EOF || retStat < 1 )
      {
      vlErrorMacro(<< "Premature EOF reading type");
      return;
      }

    rewind(fp);
    if ( ! strncmp(this->Reader.LowerCase(line),"polydata",8) )
      {
      vlPolyReader *preader = new vlPolyReader;
      preader->SetFilename(this->Reader.GetFilename());
      preader->SetScalarsName(this->Reader.GetScalarsName());
      preader->SetVectorsName(this->Reader.GetVectorsName());
      preader->SetNormalsName(this->Reader.GetNormalsName());
      preader->SetTensorsName(this->Reader.GetTensorsName());
      preader->SetTCoordsName(this->Reader.GetTCoordsName());
      preader->SetLookupTableName(this->Reader.GetLookupTableName());
      preader->Update();
      reader = (vlDataSet *)preader;
      }

    else if ( ! strncmp(line,"structured_points",17) )
      {
      vlStructuredPointsReader *preader = new vlStructuredPointsReader;
      preader->SetFilename(this->Reader.GetFilename());
      preader->SetScalarsName(this->Reader.GetScalarsName());
      preader->SetVectorsName(this->Reader.GetVectorsName());
      preader->SetNormalsName(this->Reader.GetNormalsName());
      preader->SetTensorsName(this->Reader.GetTensorsName());
      preader->SetTCoordsName(this->Reader.GetTCoordsName());
      preader->SetLookupTableName(this->Reader.GetLookupTableName());
      preader->Update();
      reader = (vlDataSet *)preader;
      }

    else if ( ! strncmp(line,"structured_grid",15) )
      {
      vlStructuredGridReader *preader = new vlStructuredGridReader;
      preader->SetFilename(this->Reader.GetFilename());
      preader->SetScalarsName(this->Reader.GetScalarsName());
      preader->SetVectorsName(this->Reader.GetVectorsName());
      preader->SetNormalsName(this->Reader.GetNormalsName());
      preader->SetTensorsName(this->Reader.GetTensorsName());
      preader->SetTCoordsName(this->Reader.GetTCoordsName());
      preader->SetLookupTableName(this->Reader.GetLookupTableName());
      preader->Update();
      reader = (vlDataSet *)preader;
      }

    else if ( ! strncmp(line,"unstructured_grid",17) )
      {
      vlUnstructuredGridReader *preader = new vlUnstructuredGridReader;
      preader->SetFilename(this->Reader.GetFilename());
      preader->SetScalarsName(this->Reader.GetScalarsName());
      preader->SetVectorsName(this->Reader.GetVectorsName());
      preader->SetNormalsName(this->Reader.GetNormalsName());
      preader->SetTensorsName(this->Reader.GetTensorsName());
      preader->SetTCoordsName(this->Reader.GetTCoordsName());
      preader->SetLookupTableName(this->Reader.GetLookupTableName());
      preader->Update();
      reader = (vlDataSet *)preader;
      }

    else
      {
      vlErrorMacro(<< "Cannot read dataset type: " << line);
      return;
      }
    }
//
// Create appropriate dataset
//
  if ( this->DataSet ) delete this->DataSet;
  this->DataSet = reader;
  return;
}

void vlDataSetReader::PrintSelf(ostream& os, vlIndent indent)
{
  vlDataSetSource::PrintSelf(os,indent);
  this->Reader.PrintSelf(os,indent);
}
<commit_msg>ERR: Assign point data appropriately.<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    vlDSRead.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include "vlDSRead.hh"
#include "vlPolyR.hh"
#include "vlSPtsR.hh"
#include "vlSGridR.hh"
#include "vlUGridR.hh"

vlDataSetReader::vlDataSetReader()
{
}

vlDataSetReader::~vlDataSetReader()
{
}

// Description:
// Specify file name of vl data file to read.
void vlDataSetReader::SetFilename(char *name)
{
  this->Reader.SetFilename(name);
}
char *vlDataSetReader::GetFilename()
{
  return this->Reader.GetFilename();
}

// Description:
// Get the type of file (ASCII or BINARY)
int vlDataSetReader::GetFileType()
{
  return this->Reader.GetFileType();
}

// Description:
// Set the name of the scalar data to extract. If not specified, first
// scalar data encountered is extracted.
void vlDataSetReader::SetScalarsName(char *name)
{
  this->Reader.SetScalarsName(name);
}
char *vlDataSetReader::GetScalarsName()
{
  return this->Reader.GetScalarsName();
}

// Description:
// Set the name of the vector data to extract. If not specified, first
// vector data encountered is extracted.
void vlDataSetReader::SetVectorsName(char *name)
{
  this->Reader.SetVectorsName(name);
}
char *vlDataSetReader::GetVectorsName()
{
  return this->Reader.GetVectorsName();
}

// Description:
// Set the name of the tensor data to extract. If not specified, first
// tensor data encountered is extracted.
void vlDataSetReader::SetTensorsName(char *name)
{
  this->Reader.SetTensorsName(name);
}
char *vlDataSetReader::GetTensorsName()
{
  return this->Reader.GetTensorsName();
}

// Description:
// Set the name of the normal data to extract. If not specified, first
// normal data encountered is extracted.
void vlDataSetReader::SetNormalsName(char *name)
{
  this->Reader.SetNormalsName(name);
}
char *vlDataSetReader::GetNormalsName()
{
  return this->Reader.GetNormalsName();
}

// Description:
// Set the name of the texture coordinate data to extract. If not specified,
// first texture coordinate data encountered is extracted.
void vlDataSetReader::SetTCoordsName(char *name)
{
  this->Reader.SetTCoordsName(name);
}
char *vlDataSetReader::GetTCoordsName()
{
  return this->Reader.GetTCoordsName();
}

// Description:
// Set the name of the lookup table data to extract. If not specified, uses
// lookup table named by scalar. Otherwise, this specification supersedes.
void vlDataSetReader::SetLookupTableName(char *name)
{
  this->Reader.SetLookupTableName(name);
}
char *vlDataSetReader::GetLookupTableName()
{
  return this->Reader.GetLookupTableName();
}

void vlDataSetReader::Execute()
{
  FILE *fp;
  int retStat;
  char line[257];
  vlDataSet *reader;

  vlDebugMacro(<<"Reading vl dataset...");
  this->Initialize();
  if ( this->Debug ) this->Reader.DebugOn();
  else this->Reader.DebugOff();

  if ( !(fp=this->Reader.OpenVLFile()) || !this->Reader.ReadHeader(fp) )
      return;
//
// Determine dataset type
//
  if ( (retStat=fscanf(fp,"%256s",line)) == EOF || retStat < 1 )
    {
    vlErrorMacro(<< "Premature EOF reading dataset keyword");
    return;
    }

  if ( !strncmp(this->Reader.LowerCase(line),"dataset",(unsigned long)7) )
    {
//
// See if type is recognized.
//
    if ( (retStat=fscanf(fp,"%256s",line)) == EOF || retStat < 1 )
      {
      vlErrorMacro(<< "Premature EOF reading type");
      return;
      }

    rewind(fp);
    if ( ! strncmp(this->Reader.LowerCase(line),"polydata",8) )
      {
      vlPolyReader *preader = new vlPolyReader;
      preader->SetFilename(this->Reader.GetFilename());
      preader->SetScalarsName(this->Reader.GetScalarsName());
      preader->SetVectorsName(this->Reader.GetVectorsName());
      preader->SetNormalsName(this->Reader.GetNormalsName());
      preader->SetTensorsName(this->Reader.GetTensorsName());
      preader->SetTCoordsName(this->Reader.GetTCoordsName());
      preader->SetLookupTableName(this->Reader.GetLookupTableName());
      preader->Update();
      reader = (vlDataSet *)preader;
      }

    else if ( ! strncmp(line,"structured_points",17) )
      {
      vlStructuredPointsReader *preader = new vlStructuredPointsReader;
      preader->SetFilename(this->Reader.GetFilename());
      preader->SetScalarsName(this->Reader.GetScalarsName());
      preader->SetVectorsName(this->Reader.GetVectorsName());
      preader->SetNormalsName(this->Reader.GetNormalsName());
      preader->SetTensorsName(this->Reader.GetTensorsName());
      preader->SetTCoordsName(this->Reader.GetTCoordsName());
      preader->SetLookupTableName(this->Reader.GetLookupTableName());
      preader->Update();
      reader = (vlDataSet *)preader;
      }

    else if ( ! strncmp(line,"structured_grid",15) )
      {
      vlStructuredGridReader *preader = new vlStructuredGridReader;
      preader->SetFilename(this->Reader.GetFilename());
      preader->SetScalarsName(this->Reader.GetScalarsName());
      preader->SetVectorsName(this->Reader.GetVectorsName());
      preader->SetNormalsName(this->Reader.GetNormalsName());
      preader->SetTensorsName(this->Reader.GetTensorsName());
      preader->SetTCoordsName(this->Reader.GetTCoordsName());
      preader->SetLookupTableName(this->Reader.GetLookupTableName());
      preader->Update();
      reader = (vlDataSet *)preader;
      }

    else if ( ! strncmp(line,"unstructured_grid",17) )
      {
      vlUnstructuredGridReader *preader = new vlUnstructuredGridReader;
      preader->SetFilename(this->Reader.GetFilename());
      preader->SetScalarsName(this->Reader.GetScalarsName());
      preader->SetVectorsName(this->Reader.GetVectorsName());
      preader->SetNormalsName(this->Reader.GetNormalsName());
      preader->SetTensorsName(this->Reader.GetTensorsName());
      preader->SetTCoordsName(this->Reader.GetTCoordsName());
      preader->SetLookupTableName(this->Reader.GetLookupTableName());
      preader->Update();
      reader = (vlDataSet *)preader;
      }

    else
      {
      vlErrorMacro(<< "Cannot read dataset type: " << line);
      return;
      }
    }
//
// Create appropriate dataset
//
  if ( this->DataSet ) delete this->DataSet;
  this->DataSet = reader;
  *(this->DataSet->GetPointData()) = *(reader->GetPointData());

  return;
}

void vlDataSetReader::PrintSelf(ostream& os, vlIndent indent)
{
  vlDataSetSource::PrintSelf(os,indent);
  this->Reader.PrintSelf(os,indent);
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkLight.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include <stdlib.h>
#include <iostream.h>
#include "vtkLight.hh"
#include "vtkRenderer.hh"
#include "vtkRenderWindow.hh"
#include "vtkLightDevice.hh"

// Description:
// Create a light with focal point at origin and position=(0,0,1).
// Light color is white, intensity=1, and the light is turned on.
vtkLight::vtkLight()
{
  this->FocalPoint[0] = 0.0;
  this->FocalPoint[1] = 0.0;
  this->FocalPoint[2] = 0.0;

  this->Position[0] = 0.0;
  this->Position[1] = 0.0;
  this->Position[2] = 1.0;

  this->Color[0] = 1.0;
  this->Color[1] = 1.0;
  this->Color[2] = 1.0;

  this->Switch = 1;

  this->Intensity = 1.0;
  this->Positional = 0;
  this->ConeAngle= 30;
  this->AttenuationValues[0] = 1;
  this->AttenuationValues[1] = 0;
  this->AttenuationValues[2] = 0;
  this->Exponent = 1;
  this->Device = NULL;
}

vtkLight::~vtkLight()
{
  if (this->Device)
    {
    this->Device->Delete();
    }
}

void vtkLight::Render(vtkRenderer *ren,int light_index)
{
  if (!this->Device)
    {
    this->Device = ren->GetRenderWindow()->MakeLight();
    }
  this->Device->Render(this,ren,light_index);
}

void vtkLight::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkObject::PrintSelf(os,indent);

  os << indent << "AttenuationValues: (" << this->AttenuationValues[0] << ", "
    << this->AttenuationValues[1] << ", " << this->AttenuationValues[2] << ")\n";
  os << indent << "Color: (" << this->Color[0] << ", "
    << this->Color[1] << ", " << this->Color[2] << ")\n";
  os << indent << "Cone Angle: " << this->ConeAngle << "\n";
  if ( this->Device )
    {
    os << indent << "Device:\n";
    this->Device->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "Device: (none)\n";
    }
  os << indent << "Exponent: " << this->Exponent << "\n";
  os << indent << "Focal Point: (" << this->FocalPoint[0] << ", "
    << this->FocalPoint[1] << ", " << this->FocalPoint[2] << ")\n";
  os << indent << "Intensity: " << this->Intensity << "\n";
  os << indent << "Position: (" << this->Position[0] << ", "
    << this->Position[1] << ", " << this->Position[2] << ")\n";
  os << indent << "Positional: " << (this->Positional ? "On\n" : "Off\n");
  os << indent << "Switch: " << (this->Switch ? "On\n" : "Off\n");
}

<commit_msg>updated comments<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkLight.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include <stdlib.h>
#include <iostream.h>
#include "vtkLight.hh"
#include "vtkRenderer.hh"
#include "vtkRenderWindow.hh"
#include "vtkLightDevice.hh"

// Description:
// Create a light with the focal point at the origin and its position
// set to (0,0,1). The lights color is white, intensity=1, and the light
// is turned on.
vtkLight::vtkLight()
{
  this->FocalPoint[0] = 0.0;
  this->FocalPoint[1] = 0.0;
  this->FocalPoint[2] = 0.0;

  this->Position[0] = 0.0;
  this->Position[1] = 0.0;
  this->Position[2] = 1.0;

  this->Color[0] = 1.0;
  this->Color[1] = 1.0;
  this->Color[2] = 1.0;

  this->Switch = 1;

  this->Intensity = 1.0;
  this->Positional = 0;
  this->ConeAngle= 30;
  this->AttenuationValues[0] = 1;
  this->AttenuationValues[1] = 0;
  this->AttenuationValues[2] = 0;
  this->Exponent = 1;
  this->Device = NULL;
}

vtkLight::~vtkLight()
{
  if (this->Device)
    {
    this->Device->Delete();
    }
}

void vtkLight::Render(vtkRenderer *ren,int light_index)
{
  if (!this->Device)
    {
    this->Device = ren->GetRenderWindow()->MakeLight();
    }
  this->Device->Render(this,ren,light_index);
}

void vtkLight::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkObject::PrintSelf(os,indent);

  os << indent << "AttenuationValues: (" << this->AttenuationValues[0] << ", "
    << this->AttenuationValues[1] << ", " << this->AttenuationValues[2] << ")\n";
  os << indent << "Color: (" << this->Color[0] << ", "
    << this->Color[1] << ", " << this->Color[2] << ")\n";
  os << indent << "Cone Angle: " << this->ConeAngle << "\n";
  if ( this->Device )
    {
    os << indent << "Device:\n";
    this->Device->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "Device: (none)\n";
    }
  os << indent << "Exponent: " << this->Exponent << "\n";
  os << indent << "Focal Point: (" << this->FocalPoint[0] << ", "
    << this->FocalPoint[1] << ", " << this->FocalPoint[2] << ")\n";
  os << indent << "Intensity: " << this->Intensity << "\n";
  os << indent << "Position: (" << this->Position[0] << ", "
    << this->Position[1] << ", " << this->Position[2] << ")\n";
  os << indent << "Positional: " << (this->Positional ? "On\n" : "Off\n");
  os << indent << "Switch: " << (this->Switch ? "On\n" : "Off\n");
}

<|endoftext|>