efl

Форк
0
/
eldbus_model_proxy.c 
726 строк · 21.7 Кб
1
#ifdef HAVE_CONFIG_H
2
# include <config.h>
3
#endif
4

5
#include <Eina.h>
6

7
#include "eldbus_model_proxy_private.h"
8
#include "eldbus_model_private.h"
9

10
#define MY_CLASS ELDBUS_MODEL_PROXY_CLASS
11
#define MY_CLASS_NAME "Eldbus_Model_Proxy"
12

13
static void _eldbus_model_proxy_property_get_all_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
14
static void _eldbus_model_proxy_property_set_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
15
static void _eldbus_model_proxy_property_set_load_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
16
static void _eldbus_model_proxy_start_monitor(Eldbus_Model_Proxy_Data *);
17
static void _eldbus_model_proxy_property_changed_cb(void *, Eldbus_Proxy *, void *);
18
static void _eldbus_model_proxy_property_invalidated_cb(void *, Eldbus_Proxy *, void *);
19
static const char *_eldbus_model_proxy_property_type_get(Eldbus_Model_Proxy_Data *, const char *);
20
static void _eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *);
21
static void _eldbus_model_proxy_create_signals_children(Eldbus_Model_Proxy_Data *);
22

23

24
typedef struct _Eldbus_Model_Proxy_Property_Set_Data Eldbus_Model_Proxy_Property_Set_Data;
25
typedef struct _Eldbus_Property_Promise Eldbus_Property_Promise;
26

27
struct _Eldbus_Model_Proxy_Property_Set_Data
28
{
29
   Eldbus_Model_Proxy_Data *pd;
30

31
   Eina_Stringshare *property;
32
   Eina_Promise *promise;
33
   Eina_Value *value;
34
};
35

36
struct _Eldbus_Property_Promise
37
{
38
  Eina_Promise *promise;
39
  Eina_Stringshare *property;
40
};
41

42
static Eina_Bool
43
_eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *pd)
44
{
45
   Eldbus_Introspection_Property *property;
46
   Eina_List *it;
47

48
   if (pd->proxy)
49
     return EINA_TRUE;
50

51
   pd->proxy = eldbus_proxy_get(pd->object, pd->name);
52
   EINA_SAFETY_ON_NULL_RETURN_VAL(pd->proxy, EINA_FALSE);
53

54
   EINA_LIST_FOREACH(pd->interface->properties, it, property)
55
     {
56
        const Eina_Value_Type *type;
57
        Eina_Stringshare *name;
58
        Eina_Value *value;
59

60
        type = _dbus_type_to_eina_value_type(property->type[0]);
61
        name = eina_stringshare_add(property->name);
62
        value = eina_value_new(type);
63

64
        eina_hash_direct_add(pd->properties, name, value);
65
     }
66

67
   return EINA_TRUE;
68
}
69

70
static void
71
_eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *pd)
72
{
73
   Eldbus_Pending *pending;
74

75
   EINA_LIST_FREE(pd->pendings, pending)
76
     eldbus_pending_cancel(pending);
77

78
   if (pd->monitoring)
79
     {
80
        eldbus_proxy_event_callback_del(pd->proxy,
81
                                        ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
82
                                        _eldbus_model_proxy_property_changed_cb,
83
                                        pd);
84
        eldbus_proxy_event_callback_del(pd->proxy,
85
                                        ELDBUS_PROXY_EVENT_PROPERTY_REMOVED,
86
                                        _eldbus_model_proxy_property_invalidated_cb,
87
                                        pd);
88
     }
89
   pd->monitoring = EINA_FALSE;
90

91
   if (pd->proxy) eldbus_proxy_unref(pd->proxy);
92
   pd->proxy = NULL;
93
}
94

95
static void
96
_eldbus_model_proxy_object_del(void *data, Eldbus_Object *object EINA_UNUSED, void *event_info EINA_UNUSED)
97
{
98
   Eldbus_Model_Proxy_Data *pd = data;
99

100
   pd->object = NULL;
101
}
102

