You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@plc4x.apache.org by Christofer Dutz <ch...@c-ware.de> on 2021/01/22 08:30:59 UTC

Idea how to generate even more driver code ....

Hi all,

last night I had an idea how we can perhaps make it even simpler to write drivers and even have more code generated.

Up till now we auto-generate the model, the serializers and the parsers. This was a huge amount of code.

Right now when implementing drivers in the different languages, I keep on having to create instances of the same messages.
Even in java some times this wrapping model classes in other model classes and again in yet some other model classes, this still is anoying .
In C it's allmost a nightmare.

So I thought ... how about extending mspec a bit again and to use this to provide something like "message-factories".
Assume we had a new type "messageFactory" (possibly we could even have multiple of these segments) and each case is a separate message template.

So instead of:

S7ParameterSetupCommunication s7ParameterSetupCommunication =
    new S7ParameterSetupCommunication(
        s7DriverContext.getMaxAmqCaller(), s7DriverContext.getMaxAmqCallee(), s7DriverContext.getPduSize());
S7Message s7Message = new S7MessageRequest(0, s7ParameterSetupCommunication,
    null);
COTPPacketData cotpPacketData = new COTPPacketData(null, s7Message, true, (short) 1);
return new TPKTPacket(cotpPacketData);

Or:


*s7_connect_request_packet = malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
if (*s7_connect_request_packet == NULL) {
  return NO_MEMORY;
}
(*s7_connect_request_packet)->payload =
    malloc(sizeof(plc4c_s7_read_write_cotp_packet));
if ((*s7_connect_request_packet)->payload == NULL) {
  return NO_MEMORY;
}
(*s7_connect_request_packet)->payload->_type =
    plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data;
(*s7_connect_request_packet)->payload->parameters = NULL;
(*s7_connect_request_packet)->payload->cotp_packet_data_eot = true;
(*s7_connect_request_packet)->payload->cotp_packet_data_tpdu_ref = 1;

(*s7_connect_request_packet)->payload->payload =
    malloc(sizeof(plc4c_s7_read_write_s7_message));
if ((*s7_connect_request_packet)->payload->payload == NULL) {
  return NO_MEMORY;
}
(*s7_connect_request_packet)->payload->payload->_type =
    plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_request;

(*s7_connect_request_packet)->payload->payload->parameter =
    malloc(sizeof(plc4c_s7_read_write_s7_parameter));
if ((*s7_connect_request_packet)->payload->payload->parameter == NULL) {
  return NO_MEMORY;
}
(*s7_connect_request_packet)->payload->payload->parameter->_type =
    plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_setup_communication;
(*s7_connect_request_packet)
    ->payload->payload->parameter
    ->s7_parameter_setup_communication_max_amq_callee =
    configuration->max_amq_callee;
(*s7_connect_request_packet)
    ->payload->payload->parameter
    ->s7_parameter_setup_communication_max_amq_caller =
    configuration->max_amq_caller;
(*s7_connect_request_packet)
    ->payload->payload->parameter
    ->s7_parameter_setup_communication_pdu_length = configuration->pdu_size;

(*s7_connect_request_packet)->payload->payload->payload = NULL;

We could simply write:

S7Message message = S7MessageFactory.createS7ConnectionReqeust(maxAmqCaller, maxAmqCallee, maxPduSize);

What do you think?

Chris

AW: Idea how to generate even more driver code ....

Posted by Christofer Dutz <ch...@c-ware.de>.
Right now I wasn't planing on creating "builders" but instead factory methods/functions for very concrete messages. 

You can give each a name, so for different situations you would simply call different factory functions/methods. So it wouldn't have any "optional" parameters as they would all be required.

Of course optional parameters would add more comfort, but it would be another layer of code-generation which has to be specified. Right now I could probably rely on what we have.

Chris


-----Ursprüngliche Nachricht-----
Von: Ben Hutcheson <be...@gmail.com> 
Gesendet: Freitag, 22. Januar 2021 12:03
An: dev@plc4x.apache.org
Betreff: Re: Idea how to generate even more driver code ....

I think it is a good idea, it's a pain having to specify loads of null values.

One thought though would be tobe able to specify an ordering and default value for the parameters. Then if the language supports it default values could just be defined instead of creating a builder.

