Sha256: 08845b3d7794d587f22ea96ed83af48458d52df687a89fa097dadd37596a5102

Contents?: true

Size: 1.7 KB

Versions: 396

Compression:

Stored size: 1.7 KB

Contents

module React
  alias CellValue = Int32

  abstract class Cell
    @dependents = [] of ComputeCell

    def initialize(initial : CellValue)
      @value = initial
    end

    getter :value

    protected getter :dependents
  end

  class InputCell < Cell
    def value=(new_value : CellValue)
      @value = new_value
      @dependents.each(&.propagate)
      @dependents.each(&.fire_callbacks)
    end
  end

  class ComputeCell < Cell
    alias CallbackID = Int32

    @callbacks_given = 0
    @callbacks = {} of CallbackID => CellValue ->
    @last_callback_value : CellValue

    def initialize(input : Cell, &compute : CellValue -> CellValue)
      initialize(->{ compute.call(input.value) }, input)
    end

    def initialize(input1 : Cell, input2 : Cell, &compute : (CellValue, CellValue) -> CellValue)
      initialize(->{ compute.call(input1.value, input2.value) }, input1, input2)
    end

    private def initialize(@new_value : -> CellValue, *dependencies : Cell)
      super(@new_value.call)
      @last_callback_value = @value
      dependencies.each { |i| i.dependents << self }
    end

    def add_callback(&block : CellValue ->) : CallbackID
      @callbacks_given += 1
      @callbacks[@callbacks_given] = block
      @callbacks_given
    end

    def remove_callback(id : CallbackID)
      @callbacks.delete(id)
    end

    protected def propagate
      new_value = @new_value.call
      return if new_value == @value
      @value = new_value
      @dependents.each(&.propagate)
    end

    protected def fire_callbacks
      return if @value == @last_callback_value
      @last_callback_value = @value
      @callbacks.each_value { |c| c.call(@value) }
      @dependents.each(&.fire_callbacks)
    end
  end
end

Version data entries

396 entries across 396 versions & 1 rubygems

Version Path
trackler-2.2.1.180 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.179 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.178 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.177 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.176 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.175 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.174 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.173 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.172 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.171 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.170 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.169 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.167 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.166 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.165 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.164 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.163 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.162 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.161 tracks/crystal/exercises/react/src/example.cr
trackler-2.2.1.160 tracks/crystal/exercises/react/src/example.cr