103
static Efl_Object*
104
_eldbus_model_proxy_efl_object_constructor(Eo *obj, Eldbus_Model_Proxy_Data *pd)
105
{
106
   obj = efl_constructor(efl_super(obj, MY_CLASS));
107

108
   pd->obj = obj;
109
   pd->properties = eina_hash_stringshared_new(NULL);
110

111
   return obj;
112
}
113

114
static Efl_Object*
115
_eldbus_model_proxy_efl_object_finalize(Eo *obj, Eldbus_Model_Proxy_Data *pd)
116
{
117
   if (!pd->object ||
118
       !pd->name ||
119
       !pd->interface)
120
     return NULL;
121

122
   if (!_eldbus_model_proxy_load(pd)) return NULL;
123

124
   if (!eldbus_model_connection_get(obj))
125
     eldbus_model_connection_set(obj, eldbus_object_connection_get(pd->object));
126

127
   eldbus_object_event_callback_add(pd->object, ELDBUS_OBJECT_EVENT_DEL, _eldbus_model_proxy_object_del, pd);
128

129
   return efl_finalize(efl_super(obj, MY_CLASS));
130
}
131

132
static void
133
_eldbus_model_proxy_object_set(Eo *obj EINA_UNUSED,
134
                               Eldbus_Model_Proxy_Data *pd,
135
                               Eldbus_Object *object)
136
{
137
   pd->object = eldbus_object_ref(object);
138
}
139

140
static void
141
_eldbus_model_proxy_interface_set(Eo *obj EINA_UNUSED,
142
                                  Eldbus_Model_Proxy_Data *pd,
143
                                  const Eldbus_Introspection_Interface *interface)
144
{
145
   pd->name = eina_stringshare_add(interface->name);
146
   pd->interface = interface;
147
}
148

149
static void
150
_eldbus_model_proxy_efl_object_invalidate(Eo *obj, Eldbus_Model_Proxy_Data *pd)
151
{
152
   Eo *child;
153

154
   EINA_LIST_FREE(pd->childrens, child)
155
     efl_unref(child);
156

157
   _eldbus_model_proxy_unload(pd);
158

159
   if (pd->object)
160
     {
161
        eldbus_object_event_callback_del(pd->object, ELDBUS_OBJECT_EVENT_DEL, _eldbus_model_proxy_object_del, pd);
162
        eldbus_object_unref(pd->object);
163
     }
164

165
   efl_invalidate(efl_super(obj, MY_CLASS));
166
}
167

168
static void
169
_eldbus_model_proxy_efl_object_destructor(Eo *obj, Eldbus_Model_Proxy_Data *pd)
170
{
171
   Eina_Hash_Tuple *tuple;
172
   Eina_Iterator *it;
173

174
   it = eina_hash_iterator_tuple_new(pd->properties);
175
   EINA_ITERATOR_FOREACH(it, tuple)
176
     {
177
        Eina_Stringshare *property = tuple->key;
178
        Eina_Value *value = tuple->data;
179

180
        eina_stringshare_del(property);
181
        eina_value_free(value);
182
     }
183
   eina_iterator_free(it);
184
   eina_hash_free(pd->properties);
185

186
   eina_stringshare_del(pd->name);
187

188
   efl_destructor(efl_super(obj, MY_CLASS));
189
}
190

191
static Eina_Iterator *
192
_eldbus_model_proxy_efl_model_properties_get(const Eo *obj EINA_UNUSED,
193
                                             Eldbus_Model_Proxy_Data *pd)
194
{
195
   return eina_hash_iterator_key_new(pd->properties);
196
}
197

198
#define PROPERTY_EXIST 1
199
#define PROPERTY_READ  2
200
#define PROPERTY_WRITE 4
201

