11extends RefCounted
22class_name PaimaMiddleware
33
4- ## Wrapper for core of Paima middleware.
4+ ## Wrapper for the core of Paima middleware.
55##
6- ## Provides API for logging-in and querying `RoundExecutor`.
7- ## All calls wrap JS object with Paima middleware. Handling of JS Promises is done
8- ## via signals and `await`s.
9-
6+ ## Provides an API for logging-in and querying the `RoundExecutor`.[br][br]
7+ ##
8+ ## This API deals mostly with objects from the Paima middleware, and hence uses
9+ ## [JavaScriptObject]s for many different things. Most importantly, the API is
10+ ## initialized with the [code]paima_endpoints[/code] object.[br][br]
11+ ##
12+ ## Most methods exposed in this API are asynchronous. As such, they can be [code]await[/code]ed
13+ ## or a callback can be bound to their respective signals.[br][br]
14+ ##
15+ ## [b]How to obtain [code]paima_endpoints[/code][/b][br][br]
16+ ##
17+ ## This object is provided by the Paima middleware ([code]paimaMiddleware.js[/code]), and in Javascript
18+ ## it can be easily brought into scope with an import statement:[br][br]
19+ ##
20+ ## [code]import endpoints from './paima/paimaMiddleware.js'[/code][br][br]
21+ ##
22+ ## Unfortunately, in GDScript it is not as easy. Import statements are not available,
23+ ## so only global objects may be accessed, such as [code]window[/code].[br][br]
24+ ##
25+ ## Hence, the main way of obtaining [code]paima_endpoints[/code] is by attaching it
26+ ## to the global [code]window[/code] object when the web page is loaded. In order
27+ ## to do this, the web export template for the project must be modified accordingly:[br][br]
28+ ##
29+ ## [code][preset.0.options][/code][br]
30+ ## [code]...[/code][br]
31+ ## [code]html/head_include="<script type=\"module\">[/code][br]
32+ ## [code]import endpoints from './paima/paimaMiddleware.js';[/code][br]
33+ ## [code]window.paima_endpoints = endpoints;[/code][br][br]
34+ ##
35+ ## In GDScript, the [code]window[/code] (and thus [code]paima_endpoints[/code])
36+ ## can be easily retrieved (check [method _init] docs).[br][br]
37+ ##
38+ ## [b]How to use the class[/b][br][br]
39+ ##
40+ ## The core methods available in [code]paima_endpoints[/code] are game-independent
41+ ## and may be used directly from [PaimaMiddleware] without calling directly into
42+ ## Javascript code (e.g: [method login], [method queryRoundExecutor]).[br][br]
43+ ##
44+ ## However, for method that are specific to a given game, the [code]paima_endpoints[/code]
45+ ## object must be used directly and calls into Javascript are necessary. To retrieve
46+ ## the endpoints object, use [method get_endpoints]. Consult this method's documentation
47+ ## to learn how to call into Javascript from GDScript.
48+
49+ ## Wallet mode
50+ ##
51+ ## The kind of wallet to be used when logging into Paima.
1052enum WalletMode {
1153 EVM_INJECTED = 0 ,
1254 EVM_ETHERS = 1 ,
@@ -16,53 +58,82 @@ enum WalletMode {
1658 ALGORAND = 5
1759 }
1860
61+ ## Login information
62+ ##
63+ ## Used in [method PaimaMiddleware.login]
1964class LoginInfo :
2065 var _wallet_name : String
21- var _mode : int
66+ var _mode : WalletMode
2267 var _prefer_batcher : bool
2368
24- ## For Cardano wallets `prefer_batcher` should be set to `true`
25- ## as they can work only through Paima barcher
69+ ## Create [PaimaMiddleware.LoginInfo] by providing a [param wallet_name], a [param mode] and a
70+ ## [param prefer_batcher_flag].[br][br]
71+ ## For Cardano wallets, [param prefer_batcher] should always be set
72+ ## to [code]true[/code], as they can only work through the Paima batcher.
2673 func _init (
2774 wallet_name : String ,
28- mode : int ,
75+ mode : WalletMode ,
2976 prefer_batcher : bool
3077 ) -> void :
3178 _wallet_name = wallet_name
32- _mode = mode
79+ _mode = mode
3380 _prefer_batcher = prefer_batcher
3481
3582var _endpoints : JavaScriptObject
3683var _paima_wallet : JavaScriptObject
3784
38- var console = JavaScriptBridge .get_interface ("console" )
85+ ## The browser console, provided here for convenience
86+ var console := JavaScriptBridge .get_interface ("console" )
3987
88+ ## A [PaimaMiddleware] is initialized by providing an [param endpoints]
89+ ## object, which is normally made available under the [code]window[/code] object[br][br]
90+ ## [code]var endpoints = JavaScriptBridge.get_interface("window").paima_endpoints[/code][br]
91+ ## [code]var middleware = PaimaMiddleware(endpoints)
4092func _init (endpoints : JavaScriptObject ) -> void :
4193 _endpoints = endpoints
4294 assert (_endpoints )
4395
96+ ## Get the middleware endpoints, which can be used for executing middleware functions.[br]
97+ ## The core functions are already wrapped by [PaimaMiddleware] in a more convenient form,
98+ ## use this function for wrapping endpoints [b]not[/b] provided by the class (i.e: endpoints specific to
99+ ## your game).[br][br]
100+ ##
101+ ## For example, if you want to execute a [code]join_match[/code] function:[br][br]
102+ ##
103+ ## First, you define a GDScript callback you want to run after joining the match[br]
104+ ## [code]function join_match_cb(join_result: JavaScriptObject) -> void:[/code][br]
105+ ## [code] ...[/code][br][br]
106+ ##
107+ ## Then, you wrap the GDScript callback in a Javascript callback using [method JavasScriptBridge.create_callback][br]
108+ ## [code]var join_match_cb_js := JavaScriptBridge.create_callback(join_match_cb)[/code][br][br]
109+ ##
110+ ## Finally, you get the the endpoints object and execute [code]join_match[/code]. The return value
111+ ## will be a promise to which you can attach your Javascript callback using the Promise API.[br]
112+ ## [code]middleware.get_endpoints().join_match(...).then()[/code]
44113func get_endpoints () -> JavaScriptObject :
45114 return _endpoints
46-
115+
116+ ## Get the wallet being used by the Paima middleware
47117func get_wallet () -> JavaScriptObject :
48118 return _paima_wallet
49119
120+ ## Get the wallet address
121+ # TODO: Provide a return type for this function?
50122func get_wallet_address ():
51123 return _paima_wallet .result .walletAddress
52124
53- ## Login
54- ## # The func
55- func login (login_info : LoginInfo , on_login_cb = null ) -> bool :
125+ ## Log into Paima using [param login_info].
126+ func login (login_info : LoginInfo ) -> bool :
56127 var js_login_info = _to_js_login_info (login_info )
57128 console .log ("GD:Paima: login_info: " , js_login_info )
58129 _endpoints .userWalletLogin (js_login_info ).then (_on_login_js )
59130 var login_successful = await on_paima_login
60131 return login_successful
61132
62- ## # Signal for `await`
133+ ## Emitted by [method login]
63134signal on_paima_login (success : bool )
64135
65- ## # Callback
136+ # Callback
66137var _on_login_js = JavaScriptBridge .create_callback (_on_login )
67138func _on_login (args ) -> void :
68139 var wallet = args [0 ]
@@ -75,6 +146,8 @@ func _on_login(args) -> void:
75146 console .log ("Paima wallet login result:" , wallet )
76147 on_paima_login .emit (false )
77148
149+ ## Returns [code]true[/code] if a wallet was successfully set for the Paima
150+ ## middleware.
78151func wallet_is_set () -> bool :
79152 return _paima_wallet && _paima_wallet .success
80153
@@ -87,8 +160,8 @@ func _to_js_login_info(login_info: LoginInfo) -> JavaScriptObject:
87160 info .preference = pref
88161 return info
89162
90- ## Query round executor
91- ## # The func
163+ ## Query the state of the round executor by providing a [parama lobby_id] and
164+ ## a [param round_number].
92165func query_round_executor (lobby_id : String , round_number : int ) -> RoundExecutor :
93166 _endpoints .getRoundExecutor (lobby_id , round_number ).then (_on_executor_query_response_js )
94167 var re = await on_executor_response
@@ -100,12 +173,12 @@ func query_round_executor(lobby_id: String, round_number: int) -> RoundExecutor:
100173 executor = null
101174 return executor
102175
103- ## # JS callback
104- var _on_executor_query_response_js = JavaScriptBridge .create_callback (on_executor_query_response )
105- func on_executor_query_response (args ) -> void :
176+ # JS callback
177+ var _on_executor_query_response_js = JavaScriptBridge .create_callback (_on_executor_query_response )
178+ func _on_executor_query_response (args ) -> void :
106179 on_executor_response .emit (args [0 ])
107180
108- ## # Signal for `await`
181+ ## Emitted by [method query_round_executor]
109182signal on_executor_response (re_result : JavaScriptObject )
110183
111184func _new_js_obj () -> JavaScriptObject :
0 commit comments