<commit_before>#pragma once

#include <string>
#include <functional>
#include <list>
#include <unordered_set>
#include <algorithm>
#include <memory>
#include <vector>
#include <cstring>

namespace pawn_cb
{
	namespace _internal
	{
		class Manager
		{
		public: // singleton
			static Manager &Get()
			{
				static Manager instance;
				return instance;
			}

		private: //constructor / destructor
			Manager() = default;
			~Manager() = default;

		private: //variables
			std::unordered_set<AMX *> _amxInstances;

		public: //functions
			inline void AddAmx(AMX *amx)
			{
				_amxInstances.insert(amx);
			}
			inline void RemoveAmx(AMX *amx)
			{
				_amxInstances.erase(amx);
			}

			inline bool IsValidAmx(AMX *amx) const
			{
				return _amxInstances.count(amx) == 1;
			}
			inline void ForEach(std::function<bool(AMX *)> func)
			{
				for (auto *a : _amxInstances)
					if (!func(a))
						return;
			}
		};
	}

	inline void AddAmx(AMX *amx)
	{
		_internal::Manager::Get().AddAmx(amx);
	}
	inline void RemoveAmx(AMX *amx)
	{
		_internal::Manager::Get().RemoveAmx(amx);
	}

	class Error
	{
		friend class Callback;
	public:
		enum class Type
		{
			NONE,
			INVALID_AMX,
			INVALID_PARAMETERS,
			INVALID_PARAM_COUNT,
			INVALID_FORMAT_SPECIFIER,
			EMPTY_NAME,
			NAME_TOO_LONG,
			NOT_FOUND,
			EXPECTED_ARRAY_SIZE,
			INVALID_ARRAY_SIZE,
			NO_ARRAY_SIZE,
		};

	public:
		Error() : _type(Type::NONE) { }
		~Error() = default;

	private:
		Type _type;

		void set(Type type)
		{
			_type = type;
		}

		void reset()
		{
			set(Type::NONE);
		}

	public:
		Type get() const
		{
			return _type;
		}
		operator Type() const
		{
			return get();
		}
		operator bool() const
		{
			return get() != Type::NONE;
		}
	};

	using Callback_t = std::shared_ptr<class Callback>;
	class Callback
	{
	private:
		class Param
		{
			friend class ::pawn_cb::Callback;
		public:
			enum class Type
			{
				INVALID,
				CELL,
				STRING,
				ARRAY,
				REFERENCE,
			};

		private:
			Type _type;

			union
			{
				cell Cell;
				std::string String;
				std::vector<cell> Array;
				cell *Reference;
			};

		public:
			Param() : _type(Type::INVALID) { }
			template<typename T, typename std::enable_if<
				std::is_arithmetic<T>::value, cell>::type = 0>
				Param(T value) :
				_type(Type::CELL),
				Cell(static_cast<cell>(std::is_floating_point<T>::value ? amx_ftoc(value) : value))
			{ }
			Param(const char *value) :
				_type(Type::STRING)
			{
				new(&String) std::string(value);
			}
			Param(std::string &&value) :
				_type(Type::STRING)
			{
				new(&String) std::string(value);
			}

			template<typename T, typename std::enable_if<
				std::is_arithmetic<T>::value, cell>::type = 0>
				Param(std::vector<T> const &value) :
				_type(Type::ARRAY)
			{
				new(&Array) std::vector<cell>(value.size());

				std::transform(value.begin(), value.end(), std::back_inserter(Array),
					[](T const &v) {
					return std::is_floating_point<T>::value ? amx_ftoc(v) : static_cast<cell>(v);
				});
			}
			Param(cell *array, size_t size) :
				_type(Type::ARRAY)
			{
				new(&Array) std::vector<cell>(array[0], array[size]);
			}
			Param(cell *ref) :
				_type(Type::REFERENCE),
				Reference(ref)
			{ }

			Param(Param const &rhs) = delete;
			Param &operator=(Param const &rhs) = delete;
			Param(Param &&rhs) : _type(rhs._type)
			{
				switch (_type)
				{
				case Type::CELL:
					Cell = rhs.Cell;
					break;
				case Type::STRING:
					new(&String) std::string(std::move(rhs.String));
					break;
				case Type::ARRAY:
					new(&Array) std::vector<cell>(std::move(rhs.Array));
					break;
				case Type::REFERENCE:
					Reference = rhs.Reference;
					break;
				case Type::INVALID:
					// initialize nothing
					break;
				}
			}
			Param &operator=(Param &&rhs)
			{
				_type = rhs._type;
				switch (_type)
				{
				case Type::CELL:
					Cell = rhs.Cell;
					break;
				case Type::STRING:
					new(&String) std::string(std::move(rhs.String));
					break;
				case Type::ARRAY:
					new(&Array) std::vector<cell>(std::move(rhs.Array));
					break;
				case Type::REFERENCE:
					Reference = rhs.Reference;
					break;
				case Type::INVALID:
					// initialize nothing
					break;
				}
				return *this;
			}

			void Push(AMX *amx, cell &push_addr)
			{
				cell tmp;
				switch (_type)
				{
				case Type::CELL:
					amx_Push(amx, Cell);
					break;
				case Type::STRING:
					amx_PushString(amx, &tmp, nullptr, String.c_str(), 0, 0);
					if (push_addr < 0)
						push_addr = tmp;
					break;
				case Type::ARRAY:
					amx_PushArray(amx, &tmp, nullptr, Array.data(), Array.size());
					if (push_addr < 0)
						push_addr = tmp;
					break;
				case Type::REFERENCE:
					amx_PushAddress(amx, Reference);
					break;
				case Type::INVALID:
					// initialize nothing
					break;
				}
			}

		public:
			~Param()
			{
				if (_type == Type::STRING)
					String.~basic_string();
				else if (_type == Type::ARRAY)
					Array.~vector();
			}
		};

	private: //type definitions
		using ParamList_t = std::list<Param>;

	private: //constructor / destructor
		Callback(AMX *amx, int cb_idx, ParamList_t &&params) :
			_amx(amx),
			_amx_index(cb_idx),
			_params(std::move(params))
		{ }

	public:
		~Callback() = default;

	private: //variables
		AMX *_amx = nullptr;
		int _amx_index = -1;

		ParamList_t _params;

	public: //functions
		bool Execute(cell &ret_val)
		{
			cell amx_address = -1;
			for (auto &p : _params)
				p.Push(_amx, amx_address);

			ret_val = 0;
			int error = amx_Exec(_amx, &ret_val, _amx_index);

			if (amx_address >= 0)
				amx_Release(_amx, amx_address);

			return error == AMX_ERR_NONE;
		}
		bool Execute()
		{
			cell unused;
			return Execute(unused);
		}

	private:
		template<typename T, typename... Tv>
		static void AddArgs(ParamList_t &list, T value, Tv&&... tail)
		{
			list.emplace_front(value);
			AddArgs(list, std::forward<Tv>(tail)...);
		}

		static void AddArgs(ParamList_t &list)
		{
			(void)list; // unused
		}

		static bool DoBasicInit(Error &error, AMX *amx, const char *name, int &cb_idx)
		{
			error.reset();

			if (amx == nullptr)
			{
				error.set(Error::Type::INVALID_AMX);
				return false;
			}

			if (name == nullptr || strlen(name) == 0)
			{
				error.set(Error::Type::EMPTY_NAME);
				return false;
			}

			if (strlen(name) > 31)
			{
				error.set(Error::Type::NAME_TOO_LONG);
				return false;
			}

			cb_idx = -1;
			if (amx_FindPublic(amx, name, &cb_idx) != AMX_ERR_NONE || cb_idx < 0)
			{
				error.set(Error::Type::NOT_FOUND);
				return false;
			}

			return true;
		}

	public: //factory functions
		template<typename... Tv>
		static Callback_t Prepare(Error &error, AMX *amx, const char *name, Tv&&... params)
		{
			int cb_idx;
			if (!DoBasicInit(error, amx, name, cb_idx))
				return nullptr;

			ParamList_t param_list;
			AddArgs(param_list, std::forward<Tv>(params)...);

			return Callback_t(new Callback(amx, cb_idx, std::move(param_list)));
		}

		static Callback_t Prepare(AMX *amx, const char *name, const char *format,
			cell *params, cell param_offset, Error &error)
		{
			int cb_idx;
			if (!DoBasicInit(error, amx, name, cb_idx))
				return nullptr;

			const size_t num_params = (format == nullptr) ? 0 : strlen(format);
			if ((params[0] / sizeof(cell) - (param_offset - 1)) != num_params)
			{
				error.set(Error::Type::INVALID_PARAM_COUNT);
				return nullptr;
			}

			ParamList_t param_list;
			if (num_params != 0)
			{
				cell param_idx = 0;
				cell *address_ptr = nullptr;
				cell *array_addr_ptr = nullptr;

				do
				{
					if (array_addr_ptr != nullptr && (*format) != 'd' && (*format) != 'i')
					{
						error.set(Error::Type::EXPECTED_ARRAY_SIZE);
						return nullptr;
					}

					switch (*format)
					{
					case 'd': //decimal
					case 'i': //integer
					{
						amx_GetAddr(amx, params[param_offset + param_idx], &address_ptr);
						cell value = *address_ptr;
						if (array_addr_ptr != nullptr)
						{
							if (value <= 0)
							{
								error.set(Error::Type::INVALID_ARRAY_SIZE);
								return nullptr;
							}

							param_list.emplace_front(array_addr_ptr, value);
							array_addr_ptr = nullptr;
						}

						param_list.emplace_front(value);
					}
					break;
					case 'f': //float
					case 'b': //bool
						amx_GetAddr(amx, params[param_offset + param_idx], &address_ptr);
						param_list.emplace_front(*address_ptr);
						break;
					case 's': //string
						param_list.emplace_front(
							amx_GetCppString(amx, params[param_offset + param_idx]));
						break;
					case 'a': //array
						amx_GetAddr(amx, params[param_offset + param_idx], &array_addr_ptr);
						break;
					case 'r': //reference
						amx_GetAddr(amx, params[param_offset + param_idx], &address_ptr);
						param_list.emplace_front(address_ptr);
						break;
					default:
						error.set(Error::Type::INVALID_FORMAT_SPECIFIER);
						return nullptr;
					}
					param_idx++;
				} while (*(++format) != '\0');

				if (array_addr_ptr != nullptr)
				{
					error.set(Error::Type::NO_ARRAY_SIZE);
					return nullptr;
				}
			}

			return Callback_t(new Callback(amx, cb_idx, std::move(param_list)));
		}