202
static unsigned char
203
eldbus_model_proxy_property_check(Eldbus_Model_Proxy_Data *pd,
204
                                  const char *property)
205
{
206
    Eldbus_Introspection_Property *property_introspection =
207
      eldbus_introspection_property_find(pd->interface->properties, property);
208
    unsigned char r = 0;
209

210
    if (property_introspection == NULL)
211
       {
212
          WRN("Property not found: %s", property);
213
          return 0;
214
       }
215

216
    r = PROPERTY_EXIST;
217
    // Check read access
218
    if (property_introspection->access == ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READ ||
219
        property_introspection->access == ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READWRITE)
220
      r |= PROPERTY_READ;
221
    // Check write access
222
    if (property_introspection->access == ELDBUS_INTROSPECTION_PROPERTY_ACCESS_WRITE ||
223
        property_introspection->access == ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READWRITE)
224
      r |= PROPERTY_WRITE;
225

226
    return r;
227
}
228

229
static void
230
_eldbus_model_proxy_cancel_cb(Efl_Loop_Consumer *consumer EINA_UNUSED,
231
                              void *data,
232
                              const Eina_Future *dead_future EINA_UNUSED)
233
{
234
   Eldbus_Model_Proxy_Property_Set_Data *sd = data;
235

236
   sd->promise = NULL;
237
   eina_stringshare_del(sd->property);
238
   eina_value_free(sd->value);
239
   free(sd);
240
}
241

242
static Eldbus_Pending *
243
_eldbus_model_proxy_load_all(Eldbus_Model_Proxy_Data *pd,
244
                             Eina_Promise *promise, const char *property,
245
                             Eldbus_Message_Cb callback,
246
                             void *data)
247
{
248
   Eldbus_Property_Promise *p;
249
   Eldbus_Pending *pending = NULL;
250

251
   p = calloc(1, sizeof(Eldbus_Property_Promise));
252
   if (!p)
253
     {
254
        if (promise) eina_promise_reject(promise, ENOMEM);
255
        return NULL;
256
     }
257

258
   p->promise = promise;
259
   p->property = eina_stringshare_add(property);
260
   pd->promises = eina_list_append(pd->promises, p);
261

262
   if (!pd->pendings)
263
     {
264
        pending = eldbus_proxy_property_get_all(pd->proxy, callback, data);
265
     }
266
   return pending;
267
}
268

269
static Eina_Future *
270
_eldbus_model_proxy_efl_model_property_set(Eo *obj EINA_UNUSED,
271
                                           Eldbus_Model_Proxy_Data *pd,
272
                                           const char *property,
273
                                           Eina_Value *value)
274
{
275
   Eldbus_Model_Proxy_Property_Set_Data *data = NULL;
276
   const char *signature;
277
   Eldbus_Pending *pending;
278
   unsigned char access;
279
   Eina_Error err = 0;
280

281
   DBG("(%p): property=%s", obj, property);
282

283
   access = eldbus_model_proxy_property_check(pd, property);
284
   err = EFL_MODEL_ERROR_NOT_FOUND;
285
   if (!access) goto on_error;
286
   err = EFL_MODEL_ERROR_READ_ONLY;
287
   if (!(access & PROPERTY_WRITE)) goto on_error;
288

289
   err = EFL_MODEL_ERROR_UNKNOWN;
290
   signature = _eldbus_model_proxy_property_type_get(pd, property);
291
   if (!signature) goto on_error;
292

293
   err = ENOMEM;
294
   data = calloc(1, sizeof (Eldbus_Model_Proxy_Property_Set_Data));
295
   if (!data) goto on_error;
296

297
   data->pd = pd;
298
   data->promise = efl_loop_promise_new(obj);
299
   data->property = eina_stringshare_add(property);
300
   if (!(data->value = eina_value_dup(value))) goto on_error;
301

302
   if (!pd->is_loaded)
303
     {
304
        pending = _eldbus_model_proxy_load_all(pd, data->promise, property,
305
                                               _eldbus_model_proxy_property_set_load_cb, data);
306
     }
307
   else
308
     {
309
        pending = eldbus_proxy_property_value_set(pd->proxy, property, signature, (Eina_Value*)value,
310
                                                  _eldbus_model_proxy_property_set_cb, data);
311
     }
312

313
   if (pending) pd->pendings = eina_list_append(pd->pendings, pending);
314
   return efl_future_then(obj, eina_future_new(data->promise),
315
                          .data = data, .free = _eldbus_model_proxy_cancel_cb);
316

317
 on_error:
318
   free(data);
319
   return efl_loop_future_rejected(obj, err);
320
}
321

