RMI

ProudNet is a self-developed Remote Method Invocation (RMI) system that is much faster and lighter than the more popular IDL formats and RMI systems. For game development, we only support asynchronous RMI, i.e. RMI that does not wait for a 'function call return value'.

RMI function groups

A collection of zero or more RMI functions. In a PIDL file, it takes the form of a global construction block.

global SimpleC2S
{
    ...;
}

When you call a RMI function on the proxy, it returns immediately, and you do not have to wait to receive the results of the RMI function execution on the proxy side.

RMI method argument properties

Method arguments contain property definitions, and you can write one or more for each parameter.

in : It means that it is an input format argument and must be used. 'out' is not supported in the current version.

// For example, if you declare the RMI method as follows 
Test([in] Proud::String a,[in] int b,[in] float c);

// the following C++ code is generated.
Test(Proud::HostID remote, Proud::RmiContext& rmiContext, const Proud::String& a, const int& b, const float& c);

In most cases, the attributes of the arguments to RMI methods use only in.

- byval properties

This means that the argument is passed by value, and when this is used, the & sign is omitted from the argument format in C++ proxy and stub. It is suitable for small argument types such as int or float.

// If you declare an RMI function like this,
Foo([in] int a);

// Function parameters are passed by reference to the created C++ Proxy and Stub. 
// This is the const int& a below.
SimpleC2S.Foo = [](Proud::HostID from, Proud::RmiContext& rmiContext, const int& a) = { ... };

// If you declare an RMI function by adding a byval attribute like this,
Foo([in, byval] int a);

// it is changed to by value.
SimpleC2S.Foo = [](Proud::HostID from, Proud::RmiContext& rmiContext, int a) = { ... };

- mutable properties

This means that the argument is not const type, and when used, the C++ proxy and stub will omit the const keyword from the argument type. This is appropriate when you want to change the value of an argument received from an RMI stub.

// If you add a mutable property like this
Foo([in, mutable] int a);

// it changes to a variable that can be changed. The const will be missing.
SimpleC2S.Foo = [](Proud::HostID from, Proud::RmiContext& rmiContext, int& a) = { ... };

Communicating between programs in different languages

There may be times when you want two programs to communicate over ProudNet, but in different programming languages. In this case, the PIDL compiler creates proxy and stub in two or more languages, and then each program can use what it needs.

Basic types such as int, double and string are already provided in ProudNet's wrapping module for languages other than C++. However, in different languages, the names of these basic types tend to be different. For example, in C# the string class is System.String, while in C++ it is std::string, std::wstring, ATL::CString and Proud::String.

To address this, the PIDL compiler provides the ability to change the type of variables in generated proxy and stub to be language specific if desired.

Below is an example of usage.

rename cs(TypeA,TypeB);     // 1
 
rename cpp(TypeC,TypeD);    // 2
 
global XXX 2000
{
    Foo([in]TypeA a);  // 3
    Goo([in]TypeC c);  // 4
}

RMI message scope

Each RMI function declaration has one message type. The message type in ProudNet is determined by the user in a range of 60,000 or less, which is done when the user writes the .pidl file.

For versions earlier than 1.7.42965-master, you should use values in the range of 1,300 to 60,000.

Examples of message type values for each RMI are shown below.

global SampleRMI 2000
{
    Foo1(...); // Assigned Message Type ID = 2001
    Foo2(...); // Assigned Message Type ID = 2002
    Foo3(...); // Assigned Message Type ID = 2003
}

Each function increases the message type value by one. And we will refer to the type value assigned to the last declared RMI function as the message range. In the example above, 2,000 to 2,003 is the message range for SampleRMI.

When you attach the created Proxy and Stub to Proud.CNetClient , Proud.CNetServer , Proud.CLanClient , Proud.CLanServer, the message scope of each RMI function group is reserved to RMI message scope Proud.CNetClient , Proud.CNetServer , Proud.CLanClient , Proud.CLanServer .

If the message scopes of the proxy and stub to be attached overlap, AttachProxy() or AttachStub() will raise an exception.

C#: CNetClient -> NetClient

CNetServer -> NetServer


Usage

Utilization of RMI

Last updated