Communicating with modules: direct strings vs. structures with marshalling

diego.berninidiego.bernini Software EngineerPosts: 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

Comments

  • JasonSJasonS If I had known it was going to be that kind of party... Posts: 228
    I have used this method successfully for more complicated modules in the past. I was quite pleased with the performance. I would stick to VARIABLE_TO_STRING and STRING _TO_VARIABLE for two reasons, the strings will be shorter, and I have had problems with VARIABLE_TO_XML generating corrupted XML when passing it a nested structure.

    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.
  • viningvining X Member Posts: 4,353
    Same here, I usually set the 1st byte to determine message type and weather or not to decode (vst or stv).
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    Structures can't be passed to functions or modules, and are slower in general than arrays. Nested structures are very slow. There are compiler bugs when it comes to structures as well, with no known workarounds, so you can code yourself into a corner with no escape. Conceptually, OO is great, but it can be taken too far and often is. I think this would be one of those occasions.
    Paul
  • diego.berninidiego.bernini Software Engineer Posts: 8
    Many thanks for your very valuable comments guys!
  • JasonSJasonS If I had known it was going to be that kind of party... Posts: 228
    I use nested structures all the time with no problems, and no problems with speed. I have many modules that pass variable encoded strings with no problems. My advice is to try it yourself and see if it works for you.

    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.
  • diego.berninidiego.bernini Software Engineer Posts: 8
    Yeah, I see your point , many thanks JasonS!
Sign In or Register to comment.