RTC Remote Functions,rtcfunctions
Author
RTC Remote Functions - working with flexible structures
Danijel Tkalcec [RTC]
01.06.2006 20:27:57
Registered user
You can form your structure as simple and as complex as you want. RTC uses highly flexible format, so that you can define virtually any structure you want, even call remote function which will call other remote functions to get parameters.
You can store multiple values in each element by using newRecord, newArray or newDataSet. Here is one example of creating an array called “numbers”, which will hold a number of records (here 0 to 9) with “x:integer; dt:TDateTime” and send this to a remote function named “callme”.
This is the client-side code:
with myClientModule do
begin
with Data.newFunction(’callme’) do
begin
// prepare an array to send as parameter
with NewArray(’numbers’) do
begin
for I := 0 To 9 do
begin
// each item inside this array
// will be a new record
with newRecord(I) do
begin
asInteger[’X'] := I;
asDateTime[’dt’] := Now;
end;
end;
end;
Call(myResult);
end;
And on the server side, you can access all data inside this array like this:
// need to make sure this parameter is an array …
if isType[’numbers’]=rtc_Array then
with asArray[’numbers’] do
begin
// loop through all elements
for I := 0 to Count-1 do
begin
// make sure this element is a record
if isType[i]=rtc_Record then
with asRecord[I] do
begin
// read the data inside the record
X := asInteger[’X'];
dt := asDateTime[’dt’];
end;
end;
end;
Whenever you expect to use complex types, you should use “isType” to check if that element really contains the data type you expect, so you don’t end up with access violations in case the element is not assigned (in which case asRecord, asArray and asDataSet would return NIL).
Using the same paradigm, you can write your remote function to return any complex structure back to the client. You will simply prepare the data for “Result” using the same newRecord, newArray and newDataSet properties as you did on the client side to send parameters to the server. The only difference is that when you call a remote function from the client, you are sending data using a record, so that each of your parameters have a name and when returning a result back to the client, you actually have only “one” parameter (Result) and if you want to send more values back, you will use something like this …
with Result.newRecord do
begin
// prepare an array to send as parameter
with NewArray(’numbers’) do
begin
for I := 0 To 9 do
begin
// each item inside this array
// will be a new record
with newRecord(I) do
begin
asInteger[’X'] := I;
asDateTime[’dt’] := Now;
end;
end;
end;
end;
You see that the code is identical to the one I used to send this structure from client to the server. Difference is only that here I’m creating a record using “newRecord”, while client has created a function call using “newFunction”.
You can also use nested function calls by using “newFunction” as a “parameter” for any parameter expected by the function you are calling. For example, you can call something like “add(mull(a,b), mull(c,d))” by using this code …
with rtcClientModule do
begin
with Data.newFunction(’add’) do
begin
// to prepare the “A” parameter
// when calling the “add” function
// we will call the “mull” function
with newFunction(’A', ‘mull’) do
begin
// prepare “A” and “B” parameters
// for first call to the “mull” function
asInteger[’A']:=12;
asInteger[’B']:=34;
end;
// to prepare the “B” parameter
// when calling the “add” function
// we will call the “mull” function
with newFunction(’B', ‘mull’) do
begin
// prepare “A” and “B” parameters
// for second call to “mull”
asFloat[’A']:=56.7;
asFloat[’B']:=78.92;
end;
end;
Call(myResult);
end;
In this example, we are sending a nested function call to the server. Remote functions on the server-side do not have to be specially prepared to be able to execute nested function calls, this is already given by RTC design. What will happen is that the two “mull” functions will be executed and results from those functions will be passed as parameters to the “add” function, which will prepare the final result which will be returned to the client. This is comparable to calling normal functions in delphi, where you call other functions to prepare parameters and expect to get the final result back from the “outside” function (in this case, “add”).
I was only going to 2-nd level depth in those examples, but there is no limit to how deep your complex structure can be and you can combine all data types (simple and complex) at all levels, while every value you use can be of ANY data type. Here’s another example, preparing another complex structure to return as a result of a remote function …
with Result.newRecord do
begin
// “data” var will be a DataSet
with newDataSet(’data’) do
begin
// will be creating 100 records
for a:=1 to 100 do
begin
Append;
// “x” field will be an array
with newArray(’X') do
for b:=0 to 99 do
// fill the array
asInteger[b]:=b;
// “y” field will be a record
with newRecord(’Y') do
begin
// “txt” in record is a string
asString[’txt’]:=’We are on ‘+IntToStr(A);
// “rand” in record is an array
with newArray(’rand’) do
for a:=1 to 100 do
asFloat[a]:=random(1000)/a;
end;
// “name” field will be a string
asString[’name’]:=’my Name is X’;
// “tim” field will hold current date/time
asDateTime[’tim’]:=Now;
end;
end;
// “test” var will be a record
with newRecord(’test’) do
begin
asString[’var1']:=’hola’;
asInteger[’var2']:=1234;
asFloat[’var3']:=123.45;
asDateTime[’var4']:=Date;
asCurrency[’var5']:=13.5;
asBoolean[’ok']:=True;
end;
// “num” var will be a simple number
asInteger[’num']:=1564;
end;
Well, I guess this shows how complex and how simple structures can be used with RTC remote functions. Free your imagination. If you can imagine a structure, then you can also send it as a parameter of your RTC remote function and also receive it as a result from your remote functions. There are no limits.