On Fri, Jan 22, 2021 at 5:13 AM Christofer Dutz <ch...@c-ware.de>
wrote:

>
>
> -----Ursprüngliche Nachricht-----
> Von: Christofer Dutz
> Gesendet: Freitag, 22. Januar 2021 11:09
> An: Łukasz Dywicki <lu...@code-house.org>
> Betreff: AW: Idea how to generate even more driver code ....
>
> And especially to get rid of having to pass in all of the different 
> constant values.
>
> Chris
>
> -----Ursprüngliche Nachricht-----
> Von: Łukasz Dywicki <lu...@code-house.org>
> Gesendet: Freitag, 22. Januar 2021 11:00
> An: dev@plc4x.apache.org; Christofer Dutz <ch...@c-ware.de>
> Betreff: Re: Idea how to generate even more driver code ....
>
> From my side I can just say yes, yes, yes.
>
> CANopen protocol due to abstract nature of CAN transport come with 
> similar thing called "FrameBuilder":
>
> https://github.com/apache/plc4x/blob/develop/plc4j/drivers/canopen/src
> /main/java/org/apache/plc4x/java/canopen/transport/socketcan/CANOpenSo
> cketCANFrameBuilder.java
>
> I had to do it for different reasons than yours but it is ultimately 
> there to cut down amount of new Frame(receiver, new Payload(type, new 
> Data(....))).
>
> Best,
> Łukasz
>
>
> On 22.01.2021 09:30, Christofer Dutz wrote:
> > Hi all,
> >
> > last night I had an idea how we can perhaps make it even simpler to
> write drivers and even have more code generated.
> >
> > Up till now we auto-generate the model, the serializers and the parsers.
> This was a huge amount of code.
> >
> > Right now when implementing drivers in the different languages, I 
> > keep
> on having to create instances of the same messages.
> > Even in java some times this wrapping model classes in other model
> classes and again in yet some other model classes, this still is anoying .
> > In C it's allmost a nightmare.
> >
> > So I thought ... how about extending mspec a bit again and to use 
> > this
> to provide something like "message-factories".
> > Assume we had a new type "messageFactory" (possibly we could even 
> > have
> multiple of these segments) and each case is a separate message template.
> >
> > So instead of:
> >
> > S7ParameterSetupCommunication s7ParameterSetupCommunication =
> >     new S7ParameterSetupCommunication(
> >         s7DriverContext.getMaxAmqCaller(),
> > s7DriverContext.getMaxAmqCallee(), s7DriverContext.getPduSize());
> S7Message s7Message = new S7MessageRequest(0, 
> s7ParameterSetupCommunication,
> >     null);
> > COTPPacketData cotpPacketData = new COTPPacketData(null, s7Message, 
> > true, (short) 1); return new TPKTPacket(cotpPacketData);
> >
> > Or:
> >
> >
> > *s7_connect_request_packet =
> > malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
> > if (*s7_connect_request_packet == NULL) {
> >   return NO_MEMORY;
> > }
> > (*s7_connect_request_packet)->payload =
> >     malloc(sizeof(plc4c_s7_read_write_cotp_packet));
> > if ((*s7_connect_request_packet)->payload == NULL) {
> >   return NO_MEMORY;
> > }
> > (*s7_connect_request_packet)->payload->_type =
> >
> > plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet
> > _d ata; (*s7_connect_request_packet)->payload->parameters = NULL; 
> > (*s7_connect_request_packet)->payload->cotp_packet_data_eot = true; 
> > (*s7_connect_request_packet)->payload->cotp_packet_data_tpdu_ref = 
> > 1;
> >
> > (*s7_connect_request_packet)->payload->payload =
> >     malloc(sizeof(plc4c_s7_read_write_s7_message));
> > if ((*s7_connect_request_packet)->payload->payload == NULL) {
> >   return NO_MEMORY;
> > }
> > (*s7_connect_request_packet)->payload->payload->_type =
> >
> > plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_r
> > eq
> > uest;
> >
> > (*s7_connect_request_packet)->payload->payload->parameter =
> >     malloc(sizeof(plc4c_s7_read_write_s7_parameter));
> > if ((*s7_connect_request_packet)->payload->payload->parameter == NULL) {
> >   return NO_MEMORY;
> > }
> > (*s7_connect_request_packet)->payload->payload->parameter->_type =
> >
> > plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_paramet
> > er
> > _setup_communication;
> > (*s7_connect_request_packet)
> >     ->payload->payload->parameter
> >     ->s7_parameter_setup_communication_max_amq_callee =
> >     configuration->max_amq_callee;
> > (*s7_connect_request_packet)
> >     ->payload->payload->parameter
> >     ->s7_parameter_setup_communication_max_amq_caller =
> >     configuration->max_amq_caller;
> > (*s7_connect_request_packet)
> >     ->payload->payload->parameter
> >     ->s7_parameter_setup_communication_pdu_length =
> > configuration->pdu_size;
> >
> > (*s7_connect_request_packet)->payload->payload->payload = NULL;
> >
> > We could simply write:
> >
> > S7Message message =
> > S7MessageFactory.createS7ConnectionReqeust(maxAmqCaller, 
> > maxAmqCallee, maxPduSize);
> >
> > What do you think?
> >
> > Chris
> >
>

