Re: delayed win32lib

new topic     » goto parent     » topic index » view thread      » older message » newer message

------------uplnNYK2elyWaKL89qxZ9M

On Mon, 08 Sep 2003 00:01:27 +0100 (09/08/03 09:01:27)
, Pete Lomax <petelomax at blueyonder.co.uk> wrote:

>
>
> On Mon, 08 Sep 2003 05:48:09 +1000, Derek Parnell
> <ddparnell at bigpond.com> wrote:
>
>> I found a nasty bug, so I've delayed its release; maybe another day.
>>
>> If you really want to start looking at it before its really ready you 
>> can find it at
>>
>>  http://users.bigpond.com/ddparnell/euphoria/w32005902beta.zip
>>
>> This does not include the docs or updated examples yet.
> or series.e, lol
>

Ooops! Different folder.



-- 

cheers,
Derek Parnell
------------uplnNYK2elyWaKL89qxZ9M
Content-Disposition: attachment; filename=SERIES.E
Content-Type: text/plain; name=SERIES.E
Content-Transfer-Encoding: 8bit

-- series.e  v1.0 17/July/2002, Derek Parnell
-- A set of routines to manage sets of sequential unique numbers.
--
-- Contains the following routines:
--      next_number(name)              Returns the next number in a 
--                                        named series.
--      current_number(name)           Returns the number returned
--                                        by the most recent call to 
--                                        next_number()
--      define_series(name, attrvals)  Used to initialise or reset
--                                        a series' attributes.
--      get_series(name)               Returns the current attributes
--                                        of a series


-----------------------------------------------
-- FUNCTION: next_number(object Name)
--  RETURNS: The next number in the series.
--  PARAMETERS:
--    Name      Can be any Euphoria object. Each series has a unique 
--              name of your choosing.
--  ACTIONS:
--  *If the series named does not exist, this creates a new series with
--   the default attributes. And if for some reason it cannot create a 
--   new series, it returns immediately with an empty sequence.
--  *Calculates the next number.
--  *If the series is a 'wrapping' type, and the next number is beyond 
--   the last number for the series, the next number is set to the
--   series' first number.
--
--  EXAMPLE:                     
--      -- Define the record layout for Customer.    
--      constant CustID    = next_number("CustRecord"),
--               CustName  = next_number("CustRecord"),
--               CustAddr  = next_number("CustRecord"),
--               CustPhone = next_number("CustRecord"),
--               SIZEOF_Cust = current_number("CustRecord")    
--
--      lNewRecord = repeat(0, SIZEOF_Cust)
--      lNewRecord[CustID] = next_number("custid")

-----------------------------------------------
-- PROCEDURE: define_series(object Name, sequence Values)
--  PARAMETERS:
--    Name      Can be any Euphoria object. Each series has a unique name
--              of your choosing.
--    Values    Is a list of zero or more attribute-value pairs.
--  ACTIONS:
--  *If the series named does not exist, this creates a new series with
--   the default attributes.
--  *Then for each attribute-value pair, it sets the series' attribute
--   to the value supplied. Invalid attributes and values are ignored.
--  The attributes of a series are:
--      SValue      ATOM: The next number to be returned. Default: 1.
--      SIncr       ATOM: The increment used to calculate the new next 
--                        number. Can be negative. Default: 1.
--      SWrap       INTEGER: If the series is a wrapping type, this
--                        should be True. Default: False
--      SFirst      ATOM: The first number to be used in the series.
--                        Default: 1
--      SLast       ATOM: The last number to be used in the series.
--                        Default: 0
--      SRtnId      INTEGER: A routine_id of a callback routine or
--                        -1. Default: -1
--      SUserData   OBJECT: Not used by these routines. It is passed
--                        unchanged to the callback routine. Default: 0
--
--  Note, when you use this routine to set the Value attribute, the 
--  value is not actually reset until the next call to next_number().
--
--  Callback Routine.
--      If defined for a series, the callback routine is invoked just
--      prior to returning from a next_number() or current_number() call.
--      The callback routine receives five parameters: 
--       object: The series name
--       object: The type of callback. Either SCB_NextNum or SCB_CurrentNum
--       atom: For SCB_NextNum this is the next value in the series, 
--             for SCB_CurrentNum this is the previous value returned.
--       integer: Wrapped flag. Only used for SCB_NextNum. If True, 
--             it means that the value has come about because the
--             series has wrapped around from Last to First values.
--       object: The user data. This is passed unaltered from the 
--             define_series() call that set it.
--  The callback routine must return something. Whatever it returns
--  is passed back unaltered to the application in place of the normal
--  value.
--      
--    
--  EXAMPLE:                            
--      -- Customer IDs start at 60001. Use a checkdigit routine to 
--      -- adjust the returned value.    
--      define_series("cust", { {SValue, 60001}, 
--                              {SRtnId, routine_id(GenCheckDigit)},
--                              {SUserData, 11} } )    
--      NextCustID = next_number("cust")
--
--      define_series("row", { {SValue,1}, {SWrap,True}, 
--                             {SFirst,1}, {SLast,24} } )
--      define_series("col", { {SValue,1}, {SWrap,True}, 
--                             {SFirst,1}, {SLast,80} } )
--      . . .
--      while True do
--          k = GetKeyCode()
--          if k != prevcode then
--              if k = Up then
--                defines_series("row", { {SIncr, -1} } )
--                defines_series("col", { {SIncr, 0} } )
--              elsif k = Down then
--                defines_series("row", { {SIncr, 1} } )
--                defines_series("col", { {SIncr, 0} } )
--              elsif k = Left then
--                defines_series("col", { {SIncr, -1} } )
--                defines_series("row", { {SIncr, 0} } )
--              elsif k = Right then
--                defines_series("col", { {SIncr, 1} } )
--                defines_series("row", { {SIncr, 0} } )
--              end if
--              prevcode = k
--          end if
--
--          c = next_number("col")
--          r = next_number("row")
--          . . .
--      end while
--
--      define_series("angle", { {SValue,0}, {SFirst,0}, {SLast,2*PI}, 
--                               {sIncr,0.1}, {SWrap,True} } )
--      . . .
--      Plot (next_number("angle"))

