Register to post in forums, or Log in to your existing account
 

This forum is locked: you cannot post, reply to, or edit topics.  This topic is locked: you cannot edit posts or make replies.     Home » Forums » General zApp Discussion Goto page 1, 2  Next
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Mon Apr 18, 2005 11:31 pm   

Changes to zApp events
 
As I've started getting into the documentation of zApp events, I have realized that they are not implemented properly. So, before too many people start using zApp for real applications, I'm going to make a big change to the event handling right now.

In the previous versions, you would define an event handle via a subroutine in the scripting language. For example, to handle a KeyPress event, you would have done something like this:
Code:
sub ControlName_OnKeyPress( Sender, Param)
  handle event here
end sub

The problem with this is that it is dependant upon the implementation of subroutines or procedures in the particular scripting language you are using. The above code works fine for VBScript, but would be handled differently for other languages. And the differences in argument passing of various languages makes this implementation incorrect.

I also realized that the above implementation was very "un-zApp-like". It just didn't fit with the XML syntax of the application.

So, here is how I'll be implementing events in the next version. You'll just define a <SCRIPT> object within the control that you want to assign an event handle for, and set the EVENT property of the SCRIPT to the name of the event you want to handle. For example, to handle the OnKeyPress event like we did before, the new code would look like this:
Code:
<CONTROL...>
  <SCRIPT event='OnKeyPress'>
    handle event here
  </SCRIPT>
</CONTROL>

Also, each control adds properties for the events, so that you can also use the shortcut definition like this:
Code:
<CONTROL OnKeyPress='event code here'/>

The advantage of using the <SCRIPT> tag is that you can set the Language of the script to something other than the default. When using the inline property, the language of the event code is assumed to be the default language of the application.

The way I've handled the parameter passing for the event code is using the same syntax as before. Each event handler has access to a "Sender" object, which points to the zApp object that issued the event, and a "Param" object which contains the parameters for the event handler. By handling these objects as COM objects within zApp itself, it is no longer dependant upon the argument passing methods of the scripting language itself.

As a specific example, if you look at the CALC.ZML demo program, you will see the OnKeyDown and OnKeyUp events handled for the overall window. Here is the old code:
Code:
<WINDOW name='main'...>
   ...
  sub main_OnKeyDown( Sender, Param)
    S = GetKey( Param.Key)
    if (Len(S) > 0) then
      core.Exec( S &amp; ".Down = true")
      Param.Key = 0
    end if
  end sub
  sub main_OnKeyUp( Sender, Param)
    S = GetKey( Param.Key)
    if (Len(S) > 0) then
      core.Exec( S &amp; ".Down = false")
      Param.Key = 0
    end if
  end sub
  ...
</WINDOW>

and here is the new code:
Code:
<WINDOW name='main'...>
  <SCRIPT event='OnKeyDown'>
    S = GetKey( Param.Key)
    if (Len(S) > 0) then
      core.Exec( S &amp; ".Down = true")
      Param.Key = 0
    end if
  </SCRIPT>
  <SCRIPT event='OnKeyUp'>
    S = GetKey( Param.Key)
    if (Len(S) > 0) then
      core.Exec( S &amp; ".Down = false")
      Param.Key = 0
    end if
  </SCRIPT>
</WINDOW>

This change should make it easier to handle events in zApp just like writing any other script, and should allow zApp to deal with different scripting languages much better than before.

Hopefully this syntax change is easy enough that anyone who already implemented event handled won't have much trouble changing the syntax. Once zApp has a public release, I'll pay more attention to backwards compatibility, but this was a case where I really needed to make a change and remove the old method of handling events.
Reply with quote
theNerd
Adept


Joined: 01 Mar 2005
Posts: 277

PostPosted: Mon Apr 18, 2005 11:49 pm   
 
Yup! I like this change. I'm glad you made it.
Reply with quote
Kiasyn
Apprentice


Joined: 05 Dec 2004
Posts: 196
Location: New Zealand

PostPosted: Mon Apr 18, 2005 11:56 pm   
 
Me too :D... and theNerd... do you just like sit on the forums all day :p
_________________
Kiasyn
Owner of Legends of Drazon
Coder on Dark Legacy
Check out Talon, an easy IMC connection.
Reply with quote
theNerd
Adept


Joined: 01 Mar 2005
Posts: 277

PostPosted: Tue Apr 19, 2005 12:32 am   
 
@Kiasyn: Pretty much! I'm hoping to increase my Posts count to as much as Zugg has. As of now I only need 9426 more posts to go. Laughing

