#pragma once

#include "socket.h"
#include "memblock.h"

class Slot;

#define SLOTLINK_MEMORYBLOCK_ALLOCATION (100)

class SlotLink : public Link
{
	friend class Slot;

public:
	~SlotLink();
	Logical TestInstance() const;

private:
	SlotLink(Slot *slot, Plug *plug);

private:
	static MemoryBlock* GetAllocatedMemory();

	void* operator new(size_t)			{ return GetAllocatedMemory()->New(); }
	void operator delete(void *where)	{ return GetAllocatedMemory()->Delete(where); }
};

class Slot : public Socket
{
	friend class SlotLink;

public:
	Slot(Node *node);
	~Slot();

	Logical TestInstance() const;

	void Remove();

protected:
	void AddImplementation(Plug *plug);
	Plug* GetCurrentPlug() const;

private:
	SlotLink *slotLink;
};

template <class T> class SlotOf : public Slot
{
public:
	SlotOf(Node *node);
	~SlotOf();

	void Add(T plug)	{ AddImplementation(Cast_Object(Plug*, plug)); }

	T GetCurrent() const	{ return (T)GetCurrentPlug(); }
};

template <class T> SlotOf<T>::SlotOf(Node *node) : Slot(node)
{
}

template <class T> SlotOf<T>::~SlotOf()
{
}