summaryrefslogtreecommitdiff
path: root/src/lib/emodel/emodel.eo
blob: 39fccf239c94f6a42c18408869f30e1958882b7f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/*
 * type Emodel_Load_Status: enum _Emodel_Load_Status
 * {
 *    EMODEL_LOAD_STATUS_ERROR = 0, /*@ Error in Load Model *
 *    EMODEL_LOAD_STATUS_LOADING_PROPERTIES = (1 << 0), /*@ properties load in progress *
 *    EMODEL_LOAD_STATUS_LOADING_CHILDREN =   (1 << 1), /*@ children load in progress *
 *    EMODEL_LOAD_STATUS_LOADING = (1 << 0) | (1 << 1), /*@ children and properties load in progress *
 *
 *    EMODEL_LOAD_STATUS_LOADED_PROPERTIES = (1 << 2), /*@ Model as ready to fetch properties *
 *    EMODEL_LOAD_STATUS_LOADED_CHILDREN =   (1 << 3), /*@ Model as ready to fetch children *
 *    EMODEL_LOAD_STATUS_LOADED = (1 << 2) | (1 << 3), /*@ Model as ready to fetch properties and children *
 *
 *    EMODEL_LOAD_STATUS_UNLOADING = (1 << 4), /*@ Model Unload in progress *
 *    EMODEL_LOAD_STATUS_UNLOADED =  (1 << 5)  /*@ Model Unloaded *
 * }
 *
 * type Emodel_Property_Pair: struct _Emodel_Property_Pair
 * {
 *  value: Eina_Value; /*@ the new property value *
 *  property: const(char)*; /*@ the property name that has been changed *
 * }
 *
 * type Emodel_Property_Event: struct _Emodel_Property_Event
 * {
 *  changed_properties: Eina_List* <Emodel_Property_Pair*>; /*@ List of changed properties *
 *  invalidated_properties: Eina_List* <const(char)*>; /*@ Removed properties identified by name *
 * }
 */

