Jetpack/Collections

< Jetpack
Revision as of 15:20, 28 January 2012 by BenB (talk | contribs) (First spec)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Collections

This describes a future module that will have a coherent set of collection/list classes, with a common API, similar to java.util.Collection.

  • Base API implemented by all collections
    • similar to java.util.Collection probably
    • with observers to allow you to subscribe to changes and be notified when items are added or remoted
    • Ability to specify identity and sorting for items, e.g. "if |id| property matches, it's the same item" and "sort on |name| property" or "if a.name > b.name, then a > b"
  • Operators on the collections
 * Operate on whole lists, e.g. allItems = add(serverItems, localItems);
 * Follow the observers
 * add
 * subtract
 * sort
  • Some basic collection implementations
 * Array - ordered list of items, integer-indexed - based on JS Array
 * Map - key/value pair - based on JS Object properties
 * OrderedMap - allows fast lookup
 * Set
 * OrderedMap
 * Others can live in third-party modules, but if they adhere to the common APi, they would fit in nicely
  • UI
 * Listbox, tree node childred etc. all could accept such lists
 * E.g. listbox.showList(allItems)
 * The UI then updates automatically based on changes of the underlying list, and the programmer doesn't have to think about it.
 * The API of the UI then wouldn't need "add/remoteItem" functions.
  • Other classes
 * Pretty much anything that takes a list in Jetpack could be using this API, at least optionally.

Example

Show only those server items which are not in local items, i.e. only offer new stuff

var serverItems = new JArray(); serverItems.add(itemA); serverItems.add(itemB); var localItems = listAllMyItems(path); var offerItems = subtract(serverItems, localItems); var listbox = E("itemsList"); listbox.showList(offerItems);

That's all already. Now, when items are added to serverItems, they automatically appear in the list UI (without any further app code), *unless* they are in localItems.

That's because the subtract operator automatically subscribed to changes in serverItems. If you then later do serverItems.add(itemC), the subtract operator would check whether the same items is in localItem, and only if it's not, it would add it to offerItems. listbox.showList() in turn automatically subscribed to changes in offerItems, gets notified about the new item there, and shows it. All of that would happen just with the above code lines, there is no additional code needed to follow updates.

Of course, if you wanted to show both serverItems and localItems in the UI, you would do |add()| instead of |substract()|.

This means that you don't need additional wiring to make the UI update after the user (or server) did add/remove item actions, you only need to update the underlying lists.

Implementation

  • Ben Bucksch will provide API, base implementation, and operators
  • M.-A. Darche will provide OrderedMap and possibly Set and OrderedSet
  • Others are welcome to make UI elements support these collections.

Feedback needed

Comparation of items

How to specify identity and sorting for items, e.g. "if |id| property matches, it's the same item" and "sort on |name| property" or "if a.name > b.name, then a > b"

Options:

  • base class for items -- convenient, but doesn't allow to collect objects not supporting this API, also doesn't allow to specify different sorting based on situation
  • Operators and Set and Ordered* collections take functions that can compare the objects -- cumbersome, because it needs to be specified for every use
  • specify id and sortBy properties or -- more convenient
  • specify isSameObject() and isGreaterThan() functions - more flexible