How to pass String parameter to Notify() and receive that parameter to Notification()

Say for example, I use variable

LOC:Param1 STRING('hello')

I want to push a notify to a certain thread

NOTIFY(NOTIFY_NEW_MSG,GLOTHREAD:BGSERVICE,ADDRESS(LOC:Param1))

when i receive the event:notify using NOTIFICATION() command, how will i read the value of passed parameter hello? I tried checking the docs from clarion but I can’t find such answer. Thanks in advanced.

Look at the Clarion help for both NOTIFY and NOTIFICATION.

There are examples of both sides of the code there.

From NOTIFY

DynMenu.Construct  PROCEDURE()

  CODE
  SELF.NofWindows = 0
  NOTIFY (NOTIFY:Load, 1, ADDRESS (SELF.IDynMenu)) !Send Notify event to primary thread
  RETURN

From NOTIFICATION

  CASE EVENT()
  OF EVENT:Notify
     IF NOTIFICATION (NCode,, NParam) !NOTIFY has sent a Notify Event. Get Code and Parameter
     DM &= NParam + 0                !Assign passed parameter to reference var

     CASE Ncode                      !Test the Notify Code
     OF NOTIFY:Load
        DM.CreateMenu (Q)              !Execute appropriate action
     OF NOTIFY:Unload
       DO DestroyMenu
      UNLOAD ('DLL.DLL')             !Execute appropriate action
     END
   END

Basically NOTIFY lets you send a code to a thread with an optional parameter.

NOTIFY( notifycode, <thread>, <parameter> )

Then NOTIFICATION receives the values and you can parse them in the event loop.

NOTIFICATION(notifycode, <thread>, <parameter> )

Peek( NParam, Loc:AnotherMatchingVar )

You could also procedure overload and because you are using Address (var ) in the parameter you can prefix the parameter data type with an asterisk.

When you come to Peek the parameter or pass it by address, the first procedure needs to exist still in order to read the address.

Proc1( NParam )

Proc1( *String pVar )
Proc1( *Cstring pVar )
Proc1 *Long pVar )

Proc1( *String pVar )
code
Loc:String = pVar

The other caveat with using Notify/Notification is the buffer is First In Last Out, so be careful.

SendMessage is FIFO and I use that alot.

1 Like

Look at a &STRING reference and Reference Assignments

NString &STRING

OF EVENT:Notify
    IF NOTIFICATION (NCode,, NParam)
      NString &= (NParam)

IIRC you may have trouble with that local variable that is on the stack, it may need to be created with NEW so it is on the heap.


For something as simple as your example it would be better to setup Equates and use numbers:

BlargNotify Itemize,Pre()
BlargNotify:Hello EQUATE 
     END
2 Likes

Thanks guys, I have tried using PEEK() which worked for me.

Hi Rich,

Do you have an example program that mimics notify() and notification() using sendmessage() and getmessage() function where this is used as threaded interactions? It seems that I am now encountering issues using notify() because of filo functionality.

You might be interested in GUTS. CapeSoft GUTS

You could use a Global Queue to hold your data so you can access it FIFO i.e. ADD() new to the end and GET(,1) to process. Or process it in any way you wish, it’s your Queue.

You will need a Global Critical Section to synchronize access to the Queue. Then use NOTIFY just to wake up the other thread to process.

There are Windows Objects for what you want, but that will be a lot more difficult coding than a Queue and CS. I think the Named Pipe provides FIFO data and notification.

1 Like

Not at the moment, I’m in the middle of building a class writing template, that works how I think it should work, which will then speed up building classes for code with specific area’s of functionality.

I’ve got the code running in an app, but it involves alot of cut’n’paste between apps which is why I’m moving alot of code like this to classes now. So may be in a few months time, there might be an example, but no promises. :grinning_face:

to be honest, I’ve never understood the appeal of a class writing template. It’s so much easier to just code the class in a real editor vs being forced in an out of the modal editors inside of an app

3 Likes

I completely agree with Carl, if you need to control the order that your data comes through you can never rely on event/messages as their order is not guaranteed.

With that in mind, I would suggest implementing a publisher/subscriber pattern where you send an event to the subscriber that tells the subscriber that now would be a good time to go look for data.

When that event comes in, the subscriber reads all of the data that’s there. Depending on the use case, the subscriber may consume the data (delete after reading).

This approach also has better performance as events are slow

If you really need top performance drop all of the events and have use WaitMultipleObjects and signaling synch objects. I wrote a system where my 64bit .NET program “calls” into a 32 bit clarion program using this approach, and damn it’s fast - round trips in less than 1 .NET clock tick which is a 10milliionth of a second

