summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/blink/event.rb9
-rw-r--r--lib/blink/transaction.rb43
-rw-r--r--lib/blink/transportable.rb42
-rw-r--r--lib/blink/type.rb50
-rw-r--r--lib/blink/type/component.rb16
-rw-r--r--lib/blink/type/typegen.rb3
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]