-
Notifications
You must be signed in to change notification settings - Fork 3
/
emitter.bash
executable file
·205 lines (160 loc) · 5.26 KB
/
emitter.bash
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#!/usr/bin/env bash
declare -A Stack
declare -i _MAXLISTENER_=11
event() {
local subcomm=$1
case $subcomm in
attach)
# total number of arguement must be exactly 3
[[ ! ${#@} -eq 3 ]] && {
throw error "Invalid Number of Arguments to $subcomm"
}
# if subcomm is attach assign the second variable as the type of the event
# assign the third variable as the callback to fire
local typeofEvent=$2
local messageCallback=$3
# checking if truy messageCallback is a function
declare -F ${messageCallback} >/dev/null
# if messageCallback is not a function return from this function
[[ $? -gt 0 ]] && {
throw error "${messageCallback} is not defined"
return 1;
}
{
[[ ${#Stack[@]} -eq ${_MAXLISTENER_} ]] || [[ ${#Stack[@]} -gt ${_MAXLISTENER_} ]]
} && {
throw error "Number of listeners exceeded, use setMaxlisteners subcommand to increment the amount of listeners"
}
# assigining the event type as a key to the global Array Stack and messageCallback as it's value
Stack[$typeofEvent]=${messageCallback}
;;
emit)
# total number of argument must not be less than 2
[[ ${#@} -lt 2 ]] && {
throw error "Invalid Number of Arguments to $subcomm"
}
# assign the second variable as the type of event
# argsToCallback contains args to be passed to the function messageCallback inside the attach case
# the args should be passed like this
# "firstarg secondarg 'third arg'" <<< use ' ' if the argument contains space or tabs
# the last two argument to the messageCallback function is the typeofEvent fired and the messageCallback function itself
local typeofEvent=$2
local argsToCallback=$3
read -a argsToCallback <<<${argsToCallback}
argsToCallback[$(( ${#argsToCallback[@]} + 1 ))]=${typeofEvent}
shift 2
# if there is not listener in the stack, throw an error
[[ ${#Stack[@]} -eq 0 ]] && {
throw error "There is no listener in the stack to emit"
}
for stacks in "${!Stack[@]}";do
[[ "$stacks" == "$typeofEvent" ]] && {
argsToCallback[$(( ${#argsToCallback[@]} + 1 ))]=${Stack[$stacks]}
eval ${Stack[$stacks]} "${argsToCallback[*]}"
break
}
done
[[ $? -gt 0 ]] && {
throw error "cannot emit ${typeofEvent} because it has not been registerd as a listener"
}
;;
detach)
# Deatch ( remove ) the event type from the Stack
local typeofEvent=$2
[[ ! ${#@} -eq 2 ]] && {
throw error "Invalid Number of Arguments to $subcomm"
}
for stacks in "${!Stack[@]}";do
[[ "$stacks" == "$typeofEvent" ]] && {
unset Stack[$stacks]
break
}
done
[[ $? -gt 0 ]] && {
throw error "cannot detach ${typeofEvent} because it has not been registerd as a listener"
}
;;
once)
# total number of argument must not be less than 2
[[ ${#@} -lt 2 ]] && {
throw error "Invalid Number of Arguments to $subcomm"
}
local typeofEvent=$2
local argsToCallback=$3
read -a argsToCallback <<<${argsToCallback}
argsToCallback[$(( ${#argsToCallback[@]} + 1 ))]=${typeofEvent}
shift 2
# if there is not listener in the stack, throw an error
[[ ${#Stack[@]} -eq 0 ]] && {
throw error "There is no listener in the stack to emit"
}
for stacks in "${!Stack[@]}";do
[[ "$stacks" == "$typeofEvent" ]] && {
argsToCallback[$(( ${#argsToCallback[@]} + 1 ))]=${Stack[$stacks]}
eval ${Stack[$stacks]} "${argsToCallback[*]}"
unset Stack[$stacks];
break
}
done
[[ $? -gt 0 ]] && {
throw error "cannot emit ${typeofEvent} because it has not been registerd as a listener"
}
;;
list)
[[ ${#Stack[@]} -eq 0 ]] && {
throw error "There is no listener in the stack"
}
for stacks in "${!Stack[@]}";do
printf "%s\n" "${stacks}"
done
;;
removeAll)
unset Stack
;;
setMaxListener)
[[ ! ${#@} -eq 2 ]] && {
throw error "$subcomm requires only one argument"
}
local num=${2}
[[ ! ${num} =~ ^[[:digit:]]{1,}$ ]] && {
throw error "the argument to $subcomm must be an integer"
}
_MAXLISTENER_=${num}
;;
*)
throw error "\" $subcomm \" is not a valid subcommand"
;;
esac
}
throw() {
local subComm="${1}"
local message="${2}"
local open="\e["
local close="\e[0m"
local bold="1;"
local light="0;"
local red="31m"
local yellow="33m"
case $subComm in
error)
[[ -z ${message} ]] && {
#${FUNCNAME[$(( ${#FUNCNAME[@]} - $(( ${#FUNCNAME[@]} - 2 )) ))]} ,
# to get the calling function, when you do a - 1 it gives
# the source builtin command as the calling function,
# so we have to minus by 2
message="An Error has occured in ${FUNCNAME[$(( ${#FUNCNAME[@]} - 2))]}"
}
printf "${open}${bold}${red}%s${close}\n" "${message}"
;;
warning)
[[ -z ${message} ]] && {
message="An Error has occured in ${FUNCNAME[$(( ${#FUNCNAME[@]} - 2))]}"
}
printf "${open}${bold}${yellow}%s${close}\n" "${message}"
;;
*)
${FUNCNAME} error "Invalid Arugment was passed to ${FUNCNAME}"
;;
esac
exit 1;
}