-----------------------------------------------
-- FUNCTION: get_series(object Name)
--  RETURNS: A list of attribute-value pairs. If the series doesn't 
--           exist, an empty sequence is returned.
--  PARAMETERS:
--    Name      Can be any Euphoria object. Each series has a unique
--              name of your choosing.
--  ACTIONS:
--      If the named series doesn't exist, return an empty sequence.
--      Build a list of attributes and their values.
--      Return the attribute-value pair list.    
    
-----------------------------------------------
-- FUNCTION: current_number(object Name)
--  RETURNS: The previous number returned in the series.
--  PARAMETERS:
--    Name      Can be any Euphoria object. Each series has a unique
--              name of your choosing.
--  ACTIONS:
--  If the series named does not exist, this returns an empty sequence..
--  Returns the current value.
--
--  EXAMPLE:
--       procedure AddNewCustomer()
--           NextID = next_number("cust")
--            . . .
--       end procedure    
--       . . . 
--      AddNewCustomer()
--      -- Get the ID that was just used.
--      CustID = current_number("cust")


without trace                                                      
without warning
constant   
        True            = (1=1),
        False           = (not True)
global constant        
        SValue          = 'v',
        SIncr           = 'i',
        SWrap           = 'w',
        SFirst          = 'f',
        SLast           = 'l',
        SRtnId          = 'r',
        SUserData       = 'u',
        SCB_NextNum     = 'N',
        SCB_CurrentNum  = 'C'

constant 
        kSFlds       = {  SIncr,SWrap,SFirst,SLast,SValue,SRtnId,SUserData},
        kEmptySeries = {0,    1,    0,     1,    0,    {},    -1,        0},
        kSValue      = 1, -- Always the first field
        kSResetValue = find(SValue,   kSFlds) + 1,
        kSIncr       = find(SIncr,    kSFlds) + 1,
        kSWrap       = find(SWrap,    kSFlds) + 1,
        kSFirst      = find(SFirst,   kSFlds) + 1,
        kSLast       = find(SLast,    kSFlds) + 1,
        kSRtnId      = find(SRtnId,   kSFlds) + 1,
        kSUserData   = find(SUserData,kSFlds) + 1

sequence vDefnSeries        -- Names of series
sequence vSeriesData        -- Attribute-set per series
vDefnSeries = {}
vSeriesData = {}

-----------------------------------------------
global procedure define_series(object pName, sequence pValues)
-----------------------------------------------
    integer lID
    integer lFld

    -- Find the series asked for. If it doesn't exist, create it.    
    lID = find(pName, vDefnSeries)
    if lID = 0 then
        vSeriesData = append(vSeriesData, kEmptySeries)
        vDefnSeries  = append(vDefnSeries, pName)
        lID = length(vDefnSeries)
    end if
    
    -- Apply the attribute values, ignoring any invalid ones.
    for i = 1 to length(pValues) do

        -- Only accept attr-value pairs: ie. must be a 2-element sequence.
        if sequence(pValues[i]) and length(pValues[i]) = 2 then

            -- Convert the attribute code into an offset into the series' data.
            -- I need to add one to skip over the Current Value field.
            lFld = find(pValues[i][1], kSFlds) + 1

            -- Only apply if valid attr type and the datatype is suitable.
            if lFld > 1 and (atom(pValues[i][2]) or (lFld = kSUserData)) then

                vSeriesData[lID][lFld] = pValues[i][2]
            end if
        end if                                                    
    end for
                        