Re: Idea how to generate even more driver code ....

Posted by Ben Hutcheson <be...@gmail.com>.
I think it is a good idea, it's a pain having to specify loads of null
values.

One thought though would be tobe able to specify an ordering and default
value for the parameters. Then if the language supports it default values
could just be defined instead of creating a builder.

On Fri, Jan 22, 2021 at 5:13 AM Christofer Dutz <ch...@c-ware.de>
wrote:

>
>
> -----Ursprüngliche Nachricht-----
> Von: Christofer Dutz
> Gesendet: Freitag, 22. Januar 2021 11:09
> An: Łukasz Dywicki <lu...@code-house.org>
> Betreff: AW: Idea how to generate even more driver code ....
>
> And especially to get rid of having to pass in all of the different
> constant values.
>
> Chris
>
> -----Ursprüngliche Nachricht-----
> Von: Łukasz Dywicki <lu...@code-house.org>
> Gesendet: Freitag, 22. Januar 2021 11:00
> An: dev@plc4x.apache.org; Christofer Dutz <ch...@c-ware.de>
> Betreff: Re: Idea how to generate even more driver code ....
>
> From my side I can just say yes, yes, yes.
>
> CANopen protocol due to abstract nature of CAN transport come with similar
> thing called "FrameBuilder":
>
> https://github.com/apache/plc4x/blob/develop/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/transport/socketcan/CANOpenSocketCANFrameBuilder.java
>
> I had to do it for different reasons than yours but it is ultimately there
> to cut down amount of new Frame(receiver, new Payload(type, new
> Data(....))).
>
> Best,
> Łukasz
>
>
> On 22.01.2021 09:30, Christofer Dutz wrote:
> > Hi all,
> >
> > last night I had an idea how we can perhaps make it even simpler to
> write drivers and even have more code generated.
> >
> > Up till now we auto-generate the model, the serializers and the parsers.
> This was a huge amount of code.
> >
> > Right now when implementing drivers in the different languages, I keep
> on having to create instances of the same messages.
> > Even in java some times this wrapping model classes in other model
> classes and again in yet some other model classes, this still is anoying .
> > In C it's allmost a nightmare.
> >
> > So I thought ... how about extending mspec a bit again and to use this
> to provide something like "message-factories".
> > Assume we had a new type "messageFactory" (possibly we could even have
> multiple of these segments) and each case is a separate message template.
> >
> > So instead of:
> >
> > S7ParameterSetupCommunication s7ParameterSetupCommunication =
> >     new S7ParameterSetupCommunication(
> >         s7DriverContext.getMaxAmqCaller(),
> > s7DriverContext.getMaxAmqCallee(), s7DriverContext.getPduSize());
> S7Message s7Message = new S7MessageRequest(0, s7ParameterSetupCommunication,
> >     null);
> > COTPPacketData cotpPacketData = new COTPPacketData(null, s7Message,
> > true, (short) 1); return new TPKTPacket(cotpPacketData);
> >
> > Or:
> >
> >
> > *s7_connect_request_packet =
> > malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
> > if (*s7_connect_request_packet == NULL) {
> >   return NO_MEMORY;
> > }
> > (*s7_connect_request_packet)->payload =
> >     malloc(sizeof(plc4c_s7_read_write_cotp_packet));
> > if ((*s7_connect_request_packet)->payload == NULL) {
> >   return NO_MEMORY;
> > }
> > (*s7_connect_request_packet)->payload->_type =
> >
> > plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_d
> > ata; (*s7_connect_request_packet)->payload->parameters = NULL;
> > (*s7_connect_request_packet)->payload->cotp_packet_data_eot = true;
> > (*s7_connect_request_packet)->payload->cotp_packet_data_tpdu_ref = 1;
> >
> > (*s7_connect_request_packet)->payload->payload =
> >     malloc(sizeof(plc4c_s7_read_write_s7_message));
> > if ((*s7_connect_request_packet)->payload->payload == NULL) {
> >   return NO_MEMORY;
> > }
> > (*s7_connect_request_packet)->payload->payload->_type =
> >
> > plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_req
> > uest;
> >
> > (*s7_connect_request_packet)->payload->payload->parameter =
> >     malloc(sizeof(plc4c_s7_read_write_s7_parameter));
> > if ((*s7_connect_request_packet)->payload->payload->parameter == NULL) {
> >   return NO_MEMORY;
> > }
> > (*s7_connect_request_packet)->payload->payload->parameter->_type =
> >
> > plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter
> > _setup_communication;
> > (*s7_connect_request_packet)
> >     ->payload->payload->parameter
> >     ->s7_parameter_setup_communication_max_amq_callee =
> >     configuration->max_amq_callee;
> > (*s7_connect_request_packet)
> >     ->payload->payload->parameter
> >     ->s7_parameter_setup_communication_max_amq_caller =
> >     configuration->max_amq_caller;
> > (*s7_connect_request_packet)
> >     ->payload->payload->parameter
> >     ->s7_parameter_setup_communication_pdu_length =
> > configuration->pdu_size;
> >
> > (*s7_connect_request_packet)->payload->payload->payload = NULL;
> >
> > We could simply write:
> >
> > S7Message message =
> > S7MessageFactory.createS7ConnectionReqeust(maxAmqCaller, maxAmqCallee,
> > maxPduSize);
> >
> > What do you think?
> >
> > Chris
> >
>

