-
Notifications
You must be signed in to change notification settings - Fork 1
/
virtual_property.coffee
101 lines (91 loc) · 2.35 KB
/
virtual_property.coffee
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
AS = require("alpha_simprini")
_ = require "underscore"
AS.Model.VirtualProperty = AS.Model.Field.extend ({def}) ->
# @::initialize.doc =
# params: [
# ["@name", String, true]
# ["@_constructor", AS.Object, true]
# ["@options", Object, true]
# ]
# desc: """
#
# """
def initialize: (@name, @_constructor, @options={}) ->
@options.name = @name
@dependencies = @options.dependencies
@_constructor.writeInheritableValue 'properties', @name, this
# @::instance.doc =
# params: [
# ["object", AS.Model, true]
# ]
# desc: """
#
# """
def instance: (object) -> @constructor.Instance.new(object, @options)
NULL_CACHE = new Object
AS.Model.VirtualProperty.Instance = AS.Property.Instance.extend ({def}) ->
# @::initialize.doc =
# params: [
# ["@object", AS.Model, true]
# ["@options", Object, true]
# ]
# desc: """
#
# """
def initialize: (@object, @options) ->
@cached = NULL_CACHE
@bindDependencies()
# @::bindDependencies.doc =
# desc: """
#
# """
def bindDependencies: ->
for dependency in @options.dependencies
@object[dependency].addDependant(this)
# @::set.doc =
# params: [
# [value, "*", true]
# ]
# desc: """
#
# """
def set: (value) ->
if set = @options.getSet.set
set.call(@object, value)
else
throw "Can't set a VirtualProperty name: #{@options.name}, dependencies: #{@options.dependencies.join(',')}"
# @::get.doc =
# return: "*"
# desc: """
#
# """
def get: -> @cached = @compute()
# @::compute.doc =
# private: true
# params: [
# []
# ]
# desc: """
#
# """
def compute: (args) -> @options.getSet.get.call(@object)
# @::triggerFor.doc =
# private: true
# desc: """
#
# """
def triggerFor: () ->
# JUST LET THINGS GO TO HELL. WE NEED A RUNLOOP AND DIRTY TRACKING I GUESS ):(
# computed = @compute()
# return if @cached is computed
# @cached = computed
@trigger("change")
@object.trigger("change")
@object.trigger("change:#{@options.name}")
AS.Model.defs virtualProperties: (dependencies..., properties) ->
for name, fn of properties
if _.isFunction(fn)
getSet = {get: fn}
else
getSet = fn
AS.Model.VirtualProperty.new(name, this, dependencies: dependencies, getSet: getSet)