Source frame_utils.nas
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
#---------------------------------------------------------------------------
#
# 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;
}
}
},
};