end procedure


-----------------------------------------------
global function next_number(object pName)
-----------------------------------------------
    integer lID
    atom lNextNum
    sequence lRC
    integer lWrapped
    
    
    -- Find the series asked for. If it doesn't exist, create it.    
    lID = find(pName, vDefnSeries)
    if lID = 0 then
        define_series(pName,{})
        lID = find(pName, vDefnSeries)
        -- It should exist now. If not, then bail out.
        if lID = 0 then
            return {}
        end if
    end if
                    
    lWrapped = False
                                        
    -- Has the next value been reset by a call to define_series()?
    if sequence(vSeriesData[lID][kSResetValue]) then
        -- No, do the normal case.
        lNextNum = vSeriesData[lID][kSValue] + vSeriesData[ lID ][ kSIncr ]
        -- Handle those series that wrap from last back to first.
        if vSeriesData[ lID ] [ kSWrap ] then
            if vSeriesData[ lID ][ kSIncr ] > 0 then
                if lNextNum > vSeriesData[ lID ][ kSLast ] then
                    lNextNum = vSeriesData[ lID ] [ kSFirst ]
                end if
            else
                if lNextNum < vSeriesData[ lID ][ kSLast ] then
                    lNextNum = vSeriesData[ lID ] [ kSFirst ]
                end if
            end if
        end if

    else
        -- Yes, use the reset value instead of calculating it.
        lNextNum = vSeriesData[lID][kSResetValue]
         vSeriesData[lID][kSResetValue] = {}
        -- Range-check those series that wrap.
        if vSeriesData[ lID ] [ kSWrap ] then
            if vSeriesData[ lID ][ kSIncr ] > 0  then
                if lNextNum > vSeriesData[ lID ][ kSLast ] or
                   lNextNum < vSeriesData[ lID ][ kSFirst ] then
                   
                    lNextNum = vSeriesData[ lID ] [ kSFirst ]
                    lWrapped = True
                end if
            else
                if lNextNum < vSeriesData[ lID ][ kSLast ] or
                   lNextNum > vSeriesData[ lID ][ kSFirst ] then
                   
                    lNextNum = vSeriesData[ lID ] [ kSFirst ]
                    lWrapped = True
                end if
            end if
        end if
    end if        
                            
                 
    -- Save the value for the next call
    vSeriesData[ lID ] [ kSValue ] = lNextNum
                       
    -- Check for any callback routine.
    if vSeriesData[ lID ] [ kSRtnId ] > -1 then
        return call_func(vSeriesData[ lID ] [ kSRtnId ],
                          {pName, SCB_NextNum, lNextNum, lWrapped,
                           vSeriesData[ lID ] [ kSUserData ]} )
    else                          
        return lNextNum
    end if
            
end function    

-----------------------------------------------
global function current_number(object pName)
-----------------------------------------------
    integer lID
    atom lNextNum
    
    -- Find the series asked for. If it doesn't exist, bail out.    
    lID = find(pName, vDefnSeries)
    if lID = 0 then
        return {}
    end if
    
    -- Check for any callback routine.
    if vSeriesData[ lID ] [ kSRtnId ] > -1 then
        return call_func(vSeriesData[ lID ] [ kSRtnId ],
                          {pName, SCB_CurrentNum, 
                           vSeriesData[lID][kSValue], False,
                           vSeriesData[ lID ] [ kSUserData ]} )
    else                          
        return vSeriesData[lID][kSValue]
    end if
end function    

-----------------------------------------------
global function get_series(object pName)
-----------------------------------------------
    -- Returns a series definition.
    integer lID
    integer lX
    
    -- Find the series asked for. If it doesn't exist, bail out.    
    lID = find(pName, vDefnSeries)
    if lID = 0 then
        return {}
    end if
                                       
    -- Check for a pending value reset.
    if sequence(vSeriesData[ lID ][ kSResetValue]) then
        lX = kSValue
    else
        lX = kSResetValue
    end if
    
    -- Build the attribute-pair list. The attribute order is not significant.
    return
         {
            {SValue, vSeriesData[ lID ][ lX]},
            {SIncr, vSeriesData[ lID ][ kSIncr]},
            {SWrap, vSeriesData[ lID ][ kSWrap]},
            {SFirst, vSeriesData[ lID ][ kSFirst]},
            {SLast, vSeriesData[ lID ][ kSLast]},
            {SRtnId, vSeriesData[ lID ][ kSRtnId]},
            {SUserData, vSeriesData[ lID ][ kSUserData]}
         }
    
end function
------------uplnNYK2elyWaKL89qxZ9M--

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu