Re: delayed win32lib
- Posted by Derek Parnell <ddparnell at bigpond.com> Sep 08, 2003
- 338 views
------------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--