Become a fan of Slashdot on Facebook

 



Forgot your password?
typodupeerror
×
User Journal

Journal codefool's Journal: Time-Sliced Procedures in Javascript

/////////////////////////////////////////////////////////////////////////////////////////
//
//  clsTimeSlice
//
//  The atomic time slice object. Represents either a function call or a method call
//  to an object. The evoked function/method must answer false to continue processing, or
//  true to terminate it.
//
function clsTimeSlice( fnSlice, objObj, name, latency )
{
    this.fnSlice = fnSlice;
    this.obj     = objObj;
    this.name    = name;
    this.latency = ( null == latency || latency < 1 ) ? clsTimeSlicedProc.SLICE_LATENCY : latency;
}

clsTimeSlice.prototype.exec =
    function()
    {
        var bRet;
        if( null != this.obj )
            bRet = this.fnSlice.call( this.obj );
        else
            bRet = this.fnSlice();
        return bRet;
    }

/////////////////////////////////////////////////////////////////////////////////////////
//
//  clsTimeSlicedProc
//
//  Container for a time-sliced procedure.
//
function clsTimeSlicedProc( sObjectName )
{
    this.init( sObjectName );
}
clsTimeSlicedProc.CHAIN_INDEX            = -1;
clsTimeSlicedProc.SLICE_LATENCY          = 2;   // #ms between slices

clsTimeSlicedProc.prototype.init =
    function( sObjectName )
    {
        this.name       = sObjectName;
        this.slices     = new Array();
        this.sliceChain = null;
        this.latch      = false;
        this.next       = 0;
        this.error      = 0;
        this.run        = false;
    }

clsTimeSlicedProc.prototype.reset        = function()          { this.init( this.name ); }
clsTimeSlicedProc.prototype.sliceCnt     = function()          { return this.slices.length; }
clsTimeSlicedProc.prototype.slice        =
    function( idx )
    {
        if( idx < this.sliceCnt() )
            return this.slices[ idx ];
        return null;
    }

clsTimeSlicedProc.prototype.latched      = function()             { return this.latch; };
clsTimeSlicedProc.prototype.addSlice     = function( s )          { this.slices[ this.slices.length ] = s; return s; }
clsTimeSlicedProc.prototype.createSlice  = function( f, o, n, l ) { this.addSlice( new clsTimeSlice( f, o, n, l ) ); return this; }
clsTimeSlicedProc.prototype.addFunction  = function( f, n, l )    { this.addSlice( new clsTimeSlice( f, null, n, l ) )._f = true; return this; }
clsTimeSlicedProc.prototype.chain        = function( f, o, n, l ) { this.sliceChain = new clsTimeSlice( f, o, n, l ); return this; }
clsTimeSlicedProc.prototype.setErrorCode = function( c )          { this.error = c; }
clsTimeSlicedProc.prototype.hasError     = function()             { return !!( this.error != 0 ); }
clsTimeSlicedProc.prototype.finish       = function()             { this.next = clsTimeSlicedProc.CHAIN_INDEX; }

clsTimeSlicedProc.prototype.begin        =
    function()
    {
        if( this.latch )
            return false;

        this.latch = true;
        this._doSlice( this.next );
        return true;
    }

clsTimeSlicedProc.prototype.setNextSlice =
    function( indexOrName )
    {
        if( typeof indexOrName == "string" )
        {
            // search for a slice by name
            for( var idx = 0; idx < this.slices.length; idx++ )
            {
                if( this.slice( idx ).name == indexOrName )
                {
                    this.next = idx;
                    break;
                }
            }
            if( idx >= this.slices.length )
                alert( this.name + ": Not able to find slice with tag '" + indexOrName + "'" );
        }
        // must allow index to exceed slice count in order for loop to ever terminate!
        else if( indexOrName <= this.sliceCnt() )
            this.next = indexOrName;
    }

clsTimeSlicedProc.prototype._doSlice =
    function( iIndex )
    {
        var l = ( iIndex in this.slices ) ? this.slices[ iIndex ].latency : clsTimeSlicedProc.SLICE_LATENCY;
        setTimeout( this.name + ".exec( " + iIndex + ")", l );
    }

clsTimeSlicedProc.prototype.exec =
    function( iIndex )
    {
        if( clsTimeSlicedProc.CHAIN_INDEX == iIndex )
        {
            if( null != this.sliceChain )
                this.sliceChain.exec();
            this.sliceChain = null;            // chain is a one-shot deal
            this.latch = false;
        }
        else
        {
            if( !this.hasError() && iIndex < this.sliceCnt() )
            {
                this.setNextSlice( iIndex + 1 );
                if( this.slices[ iIndex ].exec() || this.slices[ iIndex ]._f )
                    iIndex = this.next;
                this._doSlice( iIndex );
            }
            else
            {
                this._doSlice( clsTimeSlicedProc.CHAIN_INDEX );
            }
        }
    }
This discussion has been archived. No new comments can be posted.

Time-Sliced Procedures in Javascript

Comments Filter:

Understanding is always the understanding of a smaller problem in relation to a bigger problem. -- P.D. Ouspensky

Working...