Approaching Messaging and Scripting |
PETER POTREBIC: Welcome. I hope you guys enjoyed the lunch by Metrowerks. If you see Greg or John Watte in the hallways, maybe thank them again. This is going to be the talk about an introduction to messaging and scripting on BeOS, and my name is Peter Potrebic. In the BeOS I kind of like to think about it as there's two components to the application model. One of them is our messaging system. We heavily rely on messaging and this is to take full advantage of the hardware. You can have lots of things happening asynchronously and it makes multi-threading shine. So you kind of combine those two concepts, messaging and multi-threading, and you get a basic idea of what it is like to be a Be application.
A Be application is a series -- a group of
threads working together that are using messaging to
communicate with each other and to synchronize
activities.
I would like to kind of maybe take a step back. In our system there's actually several forms of messaging. You could think -- you could look at it there. We have a port system. Our kernel has a concept of ports. We also have a concept of pipes, which I believe Cyril demonstrated yesterday. We also have thread messages. And then there's also this concept of the BMessage object. And that's what I'm going to be focusing on now. But -- so just keep in mind there are other forms of messaging in our system.
The BMessage system is what the framework defines. The application framework, our kits. BMessages themselves are used in many places in our framework. I've tried to, and other people, we've always tried to leverage what we currently and what we already built in different places. So messages are used in our handling mechanism, our clipboard uses messages. When you -- when you're pasting information, when you're copying information, you're always moving data in and out of the Clipboard. And that is using the BMessage, API in a BMessage on our inter- and intra-application communication system uses BMessages. The scripting architecture which I will describe later on in my talk, that uses BMessages. You can use BMessages, a plain data container.
And two new pieces of our system, archiving and
the replicator technology, which Mark demonstrated
yesterday, and I'll show a little bit more about that in
this talk, that also uses BMessages, so it's a very key
and central part of our system.
So the BMessage class, what it is is a collection of name and value pairs. And each name has an associated type. So you can add some name data to a message. You can actually add values under that same name. They all have to have the same type. So you can see the sample code here, I have a BMessage object, this shows you how you add data to a message.
The API is a series of add type calls.
AddInt32. I do a second. So I have two values stored
under that one name. So you can think of it as an array
of data. And then I add a string under the name comment,
and then the last line, I try to add an int under the
same name, and that's not allowed because everything
under a given name has to have the same type. And new in
this current release is this API is extensible so that
developers can add their own types and add them to a
message and find them in a message. I'll show you the
reciprocal defined API shortly, how you get data out of a
BMessage.
So one of the main areas where messages show up
in the API is in our event handling system. So I'm going
to talk about that a little bit now. The main class is
called a looper. And you've probably heard of that class
before. And William talked about it yesterday in some of
his talks and it was probably mentioned in other talks as
well. It's our extraction for a thread running an event
loop. So if you're familiar with the Mac, on the Mac,
applications have one event loop where a message comes in
and it gets dispatched to the appropriate place. In our
system every looper is its own thread of execution and it
has an associated queue of messages. And the looper gets
messages out of the queue and it then gives that message
to the appropriate handler. So there's another class
called handler. And that's objects of this type actually
handle the message.
For example, system event like KeyDown, that message goes to looper, actually a window, every window in our system is a thread of execution. Every window in our system is one of these BLooper objects. BWindow descends from -- I can show you that slide. Here is a little class hierarchy where the looper, that thread of execution, every BApplication application is a looper. Every window is also a looper so it runs an event loop. So the looper gets these messages and gives them off to a handler. You can see a looper itself is a handler and so are views and other things in our system.
So a system event like KeyDown will come to the correct window. That window will say, okay, KeyDown is targeted for the focused view. And it will then give that message to the focused view. Event messages that aren't system events will just be given to the generic -- will be given to the generic method, MessageReceived. And I'll actually show you a little bit of sample code that kind of shows you the internal guts of what this event loop might look like. Here's some code that actually runs in the system. You don't write this code, but just kind of gives you an idea what this looper object is. So it runs -- basically, this while loop will wait for a message to come in. When a message comes in, it figures out who the target is, it figures out what the handler is for the message. If it's one of those system events like I previously described, it looks at the type of the message, for instance, if it was a MouseDown message or a KeyDown message, and it calls the appropriate Hook function.
For each system event that we define, there's a
corresponding Hook function that gets called. So in the
case of these two, a BView of the target would be a view
in this case because views are the things that handle
MouseDown messages and KeyDown messages, so this target
object is actually a view and you call the appropriate
Hook function.
Here is an example of the API for getting data
out of a message. A MouseDown message, one of the
interesting pieces of information is the location of the
mouse, and that's stored in this BMessage Class, in this
BMessage object. And there's a function called
FindPoint. You give it the name and you give an address
of a point and the data gets filled into that point.
Then we pass that point to the MouseDown function.
If it's not one of these system events, we go
down here to this else clause, generic MessageReceived.
That is to handle all the events that your application or
your view defines, extending the set of understood
messages.
So now let's look at a little code that a developer would actually write. Here is some subclass of BView and it's interested in both MouseDown and KeyDown messages, so you would override the two virtual functions, MouseDown and KeyDown, and these would get called for you by the system just in that code that we were just looking at. So you would then implement whatever it is that you wanted to do. In the MouseDown message you're past the point where the mouse click occurred. The BMessage actually contains more information about the event, such as when it occurred. Different system events have a different set of data that's contained inside the message. So if you want this extra information, you can always get a pointer to the current messages. And then you can go and find all the information you want.
And KeyDown is very similar, and from KeyDown you do whatever it is that your view wants to do. Typically, you would draw something or whatever. And then for events that you define, you would override the function MessageReceived. And you would have a case statement where you would switch on the various messages that you understand, and again, using the BMessage API, you would get out the relative data out of that message and do whatever it is that you would -- whatever it is that you do when you receive that message.
And I would like to point out -- let me
scroll. Calling inherited, working in a framework, you
always have to know when you're overriding a function,
should you call inherited or be -- there are many cases
when not calling is very critical.
For instance, in our view in window system, 99
percent of the time the right thing to do is call
inherited to enable all the functionality of our system.
So it's something that you have to keep in mind as you're
dealing with any framework really is when is it
appropriate or inappropriate to call inherited.
So you've seen a little bit on how you build a
BMessage object and you add data to it through the
various add calls. You've seen now how you handle
messages, you override system functions or you override
messages received. How do you get a message you've
created to an appropriate handler and looper? And so how
do you deliver a BMessage to its target? Well, there's
two cases that you can think about.
There's sending a message within your
application and trying to send a message between
applications. And there are two mechanisms, two
different APIs for delivering messages in our system.
The BLooper class itself has a post message function
where you pass it the message that you want to deliver,
and the handler inside that looper that you want to
deliver it to. Then there's also this class called
BMessenger, and I'll explain a little more about the
BMessenger class. I think it's on the next slide.
Now, when you're sending a message within the application, you can use either one of these APIs. When you're sending a message between apps -- I don't know if its obvious the first time -- you can't use the first API because that involves having a pointer to an object. If you're trying to send it to an object with another address space, that pointer doesn't mean anything. It's this BMessenger class that's key to sending messages between applications. You can think of the BMessenger as just a token for a handler looper pair.
Remember, all messages go to a handler in or under the control of a looper, like a view in a window. The BMessenger is just a token for that combo. This token is valid across the entire machine. If you have a BMessenger for some, you can send it a message, whether it lives in your own address space or some other address space.
So how do you create one of these BMessenger objects? There's two basic ways to construct one. One is you can give it the handler and looper you want to talk to. This you can do if you want to have a BMessenger as something in your address space. You might already have the pointers to window and view.
The second constructor is key to enabling interapplication communication. That's where you specify the signature of the application you want to talk to. One of the new things in this current release is we're now using MIME syntax for file typing and application signatures. So every application would have a signature that was a MIME-formed string on the Mac form ULongs. We're using MIME strings. You give it the signature of the application you want to talk to, and that would construct a messenger to that application, and then you could use that messenger to talk to the application object of that application. And once you have that first connection to the application object, you'll see in a short while the message -- the scripting architecture allows you to get messages to any object in that other application. Then you can start directly communicating with any of the objects in the remote application.
A SPEAKER: So what is BMessenger?
PETER POTREBIC: A messenger on the inside just this token for a looper and handler pair. I mean, the implementation is a looper runs this event loop and it has a message queue. This message queue is really a kernel port. It's this port mechanism that the kernel defines. And a port has an identifier which is unique across the machine. Just like a thread ID is unique, so is a port. Part of the token in a messenger is that port ID. Within an application space, every handler also has a unique token that's unique to that address space. So you put those two tokens together, and that gives you a unique token across the whole machine. And although currently the messenger architecture doesn't extend across a network, you can see how adding an IP address with these two other tokens would give you a token that was then --
A SPEAKER: Unique for the network?
PETER POTREBIC: -- unique for the network. In this current release messengers don't extend across the network, but we have that in mind as we designed this.
A SPEAKER: Applications?
PETER POTREBIC: I didn't hear the question.
A SPEAKER: Could you give a practical example of when there are multiple loopers in one application?
PETER POTREBIC: He asked the question, to give a practical example of when you have multiple loopers within one application. Well, any time you have an application with one window, you have two loopers. Remember, the application object itself is a looper and in every window is also a looper. So you have two threads. So every -- I mean, basically every application is going to have multiple loopers in the BeOS.
So now let's move into talk about scripting a little bit. Scripting uses everything you've learned to this point. It uses this BMessage architecture. It uses BMessengers to talk to other objects. And the architecture that we've defined in this current release is useful for an application controlling another application, it can be used by scripting environment, could be built on the BeOS, use this architecture to control a set of applications, it can define a scripting language. The scripting language would use the scripting architecture to send these messages. And a lot of the components in our kit have some built-in scriptability. For instance, our application object knows about the windows. Our windows know about views. Various views know about interesting attributes like each view knows about its frame. So right out of the box, any application will be scriptable to some level and then developers can extend that as appropriate for the domain of their application. If you're defining a database, you could create a concept of records and things like that that would then be scriptable through any scripting environment.
A SPEAKER: This is going to be open? There's not going to be a set like Applescript has the object model? There's not going to be separate model?
PETER POTREBIC: The question is in an Applescript if there was an object model which was separate from maybe your applications object model. In the BeOS, it's very -- well, it's not very tied to, but we leverage off -- every BeOS application has an object and messaging already because there are loopers and handlers and a BMessenger class which lets you send messages. So rather than kind of inventing a separate object model, just use the existing one that you're already defining because you're using our framework.
Now, you can extend that object model to include, you know, other entities that you define. You can subclass this handler object, which is a very light weight object. Basically all it is is this system -- this unique token within an address space. So you're not inheriting a whole lot of heft. So even the smallest construct in your application, you could say, I'll make it a handler and that way it can receive messages and you're not getting a whole lot of baggage. So it's not expensive to extend this object model as appropriate. So some of the lingo or language we're defining is similar to AppleEvents. Some of the words we use and some of the flavor to it.
Every scriptable object has what we call a set of properties. And these properties are, for example, an application knows about its windows, so windows are a property application. Views are a property of windows. Views are also a property of views because a window has some views. Each views can have views inside of it. Controls have certain attributes. Every control has a value. It has a label, things like that.
So these are properties, these are some of the properties that we've defined right in our kits so that -- this is why every application will be scriptable to some, to some level, and any objects that you define, you can extend the set of properties that it understands.
And properties are addressable via what I call
forms. For instance, you can ask an application for a
window named George or you can ask an application for the
first window. So those are the different forms by
which -- of the window properties addressable. In text
you might be able to say, I want the characters 5 through
10. So you're asking for text via range form. And
again, the sets of forms is also extendable by the
developer.
And we also came up with a concept that we call specifiers. And that's basically combining a property and a form. And that's a specifier. So an example, that first item is a phrase, frame of view George of Window 2. The first specifier is frame. And the second specifier is view George and the third specifier is Window 2. Each of those specifiers identifies a property, frame, view and window, and then implicit in that is the form.
Frame, since it's unique to the view, you don't
need any further qualification. It's just the frame.
There's not a first frame or a second frame, things like
that. For view, you can -- there's multiple views, so
you would have to specify it by name or by index and so
forth.
So let me show how you would build something like this programatically. What you have is we're building this BMessenger object. If you remember, the constructor takes the application. Imagine some application running whose signature is application/test app, a MIME string. You construct a message and set some property, the what field or type of message. Now we're going to add three specifiers which match. Those three specifiers match that previous example, the phrase frame of view George of Window 2. So to that message we add a specifier frame and then we add a specifier view George and we add a specifier Window 2. So we're trying to set the frame and then we give the data that we want to set the frame to. And then we send the message. So you could -- so you can imagine that a scripting environment would take some more human readable expression, parse that, translate that into these lines of code and send it off to the target application and --
A SPEAKER: Is there terminology there? Do you find a terminology resource which tells you what terms or what specifiers or properties available?
PETER POTREBIC: The question was if there was a defined format or location of where this terminology would be defined. So an application and enhanced scriptability. How do you know about that stuff? That's something we're currently still working on, on how that -- where that information would live. There is some supportability in at run time. Every object, you can ask for its suites that it supports and we expect to have suites of evolve, like just in the Mac world where you have a simple text editing suite or a database suite. So you ask an object, what suites do you understand? If it comes back and tells you, I understand a simple text, manipulation suite, that implicitly tells you ten different kinds of script messages it understands.
A SPEAKER: Can you ask an object for its properties, specifiers?
PETER POTREBIC: Right now what you can ask is what suites you understand, so you can't ask for a list, enumerated list.
A SPEAKER: Peter, repeat the question.
PETER POTREBIC: He asked if you have an object tell all the properties, specifers it understands. Only at the high level what are the suites it understands. It won't give you back an enumeration of all of the individual messages that it understands.
A SPEAKER: And that is what version it supports?
PETER POTREBIC: Pardon?
A SPEAKER: As suites evolve, can handle more things, what are you going to do?
PETER POTREBIC: The question was as suites evolve, how are we going to handle that. The name of a suite is also we're using the MIME form string, so a suite would be called suites/simpletext. So you could have suites/simpletext. If there's a new version, you could call it simpletext.1.1. So when you ask an object, what do you understand, it could return both simpletext and simpletext1.1 as, you know, suites evolve. One more question and then I'll get back. And I can't answer all of them.
A SPEAKER: Can you ask for a BMessenger that handles a suite type instead of a particular app?
PETER POTREBIC: I have a post-it note. The question was, can you ask for a messenger that handles a particular suite type rather than asking for messenger to a specific object, and I have a post-it note under my machine saying that same thing. Currently, no, but it's something that I'm definitely thinking about. I'm thinking about a messenger that handles a suite and also give me a messenger that handles text/plain. The same kind of thing.
A SPEAKER: Through the raster, also.
PETER POTREBIC: Exactly. I'm thinking about that. I would like to do that. It's just not there today.
So this message that we built, I wanted to show you kind of graphically what the message looks like. So this -- the big box here is kind of the first message we created and the specifiers get kind of linked in with this message and here is the data. So this gets delivered to the test app, the destination application. And part of the scripting architecture, what it does, it manages kind of the translation or the getting of that message to its final destination which is view George. So the application precedes the message. It looks at the Window 2 specifier. It says, okay, I know Window 2. It also knows that Window 2 is also in another thread of execution.
So that message will then get sent to that
other thread of execution, the window. The window will
then be given a pointer to the view George specifier.
And it will say, okay, I know about views. And it looks
for the view named George and it then delivers that
Message to view George and view George says, okay, I know
about frame. I have a frame and I'm supposed to set my
frame to this so it carries out the execution.
So what the script architecture does is enables
you to build this style of message and it also manages
the movement of the message through your application.
And as you extend the set of specifiers that you
understand, you're just asked questions at the
appropriate time. Do you understand view George? And
the system handles, okay, now, deliver it to the next
guy.
Now, I wanted to give a little demonstration of the scriptability of our system. I'm going to launch the network preferences app and I'm not sure if the author of the network preferences app is here. I guess not. But he didn't do anything. I mean, he probably doesn't even know you can do this with his application. And I wrote a little -- I just wrote a little cheesy interpreter in like 22 minutes that -- so this is not a proposed scripting language that you are going to see. It was just something to demonstrate the scriptability. So what I'm doing here is I'm -- that's low. Yeah.
So what I'm doing here is I'm telling my little script interpreter that I want to speak with the network application and I'm asking it to get the title of the Window 0. Up at the top you can see the title of Window 0 is Network. So I execute that. And I get back Network. Yea.
Whoa. Sorry. My little control fell off. So now I'm going to set the title of that window. And the title of that window changed. There's obviously a lot more you can do with this and I'm going to reposition things a little bit so it's a little bit more visible. I'm just going to focus on this area of the network app. And you can do things like query a control. I've mentioned this before. I can query the value of a control. I just executed a command that asks for the value of the view called FTP Enable, which is that check box up there. These names I'm using are kind of internal names, not the user visible names. So this is what -- part of publishing what your application in the scriptability of the application, would be the names of some of the interesting pieces of your application.
A SPEAKER: So the suite would say, here is the suite, and these are the names linked to all this?
PETER POTREBIC: Right. So you can see the value is zero and then I can set the value to 1. You see it's just like the user selecting the check box. And I don't know if you noticed, but that also then enabled the revert and save buttons as appropriate.
Yes?
A SPEAKER: What happens if your application has made assumptions about the state of its UI? Would they get invalidated by someone else's script? Is there ways of your application becoming unstable by that?
A SPEAKER: You're actually doing the same thing with UI.
PETER POTREBIC: The question was, what about --
A SPEAKER: What if it makes an assumption about its own state?
PETER POTREBIC: What if the application makes an assumption about its own state and the scriptability kind of interferes with that. Well, in what I've showed you, well, in clicking the check box, that wouldn't interfere with that because it is just like the user, clicking on the check box. What I showed you before, changing the name of a window, well, that depends. What I'm going to show you now definitely would have issue, but I thought it was a fun demo so I'm going to do it anyway.
I'm going to run this little script here that's just five or six -- I guess -- did it open? That's five or six commands and it deleted a whole bunch of views, it changed the name of the text. And that certainly would. I didn't actually believe that. Each view has a hidden attribute so you can query are you visible or not visible. So all I did was I hide the buttons and check boxes and things like that. So they're still there. They're just not being drawn.
Anyway, that just shows you a little of the scriptability right out of the box, and applications, of course, will be scriptable in more interesting ways when you can talk to the records in a database, things like that. I want to talk about -- oh, let me back up. I did want to point out some really key features. In all of the messages we've been talking about so far, the -- I want to get one up here on the terminal. We've been doing things like -- let me raise the window, too -- we've been doing things like I'm interested in some property of this view, of this window, of that application.
So if you remember the diagram of the message, that -- the message would go to the application, the application said, oh, it's for this window, the window said, it's for this view, and the view would finally get it. So you had all this extra work going on. One of the key, I think, features in our system is that you can short-circuit that if you're going to be sending a whole bunch of messages to the same destination. You can actually get a direct link right to that object, circumventing all that extra traversing. That's through a property called messenger. So every object, you can ask for its messenger. So I can say, get me the messenger of view FTP user of Window 0. When I execute that and my interpreter can't represent what this message option looks like, it just says, got a messenger. So I receive that token back so I can reuse that token. If you have a scripting environment, you can say X equals that expression. Now you can start talking to that view directly, which really increases the through-put, the performance.
I believe in some other systems actually there's one queue for every Apple -- well, I don't know -- every event in the whole system, right. And the first thing I showed you was every event for an application was going into one queue. It would first go to the application. So different applications would have their own queue. Now what I'm showing you is you can directly talk to any object that you want to. So that will really increase the performance of the scripting system.
A SPEAKER: Is there any way that your application can recognize whether it's getting a message from an intra or an inter message?
PETER POTREBIC: The question was if an application can recognize if it was getting a message from an external source or an internal source, and yes, there is. When you receive a message, there's a couple calls you can make and you can determine things, is the sender remote, you can also determine -- you can send messages synchronously. Is the sender waiting for a synchronous reply? With the drag and drop, you may have seen some of our drag and drop capabilities. It also uses BMessages, which I failed to mention. Did I get this message because of a drop? So all those interesting kind of attributes of a message you can determine for -- to -- for things like security purposes or whatever.
So now I wanted to move on to talk a little bit about replicators. Did people see the demonstration of it yesterday?
A SPEAKER: Yeah.
A SPEAKER: Yeah.
A SPEAKER: Yes.
PETER POTREBIC: It's, for lack of a better term, kind of like a simple or small component framework. And it's new in this release and it allows applications to share functionality, to share code, to share data types that they understand. We can kind of -- it kind of came out of a couple things. In DR9, in this current release, I was adding archiving to our system, which was a feature so that you could take any of our framework objects and you can archive them, which is basically turning them into some -- into a form you can store on a disk and later rehydrate that object in all its full glory. So you could take a window and archive it and rearchive it with all of its views and subviews. If developers out there have subclass of view, you could work in this archiving architecture so that when the window is archived and recreated, your view gets recreated.
So it's taking that capability along with the dll features we support and a little bit of magic stuff. I'm willing to explain it if there's time and questions. And this resulted from the technology called replicators which lets you drag and drop application components into other applications. And I'll give a little demonstration of that.
Unfortunately, I forgot to set up this part of
the demo. Well, hopefully most of you saw this
yesterday, but this is the pre-Thursday version of net
positive, so I won't be able to show you web pages on the
desktop, but I can show you a couple of other things.
New in our UI is a menu item in the desk bar which is called show draggers. What that does is that will -- and focus here on the clock application -- that will make visible all of the replicant and replicatable components that are currently visibile. And you can pick up that component. This is a little clock application, just a simple clock face in a view. I can pick that up and drag it onto a container view, and the desktop we've defined as being a container view, and I can drop it on the desktop. And now I have a completely independent clock face. I can close the clock application. Notice, when I close it, it will disappear from the desk, the desk bar menu, so the clock application is no longer running, but I still have a completely functional clock face living inside of the tracker living inside of the desktop window.
I also have a little sample, piece of sample code which I don't believe we've -- we didn't put the code on this in this current CD, but we will make it available shortly. What this is, just a little sample app which shows how you become a container view. It's very simple. I think Steve, the author of the tracker --
A SPEAKER: With help from Peter able to do it in seven lines.
PETER POTREBIC: So seven lines of code in the tracker to support dropping the clock on the desktop. You can now drop net positive views on desktop. Seven lines of code. In this sample app you'll see basically those seven lines of code. I can pick up the clock face from the desktop, drop it in here, drop two versions. I can independently get the Be Face, consistent data, so when I close this and relaunch it, the clock faces are still there. That was all done by Steve in the tracker, seven lines of code. And to make your application replicant savvy or to make parts of your application replicatable onto the desktop is also on that same order of magnitude and complexity. And I just don't have the time to go through all of it here. There will be a newsletter article on this, talked about in the BeBook and I think Mac Tech is going to have an article on this, too.
A SPEAKER: How do you get rid of the clock?
PETER POTREBIC: That's a good question. Before we really ship this current release, you will be able to drag it to the desktop. This little hand does contain a contact-sensitive menu inside of it just like other contact-sensitive menus you've seen. So you bring up that contact-sensitive menu and you can get a little BeBox. I thought developers might like to have some copyright information even though you've ripped out a piece of their application, so this is a place where you can still credit yourself for doing all the good work. And through there there's also a delete, so that will remove it from whatever container it's living in.
A SPEAKER: So you could grab a replicant and ship it?
PETER POTREBIC: What?
A SPEAKER: If I grab a replicant out of another application, I could ship it?
PETER POTREBIC: The question was, could you actually grab a replicant from another application and ship it, and the answer is yes, you could.
A SPEAKER: The replicant is a link to the application or a copy?
PETER POTREBIC: The question is, is the replicant a link to the application or a copy? What a link is, you take it -- you archive the object and you also archive information that points to the code, either an application itself or an executable or library that defines the -- that provides the code that can recreate the object. And so it's really a link to that object. So when the clock view is living inside of that container app, that container app has actually loaded the dll or application, whatever that defines that application.
A SPEAKER: So if you don't do it, you've deleted the clock from the system?
PETER POTREBIC: Right. The question was, if you deleted the clock executable, what happens to the replicants that are living in this little demo app. Yeah, they would no longer function.
A SPEAKER: Do you get black frames?
PETER POTREBIC: That's kind of -- the question was, do you get black frames or do they go away entirely. And that's in the area where I need to do more work. Right now they just don't appear.
A SPEAKER: It probably crashes.
PETER POTREBIC: I'm just about done and then I can take questions. I was going to get my watch out to see what time it is, but I guess one fellow at work actually put 200 clocks on his desktop. It was pretty funny. Okay. The thing is he didn't know how to delete them and we showed him the pop-up and he said, "Come on, I'm not going to do that 200 times." And, I mean, he's right.
So I've really only scratched the surface of what our messaging and scripting architecture enables. I didn't even talk about some of the pieces of our system that uses messages. I briefly mentioned the Clipboard and our Clipboard uses messaging. And one of the new things is we support multiple clipboards. There's the system clipboard where normal copies and pastes go, but an application can define a clipboard under a certain name and that gives it -- and another application, with that same name, that gives you a conduit through which you can share information. That's all done in messaging, BMessages. Our MIME typing system uses BMessages in various places so there's a lot there.
But don't feel like you have to kind of understand all of these things at once. You can really approach it and understanding, okay, loopers and handlers and messages and an event loop, and once you have your application up and running, then you can decide, okay, wouldn't it be neat in the check mail button if my application was a replicant and I can drop it on the desktop and I could -- users could check mail this way. You could approach that. You don't have to think about that right away since it's all built on top of BMessages, all little increments on top of what you already learned.
And there's -- I'm trying to provide as much information as possible. I mentioned I'll be talking about replicants in a newsletter and a Mac Tech article and BeBook is a good resource in sharing experiences with each other.
That's all I have. Questions now.
A SPEAKER: How is the DR9 documentation different from the DR8 BeBook?
PETER POTREBIC: The question was, how much different are things in DR9 versus the documentation what happened in DR8? In terms of the BMessage the API has changed some, but in trivial ways. It used to be AddLong and now there's AddInt32. So just changed the name. So that's pretty simple. But nothing basic other than that has changed in terms of new messages and the events model with handlers and loopers. So all of that stuff translates. Most everything has been just an extension. Like multiple clipboards is just an extension of what we had before. The scripting is just an extension to what we had before. So all that conceptual background and what's described in BMessages still -- in DR8 documentation still applies.
A SPEAKER: Is Be thinking forward to have a base common language for BeOS?
PETER POTREBIC: The question was, are we thinking about a base common language for the scriptability on the BeOS. And the answer is yes, we are thinking of one. But the way we're thinking of one is it would be really great to have Frontier on our system. I don't know that we're necessarily the -- should be defining what it is the developers want to use in terms of a scripting language. And we -- multiple languages could co-exist and there's pros and cons to, oh, yeah, I don't want to learn ten languages or one language, but with the common scripting architecture, you shouldn't ever be required to use a particular language because that's what it comes to -- because that's what some application comes with. You should be able to use Frontier to script that application just the same because the underlying architecture is -- everyone is going to have specifiers and forms and things like that.
The back?
A SPEAKER: Why is it you chose not to do an enumeration property?
PETER POTREBIC: I thought about that. It just seems there's -- and I'm still thinking about it. It's just very rich. There's properties. There's what forms are applicable to a property. It's not just knowing that an application knows about windows. It's that you can only ask for a window by index and by name. So and -- it's just -- it was a fairly -- okay. In a rich set of information and kind of the way we do things at Be is we try to look at a problem and find the 60 percent or the 80 percent that's really -- that will get you the most, you know, bang for your buck, and we try to get that out there as soon as we can and then we continue working on that area, to try to give you what else is out there. So by no means what I said here is the end of the line in terms of the functionality we're going to provide, but it's just let's try to define this level and then -- because -- and then try to bump that up as we can.
Over here?
A SPEAKER: First of all, you guys have done a great job. You've done a much better job than Apple did.
Secondly, I want to second what he's saying. I think you need richer data in order to really understand what's app successful. And finally, a question having to do with did you guys release the descriptors or really just Window Number 1 or a window with a name? Applescript has -- AppleEvents has a thing called Whose Descriptors, which are generic ways you can compare.
PETER POTREBIC: The question was, do we support Whose Descriptors, and for instance, you then have a query like get me the frame of the window whose -- whose position is here. Some other -- and I thought about that as I was developing this. I thought that Whose terminology, in my mind. But I guess I could use the same answer I just gave. Let's try to get out there with this amount of functionality and then try to come out with the next amount, as opposed to trying to come out with the world right off the bat and it will just take forever. Plus, then it doesn't give us a chance to get good feedback from you guys, should we go this route, that route.
Over there?
A SPEAKER: Two questions and both kind of short. The first one is, is it possible to, say, subscribe to events that are occurring in application without having to do it repeatedly? And the second question is, does the replicator model provide any type of support for resources that an object may be using beyond the event descriptors?
PETER POTREBIC: The second question, does the replicant -- and I will add the archiving capability, support saving and restoring things like file descriptors and things like that -- and the answer is no. It doesn't. Right now the archiving capability is basically for archiving -- it's limited to archiving a tree of objects. So it doesn't even gracefully right now handle -- you have two objects and they both refer to it, the same third object. Your code has to manage, okay, who is going to archive that so that you don't get two duplicates. And again, I've thought about the issues and how to enhance that. So that should be coming down the road. And then the second -- the first part?
A SPEAKER: The first question was is it possible to subscribe to events that occur in application?
PETER POTREBIC: The first point was is, it possible to subscribe to events in an application to kind of know what's going on, kind of like watch points in the file system. Right now, within an application itself, you can do some of that snooping. You cannot do it between applications currently. But it is something that I have thought about. But it's not currently there. I don't -- is someone going to kick me out when I run out of time?
A SPEAKER: You can answer just a couple more questions.
PETER POTREBIC: A couple more questions.
A SPEAKER: I've got two.
PETER POTREBIC: Pick one.
A SPEAKER: All right. For replicants like dll's since they're not -- you can't drag around, what method would you use?
PETER POTREBIC: The question was, for a replicant that's just defined in a dll, since you can't double click and launch it as an application, how do you get at its UI to share. That's a good question. My idea with replicants, not just meant for a drag and drop, meant for the user. I've got other ideas on an application might just send some other application a replicant, not because some user dragged and dropped it, but because that was, you know, an interesting thing to do. The little -- the little status view in the desk bar is actually a container view. That can take replicant. So an application might just send that view a replicant saying, put this little icon in there, a little status indicator that you have new mail waiting to be read.
Other ways, other than just drag and drop, so a replicator making an add-on -- you know, it could be accessed through that type of model is one possible solution. But that is a good question. I'll have to think about that.
Okay. One more question.
A SPEAKER: How does a replicant get information about the container?
PETER POTREBIC: Through the scripting architecture.
A SPEAKER: Repeat the question?
PETER POTREBIC: Oh, sorry. How does an object, a replicant, get information about its container? And you can ask -- also ask how does the container get information about the replicant, and that is through this -- through the messaging architecture and the scripting architecture. So, for instance, if I drop the clock view in its container, the container could have the view what suites do you understand. It can ask things like how big are you, things like that, if this container view wants to do some type of layout. So reversing it, the object, could also ask the container, you know, what are you?
A SPEAKER: So you could actually set up something like links that open, at a link, you can actually set up a link?
PETER POTREBIC: The question was, can you set up links between these components as you drag and drop it, and yes, you could.
I guess that's all we have time for. Thanks a
lot.
Home | About Be | Be Products | BeWare | Purchase | Events | Developers | Be User Groups | Support