|
| 1 | +;+ |
| 2 | +; |
| 3 | +; Simple object template that, by default, allows you to use the dot |
| 4 | +; notation to modify object properties. This works the same way that |
| 5 | +; dictionaries and many ENVI objects operate. |
| 6 | +; |
| 7 | +; To use the template, you will simply need to replace all instances |
| 8 | +; of "objectTemplate" with the name of your object. This also means |
| 9 | +; that the name of the file will need to be updates as well. |
| 10 | +; |
| 11 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 12 | +;- |
| 13 | + |
| 14 | + |
| 15 | +;+ |
| 16 | +; :Description: |
| 17 | +; Init function for our object so that we can call the |
| 18 | +; object directly as a function instead of needing to use |
| 19 | +; the obj_new() function |
| 20 | +; |
| 21 | +; |
| 22 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 23 | +;- |
| 24 | +function objectTemplate::Init |
| 25 | + compile_opt idl2, hidden |
| 26 | + |
| 27 | + ;here you should initialize static object properties such as |
| 28 | + ;default values and the _initialize method can set properties |
| 29 | + ;that are based on user input or something else |
| 30 | + |
| 31 | + ;initialize our dynamic object properties |
| 32 | + self._Initialize |
| 33 | + |
| 34 | + ;we succeeded, so return one for a valid object |
| 35 | + return, 1 |
| 36 | +end |
| 37 | + |
| 38 | +;+ |
| 39 | +; :Description: |
| 40 | +; Simple procedure to initialize all of the properties of the object |
| 41 | +; to their default values. |
| 42 | +; |
| 43 | +; |
| 44 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 45 | +;- |
| 46 | +pro objectTemplate::_Initialize |
| 47 | + compile_opt idl2, hidden |
| 48 | + |
| 49 | +end |
| 50 | + |
| 51 | + |
| 52 | +;+ |
| 53 | +; :Description: |
| 54 | +; Object method for eny custom cleanup actions that we may need. |
| 55 | +; |
| 56 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 57 | +; |
| 58 | +;- |
| 59 | +pro objectTemplate::Cleanup |
| 60 | + compile_opt idl2, hidden |
| 61 | + |
| 62 | + |
| 63 | + |
| 64 | +end |
| 65 | + |
| 66 | + |
| 67 | +;+ |
| 68 | +; :Description: |
| 69 | +; Get property method that works with the "dot" notation. |
| 70 | +; |
| 71 | +; |
| 72 | +; :Keywords: |
| 73 | +; _REF_EXTRA: in, requried, type=assorted |
| 74 | +; Allowed properties are any object definition parameters. |
| 75 | +; |
| 76 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 77 | +;- |
| 78 | +pro objectTemplate::GetProperty, _REF_EXTRA=extra |
| 79 | + compile_opt idl2, hidden |
| 80 | + on_error, 2 |
| 81 | + |
| 82 | + if (extra ne !NULL) then begin |
| 83 | + ;get self tag names, first three are related to IDL_Object and not needed |
| 84 | + properties = (tag_names(self))[3:*] |
| 85 | + |
| 86 | + ;check if property we are getting exists |
| 87 | + foreach property, strupcase(extra) do begin |
| 88 | + prop_idx = (where(property eq properties, is_prop))[0] |
| 89 | + ;property exists, return it |
| 90 | + if (is_prop eq 1) then begin |
| 91 | + currentvalue = self.(3 + prop_idx) |
| 92 | + |
| 93 | + case (1) of |
| 94 | + isa(currentvalue, 'list') OR isa(currentvalue, 'hash'):begin |
| 95 | + (scope_varfetch(property, /REF_EXTRA)) = currentvalue |
| 96 | + end |
| 97 | + |
| 98 | + (currentValue eq !NULL):begin |
| 99 | + (scope_varfetch(property, /REF_EXTRA)) = !NULL |
| 100 | + end |
| 101 | + |
| 102 | + isa(currentvalue, 'pointer'):begin |
| 103 | + (scope_varfetch(property, /REF_EXTRA)) = *currentvalue |
| 104 | + end |
| 105 | + |
| 106 | + else:begin |
| 107 | + (scope_varfetch(property, /REF_EXTRA)) = currentvalue |
| 108 | + end |
| 109 | + endcase |
| 110 | + endif else begin |
| 111 | + message, 'Property "' + property + '" is not a valid object property!' |
| 112 | + endelse |
| 113 | + endforeach |
| 114 | + end |
| 115 | +end |
| 116 | + |
| 117 | + |
| 118 | +; :Description: |
| 119 | +; Wrapper method for overloading implied print which uses the |
| 120 | +; same method as the _overloadPrint method. |
| 121 | +; |
| 122 | +; |
| 123 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 124 | +;- |
| 125 | +function objectTemplate::_OverloadImpliedPrint, varname |
| 126 | + compile_opt idl2, hidden |
| 127 | + return, self->objectTemplate::_overloadPrint() |
| 128 | +end |
| 129 | + |
| 130 | + |
| 131 | +;+ |
| 132 | +; :Description: |
| 133 | +; Object method for overloading printing and getting some basic information |
| 134 | +; from our crop centers object. |
| 135 | +; |
| 136 | +; |
| 137 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 138 | +;- |
| 139 | +function objectTemplate::_OverloadPrint |
| 140 | + compile_opt idl2, hidden |
| 141 | + tags = tag_names(self) |
| 142 | + sorted = sort(tags[3:*]) |
| 143 | + output = list() |
| 144 | + |
| 145 | + ;determine the number of white spaces we need to add |
| 146 | + maxlen = max(strlen(tags)) + 6 |
| 147 | + |
| 148 | + for k=0,n_elements(sorted)-1 do begin |
| 149 | + i = 3 + sorted[k] |
| 150 | + help, self.(i), OUTPUT=o |
| 151 | + split = strsplit(o, /EXTRACT) |
| 152 | + type = split[1] |
| 153 | + add = '' |
| 154 | + for j=0, maxlen-strlen(tags[i]) do add += ' ' |
| 155 | + output.add, string(9b) + strupcase(tags[i]) + add + type |
| 156 | + |
| 157 | + case 1 of |
| 158 | + isa(self.(i), 'LIST'):begin |
| 159 | + help, self.(i), OUTPUT = o |
| 160 | + type = strjoin((strsplit(o, /EXTRACT))[1:*], ' ') |
| 161 | + output.add, string(9b) + string(9b) + type |
| 162 | + end |
| 163 | + isa(self.(i), 'HASH'):begin |
| 164 | + help, self.(i), OUTPUT = o |
| 165 | + type = strjoin((strsplit(o, /EXTRACT))[1:*], ' ') |
| 166 | + output.add, string(9b) + string(9b) + type |
| 167 | + end |
| 168 | + (self.(i) eq !NULL):begin |
| 169 | + output.add, string(9b) + string(9b) + '!NULL' |
| 170 | + end |
| 171 | + isa(self.(i), 'OBJREF'):begin |
| 172 | + printed = string(self.(i), /IMPLIED_PRINT) |
| 173 | + foreach line, printed do output.add, string(9b) + string(9b) + line |
| 174 | + end |
| 175 | + isa(self.(i), 'POINTER'):begin |
| 176 | + help, *(self.(i)), OUTPUT=o |
| 177 | + split = (strsplit(o, /EXTRACT))[1:-1] |
| 178 | + if isa(split, 'LIST') then split = split.toarray() |
| 179 | + type = strjoin(split[1:*], ' ') |
| 180 | + output.add, string(9b) + string(9b) + type |
| 181 | + end |
| 182 | + else:begin |
| 183 | + output.add, string(9b) + string(9b) + strjoin(strtrim(self.(i),2),' ') |
| 184 | + end |
| 185 | + endcase |
| 186 | + endfor |
| 187 | + |
| 188 | + return, strjoin(output.toarray(), string(10b)) |
| 189 | +end |
| 190 | + |
| 191 | +;+ |
| 192 | +; :Description: |
| 193 | +; Set property method that works with the ".dot" notation. |
| 194 | +; |
| 195 | +; |
| 196 | +; :Keywords: |
| 197 | +; _REF_EXTRA: in, requried, type=assorted |
| 198 | +; Set keywords that match object properties in the object definition. |
| 199 | +; |
| 200 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 201 | +;- |
| 202 | +pro objectTemplate::SetProperty, _REF_EXTRA = extra |
| 203 | + compile_opt idl2, hidden |
| 204 | + on_error, 2 |
| 205 | + |
| 206 | + if (extra ne !NULL) then begin |
| 207 | + ;get self tag names, first three are related to IDL_Object and not needed |
| 208 | + properties = (tag_names(self))[3:*] |
| 209 | + |
| 210 | + ;check if property we are setting exists |
| 211 | + foreach property, strupcase(extra) do begin |
| 212 | + prop_idx = (where(property eq properties , is_prop))[0] |
| 213 | + ;property exists, set it |
| 214 | + if (is_prop eq 1) then begin |
| 215 | + new_value = scope_varfetch(property, /REF_EXTRA) |
| 216 | + self._SetProperty, property, prop_idx, new_value |
| 217 | + endif else begin |
| 218 | + message, 'Property "' + property + '" is not a valid object property!' |
| 219 | + endelse |
| 220 | + endforeach |
| 221 | + endif |
| 222 | +end |
| 223 | + |
| 224 | +;+ |
| 225 | +; :Description: |
| 226 | +; Underlying set property method for this object so we don't have to have a |
| 227 | +; separate one at init and setproprty |
| 228 | +; |
| 229 | +; :Params: |
| 230 | +; property: name of property |
| 231 | +; prop_idx: index of property in structure |
| 232 | +; new_value: new value to replace the property with |
| 233 | +; |
| 234 | +; |
| 235 | +; |
| 236 | +; :Author: Zachary Norman - GitHub: znorman17 |
| 237 | +;- |
| 238 | +pro objectTemplate::_SetProperty, property, prop_idx, new_value |
| 239 | + compile_opt idl2, hidden |
| 240 | + ;check if we have a pointer or not |
| 241 | + currentvalue = self.(3 + prop_idx) |
| 242 | + |
| 243 | + ;check if we are resetting a certain property which only works for |
| 244 | + ;strings, pointers, and objects otherwise structures are too strict |
| 245 | + ;to try and change the currentvalue |
| 246 | + if (new_value eq !NULL) then begin |
| 247 | + old_value = self.(3 + prop_idx) |
| 248 | + case 1 of |
| 249 | + (old_value.typecode eq 7): self.(3 + prop_idx) = '' |
| 250 | + (old_value.typecode eq 10): self.(3 + prop_idx) = ptr_new() |
| 251 | + (old_value.typecode eq 11): self.(3 + prop_idx) = obj_new() |
| 252 | + else: begin |
| 253 | + message, 'Cannot set property "' + property + '" to !NULL because the datatype (' + strtrim(type,2) + ') will not allow it!' |
| 254 | + end |
| 255 | + endcase |
| 256 | + ;not setting the variable to !NULL |
| 257 | + endif else begin |
| 258 | + ;special checks for the property that we are setting |
| 259 | + ;these are examples for how to can create custom routines |
| 260 | + case property of |
| 261 | + 'PROP1':begin |
| 262 | + |
| 263 | + end |
| 264 | + 'PROP2':begin |
| 265 | + |
| 266 | + end |
| 267 | + else:begin |
| 268 | + ;default set property |
| 269 | + if ISA(currentvalue, 'pointer') then begin |
| 270 | + self.(3 + prop_idx) = ptr_new(new_value) |
| 271 | + endif else begin |
| 272 | + self.(3 + prop_idx) = new_value |
| 273 | + endelse |
| 274 | + endelse |
| 275 | + endcase |
| 276 | + endelse |
| 277 | +end |
| 278 | + |
| 279 | +;+ |
| 280 | +; :Description: |
| 281 | +; Object definition. |
| 282 | +; |
| 283 | +; |
| 284 | +; :Author: Zachary Norman - znorman@harris.com |
| 285 | +;- |
| 286 | +pro objectTemplate__define |
| 287 | + compile_opt idl2 |
| 288 | + |
| 289 | + compile_opt idl2, hidden |
| 290 | + struct = {ObjectTemplate, $ |
| 291 | + inherits IDL_Object,$ |
| 292 | + |
| 293 | + } |
| 294 | +end |
0 commit comments