Copyright © 2009, 2010 Arndt Roger Schneider
Although hugelist has constant complexity, it still doesn't suffice for volatile data; neither for distributed systems, where the data source is a remote machine and all data has to be send via network to the display.
The idea behind on-demand data acquisition is to delay any data gathering until the data is displayed. The application’s logic layer won't be littered with data replication code, too.
A short time frame is used after each user interaction, to gather the next data chunk. This time frame should not exceed 210ms; 70ms to see, 70ms to understand and 70ms to act for the user. This 210ms have to suffice for every kind of data acquisition.
On-demand data gathering is an integral feature of hugelist starting with version 1.5.
On-demand data gathering is controlled by the -ondemandcommand property. ondemandcommand accepts a Tcl-procedure as its value. These procedure gets called for every item, immediately before the item is displayed. Three item properties are being queried via ondemandcommand: text, image and vector.
The ID in Example 3, “ondemandcommand Signature” is the value at the position listindex in the hugelist internal listvariable.
Example 4. Using On-demand
proc cmd {t h k i d} { if ![regexp {image|text|vector} $$t] { error [concat "Unknown Item type $t," \ " must be »image«, »text« or »vector«!"] } switch $t { image { # return an image for item $k at index $i } text { # return a string for item $k at index $i } vector { # return a vector for item $k at index $i } default {} } # return the given default value # $d is identical with k for type text. return $d }
hugelist::create .ondemandlist \ -ondemandcommand cmd ...
itemconfigure and itemcget operate on the hugelist internal stored data. The listvariable values are thus the identifiers (ID) inside the model. Non of the queried data is being stored inside the hugelist! Thus:
itemconfigure 1 -text xyz
replaces the ID at index 1 with xyz; xyz is then queried for with cmd.
hugelist 1.4 does not had the ability for on-demand data acquisition, but it can be added. Example 5, “Virtual Listbox: Inject” and Example 6, “Virtual Listbox: make Inject” display two Tcl-procedures, which are used to release a »trace« on an internal hugelist storage, for injecting on-demand data acquisition into an hugelist.
Example 5. Virtual Listbox: Inject
proc inject { name cmd args } { #set DEBUG_LEVEL -1 rtl::debug stdout "injected code" rtl::seteach { kind listbox } [split $name :] set ID [lindex $args 0] set lname [winfo name $listbox] rtl::verified { # Here the new data is injected into the # hugelist. set ::hugelist::(${listbox}:values) \ [lreplace $::hugelist::(${listbox}:values) \ $ID $ID "$lname item $ID" ] } stdout { Query is out of range: $info } return [eval [concat ::ranges::dispatch \ $name $cmd $args]] }
Example 5, “Virtual Listbox: Inject” is responsible to query for the necessary data and to replace it inside the hugelist. Inside inject the ID –the index inside the listbox variable– is used to identify the data and the storage location in the hugelist.
Example 6. Virtual Listbox: make Inject
proc makeinject {name {cmd inject}} { trace remove command $name delete \ [list ::ranges::dispose $name] interp alias {} $name \ {} $cmd $name }
Example 6, “Virtual Listbox: make Inject” is a service procedure which releases the »trace« for a given internal storage facility and to extend it with »inject«.
Example 7. Virtual Listbox
toplevel .top -width 200p -height 200p hugelist::create .top.hugelist # Turn the hugelist into a virtual listbox. makeinject wranges:.top.hugelist pack .top.hugelist
Example 7, “Virtual Listbox” shows how both Example 5, “Virtual Listbox: Inject” and Example 6, “Virtual Listbox: make Inject” are used with a hugelist. The newly traced procedure »inject« is hence called together with »hugelist::display« and queries »inject« for each to be visible item.