|
174 | 174 | (property-type-name property))) |
175 | 175 | (error "invalid value for property" (property-name property)))))) |
176 | 176 |
|
177 | | -(define (make-class type-name parent . properties) |
178 | | - (let ((new-class (list type-name parent properties))) |
| 177 | +(define (make-class type-name parent properties . opts) |
| 178 | + ; opts is an alist of (option-name . option-value) pairs, e.g. |
| 179 | + ; ((after-copy . mesh_after_copy) (after-destroy . mesh_after_destroy)). |
| 180 | + ; Recognised options are 'after-copy and 'after-destroy, each a C function |
| 181 | + ; name (symbol) that gen-ctl-io invokes from the generated <type>_copy / |
| 182 | + ; <type>_destroy bodies. Unknown options are accepted and ignored to keep |
| 183 | + ; this loosely versioned across libctl / gen-ctl-io / consumer combos. |
| 184 | + (let ((new-class (list type-name parent properties opts))) |
179 | 185 | (set! class-list (cons new-class class-list)) |
180 | 186 | new-class)) |
181 | 187 | (define (class-type-name class) (first class)) |
182 | 188 | (define (class-parent class) (second class)) |
183 | 189 | (define (class-properties class) (third class)) |
| 190 | +(define (class-options class) |
| 191 | + (if (>= (length class) 4) (fourth class) '())) |
| 192 | +(define (class-option class key) |
| 193 | + (assoc-ref (class-options class) key)) |
| 194 | +(define (class-after-copy class) (class-option class 'after-copy)) |
| 195 | +(define (class-after-destroy class) (class-option class 'after-destroy)) |
184 | 196 | (define (class-properties-all class) |
185 | 197 | (append (class-properties class) |
186 | 198 | (let ((parent (class-parent class))) |
|
276 | 288 | ; code above. |
277 | 289 |
|
278 | 290 | (defmacro-public define-class (class-name parent . properties) |
279 | | - (let ((pdefs (map |
280 | | - (lambda (p) |
281 | | - (let ((name (cadr p)) |
282 | | - (type-name (cadddr p))) |
283 | | - `(define ,name |
284 | | - (type-property-value-constructor |
285 | | - ,type-name (quote ,name))))) |
286 | | - (list-transform-positive properties |
287 | | - (lambda (p) (eq? (car p) 'define-property))))) |
288 | | - (ppdefs (map |
| 291 | + (let* ((class-option-form? |
| 292 | + (lambda (p) (and (pair? p) |
| 293 | + (memq (car p) '(after-copy after-destroy))))) |
| 294 | + (option-forms (list-transform-positive properties class-option-form?)) |
| 295 | + (non-option-forms (list-transform-negative properties class-option-form?)) |
| 296 | + (pdefs (map |
289 | 297 | (lambda (p) |
290 | 298 | (let ((name (cadr p)) |
291 | | - (type-name (cadddr p)) |
292 | | - (post-process-func (list-ref p 4))) |
293 | | - `(define ,name (post-processing-constructor |
294 | | - ,post-process-func |
295 | | - (type-property-value-constructor |
296 | | - ,type-name (quote ,name)))))) |
297 | | - (list-transform-positive properties |
298 | | - (lambda (p) |
299 | | - (eq? (car p) 'define-post-processed-property))))) |
300 | | - (props (map |
301 | | - (lambda (p) |
302 | | - (cond |
303 | | - ((eq? (car p) 'define-property) |
| 299 | + (type-name (cadddr p))) |
| 300 | + `(define ,name |
| 301 | + (type-property-value-constructor |
| 302 | + ,type-name (quote ,name))))) |
| 303 | + (list-transform-positive non-option-forms |
| 304 | + (lambda (p) (eq? (car p) 'define-property))))) |
| 305 | + (ppdefs (map |
| 306 | + (lambda (p) |
304 | 307 | (let ((name (cadr p)) |
305 | | - (default (caddr p)) |
306 | 308 | (type-name (cadddr p)) |
307 | | - (constraints (cddddr p))) |
308 | | - `(make-property (quote ,name) ,type-name ,default |
309 | | - not-derived ,@constraints))) |
310 | | - ((eq? (car p) 'define-post-processed-property) |
311 | | - (let ((name (cadr p)) |
312 | | - (default (caddr p)) |
313 | | - (type-name (cadddr p)) |
314 | | - (post-process-func (list-ref p 4)) |
315 | | - (constraints (cdr (cddddr p)))) |
316 | | - `(make-property (quote ,name) ,type-name ,default |
317 | | - not-derived ,@constraints))) |
318 | | - (else p))) |
319 | | - properties))) |
| 309 | + (post-process-func (list-ref p 4))) |
| 310 | + `(define ,name (post-processing-constructor |
| 311 | + ,post-process-func |
| 312 | + (type-property-value-constructor |
| 313 | + ,type-name (quote ,name)))))) |
| 314 | + (list-transform-positive non-option-forms |
| 315 | + (lambda (p) |
| 316 | + (eq? (car p) 'define-post-processed-property))))) |
| 317 | + (props (map |
| 318 | + (lambda (p) |
| 319 | + (cond |
| 320 | + ((eq? (car p) 'define-property) |
| 321 | + (let ((name (cadr p)) |
| 322 | + (default (caddr p)) |
| 323 | + (type-name (cadddr p)) |
| 324 | + (constraints (cddddr p))) |
| 325 | + `(make-property (quote ,name) ,type-name ,default |
| 326 | + not-derived ,@constraints))) |
| 327 | + ((eq? (car p) 'define-post-processed-property) |
| 328 | + (let ((name (cadr p)) |
| 329 | + (default (caddr p)) |
| 330 | + (type-name (cadddr p)) |
| 331 | + (post-process-func (list-ref p 4)) |
| 332 | + (constraints (cdr (cddddr p)))) |
| 333 | + `(make-property (quote ,name) ,type-name ,default |
| 334 | + not-derived ,@constraints))) |
| 335 | + (else p))) |
| 336 | + non-option-forms)) |
| 337 | + (opt-args (map (lambda (o) |
| 338 | + `(cons (quote ,(car o)) (quote ,(cadr o)))) |
| 339 | + option-forms))) |
320 | 340 | `(begin |
321 | 341 | ,@pdefs |
322 | 342 | ,@ppdefs |
323 | 343 | (define ,class-name (make-class (quote ,class-name) |
324 | 344 | ,parent |
325 | | - ,@props))))) |
| 345 | + (list ,@props) |
| 346 | + ,@opt-args))))) |
0 commit comments