At work I have two computers, one with the monitor facing the isle (I do actual work on that one) and the other facing the other way so no one can see what's on the screen. That's the one I have the forum on Very Happy I just press F5 to refresh the Forum peridoically to see if anyone's posted something worthwhile. Wink
Reply with quote
theNerd
Adept


Joined: 01 Mar 2005
Posts: 277

PostPosted: Tue Apr 19, 2005 12:34 am   
 
@Kiasyn: Hey! Shocked How would you know if I sat on the forums all day if you weren't on them yourself all the time? Razz
Reply with quote
Tarn
GURU


Joined: 10 Oct 2000
Posts: 867
Location: USA

PostPosted: Tue Apr 19, 2005 4:28 am   
 
Zugg:

I like the syntax.

Does Param always have an index property in case the item is a control array? How will events be handled if a control is loaded at runtime? (thought I remembered this as being possible in zApp but I don't mind if it isn't). How will events be handled for objects that are not controls on forms?

theNerd:
Quote:

@Kiasyn: Hey! How would you know if I sat on the forums all day if you weren't on them yourself all the time?


Looking at the intervals between Zugg's posts and your replies would be one way :)

-Tarn
Reply with quote
Tarn
GURU


Joined: 10 Oct 2000
Posts: 867
Location: USA

PostPosted: Tue Apr 19, 2005 2:58 pm   
 
OK, I found the AddControl function in the core library, but I'm not sure how I'd respond to events on them with the new syntax.

Just thought I'd add an example to my previous post: When writing a server in some languages, it's pretty common to have a socket control array, into which you load additional controls at runtime as you need them. Example: a chat server when you don't want to be restricted to a fixed number of connections, or suck up the memory and resources for 100 of them right when you load your program because you might only need one.

I don't like representing things like sockets as visual controls, but there are a lot of popular controls doing things that way- the SocketWrench ones for example.

Another time you might not know how many controls you'd need at runtime would be if you wanted to tile a selection of images and accept user events on them (mousedown, etc).


-Tarn
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 19, 2005 4:24 pm   
 
I think that I mentioned in my post that there are *two* new ways to handle events. The first involves the XML code, which you can't use for a control added at runtime. But the second involves a property name for each event. So, you'd just assign your event script to the Control.OnKeyPress property (or whatever the event name is).

Something like this:
Code:
Set C = core.AddControl( "Button", "MyButton", "MainForm")
C.OnClick = "msgbox ""Hello world"""

As far as your array question, I haven't seen any events that send array parameters. Since arrays tend to be very implementation dependant, most people stay away from them. What you usually get is an object or collection that takes an index, and that would work just fine.

The stuff you are describing for socket arrays won't be handled that way in zApp. zApp network objects are typically a much higher level. For example, with the HTTP component in zApp that handles web servers, the socket array is handled internally and it only creates as many sockets as it needs dynamically. Having a fixed array is a very poor implementation for a server. Any other server component in zApp would handle the connections internally like this too.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Apr 19, 2005 4:26 pm   
 
Oh, if you want more information on how zApp network sockets and other network components will likely be implemented, take a look at the Indy component set at www.indyproject.org That is the component set used in zApp and they are one of the most highly used and recognized network components for Delphi. You can read their documentation to see how you might use their sockets to create servers...you never end up creating individual socket arrays like you were talking about.
Reply with quote
Tarn
GURU


Joined: 10 Oct 2000
Posts: 867
Location: USA

PostPosted: Wed Apr 20, 2005 3:47 am   
 
[quote="Zugg"]
Something like this:
Code:
Set C = core.AddControl( "Button", "MyButton", "MainForm")
C.OnClick = "msgbox ""Hello world"""

[/quote]

Excellent! That even gives the ability to add or change code at runtime (via the string you assign).

Quote:

As far as your array question, I haven't seen any events that send array parameters. Since arrays tend to be very implementation dependant, most people stay away from them. What you usually get is an object or collection that takes an index, and that would work just fine.


It wouldn't be something you'd directly see in the control documentation- it's part of the background handling of languages like VB to add Index to the event call arguments if you have a stack of identical controls with the same name. In C++, I'd generally use callbacks like your syntax above (which is more flexible because you can pass whatever data you want around, but also results in a little more work for the coder).

The approach you have just explained is powerful and reasonably intuitive to me, probably better for an interpreted language than the C++ passing of a pointer to a function.

-Tarn
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Apr 20, 2005 4:34 am   
 
