Special

Introducing the “Welcome to Xojo” Bundle!

New to Xojo and looking for guidance? We've put together a terrific bundle to welcome you! Xojo Bundle

This bundle includes six back issues of the magazine -- all of year 21 in printed book and digital formats -- plus a one-year subscription (beginning with 22.1) so you'll be learning all about Xojo for the next year. It's the perfect way to get started programming with Xojo. And you save as much as $35 over the non-bundle price!

This offer is only available for a limited time as supplies are limited, so hurry today and order this special bundle before the offer goes away!

Article Preview


Buy Now

Issue 2.6

COLUMN

Using RBScript

Creating plugins for your application

Issue: 2.6 (July/August 2004)
Author: Thomas Reed
Author Bio: Thomas Reed has been programming as a hobbyist for more than 20 years, and fell in love with the Mac in 1984.
Article Description: No description available.
Article Length (in bytes): 10,797
Starting Page Number: 30
Article Number: 2614
Resource File(s):

Download Icon 2614.zip Updated: 2013-03-11 19:07:58

Related Link(s): None

Excerpt of article text...

Ask many REALbasic developers how to create a plugin architecture for your application and they're likely to tell you to write it in another language. Fortunately, this unpleasant advice couldn't be further from the truth. Not only is creating your own plugin architecture possible in REALbasic, it is not even all that difficult. RBScript is the answer.

RBScript provides a simple scripting language with which the user can easily create plugins. Because RBScripts are compiled before running, rather than being interpreted while running, they are as fast as native REALbasic code. The RBScript syntax is powerful enough to allow creation of classes, modules, and interfaces that can be used within the script.

With all of these things in its favor, why don't more people recommend RBScript for plugins? In part, I believe this is because some developers simply haven't explored RBScript. However, RBScripts do have one seemingly significant limitation: all RBScripts run in a "black box". They have access to only the most basic data types -- Integer, Single, Double, String, Boolean, and Color. They also recognize the Variant and Object (but not Object subclass) types, though variables of these types cannot be passed between the script and the application. An RBScript cannot in any way interact directly with any other kind of variable. This means they cannot interact with the outside world except in a very limited manner.

The RBScript's Context property is its sole lifeline to the world. The script's Context can be an instance of any Object subclass, though typically it will be a class that you create specifically for this purpose. The script can access any public (or, in REALbasic 5.5, protected) methods and properties of its Context object, as long as there are only basic data types involved. For example, if the Context object has properties "Count as Integer" and "File as FolderItem", the script can use Count but cannot do anything with File.

Sounds like a pretty fatal flaw, doesn't it? How is an RBScript supposed to read or write files without access to the FolderItem class? How can it draw if it can't touch a Graphics object? On paper, these issues may seem like enough to kill your plugin idea prematurely. In reality, this is a mere bump in the road.

In a way, an RBScript is no different from a REALbasic application. An application also lives in a kind of a box. Without the API (Application Programming Interface) provided by the REALbasic framework, your application can't do anything useful, because it cannot affect or communicate with the world in any way. The API provided by the framework provides your application with a means of expressing itself. The REALbasic framework, in turn, taps into APIs provided by the various operating systems that are supported by REALbasic. At each of these points, there is an effective barrier, with the API providing ways for the code on one side of the barrier to affect what goes on on the other side. Your RBScript and its Context are no different. The Context provides an API to the script, allowing the script rigidly defined ways of interacting with the outside world.

...End of Excerpt. Please purchase the magazine to read the full article.


Errata (2004-09-15)

Code Listings 2 and 3 from this article were accidentally omitted from this issue. This code has been added to archive and is also reprinted here:

Listing 2: Storing persistent data
Sub PersistentValue(key as string, assigns i as integer)
  pDict.Value(key) = i
End Sub

Sub PersistentValue(key as string, assigns s as string)
  pDict.Value(key) = s
End Sub

Sub PersistentValue(key as string, assigns b as boolean)
  pDict.Value(key) = b
End Sub

Function PersistentValueInteger(key as string) as integer
  return pDict.Value(key).IntegerValue
End Function

Function PersistentValueString(key as string) as string
  return pDict.Value(key).StringValue
End Function

Function PersistentValueBoolean(key as string) as boolean
  return pDict.Value(key).BooleanValue
End Function
Listing 3: Example Line tool script
const kMouseDown = 1
const kMouseDrag = 2
const kMouseUp = 3

dim startX, startY as integer

select case EventType
  
  case kMouseDown
    DrawPoint(CurX, CurY)
    PersistentValue("startX") = CurX
    PersistentValue("startY") = CurY
  
  case kMouseUp
    startX = PersistentValueInteger("startX")
    startY = PersistentValueInteger("startY")
    DrawLine(startX, startY, CurX, CurY)
  
end select