class Build::Files::Monitor

def add(handle)

def add(handle)
	@logger.debug{"Adding handle: #{handle}"}
	
	handle.directories.each do |directory|
		@directories[directory] << handle
		
		# We just added the first handle:
		if @directories[directory].size == 1
			# If the handle already existed, this might trigger unnecessarily.
			@updated = true
		end
	end
	
	handle
end

def default_driver

def default_driver
	case RUBY_PLATFORM
	when /linux/i then :inotify
	when /darwin/i then :fsevent
	else :polling
	end
end

def delay_deletions

def delay_deletions
	@deletions = []
	
	yield
	
	@deletions.each do |handle|
		purge(handle)
	end
	
	@deletions = nil
end

def delete(handle)

def delete(handle)
	if @deletions
		@logger.debug{"Delayed delete handle: #{handle}"}
		@deletions << handle
	else
		purge(handle)
	end
end

def initialize(logger: nil)

def initialize(logger: nil)
	@directories = Hash.new { |hash, key| hash[key] = Set.new }
	
	@updated = false
	
	@deletions = nil
	
	@logger = logger || Logger.new(nil)
end

def purge(handle)

def purge(handle)
	@logger.debug{"Purge handle: #{handle}"}
	
	handle.directories.each do |directory|
		@directories[directory].delete(handle)
		
		# Remove the entire record if there are no handles:
		if @directories[directory].size == 0
			@directories.delete(directory)
			
			@updated = true
		end
	end
end

def roots

def roots
	@directories.keys
end

def run(options = {}, &block)

def run(options = {}, &block)
	if driver = (options[:driver] || default_driver)
		method_name = "run_with_#{driver}"
		Files.send(method_name, self, options, &block)
	else
		raise ArgumentError.new("Could not find driver for platform #{RUBY_PLATFORM}!")
	end
end

def track_changes(files, &block)

def track_changes(files, &block)
	handle = Handle.new(self, files, &block)
	
	add(handle)
end

def update(directories, *args)

Notify the monitor that files in these directories have changed.
def update(directories, *args)
	@logger.debug{"Update: #{directories} #{args.inspect}"}
	
	delay_deletions do
		directories.each do |directory|
			@logger.debug{"Directory: #{directory}"}
			
			@directories[directory].each do |handle|
				@logger.debug{"Handle changed: #{handle.inspect}"}
				
				# Changes here may not actually require an update to the handle:
				handle.changed!(*args)
			end
		end
	end
end