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