I’m sure you’ll find some reasons in here. :grin:

Peter Thiel’s CS183: Startup - Class 1 Notes Essay

TLDR; can ya spell it out for me.
At a glance I see no mention of templates
I completely agree that using classes is a great way to code
I just don’t see how templates improve on the experience for writing them

Templates help you not make mistakes, and then novices or occasional users like me get up to speed with functionality more quickly. Classes are no different, but I think an AppGen template done right, can make coding a class much more quickly imo, but you’ll need to see the template (when its completed) to decide for yourself if its an improvement or not.

I am starting to think if the filo functionality is the reason sometimes my app has issues

The use of notify() and notification() in my current scenario should be - when I select a record/menu in the list(where my list is acting like a sidebar menu), it will hide the previous selected threaded menu window, and will open and show the selected menu window. The problem I encountered is sometimes it does not open the window and the previous window is still shown. To be honest I should be using donut holes instead but it requires string theory, and the client I have been working for does not have that template, only pure clarion. Usercontrol template should also be a candidate but it has limited functionality and it hangs clarion ide a lot

Subclassing is a way of intercepting messages sent from the OS, Clarion runtime & addon’s, and other programs to your program.

You can intercept these before the Clarion runtime gets them and process them yourself, choosing to destroy the message or pass it on to the runtime to process (if its a message it would process).

You can learn alot about how the runtime process these messages, which will explain why @MarkGoldberg says what he says.

For a few reasons, you cant guarantee the order the messages will be sent in from various sources, but you will always get a message, it will never be dropped like a network TCP packet due to congestion at a switch by the switch.

However a seperate problem exists with Notify() and Notification(), in that the Notification() buffer is a FILO buffer and imo should be a FIFO buffer. I’ve tried various work arounds like popping them into my own buffer but you cant tell when a message is a from first batch or second batch of messages, unless this is coded into the message. MS also suggestions a message queue should be FIFO (see here)

At that point you’ll likely seek the route of least resistance, like electricity does, and use the Window API’s.

When you subclass and trap messages, you can trap a range of messages, and ignore others.

These are the sort of messages defined by Windows, which the runtime will handled for you in the main where applicable.

The problem is with Notification and its buffer, if you only send one message periodically from a thread it wont be a problem, but if you send a series of messages from a thread in a short burst, it will be a problem because you’ll need to build some sort of encoding into the messages. This problem shows up very easily on slow computers so it helps to test on the slowest cheapest computer you can find.

IF you need to send a message across threads or programs or user security access levels and have the receiving app respond immediately, I would suggest using this api. When an object is sent from one program to another windows goes into a sort of windowless modal state, so you can then have your app/code act immediately. It seems to affect CPU thread switching/scheduling (which is interesting because there is only one Windows Scheduler and yet Linux have a few different CPU schedulers to hand) and the usual rules of CPU thread processing which is discussed briefly here.

The only caveat with using this WaitForMultipleObjectsEx api, is it will pause a simple loop or accept loop until something is recieved, which may not be something you want, in which case use the Window’s api’s for sending and recieving messages mentioned above. This API also doesnt translate to Linux C either, as seen here, here and here.

You can find it in use in clarion code here.

1 Like

IIRC the String Theory use is very minimal, just one error message string, that’s it

It allowed for a message of any size, but realistically it’s not going to be that big. It could be changed to a String(1000), an ANY, or Ultimate String class. I’m sure I did it myself. I tried to find the code online, but it was from CIDC.

When working with multiple threads and events (messages) you cannot rely on order, that’s thinking it is synchronized. The idea is the threads run free. So you must deal with that.

Usually keeping separate state variables. Then use Notify() or Post() to tell the other Thread that the State has changed, so it must read the State variables and act, then adjust the State variables.

2 Likes

Thank you so much Carl, I will try this one.

Thanks Rich, I really appreciate your detailed explanation.

In my experience, they dont, and one of the factors that affects that is using Critical Sections, if the debug message sent to debug view is received in order.

tldr.
If a critical section is in use in the clarion application, clarion true threads have have more cpu time to do stuff. and there is less clarion app thread swapping in the clarion application.

If a critical section is NOT in use in the clarion application, clarion true threads have less cpu time to do stuff and there is more clarion app thread swapping in the clarion application.

This seems to be something the OS controls and recognises when synch objects are in use. I dont know if its a deliberate Windows OS change of behaviour that occurs if a synch object is in use though.