interface Emodel ()
{
   legacy_prefix: null;
      properties {
         load_status {
            get {
            /*@
             Get a load emodel current status.

             @return: @c Emodel_Load_Status

             By convention this means get the current model status.
             Possible values are defined Emodel_Load_Status enumerator.

             @see Emodel_Load_Status
             @see emodel_load

             @since 1.11 */
             return: Emodel_Load_Status;
            }
         }
         properties_list {
            get {
                /*@
                Get properties list from model.

              @return: @c Emodel_Load_Status

                properties_list_get is due to provide callers a way the fetch the current
                properties implemented/used by the model.
                The event EMODEL_EVENT_PROPERTIES_CHANGE will be raised to notify listeners
                of any modifications in the properties list.

                @see EMODEL_EVENT_PROPERTIES_CHANGE
                @since 1.11 */

                return: Emodel_Load_Status;
         }
         values {
               const(list<const(char*)>*) properties_list; /*@ list of current properties */
            }
        }
         property {
            set {
                /*@
                Set a property value of a given property name.

                @return: @c EINA_TRUE, on success, @c EINA_FALSE in readonly property or error

                The caller must ensure to call at least emodel_prop_list before being
                able to see/set properties.
                This function sets a new property value into given property name. Once
                the operation is completed the concrete implementation should raise
                EMODEL_EVENT_PROPERTIES_CHANGE event in order to notify listeners of the
                new value of the property.

                If the model doesn't have the property then there are two possibilities,
                either raise an error or create the new property in model

                @see emodel_property_get
                @see EMODEL_EVENT_PROPERTIES_CHANGE
                @since 1.11 */

                return: Emodel_Load_Status;
            }
            get {
                /*@
                Retrieve the value of a given property name.

                @return: @c Load Status, on success, @c EMODEL_LOAD_STATUS_ERROR otherwise

                property_get will only be available when load status is equal to
                EMODEL_LOAD_STATUS_LOADED.

                At this point the caller is free to get values from properties.
                The event EMODEL_EVENT_PROPERTIES_CHANGE may be raised to notify
                listeners of the property/value.

                @see emodel_properties_list_get
                @see EMODEL_EVENT_PROPERTIES_CHANGE

                @since 1.11 */
                return: Emodel_Load_Status;
             }
             keys {
               const(char)* property; /*@ Property name */
             }
             values {
               Eina_Value value; /*@ New value */
             }
         }
         children_slice {
            get {
               /*@
               Get children slice OR full range.

               @return: @c Emodel_Load_Status. See below for more info.

               Before being able to get the children list the model status must be
               on loaded status (EMODEL_LOAD_STATUS_LOADED).
               However there may be circunstancies where the model could be
               in a different state, in such cases it is advisable
               to simply return: its current state, which will be
               of course, different than @c EMODEL_LOAD_STATUS_LOADED_CHILDREN.
               When children accessor is return:ed as NULL one should then
               test the current load status return:ed by @children_slice_get
               in order to check against an empty list or real error.

               children_slice_get behaves in two different ways, it may provide
               the slice if both @c start AND @c count are non-zero OR full range otherwise.

               The return:ed Eina_Accessor must be freed when it is no longer needed and
               eo_unref() must be invoked for children if caller wants a copy.

               Since 'slice' is a range, for example if we have 20 childs a slice could be
               the range from 3(start) to 4(count), see:
               child 0  [no]
               child 1  [no]
               child 2  [yes]
               child 3  [yes]
               child 4  [yes]
               child 5  [yes]
               child 6  [no]
               child 7  [no]

               Optionally the user can call children_count_get to know
               the number of children so a valid range can be known in advance.

               Below are examples of both usage types: slices and full ranges.
               @code

               // Returns full list
               eo_do(obj, emodel_children_slice_get(0, 0, &children_accessor));

               // Returns 5 items, counting from item #5
               eo_do(obj, emodel_children_slice_get(5, 5, &children_accessor));

               @endcode

               @see emodel_children_get
               @see emodel_children_count_get
               @see emodel_load
               @see emodel_load_status_get
               @since 1.11 */

               return: Emodel_Load_Status;
            }
            keys {
                unsigned start; /*@ Range begin - start from here. If start and count are 0 slice is ignored.*/
                unsigned count; /*@ Range size. If count and start are 0 slice is ignored.*/
            }
            values {
                accessor<list*>* children_accessor;
            }
         }
         children_count {
             get {
                /*@
                Get children count.

                @return: @c EINA_TRUE, on success, @c EINA_FALSE otherwise

                When emodel_load is completed emodel_coildren_count_get can be use
                to get the number of children. children_count_get can also be used
                before calling children_slice_get so a valid range is known.
                Event EMODEL_CHILDREN_COUNT_CHANGED is emitted when count is finished.

                @see emodel_children_get
                @see emodel_children_slice_get
                @see emodel_load
                @see emodel_load_status_get
                @since 1.11 */

                return: Emodel_Load_Status;
             }
            values {
                unsigned children_count;
            }
         }
      }
      methods {
         load {
            /*@
              Load emodel.

              By convention this means loading data from an external source and populating
              the models properties and children with it. For example in the case of file
              system backed model, this means opening the relevant files and reading the
              data from them(creating the properties and children from it).
              the model emit EMODEL_EVENT_LOAD_STATUS after end with Emodel_Load_Status
              @warning This convention should be followed, but no guarantees of behaviour
              by user defined types can be given.

              Alternatively is possible to use properties_load to load only properties
              and children_load to load only children. If emodel_load is called then
              calling properties_load and/or children_load is not necessary.

              @see Emodel_Load_Status
              @see emodel_properties_load
              @see emodel_children_load
              @see emodel_unload
              @see emodel_load_status_get

              @since 1.11 */
         }
         unload {
            /*@
              Unload emodel.

              By convention this means releasing data received/read from an external source. For
              example of a database backed model this might mean releasing the iterator for
              the currently loaded data or deleting a temporary table.
              the model emit EMODEL_EVENT_LOAD_STATUS after end with model load status
              @warning This convention should be followed, but no guarantees of behaviour
              by user defined types can be given.

              @see Emodel_Load_Status
              @see emodel_load
              @see emodel_load_status_get

              @since 1.11 */
         }
         properties_load {
            /*@
              Properties emodel load.

              By convention this means loading data from an external source and populating
              the models properties only. This method is a subset of emodel_load, meaning that
              it won't load children, it is a hint.
              For loadind both properties and children use emodel_load
              instead.

              @see emodel_load

              @since 1.11 */
         }
         children_load {
            /*@
              Children emodel load.

              By convention this means loading data from an external source and populating
              the models children only. This method is a subset of emodel_load, meaning that
              it won't load properties. For loadind both properties and children use emodel_load
              instead.

              @see emodel_load

              @since 1.11 */
         }
         child_add {
            /*@
              Add a new child.

              @return: @c Emodel* on success, @c NULL otherwise

              Add a new child, possibly dummy, depending on the implementation,
              of a internal keeping. When the child is effectively
              added the event EMODEL_EVENT_CHILD_ADD is then raised and the new child
              is kept along with other children.

              @see EMODEL_EVENT_CHILD_ADD
              @see load_status_get

              @since 1.11 */

            return: Eo *;
         }
         child_del {
            /*@
              Remove a child.

              @return: @c Emodel_Load_Status on success, @c EMODEL_LOAD_STATUS_ERROR otherwise.

              Remove a child of a internal keeping. When the child is effectively
              removed the event EMODEL_EVENT_CHILD_REMOVED is then raised to give a
              chance for listeners to perform any cleanup and/or update references.

              @see EMODEL_EVENT_CHILD_REMOVED
              @since 1.11 */

              return: Emodel_Load_Status;

            params {
               @in Eo* child; /*@ Child to be removed */
            }
         }
      }

   events {
      load,status: Emodel_Load_Status; /*@ Event dispatch when load status changes */
      properties,changed: Emodel_Properties_Evt; /*@ Event dispatched when properties list is available. */
      child,added; /*@ Event dispatched when new child is added. */
      child,removed; /*@ Event dispatched when child is removed. */
      children,count,changed; /*@ Event dispatched when children count is finished. */
   }
}