On Mon, Apr 10, 2017 at 7:46 PM, Gustavo Sverzut Barbieri
<barbi...@gmail.com> wrote:
> On Mon, Apr 10, 2017 at 7:12 PM, Cedric BAIL <cedric.b...@free.fr> wrote:
>> Finally something that we are not addressing yet, but would I think
>> make sense, is some way to describe simple layout (Like Android XML
>> file or Microsoft XAML). With Eo property it becomes quite easy to
>> automatically generate code for this.
>
> We're incurring in the same error as we did for EDC, thinking much of
> our side instead of users... EDC started as something for designers
> but then we never provided WYSIWYG and it sucked... the primitives are
> all there, but unusable for the naive or designers.
>
> the only way to describe this is to create a WYSIWYG first, then come
> with some format to store it... But do that as the *USER* point of
> view, not from EFL development PoV. Ignore our terms, ignore our
> limitations, try to make design use cases and then we see how to
> implement that with our tech, adding features and removing limitations
> as needed.

That's where I have a different opinion. Developers are bad with
WYSIWYG interface. Designers are the users of that potential WYSIWYG
interface. Problem is that in the population we are trying to address,
a large portion of them are developers without a sidekick designer.
They are the one who want to be able to do simple UI "assemblage" from
a file. EDC is way to complicated and powerful for what they want. We
actually do not have anything to address the needs of this people.
This is what I am talking above.

[...]

>> We have been iterating over a MVC design for more than a year now. I
>> think we are nearing a design that start to look good. The funny part
>> is when I was trying to find some presentation to explain people about
>> MVC and the difference with what we were doing, I stumble on Microsoft
>> MVVM design pattern which is pretty close to the design we have
>> selected. So we will rename the work we have done from ProxyModel to
>> ViewModel to use the same naming convention as everyone else.
>>
>> The main difference between MVC and MVVM is that it allow the
>> definition of a clean interface between View and Model. There isn't
>> really a ProxyModel or ViewModel interface, as they really are just a
>> Model that get data from another Model and interpret them into what
>> the View will actually display. This means you can easily reuse Model
>> and that you can test your Proxy/ViewModel without connecting it to an
>> actual View.
>>
>> And last very nice benefit, I think, is that you are defining a
>> "connection" for each parameter of your widget. So to connect a View
>> with a Model, you are only setting the model and indicating which
>> property to fetch on the model. No need to deal with callback in many
>> case ! For an example (which is broken at the moment) of the idea you
>> can look at layout_model_connect.c in efl elementary example.
>>
>> The most complex work will now be in writing this Proxy or View Model.
>> This is something we have to work on to make it easier.
>
> I've talked to you and felipe at IRC, I still think that the current
> Model is trying to address too much of "performance and async" at the
> level that it will suck for developers.
>
> to address the correct goal of "never block", what the current
> implementation does is make all property-get async, resulting in a
> promise... callback, etc. Whenever you need a simple:
>
>   if (model.a + model.b < model.c) do_bla(model);
>
> then you're screwed... you need to store these elsewhere, wait on 3
> callbacks, then execute what you want. Okay, helpers to accumulate and
> wait on all futures... then dispatch an array of values will be there,
> but still.
>
> caching is also left to outside. But to cache properly you need to
> know your information, access pattern, load coast, evict cost... Okay,
> applications may know better which information they are going to use,
> but they can hint that to model if needed (we could add a way to
> declare "hot properties").
>
> My suggestion is that we benefit from "models are live entities and
> always change", thus the users *MUST* monitor the changed events...
> and make all property getters/setters synchronous. However you may
> call a property get and receive a dummy value, which will trigger the
> fetch of real values, then emit "changed", which will likely trigger
> the code path again and that one will receive the actual values.

My main concern with this proposition is that it is very very easy to
write blocking code and it makes also the code of the model more
complex in the sense that you have to remember which request you are
currently answering and where your dummy values are. The reason we
push for a single API to fetch property is because we want to simplify
the logic by having just one pattern to be implemented in model.
Ideally this would mean that the monitoring is to be done solely by
the root model and the leaf.

I understand why you want to go with your model. It will by design
force us to implement a cache/dummy in each model, but this doesn't
mean you can't have a cache with promise/future as the method to
fetch. It will also provide an information to the View right away
(Even if not valid, it will have a default value). The idea in our
case is to set the default value on the View and maybe also the value
to be set in case of error (as an helper). This way if the real value
take some times to be fetch, it won't require multiple fetch of the
same value. The main difference is that we force people to always go
with an async model, this reduce the likeliness that someone will come
with some code that will stall the UI which is a real concern.

> example: FS model. walking a directory and generating children models
> will give you the filename and MAYBE the d_type (it may be
> DT_UNKNOWN). You know the rest of the model is sizeof(struct stat),
> which makes your Eo private data very small. Once a property get that
> needs 'stat()', then you return dummy values but trigger an
> async/thread/eio stat... that will give you ALL the fields (mode, uid,
> gid, size...). Unless object changes (ie: inotify), then no extra
> async call, promise/future are needed.
>
> compare this to the implementation where N calls to get("size"),
> get("mode"), get("uid"), get("gid") will result in N*4 promises/future
> pairs, N*4 callbacks...

We have been talking about providing an API for doing grouped fetch,
but pushed that to later as we don't think it will really impact
performance that much. We only fetch property that are actually
visible and used by a View. How many property will you fetch on one
screen ? And when it does become a problem, we can address that by
sending back an array, structure, hash, whatever for a group fetch. I
don't think it is an inherent problem.

> DB can be done like that as well. My experience with Canola running
> Python on a Maemo 770 (64mb ram, armv5) required us to do exactly
> that. DB access resulted in shallow objects, that were populated as
> needed. In our case, when a 10,000 song DB was queried, we would only
> call 'SELECT COUNT(*) FROM TABLE' and say we had 10,000 song without
> creating any actual children. Then when an index/slice/range was
> asked, we'd optimize block/group load ('LIMIT = X', X being multiple
> of 10, 100 or whatever). and only the important/cheap information,
> like Music title. Whenever the user asked for cover, length, artist...
> these would "pagefault" and load the values with individual 'SELECT',
> populating the model as needed.

We do have exactly that in our current model. We would set the count
and would fetch children for a given range too. There is indeed no
point into loading all of them and it critical to not load what has no
chance to be display by any View.

> This is also great approach when you have in-memory info, as you never
> generate async calls... say you're exposing Eet-decoded object in
> Efl_Model... what's the benefit of generating many promise/future?
> It's all in there, all memory is easily accessible. That's also the
> case for things like JSON, where you can tokenize and keep pointers to
> in-memory buffers, then it's a memcpy and some eventual decode (like
> parse the int/float... unescape strings...)

The point is to push people to write asynchronous code. EFL is able to
keep up with a UI at 60fps on a lot of hardware, but more often than
not we are pointed to code that perform poorly, because they didn't
implement it in an asynchronous way. Sure there is an overhead with
promise/future, but there is a overhead also with MVVM. What is the
benefit of using a data model in the case you describe ? Well,
reusability, clearer code construction, easier to extend... I think
this apply to make the fetching of property an asynchronous call to.
-- 
Cedric BAIL

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to