lib/knj/objects.rb in knjrbfw-0.0.23 vs lib/knj/objects.rb in knjrbfw-0.0.24
- old
+ new
@@ -13,15 +13,13 @@
@args[:module] = Kernel if !@args[:module]
@args[:cache] = :weak if !@args.key?(:cache)
@objects = {}
@locks = {}
@data = {}
- @mutex_require = Mutex.new
+ @lock_require = Monitor.new
- if @args[:cache] == :weak
- require "#{$knjpath}wref"
- end
+ require "#{$knjpath}wref" if @args[:cache] == :weak
@events = Knj::Event_handler.new
@events.add_event(
:name => :no_html,
:connections_max => 1
@@ -32,10 +30,14 @@
)
@events.add_event(
:name => :missing_class,
:connections_max => 1
)
+ @events.add_event(
+ :name => :require_class,
+ :connections_max => 1
+ )
raise "No DB given." if !@args[:db] and !@args[:custom]
raise "No class path given." if !@args[:class_path] and (@args[:require] or !@args.key?(:require))
if args[:require_all]
@@ -70,10 +72,15 @@
end
@locks[classname] = Mutex.new
end
+ def uninit_class(classname)
+ @objects.delete(classname)
+ @locks.delete(classname)
+ end
+
#Returns a cloned version of the @objects variable. Cloned because iteration on it may crash some of the other methods in Ruby 1.9+
def objects
objs_cloned = {}
@objects.keys.each do |key|
@@ -147,19 +154,35 @@
def requireclass(classname, args = {})
classname = classname.to_sym
return false if @objects.key?(classname)
- @mutex_require.synchronize do
+ @lock_require.synchronize do
#Maybe the classname got required meanwhile the synchronized wait - check again.
return false if @objects.key?(classname)
- if (@args[:require] or !@args.key?(:require)) and (!args.key?(:require) or args[:require])
- filename = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}.rb"
- filename_req = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}"
- raise "Class file could not be found: #{filename}." if !File.exists?(filename)
- require filename_req
+ if @events.connected?(:require_class)
+ @events.call(:require_class, {
+ :class => classname
+ })
+ else
+ doreq = false
+
+ if args[:require]
+ doreq = true
+ elsif args.key?(:require) and !args[:require]
+ doreq = false
+ elsif @args[:require] or !@args.key?(:require)
+ doreq = true
+ end
+
+ if doreq
+ filename = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}.rb"
+ filename_req = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}"
+ raise "Class file could not be found: #{filename}." if !File.exists?(filename)
+ require filename_req
+ end
end
if args[:class]
classob = args[:class]
else
@@ -225,11 +248,11 @@
self.requireclass(classname) if !@objects.key?(classname)
@locks[classname].synchronize do
#Maybe the object got spawned while we waited for the lock? If so we shouldnt spawn another instance.
- if obj = @objects[classname].get!(id) and obj.id.to_i == id
+ if @args[:cache] == :weak and obj = @objects[classname].get!(id) and obj.id.to_i == id
return obj
end
#Spawn object.
if @args[:datarow] or @args[:custom]
@@ -259,10 +282,11 @@
@objects[classname].delete(id)
@objects_idclass.delete(id)
end
end
+ #Returns the first object found from the given arguments. Also automatically limits the results to 1.
def get_by(classname, args = {})
classname = classname.to_sym
self.requireclass(classname)
classob = @args[:module].const_get(classname)
@@ -342,10 +366,14 @@
if args[:addnew] or args[:add]
html << "<option"
html << " selected=\"selected\"" if !args[:selected]
html << " value=\"\">#{_("Add new")}</option>"
+ elsif args[:none]
+ html << "<option"
+ html << " selected=\"selected\"" if !args[:selected]
+ html << " value=\"\">#{_("None")}</option>"
end
self.list(classname, args[:list_args]) do |object|
html << "<option value=\"#{object.id.html}\""
@@ -459,10 +487,11 @@
end
end
#Add a new object to the database and to the cache.
def add(classname, data = {})
+ raise "data-variable was not a hash: '#{data.class.name}'." if !data.is_a?(Hash)
classname = classname.to_sym
self.requireclass(classname)
if @args[:datarow]
classobj = @args[:module].const_get(classname)
@@ -592,10 +621,13 @@
@objects.delete(classname)
end
#Delete an object. Both from the database and from the cache.
def delete(object)
+ #Return false if the object has already been deleted.
+ return false if object.deleted?
+
self.call("object" => object, "signal" => "delete_before")
self.unset(object)
obj_id = object.id
object.delete if object.respond_to?(:delete)
@@ -635,9 +667,10 @@
end
else
arr_ids = []
ids = []
objs.each do |obj|
+ next if obj.deleted?
ids << obj.id
if ids.length >= 1000
arr_ids << ids
ids = []
end
\ No newline at end of file