@ -340,27 +340,11 @@ void {{ ClassName }}::{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.join(par
{% endmacro %}
{% endmacro %}
{#
{#
#}
{% macro DefineRpcSignal(Component, ClassName, Property, InvokeFrom) %}
{% set paramNames = [] %}
{% set paramTypes = [] %}
{% set paramDefines = [] %}
{{ AutoComponentMacros.ParseRpcParams(Property, paramNames, paramTypes, paramDefines) }}
void {{ ClassName }}::Signal{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.join(paramDefines) }})
{
m_{{ UpperFirst(Property.attrib['Name']) }}Event.Signal({{ ', '.join(paramNames) }});
}
{% endmacro %}
{#
#}
#}
{% macro DefineRpcInvocations(Component, ClassName, InvokeFrom, HandleOn, IsProtected) %}
{% macro DefineRpcInvocations(Component, ClassName, InvokeFrom, HandleOn, IsProtected) %}
{% call(Property) AutoComponentMacros.ParseRemoteProcedures(Component, InvokeFrom, HandleOn) %}
{% call(Property) AutoComponentMacros.ParseRemoteProcedures(Component, InvokeFrom, HandleOn) %}
{% if Property.attrib['IsPublic']|booleanTrue != IsProtected %}
{% if Property.attrib['IsPublic']|booleanTrue != IsProtected %}
{{ DefineRpcInvocation(Component, ClassName, Property, InvokeFrom, HandleOn) -}}
{{ DefineRpcInvocation(Component, ClassName, Property, InvokeFrom, HandleOn) -}}
{% if Property.attrib['GenerateEventBindings']|booleanTrue == true %}
{{ DefineRpcSignal(Component, ClassName, Property, InvokeFrom) -}}
{% endif %}
{% endif %}
{% endif %}
{% endcall %}
{% endcall %}
{% endmacro %}
{% endmacro %}
@ -374,33 +358,46 @@ void {{ ClassName }}::Signal{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.jo
{% set paramTypes = [] %}
{% set paramTypes = [] %}
{% set paramDefines = [] %}
{% set paramDefines = [] %}
{{ AutoComponentMacros.ParseRpcParams(Property, paramNames, paramTypes, paramDefines) }}
{{ AutoComponentMacros.ParseRpcParams(Property, paramNames, paramTypes, paramDefines) }}
->Method("{{ UpperFirst(Property.attrib['Name']) }}", [](const {{ ClassName }}* self, {{ ', '.join(paramDefines) }}) {
->Method("{{ UpperFirst(Property.attrib['Name']) }}", []({{ ClassName }}* self, {{ ', '.join(paramDefines) }}) {
{% if (InvokeFrom == 'Server') %}
self->{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.join(paramNames) }});
{% elif (InvokeFrom == 'Authority') or (InvokeFrom == 'Autonomous') %}
if (self->m_controller)
{
self->m_controller->{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.join(paramNames) }});
self->m_controller->{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.join(paramNames) }});
}
else
{
AZ_Warning("Network RPC", false, "{{ ClassName }} {{ UpperFirst(Property.attrib['Name']) }} method failed. Entity '%s' (id: %s) {{ ClassName }} is missing the network controller. This remote-procedure can only be invoked from {{InvokeFrom}} network entities, because this entity doesn't have a controller, it must not be a {{InvokeFrom}} entity. Please check your network context before attempting to call {{ UpperFirst(Property.attrib['Name']) }}.", self->GetEntity()->GetName().c_str(), self->GetEntityId().ToString().c_str())
}
{% endif %}
})
})
->Method("{{ UpperFirst(Property.attrib['Name']) }}ByEntityId", [](AZ::EntityId id, {{ ', '.join(paramDefines) }}) {
->Method("{{ UpperFirst(Property.attrib['Name']) }}ByEntityId", [](AZ::EntityId id, {{ ', '.join(paramDefines) }}) {
AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(id);
AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(id);
if (!entity)
if (!entity)
{
{
AZ_Warning("Network Property ", false, "{{ ClassName }} {{ UpperFirst(Property.attrib['Name']) }}ByEntityId failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
AZ_Warning("Network RPC ", false, "{{ ClassName }} {{ UpperFirst(Property.attrib['Name']) }}ByEntityId failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
return;
return;
}
}
{{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>();
{{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>();
if (!networkComponent)
if (!networkComponent)
{
{
AZ_Warning("Network Property ", false, "{{ ClassName }} {{ UpperFirst(Property.attrib['Name']) }}ByEntityId failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str())
AZ_Warning("Network RPC ", false, "{{ ClassName }} {{ UpperFirst(Property.attrib['Name']) }}ByEntityId failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str())
return;
return;
}
}
{% if (InvokeFrom == 'Server') %}
networkComponent->{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.join(paramNames) }});
{% elif (InvokeFrom == 'Authority') or (InvokeFrom == 'Autonomous') %}
{{ ClassName }}Controller* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController());
{{ ClassName }}Controller* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController());
if (!controller)
if (!controller)
{
{
AZ_Warning("Network Property ", false, "{{ ClassName }} {{ UpperFirst(Property.attrib['Name']) }}ByEntityId method failed. Entity '%s' (id: %s) {{ ClassName }} is missing the network controller. This RemoteProcedure can only be invoked from {{InvokeFrom}} network entities, because this entity doesn't have a controller, it must not be a {{InvokeFrom}} entity. Please check your network context before attempting to call {{ UpperFirst(Property.attrib['Name']) }}.", entity->GetName().c_str(), id.ToString().c_str())
AZ_Warning("Network RPC ", false, "{{ ClassName }} {{ UpperFirst(Property.attrib['Name']) }}ByEntityId method failed. Entity '%s' (id: %s) {{ ClassName }} is missing the network controller. This RemoteProcedure can only be invoked from {{InvokeFrom}} network entities, because this entity doesn't have a controller, it must not be a {{InvokeFrom}} entity. Please check your network context before attempting to call {{ UpperFirst(Property.attrib['Name']) }}.", entity->GetName().c_str(), id.ToString().c_str())
return;
return;
}
}
controller->{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.join(paramNames) }});
controller->{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.join(paramNames) }});
{% endif %}
}, { { { "Source", "The Source containing the {{ ClassName }}Controller" }{% for paramName in paramNames %}, {"{{ paramName }}"}{% endfor %}}})
}, { { { "Source", "The Source containing the {{ ClassName }}Controller" }{% for paramName in paramNames %}, {"{{ paramName }}"}{% endfor %}}})
->Attribute(AZ::Script::Attributes::ToolTip, "{{Property.attrib['Description']}}")
->Attribute(AZ::Script::Attributes::ToolTip, "{{Property.attrib['Description']}}")
{% endif %}
{% endif %}
@ -436,9 +433,13 @@ void {{ ClassName }}::Signal{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.jo
{% set paramTypes = [] %}
{% set paramTypes = [] %}
{% set paramDefines = [] %}
{% set paramDefines = [] %}
{{ AutoComponentMacros.ParseRpcParams(Property, paramNames, paramTypes, paramDefines) }}
{{ AutoComponentMacros.ParseRpcParams(Property, paramNames, paramTypes, paramDefines) }}
->Method("Get{{ UpperFirst(Property.attrib['Name']) }}Event", [](const {{ ClassName }}* self) -> AZ::Event<{{ ', '.join(paramTypes) }}>&
->Method("Get{{ UpperFirst(Property.attrib['Name']) }}Event", []({{ ClassName }}* self) -> AZ::Event<{{ ', '.join(paramTypes) }}>&
{
{
{% if HandleOn == 'Client' %}
return self->Get{{ UpperFirst(Property.attrib['Name']) }}Event();
{% elif (HandleOn == 'Authority') or (HandleOn == 'Autonomous') %}
return self->m_controller->Get{{ UpperFirst(Property.attrib['Name']) }}Event();
return self->m_controller->Get{{ UpperFirst(Property.attrib['Name']) }}Event();
{% endif %}
})
})
->Attribute(AZ::Script::Attributes::AzEventDescription, {{ LowerFirst(Property.attrib['Name']) }}EventDesc)
->Attribute(AZ::Script::Attributes::AzEventDescription, {{ LowerFirst(Property.attrib['Name']) }}EventDesc)
->Method("Get{{ UpperFirst(Property.attrib['Name']) }}EventByEntityId", [](AZ::EntityId id) -> AZ::Event<{{ ', '.join(paramTypes) }}>*
->Method("Get{{ UpperFirst(Property.attrib['Name']) }}EventByEntityId", [](AZ::EntityId id) -> AZ::Event<{{ ', '.join(paramTypes) }}>*
@ -456,7 +457,9 @@ void {{ ClassName }}::Signal{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.jo
AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }}EventByEntityId failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str())
AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }}EventByEntityId failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str())
return nullptr;
return nullptr;
}
}
{% if HandleOn == 'Client' %}
return &networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}Event();
{% elif (HandleOn == 'Authority') or (HandleOn == 'Autonomous') %}
{{ ClassName }}Controller* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController());
{{ ClassName }}Controller* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController());
if (!controller)
if (!controller)
{
{
@ -465,6 +468,7 @@ void {{ ClassName }}::Signal{{ UpperFirst(Property.attrib['Name']) }}({{ ', '.jo
}
}
return &controller->Get{{ UpperFirst(Property.attrib['Name']) }}Event();
return &controller->Get{{ UpperFirst(Property.attrib['Name']) }}Event();
{% endif %}
})
})
->Attribute(AZ::Script::Attributes::AzEventDescription, AZStd::move({{ LowerFirst(Property.attrib['Name']) }}EventDesc))
->Attribute(AZ::Script::Attributes::AzEventDescription, AZStd::move({{ LowerFirst(Property.attrib['Name']) }}EventDesc))
{% endif %}
{% endif %}
@ -494,29 +498,31 @@ case {{ UpperFirst(Component.attrib['Name']) }}Internal::RemoteProcedure::{{ Upp
{
{
AZ_Assert(GetNetBindComponent()->GetNetEntityRole() == Multiplayer::NetEntityRole::Authority, "Entity proxy does not have authority");
AZ_Assert(GetNetBindComponent()->GetNetEntityRole() == Multiplayer::NetEntityRole::Authority, "Entity proxy does not have authority");
m_controller->Handle{{ UpperFirst(Property.attrib['Name']) }}(invokingConnection, {{ ', '.join(rpcParamList) }});
m_controller->Handle{{ UpperFirst(Property.attrib['Name']) }}(invokingConnection, {{ ', '.join(rpcParamList) }});
{% if Property.attrib['GenerateEventBindings']|booleanTrue == true %}
{% if ( Property.attrib['GenerateEventBindings']|booleanTrue == true) %}
m_controller->Signal{{ UpperFirst(Property.attrib['Name']) }} ({{ ', '.join(rpcParamList) }});
m_controller->Get{{ UpperFirst(Property.attrib['Name']) }}Event().Signal ({{ ', '.join(rpcParamList) }});
{% endif %}
{% endif %}
}
}
{% if Property.attrib['IsReliable']|booleanTrue %}
{# if the rpc is not reliable we can simply drop it, also note message reliability type is default reliable in EntityRpcMessage #}
else // Note that this rpc is marked reliable, trigger the appropriate rpc event so it can be forwarded
else // Note that this rpc is marked reliable, trigger the appropriate rpc event so it can be forwarded
{
{
{% if Property.attrib['IsReliable']|booleanTrue %}
{# if the rpc is not reliable we can simply drop it, also note message reliability type is default reliable in EntityRpcMessage #}
m_netBindComponent->{{ "GetSend" + InvokeFrom + "To" + HandleOn + "RpcEvent" }}().Signal(message);
m_netBindComponent->{{ "GetSend" + InvokeFrom + "To" + HandleOn + "RpcEvent" }}().Signal(message);
}
{% endif %}
{% endif %}
}
{% elif HandleOn == 'Autonomous' %}
{% elif HandleOn == 'Autonomous' %}
if (m_controller)
if (m_controller)
{
{
AZ_Assert(GetNetBindComponent()->GetNetEntityRole() == Multiplayer::NetEntityRole::Autonomous, "Entity proxy does not have autonomy");
AZ_Assert(GetNetBindComponent()->GetNetEntityRole() == Multiplayer::NetEntityRole::Autonomous, "Entity proxy does not have autonomy");
m_controller->Handle{{ UpperFirst(Property.attrib['Name']) }}(invokingConnection, {{ ', '.join(rpcParamList) }});
m_controller->Handle{{ UpperFirst(Property.attrib['Name']) }}(invokingConnection, {{ ', '.join(rpcParamList) }});
{% if Property.attrib['GenerateEventBindings']|booleanTrue == true %}
{% if Property.attrib['GenerateEventBindings']|booleanTrue == true %}
m_controller->Signal{{ UpperFirst(Property.attrib['Name']) }} ({{ ', '.join(rpcParamList) }});
m_controller->Get{{ UpperFirst(Property.attrib['Name']) }}Event().Signal ({{ ', '.join(rpcParamList) }});
{% endif %}
{% endif %}
}
}
{% else %}
{% elif HandleOn == 'Client' %}
Handle{{ UpperFirst(Property.attrib['Name']) }}(invokingConnection, {{ ', '.join(rpcParamList) }});
Handle{{ UpperFirst(Property.attrib['Name']) }}(invokingConnection, {{ ', '.join(rpcParamList) }});
{% if Property.attrib['GenerateEventBindings']|booleanTrue == true %}
m_{{ UpperFirst(Property.attrib['Name']) }}Event.Signal({{ ', '.join(rpcParamList) }});
{% endif %}
{% endif %}
{% endif %}
}
}
else if (paramsSerialized)
else if (paramsSerialized)