xref: /haiku/src/add-ons/kernel/file_systems/packagefs/nodes/NodeListener.h (revision 9f81ca838ce7b92b5689e57d3f86765db4705a7b)
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 
17 class Node;
18 
19 
20 #define NOT_LISTENING_NODE	((Node*)~(addr_t)0)
21 
22 
23 class OldNodeAttributes {
24 public:
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 
34 class NodeListener {
35 public:
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 
StartedListening(Node * node)44 			void				StartedListening(Node* node)
45 									{ fNode = node; }
StoppedListening()46 			void				StoppedListening()
47 									{ fNode = NOT_LISTENING_NODE; }
IsListening()48 			bool				IsListening() const
49 									{ return fNode != NOT_LISTENING_NODE; }
ListenedNode()50 			Node*				ListenedNode() const
51 									{ return fNode; }
52 
53 	inline	void				AddNodeListener(NodeListener* listener);
54 	inline	NodeListener*		RemoveNodeListener();
55 
PreviousNodeListener()56 			NodeListener*		PreviousNodeListener() const
57 									{ return fPrevious; }
NextNodeListener()58 			NodeListener*		NextNodeListener() const
59 									{ return fNext; }
60 
NodeListenerHashLink()61 			NodeListener*&		NodeListenerHashLink()
62 									{ return fHashLink; }
63 
64 private:
65 			NodeListener*		fHashLink;
66 			NodeListener*		fPrevious;
67 			NodeListener*		fNext;
68 			Node*				fNode;
69 };
70 
71 
72 inline void
AddNodeListener(NodeListener * listener)73 NodeListener::AddNodeListener(NodeListener* listener)
74 {
75 	listener->fPrevious = this;
76 	listener->fNext = fNext;
77 
78 	fNext->fPrevious = listener;
79 	fNext = listener;
80 }
81 
82 
83 inline NodeListener*
RemoveNodeListener()84 NodeListener::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 
101 struct NodeListenerHashDefinition {
102 	typedef Node*			KeyType;
103 	typedef	NodeListener	ValueType;
104 
HashKeyNodeListenerHashDefinition105 	size_t HashKey(Node* key) const
106 	{
107 		return (size_t)key;
108 	}
109 
HashNodeListenerHashDefinition110 	size_t Hash(const NodeListener* value) const
111 	{
112 		return HashKey(value->ListenedNode());
113 	}
114 
CompareNodeListenerHashDefinition115 	bool Compare(Node* key, const NodeListener* value) const
116 	{
117 		return key == value->ListenedNode();
118 	}
119 
GetLinkNodeListenerHashDefinition120 	NodeListener*& GetLink(NodeListener* value) const
121 	{
122 		return value->NodeListenerHashLink();
123 	}
124 };
125 
126 
127 typedef DoublyLinkedList<NodeListener> NodeListenerList;
128 typedef BOpenHashTable<NodeListenerHashDefinition> NodeListenerHashTable;
129 
130 
131 #endif	// NODE_LISTENER_H
132