Skip to content

Commit

Permalink
Added working dependencies.
Browse files Browse the repository at this point in the history
  • Loading branch information
exerro committed Nov 16, 2015
1 parent b2ac06e commit 413ef1c
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 10 deletions.
14 changes: 14 additions & 0 deletions src/core/Sheet.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ function Sheet:Sheet( x, y, width, height )
self.style = Style( self )

self.canvas = DrawingCanvas( width, height )

-- @if SHEETS_DYNAMIC
local vendor = DynamicValueVendor( self )

vendor:addAttribute( "x", {}, self.setX )
vendor:addAttribute( "y", {}, self.setY )
vendor:addAttribute( "z", {}, self.setZ )
vendor:addAttribute( "width", {}, self.setWidth )
vendor:addAttribute( "height", {}, self.setHeight )
vendor:addAttribute( "style", {}, self.setStyle )
vendor:addAttribute( "parent", {}, self.setParent )

self.dynamic = vendor
-- @endif
end

function Sheet:setX( x )
Expand Down
4 changes: 2 additions & 2 deletions src/dynamic/BinaryExpression.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ function BinaryExpression:resolve( env )
local lvalue, rvalue = self.lvalue:resolve( env ), self.rvalue:resolve( env )

if type( lvalue ) ~= "number" then
Exception.throw( ParserException( "expected number lvalue, got " .. type( lvalue ), self.position ) )
Exception.throw( ExpressionException( "expected number lvalue, got " .. type( lvalue ), self.position ) )
elseif type( rvalue ) ~= "number" then
Exception.throw( ParserException( "expected string rvalue, got " .. type( rvalue ), self.position ) )
Exception.throw( ExpressionException( "expected string rvalue, got " .. type( rvalue ), self.position ) )
end

if self.operator == OPERATOR_BINARY_ADD then
Expand Down
181 changes: 181 additions & 0 deletions src/dynamic/DynamicValueVendor.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@

-- @once

-- @ifndef __INCLUDE_sheets
-- @error 'sheets' must be included before including 'sheets.dynamic.DynamicValueVendor'
-- @endif

-- @print Including sheets.dynamic.DynamicValueVendor

class "DynamicValueVendor" {
instance = nil;
objects = {};
attributes = {};
}

function DynamicValueVendor:DynamicValueVendor( instance )
if not class.isInstance( instance ) then
Exception.throw( IncorrectConstructorException( self.class:type() .. " expects Instance instance when created, got " .. class.type( instance ), 3 ) )
end

self.instance = instance
self.objects = {}
self.attributes = {}
end

function DynamicValueVendor:addAttribute( attribute, dependencies, setter, getter )
parameters.check( 4, "attribute", "string", attribute, "dependencies", dependencies and "table" or "nil", dependencies, "setter", setter and "function" or "nil", setter, "getter", getter and "function" or "nil", getter )

if self.attributes[attribute] then
self.attributes[attribute].setter = setter
self.attributes[attribute].getter = getter
else
self.attributes[attribute] = {
setter = setter;
getter = getter;
dependencies = {};
linked = {};
}
end

return self:setAttributeDependencies( attribute, dependencies )
end

function DynamicValueVendor:setAttributeDependencies( attribute, dependencies )
parameters.check( 2, "attribute", "string", attribute, "dependencies", dependencies and "table" or "nil", dependencies )

local attributes = self.attributes
local a = attributes[attribute]

if not a then
Exception.throw( DynamicValueException( "no such attribute '" .. attribute .. "'", 2 ) )
end

for i = 1, #a.dependencies do
attributes[a.dependencies[i]].linked[attribute] = nil
end

a.dependencies = {}

for i = 1, #dependencies do
if not attributes[dependencies[i]] then
Exception.throw( DynamicValueException( "no such dependency attribute '" .. attribute .. "'", 2 ) )
elseif a.linked[dependencies[i]] then
Exception.throw( DynamicValueException( "cyclic reference '" .. dependencies[i] .. "' <--> '" .. attribute .. "'", 2 ) )
elseif dependencies[i] == attribute then
Exception.throw( DynamicValueException( "self reference of '" .. attribute .. "'", 2 ) )
end

a.dependencies[i] = dependencies[i]
attributes[ dependencies[i] ].linked[attribute] = true
end

self:updateAttribute( attribute )
end

function DynamicValueVendor:setAttributeSetter( attribute, setter )
parameters.check( 2, "attribute", "string", attribute, "setter", setter and "function" or "nil", setter )

if not self.attributes[attribute] then
Exception.throw( DynamicValueException( "no such attribute '" .. attribute .. "'", 2 ) )
end

self.attributes[attribute].setter = setter

self:updateAttribute( attribute )
end

function DynamicValueVendor:setAttributeGetter( attribute, getter )
parameters.check( 2, "attribute", "string", attribute, "getter", getter and "function" or "nil", getter )

if not self.attributes[attribute] then
Exception.throw( DynamicValueException( "no such attribute '" .. attribute .. "'", 2 ) )
end

self.attributes[attribute].getter = getter

self:updateAttribute( attribute )
end

function DynamicValueVendor:removeAttribute( attribute )
parameters.check( 1, "attribute", "string", attribute )

if not self.attributes[attribute] then
return
end

