#pragma once

/**
 * \file PacketVisitor.h
 * \brief File containing the blitz::protocol::PacketVisitor class
 */

#include <blitz/protocol/Packets.h>

namespace blitz {
namespace protocol {

#define DeclarePacket(PacketName, ...)                                                                                                \
	/** This function is called when the packet processed by PacketVisitor::Check is a PacketName */                                                                                                                            \
	virtual void Visit(const packets::PacketName&) {}

/**
 * \class PacketVisitor
 * \brief This class uses double-dispatch in order to find the real type of a packet
 */
class PacketVisitor : private NonCopyable {
  protected:
	PacketVisitor() {}
	virtual ~PacketVisitor() {}

  public:
	/**
	 * \brief Calls the right PacketVisitor::Visit method corresponding to the real type of the packet
	 * \param packet the Packet to visit
	 */
	void Check(const Packet& packet);

	DeclareAllPacket()
};

#undef DeclarePacket

}  // namespace protocol
}  // namespace blitz