		template<typename... Tv>
		static bool Call(Error &error, AMX *amx, cell &ret_val, const char *name, Tv&&... params)
		{
			int cb_idx;
			if (!DoBasicInit(error, amx, name, cb_idx))
				return false;

			ParamList_t param_list;
			AddArgs(param_list, std::forward<Tv>(params)...);

			Callback cb(amx, cb_idx, std::move(param_list));
			return cb.Execute(ret_val);
		}

		template<typename... Tv>
		static bool Call(Error &error, AMX *amx, const char *name, Tv&&... params)
		{
			cell unused;
			return Call(error, amx, unused, name, std::forward<Tv>(params)...);
		}

		template<typename... Tv>
		static bool CallFirst(Error &error, cell &ret_val, const char *name, Tv&&... params)
		{
			bool success = false;
			_internal::Manager::Get().ForEach([&](AMX *amx)
			{
				bool res = Call(error, amx, ret_val, name, std::forward<Tv>(params)...);
				if (error == Error::Type::NOT_FOUND)
					return true; // continue / skip

				if (error || !res)
					return false; // break

				// callback was successfully called, stop lookup and break out of loop
				success = true;
				return false; // break
			});
			return success;
		}

		template<typename... Tv>
		static bool CallFirst(Error &error, const char *name, Tv&&... params)
		{
			cell unused;
			return CallFirst(error, unused, name, std::forward<Tv>(params)...);
		}
	};
}
<commit_msg>Include iterator, should now fix the error.<commit_after>#pragma once

#include <string>
#include <functional>
#include <list>
#include <unordered_set>
#include <algorithm>
#include <memory>
#include <vector>
#include <cstring>
#include <iterator>

namespace pawn_cb
{
	namespace _internal
	{
		class Manager
		{
		public: // singleton
			static Manager &Get()
			{
				static Manager instance;
				return instance;
			}

		private: //constructor / destructor
			Manager() = default;
			~Manager() = default;

		private: //variables
			std::unordered_set<AMX *> _amxInstances;

		public: //functions
			inline void AddAmx(AMX *amx)
			{
				_amxInstances.insert(amx);
			}
			inline void RemoveAmx(AMX *amx)
			{
				_amxInstances.erase(amx);
			}

			inline bool IsValidAmx(AMX *amx) const
			{
				return _amxInstances.count(amx) == 1;
			}
			inline void ForEach(std::function<bool(AMX *)> func)
			{
				for (auto *a : _amxInstances)
					if (!func(a))
						return;
			}
		};
	}

	inline void AddAmx(AMX *amx)
	{
		_internal::Manager::Get().AddAmx(amx);
	}
	inline void RemoveAmx(AMX *amx)
	{
		_internal::Manager::Get().RemoveAmx(amx);
	}

	class Error
	{
		friend class Callback;
	public:
		enum class Type
		{
			NONE,
			INVALID_AMX,
			INVALID_PARAMETERS,
			INVALID_PARAM_COUNT,
			INVALID_FORMAT_SPECIFIER,
			EMPTY_NAME,
			NAME_TOO_LONG,
			NOT_FOUND,
			EXPECTED_ARRAY_SIZE,
			INVALID_ARRAY_SIZE,
			NO_ARRAY_SIZE,
		};

	public:
		Error() : _type(Type::NONE) { }
		~Error() = default;

	private:
		Type _type;

		void set(Type type)
		{
			_type = type;
		}

		void reset()
		{
			set(Type::NONE);
		}

	public:
		Type get() const
		{
			return _type;
		}
		operator Type() const
		{
			return get();
		}
		operator bool() const
		{
			return get() != Type::NONE;
		}
	};

	using Callback_t = std::shared_ptr<class Callback>;
	class Callback
	{
	private:
		class Param
		{
			friend class ::pawn_cb::Callback;
		public:
			enum class Type
			{
				INVALID,
				CELL,
				STRING,
				ARRAY,
				REFERENCE,
			};

		private:
			Type _type;

			union
			{
				cell Cell;
				std::string String;
				std::vector<cell> Array;
				cell *Reference;
			};

		public:
			Param() : _type(Type::INVALID) { }
			template<typename T, typename std::enable_if<
				std::is_arithmetic<T>::value, cell>::type = 0>
				Param(T value) :
				_type(Type::CELL),
				Cell(static_cast<cell>(std::is_floating_point<T>::value ? amx_ftoc(value) : value))
			{ }
			Param(const char *value) :
				_type(Type::STRING)
			{
				new(&String) std::string(value);
			}
			Param(std::string &&value) :
				_type(Type::STRING)
			{
				new(&String) std::string(value);
			}

			template<typename T, typename std::enable_if<
				std::is_arithmetic<T>::value, cell>::type = 0>
				Param(std::vector<T> const &value) :
				_type(Type::ARRAY)
			{
				new(&Array) std::vector<cell>(value.size());

				std::transform(value.begin(), value.end(), std::back_inserter(Array),
					[](T const &v) {
					return std::is_floating_point<T>::value ? amx_ftoc(v) : static_cast<cell>(v);
				});
			}
			Param(cell *array, size_t size) :
				_type(Type::ARRAY)
			{
				new(&Array) std::vector<cell>(array[0], array[size]);
			}
			Param(cell *ref) :
				_type(Type::REFERENCE),
				Reference(ref)
			{ }

			Param(Param const &rhs) = delete;
			Param &operator=(Param const &rhs) = delete;
			Param(Param &&rhs) : _type(rhs._type)
			{
				switch (_type)
				{
				case Type::CELL:
					Cell = rhs.Cell;
					break;
				case Type::STRING:
					new(&String) std::string(std::move(rhs.String));
					break;
				case Type::ARRAY:
					new(&Array) std::vector<cell>(std::move(rhs.Array));
					break;
				case Type::REFERENCE:
					Reference = rhs.Reference;
					break;
				case Type::INVALID:
					// initialize nothing
					break;
				}
			}
			Param &operator=(Param &&rhs)
			{
				_type = rhs._type;
				switch (_type)
				{
				case Type::CELL:
					Cell = rhs.Cell;
					break;
				case Type::STRING:
					new(&String) std::string(std::move(rhs.String));
					break;
				case Type::ARRAY:
					new(&Array) std::vector<cell>(std::move(rhs.Array));
					break;
				case Type::REFERENCE:
					Reference = rhs.Reference;
					break;
				case Type::INVALID:
					// initialize nothing
					break;
				}
				return *this;
			}

			void Push(AMX *amx, cell &push_addr)
			{
				cell tmp;
				switch (_type)
				{
				case Type::CELL:
					amx_Push(amx, Cell);
					break;
				case Type::STRING:
					amx_PushString(amx, &tmp, nullptr, String.c_str(), 0, 0);
					if (push_addr < 0)
						push_addr = tmp;
					break;
				case Type::ARRAY:
					amx_PushArray(amx, &tmp, nullptr, Array.data(), Array.size());
					if (push_addr < 0)
						push_addr = tmp;
					break;
				case Type::REFERENCE:
					amx_PushAddress(amx, Reference);
					break;
				case Type::INVALID:
					// initialize nothing
					break;
				}
			}

		public:
			~Param()
			{
				if (_type == Type::STRING)
					String.~basic_string();
				else if (_type == Type::ARRAY)
					Array.~vector();
			}
		};

	private: //type definitions
		using ParamList_t = std::list<Param>;

	private: //constructor / destructor
		Callback(AMX *amx, int cb_idx, ParamList_t &&params) :
			_amx(amx),
			_amx_index(cb_idx),
			_params(std::move(params))
		{ }

	public:
		~Callback() = default;

	private: //variables
		AMX *_amx = nullptr;
		int _amx_index = -1;

		ParamList_t _params;

	public: //functions
		bool Execute(cell &ret_val)
		{
			cell amx_address = -1;
			for (auto &p : _params)
				p.Push(_amx, amx_address);

			ret_val = 0;
			int error = amx_Exec(_amx, &ret_val, _amx_index);

			if (amx_address >= 0)
				amx_Release(_amx, amx_address);

			return error == AMX_ERR_NONE;
		}
		bool Execute()
		{
			cell unused;
			return Execute(unused);
		}

	private:
		template<typename T, typename... Tv>
		static void AddArgs(ParamList_t &list, T value, Tv&&... tail)
		{
			list.emplace_front(value);
			AddArgs(list, std::forward<Tv>(tail)...);
		}

		static void AddArgs(ParamList_t &list)
		{
			(void)list; // unused
		}

		static bool DoBasicInit(Error &error, AMX *amx, const char *name, int &cb_idx)
		{
			error.reset();

			if (amx == nullptr)
			{
				error.set(Error::Type::INVALID_AMX);
				return false;
			}

			if (name == nullptr || strlen(name) == 0)
			{
				error.set(Error::Type::EMPTY_NAME);
				return false;
			}

			if (strlen(name) > 31)
			{
				error.set(Error::Type::NAME_TOO_LONG);
				return false;
			}

			cb_idx = -1;
			if (amx_FindPublic(amx, name, &cb_idx) != AMX_ERR_NONE || cb_idx < 0)
			{
				error.set(Error::Type::NOT_FOUND);
				return false;
			}

			return true;
		}

	public: //factory functions
		template<typename... Tv>
		static Callback_t Prepare(Error &error, AMX *amx, const char *name, Tv&&... params)
		{
			int cb_idx;
			if (!DoBasicInit(error, amx, name, cb_idx))
				return nullptr;

			ParamList_t param_list;
			AddArgs(param_list, std::forward<Tv>(params)...);

			return Callback_t(new Callback(amx, cb_idx, std::move(param_list)));
		}

		static Callback_t Prepare(AMX *amx, const char *name, const char *format,
			cell *params, cell param_offset, Error &error)
		{
			int cb_idx;
			if (!DoBasicInit(error, amx, name, cb_idx))
				return nullptr;

			const size_t num_params = (format == nullptr) ? 0 : strlen(format);
			if ((params[0] / sizeof(cell) - (param_offset - 1)) != num_params)
			{
				error.set(Error::Type::INVALID_PARAM_COUNT);
				return nullptr;
			}

			ParamList_t param_list;
			if (num_params != 0)
			{
				cell param_idx = 0;
				cell *address_ptr = nullptr;
				cell *array_addr_ptr = nullptr;

				do
				{
					if (array_addr_ptr != nullptr && (*format) != 'd' && (*format) != 'i')
					{
						error.set(Error::Type::EXPECTED_ARRAY_SIZE);
						return nullptr;
					}

					switch (*format)
					{
					case 'd': //decimal
					case 'i': //integer
					{
						amx_GetAddr(amx, params[param_offset + param_idx], &address_ptr);
						cell value = *address_ptr;
						if (array_addr_ptr != nullptr)
						{
							if (value <= 0)
							{
								error.set(Error::Type::INVALID_ARRAY_SIZE);
								return nullptr;
							}

							param_list.emplace_front(array_addr_ptr, value);
							array_addr_ptr = nullptr;
						}

						param_list.emplace_front(value);
					}
					break;
					case 'f': //float
					case 'b': //bool
						amx_GetAddr(amx, params[param_offset + param_idx], &address_ptr);
						param_list.emplace_front(*address_ptr);
						break;
					case 's': //string
						param_list.emplace_front(
							amx_GetCppString(amx, params[param_offset + param_idx]));
						break;
					case 'a': //array
						amx_GetAddr(amx, params[param_offset + param_idx], &array_addr_ptr);
						break;
					case 'r': //reference
						amx_GetAddr(amx, params[param_offset + param_idx], &address_ptr);
						param_list.emplace_front(address_ptr);
						break;
					default:
						error.set(Error::Type::INVALID_FORMAT_SPECIFIER);
						return nullptr;
					}
					param_idx++;
				} while (*(++format) != '\0');

				if (array_addr_ptr != nullptr)
				{
					error.set(Error::Type::NO_ARRAY_SIZE);
					return nullptr;
				}
			}

			return Callback_t(new Callback(amx, cb_idx, std::move(param_list)));
		}

		template<typename... Tv>
		static bool Call(Error &error, AMX *amx, cell &ret_val, const char *name, Tv&&... params)
		{
			int cb_idx;
			if (!DoBasicInit(error, amx, name, cb_idx))
				return false;

			ParamList_t param_list;
			AddArgs(param_list, std::forward<Tv>(params)...);

			Callback cb(amx, cb_idx, std::move(param_list));
			return cb.Execute(ret_val);
		}

		template<typename... Tv>
		static bool Call(Error &error, AMX *amx, const char *name, Tv&&... params)
		{
			cell unused;
			return Call(error, amx, unused, name, std::forward<Tv>(params)...);
		}

		template<typename... Tv>
		static bool CallFirst(Error &error, cell &ret_val, const char *name, Tv&&... params)
		{
			bool success = false;
			_internal::Manager::Get().ForEach([&](AMX *amx)
			{
				bool res = Call(error, amx, ret_val, name, std::forward<Tv>(params)...);
				if (error == Error::Type::NOT_FOUND)
					return true; // continue / skip

				if (error || !res)
					return false; // break

				// callback was successfully called, stop lookup and break out of loop
				success = true;
				return false; // break
			});
			return success;
		}

		template<typename... Tv>
		static bool CallFirst(Error &error, const char *name, Tv&&... params)
		{
			cell unused;
			return CallFirst(error, unused, name, std::forward<Tv>(params)...);
		}
	};
}
<|endoftext|>


<commit_before>// Copyright 2016 bitHeads, Inc. All Rights Reserved.

#include "braincloud/BrainCloudSocialLeaderboard.h"

#include "braincloud/BrainCloudClient.h"
#include "braincloud/IServerCallback.h"
#include "braincloud/ServerCall.h"
#include "braincloud/ServiceName.h"
#include "braincloud/ServiceOperation.h"
#include "braincloud/OperationParam.h"
#include "json/json.h"

#include "braincloud/internal/JsonUtil.h"
#include <time.h>

namespace BrainCloud
{
	BrainCloudSocialLeaderboard::BrainCloudSocialLeaderboard(BrainCloudClient* in_client) : m_client(in_client) { }

	void BrainCloudSocialLeaderboard::getSocialLeaderboard(const char * in_leaderboardId, bool in_replaceName, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceReplaceName.getValue()] = in_replaceName;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetSocialLeaderboard, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getMultiSocialLeaderboard(const std::vector<std::string> & in_leaderboardIds, int in_leaderboardResultCount, bool in_replaceName, IServerCallback * in_callback)
	{
		Json::Value message;
		if (in_leaderboardIds.size() > 0)
		{
			message[OperationParam::SocialLeaderboardServiceLeaderboardIds.getValue()] = JsonUtil::stringVectorToJson(in_leaderboardIds);
		}
		message[OperationParam::SocialLeaderboardServiceLeaderboardResultCount.getValue()] = in_leaderboardResultCount;
		message[OperationParam::SocialLeaderboardServiceReplaceName.getValue()] = in_replaceName;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetMultiSocialLeaderboard, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardPage(const char * in_leaderboardId, SortOrder in_sortOrder, int in_startIndex,
		int in_endIndex, bool in_includeLeaderboardSize, IServerCallback * in_callback)
	{
		std::string sortOrder = sortOrderToString(in_sortOrder);

		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceSortOrder.getValue()] = sortOrder;
		message[OperationParam::SocialLeaderboardServiceStartIndex.getValue()] = in_startIndex;
		message[OperationParam::SocialLeaderboardServiceEndIndex.getValue()] = in_endIndex;
		message[OperationParam::SocialLeaderboardServiceIncludeLeaderboardSize.getValue()] = in_includeLeaderboardSize;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardPage, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardPageByVersion(const char * in_leaderboardId, SortOrder in_sortOrder, int in_startIndex, int in_endIndex, bool in_includeLeaderboardSize, int in_versionId, IServerCallback * in_callback)
	{
		std::string sortOrder = sortOrderToString(in_sortOrder);

		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceSortOrder.getValue()] = sortOrder;
		message[OperationParam::SocialLeaderboardServiceStartIndex.getValue()] = in_startIndex;
		message[OperationParam::SocialLeaderboardServiceEndIndex.getValue()] = in_endIndex;
		message[OperationParam::SocialLeaderboardServiceIncludeLeaderboardSize.getValue()] = in_includeLeaderboardSize;
		message[OperationParam::SocialLeaderboardServiceVersionId.getValue()] = in_versionId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardPage, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardView(const char * in_leaderboardId, SortOrder in_sortOrder, int in_beforeCount,
		int in_afterCount, bool in_includeLeaderboardSize, IServerCallback * in_callback)
	{
		std::string sortOrder = sortOrderToString(in_sortOrder);

		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceSortOrder.getValue()] = sortOrder;
		message[OperationParam::SocialLeaderboardServiceBeforeCount.getValue()] = in_beforeCount;
		message[OperationParam::SocialLeaderboardServiceAfterCount.getValue()] = in_afterCount;
		message[OperationParam::SocialLeaderboardServiceIncludeLeaderboardSize.getValue()] = in_includeLeaderboardSize;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardView, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardViewByVersion(const char * in_leaderboardId, SortOrder in_sortOrder, int in_beforeCount,
		int in_afterCount, bool in_includeLeaderboardSize, int in_versionId, IServerCallback * in_callback)
	{
		std::string sortOrder = sortOrderToString(in_sortOrder);

		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceSortOrder.getValue()] = sortOrder;
		message[OperationParam::SocialLeaderboardServiceBeforeCount.getValue()] = in_beforeCount;
		message[OperationParam::SocialLeaderboardServiceAfterCount.getValue()] = in_afterCount;
		message[OperationParam::SocialLeaderboardServiceIncludeLeaderboardSize.getValue()] = in_includeLeaderboardSize;
		message[OperationParam::SocialLeaderboardServiceVersionId.getValue()] = in_versionId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardView, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardVersions(const char * in_leaderboardId, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardVersions, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::postScoreToLeaderboard(const char * in_leaderboardId, int64_t in_score, const std::string& in_jsonOtherData, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceScore.getValue()] = (Json::Int64) in_score;
		message[OperationParam::SocialLeaderboardServiceData.getValue()] = JsonUtil::jsonStringToValue(in_jsonOtherData);

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::PostScore, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::postScoreToDynamicLeaderboard(
		const char * in_leaderboardId,
		int64_t in_score,
		const std::string& in_jsonData,
		SocialLeaderboardType in_leaderboardType,
		RotationType in_rotationType,
		struct tm* in_rotationReset,
		int in_retainedCount,
		IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceScore.getValue()] = (Json::Int64) in_score;
		message[OperationParam::SocialLeaderboardServiceData.getValue()] = JsonUtil::jsonStringToValue(in_jsonData);

		message[OperationParam::SocialLeaderboardServiceLeaderboardType.getValue()] = leaderboardTypeToString(in_leaderboardType).c_str();
		message[OperationParam::SocialLeaderboardServiceRotationType.getValue()] = leaderboardRotationTypeToString(in_rotationType).c_str();

		if (in_rotationReset != NULL)
		{
			time_t timestamp = mktime(in_rotationReset);
			message[OperationParam::SocialLeaderboardServiceRotationResetTime.getValue()] = (int64_t)timestamp * 1000;
		}
		message[OperationParam::SocialLeaderboardServiceRetainedCount.getValue()] = in_retainedCount;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::PostScoreDynamic, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::resetLeaderboardScore(const char * in_leaderboardId, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::Reset, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getCompletedLeaderboardTournament(const char * in_leaderboardId, bool in_replaceName, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceReplaceName.getValue()] = in_replaceName;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetCompletedTournament, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::triggerSocialLeaderboardTournamentReward(const char * in_leaderboardId, const char * in_eventName, uint64_t in_eventMultiplier, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceEventName.getValue()] = in_eventName;
		message[OperationParam::SocialLeaderboardServiceEventMultiplier.getValue()] = (Json::UInt64) in_eventMultiplier;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::RewardTournament, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::playerTournamentReward(const char * in_eventName, uint64_t in_multiplier, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceEventName.getValue()] = in_eventName;
		message[OperationParam::SocialLeaderboardServiceEventMultiplier.getValue()] = (Json::UInt64) in_multiplier;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::RewardTournament, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGroupSocialLeaderboard(const char * in_leaderboardId, const char * in_groupId, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::GroupId.getValue()] = in_groupId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGroupSocialLeaderboard, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getPlayersSocialLeaderboard(const char * in_leaderboardId, std::vector<std::string> in_profileIds, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::ProfileIds.getValue()] = JsonUtil::stringVectorToJson(in_profileIds);

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetPlayersSocialLeaderboard, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	std::string BrainCloudSocialLeaderboard::leaderboardTypeToString(SocialLeaderboardType type)
	{
		std::string typeString = "HIGH_VALUE";

		if (type == CUMULATIVE)
			typeString = "CUMULATIVE";
		else if (type == LAST_VALUE)
			typeString = "LAST_VALUE";
		else if (type == LOW_VALUE)
			typeString = "LOW_VALUE";

		return typeString;
	}

	std::string BrainCloudSocialLeaderboard::leaderboardRotationTypeToString(RotationType type)
	{
		std::string typeString = "NEVER";

		switch (type)
		{
		case DAILY:
			typeString = "DAILY";
			break;
		case WEEKLY:
			typeString = "WEEKLY";
			break;
		case MONTHLY:
			typeString = "MONTHLY";
			break;
		case YEARLY:
			typeString = "YEARLY";
			break;
		default:
			break;
		}

		return typeString;
	}

	std::string BrainCloudSocialLeaderboard::sortOrderToString(SortOrder in_sortOrder)
	{
		std::string sortOrder = "HIGHEST_RANKED";

		if (in_sortOrder == HIGH_TO_LOW)
		{
			sortOrder = "HIGH_TO_LOW";
		}
		else if (in_sortOrder == LOW_TO_HIGH)
		{
			sortOrder = "LOW_TO_HIGH";
		}
		else
		{
			sortOrder = "HIGHEST_RANKED";
		}
		return sortOrder;
	}
}<commit_msg>Fix linux time conversion<commit_after>// Copyright 2016 bitHeads, Inc. All Rights Reserved.

#include "braincloud/BrainCloudSocialLeaderboard.h"

#include "braincloud/BrainCloudClient.h"
#include "braincloud/IServerCallback.h"
#include "braincloud/ServerCall.h"
#include "braincloud/ServiceName.h"
#include "braincloud/ServiceOperation.h"
#include "braincloud/OperationParam.h"
#include "json/json.h"

#include "braincloud/internal/JsonUtil.h"
#include <time.h>

namespace BrainCloud
{
	BrainCloudSocialLeaderboard::BrainCloudSocialLeaderboard(BrainCloudClient* in_client) : m_client(in_client) { }

	void BrainCloudSocialLeaderboard::getSocialLeaderboard(const char * in_leaderboardId, bool in_replaceName, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceReplaceName.getValue()] = in_replaceName;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetSocialLeaderboard, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getMultiSocialLeaderboard(const std::vector<std::string> & in_leaderboardIds, int in_leaderboardResultCount, bool in_replaceName, IServerCallback * in_callback)
	{
		Json::Value message;
		if (in_leaderboardIds.size() > 0)
		{
			message[OperationParam::SocialLeaderboardServiceLeaderboardIds.getValue()] = JsonUtil::stringVectorToJson(in_leaderboardIds);
		}
		message[OperationParam::SocialLeaderboardServiceLeaderboardResultCount.getValue()] = in_leaderboardResultCount;
		message[OperationParam::SocialLeaderboardServiceReplaceName.getValue()] = in_replaceName;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetMultiSocialLeaderboard, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardPage(const char * in_leaderboardId, SortOrder in_sortOrder, int in_startIndex,
		int in_endIndex, bool in_includeLeaderboardSize, IServerCallback * in_callback)
	{
		std::string sortOrder = sortOrderToString(in_sortOrder);

		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceSortOrder.getValue()] = sortOrder;
		message[OperationParam::SocialLeaderboardServiceStartIndex.getValue()] = in_startIndex;
		message[OperationParam::SocialLeaderboardServiceEndIndex.getValue()] = in_endIndex;
		message[OperationParam::SocialLeaderboardServiceIncludeLeaderboardSize.getValue()] = in_includeLeaderboardSize;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardPage, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardPageByVersion(const char * in_leaderboardId, SortOrder in_sortOrder, int in_startIndex, int in_endIndex, bool in_includeLeaderboardSize, int in_versionId, IServerCallback * in_callback)
	{
		std::string sortOrder = sortOrderToString(in_sortOrder);

		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceSortOrder.getValue()] = sortOrder;
		message[OperationParam::SocialLeaderboardServiceStartIndex.getValue()] = in_startIndex;
		message[OperationParam::SocialLeaderboardServiceEndIndex.getValue()] = in_endIndex;
		message[OperationParam::SocialLeaderboardServiceIncludeLeaderboardSize.getValue()] = in_includeLeaderboardSize;
		message[OperationParam::SocialLeaderboardServiceVersionId.getValue()] = in_versionId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardPage, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardView(const char * in_leaderboardId, SortOrder in_sortOrder, int in_beforeCount,
		int in_afterCount, bool in_includeLeaderboardSize, IServerCallback * in_callback)
	{
		std::string sortOrder = sortOrderToString(in_sortOrder);

		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceSortOrder.getValue()] = sortOrder;
		message[OperationParam::SocialLeaderboardServiceBeforeCount.getValue()] = in_beforeCount;
		message[OperationParam::SocialLeaderboardServiceAfterCount.getValue()] = in_afterCount;
		message[OperationParam::SocialLeaderboardServiceIncludeLeaderboardSize.getValue()] = in_includeLeaderboardSize;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardView, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardViewByVersion(const char * in_leaderboardId, SortOrder in_sortOrder, int in_beforeCount,
		int in_afterCount, bool in_includeLeaderboardSize, int in_versionId, IServerCallback * in_callback)
	{
		std::string sortOrder = sortOrderToString(in_sortOrder);

		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceSortOrder.getValue()] = sortOrder;
		message[OperationParam::SocialLeaderboardServiceBeforeCount.getValue()] = in_beforeCount;
		message[OperationParam::SocialLeaderboardServiceAfterCount.getValue()] = in_afterCount;
		message[OperationParam::SocialLeaderboardServiceIncludeLeaderboardSize.getValue()] = in_includeLeaderboardSize;
		message[OperationParam::SocialLeaderboardServiceVersionId.getValue()] = in_versionId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardView, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGlobalLeaderboardVersions(const char * in_leaderboardId, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGlobalLeaderboardVersions, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::postScoreToLeaderboard(const char * in_leaderboardId, int64_t in_score, const std::string& in_jsonOtherData, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceScore.getValue()] = (Json::Int64) in_score;
		message[OperationParam::SocialLeaderboardServiceData.getValue()] = JsonUtil::jsonStringToValue(in_jsonOtherData);

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::PostScore, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::postScoreToDynamicLeaderboard(
		const char * in_leaderboardId,
		int64_t in_score,
		const std::string& in_jsonData,
		SocialLeaderboardType in_leaderboardType,
		RotationType in_rotationType,
		struct tm* in_rotationReset,
		int in_retainedCount,
		IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceScore.getValue()] = (Json::Int64) in_score;
		message[OperationParam::SocialLeaderboardServiceData.getValue()] = JsonUtil::jsonStringToValue(in_jsonData);

		message[OperationParam::SocialLeaderboardServiceLeaderboardType.getValue()] = leaderboardTypeToString(in_leaderboardType).c_str();
		message[OperationParam::SocialLeaderboardServiceRotationType.getValue()] = leaderboardRotationTypeToString(in_rotationType).c_str();

		if (in_rotationReset != NULL)
		{
			time_t timestamp = mktime(in_rotationReset);
			int64_t time = (int64_t)timestamp * 1000;
			message[OperationParam::SocialLeaderboardServiceRotationResetTime.getValue()] = time;
		}
		message[OperationParam::SocialLeaderboardServiceRetainedCount.getValue()] = in_retainedCount;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::PostScoreDynamic, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::resetLeaderboardScore(const char * in_leaderboardId, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::Reset, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getCompletedLeaderboardTournament(const char * in_leaderboardId, bool in_replaceName, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceReplaceName.getValue()] = in_replaceName;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetCompletedTournament, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::triggerSocialLeaderboardTournamentReward(const char * in_leaderboardId, const char * in_eventName, uint64_t in_eventMultiplier, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::SocialLeaderboardServiceEventName.getValue()] = in_eventName;
		message[OperationParam::SocialLeaderboardServiceEventMultiplier.getValue()] = (Json::UInt64) in_eventMultiplier;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::RewardTournament, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::playerTournamentReward(const char * in_eventName, uint64_t in_multiplier, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceEventName.getValue()] = in_eventName;
		message[OperationParam::SocialLeaderboardServiceEventMultiplier.getValue()] = (Json::UInt64) in_multiplier;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::RewardTournament, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getGroupSocialLeaderboard(const char * in_leaderboardId, const char * in_groupId, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::GroupId.getValue()] = in_groupId;

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetGroupSocialLeaderboard, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	void BrainCloudSocialLeaderboard::getPlayersSocialLeaderboard(const char * in_leaderboardId, std::vector<std::string> in_profileIds, IServerCallback * in_callback)
	{
		Json::Value message;
		message[OperationParam::SocialLeaderboardServiceLeaderboardId.getValue()] = in_leaderboardId;
		message[OperationParam::ProfileIds.getValue()] = JsonUtil::stringVectorToJson(in_profileIds);

		ServerCall * sc = new ServerCall(ServiceName::SocialLeaderboard, ServiceOperation::GetPlayersSocialLeaderboard, message, in_callback);
		m_client->getBrainCloudComms()->addToQueue(sc);
	}

	std::string BrainCloudSocialLeaderboard::leaderboardTypeToString(SocialLeaderboardType type)
	{
		std::string typeString = "HIGH_VALUE";

		if (type == CUMULATIVE)
			typeString = "CUMULATIVE";
		else if (type == LAST_VALUE)
			typeString = "LAST_VALUE";
		else if (type == LOW_VALUE)
			typeString = "LOW_VALUE";

		return typeString;
	}

	std::string BrainCloudSocialLeaderboard::leaderboardRotationTypeToString(RotationType type)
	{
		std::string typeString = "NEVER";

		switch (type)
		{
		case DAILY:
			typeString = "DAILY";
			break;
		case WEEKLY:
			typeString = "WEEKLY";
			break;
		case MONTHLY:
			typeString = "MONTHLY";
			break;
		case YEARLY:
			typeString = "YEARLY";
			break;
		default:
			break;
		}

		return typeString;
	}

	std::string BrainCloudSocialLeaderboard::sortOrderToString(SortOrder in_sortOrder)
	{
		std::string sortOrder = "HIGHEST_RANKED";

		if (in_sortOrder == HIGH_TO_LOW)
		{
			sortOrder = "HIGH_TO_LOW";
		}
		else if (in_sortOrder == LOW_TO_HIGH)
		{
			sortOrder = "LOW_TO_HIGH";
		}
		else
		{
			sortOrder = "HIGHEST_RANKED";
		}
		return sortOrder;
	}
}<|endoftext|>


<commit_before>// Container.cc
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//                and Simon Bowden    (rathnor at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Container.cc,v 1.7 2003/10/31 10:37:09 rathnor Exp $

#include "Container.hh"

#include "FbTk/Button.hh"
#include "FbTk/EventManager.hh"

Container::Container(const FbTk::FbWindow &parent):
    FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask), m_selected(0),
    m_update_lock(false) {
    FbTk::EventManager::instance()->add(*this, *this);
}

Container::~Container() {

}

void Container::resize(unsigned int width, unsigned int height) {
    // do we need to resize?
    if (FbTk::FbWindow::width() == width &&
        FbTk::FbWindow::height() == height)
        return;

    FbTk::FbWindow::resize(width, height);
    repositionItems();
}

void Container::moveResize(int x, int y,
                           unsigned int width, unsigned int height) {
    FbTk::FbWindow::moveResize(x, y, width, height);
    repositionItems();
}

void Container::insertItems(ItemList &item_list, int pos) {

    // make sure all items have parent == this
    ItemList::iterator it = m_item_list.begin();
    ItemList::iterator it_end = m_item_list.end();
    for (; it != it_end; ++it) {
        if ((*it)->parent() != this)
            return;
    }

    if (pos > size() || pos < 0) {
        // insert last
        m_item_list.splice(m_item_list.end(), item_list);
    } else if (pos == 0) {
        // insert first
        m_item_list.splice(m_item_list.begin(), item_list);
    } else {
        // find insert point
        for (it = m_item_list.begin(); pos != 0; ++it, --pos)
            continue;
        m_item_list.splice(it, item_list);
    }

    m_item_list.unique();

    // update position
    repositionItems();
}

void Container::insertItem(Item item, int pos) {
    if (find(item) != -1)
        return;

    // it must be a child of this window
    if (item->parent() != this)
        return;

    if (pos >= size() || pos < 0) {
        m_item_list.push_back(item);
    } else if (pos == 0) {
        m_item_list.push_front(item);
    } else {
        ItemList::iterator it = m_item_list.begin();
        for (; pos != 0; ++it, --pos)
            continue;

        m_item_list.insert(it, item);
    }

    // make sure we dont have duplicate items
    m_item_list.unique();

    repositionItems();
}

void Container::removeItem(int index) {
    if (index < 0 || index > size())
        return;

    ItemList::iterator it = m_item_list.begin();
    for (; index != 0; ++it, --index)
        continue;

    if (*it == selected())
        m_selected = 0;

    m_item_list.erase(it);

    repositionItems();
}

void Container::removeAll() {
    m_selected = 0;
    m_item_list.clear();
    if (!m_update_lock)
        clear();

}

int Container::find(Item item) {
    ItemList::iterator it = m_item_list.begin();
    ItemList::iterator it_end = m_item_list.end();
    int index = 0;
    for (; it != it_end; ++it, ++index) {
        if ((*it) == item)
            break;
    }

    if (it == it_end)
        return -1;

    return index;
}

void Container::setSelected(int pos) {
    if (pos < 0 || pos >= size())
        m_selected = 0;
    else {
        ItemList::iterator it = m_item_list.begin();
        for (; pos != 0; --pos, ++it)
            continue;
        m_selected = *it;
        if (m_selected)
            m_selected->clear();
    }

}

void Container::exposeEvent(XExposeEvent &event) {
    if (!m_update_lock)
        clearArea(event.x, event.y, event.width, event.height);
}

void Container::repositionItems() {
    if (size() == 0 || m_update_lock)
        return;

    //!! TODO vertical position

    const int max_width_per_client = maxWidthPerClient();

    ItemList::iterator it = m_item_list.begin();
    const ItemList::iterator it_end = m_item_list.end();
    int borderW = m_item_list.front()->borderWidth();

    int rounding_error = width() - ((maxWidthPerClient() + borderW)* m_item_list.size() - borderW);

    int next_x = -borderW; // zero so the border of the first shows
        int extra = 0;
    for (; it != it_end; ++it, next_x += max_width_per_client + borderW + extra) {
        if (rounding_error != 0) {
            --rounding_error;
            extra = 1;
        } else {
            extra = 0;
        }
        // resize each clients including border in size
        (*it)->moveResize(next_x,
                          -borderW,
                          max_width_per_client + extra,
                          height());
        (*it)->clear();
    }
}

unsigned int Container::maxWidthPerClient() const {
    int count = size();
    if (count == 0)
        return width();
    else {
        int borderW = m_item_list.front()->borderWidth();
        // there're count-1 borders to fit in with the windows
        // -> 1 per window plus end
        return (width() - (count - 1) * borderW) / count;
    }
}
<commit_msg>tmp fix for error in toolbar<commit_after>// Container.cc
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//                and Simon Bowden    (rathnor at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Container.cc,v 1.8 2003/12/07 15:45:28 fluxgen Exp $

#include "Container.hh"

#include "FbTk/Button.hh"
#include "FbTk/EventManager.hh"

Container::Container(const FbTk::FbWindow &parent):
    FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask), m_selected(0),
    m_update_lock(false) {
    FbTk::EventManager::instance()->add(*this, *this);
}

Container::~Container() {

}

void Container::resize(unsigned int width, unsigned int height) {
    // do we need to resize?
    if (FbTk::FbWindow::width() == width &&
        FbTk::FbWindow::height() == height)
        return;

    FbTk::FbWindow::resize(width, height);
    repositionItems();
}

void Container::moveResize(int x, int y,
                           unsigned int width, unsigned int height) {
    FbTk::FbWindow::moveResize(x, y, width, height);
    repositionItems();
}

void Container::insertItems(ItemList &item_list, int pos) {

    // make sure all items have parent == this
    ItemList::iterator it = m_item_list.begin();
    ItemList::iterator it_end = m_item_list.end();
    for (; it != it_end; ++it) {
        if ((*it)->parent() != this)
            return;
    }

    if (pos > size() || pos < 0) {
        // insert last
        m_item_list.splice(m_item_list.end(), item_list);
    } else if (pos == 0) {
        // insert first
        m_item_list.splice(m_item_list.begin(), item_list);
    } else {
        // find insert point
        for (it = m_item_list.begin(); pos != 0; ++it, --pos)
            continue;
        m_item_list.splice(it, item_list);
    }

    m_item_list.unique();

    // update position
    repositionItems();
}

void Container::insertItem(Item item, int pos) {
    if (find(item) != -1)
        return;

    // it must be a child of this window
    if (item->parent() != this)
        return;

    if (pos >= size() || pos < 0) {
        m_item_list.push_back(item);
    } else if (pos == 0) {
        m_item_list.push_front(item);
    } else {
        ItemList::iterator it = m_item_list.begin();
        for (; pos != 0; ++it, --pos)
            continue;

        m_item_list.insert(it, item);
    }

    // make sure we dont have duplicate items
    m_item_list.unique();

    repositionItems();
}

void Container::removeItem(int index) {
    if (index < 0 || index > size())
        return;

    ItemList::iterator it = m_item_list.begin();
    for (; index != 0; ++it, --index)
        continue;

    if (*it == selected())
        m_selected = 0;

    m_item_list.erase(it);

    repositionItems();
}

void Container::removeAll() {
    m_selected = 0;
    m_item_list.clear();
    if (!m_update_lock)
        clear();

}

int Container::find(Item item) {
    ItemList::iterator it = m_item_list.begin();
    ItemList::iterator it_end = m_item_list.end();
    int index = 0;
    for (; it != it_end; ++it, ++index) {
        if ((*it) == item)
            break;
    }

    if (it == it_end)
        return -1;

    return index;
}

void Container::setSelected(int pos) {
    if (pos < 0 || pos >= size())
        m_selected = 0;
    else {
        ItemList::iterator it = m_item_list.begin();
        for (; pos != 0; --pos, ++it)
            continue;
        m_selected = *it;
        if (m_selected)
            m_selected->clear();
    }

}

void Container::exposeEvent(XExposeEvent &event) {
    if (!m_update_lock)
        clearArea(event.x, event.y, event.width, event.height);
}

void Container::repositionItems() {
    if (size() == 0 || m_update_lock)
        return;

    //!! TODO vertical position

    const int max_width_per_client = maxWidthPerClient();

    ItemList::iterator it = m_item_list.begin();
    const ItemList::iterator it_end = m_item_list.end();
    int borderW = m_item_list.front()->borderWidth();

    int rounding_error = width() - ((maxWidthPerClient() + borderW)* m_item_list.size() - borderW);

    int next_x = -borderW; // zero so the border of the first shows
    int extra = 0;
    for (; it != it_end; ++it, next_x += max_width_per_client + borderW + extra) {
        //!! TODO: check this more carefully, seems like error doesn't work with even numbers
        /*
        if (rounding_error != 0) {
            --rounding_error;
            extra = 0;
        } else {
            extra = 0;
        }
        */
        // resize each clients including border in size
        (*it)->moveResize(next_x,
                          -borderW,
                          max_width_per_client + extra,
                          height());
        (*it)->clear();
    }
}

unsigned int Container::maxWidthPerClient() const {
    int count = size();
    if (count == 0)
        return width();
    else {
        int borderW = m_item_list.front()->borderWidth();
        // there're count-1 borders to fit in with the windows
        // -> 1 per window plus end
        return (width() - (count - 1) * borderW) / count;
    }
}
<|endoftext|>


<commit_before>/*The MIT License (MIT)

Copyright (c) 2015 k-brac

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include <string>
#include <vector>
#include <iostream>

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4251 )
#endif

#if __MACH__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#pragma clang diagnostic ignored "-Wweak-vtables"
#pragma clang diagnostic ignored "-Wextra-semi"
#pragma clang diagnostic ignored "-Wdocumentation"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
#define CPPUNIT_STD_NEED_ALLOCATOR 0
#endif

#include "cppunit/extensions/TestFactoryRegistry.h"
#include "cppunit/CompilerOutputter.h"
#include "cppunit/XmlOutputter.h"
#include "cppunit/TestResult.h"
#include "cppunit/TestResultCollector.h"
#include "cppunit/TestRunner.h"
#include "cppunit/BriefTestProgressListener.h"
#include "cppunit/plugin/PlugInManager.h"
#include <chrono>

class TimedBriefTestProgressListener : public CppUnit::BriefTestProgressListener {
private:
    std::chrono::time_point<std::chrono::high_resolution_clock> mTimer;
public:

    void startTest(CppUnit::Test *test)
    {
        CppUnit::BriefTestProgressListener::startTest(test);
        mTimer = std::chrono::high_resolution_clock::now();
    }

    void endTest(CppUnit::Test *test)
    {
        const std::chrono::duration<float, std::milli> elapsed = std::chrono::high_resolution_clock::now() - mTimer;
        CppUnit::stdCOut() << " (" << std::to_string(elapsed.count()) << " ms elapsed)";
        CppUnit::BriefTestProgressListener::endTest(test);
    }
};

#if __MACH__
#pragma clang diagnostic pop
#endif

#ifdef WIN32
#pragma warning( pop )
#endif

struct CommandLineParser {
    std::string xmlOutputFile;
    std::string plugName;
    std::vector<std::string> testPaths;

    void parseArgs(int argc, char* argv[]) {
        for (int i = 1; i < argc; i++) {
            std::string arg = argv[i];
            if (arg.size() >= 2 && arg.front() == '-') {
                auto it = arg.find("=");
                if (it != std::string::npos) {
                    auto key = arg.substr(0, it);
                    auto val = arg.substr(it + 1, arg.size());
                    if (val.empty()) {
                        continue;
                    }
                    if (key == "-x" || key == "--xml") {
                        xmlOutputFile = val;
                    }
                    else if (key == "-t" || key == "--test") {
                        testPaths.emplace_back(val);
                    }
                    else {
                        std::cerr << "Unknow arguments " << key << " with value : " << val << std::endl;
                    }
                }
            }
            else {
                plugName = arg;
            }
        }

    }
};

bool runPlugin(const CommandLineParser &arguments) {
	CppUnit::PlugInManager pluginManager;
	pluginManager.load(arguments.plugName);

	// Create the event manager and test controller
	CppUnit::TestResult controller;

	// Add a listener that collects test result
	CppUnit::TestResultCollector result;
	controller.addListener(&result);

	// Add a listener
    TimedBriefTestProgressListener progress;
	controller.addListener(&progress);

	pluginManager.addListener(&controller);

	// Add the top suite to the test runner
	CppUnit::TestRunner runner;
	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
	try
	{
		if (arguments.testPaths.empty()) {
			std::cout << "Running " << std::endl;
			runner.run(controller);
		}
		else {
			for (const auto & p : arguments.testPaths) {
				std::cout << "Running " << p << std::endl;
				runner.run(controller, p);
			}
		}
		std::cerr << std::endl;

		// Print test in a compiler compatible format.
		CppUnit::CompilerOutputter outputter(&result, std::cerr);
		outputter.write();

        if (!arguments.xmlOutputFile.empty()) {
            std::ofstream file(arguments.xmlOutputFile);
            CppUnit::XmlOutputter xOutputter(&result, file);
            xOutputter.write();
        }
	}
	catch (std::invalid_argument &e)  // Test path not resolved
	{
		std::cerr << std::endl
			<< "ERROR: " << e.what()
			<< std::endl;
		return false;
	}
	return result.wasSuccessful();
}

int main(int argc, char* argv[])
{
	std::cout << "usage : " << argv[0] << "{-x | -xml=file} {-t | --test=test_path} test_plugin_path" << std::endl << std::endl;
	if (argc < 2)
		return 1;

	bool result = false;
	try {
        CommandLineParser command;
        command.parseArgs(argc, argv);
		result = runPlugin(command);
	}
	catch (std::exception &e) {
		std::cerr << std::endl
			<< "ERROR: " << e.what()
			<< std::endl;

	}
	return result ? 0 : 1;
}
<commit_msg>force cout flush on windows<commit_after>/*The MIT License (MIT)

Copyright (c) 2015 k-brac

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include <string>
#include <vector>
#include <iostream>

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4251 )
#endif

#if __MACH__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#pragma clang diagnostic ignored "-Wweak-vtables"
#pragma clang diagnostic ignored "-Wextra-semi"
#pragma clang diagnostic ignored "-Wdocumentation"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
#define CPPUNIT_STD_NEED_ALLOCATOR 0
#endif

#include "cppunit/extensions/TestFactoryRegistry.h"
#include "cppunit/CompilerOutputter.h"
#include "cppunit/XmlOutputter.h"
#include "cppunit/TestResult.h"
#include "cppunit/TestResultCollector.h"
#include "cppunit/TestRunner.h"
#include "cppunit/BriefTestProgressListener.h"
#include "cppunit/plugin/PlugInManager.h"
#include <chrono>

class TimedBriefTestProgressListener : public CppUnit::BriefTestProgressListener {
private:
    std::chrono::time_point<std::chrono::high_resolution_clock> mTimer;
public:

    void startTest(CppUnit::Test *test)
    {
        CppUnit::BriefTestProgressListener::startTest(test);
        mTimer = std::chrono::high_resolution_clock::now();
    }

    void endTest(CppUnit::Test *test)
    {
        const std::chrono::duration<float, std::milli> elapsed = std::chrono::high_resolution_clock::now() - mTimer;
        CppUnit::stdCOut() << " (" << std::to_string(elapsed.count()) << " ms elapsed)";
#if defined(WIN32)
        CppUnit::stdCOut().flush();
#endif
        CppUnit::BriefTestProgressListener::endTest(test);
    }
};

#if __MACH__
#pragma clang diagnostic pop
#endif

#ifdef WIN32
#pragma warning( pop )
#endif

struct CommandLineParser {
    std::string xmlOutputFile;
    std::string plugName;
    std::vector<std::string> testPaths;

    void parseArgs(int argc, char* argv[]) {
        for (int i = 1; i < argc; i++) {
            std::string arg = argv[i];
            if (arg.size() >= 2 && arg.front() == '-') {
                auto it = arg.find("=");
                if (it != std::string::npos) {
                    auto key = arg.substr(0, it);
                    auto val = arg.substr(it + 1, arg.size());
                    if (val.empty()) {
                        continue;
                    }
                    if (key == "-x" || key == "--xml") {
                        xmlOutputFile = val;
                    }
                    else if (key == "-t" || key == "--test") {
                        testPaths.emplace_back(val);
                    }
                    else {
                        std::cerr << "Unknow arguments " << key << " with value : " << val << std::endl;
                    }
                }
            }
            else {
                plugName = arg;
            }
        }

    }
};

bool runPlugin(const CommandLineParser &arguments) {
	CppUnit::PlugInManager pluginManager;
	pluginManager.load(arguments.plugName);

	// Create the event manager and test controller
	CppUnit::TestResult controller;

	// Add a listener that collects test result
	CppUnit::TestResultCollector result;
	controller.addListener(&result);

	// Add a listener
    TimedBriefTestProgressListener progress;
	controller.addListener(&progress);

	pluginManager.addListener(&controller);

	// Add the top suite to the test runner
	CppUnit::TestRunner runner;
	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
	try
	{
		if (arguments.testPaths.empty()) {
			std::cout << "Running " << std::endl;
			runner.run(controller);
		}
		else {
			for (const auto & p : arguments.testPaths) {
				std::cout << "Running " << p << std::endl;
				runner.run(controller, p);
			}
		}
		std::cerr << std::endl;

		// Print test in a compiler compatible format.
		CppUnit::CompilerOutputter outputter(&result, std::cerr);
		outputter.write();

        if (!arguments.xmlOutputFile.empty()) {
            std::ofstream file(arguments.xmlOutputFile);
            CppUnit::XmlOutputter xOutputter(&result, file);
            xOutputter.write();
        }
	}
	catch (std::invalid_argument &e)  // Test path not resolved
	{
		std::cerr << std::endl
			<< "ERROR: " << e.what()
			<< std::endl;
		return false;
	}
	return result.wasSuccessful();
}

int main(int argc, char* argv[])
{
	std::cout << "usage : " << argv[0] << "{-x | -xml=file} {-t | --test=test_path} test_plugin_path" << std::endl << std::endl;
	if (argc < 2)
		return 1;

	bool result = false;
	try {
        CommandLineParser command;
        command.parseArgs(argc, argv);
		result = runPlugin(command);
	}
	catch (std::exception &e) {
		std::cerr << std::endl
			<< "ERROR: " << e.what()
			<< std::endl;

	}
	return result ? 0 : 1;
}
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////////
//
// BSD 3-Clause License
//
// Copyright (c) 2019, University of California, San Diego.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////

#include "AntennaRepair.h"

#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "Box.h"
#include "Coordinate.h"
#include "Pin.h"
#include "Net.h"
#include "fastroute/GlobalRouter.h"
#include "openroad/Error.hh"

namespace FastRoute {

using ord::error;

AntennaRepair::AntennaRepair(GlobalRouter *grouter,
                 antenna_checker::AntennaChecker* arc,
                 opendp::Opendp* opendp, odb::dbDatabase* db)
	: _grouter(grouter), _arc(arc), _opendp(opendp), _db(db)
	{
		_block = _db->getChip()->getBlock();
	}

int AntennaRepair::checkAntennaViolations(NetRouteMap& routing,
					  int maxRoutingLayer)
{
  std::vector<odb::dbNet*> dirtyNets;
  odb::dbTech* tech = _db->getTech();

  _arc->load_antenna_rules();

  std::map<int, odb::dbTechVia*> defaultVias = _grouter->getDefaultVias(maxRoutingLayer);

  for (auto net_route : routing) {
    odb::dbNet* db_net = net_route.first;
    GRoute &route = net_route.second;
    odb::dbWire* wire = odb::dbWire::create(db_net);
    odb::dbWireEncoder wireEncoder;
    wireEncoder.begin(wire);
    odb::dbWireType wireType = odb::dbWireType::ROUTED;

    for (FastRoute::GSegment &seg : route) {
      if (std::abs(seg.initLayer - seg.finalLayer) > 1) {
        error("Global route segment not valid\n");
      }
      int x1 = seg.initX;
      int y1 = seg.initY;
      int x2 = seg.finalX;
      int y2 = seg.finalY;
      int l1 = seg.initLayer;
      int l2 = seg.finalLayer;

      odb::dbTechLayer* currLayer = tech->findRoutingLayer(l1);

      if (l1 == l2) {  // Add wire
        if (x1 == x2 && y1 == y2)
          continue;
        wireEncoder.newPath(currLayer, wireType);
        wireEncoder.addPoint(x1, y1);
        wireEncoder.addPoint(x2, y2);
      } else {  // Add via
        int bottomLayer = (l1 < l2) ? l1 : l2;
        wireEncoder.newPath(currLayer, wireType);
        wireEncoder.addPoint(x1, y1);
        wireEncoder.addTechVia(defaultVias[bottomLayer]);
      }
    }
    wireEncoder.end();

    odb::orderWires(db_net, false, false);

    std::vector<VINFO> netViol = _arc->get_net_antenna_violations(db_net);
    if (netViol.size() > 0) {
      _antennaViolations[db_net] = netViol;
      dirtyNets.push_back(db_net);
    }
    if (wire != nullptr) {
      odb::dbWire::destroy(wire);
    }
  }

  _grouter->setDirtyNets(dirtyNets);

  std::cout << "[INFO] #Antenna violations: " << _antennaViolations.size()
            << "\n";
  return _antennaViolations.size();
}

void AntennaRepair::fixAntennas(std::string antennaCellName,
                            std::string antennaPinName)
{
  int siteWidth = -1;
  int cnt = 0;
  r_tree fixedInsts;
  getFixedInstances(fixedInsts);

  auto rows = _block->getRows();
  for (odb::dbRow* db_row : rows) {
    odb::dbSite* site = db_row->getSite();
    int site_width = site->getWidth();
    if (siteWidth == -1) {
      siteWidth = site_width;
    }

    if (siteWidth != site_width) {
      std::cout << "[WARNING] Design has rows with different site width\n";
    }
  }

  for (auto const& violation : _antennaViolations) {
    odb::dbNet* net = violation.first;
    for (int i = 0; i < violation.second.size(); i++) {
      for (odb::dbITerm* sinkITerm : violation.second[i].iterms) {
        odb::dbInst* sinkInst = sinkITerm->getInst();
        std::string antennaInstName = "ANTENNA_" + std::to_string(cnt);
        insertDiode(net,
                    antennaCellName,
                    antennaPinName,
                    sinkInst,
                    sinkITerm,
                    antennaInstName,
                    siteWidth,
                    fixedInsts);
        cnt++;
      }
    }
  }
}

void AntennaRepair::legalizePlacedCells()
{
  _opendp->detailedPlacement(0);
  _opendp->checkPlacement(false);
}

void AntennaRepair::insertDiode(odb::dbNet* net,
                            std::string antennaCellName,
                            std::string antennaPinName,
                            odb::dbInst* sinkInst,
                            odb::dbITerm* sinkITerm,
                            std::string antennaInstName,
                            int siteWidth,
                            r_tree& fixedInsts)
{
  bool legallyPlaced = false;
  bool placeAtLeft = true;
  int leftOffset = 0;
  int rightOffset = 0;
  int offset;

  std::string netName = net->getConstName();

  odb::dbMaster* antennaMaster = _db->findMaster(antennaCellName.c_str());
  odb::dbSet<odb::dbMTerm> antennaMTerms = antennaMaster->getMTerms();

  int instLocX, instLocY, instWidth;
  odb::dbBox* sinkBBox = sinkInst->getBBox();
  instLocX = sinkBBox->xMin();
  instLocY = sinkBBox->yMin();
  instWidth = sinkBBox->xMax() - sinkBBox->xMin();
  odb::dbOrientType instOrient = sinkInst->getOrient();

  odb::dbInst* antennaInst
      = odb::dbInst::create(_block, antennaMaster, antennaInstName.c_str());
  odb::dbITerm* antennaITerm = antennaInst->findITerm(antennaPinName.c_str());
  odb::dbBox* antennaBBox = antennaInst->getBBox();
  int antennaWidth = antennaBBox->xMax() - antennaBBox->xMin();

  // Use R-tree to check if diode will not overlap or cause 1-site spacing with
  // other cells
  std::vector<value> overlapInsts;
  while (!legallyPlaced) {
    if (placeAtLeft) {
      offset = -(antennaWidth + leftOffset * siteWidth);
      leftOffset++;
      placeAtLeft = false;
    } else {
      offset = instWidth + rightOffset * siteWidth;
      rightOffset++;
      placeAtLeft = true;
    }

    antennaInst->setOrient(instOrient);
    antennaInst->setLocation(instLocX + offset, instLocY);

    odb::dbBox* instBox = antennaInst->getBBox();
    box box(point(instBox->xMin() - (2 * siteWidth) + 1, instBox->yMin() + 1),
            point(instBox->xMax() + (2 * siteWidth) - 1, instBox->yMax() - 1));
    fixedInsts.query(bgi::intersects(box), std::back_inserter(overlapInsts));

    if (overlapInsts.empty()) {
      legallyPlaced = true;
    }
    overlapInsts.clear();
  }

  antennaInst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
  sinkInst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
  odb::dbITerm::connect(antennaITerm, net);

  // Add diode to the R-tree of fixed instances
  int fixedInstId = fixedInsts.size();
  odb::dbBox* instBox = antennaInst->getBBox();
  box b(point(instBox->xMin(), instBox->yMin()),
        point(instBox->xMax(), instBox->yMax()));
  value v(b, fixedInstId);
  fixedInsts.insert(v);
  fixedInstId++;
}

void AntennaRepair::getFixedInstances(r_tree& fixedInsts)
{
  odb::dbTech* tech = _db->getTech();

  int fixedInstId = 0;
  for (odb::dbInst* inst : _block->getInsts()) {
    if (inst->getPlacementStatus() == odb::dbPlacementStatus::FIRM) {
      odb::dbBox* instBox = inst->getBBox();
      box b(point(instBox->xMin(), instBox->yMin()),
            point(instBox->xMax(), instBox->yMax()));
      value v(b, fixedInstId);
      fixedInsts.insert(v);
      fixedInstId++;
    }
  }
}

}
<commit_msg>[FastRoute] Use empty instead of comparing with 0<commit_after>/////////////////////////////////////////////////////////////////////////////
//
// BSD 3-Clause License
//
// Copyright (c) 2019, University of California, San Diego.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////

#include "AntennaRepair.h"

#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "Box.h"
#include "Coordinate.h"
#include "Pin.h"
#include "Net.h"
#include "fastroute/GlobalRouter.h"
#include "openroad/Error.hh"

namespace FastRoute {

using ord::error;

AntennaRepair::AntennaRepair(GlobalRouter *grouter,
                 antenna_checker::AntennaChecker* arc,
                 opendp::Opendp* opendp, odb::dbDatabase* db)
	: _grouter(grouter), _arc(arc), _opendp(opendp), _db(db)
	{
		_block = _db->getChip()->getBlock();
	}

int AntennaRepair::checkAntennaViolations(NetRouteMap& routing,
					  int maxRoutingLayer)
{
  std::vector<odb::dbNet*> dirtyNets;
  odb::dbTech* tech = _db->getTech();

  _arc->load_antenna_rules();

  std::map<int, odb::dbTechVia*> defaultVias = _grouter->getDefaultVias(maxRoutingLayer);

  for (auto net_route : routing) {
    odb::dbNet* db_net = net_route.first;
    GRoute &route = net_route.second;
    odb::dbWire* wire = odb::dbWire::create(db_net);
    odb::dbWireEncoder wireEncoder;
    wireEncoder.begin(wire);
    odb::dbWireType wireType = odb::dbWireType::ROUTED;

    for (FastRoute::GSegment &seg : route) {
      if (std::abs(seg.initLayer - seg.finalLayer) > 1) {
        error("Global route segment not valid\n");
      }
      int x1 = seg.initX;
      int y1 = seg.initY;
      int x2 = seg.finalX;
      int y2 = seg.finalY;
      int l1 = seg.initLayer;
      int l2 = seg.finalLayer;

      odb::dbTechLayer* currLayer = tech->findRoutingLayer(l1);

      if (l1 == l2) {  // Add wire
        if (x1 == x2 && y1 == y2)
          continue;
        wireEncoder.newPath(currLayer, wireType);
        wireEncoder.addPoint(x1, y1);
        wireEncoder.addPoint(x2, y2);
      } else {  // Add via
        int bottomLayer = (l1 < l2) ? l1 : l2;
        wireEncoder.newPath(currLayer, wireType);
        wireEncoder.addPoint(x1, y1);
        wireEncoder.addTechVia(defaultVias[bottomLayer]);
      }
    }
    wireEncoder.end();

    odb::orderWires(db_net, false, false);

    std::vector<VINFO> netViol = _arc->get_net_antenna_violations(db_net);
    if (!netViol.empty()) {
      _antennaViolations[db_net] = netViol;
      dirtyNets.push_back(db_net);
    }
    if (wire != nullptr) {
      odb::dbWire::destroy(wire);
    }
  }

  _grouter->setDirtyNets(dirtyNets);

  std::cout << "[INFO] #Antenna violations: " << _antennaViolations.size()
            << "\n";
  return _antennaViolations.size();
}

void AntennaRepair::fixAntennas(std::string antennaCellName,
                            std::string antennaPinName)
{
  int siteWidth = -1;
  int cnt = 0;
  r_tree fixedInsts;
  getFixedInstances(fixedInsts);

  auto rows = _block->getRows();
  for (odb::dbRow* db_row : rows) {
    odb::dbSite* site = db_row->getSite();
    int site_width = site->getWidth();
    if (siteWidth == -1) {
      siteWidth = site_width;
    }

    if (siteWidth != site_width) {
      std::cout << "[WARNING] Design has rows with different site width\n";
    }
  }

  for (auto const& violation : _antennaViolations) {
    odb::dbNet* net = violation.first;
    for (int i = 0; i < violation.second.size(); i++) {
      for (odb::dbITerm* sinkITerm : violation.second[i].iterms) {
        odb::dbInst* sinkInst = sinkITerm->getInst();
        std::string antennaInstName = "ANTENNA_" + std::to_string(cnt);
        insertDiode(net,
                    antennaCellName,
                    antennaPinName,
                    sinkInst,
                    sinkITerm,
                    antennaInstName,
                    siteWidth,
                    fixedInsts);
        cnt++;
      }
    }
  }
}

void AntennaRepair::legalizePlacedCells()
{
  _opendp->detailedPlacement(0);
  _opendp->checkPlacement(false);
}

void AntennaRepair::insertDiode(odb::dbNet* net,
                            std::string antennaCellName,
                            std::string antennaPinName,
                            odb::dbInst* sinkInst,
                            odb::dbITerm* sinkITerm,
                            std::string antennaInstName,
                            int siteWidth,
                            r_tree& fixedInsts)
{
  bool legallyPlaced = false;
  bool placeAtLeft = true;
  int leftOffset = 0;
  int rightOffset = 0;
  int offset;

  std::string netName = net->getConstName();

  odb::dbMaster* antennaMaster = _db->findMaster(antennaCellName.c_str());
  odb::dbSet<odb::dbMTerm> antennaMTerms = antennaMaster->getMTerms();

  int instLocX, instLocY, instWidth;
  odb::dbBox* sinkBBox = sinkInst->getBBox();
  instLocX = sinkBBox->xMin();
  instLocY = sinkBBox->yMin();
  instWidth = sinkBBox->xMax() - sinkBBox->xMin();
  odb::dbOrientType instOrient = sinkInst->getOrient();

  odb::dbInst* antennaInst
      = odb::dbInst::create(_block, antennaMaster, antennaInstName.c_str());
  odb::dbITerm* antennaITerm = antennaInst->findITerm(antennaPinName.c_str());
  odb::dbBox* antennaBBox = antennaInst->getBBox();
  int antennaWidth = antennaBBox->xMax() - antennaBBox->xMin();

  // Use R-tree to check if diode will not overlap or cause 1-site spacing with
  // other cells
  std::vector<value> overlapInsts;
  while (!legallyPlaced) {
    if (placeAtLeft) {
      offset = -(antennaWidth + leftOffset * siteWidth);
      leftOffset++;
      placeAtLeft = false;
    } else {
      offset = instWidth + rightOffset * siteWidth;
      rightOffset++;
      placeAtLeft = true;
    }

    antennaInst->setOrient(instOrient);
    antennaInst->setLocation(instLocX + offset, instLocY);

    odb::dbBox* instBox = antennaInst->getBBox();
    box box(point(instBox->xMin() - (2 * siteWidth) + 1, instBox->yMin() + 1),
            point(instBox->xMax() + (2 * siteWidth) - 1, instBox->yMax() - 1));
    fixedInsts.query(bgi::intersects(box), std::back_inserter(overlapInsts));

    if (overlapInsts.empty()) {
      legallyPlaced = true;
    }
    overlapInsts.clear();
  }

  antennaInst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
  sinkInst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
  odb::dbITerm::connect(antennaITerm, net);

  // Add diode to the R-tree of fixed instances
  int fixedInstId = fixedInsts.size();
  odb::dbBox* instBox = antennaInst->getBBox();
  box b(point(instBox->xMin(), instBox->yMin()),
        point(instBox->xMax(), instBox->yMax()));
  value v(b, fixedInstId);
  fixedInsts.insert(v);
  fixedInstId++;
}

void AntennaRepair::getFixedInstances(r_tree& fixedInsts)
{
  odb::dbTech* tech = _db->getTech();

  int fixedInstId = 0;
  for (odb::dbInst* inst : _block->getInsts()) {
    if (inst->getPlacementStatus() == odb::dbPlacementStatus::FIRM) {
      odb::dbBox* instBox = inst->getBBox();
      box b(point(instBox->xMin(), instBox->yMin()),
            point(instBox->xMax(), instBox->yMax()));
      value v(b, fixedInstId);
      fixedInsts.insert(v);
      fixedInstId++;
    }
  }
}

}
<|endoftext|>