local dependencies = self.attributes[attribute].dependencies
local linked = self.attributes[attribute].linked

for i = 1, #dependencies do
self.attributes[dependencies[i]].linked[attribute] = nil
end

local k, v = next( linked )
while k do
self:removeAttribute( k )
k, v = next( linked, k )
end

end

function DynamicValueVendor:updateAttribute( attribute )
parameters.check( 1, "attribute", "string", attribute )

return self:setAttribute( attribute, self:getAttribute( attribute ) )
end

function DynamicValueVendor:setAttribute( attribute, value )

parameters.check( 1, "attribute", "string", attribute )

if not self.attributes[attribute] then
Exception.throw( DynamicValueException( "no such attribute '" .. attribute .. "'", 2 ) )
end

local a = self.attributes[attribute]

if a.setter then
a.setter( self.instance, value )
else
self.instance[attribute] = value
end

local k, v = next( a.linked )
while k do
self:updateAttribute( k )
k, v = next( a.linked, k )
end

end

function DynamicValueVendor:getAttribute( attribute )

parameters.check( 1, "attribute", "string", attribute )

if not self.attributes[attribute] then
Exception.throw( DynamicValueException( "no such attribute '" .. attribute .. "'", 2 ) )
end

local a = self.attributes[attribute]

if a.getter then
return a.getter( self.instance )
else
return self.instance[attribute]
end

end

function DynamicValueVendor:wrapSetter( attribute )

parameters.check( 1, "attribute", "string", attribute )

return function( instance, value )
return self:setAttribute( attribute, value )
end

end

DynamicValueVendor.set = DynamicValueVendor.setAttribute
DynamicValueVendor.get = DynamicValueVendor.getAttribute
2 changes: 1 addition & 1 deletion src/dynamic/UnaryLeftExpression.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function UnaryLeftExpression:resolve( env )
if type( rvalue ) == "string" then
return #rvalue
else
Exception.throw( ParserException( "expected string rvalue, got " .. type( rvalue ), self.position ) )
Exception.throw( ExpressionException( "expected string rvalue, got " .. type( rvalue ), self.position ) )
end
elseif operator == OPERATOR_UNARY_NOT then
return not rvalue
Expand Down
14 changes: 14 additions & 0 deletions src/exceptions/DynamicValueException.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

-- @once

-- @ifndef __INCLUDE_sheets
-- @error 'sheets' must be included before including 'sheets.exceptions.DynamicValueException'
-- @endif

-- @print Including sheets.exceptions.DynamicValueException

class "DynamicValueException" extends "Exception"

function DynamicValueException:DynamicValueException( data, level )
return self:Exception( "DynamicValueException", data, level )
end
18 changes: 15 additions & 3 deletions src/exceptions/ExpressionException.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,20 @@

-- @print Including sheets.exceptions.ExpressionException

class "ExpressionException" extends "Exception"
class "ExpressionException" extends "Exception" {
position = nil;
}

function ExpressionException:ExpressionException( data, level )
return self:Exception( "ExpressionException", data, level )
function ExpressionException:ExpressionException( data, position )
parameters.checkConstructor( self.class, 1, "position", TokenPosition, position )
self.position = position
return self:Exception( "ExpressionException", data, 0 )
end

function ExpressionException:getData()
if type( self.data ) == "string" or class.isClass( self.data ) or class.isInstance( self.data ) then
return self.position:tostring() .. ": " .. tostring( self.data )
else
return self.position:tostring() .. ": " .. textutils.serialize( seld.data )
end
end
15 changes: 11 additions & 4 deletions src/sheets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
-- @defineifndef SHEETS_DEFAULT_TRANSITION_EASING "transition"
-- @defineifndef SHEETS_MINIFY
-- @defineifndef SHEETS_PARSING
-- @defineifndef SHEETS_SML
-- @defineifndef SHEETS_DYNAMIC
-- @defineifndef SHEETS_DYNAMIC_PARSING
-- @defineifndef SHEETS_SML

-- @if SHEETS_SML
-- @if SHEETS_DYNAMIC_PARSING
-- @define SHEETS_PARSING
-- @elif SHEETS_DYNAMIC
-- @define SHEETS_DYNAMIC
-- @elif SHEETS_SML
-- @define SHEETS_PARSING
-- @endif

Expand Down Expand Up @@ -107,7 +109,7 @@
-- @define TOKEN_OPERATOR "operator"
-- @endif

-- @if SHEETS_DYNAMIC
-- @if SHEETS_DYNAMIC_PARSING
-- @define OPERATOR_UNARY_MINUS 0
-- @define OPERATOR_UNARY_LEN 1
-- @define OPERATOR_UNARY_NOT 2
Expand Down Expand Up @@ -246,6 +248,11 @@ colour = {
-- @endif

-- @if SHEETS_DYNAMIC
-- @require sheets.exceptions.DynamicValueException
-- @require sheets.dynamic.DynamicValueVendor
-- @endif

-- @if SHEETS_DYNAMIC_PARSING
-- @require sheets.exceptions.ExpressionException
-- @require sheets.dynamic.ExpressionParser
-- @require sheets.dynamic.ExpressionEnvironment
Expand Down

0 comments on commit 413ef1c

Please sign in to comment.