diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/blink/event.rb | 9 | ||||
-rw-r--r-- | lib/blink/transaction.rb | 43 | ||||
-rw-r--r-- | lib/blink/transportable.rb | 42 | ||||
-rw-r--r-- | lib/blink/type.rb | 50 | ||||
-rw-r--r-- | lib/blink/type/component.rb | 16 | ||||
-rw-r--r-- | lib/blink/type/typegen.rb | 3 |
6 files changed, 120 insertions, 43 deletions
diff --git a/lib/blink/event.rb b/lib/blink/event.rb index 99b922930..2cdda9976 100644 --- a/lib/blink/event.rb +++ b/lib/blink/event.rb @@ -37,10 +37,10 @@ module Blink # the last, a later-refreshed object could somehow be connected # to the "old" object rather than "new" # but we're pretty far from that being a problem - if transaction.triggered(self) > 1 + if transaction.triggercount(self) > 0 Blink.verbose "%s has already run" % self else - Blink.verbose "'%s' generated '%s'; triggering '%s' on '%s'" % + Blink.verbose "'%s' matched '%s'; triggering '%s' on '%s'" % [@source,@event,@method,@target] begin if @target.respond_to?(@method) @@ -53,12 +53,13 @@ module Blink # um, what the heck do i do when an object fails to refresh? # shouldn't that result in the transaction rolling back? # XXX yeah, it should - Blink.error "'%s' failed to refresh: '%s'" % - [@target,detail] + Blink.error "'%s' failed to %s: '%s'" % + [@target,@method,detail] raise #raise "We need to roll '%s' transaction back" % #transaction end + transaction.triggered(self) end end end diff --git a/lib/blink/transaction.rb b/lib/blink/transaction.rb index 56d1268b5..245c07445 100644 --- a/lib/blink/transaction.rb +++ b/lib/blink/transaction.rb @@ -15,7 +15,7 @@ require 'blink/statechange' #--------------------------------------------------------------- module Blink class Transaction - attr_accessor :toplevel + attr_accessor :toplevel, :component #--------------------------------------------------------------- # a bit of a gross hack; a global list of objects that have failed to sync, @@ -43,11 +43,12 @@ class Transaction def evaluate Blink.notice "executing %s changes or transactions" % @changes.length - @changes.each { |change| + return @changes.collect { |change| if change.is_a?(Blink::StateChange) change.transaction = self + events = nil begin - change.forward + events = [change.forward].flatten #@@changed.push change.state.parent rescue => detail Blink.error("%s failed: %s" % [change,detail]) @@ -58,26 +59,26 @@ class Transaction # this still could get hairy; what if file contents changed, # but a chmod failed? how would i handle that error? dern end + + # first handle the subscriptions on individual objects + events.each { |event| + change.state.parent.subscribers?(event).each { |sub| + sub.trigger(self) + } + } + events elsif change.is_a?(Blink::Transaction) - # yay, recursion change.evaluate else raise "Transactions cannot handle objects of type %s" % child.class end + }.flatten.each { |event| + # this handles subscriptions on the components, rather than + # on idividual objects + self.component.subscribers?(event).each { |sub| + sub.trigger(self) + } } - - if @toplevel # if we're the top transaction, perform the refreshes - Blink::Event.process - #notifies = @@changed.uniq.collect { |object| - # object.notify - #}.flatten.uniq - - # now we have the entire list of objects to notify - else - Blink.notice "I'm not top-level" - # these are the objects that need to be refreshed - #return @refresh.uniq - end end #--------------------------------------------------------------- @@ -137,8 +138,16 @@ class Transaction #--------------------------------------------------------------- #--------------------------------------------------------------- + def triggercount(sub) + Blink.notice "Triggercount on %s is %s" % [sub,@triggered[sub]] + return @triggered[sub] + end + #--------------------------------------------------------------- + + #--------------------------------------------------------------- def triggered(sub) @triggered[sub] += 1 + Blink.notice "%s was triggered; count is %s" % [sub,@triggered[sub]] end #--------------------------------------------------------------- end diff --git a/lib/blink/transportable.rb b/lib/blink/transportable.rb index d7ca9d5e3..522a34d7c 100644 --- a/lib/blink/transportable.rb +++ b/lib/blink/transportable.rb @@ -103,10 +103,43 @@ module Blink class TransBucket < Array attr_accessor :name, :type + def push(*args) + args.each { |arg| + case arg + when Blink::TransBucket, Blink::TransObject, Blink::TransSetting + # nada + else + raise "TransBuckets cannot handle objects of type %s" % + arg.class + end + } + super + end + def to_type # this container will contain the equivalent of all objects at # this level - container = Blink::Component.new + #container = Blink::Component.new(:name => @name, :type => @type) + unless defined? @name + raise "TransBuckets must have names" + end + unless defined? @type + Blink.verbose "TransBucket '%s' has no type" % @name + end + hash = { + :name => @name, + :type => @type + } + if defined? @parameters + @parameters.each { |param,value| + Blink.warning "Defining %s on %s of type %s" % + [param,@name,@type] + hash[param] = value + } + else + Blink.warning "%s has no parameters" % @name + end + container = Blink::Component.new(hash) nametable = {} self.each { |child| @@ -155,6 +188,13 @@ module Blink return container end + def param(param,value) + unless defined? @parameters + @parameters = {} + end + @parameters[param] = value + end + end #------------------------------------------------------------ end diff --git a/lib/blink/type.rb b/lib/blink/type.rb index f603c5e24..b08acdc49 100644 --- a/lib/blink/type.rb +++ b/lib/blink/type.rb @@ -236,9 +236,9 @@ class Blink::Type < Blink::Element end if @objects.has_key?(newobj.name) - puts @objects - raise "Object '%s' of type '%s' already exists" % - [newobj.name,newobj.class.name] + raise "Object '%s' of type '%s' already exists with id '%s' vs. '%s'" % + [newobj.name,newobj.class.name, + @objects[newobj.name].object_id,newobj.object_id] else #Blink.debug("adding %s of type %s to class list" % # [object.name,object.class]) @@ -366,6 +366,9 @@ class Blink::Type < Blink::Element #--------------------------------------------------------------- def Type.validparameter(name) + unless defined? @parameters + raise "Class %s has not defined parameters" % self + end return @parameters.include?(name) end #--------------------------------------------------------------- @@ -458,6 +461,8 @@ class Blink::Type < Blink::Element @children = [] @evalcount = 0 + @subscriptions = [] + # states and parameters are treated equivalently from the outside: # as name-value pairs (using [] and []=) # internally, however, parameters are merely a hash, while states @@ -708,9 +713,26 @@ class Blink::Type < Blink::Element #--------------------------------------------------------------- #--------------------------------------------------------------- - def metaonerror(response) - Blink.debug("Would have called metaonerror") - @onerror = response + def subscribe(hash) + if hash[:event] == '*' + hash[:event] = :ALL_EVENTS + end + + hash[:source] = self + sub = Blink::Event::Subscription.new(hash) + + # add to the correct area + @subscriptions.push sub + end + #--------------------------------------------------------------- + + #--------------------------------------------------------------- + # return all of the subscriptions to a given event + def subscribers?(event) + @subscriptions.find_all { |sub| + sub.event == event.event or + sub.event == :ALL_EVENTS + } end #--------------------------------------------------------------- @@ -737,8 +759,9 @@ class Blink::Type < Blink::Element [name,type] end Blink.debug("%s requires %s" % [self.name,object]) - Blink::Event.subscribe( - :source => object, + + # for now, we only support this one method, 'refresh' + object.subscribe( :event => '*', :target => self, :method => :refresh @@ -749,14 +772,9 @@ class Blink::Type < Blink::Element #--------------------------------------------------------------- #--------------------------------------------------------------- - def addnotify(object) - @notify.push object - end - #--------------------------------------------------------------- - - #--------------------------------------------------------------- - def notify - @notify + def metaonerror(response) + Blink.debug("Would have called metaonerror") + @onerror = response end #--------------------------------------------------------------- diff --git a/lib/blink/type/component.rb b/lib/blink/type/component.rb index d675474f6..63c89497a 100644 --- a/lib/blink/type/component.rb +++ b/lib/blink/type/component.rb @@ -17,15 +17,16 @@ module Blink @namevar = :name @states = [] - @parameters = [:name] + @parameters = [:name,:type] def each @children.each { |child| yield child } end - def initialize(*args) + def initialize(args) @children = [] - super + super(args) + Blink.verbose "Made component with name %s" % self.name end # now we decide whether a transaction is dumb, and just accepts @@ -33,8 +34,9 @@ module Blink # for now, because i've already got this implemented, let transactions # collect the changes themselves def evaluate - return transaction = Blink::Transaction.new(@children) - #transaction.run + transaction = Blink::Transaction.new(@children) + transaction.component = self + return transaction end def push(*ary) @@ -47,6 +49,10 @@ module Blink } end + def name + return "%s[%s]" % [@parameters[:type],@parameters[:name]] + end + def retrieve self.collect { |child| child.retrieve diff --git a/lib/blink/type/typegen.rb b/lib/blink/type/typegen.rb index 104e79aef..85f04912c 100644 --- a/lib/blink/type/typegen.rb +++ b/lib/blink/type/typegen.rb @@ -16,6 +16,9 @@ class TypeGenerator < Blink::Type @name = :typegen @abstract = true + @parameters = [:name] + @states = [] + #--------------------------------------------------------------- def TypeGenerator.[](name) return @subclasses[name] |