-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathlibrary_watcher.inc
131 lines (110 loc) · 3.44 KB
/
library_watcher.inc
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* A collection of functions to make tracking library availability slightly easier.
*
* If AUTO_LIBRARY_MANAGEMENT is defined, this include will add its own `OnLibraryAdded` and
* `OnLibraryRemoved` callbacks. If it is not, you'll have to call `TrackLibraryAdd` and
* `TrackLibraryRemove` yourself.
*
* The compiler will warn you that the symbols are never used, if you happen to forget.
*
* If TRACK_LIBRARY_STATES is defined, the `GetLibraryState` function and associated storage
* will be provided for library state retrieval. Otherwise, this include file only helps manage
* forwards for library availability.
*/
#if defined __stocksoup_library_watcher_included
#endinput
#endif
#define __stocksoup_library_watcher_included
enum LibraryState {
Library_Untracked = 0,
Library_Available,
Library_Unavailable
};
typedef LibraryStateCallback = function void(const char[] name, LibraryState state);
/**
* Begins tracking a library. Can be called during `OnPluginStart`.
*/
stock void HookLibraryUpdate(const char[] name, LibraryStateCallback callback) {
Handle localForward;
if (!GetLibraryWatchList().GetValue(name, localForward)) {
localForward = CreateForward(ET_Ignore, Param_String, Param_Cell);
GetLibraryWatchList().SetValue(name, localForward);
}
AddToForward(localForward, INVALID_HANDLE, callback);
}
/**
* Stops tracking a library.
*/
stock void UnhookLibraryUpdate(const char[] name, LibraryStateCallback callback) {
Handle localForward;
if (GetLibraryWatchList().GetValue(name, localForward)) {
RemoveFromForward(localForward, INVALID_HANDLE, callback);
if (GetForwardFunctionCount(localForward) == 0) {
delete localForward;
GetLibraryWatchList().Remove(name);
}
}
#if defined TRACK_LIBRARY_STATES
GetLibraryStates().DeleteKey(name);
#endif
}
static void UpdateLibraryState(const char[] name, LibraryState state) {
Handle localForward;
if (GetLibraryWatchList().GetValue(name, localForward)) {
#if defined TRACK_LIBRARY_STATES
LibraryState previousState = GetLibraryState(name);
GetLibraryStates().SetNum(name, view_as<int>(state));
#else
LibraryState previousState = Library_Untracked;
#endif
if (previousState == Library_Untracked || previousState != state) {
Call_StartForward(localForward);
Call_PushString(name);
Call_PushCell(state);
Call_Finish();
}
}
}
static stock StringMap GetLibraryWatchList() {
static StringMap s_LibraryInfo;
if (!s_LibraryInfo) {
s_LibraryInfo = new StringMap();
}
return s_LibraryInfo;
}
#if defined TRACK_LIBRARY_STATES
/**
* Returns the current library availability.
*/
stock LibraryState GetLibraryState(const char[] name) {
return view_as<LibraryState>(GetLibraryStates().GetNum(name));
}
static stock KeyValues GetLibraryStates() {
static KeyValues s_LibraryState;
if (!s_LibraryState) {
s_LibraryState = new KeyValues("library-state");
}
return s_LibraryState;
}
#endif
/**
* Functions that must be called when a library is added.
* If AUTO_LIBRARY_MANAGEMENT isn't defined, you'll have to call these functions yourself.
*/
void TrackLibraryAdd(const char[] name) {
UpdateLibraryState(name, Library_Available);
}
void TrackLibraryRemove(const char[] name) {
UpdateLibraryState(name, Library_Unavailable);
}
/**
* Automatic library tracking.
*/
#if defined AUTO_LIBRARY_MANAGEMENT
public void OnLibraryAdded(const char[] name) {
TrackLibraryAdd(name);
}
public void OnLibraryRemoved(const char[] name) {
TrackLibraryRemove(name);
}
#endif