Right. In Delphi and zApp you get event routines and they are passed a reference to the socket being manipulated. For example, when you receive data from a client, the server fires an event and passes the socket that you can read the data from as an argument to the event. So you never have to deal with the internal list of sockets, you just have to implement the event handlers.

zApp should handle this very easily with the new event structure. And yes, as you mentioned, a nice side benefit of the new architecture is the ability to assign a different script to an event at runtime. In the past you were stuck with a fixed procedure that you couldn't change. Now the event handling can be more dynamic.

The downside is that the event code is executed in the global context. Variables in the event handlers can conflict with each other potentially. Of course, you can always create a subroutine just like before and just call it from the event handler script and then you can have local variables within the subroutine again.

Finally, remember that in scripting languages you never deal with pointers directly. You are always using objects (COM objects specifically). So, you end up getting the power of C++ where you can reference complex objects, but all of the memory management is done for you. It's a great example of how COM handles memory management and lets you program without worrying about it. Microsoft makes all of these great claims about the memory management in .NET, but in reality it has already worked well in normal COM.

Notice that in zApp applications you never worry about allocating memory, or dealing with pointers. COM objects are created on the fly and destroyed when no longer needed and you never have to worry about memory management. You get powerful dynamic memory structures like Collections that can contain an unlimited number of objects without ever worrying about reallocating the memory to make the collection bigger. zApp is all about making programming easier and simpler, but retaining the power needed for modern user interfaces and modern applications.

This makes zApp easy for people used to scripting web pages where you also rarely worry about memory management, but might be a bit foreign to people used to programming in "old" languages like C/C++ or even Visual Basic.

One of these days soon I want to write a white paper on all of this. It might help people understand what zApp is really all about.
Reply with quote
Tarn
GURU


Joined: 10 Oct 2000
Posts: 867
Location: USA

PostPosted: Wed Apr 20, 2005 3:51 pm   
 
Zugg wrote:

The downside is that the event code is executed in the global context. Variables in the event handlers can conflict with each other potentially.


Hmm, or even the Obj and Params arguments themselves. That could be a potential gotcha for newbies- doing something in their event handler that causes an object to raise another event before the first one is completed. Maybe the basic examples should guide them by calling functions instead of doing lots of work in the global namespace.

If you expand your comparison of zApp to other languages, one of the points you should make versus VB is the ease of handling events from a large number of non-control objects: in traditional VB you have to either have a controlarray or specific references to each object that you're listening to events from. Thus, it's a pain to watch for events from a collection full of something without doing a workaround like adding a manager object. There's probably a better way under VB.NET, but I haven't had to do it yet.

-Tarn
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Apr 20, 2005 4:40 pm   
 
Actually, zApp is smarter than that. It implements the Param and Sender objects as stacks. When an event handler is called, the new Param and Sender values are added to the stack. When the event handler ends, the previous values are popped off the stack. So, having one event called from within another event works just fine.

Since all zApp scripts operate in the global namespace, I think people will get used to that. It has both advantages and disadvantages, but the idea of using unique variable names, for example, rather than having every script using some generic variable like "I" is just good programming style anyway.

One of the problems with using a procedure or function is that once a function is defined within the scripting language, there is no way to override it. And by allowing you to assign a script to a property, people might find it odd that they can't define new functions by just assigning a new script value.

In general, all global objects in a scripting language are persistent. It is only via some tricks in my own scripting host implementation that I can allow something like "Param" to reference a different object depending upon the context.

I've never done anything serious in VB, so I didn't know about the complex event handling that it has. Sounds like it's a pain alright.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Apr 20, 2005 4:45 pm   
 
Actually, I'm going to make another change while I'm at it. I'm going to change "Param" to be called "Event". So, for example, to reference the Key argument of the OnKeyPress event, you would access "Event.Key". This helps remove the problem where some people were using "Param" and some thought it was "Params".

Also, I'm making "Sender" just another property of the "Event" object. So instead of referencing Sender directly, you use "Event.Sender".

This should all make it clearer in the script when you are performing event handling.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Apr 20, 2005 5:19 pm   
 
Blah!!!

Silly VBScript reserves the "event" keyword. I can't even trap it in my scripting host. So, something like this:

a = Event.Key

gives a syntax error without any way for me to override what "Event" refers to. Bad Microsoft!!

