#lang racket/base
;;; SPDX-License-Identifier: LGPL-3.0-or-later
;;; SPDX-FileCopyrightText: Copyright © 2016-2021 Tony Garnock-Jones <tonyg@leastfixedpoint.com>

(provide field?
         (rename-out [make-field field])
         field-name
         field-id)

(require "dataflow.rkt")
(require "support/counter.rkt")

(struct field (name ;; Symbol
               id ;; Nat
               dataflow ;; Dataflow
               [value #:mutable] ;; Any
               )
  #:methods gen:custom-write
  [(define (write-proc f port mode)
     (fprintf f "#<field:~a:~a>" (field-id f) (field-name f)))]
  #:property prop:procedure
  (case-lambda
    [(f)
     (dataflow-record-observation! (field-dataflow f) f)
     (field-value f)]
    [(f new-value)
     (when (not (equal? (field-value f) new-value))
       (dataflow-record-damage! (field-dataflow f) f)
       (set-field-value! f new-value))]))

(define generate-field-id (make-counter))

(define (make-field dataflow name initial-value)
  (field name
         (generate-field-id)
         dataflow
         initial-value))
