Creating a callback mechanism for externals.

Andre Garzia andre at andregarzia.com
Tue Feb 17 12:22:12 EST 2009


Hello Friends,

Here I come with a topic that is hot here on my mind. I know we all
love transcript, but for building externals, we need to do it in
C/C++, so I apologize for the the amount of dirty C code that I'll
post on this message. Right now with the ExternalEnvironmentV3 and
libexternal, we have a limited number of functions available and no
clear path to create callback mechanisms from our externals. Callbacks
are useful things, specially when your dealing with network related
things, for example, you can register a callback to be triggered when
the server responds, this way, instead of looping and checking every
now and then if the server answered, we can trust that a callback
message will be triggered when the server answers. Code becomes more
clear and easier to maintain.

Since in the current incarnation of our external development SDK we
don't have a way to easily create such tool, I decided to roll one on
my own and so far I am about to achieve success. Since there are other
external writers here with much more knowledge than I, I wanted to
share what I am doing and get some feedback if I am being stupid.

First, I created a nice structure for holding a callback reference:

 struct callback {
	char *target;
	char *message;
};

So this structure holds a message name and a target for the message.
This should be enough to assemble and trigger a message. The message
member is usually passed as a parameter to some external command or
function call, the target member is obtained with the following piece
of code:

callback->message =  strdup(p_arguments[1]);
callback->target = EvalExpr("the long id of me", &t_success);
	if (t_success == EXTERNAL_FAILURE)
	{
		*r_result = strdup("could not get the long id of me.");
		*r_err = True;
		*r_pass = False;
		return;
	}

And this actually work. The message part, I am doing with strdup since
I think that without it I'll reach memory problems when the function
finishes and p_argument[] is freed. So, this stores a callback
reference and that is already working. Now on my code there's a
function that is called upon certain event and that should trigger the
callback, the code is as follow:

	strcpy (expr,"send \"");
 	strcat (expr,callback->message);
  	strcat (expr,"\" to ");
  	strcat (expr,callback->target);


	printf("Expr: %s\n", expr);
	
	result = EvalExpr(expr, &t_success);
	if (t_success == EXTERNAL_FAILURE)
	{
		printf("Error with Expr: %s\n", expr);
		return;
	}

The Expr is assembled fine, like:

send "outraMsg" to button id 1010 of card id 1002 of stack
"/home/soapdog/Desktop/ExternalsEnvironmentV3/httpserver/test.rev"

When executed in the messagebox, that expression works quite fine but
when executed from EvalExpr() it doesn't work. I don't know if
EvalExpr() is allowed to send messages or something like that. Any
clue out there?

Cheers
andre


-- 
http://www.andregarzia.com All We Do Is Code.



More information about the use-livecode mailing list