@@ -98,129 +98,166 @@ public function unref(): void
9898 }
9999
100100 /**
101+ * Connect to a signal on this object.
102+ * The callback will be triggered every time this signal is issued on this instance.
101103 * @throws Exception
102104 */
103105 public function signalConnect (string $ name , Closure $ callback ): void
104106 {
105- $ imageProgressCb = static function (
106- CData $ gClosure ,
107- ?CData $ returnValue ,
108- int $ numberOfParams ,
109- CData $ params ,
110- CData $ hint ,
111- ?CData $ data
112- ) use (&$ callback ) {
113- assert ($ numberOfParams === 3 );
114- /**
115- * Marshal-Signature: void(VipsImage* image, void* progress, void* handle)
116- */
117- $ vi = \FFI ::cast (FFI ::ctypes ('GObject ' ), FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [0 ])));
118- FFI ::gobject ()->g_object_ref ($ vi );
119- $ image = new Image ($ vi );
120- $ pr = \FFI ::cast (FFI ::ctypes ('VipsProgress ' ), FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ])));
121- $ callback ($ image , $ pr );
122- };
123- $ marshalers = ['preeval ' => $ imageProgressCb , 'eval ' => $ imageProgressCb , 'posteval ' => $ imageProgressCb ];
124-
125- if (FFI ::atLeast (8 , 9 )) {
126- $ marshalers ['read ' ] = static function (
127- CData $ gClosure ,
128- CData $ returnValue ,
129- int $ numberOfParams ,
130- CData $ params ,
131- CData $ hint ,
132- ?CData $ data
133- ) use (&$ callback ): void {
134- assert ($ numberOfParams === 4 );
135- /*
136- * Marshal-Signature: gint64(VipsSourceCustom* source, void* buffer, gint64 length, void* handle)
137- */
138- $ bufferPointer = FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ]));
139- $ bufferLength = (int )FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [2 ]));
140- $ returnBuffer = $ callback ($ bufferLength );
141- $ returnBufferLength = 0 ;
142-
143- if ($ returnBuffer !== null ) {
144- $ returnBufferLength = strlen ($ returnBuffer );
145- \FFI ::memcpy ($ bufferPointer , $ returnBuffer , $ returnBufferLength );
146- }
147- FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ returnBufferLength );
148- };
149- $ marshalers ['seek ' ] = static function (
150- CData $ gClosure ,
151- CData $ returnValue ,
152- int $ numberOfParams ,
153- CData $ params ,
154- CData $ hint ,
155- ?CData $ data
156- ) use (&$ callback ): void {
157- assert ($ numberOfParams === 4 );
158- /*
159- * Marshal-Signature: gint64(VipsSourceCustom* source, gint64 offset, int whence, void* handle)
160- */
161- $ offset = (int )FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [1 ]));
162- $ whence = (int )FFI ::gobject ()->g_value_get_int (\FFI ::addr ($ params [2 ]));
163- FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ callback ($ offset , $ whence ));
164- };
165- $ marshalers ['write ' ] = static function (
166- CData $ gClosure ,
167- CData $ returnValue ,
168- int $ numberOfParams ,
169- CData $ params ,
170- CData $ hint ,
171- ?CData $ data
172- ) use (&$ callback ): void {
173- assert ($ numberOfParams === 4 );
174- /*
175- * Marshal-Signature: gint64(VipsTargetCustom* target, void* buffer, gint64 length, void* handle)
176- */
177- $ bufferPointer = FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ]));
178- $ bufferLength = (int )FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [2 ]));
179- $ buffer = \FFI ::string ($ bufferPointer , $ bufferLength );
180- $ returnBufferLength = $ callback ($ buffer );
181- FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ returnBufferLength );
182- };
183- $ marshalers ['finish ' ] = static function (
184- CData $ gClosure ,
185- ?CData $ returnValue ,
186- int $ numberOfParams ,
187- CData $ params ,
188- CData $ hint ,
189- ?CData $ data
190- ) use (&$ callback ): void {
191- assert ($ numberOfParams === 2 );
192- /**
193- * Marshal-Signature: void(VipsTargetCustom* target, void* handle)
194- */
195- $ callback ();
196- };
197- }
198-
199- if (FFI ::atLeast (8 , 13 )) {
200- $ marshalers ['end ' ] = static function (
201- CData $ gClosure ,
202- CData $ returnValue ,
203- int $ numberOfParams ,
204- CData $ params ,
205- CData $ hint ,
206- ?CData $ data
207- ) use (&$ callback ): void {
208- assert ($ numberOfParams === 2 );
209- /**
210- * Marshal-Signature: int(VipsTargetCustom* target, void* handle)
211- */
212- FFI ::gobject ()->g_value_set_int ($ returnValue , $ callback ());
213- };
214- }
215-
216- if (!isset ($ marshalers [$ name ])) {
107+ $ marshaler = self ::getMarshaler ($ name , $ callback );
108+ if ($ marshaler === null ) {
217109 throw new Exception ("unsupported signal $ name " );
218110 }
219111
220112 $ gc = FFI ::gobject ()->g_closure_new_simple (\FFI ::sizeof (FFI ::ctypes ('GClosure ' )), null );
221- $ gc ->marshal = $ marshalers [ $ name ] ;
113+ $ gc ->marshal = $ marshaler ;
222114 FFI ::gobject ()->g_signal_connect_closure ($ this ->pointer , $ name , $ gc , 0 );
223115 }
116+
117+ private static function getMarshaler (string $ name , Closure $ callback ): ?Closure
118+ {
119+ switch ($ name ) {
120+ case 'preeval ' :
121+ case 'eval ' :
122+ case 'posteval ' :
123+ return static function (
124+ CData $ gClosure ,
125+ ?CData $ returnValue ,
126+ int $ numberOfParams ,
127+ CData $ params ,
128+ CData $ hint ,
129+ ?CData $ data
130+ ) use (&$ callback ) {
131+ assert ($ numberOfParams === 3 );
132+ /**
133+ * Signature: void(VipsImage* image, void* progress, void* handle)
134+ */
135+ $ vi = \FFI ::cast (
136+ FFI ::ctypes ('GObject ' ),
137+ FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [0 ]))
138+ );
139+ FFI ::gobject ()->g_object_ref ($ vi );
140+ $ image = new Image ($ vi );
141+ $ pr = \FFI ::cast (
142+ FFI ::ctypes ('VipsProgress ' ),
143+ FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ]))
144+ );
145+ $ callback ($ image , $ pr );
146+ };
147+ case 'read ' :
148+ if (FFI ::atLeast (8 , 9 )) {
149+ return static function (
150+ CData $ gClosure ,
151+ CData $ returnValue ,
152+ int $ numberOfParams ,
153+ CData $ params ,
154+ CData $ hint ,
155+ ?CData $ data
156+ ) use (&$ callback ): void {
157+ assert ($ numberOfParams === 4 );
158+ /*
159+ * Signature: gint64(VipsSourceCustom* source, void* buffer, gint64 length, void* handle)
160+ */
161+ $ bufferLength = (int )FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [2 ]));
162+ $ returnBuffer = $ callback ($ bufferLength );
163+ $ returnBufferLength = 0 ;
164+
165+ if ($ returnBuffer !== null ) {
166+ $ returnBufferLength = strlen ($ returnBuffer );
167+ $ bufferPointer = FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ]));
168+ \FFI ::memcpy ($ bufferPointer , $ returnBuffer , $ returnBufferLength );
169+ }
170+ FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ returnBufferLength );
171+ };
172+ }
173+
174+ return null ;
175+ case 'seek ' :
176+ if (FFI ::atLeast (8 , 9 )) {
177+ return static function (
178+ CData $ gClosure ,
179+ CData $ returnValue ,
180+ int $ numberOfParams ,
181+ CData $ params ,
182+ CData $ hint ,
183+ ?CData $ data
184+ ) use (&$ callback ): void {
185+ assert ($ numberOfParams === 4 );
186+ /*
187+ * Signature: gint64(VipsSourceCustom* source, gint64 offset, int whence, void* handle)
188+ */
189+ $ offset = (int )FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [1 ]));
190+ $ whence = (int )FFI ::gobject ()->g_value_get_int (\FFI ::addr ($ params [2 ]));
191+ FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ callback ($ offset , $ whence ));
192+ };
193+ }
194+
195+ return null ;
196+ case 'write ' :
197+ if (FFI ::atLeast (8 , 9 )) {
198+ return static function (
199+ CData $ gClosure ,
200+ CData $ returnValue ,
201+ int $ numberOfParams ,
202+ CData $ params ,
203+ CData $ hint ,
204+ ?CData $ data
205+ ) use (&$ callback ): void {
206+ assert ($ numberOfParams === 4 );
207+ /*
208+ * Signature: gint64(VipsTargetCustom* target, void* buffer, gint64 length, void* handle)
209+ */
210+ $ bufferPointer = FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ]));
211+ $ bufferLength = (int )FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [2 ]));
212+ $ buffer = \FFI ::string ($ bufferPointer , $ bufferLength );
213+ $ returnBufferLength = $ callback ($ buffer );
214+ FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ returnBufferLength );
215+ };
216+ }
217+
218+ return null ;
219+ case 'finish ' :
220+ if (FFI ::atLeast (8 , 9 )) {
221+ return static function (
222+ CData $ gClosure ,
223+ ?CData $ returnValue ,
224+ int $ numberOfParams ,
225+ CData $ params ,
226+ CData $ hint ,
227+ ?CData $ data
228+ ) use (&$ callback ): void {
229+ assert ($ numberOfParams === 2 );
230+ /**
231+ * Signature: void(VipsTargetCustom* target, void* handle)
232+ */
233+ $ callback ();
234+ };
235+ }
236+
237+ return null ;
238+ case 'end ' :
239+ if (FFI ::atLeast (8 , 13 )) {
240+ return static function (
241+ CData $ gClosure ,
242+ CData $ returnValue ,
243+ int $ numberOfParams ,
244+ CData $ params ,
245+ CData $ hint ,
246+ ?CData $ data
247+ ) use (&$ callback ): void {
248+ assert ($ numberOfParams === 2 );
249+ /**
250+ * Signature: int(VipsTargetCustom* target, void* handle)
251+ */
252+ FFI ::gobject ()->g_value_set_int ($ returnValue , $ callback ());
253+ };
254+ }
255+
256+ return null ;
257+ default :
258+ return null ;
259+ }
260+ }
224261}
225262
226263/*
0 commit comments