322
static Eina_Value *
323
_eldbus_model_proxy_efl_model_property_get(const Eo *obj EINA_UNUSED,
324
                                           Eldbus_Model_Proxy_Data *pd,
325
                                           const char *property)
326
{
327
   Eldbus_Pending *pending;
328
   unsigned char access;
329
   Eina_Error err = 0;
330

331
   access = eldbus_model_proxy_property_check(pd, property);
332
   err = EFL_MODEL_ERROR_NOT_FOUND;
333
   if (!access) goto on_error;
334
   if (!(access & PROPERTY_READ)) goto on_error;
335

336
   if (pd->is_loaded)
337
     {
338
        Eina_Stringshare *tmp;
339
        Eina_Value *value;
340

341
        err = EFL_MODEL_ERROR_NOT_FOUND;
342
        tmp = eina_stringshare_add(property);
343
        value = eina_hash_find(pd->properties, tmp);
344
        eina_stringshare_del(tmp);
345
        if (!value) goto on_error;
346

347
        return eina_value_dup(value);
348
     }
349

350
   err = ENOMEM;
351

352
   pending = _eldbus_model_proxy_load_all(pd, NULL, property,
353
                                          _eldbus_model_proxy_property_get_all_cb, pd);
354
   if (pending) pd->pendings = eina_list_append(pd->pendings, pending);
355
   else goto on_error;
356

357
   return eina_value_error_new(EAGAIN);
358

359
 on_error:
360
   return eina_value_error_new(err);
361
}
362

363
static void
364
_eldbus_model_proxy_listed(Eldbus_Model_Proxy_Data *pd)
365
{
366
   if (!pd->is_listed)
367
     {
368
        _eldbus_model_proxy_create_methods_children(pd);
369
        _eldbus_model_proxy_create_signals_children(pd);
370

371
        efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, NULL);
372
        pd->is_listed = EINA_TRUE;
373
     }
374
}
375

376
static Eina_Future*
377
_eldbus_model_proxy_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
378
                                                 Eldbus_Model_Proxy_Data *pd,
379
                                                 unsigned start,
380
                                                 unsigned count)
381
{
382
   Eina_Value v;
383

384
   _eldbus_model_proxy_listed(pd);
385

386
   v = efl_model_list_value_get(pd->childrens, start, count);
387
   return efl_loop_future_resolved(obj, v);
388
}
389

390
static unsigned int
391
_eldbus_model_proxy_efl_model_children_count_get(const Eo *obj EINA_UNUSED,
392
                                                 Eldbus_Model_Proxy_Data *pd)
393
{
394
   _eldbus_model_proxy_listed(pd);
395
   return eina_list_count(pd->childrens);
396
}
397

