import { assert } from './auxiliaries' ; interface MethodDecorator { ( target , propertyKey , descriptor ) : PropertyDescriptor ; } initialize uninitialize assert_initialized export abstract class Initializable { see initialized private _initialized = false ; protected static readonly assertInitializedFalse = ( object ) => assert ( false , `instance of ${ object . constructor . name } expected to be initialized` ) ; protected static readonly assertUninitializedFalse = ( object ) => assert ( false , `instance of ${ object . constructor . name } not expected to be initialized` ) ; /**
     * Method decorator for initialization of Initializable inheritors. This decorator asserts the initialization status
     * of the instance that is to be initialized, invokes its initialization with arbitrary number of parameters,
     * and sets the initialization status to the initialization success (either false or true).
     * In order to encourage the use of `assertInitialized` and `assertUninitialized` they are dynamically
     * bound to either a static, always-failing assert or an empty/undefined function.
     */ static initialize ( ) { return ( target , propertyKey , descriptor ) : PropertyDescriptor => { const initialize = descriptor . value ; descriptor . value = function ( ) : boolean { assert ( this . _initialized === false , `re-initialization of initialized object not anticipated` ) ; this . _initialized = initialize . apply ( this , arguments ) ; if ( this . _initialized ) { this . assertInitialized = ( ) => undefined ; this . assertUninitialized = ( ) => Initializable . assertUninitializedFalse ( this ) ; } else { this . assertUninitialized = ( ) => undefined ; this . assertInitialized = ( ) => Initializable . assertInitializedFalse ( this ) ; } return this . _initialized ; } ; return descriptor ; } ; } /**
     * Method decorator for uninitialization of Initializable inheritors. This decorator asserts the initialization
     * status of the instance that is to be uninitialized, invokes its uninitialization, and falsifies the
     * initialization status. In order to encourage the use of `assertInitialized` and `assertUninitialized` they are
     * dynamically bound to a static, always-failing assert and an empty/undefined function respectively.
     */ static uninitialize ( ) { return ( target , propertyKey , descriptor ) => { const uninitialize = descriptor . value ; descriptor . value = function ( ) : void { assert ( this . _initialized === true , `expected object to be initialized in order to uninitialize` ) ; uninitialize . apply ( this ) ; this . _initialized = false ; this . assertUninitialized = ( ) => undefined ; this . assertInitialized = ( ) => Initializable . assertInitializedFalse ( this ) ; } ; return descriptor ; } ; } /**
     * Method decorator for discarding of Initializable inheritors. This decorator asserts the initialization
     * status of the instance that is to be discarded, invokes its uninitialization, and falsifies the
     * initialization status. In order to encourage the use of `assertInitialized` and `assertUninitialized` they are
     * dynamically bound to a static, always-failing assert and an empty/undefined function respectively.
     */ static discard ( ) { return ( target , propertyKey , descriptor ) => { const discard = descriptor . value ; descriptor . value = function ( ) : void { assert ( this . _initialized === true , `expected object to be initialized in order to uninitialize` ) ; discard . apply ( this ) ; this . _initialized = false ; this . assertUninitialized = ( ) => undefined ; this . assertInitialized = ( ) => Initializable . assertInitializedFalse ( this ) ; } ; return descriptor ; } ; } see assertInitialized static assert_initialized ( ) { return ( target , propertyKey , descriptor ) => { const initialize = descriptor . value ; descriptor . value = function ( ) : any { this . assertInitialized ( ) ; return initialize . apply ( this , arguments ) ; } ; return descriptor ; } ; } see assertUninitialized static assert_uninitialized ( ) { return ( target , propertyKey , descriptor ) => { const initialize = descriptor . value ; descriptor . value = function ( ) : void { this . assertUninitialized ( ) ; initialize . apply ( this , arguments ) ; } ; return descriptor ; } ; } /**
     * Asserts the objects initialization status to be true. Note that the implementation is cached and forwarded to
     * either an empty function when initialized and to an acutal assert(false) otherwise.
     */ protected assertInitialized : ( ) => void = ( ) => Initializable . assertInitializedFalse ( this ) ; /**
     * Asserts the objects initialization status to be false. Note that the implementation is cached and forwarded to
     * either an empty function when uninitialized and to an acutal assert(false) otherwise.
     */ protected assertUninitialized : ( ) => void = ( ) => undefined ; param args returns abstract initialize ( ... args ) ; /**
     * Uninitialization event that should be specialized by inheritor and has to be decorated by @uninitialize in order
     * to assert initialization status and set the initialization status to false.
     */ abstract uninitialize ( ) ; /**
     * Property getter for readonly access to the initialization status of an initializable instance.
     */ get initialized ( ) : boolean { return this . _initialized ; } }