@@ -15,17 +15,20 @@ local decoration_handle = {}
1515
1616--- @class snowcap.decoration.DecorationHandle
1717--- @field id integer
18- --- @field private update fun (msg : any )
18+ --- @field private _update fun (msg : any )
19+ --- @field private _operate fun (oper : snowcap.widget.operation.Operation )
1920local DecorationHandle = {}
2021
2122--- @param id integer
2223--- @param update fun ( msg : any ?)
24+ --- @param operate fun ( oper : snowcap.widget.operation.Operation )
2325--- @return snowcap.decoration.DecorationHandle
24- function decoration_handle .new (id , update )
26+ function decoration_handle .new (id , update , operate )
2527 --- @type snowcap.decoration.DecorationHandle
2628 local self = {
2729 id = id ,
28- update = update ,
30+ _update = update ,
31+ _operate = operate ,
2932 }
3033 setmetatable (self , { __index = DecorationHandle })
3134 return self
@@ -80,29 +83,30 @@ function decoration.new_widget(args)
8083
8184 local decoration_id = response .decoration_id or 0
8285
86+ local sender , receiver = require (" snowcap.util.channel" ).spsc ()
87+
8388 --- @type fun ( msg : any ?)
8489 local update_on_msg = function (msg )
8590 if msg ~= nil then
86- args .program :update (msg )
87- end
88-
89- --- @diagnostic disable-next-line : redefined-local
90- local _ , err = client :snowcap_decoration_v1_DecorationService_RequestView ({
91- decoration_id = decoration_id ,
92- })
93-
94- if err then
95- log .error (err )
91+ sender :send ({
92+ message = msg ,
93+ })
94+ else
95+ sender :send ({
96+ redraw = {}
97+ })
9698 end
9799 end
98100
99- local handle = decoration_handle .new (decoration_id , update_on_msg )
100-
101101 --- @type fun ( oper : snowcap.widget.operation.Operation )
102- local forward_operation = function (oper )
103- handle :operate (oper )
102+ local operate_surface = function (oper )
103+ sender :send ({
104+ operation = oper ,
105+ })
104106 end
105107
108+ local handle = decoration_handle .new (decoration_id , update_on_msg , operate_surface )
109+
106110 --- @type fun (): snowcap.signal.HandlerPolicy
107111 local close_surface = function ()
108112 handle :close ()
@@ -112,48 +116,110 @@ function decoration.new_widget(args)
112116
113117 args .program :connect (widget_signal .redraw_needed , update_on_msg )
114118 args .program :connect (widget_signal .send_message , update_on_msg )
115- args .program :connect (widget_signal .operation , forward_operation )
119+ args .program :connect (widget_signal .operation , operate_surface )
116120 args .program :connect (widget_signal .request_close , close_surface )
117121
118122 args .program :event ({
119123 created = widget .SurfaceHandle .from_decoration_handle (handle ),
120124 })
121125
126+ err = client :snowcap_decoration_v1_DecorationService_GetDecorationEvents ({
127+ decoration_id = decoration_id ,
128+ }, function (response ) --- @diagnostic disable-line : redefined-local
129+ sender :send ({
130+ decoration_events = response .decoration_events or {}
131+ })
132+ end )
133+
122134 err = client :snowcap_widget_v1_WidgetService_GetWidgetEvents ({
123135 decoration_id = decoration_id ,
124136 }, function (response ) --- @diagnostic disable-line : redefined-local
125- for _ , event in ipairs (response .widget_events ) do
126- --- @diagnostic disable-next-line : invisible
127- local msg = widget ._message_from_event (callbacks , event )
128-
129- if msg then
130- local ok , update_err = pcall (function ()
131- args .program :update (msg )
132- end )
133- if not ok then
134- log .error (update_err )
137+ sender :send ({
138+ widget_events = response .widget_events or {}
139+ })
140+ end )
141+
142+ client .loop :wrap (function ()
143+ local pending_operations = {}
144+
145+ local msg = receiver :recv ()
146+ while msg do
147+ local update_view = false
148+
149+ if msg .widget_events then
150+ for _ , event in ipairs (msg .widget_events ) do
151+ --- @diagnostic disable-next-line : invisible
152+ local msg = widget ._message_from_event (callbacks , event )
153+
154+ if msg then
155+ local ok , update_err = pcall (function ()
156+ args .program :update (msg )
157+ end )
158+ if not ok then
159+ log .error (update_err )
160+ end
161+ end
162+ end
163+
164+ update_view = true
165+ elseif msg .message then
166+ args .program :update (msg )
167+ elseif msg .operation then
168+ table.insert (pending_operations , msg .operation )
169+ elseif msg .decoration_events then
170+ for _ , decoration_event in ipairs (msg .decoration_events ) do
171+ if decoration_event .closing ~= nil then
172+ goto main_loop_break
173+ end
135174 end
136175 end
137- end
138176
139- --- @diagnostic disable-next-line : redefined-local
140- local widget_def = args .program :view () or widget .row ({ children = {} })
141- callbacks = {}
177+ if not update_view then
178+ --- @diagnostic disable-next-line : redefined-local
179+ local _ , err = client :snowcap_decoration_v1_DecorationService_RequestView ({
180+ decoration_id = decoration_id ,
181+ })
142182
143- widget ._traverse_widget_tree (widget_def , callbacks , widget ._collect_callbacks )
183+ if err then
184+ log .error (err )
185+ end
186+ else
187+ --- @diagnostic disable-next-line : redefined-local
188+ local widget_def = args .program :view () or widget .row ({ children = {} })
189+ callbacks = {}
144190
145- --- @diagnostic disable-next-line : redefined-local
146- local _ , err = client :snowcap_decoration_v1_DecorationService_UpdateDecoration ({
147- decoration_id = decoration_id ,
148- widget_def = widget .widget_def_into_api (widget_def ),
149- })
191+ widget ._traverse_widget_tree (widget_def , callbacks , widget ._collect_callbacks )
150192
151- if err then
152- log .error (err )
193+ --- @diagnostic disable-next-line : redefined-local
194+ local _ , err = client :snowcap_decoration_v1_DecorationService_UpdateDecoration ({
195+ decoration_id = decoration_id ,
196+ widget_def = widget .widget_def_into_api (widget_def ),
197+ })
198+
199+ if err then
200+ log .error (err )
201+ end
202+
203+ for _ , oper in ipairs (pending_operations ) do
204+ --- @diagnostic disable-next-line : redefined-local
205+ local _ , err = client :snowcap_decoration_v1_DecorationService_OperateDecoration ({
206+ decoration_id = decoration_id ,
207+ operation = require (" snowcap.widget.operation" )._to_api (oper ), --- @diagnostic disable-line : invisible
208+ })
209+
210+ if err then
211+ log .error (err )
212+ end
213+ end
214+ pending_operations = {}
215+ end
216+
217+ msg = receiver :recv ()
153218 end
154- end , function ()
219+ :: main_loop_break::
220+
155221 args .program :event ({
156- closing = {},
222+ closing = {}
157223 })
158224 end )
159225
@@ -178,20 +244,13 @@ end
178244---
179245--- @param message any
180246function DecorationHandle :send_message (message )
181- self .update (message )
247+ self ._update (message )
182248end
183249
184250--- Sends an `Operation` to this decoration.
185251--- @param operation snowcap.widget.operation.Operation
186252function DecorationHandle :operate (operation )
187- local _ , err = client :snowcap_decoration_v1_DecorationService_OperateDecoration ({
188- decoration_id = self .id ,
189- operation = require (" snowcap.widget.operation" )._to_api (operation ), --- @diagnostic disable-line : invisible
190- })
191-
192- if err then
193- log .error (err )
194- end
253+ self ._operate (operation )
195254end
196255
197256--- Sets the z-index at which this decoration will render.
0 commit comments