r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3 Schemes] Implementors guide

Pavel
13-Aug-2010
[2207]
Rebol [
    file: %prot-rif.r
    title: "RIF protocol"
    author: "Pavel"
    rights: 'PD
    date: 13-Aug-2010
    ]

;; Local functions

Append-RIF: func [port [port!] record [binary!] ][


 write/append port/locals/2 to-binary length? head port/locals/1		;index 
 port the end of data file will be beginning of new record

 write/append port/locals/1 record							        ;data port new record 
 into data file


 return shift length? head port/locals/2 -3					        ;number of 
 records 8 bytes per record
]


Get-RIF: func [ port [port!] i [integer!] /local numentry indexpos 
recpos recend value ][


    numentry: shift length? head port/locals/2 -3                    
       ;number of records 8 bytes per record


 if any [i = 0 i > numentry] [return none]                        
    ;numbering starts at 1 ends at file end


 indexpos: multiply subtract i 1 8					                ;compute index 
 offset
	recpos: to-integer read/seek/part port/locals/2 indexpos 8

  either ( (8 * i) = length? head port/locals/2 ) [				;last record 
  special case
		recend: length? head port/locals/1
		][

  recend: to-integer read/seek/part port/locals/2 add indexpos 8 8		;internal 
  record
		]

 return read/seek/part port/locals/1 recpos subtract recend recpos
]

;; Scheme definition
make-scheme [
	name: 'rif
	title: "RIF Protocol"
	spec: make system/standard/port-spec-head []
    awake: none

	actor: [
		open: func [port [port!] /local path ] [
            parse port/spec/ref [thru #":" 0 2 #"/" path:]
            append port/spec compose [path: (to-file path)]
            port/locals: copy []
            either (0 = length? port/locals) [

                append port/locals open/seek rejoin [port/spec/path ".dat"]

                append port/locals open/seek rejoin [port/spec/path ".idx"]
                ][

                port/locals/1 open/seek rejoin [port/spec/path ".dat"]

                port/locals/2 open/seek rejoin [port/spec/path ".idx"]
            ]
        return port
        ]

        close: func [port [port!]] [
            foreach  port port/locals [close port]
        ]

        read: func [port [port!] /seek number [integer!] ] [
            Get-RIF port number
        ]

        write: func [port [port!] record [binary!]] [
            Append-RIF port record
        ]

    ]
]
Steeve
13-Aug-2010
[2208]
arghh... not here ;-)
Andreas
13-Aug-2010
[2209x3]
There are action!s in R3, which operate in port!s.
If you define custom schemes, you can implement how those actions 
behave for ports using your scheme by writing what we call "actors".
This is the elementary principle to understand.
Pavel
13-Aug-2010
[2212x2]
It is elementary dear Watson :-)
Watson <- me here
Graham
13-Aug-2010
[2214]
http://www.rebol.net/wiki/Schemes:Notes#Actors
Steeve
13-Aug-2010
[2215x2]
try to open the port at first
and then call your read function with it
when you directly use read on a path, i'm not sure that your 'open 
function is called
Andreas
13-Aug-2010
[2217]
Ah, all documented in the wiki :)
Pavel
13-Aug-2010
[2218]
OK lets try it better, thanks guys for lesson learned!
Andreas
13-Aug-2010
[2219x2]
(Refresh, if you have the page open. I just fixed the formatting.)
But I think I'll refine the example and add an open? actor as well.
Pavel
13-Aug-2010
[2221]
I made it 
read: func [port [port!] /seek number [integer!] ] [

		either empty? port/locals [
		open port
            	return Get-RIF port number
		][
		return Get-RIF port number
		]

and it works now
Steeve
13-Aug-2010
[2222]
Btw Pavel, in my virtual-block scheme, the reason why I rebound the 
actors, is that I don't like to use nasty long path to acces my locals.
Pavel
13-Aug-2010
[2223x2]
I hope close is in garbage collector as mentioned in wiki
And second is more speed?
Steeve
13-Aug-2010
[2225]
It should be :-)
Graham
13-Aug-2010
[2226x2]
can't you 

return get-rif either empty? ...
or 

if empty? port/locals [ open port ]
get-rif port number
Pavel
13-Aug-2010
[2228]
graham it is better thanks
Graham
13-Aug-2010
[2229]
we should rename this group to !REBOL schemes
Steeve
13-Aug-2010
[2230]
but we"re missing a rename actor
Graham
13-Aug-2010
[2231x2]
we can use a proxy actor
Ahh.... I can rename :)
BrianH
13-Aug-2010
[2233x2]
Pavel, the names for the get/put operations of key-value stores are 
PICK and POKE.
We have a separate !REBOL3 Schemes group on purpose. Please don't 
rename it.
Andreas
13-Aug-2010
[2235]
We didn't have a separate !REBOL3 Schemes group.
BrianH
13-Aug-2010
[2236]
We created a bunch of spinoff groups because !REBOL3 was getting 
too busy.
Andreas
13-Aug-2010
[2237x2]
I guess you took the "!REBOL Schemes" too literally. It is "!REBOL3 
Schemes" Graham intented, and in fact, already renamed this group 
to. (It was "!REBOL3 Network Schemes" previously.)
intended*
BrianH
13-Aug-2010
[2239]
OK, cool. That is shorter :)
Andreas
13-Aug-2010
[2240]
Yeah. And more approriate :)
Graham
13-Aug-2010
[2241]
Wasn't this group orginally named "Graham's foray into scheme arcana" 
 or something similar??
Steeve
13-Aug-2010
[2242]
scheme on you
BrianH
13-Aug-2010
[2243]
Pavel, you were right the first time in trying to implement GET/PUT 
actors, but you got the names wrong. Try again with PICK and POKE.
Graham
13-Aug-2010
[2244]
get: :pick
put: :poke
BrianH
13-Aug-2010
[2245]
Metaphorically, yes. Literally, that will break REBOL :)
Graham
13-Aug-2010
[2246]
basic: :rebol
Anton
14-Aug-2010
[2247]
I think the group name should be tweaked a bit more to remove the 
"Scheme" inside the bracketed part. I don't see the need to have 
it mentioned twice.
Gregg
14-Aug-2010
[2248]
Done.
Steeve
28-Aug-2010
[2249x2]
Any example how to process inputs from the console's port while processing 
other ports using WAIT ?

I looked at the source of the input function, but it doesn't help....
I tried to launch a task! to wait for other port inputs and to keep 
the console safe.
But WAIT seems not working inside a task!
NickA
4-Sep-2010
[2251x2]
Is this helpful?:

print ""
q: open/binary/no-wait [scheme: 'console]
count: 0
forever [
    count: count + 1
    if not none? wait/all [q :00:00.01] [
        wait q
        qq: to string! copy q
        probe qq

        print ["^/loop count incremented to" count "while waiting^/"]

        insert s: open sound:// load %/c/windows/media/tada.wav wait s close 
        s
    ]
]
Oops - sorry, didn't see that this was R3 Schemes group.
Pavel
20-Dec-2010
[2253]
How to pass a received data from awake handler to actor level? I 
can do Print port/data it works, but I need return a value from read 
actor
Steeve
20-Dec-2010
[2254x3]
you can't return data from the awake handler
you just can stop it
*only*