From 0ecca2ea761cbd7755edeb1d2dbcb945e30cee7d Mon Sep 17 00:00:00 2001 From: Jonathan Carvalhosa Date: Fri, 16 Oct 2026 16:27:33 -0300 Subject: [PATCH] C#: create the sender and receiver models on first use The generated Sender, Receiver, Proxy and Client created the model of every message of the protocol in their constructors, and the Receiver and Client also built the Default value of every message. Each model is a distinct generic instantiation over the message struct, so the first Sender or Receiver of a process made the JIT compile all of them before a single message went out, whichever messages the process actually used: a protocol with a few hundred message and field models spent a noticeable part of a client's start-up there. Each model is now created the first time its message is sent or received, behind a property of the same name, so existing code reading Sender.XModel or Client.XSenderModel compiles unchanged. Once a model exists the access is a null check, with no further allocation. The received value fields are no longer initialized with Default, since every receive assigns them through Deserialize(out ...) before they are read. Co-Authored-By: Claude Opus 5.5 --- include/generator_csharp.h | 1 + projects/CSharp/Proto/com.chronoxor.proto.cs | 159 ++++++------------ .../CSharp/Proto/com.chronoxor.protoex.cs | 159 ++++++------------ source/generator_csharp.cpp | 125 +++++--------- 4 files changed, 154 insertions(+), 290 deletions(-) diff --git a/include/generator_csharp.h b/include/generator_csharp.h index de03986d3..470a3df91 100644 --- a/include/generator_csharp.h +++ b/include/generator_csharp.h @@ -89,6 +89,7 @@ class GeneratorCSharp : public Generator bool IsKnownType(const std::string& type); bool IsReferenceType(const std::string& type); + std::string ConvertToLower(const std::string& type); std::string ConvertEnumRead(const std::string& type); std::string ConvertEnumSize(const std::string& type); std::string ConvertEnumType(const std::string& type); diff --git a/projects/CSharp/Proto/com.chronoxor.proto.cs b/projects/CSharp/Proto/com.chronoxor.proto.cs index 70997faae..ba91227ee 100644 --- a/projects/CSharp/Proto/com.chronoxor.proto.cs +++ b/projects/CSharp/Proto/com.chronoxor.proto.cs @@ -4709,21 +4709,18 @@ public interface ISenderListener : com.chronoxor.FBE.ISenderListener public class Sender : com.chronoxor.FBE.Sender, ISenderListener { // Sender models accessors - public readonly OrderMessageModel OrderMessageModel; - public readonly BalanceMessageModel BalanceMessageModel; - public readonly AccountMessageModel AccountMessageModel; + private OrderMessageModel _orderMessageModel; + public OrderMessageModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageModel(Buffer)); + private BalanceMessageModel _balanceMessageModel; + public BalanceMessageModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageModel(Buffer)); + private AccountMessageModel _accountMessageModel; + public AccountMessageModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageModel(Buffer)); public Sender() : base(false) { - OrderMessageModel = new OrderMessageModel(Buffer); - BalanceMessageModel = new BalanceMessageModel(Buffer); - AccountMessageModel = new AccountMessageModel(Buffer); } public Sender(com.chronoxor.FBE.Buffer buffer) : base(buffer, false) { - OrderMessageModel = new OrderMessageModel(Buffer); - BalanceMessageModel = new BalanceMessageModel(Buffer); - AccountMessageModel = new AccountMessageModel(Buffer); } public long Send(object obj) { return SendListener(this, obj); } @@ -4818,27 +4815,18 @@ public class Receiver : com.chronoxor.FBE.Receiver, IReceiverListener private global::com.chronoxor.proto.AccountMessage AccountMessageValue; // Receiver models accessors - private readonly OrderMessageModel OrderMessageModel; - private readonly BalanceMessageModel BalanceMessageModel; - private readonly AccountMessageModel AccountMessageModel; + private OrderMessageModel _orderMessageModel; + private OrderMessageModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageModel()); + private BalanceMessageModel _balanceMessageModel; + private BalanceMessageModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageModel()); + private AccountMessageModel _accountMessageModel; + private AccountMessageModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageModel()); public Receiver() : base(false) { - OrderMessageValue = global::com.chronoxor.proto.OrderMessage.Default; - OrderMessageModel = new OrderMessageModel(); - BalanceMessageValue = global::com.chronoxor.proto.BalanceMessage.Default; - BalanceMessageModel = new BalanceMessageModel(); - AccountMessageValue = global::com.chronoxor.proto.AccountMessage.Default; - AccountMessageModel = new AccountMessageModel(); } public Receiver(com.chronoxor.FBE.Buffer buffer) : base(buffer, false) { - OrderMessageValue = global::com.chronoxor.proto.OrderMessage.Default; - OrderMessageModel = new OrderMessageModel(); - BalanceMessageValue = global::com.chronoxor.proto.BalanceMessage.Default; - BalanceMessageModel = new BalanceMessageModel(); - AccountMessageValue = global::com.chronoxor.proto.AccountMessage.Default; - AccountMessageModel = new AccountMessageModel(); } internal override bool OnReceive(long type, byte[] buffer, long offset, long size) { return OnReceiveListener(this, type, buffer, offset, size); } @@ -4927,21 +4915,18 @@ void OnProxy(AccountMessageModel model, long type, byte[] buffer, long offset, l public class Proxy : com.chronoxor.FBE.Receiver, IProxyListener { // Proxy models accessors - private readonly OrderMessageModel OrderMessageModel; - private readonly BalanceMessageModel BalanceMessageModel; - private readonly AccountMessageModel AccountMessageModel; + private OrderMessageModel _orderMessageModel; + private OrderMessageModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageModel()); + private BalanceMessageModel _balanceMessageModel; + private BalanceMessageModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageModel()); + private AccountMessageModel _accountMessageModel; + private AccountMessageModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageModel()); public Proxy() : base(false) { - OrderMessageModel = new OrderMessageModel(); - BalanceMessageModel = new BalanceMessageModel(); - AccountMessageModel = new AccountMessageModel(); } public Proxy(com.chronoxor.FBE.Buffer buffer) : base(buffer, false) { - OrderMessageModel = new OrderMessageModel(); - BalanceMessageModel = new BalanceMessageModel(); - AccountMessageModel = new AccountMessageModel(); } internal override bool OnReceive(long type, byte[] buffer, long offset, long size) { return OnReceiveListener(this, type, buffer, offset, size); } @@ -5011,9 +4996,12 @@ public interface IClientListener : com.chronoxor.FBE.IClientListener, ISenderLis public class Client : com.chronoxor.FBE.Client, IClientListener { // Client sender models accessors - public readonly OrderMessageModel OrderMessageSenderModel; - public readonly BalanceMessageModel BalanceMessageSenderModel; - public readonly AccountMessageModel AccountMessageSenderModel; + private OrderMessageModel _orderMessageSenderModel; + public OrderMessageModel OrderMessageSenderModel => _orderMessageSenderModel ?? (_orderMessageSenderModel = new OrderMessageModel(SendBuffer)); + private BalanceMessageModel _balanceMessageSenderModel; + public BalanceMessageModel BalanceMessageSenderModel => _balanceMessageSenderModel ?? (_balanceMessageSenderModel = new BalanceMessageModel(SendBuffer)); + private AccountMessageModel _accountMessageSenderModel; + public AccountMessageModel AccountMessageSenderModel => _accountMessageSenderModel ?? (_accountMessageSenderModel = new AccountMessageModel(SendBuffer)); // Client receiver values accessors private global::com.chronoxor.proto.OrderMessage OrderMessageReceiverValue; @@ -5021,33 +5009,18 @@ public class Client : com.chronoxor.FBE.Client, IClientListener private global::com.chronoxor.proto.AccountMessage AccountMessageReceiverValue; // Client receiver models accessors - private readonly OrderMessageModel OrderMessageReceiverModel; - private readonly BalanceMessageModel BalanceMessageReceiverModel; - private readonly AccountMessageModel AccountMessageReceiverModel; + private OrderMessageModel _orderMessageReceiverModel; + private OrderMessageModel OrderMessageReceiverModel => _orderMessageReceiverModel ?? (_orderMessageReceiverModel = new OrderMessageModel()); + private BalanceMessageModel _balanceMessageReceiverModel; + private BalanceMessageModel BalanceMessageReceiverModel => _balanceMessageReceiverModel ?? (_balanceMessageReceiverModel = new BalanceMessageModel()); + private AccountMessageModel _accountMessageReceiverModel; + private AccountMessageModel AccountMessageReceiverModel => _accountMessageReceiverModel ?? (_accountMessageReceiverModel = new AccountMessageModel()); public Client() : base(false) { - OrderMessageSenderModel = new OrderMessageModel(SendBuffer); - OrderMessageReceiverValue = global::com.chronoxor.proto.OrderMessage.Default; - OrderMessageReceiverModel = new OrderMessageModel(); - BalanceMessageSenderModel = new BalanceMessageModel(SendBuffer); - BalanceMessageReceiverValue = global::com.chronoxor.proto.BalanceMessage.Default; - BalanceMessageReceiverModel = new BalanceMessageModel(); - AccountMessageSenderModel = new AccountMessageModel(SendBuffer); - AccountMessageReceiverValue = global::com.chronoxor.proto.AccountMessage.Default; - AccountMessageReceiverModel = new AccountMessageModel(); } public Client(com.chronoxor.FBE.Buffer sendBuffer, com.chronoxor.FBE.Buffer receiveBuffer) : base(sendBuffer, receiveBuffer, false) { - OrderMessageSenderModel = new OrderMessageModel(SendBuffer); - OrderMessageReceiverValue = global::com.chronoxor.proto.OrderMessage.Default; - OrderMessageReceiverModel = new OrderMessageModel(); - BalanceMessageSenderModel = new BalanceMessageModel(SendBuffer); - BalanceMessageReceiverValue = global::com.chronoxor.proto.BalanceMessage.Default; - BalanceMessageReceiverModel = new BalanceMessageModel(); - AccountMessageSenderModel = new AccountMessageModel(SendBuffer); - AccountMessageReceiverValue = global::com.chronoxor.proto.AccountMessage.Default; - AccountMessageReceiverModel = new AccountMessageModel(); } public long Send(object obj) { return SendListener(this, obj); } @@ -5248,21 +5221,18 @@ public interface IFinalSenderListener : com.chronoxor.FBE.ISenderListener public class FinalSender : com.chronoxor.FBE.Sender, IFinalSenderListener { // Sender models accessors - public readonly OrderMessageFinalModel OrderMessageModel; - public readonly BalanceMessageFinalModel BalanceMessageModel; - public readonly AccountMessageFinalModel AccountMessageModel; + private OrderMessageFinalModel _orderMessageModel; + public OrderMessageFinalModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageFinalModel(Buffer)); + private BalanceMessageFinalModel _balanceMessageModel; + public BalanceMessageFinalModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageFinalModel(Buffer)); + private AccountMessageFinalModel _accountMessageModel; + public AccountMessageFinalModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageFinalModel(Buffer)); public FinalSender() : base(true) { - OrderMessageModel = new OrderMessageFinalModel(Buffer); - BalanceMessageModel = new BalanceMessageFinalModel(Buffer); - AccountMessageModel = new AccountMessageFinalModel(Buffer); } public FinalSender(com.chronoxor.FBE.Buffer buffer) : base(buffer, true) { - OrderMessageModel = new OrderMessageFinalModel(Buffer); - BalanceMessageModel = new BalanceMessageFinalModel(Buffer); - AccountMessageModel = new AccountMessageFinalModel(Buffer); } public long Send(object obj) { return SendListener(this, obj); } @@ -5357,27 +5327,18 @@ public class FinalReceiver : com.chronoxor.FBE.Receiver, IFinalReceiverListener private global::com.chronoxor.proto.AccountMessage AccountMessageValue; // Receiver models accessors - private readonly OrderMessageFinalModel OrderMessageModel; - private readonly BalanceMessageFinalModel BalanceMessageModel; - private readonly AccountMessageFinalModel AccountMessageModel; + private OrderMessageFinalModel _orderMessageModel; + private OrderMessageFinalModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageFinalModel()); + private BalanceMessageFinalModel _balanceMessageModel; + private BalanceMessageFinalModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageFinalModel()); + private AccountMessageFinalModel _accountMessageModel; + private AccountMessageFinalModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageFinalModel()); public FinalReceiver() : base(true) { - OrderMessageValue = global::com.chronoxor.proto.OrderMessage.Default; - OrderMessageModel = new OrderMessageFinalModel(); - BalanceMessageValue = global::com.chronoxor.proto.BalanceMessage.Default; - BalanceMessageModel = new BalanceMessageFinalModel(); - AccountMessageValue = global::com.chronoxor.proto.AccountMessage.Default; - AccountMessageModel = new AccountMessageFinalModel(); } public FinalReceiver(com.chronoxor.FBE.Buffer buffer) : base(buffer, true) { - OrderMessageValue = global::com.chronoxor.proto.OrderMessage.Default; - OrderMessageModel = new OrderMessageFinalModel(); - BalanceMessageValue = global::com.chronoxor.proto.BalanceMessage.Default; - BalanceMessageModel = new BalanceMessageFinalModel(); - AccountMessageValue = global::com.chronoxor.proto.AccountMessage.Default; - AccountMessageModel = new AccountMessageFinalModel(); } internal override bool OnReceive(long type, byte[] buffer, long offset, long size) { return OnReceiveListener(this, type, buffer, offset, size); } @@ -5462,9 +5423,12 @@ public interface IFinalClientListener : com.chronoxor.FBE.IClientListener, IFina public class FinalClient : com.chronoxor.FBE.Client, IFinalClientListener { // Client sender models accessors - public readonly OrderMessageFinalModel OrderMessageSenderModel; - public readonly BalanceMessageFinalModel BalanceMessageSenderModel; - public readonly AccountMessageFinalModel AccountMessageSenderModel; + private OrderMessageFinalModel _orderMessageSenderModel; + public OrderMessageFinalModel OrderMessageSenderModel => _orderMessageSenderModel ?? (_orderMessageSenderModel = new OrderMessageFinalModel(SendBuffer)); + private BalanceMessageFinalModel _balanceMessageSenderModel; + public BalanceMessageFinalModel BalanceMessageSenderModel => _balanceMessageSenderModel ?? (_balanceMessageSenderModel = new BalanceMessageFinalModel(SendBuffer)); + private AccountMessageFinalModel _accountMessageSenderModel; + public AccountMessageFinalModel AccountMessageSenderModel => _accountMessageSenderModel ?? (_accountMessageSenderModel = new AccountMessageFinalModel(SendBuffer)); // Client receiver values accessors private global::com.chronoxor.proto.OrderMessage OrderMessageReceiverValue; @@ -5472,33 +5436,18 @@ public class FinalClient : com.chronoxor.FBE.Client, IFinalClientListener private global::com.chronoxor.proto.AccountMessage AccountMessageReceiverValue; // Client receiver models accessors - private readonly OrderMessageFinalModel OrderMessageReceiverModel; - private readonly BalanceMessageFinalModel BalanceMessageReceiverModel; - private readonly AccountMessageFinalModel AccountMessageReceiverModel; + private OrderMessageFinalModel _orderMessageReceiverModel; + private OrderMessageFinalModel OrderMessageReceiverModel => _orderMessageReceiverModel ?? (_orderMessageReceiverModel = new OrderMessageFinalModel()); + private BalanceMessageFinalModel _balanceMessageReceiverModel; + private BalanceMessageFinalModel BalanceMessageReceiverModel => _balanceMessageReceiverModel ?? (_balanceMessageReceiverModel = new BalanceMessageFinalModel()); + private AccountMessageFinalModel _accountMessageReceiverModel; + private AccountMessageFinalModel AccountMessageReceiverModel => _accountMessageReceiverModel ?? (_accountMessageReceiverModel = new AccountMessageFinalModel()); public FinalClient() : base(true) { - OrderMessageSenderModel = new OrderMessageFinalModel(SendBuffer); - OrderMessageReceiverValue = global::com.chronoxor.proto.OrderMessage.Default; - OrderMessageReceiverModel = new OrderMessageFinalModel(); - BalanceMessageSenderModel = new BalanceMessageFinalModel(SendBuffer); - BalanceMessageReceiverValue = global::com.chronoxor.proto.BalanceMessage.Default; - BalanceMessageReceiverModel = new BalanceMessageFinalModel(); - AccountMessageSenderModel = new AccountMessageFinalModel(SendBuffer); - AccountMessageReceiverValue = global::com.chronoxor.proto.AccountMessage.Default; - AccountMessageReceiverModel = new AccountMessageFinalModel(); } public FinalClient(com.chronoxor.FBE.Buffer sendBuffer, com.chronoxor.FBE.Buffer receiveBuffer) : base(sendBuffer, receiveBuffer, true) { - OrderMessageSenderModel = new OrderMessageFinalModel(SendBuffer); - OrderMessageReceiverValue = global::com.chronoxor.proto.OrderMessage.Default; - OrderMessageReceiverModel = new OrderMessageFinalModel(); - BalanceMessageSenderModel = new BalanceMessageFinalModel(SendBuffer); - BalanceMessageReceiverValue = global::com.chronoxor.proto.BalanceMessage.Default; - BalanceMessageReceiverModel = new BalanceMessageFinalModel(); - AccountMessageSenderModel = new AccountMessageFinalModel(SendBuffer); - AccountMessageReceiverValue = global::com.chronoxor.proto.AccountMessage.Default; - AccountMessageReceiverModel = new AccountMessageFinalModel(); } public long Send(object obj) { return SendListener(this, obj); } diff --git a/projects/CSharp/Proto/com.chronoxor.protoex.cs b/projects/CSharp/Proto/com.chronoxor.protoex.cs index 7e747b668..359f8bd79 100644 --- a/projects/CSharp/Proto/com.chronoxor.protoex.cs +++ b/projects/CSharp/Proto/com.chronoxor.protoex.cs @@ -4820,23 +4820,20 @@ public class Sender : com.chronoxor.FBE.Sender, ISenderListener public readonly proto.FBE.Sender protoSender; // Sender models accessors - public readonly OrderMessageModel OrderMessageModel; - public readonly BalanceMessageModel BalanceMessageModel; - public readonly AccountMessageModel AccountMessageModel; + private OrderMessageModel _orderMessageModel; + public OrderMessageModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageModel(Buffer)); + private BalanceMessageModel _balanceMessageModel; + public BalanceMessageModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageModel(Buffer)); + private AccountMessageModel _accountMessageModel; + public AccountMessageModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageModel(Buffer)); public Sender() : base(false) { protoSender = new proto.FBE.Sender(Buffer); - OrderMessageModel = new OrderMessageModel(Buffer); - BalanceMessageModel = new BalanceMessageModel(Buffer); - AccountMessageModel = new AccountMessageModel(Buffer); } public Sender(com.chronoxor.FBE.Buffer buffer) : base(buffer, false) { protoSender = new proto.FBE.Sender(Buffer); - OrderMessageModel = new OrderMessageModel(Buffer); - BalanceMessageModel = new BalanceMessageModel(Buffer); - AccountMessageModel = new AccountMessageModel(Buffer); } public long Send(object obj) { return SendListener(this, obj); } @@ -4939,29 +4936,20 @@ public class Receiver : com.chronoxor.FBE.Receiver, IReceiverListener private global::com.chronoxor.protoex.AccountMessage AccountMessageValue; // Receiver models accessors - private readonly OrderMessageModel OrderMessageModel; - private readonly BalanceMessageModel BalanceMessageModel; - private readonly AccountMessageModel AccountMessageModel; + private OrderMessageModel _orderMessageModel; + private OrderMessageModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageModel()); + private BalanceMessageModel _balanceMessageModel; + private BalanceMessageModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageModel()); + private AccountMessageModel _accountMessageModel; + private AccountMessageModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageModel()); public Receiver() : base(false) { protoReceiver = new proto.FBE.Receiver(Buffer); - OrderMessageValue = global::com.chronoxor.protoex.OrderMessage.Default; - OrderMessageModel = new OrderMessageModel(); - BalanceMessageValue = global::com.chronoxor.protoex.BalanceMessage.Default; - BalanceMessageModel = new BalanceMessageModel(); - AccountMessageValue = global::com.chronoxor.protoex.AccountMessage.Default; - AccountMessageModel = new AccountMessageModel(); } public Receiver(com.chronoxor.FBE.Buffer buffer) : base(buffer, false) { protoReceiver = new proto.FBE.Receiver(Buffer); - OrderMessageValue = global::com.chronoxor.protoex.OrderMessage.Default; - OrderMessageModel = new OrderMessageModel(); - BalanceMessageValue = global::com.chronoxor.protoex.BalanceMessage.Default; - BalanceMessageModel = new BalanceMessageModel(); - AccountMessageValue = global::com.chronoxor.protoex.AccountMessage.Default; - AccountMessageModel = new AccountMessageModel(); } internal override bool OnReceive(long type, byte[] buffer, long offset, long size) { return OnReceiveListener(this, type, buffer, offset, size); } @@ -5056,23 +5044,20 @@ public class Proxy : com.chronoxor.FBE.Receiver, IProxyListener public proto.FBE.Proxy protoProxy; // Proxy models accessors - private readonly OrderMessageModel OrderMessageModel; - private readonly BalanceMessageModel BalanceMessageModel; - private readonly AccountMessageModel AccountMessageModel; + private OrderMessageModel _orderMessageModel; + private OrderMessageModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageModel()); + private BalanceMessageModel _balanceMessageModel; + private BalanceMessageModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageModel()); + private AccountMessageModel _accountMessageModel; + private AccountMessageModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageModel()); public Proxy() : base(false) { protoProxy = new proto.FBE.Proxy(Buffer); - OrderMessageModel = new OrderMessageModel(); - BalanceMessageModel = new BalanceMessageModel(); - AccountMessageModel = new AccountMessageModel(); } public Proxy(com.chronoxor.FBE.Buffer buffer) : base(buffer, false) { protoProxy = new proto.FBE.Proxy(Buffer); - OrderMessageModel = new OrderMessageModel(); - BalanceMessageModel = new BalanceMessageModel(); - AccountMessageModel = new AccountMessageModel(); } internal override bool OnReceive(long type, byte[] buffer, long offset, long size) { return OnReceiveListener(this, type, buffer, offset, size); } @@ -5148,9 +5133,12 @@ public class Client : com.chronoxor.FBE.Client, IClientListener public readonly proto.FBE.Client protoClient; // Client sender models accessors - public readonly OrderMessageModel OrderMessageSenderModel; - public readonly BalanceMessageModel BalanceMessageSenderModel; - public readonly AccountMessageModel AccountMessageSenderModel; + private OrderMessageModel _orderMessageSenderModel; + public OrderMessageModel OrderMessageSenderModel => _orderMessageSenderModel ?? (_orderMessageSenderModel = new OrderMessageModel(SendBuffer)); + private BalanceMessageModel _balanceMessageSenderModel; + public BalanceMessageModel BalanceMessageSenderModel => _balanceMessageSenderModel ?? (_balanceMessageSenderModel = new BalanceMessageModel(SendBuffer)); + private AccountMessageModel _accountMessageSenderModel; + public AccountMessageModel AccountMessageSenderModel => _accountMessageSenderModel ?? (_accountMessageSenderModel = new AccountMessageModel(SendBuffer)); // Client receiver values accessors private global::com.chronoxor.protoex.OrderMessage OrderMessageReceiverValue; @@ -5158,35 +5146,20 @@ public class Client : com.chronoxor.FBE.Client, IClientListener private global::com.chronoxor.protoex.AccountMessage AccountMessageReceiverValue; // Client receiver models accessors - private readonly OrderMessageModel OrderMessageReceiverModel; - private readonly BalanceMessageModel BalanceMessageReceiverModel; - private readonly AccountMessageModel AccountMessageReceiverModel; + private OrderMessageModel _orderMessageReceiverModel; + private OrderMessageModel OrderMessageReceiverModel => _orderMessageReceiverModel ?? (_orderMessageReceiverModel = new OrderMessageModel()); + private BalanceMessageModel _balanceMessageReceiverModel; + private BalanceMessageModel BalanceMessageReceiverModel => _balanceMessageReceiverModel ?? (_balanceMessageReceiverModel = new BalanceMessageModel()); + private AccountMessageModel _accountMessageReceiverModel; + private AccountMessageModel AccountMessageReceiverModel => _accountMessageReceiverModel ?? (_accountMessageReceiverModel = new AccountMessageModel()); public Client() : base(false) { protoClient = new proto.FBE.Client(SendBuffer, ReceiveBuffer); - OrderMessageSenderModel = new OrderMessageModel(SendBuffer); - OrderMessageReceiverValue = global::com.chronoxor.protoex.OrderMessage.Default; - OrderMessageReceiverModel = new OrderMessageModel(); - BalanceMessageSenderModel = new BalanceMessageModel(SendBuffer); - BalanceMessageReceiverValue = global::com.chronoxor.protoex.BalanceMessage.Default; - BalanceMessageReceiverModel = new BalanceMessageModel(); - AccountMessageSenderModel = new AccountMessageModel(SendBuffer); - AccountMessageReceiverValue = global::com.chronoxor.protoex.AccountMessage.Default; - AccountMessageReceiverModel = new AccountMessageModel(); } public Client(com.chronoxor.FBE.Buffer sendBuffer, com.chronoxor.FBE.Buffer receiveBuffer) : base(sendBuffer, receiveBuffer, false) { protoClient = new proto.FBE.Client(SendBuffer, ReceiveBuffer); - OrderMessageSenderModel = new OrderMessageModel(SendBuffer); - OrderMessageReceiverValue = global::com.chronoxor.protoex.OrderMessage.Default; - OrderMessageReceiverModel = new OrderMessageModel(); - BalanceMessageSenderModel = new BalanceMessageModel(SendBuffer); - BalanceMessageReceiverValue = global::com.chronoxor.protoex.BalanceMessage.Default; - BalanceMessageReceiverModel = new BalanceMessageModel(); - AccountMessageSenderModel = new AccountMessageModel(SendBuffer); - AccountMessageReceiverValue = global::com.chronoxor.protoex.AccountMessage.Default; - AccountMessageReceiverModel = new AccountMessageModel(); } public long Send(object obj) { return SendListener(this, obj); } @@ -5402,23 +5375,20 @@ public class FinalSender : com.chronoxor.FBE.Sender, IFinalSenderListener public readonly proto.FBE.FinalSender protoSender; // Sender models accessors - public readonly OrderMessageFinalModel OrderMessageModel; - public readonly BalanceMessageFinalModel BalanceMessageModel; - public readonly AccountMessageFinalModel AccountMessageModel; + private OrderMessageFinalModel _orderMessageModel; + public OrderMessageFinalModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageFinalModel(Buffer)); + private BalanceMessageFinalModel _balanceMessageModel; + public BalanceMessageFinalModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageFinalModel(Buffer)); + private AccountMessageFinalModel _accountMessageModel; + public AccountMessageFinalModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageFinalModel(Buffer)); public FinalSender() : base(true) { protoSender = new proto.FBE.FinalSender(Buffer); - OrderMessageModel = new OrderMessageFinalModel(Buffer); - BalanceMessageModel = new BalanceMessageFinalModel(Buffer); - AccountMessageModel = new AccountMessageFinalModel(Buffer); } public FinalSender(com.chronoxor.FBE.Buffer buffer) : base(buffer, true) { protoSender = new proto.FBE.FinalSender(Buffer); - OrderMessageModel = new OrderMessageFinalModel(Buffer); - BalanceMessageModel = new BalanceMessageFinalModel(Buffer); - AccountMessageModel = new AccountMessageFinalModel(Buffer); } public long Send(object obj) { return SendListener(this, obj); } @@ -5521,29 +5491,20 @@ public class FinalReceiver : com.chronoxor.FBE.Receiver, IFinalReceiverListener private global::com.chronoxor.protoex.AccountMessage AccountMessageValue; // Receiver models accessors - private readonly OrderMessageFinalModel OrderMessageModel; - private readonly BalanceMessageFinalModel BalanceMessageModel; - private readonly AccountMessageFinalModel AccountMessageModel; + private OrderMessageFinalModel _orderMessageModel; + private OrderMessageFinalModel OrderMessageModel => _orderMessageModel ?? (_orderMessageModel = new OrderMessageFinalModel()); + private BalanceMessageFinalModel _balanceMessageModel; + private BalanceMessageFinalModel BalanceMessageModel => _balanceMessageModel ?? (_balanceMessageModel = new BalanceMessageFinalModel()); + private AccountMessageFinalModel _accountMessageModel; + private AccountMessageFinalModel AccountMessageModel => _accountMessageModel ?? (_accountMessageModel = new AccountMessageFinalModel()); public FinalReceiver() : base(true) { protoReceiver = new proto.FBE.FinalReceiver(Buffer); - OrderMessageValue = global::com.chronoxor.protoex.OrderMessage.Default; - OrderMessageModel = new OrderMessageFinalModel(); - BalanceMessageValue = global::com.chronoxor.protoex.BalanceMessage.Default; - BalanceMessageModel = new BalanceMessageFinalModel(); - AccountMessageValue = global::com.chronoxor.protoex.AccountMessage.Default; - AccountMessageModel = new AccountMessageFinalModel(); } public FinalReceiver(com.chronoxor.FBE.Buffer buffer) : base(buffer, true) { protoReceiver = new proto.FBE.FinalReceiver(Buffer); - OrderMessageValue = global::com.chronoxor.protoex.OrderMessage.Default; - OrderMessageModel = new OrderMessageFinalModel(); - BalanceMessageValue = global::com.chronoxor.protoex.BalanceMessage.Default; - BalanceMessageModel = new BalanceMessageFinalModel(); - AccountMessageValue = global::com.chronoxor.protoex.AccountMessage.Default; - AccountMessageModel = new AccountMessageFinalModel(); } internal override bool OnReceive(long type, byte[] buffer, long offset, long size) { return OnReceiveListener(this, type, buffer, offset, size); } @@ -5634,9 +5595,12 @@ public class FinalClient : com.chronoxor.FBE.Client, IFinalClientListener public readonly proto.FBE.FinalClient protoClient; // Client sender models accessors - public readonly OrderMessageFinalModel OrderMessageSenderModel; - public readonly BalanceMessageFinalModel BalanceMessageSenderModel; - public readonly AccountMessageFinalModel AccountMessageSenderModel; + private OrderMessageFinalModel _orderMessageSenderModel; + public OrderMessageFinalModel OrderMessageSenderModel => _orderMessageSenderModel ?? (_orderMessageSenderModel = new OrderMessageFinalModel(SendBuffer)); + private BalanceMessageFinalModel _balanceMessageSenderModel; + public BalanceMessageFinalModel BalanceMessageSenderModel => _balanceMessageSenderModel ?? (_balanceMessageSenderModel = new BalanceMessageFinalModel(SendBuffer)); + private AccountMessageFinalModel _accountMessageSenderModel; + public AccountMessageFinalModel AccountMessageSenderModel => _accountMessageSenderModel ?? (_accountMessageSenderModel = new AccountMessageFinalModel(SendBuffer)); // Client receiver values accessors private global::com.chronoxor.protoex.OrderMessage OrderMessageReceiverValue; @@ -5644,35 +5608,20 @@ public class FinalClient : com.chronoxor.FBE.Client, IFinalClientListener private global::com.chronoxor.protoex.AccountMessage AccountMessageReceiverValue; // Client receiver models accessors - private readonly OrderMessageFinalModel OrderMessageReceiverModel; - private readonly BalanceMessageFinalModel BalanceMessageReceiverModel; - private readonly AccountMessageFinalModel AccountMessageReceiverModel; + private OrderMessageFinalModel _orderMessageReceiverModel; + private OrderMessageFinalModel OrderMessageReceiverModel => _orderMessageReceiverModel ?? (_orderMessageReceiverModel = new OrderMessageFinalModel()); + private BalanceMessageFinalModel _balanceMessageReceiverModel; + private BalanceMessageFinalModel BalanceMessageReceiverModel => _balanceMessageReceiverModel ?? (_balanceMessageReceiverModel = new BalanceMessageFinalModel()); + private AccountMessageFinalModel _accountMessageReceiverModel; + private AccountMessageFinalModel AccountMessageReceiverModel => _accountMessageReceiverModel ?? (_accountMessageReceiverModel = new AccountMessageFinalModel()); public FinalClient() : base(true) { protoClient = new proto.FBE.FinalClient(SendBuffer, ReceiveBuffer); - OrderMessageSenderModel = new OrderMessageFinalModel(SendBuffer); - OrderMessageReceiverValue = global::com.chronoxor.protoex.OrderMessage.Default; - OrderMessageReceiverModel = new OrderMessageFinalModel(); - BalanceMessageSenderModel = new BalanceMessageFinalModel(SendBuffer); - BalanceMessageReceiverValue = global::com.chronoxor.protoex.BalanceMessage.Default; - BalanceMessageReceiverModel = new BalanceMessageFinalModel(); - AccountMessageSenderModel = new AccountMessageFinalModel(SendBuffer); - AccountMessageReceiverValue = global::com.chronoxor.protoex.AccountMessage.Default; - AccountMessageReceiverModel = new AccountMessageFinalModel(); } public FinalClient(com.chronoxor.FBE.Buffer sendBuffer, com.chronoxor.FBE.Buffer receiveBuffer) : base(sendBuffer, receiveBuffer, true) { protoClient = new proto.FBE.FinalClient(SendBuffer, ReceiveBuffer); - OrderMessageSenderModel = new OrderMessageFinalModel(SendBuffer); - OrderMessageReceiverValue = global::com.chronoxor.protoex.OrderMessage.Default; - OrderMessageReceiverModel = new OrderMessageFinalModel(); - BalanceMessageSenderModel = new BalanceMessageFinalModel(SendBuffer); - BalanceMessageReceiverValue = global::com.chronoxor.protoex.BalanceMessage.Default; - BalanceMessageReceiverModel = new BalanceMessageFinalModel(); - AccountMessageSenderModel = new AccountMessageFinalModel(SendBuffer); - AccountMessageReceiverValue = global::com.chronoxor.protoex.AccountMessage.Default; - AccountMessageReceiverModel = new AccountMessageFinalModel(); } public long Send(object obj) { return SendListener(this, obj); } diff --git a/source/generator_csharp.cpp b/source/generator_csharp.cpp index 533dfb6bf..d069d0a4a 100644 --- a/source/generator_csharp.cpp +++ b/source/generator_csharp.cpp @@ -6696,13 +6696,21 @@ void GeneratorCSharp::GenerateSender(const std::string& domain, const std::share WriteLine(); } - // Generate sender models accessors + // Generate sender models accessors, each model created on the first send of its message: + // creating all of them in the constructor makes the JIT compile every model of the protocol + // before the first message goes out, whichever messages the process will actually use if (p->body) { WriteLineIndent("// Sender models accessors"); for (const auto& s : p->body->structs) + { if (s->message) - WriteLineIndent("public readonly " + *s->name + model + " " + *s->name + "Model;"); + { + std::string field = "_" + ConvertToLower(*s->name) + "Model"; + WriteLineIndent("private " + *s->name + model + " " + field + ";"); + WriteLineIndent("public " + *s->name + model + " " + *s->name + "Model => " + field + " ?? (" + field + " = new " + *s->name + model + "(Buffer));"); + } + } WriteLine(); } @@ -6715,12 +6723,6 @@ void GeneratorCSharp::GenerateSender(const std::string& domain, const std::share for (const auto& import : p->import->imports) WriteLineIndent(*import + "Sender = new " + *import + ".FBE." + sender + "(Buffer);"); } - if (p->body) - { - for (const auto& s : p->body->structs) - if (s->message) - WriteLineIndent(*s->name + "Model = new " + *s->name + model + "(Buffer);"); - } Indent(-1); WriteLineIndent("}"); WriteLineIndent("public " + sender + "(" + domain + "FBE.Buffer buffer) : base(buffer, " + std::string(final ? "true" : "false") + ")"); @@ -6731,12 +6733,6 @@ void GeneratorCSharp::GenerateSender(const std::string& domain, const std::share for (const auto& import : p->import->imports) WriteLineIndent(*import + "Sender = new " + *import + ".FBE." + sender + "(Buffer);"); } - if (p->body) - { - for (const auto& s : p->body->structs) - if (s->message) - WriteLineIndent(*s->name + "Model = new " + *s->name + model + "(Buffer);"); - } Indent(-1); WriteLineIndent("}"); WriteLine(); @@ -6912,8 +6908,14 @@ void GeneratorCSharp::GenerateReceiver(const std::string& domain, const std::sha WriteLine(); WriteLineIndent("// Receiver models accessors"); for (const auto& s : p->body->structs) + { if (s->message) - WriteLineIndent("private readonly " + *s->name + model + " " + *s->name + "Model;"); + { + std::string field = "_" + ConvertToLower(*s->name) + "Model"; + WriteLineIndent("private " + *s->name + model + " " + field + ";"); + WriteLineIndent("private " + *s->name + model + " " + *s->name + "Model => " + field + " ?? (" + field + " = new " + *s->name + model + "());"); + } + } WriteLine(); } @@ -6926,18 +6928,6 @@ void GeneratorCSharp::GenerateReceiver(const std::string& domain, const std::sha for (const auto& import : p->import->imports) WriteLineIndent(*import + "Receiver = new " + *import + ".FBE." + receiver + "(Buffer);"); } - if (p->body) - { - for (const auto& s : p->body->structs) - { - if (s->message) - { - std::string struct_name = ConvertTypeName(domain, *p->name, *s->name, false); - WriteLineIndent(*s->name + "Value = " + struct_name + ".Default;"); - WriteLineIndent(*s->name + "Model = new " + *s->name + model + "();"); - } - } - } Indent(-1); WriteLineIndent("}"); WriteLineIndent("public " + receiver + "(" + domain + "FBE.Buffer buffer) : base(buffer, " + std::string(final ? "true" : "false") + ")"); @@ -6948,18 +6938,6 @@ void GeneratorCSharp::GenerateReceiver(const std::string& domain, const std::sha for (const auto& import : p->import->imports) WriteLineIndent(*import + "Receiver = new " + *import + ".FBE." + receiver + "(Buffer);"); } - if (p->body) - { - for (const auto& s : p->body->structs) - { - if (s->message) - { - std::string struct_name = ConvertTypeName(domain, *p->name, *s->name, false); - WriteLineIndent(*s->name + "Value = " + struct_name + ".Default;"); - WriteLineIndent(*s->name + "Model = new " + *s->name + model + "();"); - } - } - } Indent(-1); WriteLineIndent("}"); WriteLine(); @@ -7109,8 +7087,14 @@ void GeneratorCSharp::GenerateProxy(const std::string& domain, const std::shared { WriteLineIndent("// Proxy models accessors"); for (const auto& s : p->body->structs) + { if (s->message) - WriteLineIndent("private readonly " + *s->name + model + " " + *s->name + "Model;"); + { + std::string field = "_" + ConvertToLower(*s->name) + "Model"; + WriteLineIndent("private " + *s->name + model + " " + field + ";"); + WriteLineIndent("private " + *s->name + model + " " + *s->name + "Model => " + field + " ?? (" + field + " = new " + *s->name + model + "());"); + } + } WriteLine(); } @@ -7123,12 +7107,6 @@ void GeneratorCSharp::GenerateProxy(const std::string& domain, const std::shared for (const auto& import : p->import->imports) WriteLineIndent(*import + "Proxy = new " + *import + ".FBE." + proxy + "(Buffer);"); } - if (p->body) - { - for (const auto& s : p->body->structs) - if (s->message) - WriteLineIndent(*s->name + "Model = new " + *s->name + model + "();"); - } Indent(-1); WriteLineIndent("}"); WriteLineIndent("public " + proxy + "(" + domain + "FBE.Buffer buffer) : base(buffer, " + std::string(final ? "true" : "false") + ")"); @@ -7139,12 +7117,6 @@ void GeneratorCSharp::GenerateProxy(const std::string& domain, const std::shared for (const auto& import : p->import->imports) WriteLineIndent(*import + "Proxy = new " + *import + ".FBE." + proxy + "(Buffer);"); } - if (p->body) - { - for (const auto& s : p->body->structs) - if (s->message) - WriteLineIndent(*s->name + "Model = new " + *s->name + model + "();"); - } Indent(-1); WriteLineIndent("}"); WriteLine(); @@ -7280,8 +7252,14 @@ void GeneratorCSharp::GenerateClient(const std::string& domain, const std::share { WriteLineIndent("// Client sender models accessors"); for (const auto& s : p->body->structs) + { if (s->message) - WriteLineIndent("public readonly " + *s->name + model + " " + *s->name + "SenderModel;"); + { + std::string field = "_" + ConvertToLower(*s->name) + "SenderModel"; + WriteLineIndent("private " + *s->name + model + " " + field + ";"); + WriteLineIndent("public " + *s->name + model + " " + *s->name + "SenderModel => " + field + " ?? (" + field + " = new " + *s->name + model + "(SendBuffer));"); + } + } WriteLine(); } @@ -7300,8 +7278,14 @@ void GeneratorCSharp::GenerateClient(const std::string& domain, const std::share WriteLine(); WriteLineIndent("// Client receiver models accessors"); for (const auto& s : p->body->structs) + { if (s->message) - WriteLineIndent("private readonly " + *s->name + model + " " + *s->name + "ReceiverModel;"); + { + std::string field = "_" + ConvertToLower(*s->name) + "ReceiverModel"; + WriteLineIndent("private " + *s->name + model + " " + field + ";"); + WriteLineIndent("private " + *s->name + model + " " + *s->name + "ReceiverModel => " + field + " ?? (" + field + " = new " + *s->name + model + "());"); + } + } WriteLine(); } @@ -7351,19 +7335,6 @@ void GeneratorCSharp::GenerateClient(const std::string& domain, const std::share if (p->import) for (const auto& import : p->import->imports) WriteLineIndent(*import + "Client = new " + *import + ".FBE." + client + "(SendBuffer, ReceiveBuffer);"); - if (p->body) - { - for (const auto& s : p->body->structs) - { - if (s->message) - { - std::string struct_name = ConvertTypeName(domain, *p->name, *s->name, false); - WriteLineIndent(*s->name + "SenderModel = new " + *s->name + model + "(SendBuffer);"); - WriteLineIndent(*s->name + "ReceiverValue = " + struct_name + ".Default;"); - WriteLineIndent(*s->name + "ReceiverModel = new " + *s->name + model + "();"); - } - } - } if (!responses.empty()) { for (const auto& response : responses) @@ -7384,19 +7355,6 @@ void GeneratorCSharp::GenerateClient(const std::string& domain, const std::share if (p->import) for (const auto& import : p->import->imports) WriteLineIndent(*import + "Client = new " + *import + ".FBE." + client + "(SendBuffer, ReceiveBuffer);"); - if (p->body) - { - for (const auto& s : p->body->structs) - { - if (s->message) - { - std::string struct_name = ConvertTypeName(domain, *p->name, *s->name, false); - WriteLineIndent(*s->name + "SenderModel = new " + *s->name + model + "(SendBuffer);"); - WriteLineIndent(*s->name + "ReceiverValue = " + struct_name + ".Default;"); - WriteLineIndent(*s->name + "ReceiverModel = new " + *s->name + model + "();"); - } - } - } if (!responses.empty()) { for (const auto& response : responses) @@ -8082,6 +8040,13 @@ bool GeneratorCSharp::IsReferenceType(const std::string& type) return ((type == "bytes") || (type == "string")); } +std::string GeneratorCSharp::ConvertToLower(const std::string& type) +{ + std::string result = CppCommon::StringUtils::ToTrim(type); + result[0] = std::tolower(result[0]); + return result; +} + std::string GeneratorCSharp::ConvertEnumRead(const std::string& type) { if (type == "byte")