WG: Idea how to generate even more driver code ....

Posted by Christofer Dutz <ch...@c-ware.de>.

-----Ursprüngliche Nachricht-----
Von: Christofer Dutz 
Gesendet: Freitag, 22. Januar 2021 11:09
An: Łukasz Dywicki <lu...@code-house.org>
Betreff: AW: Idea how to generate even more driver code ....

And especially to get rid of having to pass in all of the different constant values.

Chris

-----Ursprüngliche Nachricht-----
Von: Łukasz Dywicki <lu...@code-house.org>
Gesendet: Freitag, 22. Januar 2021 11:00
An: dev@plc4x.apache.org; Christofer Dutz <ch...@c-ware.de>
Betreff: Re: Idea how to generate even more driver code ....

From my side I can just say yes, yes, yes.

CANopen protocol due to abstract nature of CAN transport come with similar thing called "FrameBuilder":
https://github.com/apache/plc4x/blob/develop/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/transport/socketcan/CANOpenSocketCANFrameBuilder.java

I had to do it for different reasons than yours but it is ultimately there to cut down amount of new Frame(receiver, new Payload(type, new Data(....))).

Best,
Łukasz


On 22.01.2021 09:30, Christofer Dutz wrote:
> Hi all,
> 
> last night I had an idea how we can perhaps make it even simpler to write drivers and even have more code generated.
> 
> Up till now we auto-generate the model, the serializers and the parsers. This was a huge amount of code.
> 
> Right now when implementing drivers in the different languages, I keep on having to create instances of the same messages.
> Even in java some times this wrapping model classes in other model classes and again in yet some other model classes, this still is anoying .
> In C it's allmost a nightmare.
> 
> So I thought ... how about extending mspec a bit again and to use this to provide something like "message-factories".
> Assume we had a new type "messageFactory" (possibly we could even have multiple of these segments) and each case is a separate message template.
> 
> So instead of:
> 
> S7ParameterSetupCommunication s7ParameterSetupCommunication =
>     new S7ParameterSetupCommunication(
>         s7DriverContext.getMaxAmqCaller(),
> s7DriverContext.getMaxAmqCallee(), s7DriverContext.getPduSize()); S7Message s7Message = new S7MessageRequest(0, s7ParameterSetupCommunication,
>     null);
> COTPPacketData cotpPacketData = new COTPPacketData(null, s7Message, 
> true, (short) 1); return new TPKTPacket(cotpPacketData);
> 
> Or:
> 
> 
> *s7_connect_request_packet =
> malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
> if (*s7_connect_request_packet == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload =
>     malloc(sizeof(plc4c_s7_read_write_cotp_packet));
> if ((*s7_connect_request_packet)->payload == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->_type =
>     
> plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_d
> ata; (*s7_connect_request_packet)->payload->parameters = NULL; 
> (*s7_connect_request_packet)->payload->cotp_packet_data_eot = true; 
> (*s7_connect_request_packet)->payload->cotp_packet_data_tpdu_ref = 1;
> 
> (*s7_connect_request_packet)->payload->payload =
>     malloc(sizeof(plc4c_s7_read_write_s7_message));
> if ((*s7_connect_request_packet)->payload->payload == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->payload->_type =
>     
> plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_req
> uest;
> 
> (*s7_connect_request_packet)->payload->payload->parameter =
>     malloc(sizeof(plc4c_s7_read_write_s7_parameter));
> if ((*s7_connect_request_packet)->payload->payload->parameter == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->payload->parameter->_type =
>     
> plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter
> _setup_communication;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_max_amq_callee =
>     configuration->max_amq_callee;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_max_amq_caller =
>     configuration->max_amq_caller;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_pdu_length =
> configuration->pdu_size;
> 
> (*s7_connect_request_packet)->payload->payload->payload = NULL;
> 
> We could simply write:
> 
> S7Message message =
> S7MessageFactory.createS7ConnectionReqeust(maxAmqCaller, maxAmqCallee, 
> maxPduSize);
> 
> What do you think?
> 
> Chris
> 

Re: Idea how to generate even more driver code ....

Posted by Łukasz Dywicki <lu...@code-house.org>.
From my side I can just say yes, yes, yes.

CANopen protocol due to abstract nature of CAN transport come with
similar thing called "FrameBuilder":
https://github.com/apache/plc4x/blob/develop/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/transport/socketcan/CANOpenSocketCANFrameBuilder.java

I had to do it for different reasons than yours but it is ultimately
there to cut down amount of new Frame(receiver, new Payload(type, new
Data(....))).

Best,
Łukasz


On 22.01.2021 09:30, Christofer Dutz wrote:
> Hi all,
> 
> last night I had an idea how we can perhaps make it even simpler to write drivers and even have more code generated.
> 
> Up till now we auto-generate the model, the serializers and the parsers. This was a huge amount of code.
> 
> Right now when implementing drivers in the different languages, I keep on having to create instances of the same messages.
> Even in java some times this wrapping model classes in other model classes and again in yet some other model classes, this still is anoying .
> In C it's allmost a nightmare.
> 
> So I thought ... how about extending mspec a bit again and to use this to provide something like "message-factories".
> Assume we had a new type "messageFactory" (possibly we could even have multiple of these segments) and each case is a separate message template.
> 
> So instead of:
> 
> S7ParameterSetupCommunication s7ParameterSetupCommunication =
>     new S7ParameterSetupCommunication(
>         s7DriverContext.getMaxAmqCaller(), s7DriverContext.getMaxAmqCallee(), s7DriverContext.getPduSize());
> S7Message s7Message = new S7MessageRequest(0, s7ParameterSetupCommunication,
>     null);
> COTPPacketData cotpPacketData = new COTPPacketData(null, s7Message, true, (short) 1);
> return new TPKTPacket(cotpPacketData);
> 
> Or:
> 
> 
> *s7_connect_request_packet = malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
> if (*s7_connect_request_packet == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload =
>     malloc(sizeof(plc4c_s7_read_write_cotp_packet));
> if ((*s7_connect_request_packet)->payload == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->_type =
>     plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data;
> (*s7_connect_request_packet)->payload->parameters = NULL;
> (*s7_connect_request_packet)->payload->cotp_packet_data_eot = true;
> (*s7_connect_request_packet)->payload->cotp_packet_data_tpdu_ref = 1;
> 
> (*s7_connect_request_packet)->payload->payload =
>     malloc(sizeof(plc4c_s7_read_write_s7_message));
> if ((*s7_connect_request_packet)->payload->payload == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->payload->_type =
>     plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_request;
> 
> (*s7_connect_request_packet)->payload->payload->parameter =
>     malloc(sizeof(plc4c_s7_read_write_s7_parameter));
> if ((*s7_connect_request_packet)->payload->payload->parameter == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->payload->parameter->_type =
>     plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_setup_communication;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_max_amq_callee =
>     configuration->max_amq_callee;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_max_amq_caller =
>     configuration->max_amq_caller;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_pdu_length = configuration->pdu_size;
> 
> (*s7_connect_request_packet)->payload->payload->payload = NULL;
> 
> We could simply write:
> 
> S7Message message = S7MessageFactory.createS7ConnectionReqeust(maxAmqCaller, maxAmqCallee, maxPduSize);
> 
> What do you think?
> 
> Chris
> 

Re: Idea how to generate even more driver code ....

Posted by Łukasz Dywicki <lu...@code-house.org>.
From my side I can just say yes, yes, yes.

CANopen protocol due to abstract nature of CAN transport come with
similar thing called "FrameBuilder":
https://github.com/apache/plc4x/blob/develop/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/transport/socketcan/CANOpenSocketCANFrameBuilder.java

I had to do it for different reasons than yours but it is ultimately
there to cut down amount of new Frame(receiver, new Payload(type, new
Data(....))).

Best,
Łukasz

On 22.01.2021 09:30, Christofer Dutz wrote:
> Hi all,
> 
> last night I had an idea how we can perhaps make it even simpler to write drivers and even have more code generated.
> 
> Up till now we auto-generate the model, the serializers and the parsers. This was a huge amount of code.
> 
> Right now when implementing drivers in the different languages, I keep on having to create instances of the same messages.
> Even in java some times this wrapping model classes in other model classes and again in yet some other model classes, this still is anoying .
> In C it's allmost a nightmare.
> 
> So I thought ... how about extending mspec a bit again and to use this to provide something like "message-factories".
> Assume we had a new type "messageFactory" (possibly we could even have multiple of these segments) and each case is a separate message template.
> 
> So instead of:
> 
> S7ParameterSetupCommunication s7ParameterSetupCommunication =
>     new S7ParameterSetupCommunication(
>         s7DriverContext.getMaxAmqCaller(), s7DriverContext.getMaxAmqCallee(), s7DriverContext.getPduSize());
> S7Message s7Message = new S7MessageRequest(0, s7ParameterSetupCommunication,
>     null);
> COTPPacketData cotpPacketData = new COTPPacketData(null, s7Message, true, (short) 1);
> return new TPKTPacket(cotpPacketData);
> 
> Or:
> 
> 
> *s7_connect_request_packet = malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
> if (*s7_connect_request_packet == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload =
>     malloc(sizeof(plc4c_s7_read_write_cotp_packet));
> if ((*s7_connect_request_packet)->payload == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->_type =
>     plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data;
> (*s7_connect_request_packet)->payload->parameters = NULL;
> (*s7_connect_request_packet)->payload->cotp_packet_data_eot = true;
> (*s7_connect_request_packet)->payload->cotp_packet_data_tpdu_ref = 1;
> 
> (*s7_connect_request_packet)->payload->payload =
>     malloc(sizeof(plc4c_s7_read_write_s7_message));
> if ((*s7_connect_request_packet)->payload->payload == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->payload->_type =
>     plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_request;
> 
> (*s7_connect_request_packet)->payload->payload->parameter =
>     malloc(sizeof(plc4c_s7_read_write_s7_parameter));
> if ((*s7_connect_request_packet)->payload->payload->parameter == NULL) {
>   return NO_MEMORY;
> }
> (*s7_connect_request_packet)->payload->payload->parameter->_type =
>     plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_setup_communication;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_max_amq_callee =
>     configuration->max_amq_callee;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_max_amq_caller =
>     configuration->max_amq_caller;
> (*s7_connect_request_packet)
>     ->payload->payload->parameter
>     ->s7_parameter_setup_communication_pdu_length = configuration->pdu_size;
> 
> (*s7_connect_request_packet)->payload->payload->payload = NULL;
> 
> We could simply write:
> 
> S7Message message = S7MessageFactory.createS7ConnectionReqeust(maxAmqCaller, maxAmqCallee, maxPduSize);
> 
> What do you think?
> 
> Chris
>