#--------------------------------------------------------------------------- # # Title : Frame Utils # # File Type : Implementation File # # Description : Objects related to frame processing # # Author : Richard Harrison (richard@zaretto.com) # # Creation Date : 05-05-2019 # # Version : 1.0 # # Copyright (C) 2019 Richard Harrison Released under GPL V2 # #---------------------------------------------------------------------------*/ #---------------------------------------------------------------------------*/ # Partition data and process # # This manages the processing of data in a manner suitable for real time # operations. Given a data array [0..size] this will process a number # of array elements each time it is called This allows for a simple way # to split up intensive processing across multiple frames. # # The limit is the number of elements to process per invocation or # a specific amount of time. # # To limit the amount of time requires a timestamp object to be set using # the set_timestamp method and then to set the maximum amount of # time (in microseconds) by calling set_max_time_usec. A value of 500us is # a good value to use - but it is upto the implementor to choose a value that # is suited to their environment # # Usually one of more instances of this class will be contained within # another object, however this will work equally well in global space. # # example usage (object); # # var VSD_Device = # { # new : func(designation, model_element, target_module_id, root_node) # { # ... # obj.process_targets = PartitionProcessor.new("VSD-targets", 20, nil); # obj.process_targets.set_max_time_usec(500); # ... # me.process_targets.set_timestamp(notification.Timestamp); # # then invoke. # me.process_targets.process(me, awg_9.tgts_list, # func(pp, obj, data){ # # initialisation; called before processing element[0] # # params # # pp is the partition processor that called this # # obj is the reference object (first argument in the .process) # # data is the entire data array. # } # , # func(pp, obj, element){ # # proces individual element; # # params # # pp is the partition processor that called this # # obj is the reference object (first argument in the .process) # # element is the element data[pp.data_index] # # return 0 to stop processing any more elements and call the completed method # # return 1 to continue processing. # }, # func(pp, obj, data) # { # # completed; called after the last element processed # # params # # pp is the partition processor that called this # # obj is the reference object (first argument in the .process) # # data is the entire data array. # }); var PartitionProcessor = { debug_output : 0, new : func(_name, _size, _timestamp=nil){ var obj = { parents : [PartitionProcessor], data_index : 0, ppos : 0, name : _name, end : 0, partition_size : _size, timestamp : _timestamp, max_time_usec : 0, }; return obj; }, set_max_time_usec : func(_maxTimeUsec){ me.max_time_usec = _maxTimeUsec; }, set_timestamp : func(_timestamp){ me.timestamp = _timestamp; }, process : func (object, data, init_method, process_method, complete_method){ if (me.end != size(data)) { # data changed during processing restart at the beginning. me.data_index = 0; } if (me.data_index == 0) { me.end = size(data); init_method(me, object, data); } if (me.end == 0) return; me.start_pos = me.data_index; if (me.timestamp != nil and me.max_time_usec > 0) { me.start_time = me.timestamp.elapsedUSec(); me.end_time = me.start_time + me.max_time_usec; } else { me.start_time = 0; me.end_time = 0; } for (me.ppos=0;me.ppos < me.partition_size; me.ppos += 1) { if (me.data_index >= me.end) { complete_method(me, object, data); me.data_index = 0; return; } if (!process_method(me, object, data[me.data_index])) { complete_method(me, object, data); me.data_index = 0; return; # halt processing requested. } else me.data_index += 1; if (me.data_index == me.start_pos) { complete_method(me, object, data); return; } if (me.end_time > 0 and me.timestamp.elapsedUSec() > me.end_time) { if (PartitionProcessor.debug_output) printf("PartitionProcessor: [%s] out of time %dus (processed# %d)",me.name, me.timestamp.elapsedUSec() - me.start_time, me.ppos); return; } } }, };