(And I can't even find a reference to the Event keyword in my VBScript book, so I don't have any idea why this doesn't work)
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Apr 20, 2005 5:34 pm   
 
Wow, I just can't express how upset I am about this silly "event" keyword restriction in VBScript. I've searched via Google and have learned than there definitely is some kind of "event" keyword in VBScript that conflicts with this, but I can't find any information on what this keyword actually does! I can't believe that the VBScript parser is so dumb that it can't handle any variable called "event".

And I *really* wanted to use that variable name!

Anyone have any other suggestions on what to call this object? I still don't like the original "Param" name. And I want it to be something easy to use and remember.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Apr 20, 2005 5:49 pm   
 
Well, for now I'm going to use "event_" as well as "event" for this object. In a scripting language other than VBScript, you can use "event" just fine. In VBScript you just use "event_" instead.

So, to access the Key parameter of an event, you call "event_.key".

Not sure I like it, but it's easy to change if someone comes up with a better idea. At least it allows me to get on with my work for now.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Thu Apr 21, 2005 1:12 am   
 
I really think events are one of the most important thing to be able to hook and handle. I would hate to have to type the underscore that often for such a silly reason. I would suggest zvent or zevent.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
theNerd
Adept


Joined: 01 Mar 2005
Posts: 277

PostPosted: Thu Apr 21, 2005 1:33 am   
 
Or, you can change it from
Code:
 event_.key
to:
Code:
Zugg_is_the_greatest_developer_ever.key
or:
Code:
I_want_to_send_theNerd_all_my_money.key
Reply with quote
Kiasyn
Apprentice


Joined: 05 Dec 2004
Posts: 196
Location: New Zealand

PostPosted: Thu Apr 21, 2005 1:37 am   
 
zEvent!!
_________________
Kiasyn
Owner of Legends of Drazon
Coder on Dark Legacy
Check out Talon, an easy IMC connection.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Thu Apr 21, 2005 2:01 am   
 
I think zEvent might be it.

But theNerd, I think you made a typo in one of your suggestions. The first suggestion is good, but I think in the second suggestion you meant to say:
Code:
I_want_to_send_Zugg_all_my_money.key

Wink
Reply with quote
theNerd
Adept


Joined: 01 Mar 2005
Posts: 277

PostPosted: Thu Apr 21, 2005 2:07 am   
 
Laughing
Reply with quote
Tarn
GURU


Joined: 10 Oct 2000
Posts: 867
Location: USA

PostPosted: Fri May 06, 2005 6:08 am   
 
I've been thinking about events recently.

Is it possible for more than one chunk of code to monitor an event?

Example:
An email app with a mailbox object (not a control) has a "NewMail" event (ok, zEvent ;) ). The app monitors this event to update the inbox display via assigning the zEvent property. An end user who misses AOL wants to write a plugin for the app that says "You've got Mail!" when new mail arrives (using the same event on the mailbox).

The plugin can't just assign the property, though, because that would overwrite the app's event handler, right?

Maybe the property should be a collection of event handlers, all of which will be called.

-Tarn
Reply with quote
slicertool
Magician


Joined: 09 Oct 2003
Posts: 459
Location: USA

PostPosted: Fri May 06, 2005 6:26 am   
 
wouldn't the plugin be just a sub that particular event trigger would call before/after the regular code happened? so essentially an append instead of an override.


slicertool




(edit by Tarn: darn- too tired- I hit Edit instead of Quote and tried to restore this way- sorry. I owe you one. )
Reply with quote
Tarn
GURU


Joined: 10 Oct 2000
Posts: 867
Location: USA

PostPosted: Fri May 06, 2005 1:50 pm   
 
slicertool wrote:

wouldn't the plugin be just a sub that particular event trigger would call before/after the regular code happened? so essentially an append instead of an override.


I think that you mean the plugin should do:
Code:

mailbox.OnNewMail = mailbox.OnNewMail & MyOwnHandler

(or that zApp should?)

I can see two problems:
1. the parent app might have code like this:
Code:

If spamchecker.IsSpam(mailbox.messages(mailbox.messagecount)) then exit sub


2. If a module wants to remove or change its own event handler, it has no idea where in the handler its own code is (unless it did something like add comment flags with GUID's):
Code:

'AOLHomesick handler begin D5E6E8FD8
CallMSVoiceLib "You've got Mail!"
'AOLHomesick handler end D5E6E8FD8


A given module might not even know whether or not another module is monitoring an event: the assignment could be in a ZXL rather than ZML, and/or the monitoring might not be done all the time but only if certain flags are set in the other module.

-Tarn
Reply with quote
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.     Home » Forums » General zApp Discussion All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
© 2009 Zugg Software. Hosted on Wolfpaw.net