398
static void
399
_eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *pd)
400
{
401
   Eldbus_Introspection_Method *method;
402
   Eina_List *it;
403

404
   EINA_LIST_FOREACH(pd->interface->methods, it, method)
405
     {
406
        const char *bus;
407
        const char *path;
408
        const char *interface_name;
409
        const char *method_name;
410
        Eo *child;
411

412
        bus = eldbus_object_bus_name_get(pd->object);
413
        if (!bus) continue;
414

415
        path = eldbus_object_path_get(pd->object);
416
        if (!path) continue;
417

418
        interface_name = pd->interface->name;
419
        if (!interface_name) continue;
420

421
        method_name = method->name;
422
        if (!method_name) continue;
423

424
        INF("(%p) Creating method child: bus = %s, path = %s, method = %s::%s",
425
                       pd->obj, bus, path, interface_name, method_name);
426

427
        child = efl_add_ref(ELDBUS_MODEL_METHOD_CLASS, pd->obj,
428
                            eldbus_model_method_proxy_set(efl_added, pd->proxy),
429
                            eldbus_model_method_set(efl_added, method));
430

431
        if (child) pd->childrens = eina_list_append(pd->childrens, child);
432
        else ERR("Could not create method child: bus = %s, path = %s method = %s::%s.",
433
                 bus, path, interface_name, method_name);
434
     }
435
}
436

437
static void
438
_eldbus_model_proxy_create_signals_children(Eldbus_Model_Proxy_Data *pd)
439
{
440
   Eina_List *it;
441
   Eldbus_Introspection_Signal *signal;
442

443
   EINA_LIST_FOREACH(pd->interface->signals, it, signal)
444
     {
445
        const char *bus;
446
        const char *path;
447
        const char *interface_name;
448
        const char *signal_name;
449
        Eo *child;
450

451
        bus = eldbus_object_bus_name_get(pd->object);
452
        if (!bus) continue;
453

454
        path = eldbus_object_path_get(pd->object);
455
        if (!path) continue;
456

457
        interface_name = pd->interface->name;
458
        if (!interface_name) continue;
459

460
        signal_name = signal->name;
461
        if (!signal_name) continue;
462

463
        DBG("(%p) Creating signal child: bus = %s, path = %s, signal = %s::%s",
464
                       pd->obj, bus, path, interface_name, signal_name);
465

466
        child = efl_add_ref(ELDBUS_MODEL_SIGNAL_CLASS, pd->obj, eldbus_model_signal_constructor(efl_added, pd->proxy, signal));
467

468
        if (child) pd->childrens = eina_list_append(pd->childrens, child);
469
        else ERR("Could not create signal child: bus = %s, path = %s signal = %s::%s.",
470
                 bus, path, interface_name, signal_name);
471
     }
472
}
473

474
static const char *
475
_eldbus_model_proxy_proxy_name_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
476
{
477
   return pd->name;
478
}
479

480
static void
481
_eldbus_model_proxy_start_monitor(Eldbus_Model_Proxy_Data *pd)
482
{
483
   if (pd->monitoring)
484
     return;
485

486
   pd->monitoring = EINA_TRUE;
487

488
   eldbus_proxy_event_callback_add(pd->proxy,
489
                                   ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
490
                                   _eldbus_model_proxy_property_changed_cb,
491
                                   pd);
492

493
   eldbus_proxy_event_callback_add(pd->proxy,
494
                                   ELDBUS_PROXY_EVENT_PROPERTY_REMOVED,
495
                                   _eldbus_model_proxy_property_invalidated_cb,
496
                                   pd);
497
}
498

499
static void
500
_eldbus_model_proxy_property_changed_cb(void *data,
501
                                        Eldbus_Proxy *proxy EINA_UNUSED,
502
                                        void *event_info)
503
{
504
   Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data;
505
   Eldbus_Object_Event_Property_Changed *event = (Eldbus_Object_Event_Property_Changed*)event_info;
506
   Eina_Value *prop_value;
507
   Eina_Bool ret;
508

509
   prop_value = eina_hash_find(pd->properties, event->name);
510
   if (!prop_value) return ;
511

512
   ret = eina_value_copy(event->value, prop_value);
513
   if (!ret) return ;
514

515
   efl_model_properties_changed(pd->obj, event->name);
516
}
517

