summaryrefslogtreecommitdiff
path: root/Runtime/Misc/UserList.h
blob: 7999ba9cc456840cceea0fede02e35b1d5e3b37f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#pragma once

#include "Runtime/Utilities/dynamic_array.h"
#include "Runtime/Utilities/NonCopyable.h"
#include "Runtime/Modules/ExportModules.h"

class MessageIdentifier;

// A UserList can be connected to other UserLists or UserListNodes.
// A UserListNode is simply the optimized case of a single-element list.
// The connected lists are symmetrical and can send messages in both directions.
// Deleting a node or list will disconnect it from the graph.

class EXPORT_COREMODULE UserListBase : public NonCopyable
{
public:
	Object* GetTarget () { return m_Target; }

protected:
	UserListBase (Object* target) : m_Target(target) {}
	struct Entry
	{
		Entry() : other(NULL), indexInOther(-1) {}
		UserListBase* other;
		int indexInOther;
	};	
	Object* m_Target;
};

class UserListNode : public UserListBase
{
public:
	UserListNode (Object* target) : UserListBase(target) {}
	~UserListNode () { Clear(); }

	void Clear ();
	bool IsConnected () const { return m_Entry.other != NULL; }

private:
	friend class UserList;
	Entry m_Entry;
};

class EXPORT_COREMODULE UserList : public UserListBase
{
public:
	UserList (Object* target) : UserListBase(target) {}
	~UserList () { Clear(); }
	
	void Clear ();
	void Reserve (size_t size);
	void AddUser (UserListNode& other);
	void AddUser (UserList& other);
	void SendMessage (const MessageIdentifier& msg);
	size_t GetSize () const { return m_Entries.size(); }

private:
	friend class UserListNode;
	Entry& GetEntryInOther (int index);
	void RemoveIndex (int index);

	dynamic_array<Entry> m_Entries;
};