# $Id: s.Singleton.xotcl 1.5 01/03/23 21:55:33+01:00 neumann@somewhere.wu-wien.ac.at $
package provide xotcl::pattern::singleton 0.8

Class SingletonBase
SingletonBase instproc getInstance args {
  [self] instvar _instance 
  if {[info exists _instance]} {
    return $_instance
  }
  return ""
} 


#
# A simple pattern mixin that makes a class to a non-specializable singleton
#
Class NonSpecializableSingleton -superclass SingletonBase

NonSpecializableSingleton instproc create args {
  [self] instvar _instance
  if {![info exists _instance]} {
    set _instance [self]
    next
  }
  return $_instance
}

NonSpecializableSingleton instproc getInstance {} {
  if {[info exists _instance]} {
    [self] instvar _instance
    return $_instance
  }
  return ""
}

#
# Specializable Singleton 
#
Class Singleton -superclass {SingletonBase Class}
Singleton instproc singletonFilter args {
  switch -exact [self calledproc] {
    init {
      [self regclass] instvar _instance
      if {![info exists _instance]} {
	set _instance [self]
	next
      } else {
	[self] destroy
      }
      return $_instance
    }
    default {
      return [next]
    }
  }
}

Singleton instproc init args {
  [self] filterappend Singleton::singletonFilter
  #
  # specialized singletons have to look up the singleton class
  # first
  Class instproc getInstance {} {
    foreach sc [[self] info superclass] {
      if {[$sc info class] == "::Singleton"} {
	return [$sc getInstance]
      } else {
	return ""
      }
    }
  }
  next
}

    