518
static void
519
_eldbus_model_proxy_property_invalidated_cb(void *data,
520
                                            Eldbus_Proxy *proxy EINA_UNUSED,
521
                                            void *event_info)
522
{
523
   Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data;
524
   Eldbus_Proxy_Event_Property_Changed *event = (Eldbus_Proxy_Event_Property_Changed*)event_info;
525

526
   efl_model_property_invalidated_notify(pd->obj, event->name);
527
}
528

529
static Eina_Array *
530
_eldbus_model_proxy_property_get_all_load(const Eldbus_Message *msg, Eldbus_Model_Proxy_Data *pd)
531
{
532
   Eldbus_Message_Iter *values = NULL;
533
   Eldbus_Message_Iter *entry;
534
   Eina_Array *changed_properties;
535
   Eina_Stringshare *tmp = NULL;
536
   const char *error_name, *error_text;
537

538
   if (eldbus_message_error_get(msg, &error_name, &error_text))
539
     {
540
        ERR("%s: %s", error_name, error_text);
541
        return NULL;
542
     }
543

544
   if (!eldbus_message_arguments_get(msg, "a{sv}", &values))
545
     {
546
        ERR("%s", "Error getting arguments.");
547
        return NULL;
548
     }
549

550
   changed_properties = eina_array_new(1);
551
   while (eldbus_message_iter_get_and_next(values, 'e', &entry))
552
     {
553
        const char *property;
554
        Eldbus_Message_Iter *variant;
555
        Eina_Value *struct_value;
556
        Eina_Value *prop_value;
557
        Eina_Value arg0;
558
        Eina_Bool ret;
559

560
        if (!eldbus_message_iter_arguments_get(entry, "sv", &property, &variant))
561
          continue;
562

563
        struct_value = eldbus_message_iter_struct_like_to_eina_value(variant);
564
        if (!struct_value) goto on_error;
565

566
        ret = eina_value_struct_value_get(struct_value, "arg0", &arg0);
567
        eina_value_free(struct_value);
568
        if (!ret) goto on_error;
569

570
        tmp = eina_stringshare_add(property);
571
        prop_value = eina_hash_find(pd->properties, tmp);
572
        if (!prop_value) goto on_error;
573

574
        ret = eina_value_copy(&arg0, prop_value);
575
        if (!ret) goto on_error;
576

577
        eina_value_flush(&arg0);
578

579
        ret = eina_array_push(changed_properties, tmp);
580
        if (!ret) goto on_error;
581

582
        // Reset tmp to NULL to avoid double free.
583
        tmp = NULL;
584
     }
585

586
   pd->is_loaded = EINA_TRUE;
587
   return changed_properties;
588

589
 on_error:
590
   eina_stringshare_del(tmp);
591
   while ((tmp = eina_array_pop(changed_properties)))
592
     eina_stringshare_del(tmp);
593
   eina_array_free(changed_properties);
594
   return NULL;
595
}
596

597
static void
598
_eldbus_model_proxy_promise_clean(Eldbus_Property_Promise* p,
599
                                  Eina_Error err)
600
{
601
   if (p->promise) eina_promise_reject(p->promise, err);
602
   eina_stringshare_del(p->property);
603
   free(p);
604
}
605

606
static void
607
_eldbus_model_proxy_property_get_all_cb(void *data,
608
                                        const Eldbus_Message *msg,
609
                                        Eldbus_Pending *pending)
610
{
611
   Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data;
612
   Eldbus_Property_Promise* p;
613
   Eina_Stringshare *sp;
614
   Eina_Array *properties;
615
   Efl_Model_Property_Event evt;
616

617
   pd->pendings = eina_list_remove(pd->pendings, pending);
618

619
   properties = _eldbus_model_proxy_property_get_all_load(msg, pd);
620
   if (!properties)
621
     {
622
        EINA_LIST_FREE(pd->promises, p)
623
          _eldbus_model_proxy_promise_clean(p, EFL_MODEL_ERROR_NOT_FOUND);
624
        return ;
625
     }
626

627
   EINA_LIST_FREE(pd->promises, p)
628
     _eldbus_model_proxy_promise_clean(p, EFL_MODEL_ERROR_READ_ONLY);
629

630
   _eldbus_model_proxy_start_monitor(pd);
631

632
   evt.changed_properties = properties;
633
   efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_PROPERTIES_CHANGED, &evt);
