Skip to content

Add native code support & InputNetowkEncoder.#19

Merged
AndreaCatania merged 1 commit intomainfrom
net_encoder_4v
Aug 15, 2022
Merged

Add native code support & InputNetowkEncoder.#19
AndreaCatania merged 1 commit intomainfrom
net_encoder_4v

Conversation

@AndreaCatania
Copy link
Collaborator

Port of: #15

This commit add support to implement the NetwokedController class from C++;
also it add the InputNetworkEncoder that can be used to simplify the
character controller implementation.

// Usually called into the constructor, or during the controller
// initialization. Registers the inputs encoded by `input_encoder`.
uint32_t input_id = input_encoder->register_input(
	StringName("move"),
	Vector2(), // Default
	DataBuffer::DATA_TYPE_NORMALIZED_VECTOR2,
	DataBuffer::COMPRESSION_LEVEL_2);

// Usually this is called from `collect_inputs()`.
// It encodes the input_array into the buffer, according to the
// registered inputs.
input_encoder->encode(input_array, r_buffer);

// Usually this is called from `controller_process`.
// It decodes the buffer and put the inputs inside the `input_array`.
input_encoder->decode(p_buffer, input_array);

// Usually this is called from `are_inputs_different`.
input_encoder->are_different(p_buffer_a, p_buffer_b);

// Usually this is called from `count_input_size`.
input_encoder->count_size(p_buffer);

> Port of: #15

This commit add support to implement the NetwokedController class from C++;
also it add the InputNetworkEncoder that can be used to simplify the
character controller implementation.

```c++
// Usually called into the constructor, or during the controller
// initialization. Registers the inputs encoded by `input_encoder`.
uint32_t input_id = input_encoder->register_input(
	StringName("move"),
	Vector2(), // Default
	DataBuffer::DATA_TYPE_NORMALIZED_VECTOR2,
	DataBuffer::COMPRESSION_LEVEL_2);

// Usually this is called from `collect_inputs()`.
// It encodes the input_array into the buffer, according to the
// registered inputs.
input_encoder->encode(input_array, r_buffer);

// Usually this is called from `controller_process`.
// It decodes the buffer and put the inputs inside the `input_array`.
input_encoder->decode(p_buffer, input_array);

// Usually this is called from `are_inputs_different`.
input_encoder->are_different(p_buffer_a, p_buffer_b);

// Usually this is called from `count_input_size`.
input_encoder->count_size(p_buffer);
```
Copy link
Contributor

@kubecz3k kubecz3k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but leaved some api suggestion which you might consider + some questions mostly to learn how it works

return i;
}
}
return INDEX_NONE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when I have such functions which are returning uncommon value to act as exception I always wonder how much do I expect for the person who is using this function to always check if that exception happened, couple thoughts:

  • For sure such function documentation is always welcome
  • other thing is the usage of INDEX_NONE in situation when it's not exposed to GdScript...
  • For such ID thing I usually expect it will return -1 in case of error actually (since that value very clearly dont make any sense and it's very clearly intentional when debugging (some very big int feels like a pointer or smth)
  • If I expect that its not super rare for user to check it I usually actually add new function called 'has_input_id' which is documented, and do an assertion inside find_input_id (like soft crash) with communicate that there is no such id and 'has_input_id' should be used - only by the fact such function is on a list when one is reading codumention/help makes him aware that it can happen

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are perfectly correct. Also I just realized INDEX_NONE is not exposed to GDS.

return size;
}

void InputNetworkEncoder::script_encode(const Array &p_inputs, Object *r_buffer) const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think NetworkedInputInfo is exposed to GdScript, so what's expected as input here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The input is just an array of variant. Each variant holds the input value

GDVIRTUAL_CALL_PTR(
node,
_controller_process,
node->native_controller_process(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why NetworkedController instance is called "node"? It was not obvious for me what this member is representing (and if some type casting is not coming into play here)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essentially ServerController is a class that operates on a target node. That's the reason why you don't need any cast, because node is a member and already casted.
A better name should be used, anyway, I agree.

node->get_inputs_buffer_mut().begin_write(METADATA_SIZE);
node->get_inputs_buffer_mut().seek(METADATA_SIZE);
node->call(SNAME("_collect_inputs"), p_delta, &node->get_inputs_buffer_mut());
node->native_collect_inputs(p_delta, node->get_inputs_buffer_mut());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to ensure: will it still collect inputs of gdscript implementation here or it's not needed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(apply also to other changes around)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume it will do, since there is GDVIRTUAL_CALL(_collect_inputs, p_delta, &r_buffer); inside native_collect_inputs() so I think it's the new way of calling gdscript from c++?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

native_collect_inputs is just a wrap function that can be overridden from C++. If not, the GDS function is normally called using GDVIRTUAL_CALL(_collect_inputs, p_delta, &r_buffer); inside native_collect_inputs()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants