Communicating with modules: direct strings vs. structures with marshalling
diego.bernini
Posts: 8
Hi to all,
I would like to receive some hints from you about best practices of communicating with modules.
Preface: I am quite new to AMX, so I am surely a AMX beginner. However I have a strong background in Object Oriented Programming, especially with C++ and Java.
I am strongly interested on developing modular, reusable and maintainable code.
According to my knowledge, the best way to communicate with modules (sending requests, obtaining responses) is through virtual devices.
In this way, the external caller sends proper request strings to the virtual device and obtains the related response strings from the virtual device. The virtual device is a parameter of the module.
The main drawback I see on this approach (but is a matter of 'flavour' of course!) is that requests and responses are directly strings, hence the caller must properly construct the strings corresponding to the requests, whereas the module must parse them and prepare the proper responses a strings. It works, for experienced AMX programmers I guess this is the common way of work, and it's fine.
However in OOP I like to work with objects and using automatic mechanisms to convert objects to string whenever needed (in terms of plain strings, XML or JSON). As you know nowadays all 'traditional' programming languages have built-in or external libraries for doing this mapping/marshalling automatically.
Working with AMX & Netlinx and developing modules, I am thinking of using the bult-in marshalling functions (VARIABLE_TO_STRING, STRING_TO_VARIABLE) in this way:
1)the module works with a proper STRUCTURE which represents the requests it may accept and the responses it returns. For example:
DEFINE_TYPE
STRUCTURE myModuleRequest {
char actionRequest[100];
integer param1;
...
float param10;
}
2) the caller has a definition of the same structure in DEFINE_TYPE. The definition may be obtained trough copy & paste or by a proper include file which is provided together with the module
3) requests to the module are performed a)preparing a proper instance of the structure b) converting it to a string and c) send it to the module
DEFINE_VARIABLE
myModuleRequest req;
....
//when the request mut be sent
req.actionRequest = 'LIGHT-ON';
req.param1=100;
....
VARIABLE_TO_STRING(req, auxString,1) //auxString is a auxiliary string
SEND_COMMAND vdvMessageBox, auxString
4) then the module receives the string and re-converts it to a variable of the same type
DEFINE_VARIABLE
myModuleRequest currentRequest;
DATA_EVENT[vdvMessaging] {
COMMAND: {
STRING_TO_VARIABLE(currentRequest, Data.text, 1)
processCommand(currentRequest)
}
}
The main advantage of this approach (again, according to my 'flavour') is that I can work with structures and fields, avoiding parsing from strings to other types(int, float etc)...this is done automatically by the marshalling functions.
What do you think?
Please share your opinions, criticism is welcome.
Many thanks,
Diego
I would like to receive some hints from you about best practices of communicating with modules.
Preface: I am quite new to AMX, so I am surely a AMX beginner. However I have a strong background in Object Oriented Programming, especially with C++ and Java.
I am strongly interested on developing modular, reusable and maintainable code.
According to my knowledge, the best way to communicate with modules (sending requests, obtaining responses) is through virtual devices.
In this way, the external caller sends proper request strings to the virtual device and obtains the related response strings from the virtual device. The virtual device is a parameter of the module.
The main drawback I see on this approach (but is a matter of 'flavour' of course!) is that requests and responses are directly strings, hence the caller must properly construct the strings corresponding to the requests, whereas the module must parse them and prepare the proper responses a strings. It works, for experienced AMX programmers I guess this is the common way of work, and it's fine.
However in OOP I like to work with objects and using automatic mechanisms to convert objects to string whenever needed (in terms of plain strings, XML or JSON). As you know nowadays all 'traditional' programming languages have built-in or external libraries for doing this mapping/marshalling automatically.
Working with AMX & Netlinx and developing modules, I am thinking of using the bult-in marshalling functions (VARIABLE_TO_STRING, STRING_TO_VARIABLE) in this way:
1)the module works with a proper STRUCTURE which represents the requests it may accept and the responses it returns. For example:
DEFINE_TYPE
STRUCTURE myModuleRequest {
char actionRequest[100];
integer param1;
...
float param10;
}
2) the caller has a definition of the same structure in DEFINE_TYPE. The definition may be obtained trough copy & paste or by a proper include file which is provided together with the module
3) requests to the module are performed a)preparing a proper instance of the structure b) converting it to a string and c) send it to the module
DEFINE_VARIABLE
myModuleRequest req;
....
//when the request mut be sent
req.actionRequest = 'LIGHT-ON';
req.param1=100;
....
VARIABLE_TO_STRING(req, auxString,1) //auxString is a auxiliary string
SEND_COMMAND vdvMessageBox, auxString
4) then the module receives the string and re-converts it to a variable of the same type
DEFINE_VARIABLE
myModuleRequest currentRequest;
DATA_EVENT[vdvMessaging] {
COMMAND: {
STRING_TO_VARIABLE(currentRequest, Data.text, 1)
processCommand(currentRequest)
}
}
The main advantage of this approach (again, according to my 'flavour') is that I can work with structures and fields, avoiding parsing from strings to other types(int, float etc)...this is done automatically by the marshalling functions.
What do you think?
Please share your opinions, criticism is welcome.
Many thanks,
Diego
0
Comments
I might still use a header on the SEND_STRING/SEND_COMMAND to retain the ability to send other types of messages between the module and main code.
Paul
I see a lot of posts in the forum about how slow some operations are and I don't get it, the only time I have seen any kind of serious performance issues has been doing things the NetLinx Language is not optimized for, i.e. Recursive Bubble Sorts, and AES-256 encryption/decryption. Both of those things can be accomplished in DUET much faster.