634
   while ((sp = eina_array_pop(properties)))
635
     eina_stringshare_del(sp);
636
   eina_array_free(properties);
637
}
638

639

640
static void
641
_eldbus_model_proxy_property_set_load_cb(void *data,
642
                                         const Eldbus_Message *msg,
643
                                         Eldbus_Pending *pending)
644
{
645
   Eldbus_Model_Proxy_Property_Set_Data *set_data = (Eldbus_Model_Proxy_Property_Set_Data *)data;
646
   Eldbus_Model_Proxy_Data *pd = set_data->pd;
647
   Eina_Array *properties;
648
   Eina_Stringshare *sp;
649
   const char *signature;
650

651
   pd->pendings = eina_list_remove(pd->pendings, pending);
652

653
   signature = _eldbus_model_proxy_property_type_get(pd, set_data->property);
654

655
   properties = _eldbus_model_proxy_property_get_all_load(msg, pd);
656
   if (!signature || !properties)
657
     {
658
        eina_promise_reject(set_data->promise, EFL_MODEL_ERROR_UNKNOWN);
659
        goto end;
660
     }
661

662
   pending = eldbus_proxy_property_value_set(pd->proxy, set_data->property,
663
                                             signature, set_data->value,
664
                                             _eldbus_model_proxy_property_set_cb, set_data);
665
   pd->pendings = eina_list_append(pd->pendings, pending);
666

667
end:
668
   if (!properties) return;
669
   while ((sp = eina_array_pop(properties)))
670
     eina_stringshare_del(sp);
671
   eina_array_free(properties);
672
}
673

674

675
static void
676
_eldbus_model_proxy_property_set_cb(void *data,
677
                                    const Eldbus_Message *msg,
678
                                    Eldbus_Pending *pending)
679
{
680
   Eldbus_Model_Proxy_Property_Set_Data *sd = (Eldbus_Model_Proxy_Property_Set_Data *)data;
681
   Eldbus_Model_Proxy_Data *pd = sd->pd;
682
   const char *error_name, *error_text;
683
   Eina_Value *value;
684

685
   pd->pendings = eina_list_remove(pd->pendings, pending);
686

687
   if (eldbus_message_error_get(msg, &error_name, &error_text))
688
     {
689
         ERR("%s: %s", error_name, error_text);
690
         eina_promise_reject(sd->promise, EFL_MODEL_ERROR_UNKNOWN);
691
         return;
692
     }
693

694
   value = eina_hash_find(pd->properties, sd->property);
695
   if (value)
696
     {
697
        efl_model_properties_changed(pd->obj, sd->property);
698
        if (sd->promise)
699
          eina_promise_resolve(sd->promise,
700
                               eina_value_reference_copy(value));
701
     }
702
   else
703
     {
704
        if (sd->promise)
705
          eina_promise_reject(sd->promise,
706
                              EFL_MODEL_ERROR_NOT_FOUND);
707
     }
708
}
709

710
static const char *
711
_eldbus_model_proxy_property_type_get(Eldbus_Model_Proxy_Data *pd,
712
                                      const char *property)
713
{
714
   Eldbus_Introspection_Property *property_introspection =
715
     eldbus_introspection_property_find(pd->interface->properties, property);
716

717
   if (property_introspection == NULL)
718
     {
719
        WRN("Property not found: %s", property);
720
        return NULL;
721
     }
722

723
   return property_introspection->type;
724
}
725

726
#include "eldbus_model_proxy.eo.c"
727

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.