Pending the release of REBOL/Command I have found I can do a lot with a TCP/IP
port and my RValue C++ class.  Since the introduction of REBOL I have been
wanting to use it as a macro language for my C++ applications (I really miss
AREXX and AREXX ports from my Amiga days).  I got tired of waiting for
REBOL/command so I rolled my own solution. 

On Thu, 10 Feb 2000, [EMAIL PROTECTED] wrote:
> I think Rebol would make a fine extension language.  The major problem all
> extension language integrators face is how to glue to language to the
> application's core datastructures.

I am using my RValue class to convert C++ values to/from REBOL.  This has
been completely re-written since my announcement a few weeks ago; memory usage
has been halved and I have added a few value types.  Each value only takes
takes 8 bytes on 32bit systems (type pointer and uns32 data/pointer), plus the
storage for words and strings.  Blocks are stored in an STL-like vector of
RValues.

In place of embedding, my application listens on a TCP/IP port. I use a C++
Command class which parses the REBOL values sent through the port (using
RValue) and dispatches them.  My application has plug-ins which have an
execute() method which accepts arguments in RValue form.  All is not
completely tidy as my Command class has a switch statement to handle certain
commands, but most commands will use the default "call plug-in" case.

As an aside, I am using the Qt GUI toolkit and it is quite easy to implement
the TCP/IP port.  The easy to use socket classes are new to Qt 2.1. 
It seems everyone is realizing that communication should be easy!  

On the REBOL side of things we can connect to the application's port using this:

    copen: func [] [ _ccon: open tcp://127.0.0.1:9000 ]

I have a 'csend' function which (simplified) does this:

    csend: func [ data ]
    [
        command: mold compose/deep data
        insert _ccon join command terminator-character

        clear return-buffer
        wait _ccon
        read-io _ccon return-buffer 1024   ; return results of command to caller
    ]

Each application command has a csend wrapper.  Here are a few (my app is a 3D
modeler called Cricket):

    make-cube: func [ arg ] [ csend [ "node/create/mesh/cube" (arg) ] ]

    smooth: func [] [ csend "mesh/edit/smooth" ]

    csave: func [ file [file! string!]] [ csend [ "save" (to-string file) ] ]

Now we can write this REBOL macro to create a smooth cube and save it to a file:

    REBOL []
    do %cricket.r
    copen

    make-cube [ size: 2 ]
    smooth
    csave %cube.obj

    cclose
    quit


To have access to REBOL from within your app. use system (or your local
variant) to call a REBOL script which will connect back using the network port. 
I haven't done this yet, but it seems simple enough.

Even after Command is released I may stick with my solution since

  1) It doesn't require the memory overhead of embedding.
  2) It can be used with any language that can communicate with a TCP/IP port.
  3) Command may not be freely available.  My app. is open-source and I do not
      expect users to pay for scripting.


Take care,
-Karl Robillard

Reply via email to