import { assert , log , LogLevel } from './auxiliaries' ; import { Context } from './context' ; import { Initializable } from './initializable' ; /**
 * A generic WebGL object trait that has a size, a status, an identifier, and is initializable. A context and an object
 * handle are provided for internal use and can be read from outside. Furthermore, an object supports optional reference
 * counting. If used, an object cannot be initialized when already referenced, and cannot be delete as long as at least
 * a single reference is active.
 */ export abstract class AbstractObject < T > extends Initializable { see context protected _context : Context ; see identifier protected _identifier : string ; see object protected _object : T | undefined ; see valid protected _valid = false ; /**
     * Number of references to this object. If at least a single reference was counted, this object can neither be
     * initialized (and thus created) nor uninitialized (and thus deleted). The reference count is controlled via
     * ref() and unref() functions.
     */ protected _referenceCount = 0 ; param context param identifier constructor ( context , identifier ? ) { super ( ) ; this . _context = context ; this . _identifier = identifier !== undefined && identifier !== `` ? identifier : 'Object' ; } returns protected abstract create ( ... args ) ; /**
     * Object deletion which is invoked on uninitialization.
     */ protected abstract delete ( ) ; @override
     * Ensure that an object handle is created at the point of initialization. When overriding this function
     * super.initialize() has to be invoked immediately/first. Please note that initialization of invalid
     * object raises an assertion in order to prevent further actions without a valid WebGL object. After
     * object creation the valid property is expected to be set accordingly.
      @ Initializable . initialize ( ) initialize ( ... args ) { this . _identifier = this . _context . allocationRegister . createUniqueIdentifier ( this . _identifier ) ; this . create ( ... args ) ; if ( ! this . _valid ) { this . _context . allocationRegister . deleteUniqueIdentifier ( this . _identifier ) ; log ( LogLevel . Error , `initialization of '${ this . _identifier }' failed` ) ; } return this . _valid ; } @override
     * Ensure that an object handle is deleted, invalidated, and its allocated GPU resources are set to zero.
     * When overriding this function super.uninitialize() has to be invoked last/at the end.
     * Note that an object cannot be uninitialized if it is referenced (reference count > 0).
      @ Initializable . uninitialize ( ) uninitialize ( ) { this . _context . allocationRegister . reallocate ( this . _identifier , 0 ) ; this . _context . allocationRegister . deleteUniqueIdentifier ( this . _identifier ) ; this . delete ( ) ; assert ( this . _object === undefined , `expected object '${ this . _identifier }' to be undefined after delete` ) ; assert ( this . _valid === false , `expected object '${ this . _identifier }' to be invalid after delete` ) ; } /**
     * Read-only access to the objects context, used to get context information and WebGL API access.
     */ get context ( ) : Context { return this . _context ; } returns get identifier ( ) : string { return this . _identifier ; } /**
     * Read-only access to the WebGL object handle.
     */ get object ( ) : T { assert ( this . _object !== undefined , `access to undefined object` ) ; return this . _object as T ; } returns get valid ( ) : boolean { return this . _valid ; } /**
     * Increment the reference count of this object.
     */ ref ( ) { assert ( this . initialized , `expected object to be initialized in order to be referenced` ) ; ++ this . _referenceCount ; } /**
     * Decrement the reference count of this object.
     */ unref ( ) { assert ( this . _referenceCount > 0 , `expected object to be referenced in order to decrease its reference count` ) ; -- this . _referenceCount ; } }