steveruizok
5/26/2018 - 10:34 AM

define.coffee

###
Define a property on a Layer that will emit a change event when that property changes. 
Also, optionally give the property an initial value and a callback to run when the property changes.

@param {Layer}		layer 		The layer on which to define the property.
@param {String}		property 	The name of the property.
@param {Object}		[value] 	The initial value of the property.
@param {Function}	[callback] 	The callback to run when this property changes. Executed with two arguments: the property's new value and the Layer itself.
@param {Function}	[validation] 	A function to validate the property's new value.
@param {String} 	[error] 	An error to throw if the validation function returned false.

@examples
Utils.define(myLayer, "toggled")
Utils.define(myLayer, "toggled", false)
Utils.define(myLayer, "toggled", false, myLayer.showToggled)
Utils.define(myLayer, "toggled", false, null, _.isBoolean, "Layer.toggled must be true or false.")

###

Utils.define = (layer, property, value, callback, validation, error) ->
	validation ?= -> true
	error ?= "Layer #{layer.id}'s property '#{property}' was given the wrong value type."
	
	Object.defineProperty layer,
		property,
		get: -> return layer["_#{property}"]
		set: (value) ->
			if value?
				if not validation(value) then throw error
				return if value is layer["_#{property}"]

			layer["_#{property}"] = value
			layer.emit("change:#{property}", value, layer)
		configurable: true
			
	if callback? and typeof callback is 'function'
		layer.on("change:#{property}", callback)
	
	layer[property] = value