Skip to content

Commit 930e3b3

Browse files
Implemented callback chain
1 parent 22d2bc6 commit 930e3b3

File tree

3 files changed

+92
-36
lines changed

3 files changed

+92
-36
lines changed

scripts/GameClient/GameClient.gml

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,48 @@ function GameClient(_ip, _port) : TCPSocket(_ip, _port) constructor {
77
sendPing = function() {
88
// Wait 1 second to send ping
99
call = call_later(1, time_source_units_seconds, function() {
10-
rpc.sendRequest("ping", current_time, function(_result) {
11-
var _ping = current_time - _result;
12-
ping = _ping;
13-
show_debug_message($"{_ping} ms");
14-
sendPing();
15-
}, function(_error) {
16-
show_debug_message($"Error {_error.code}: {_error.message}");
17-
sendPing();
18-
});
10+
rpc.sendRequest("ping", current_time)
11+
.onCallback(function(_result) {
12+
var _ping = current_time - _result;
13+
ping = _ping;
14+
show_debug_message($"{_ping} ms");
15+
})
16+
.onError(function(_error) {
17+
show_debug_message($"Error {_error.code}: {_error.message}");
18+
})
19+
.onFinally(function() {
20+
sendPing();
21+
});
1922
});
2023
}
2124
setEvent("connected", function() {
2225
// Send request to set name
23-
rpc.sendRequest("set_name", "Test", function(_result) {
24-
show_debug_message("Changed name!");
25-
}, function(_error) {
26-
show_debug_message($"Error {_error.code}: {_error.message}");
27-
});
26+
rpc.sendRequest("set_name", "Test")
27+
.onCallback(function(_result) {
28+
show_debug_message("Changed name!");
29+
})
30+
.onError(function(_error) {
31+
show_debug_message($"Error {_error.code}: {_error.message}");
32+
});
2833
// Send request to get name list
29-
rpc.sendRequest("get_name_list", [], function(_result) {
30-
show_debug_message(_result);
31-
});
34+
rpc.sendRequest("get_name_list", [])
35+
.onCallback(function(_result) {
36+
show_debug_message(_result);
37+
});
38+
// Example with chaining callbacks
39+
rpc.sendRequest("sum", [1, 2])
40+
.onCallback(function(_result) {
41+
return rpc.sendRequest("sum", [_result, 3])
42+
})
43+
.onCallback(function(_result) {
44+
return rpc.sendRequest("sum", [_result, 4])
45+
})
46+
.onCallback(function(_result) {
47+
show_debug_message(_result); // 1 + 2 + 3 + 4 = 10
48+
})
49+
.onError(function(_error) {
50+
show_debug_message(_error.message);
51+
});
3252
sendPing();
3353
});
3454
static step = function() {

scripts/GameServer/GameServer.gml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ function GameServer(_port) : TCPServer(_port) constructor {
66
rpc.registerHandler("ping", function(_params, _socket) {
77
return _params;
88
});
9+
rpc.registerHandler("sum", function(_params, _socket) {
10+
var _sum = _params[0] + _params[1];
11+
if (_sum > 10) throw "Sum error";
12+
return _sum;
13+
});
914
rpc.registerHandler("create_ball", function(_position, _socket) {
1015
ballPosition = _position;
1116
rpc.sendNotification("create_ball", ballPosition, sockets);

scripts/RPC/RPC.gml

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ function RPC(_socket) constructor {
2828
///
2929
/// @param {String} method - Name of the method to be invoked.
3030
/// @param {Struct|Array} params - Parameters to be used in the request.
31-
/// @param {Function} callback - Function to execute when the result is received successfully.
32-
/// @param {Function} errback - Function to execute when an error occurs.
3331
/// @param {Function} socket - Socket to which the request will be sent.
3432
/// @param {Real} timeout - Time, in seconds, to wait for the request result before timing out.
35-
static sendRequest = function(_method, _params, _callback, _errback, _socket = socket, _timeout = timeout) {
33+
static sendRequest = function(_method, _params, _socket = socket, _timeout = timeout) {
3634
var _id = generateID();
3735
sendJSON({
3836
"method": _method,
3937
"params": _params,
4038
"id": _id
4139
}, _socket);
42-
requests.setElement(_id, new RPCRequest(_id, _callback, _errback, _timeout, self));
40+
var _request = new RPCRequest(_id, _timeout, self);
41+
requests.setElement(_id, _request);
42+
return _request;
4343
}
4444
static sendNotification = function(_method, _params, _socket = socket) {
4545
sendJSON({
@@ -109,10 +109,7 @@ function RPC(_socket) constructor {
109109
var _id = _data.id;
110110
if (requests.hasElement(_id)) {
111111
var _request = requests.getElement(_id);
112-
var _call = _request.callback;
113-
if (is_method(_call)) {
114-
_call(_data.result);
115-
}
112+
var _callback_result = _request.runCallback(_data.result);
116113
_request.cancel();
117114
requests.removeElement(_id);
118115
} else {
@@ -126,10 +123,7 @@ function RPC(_socket) constructor {
126123
var _id = _data.id;
127124
if (requests.hasElement(_id)) {
128125
var _request = requests.getElement(_id);
129-
var _call = _request.errback;
130-
if (is_method(_call)) {
131-
_call(_error);
132-
}
126+
_request.runErrback(_error);
133127
_request.cancel();
134128
requests.removeElement(_id);
135129
}
@@ -143,22 +137,59 @@ function RPC(_socket) constructor {
143137
return increment;
144138
}
145139
}
146-
function RPCRequest(_id, _callback, _errback, _timeout, _parent) constructor {
140+
function RPCRequest(_id, _timeout, _parent) constructor {
147141
self.requestID = _id;
148142
self.parent = _parent;
149-
self.callback = _callback;
150-
self.errback = _errback;
143+
self.callbacks = [];
144+
self.errback = undefined;
145+
self.finallyMethod = undefined;
146+
static onCallback = function(_callback) {
147+
array_push(self.callbacks, _callback);
148+
return self;
149+
}
150+
static onError = function(_errback) {
151+
self.errback = _errback;
152+
return self;
153+
}
154+
static onFinally = function(_finally) {
155+
self.finallyMethod = _finally;
156+
return self;
157+
}
158+
static runCallback = function(_params) {
159+
if (array_length(self.callbacks) > 0) {
160+
var _callback = self.callbacks[0];
161+
if (is_method(_callback)) {
162+
var _callback_result = _callback(_params);
163+
if (is_struct(_callback_result) && is_instanceof(_callback_result, RPCRequest)) {
164+
array_delete(callbacks, 0, 1);
165+
_callback_result.callbacks = callbacks;
166+
_callback_result.onError(errback);
167+
_callback_result.onFinally(finallyMethod);
168+
return;
169+
}
170+
}
171+
}
172+
runFinally();
173+
}
174+
static runErrback = function(_error) {
175+
if (is_method(self.errback)) {
176+
self.errback(_error);
177+
}
178+
self.runFinally();
179+
}
180+
static runFinally = function() {
181+
if (!is_method(finallyMethod)) return;
182+
self.finallyMethod();
183+
}
151184
self.call = call_later(_timeout, time_source_units_seconds, function() {
152185
var _requests = parent.requests;
153186
if (!_requests.hasElement(requestID)) return;
154-
var _call = _requests.getElement(requestID).errback;
187+
var _request = _requests.getElement(requestID);
155188
var _error = {
156189
code: -32603,
157190
message: "Timeout error"
158191
};
159-
if (is_method(_call)) {
160-
_call(_error);
161-
}
192+
_request.runErrback(_error);
162193
_requests.removeElement(requestID);
163194
});
164195
static cancel = function() {

0 commit comments

Comments
 (0)