Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Core:setStateComponent and Core:setStateSingleton #42

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

benbrimeyer
Copy link
Contributor

@benbrimeyer benbrimeyer commented Feb 25, 2020

Adds the following members to Core to support a setStateComponent method

  • Core:setStateSingleton(componentId, newState)
    • Used to set the component's state of a singleton

Given a a component identifier and a dictionary of fields and values, overwrites the state of an existing singleton. Returns a boolean that is true if the component's state was changed. Throws if the identified singleton has not been added to the entity or if the identified component class isn't registered in the Core.

  • Core:setStateComponent(entityId, componentId, newState)
    • Used to set the component's state of an entity

Given an entity ID, a component identifier, and a dictionary of fields and values, overwrites the state of an existing component of the entity. Returns a boolean that is true if the component's state was changed. Throws if the identified component class has not been added to the entity or if the identified component class isn't registered in the Core.

  • Core:getComponentStateSetSignal(componentId)
    • Fires when setStateComponent is called on an entity

Gets a signal that fires whenever a component's state is set. The signal will be fired with the entity ID and the component that was set. Throws if the identified component class isn't registered in the Core.

  • Core.None
    • When used with a new state of setStateComponent, will delete the value from the component's state.

A symbol that can be used in conjunction with Core:setStateComponent method which will tell the Core to delete a field of a component if used as part of the new given state.

Relevant core plugin lifecycle added as well: componentStateSet(entityId, componentInstance)

Copy link
Collaborator

@AmaranthineCodices AmaranthineCodices left a comment

Choose a reason for hiding this comment

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

Sorry for taking so long to review this 😢

There's a couple of changes I'd like to see made here before merging.

or if the identified component class isn't registered in the Core.

]]
function Core:setStateComponent(entityId, componentIdentifier, newState)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think I'd prefer setComponentState here, I think it reads better!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I opted for setStateComponent to keep in the tradition of [actionType]Component as that also translates well to the plugin variants.

local componentInstance = componentInstances[entityId]

if componentInstance ~= nil then

Copy link
Collaborator

Choose a reason for hiding this comment

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

Prefix newline here can be removed.

Suggested change

core:setStateComponent(entity, ComponentClass, { x = 0 })
end).to.throw()
end)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change


local entity = core:createEntity()
core:addComponent(entity, ComponentClass)
core:setStateComponent(entity, ComponentClass, { x = 10, y = 20 })
Copy link
Collaborator

Choose a reason for hiding this comment

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

This doesn't actually verify that the fields were set here, just that the call didn't throw.


Given an entity ID, a component identifier, and a dictionary of fields
and values, overwrites the state of an existing component of the entity.
Returns a boolean that is true if the component's state was changed.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This method doesn't actually return false in any case. It'd make sense to remove this or change the implementation; a good place to check for a possible diff would be in the loop over newState.

It would also make sense to not fire the signal/invoke the plugin methods if we know a mutation didn't take place.

end
else
error(errorMessages.componentNotRegistered:format(componentIdentifier), 2)
end
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should return false, nil here to avoid implicitly returning 0 values.


local entity = core:createEntity()
core:addComponent(entity, ComponentClass)
local success, component = core:setStateComponent(entity, ComponentClass, { x = 10, y = core.None })
Copy link
Collaborator

Choose a reason for hiding this comment

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

success here is a misnomer: the first return value indicates state mutation, not success. This should be probably named mutated or something similar.

expect(component.x).to.equal(10)
expect(component.y).to.equal(20)
end)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd like to see an explicit test for the first return value, including the cases where it will be false (setState on an empty table and with the same values, etc).

@@ -24,6 +24,9 @@
- componentAdded(Core, entityId, componentInstance): Called when a component
instance is added to an entity. Called before the addition signal for that
component has been fired.
componentStateSet(Core, entityId, componentInstance): Called when a component
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make sense for plugins to be able to observe the state diff? This would be useful for e.g. replication plugins so that they can send just the state diff rather than the entire component state.

@benbrimeyer benbrimeyer changed the title Add Core:setStateComponent Add Core:setStateComponent and Core:setStateSingleton May 21, 2020
@Phalanxia
Copy link
Member

What are some use cases you have in mind for this? 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants