/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2022, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */
#pragma once

#include <atomic>
#include <mutex>
#include <queue>

namespace mrpt::rtti
{
using TRegisterFunction = void (*)();  // A void(void) function

struct queue_register_functions_t
{
	std::queue<TRegisterFunction> funcs;
	mutable std::mutex funcs_cs;

	/** Retrieve the next message in the queue, or nullptr if there is no
	 * message. The user MUST call "delete" with the returned object after use.
	 */
	inline bool get(TRegisterFunction& ret)
	{
		std::lock_guard<std::mutex> lock(funcs_cs);
		if (funcs.empty()) return false;
		else
		{
			ret = funcs.front();
			funcs.pop();
			return true;
		}
	}
};

// Use a queue for the pending register issues, but also an atomic counter,
// which is much faster to check than a CS.
std::atomic<int>& pending_class_registers_count();
queue_register_functions_t& pending_class_registers();
/** Set to true if pending_class_registers() has been called after
 * registerAllPendingClasses(). Startup value is false. */
extern bool pending_class_registers_modified;

}  // namespace mrpt::rtti
