# hotpage.rb # # $Id: hotpage.rb,v 1.4 2002/04/19 12:39:42 seki Exp $ # Copyright (c) 2002 NAKAMURA, Hiroshi # # hotpage.rb is copyrighted free software by NAKAMURA, Hiroshi # You can redistribute it and/or modify it under the same term as Ruby. # module HotPageMixIn def initialize( &hot_order ) @hot_order = hot_order || HotPageMixIn.method( :default_hot_order ) @dirty = false @pages = [] @notify = nil end def pages if dirty? update unset_dirty end @pages end def __pages collect_pages end def include?( item ) include_item?( item ) end def <<( arg ) add( arg ) self end def add( arg ) add_item( arg ) set_dirty end def delete( arg ) delete_item( arg ) set_dirty end def replace( rhs ) replace_item( rhs ) set_dirty end def notify=( notify ) @notify = notify end def set_dirty @dirty = true @notify.call if @notify end private def collect_pages raise NotImplementedError.new( "Method 'collect_pages' must be defined in derived class." ) end def update raise NotImplementedError.new( "Method 'update' must be defined in derived class." ) end def include_item?( arg ) raise NotImplementedError.new( "Method 'include_item?' must be defined in derived class." ) end def add_item( arg ) raise NotImplementedError.new( "Method 'add_item' must be defined in derived class." ) end def delete_item( arg ) raise NotImplementedError.new( "Method 'delete_item' must be defined in derived class." ) end def replace_item( rhs ) raise NotImplementedError.new( "Method 'replace_item' must be defined in derived class." ) end def dirty? @dirty end def unset_dirty @dirty = false end def hot_order( names ) names.sort( &@hot_order ) end def HotPageMixIn.default_hot_order( a, b ) a <=> b end end class HotPageContainer; include HotPageMixIn def initialize super @member = [] end private def collect_pages pages = [] @member.each do | m | pages.concat( m.__pages ) end pages end def update @pages = hot_order( collect_pages ) end def include_item?( item ) @member.each do | m | if m.include?( item ) return true end end false end def add_item( hotpage ) if !hotpage.is_a?( HotPageMixIn ) raise ArgumentError.new( "Each argument must be a HotPageMixIn." ) end hotpage.notify = self.method( :set_dirty ) @member << hotpage end def delete_item( hotpage ) @member.delete( hotpage ) end def replace_item( rhs ) @member.replace( rhs ) end end class HotPage; include HotPageMixIn private def collect_pages @pages end def update @pages = hot_order( @pages ) end def include_item?( item ) @pages.include?( item ) end def add_item( page ) @pages << page end def delete_item( page ) @pages.delete( page ) end def replace_item( rhs ) @pages.replace( rhs ) end end