Model.st
author Claus Gittinger <cg@exept.de>
Wed, 29 May 1996 00:43:39 +0200
changeset 278 f2382bb48850
parent 238 a179b5d6152e
child 318 097d70e8163f
permissions -rw-r--r--
intitial checkin

"
 COPYRIGHT (c) 1992 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

Object subclass:#Model
	instanceVariableNames:'dependents'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Support-Models'
!

!Model class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1992 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    Models are things which represent information models, i.e. something
    which holds the data for user interface components and on which these operate.
    Basically, instances keep track of which components depend on them and 
    inform the dependents of any changes.

    The Model class itself is abstract and not too useful, see subclasses,
    especially, ValueHolder and SelectionInList.

    Notice:
      Actually the Model class is not really needed; since the dependency
      mechanism is inherited by Object, you can take any object as a model.
      However, instances of Model (and subclasses) keep the dependents locally
      in an instance variable; thus speeding up access a bit.

    [Instance variables:]
        dependents      <Collection>    those objects which depend on me.
                                        To save some storage, a single dependent 
                                        is kept directly here.
                                        Otherwise, if there are multiple dependents,
                                        a collection of dependents is held here.

    [author:]
        Claus Gittinger

    [see also:]
        ValueHolder SelectionInList
        ( introduction to view programming :html: programming/viewintro.html#MVC )
"
! !

!Model methodsFor:'copying'!

postCopy
    "release dependents after copying"

    self dependents:nil
! !

!Model methodsFor:'dependents access'!

addDependent:anObject
    "make the argument, anObject be a dependent of the receiver"

    [
        |deps|

        deps := dependents.
        "/
        "/ store the very first dependent directly in
        "/ the dependents instVar
        "/
        (deps isNil and:[anObject isCollection not]) ifTrue:[
            dependents := anObject
        ] ifFalse:[
            "/
            "/ store more dependents in the dependents collection
            "/
            deps isCollection ifTrue:[
                deps add:anObject
            ] ifFalse:[
                dependents := IdentitySet with:dependents with:anObject
            ]
        ]
    ] valueUninterruptably

    "Modified: 19.4.1996 / 12:24:46 / cg"
!

dependents
    "return a Collection of dependents - nil if there is none"

    dependents isNil ifTrue:[^ nil].
    dependents isCollection ifTrue:[
        ^ dependents
    ].
    ^ IdentitySet with:dependents

    "Modified: 19.4.1996 / 12:22:04 / cg"
!

dependents:aCollection
    "set the collection of dependents"

    |dep|

    aCollection size == 1 ifTrue:[
        dep := aCollection first.
        dep isCollection ifFalse:[
            dependents := aCollection first.
            ^ self
        ]
    ].
    dependents := aCollection

    "Modified: 19.4.1996 / 12:23:05 / cg"
!

dependentsDo:aBlock
    "evaluate aBlock for all of my dependents"

    |deps|

    deps := dependents.
    deps notNil ifTrue:[
	deps isCollection ifTrue:[
	    deps do:aBlock
	] ifFalse:[
	    aBlock value:deps
	]
    ]
!

release
    "remove all dependencies from the receiver"

    dependents := nil

    "Modified: 19.4.1996 / 10:31:35 / cg"
!

removeDependent:anObject
    "make the argument, anObject be independent of the receiver"

    [
        |deps sz dep|

        deps := dependents.
        deps notNil ifTrue:[
            deps isCollection ifTrue:[
                deps remove:anObject ifAbsent:[].
                (sz := deps size) == 0 ifTrue:[
                    dependents := nil
                ] ifFalse:[
                    sz == 1 ifTrue:[
                        (dep := deps first) isCollection ifFalse:[
                            dependents := dep
                        ]
                    ]
                ]
            ] ifFalse:[
                dependents := nil
            ]
        ]
    ] valueUninterruptably

    "Modified: 19.4.1996 / 12:24:24 / cg"
! !

!Model methodsFor:'dependents access (non weak)'!

addNonWeakDependent:anObject
    "make the argument, anObject be a dependent of the receiver.
     Since all dependencies are nonWeak in Model, this is simply
     forwarded to addDependent:"

    ^ self addDependent:anObject

    "Created: 19.4.1996 / 10:28:53 / cg"
!

interrests
    "return a Collection of interrests - nil if there is none.
     Here, we use the normal dependents collection for interrests."

    ^ self dependents

    "Created: 19.4.1996 / 12:28:23 / cg"
    "Modified: 19.4.1996 / 18:07:12 / cg"
!

nonWeakDependents
    "return a Collection of dependents - nil if there is none.
     Since all dependencies are nonWeak in Model, this is a dummy."

    ^ self dependents

    "Created: 19.4.1996 / 10:29:43 / cg"
    "Modified: 19.4.1996 / 18:07:31 / cg"
!

removeNonWeakDependent:anObject
    "make the argument, anObject be independent of the receiver.
     Since all dependencies are nonWeak in Model, this is simply
     forwarded to removeDependent:"

    ^ self removeDependent:anObject

    "Created: 19.4.1996 / 12:19:40 / cg"
! !

!Model class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libview2/Model.st,v 1.24 1996-05-02 13:28:28 cg Exp $'
! !