1/*
2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef NODE_LISTENER_H
6#define NODE_LISTENER_H
7
8
9#include <time.h>
10
11#include <util/DoublyLinkedList.h>
12#include <util/OpenHashTable.h>
13
14#include "StringKey.h"
15
16
17class Node;
18
19
20#define NOT_LISTENING_NODE	((Node*)~(addr_t)0)
21
22
23class OldNodeAttributes {
24public:
25	virtual						~OldNodeAttributes();
26
27	virtual	timespec			ModifiedTime() const = 0;
28	virtual	off_t				FileSize() const = 0;
29	virtual	void*				IndexCookieForAttribute(const StringKey& name)
30									const;
31};
32
33
34class NodeListener {
35public:
36								NodeListener();
37	virtual						~NodeListener();
38
39	virtual	void				NodeAdded(Node* node);
40	virtual	void				NodeRemoved(Node* node);
41	virtual	void				NodeChanged(Node* node, uint32 statFields,
42									const OldNodeAttributes& oldAttributes);
43
44			void				StartedListening(Node* node)
45									{ fNode = node; }
46			void				StoppedListening()
47									{ fNode = NOT_LISTENING_NODE; }
48			bool				IsListening() const
49									{ return fNode != NOT_LISTENING_NODE; }
50			Node*				ListenedNode() const
51									{ return fNode; }
52
53	inline	void				AddNodeListener(NodeListener* listener);
54	inline	NodeListener*		RemoveNodeListener();
55
56			NodeListener*		PreviousNodeListener() const
57									{ return fPrevious; }
58			NodeListener*		NextNodeListener() const
59									{ return fNext; }
60
61			NodeListener*&		NodeListenerHashLink()
62									{ return fHashLink; }
63
64private:
65			NodeListener*		fHashLink;
66			NodeListener*		fPrevious;
67			NodeListener*		fNext;
68			Node*				fNode;
69};
70
71
72inline void
73NodeListener::AddNodeListener(NodeListener* listener)
74{
75	listener->fPrevious = this;
76	listener->fNext = fNext;
77
78	fNext->fPrevious = listener;
79	fNext = listener;
80}
81
82
83inline NodeListener*
84NodeListener::RemoveNodeListener()
85{
86	if (fNext == this)
87		return NULL;
88
89	NodeListener* next = fNext;
90
91	fPrevious->fNext = next;
92	next->fPrevious = fPrevious;
93
94	fPrevious = fNext = this;
95
96	return next;
97}
98
99
100
101struct NodeListenerHashDefinition {
102	typedef Node*			KeyType;
103	typedef	NodeListener	ValueType;
104
105	size_t HashKey(Node* key) const
106	{
107		return (size_t)key;
108	}
109
110	size_t Hash(const NodeListener* value) const
111	{
112		return HashKey(value->ListenedNode());
113	}
114
115	bool Compare(Node* key, const NodeListener* value) const
116	{
117		return key == value->ListenedNode();
118	}
119
120	NodeListener*& GetLink(NodeListener* value) const
121	{
122		return value->NodeListenerHashLink();
123	}
124};
125
126
127typedef DoublyLinkedList<NodeListener> NodeListenerList;
128typedef BOpenHashTable<NodeListenerHashDefinition> NodeListenerHashTable;
129
130
131#endif	// NODE_LISTENER_H
132