Notification of changes to the shared state of SharedState in components
- Tutorial
As a continuation to the previous article about the general state for components , I continue to develop the topic and I want to implement a feature that allows you to catch and process an event in each component by a state change (when the data in the general state changes in some component).
Reference to the project
Usually, in order to track the change in the data, in some component, a direct link is created, that is, we, either in the Update method, check whether the data has changed there. Frame by frame data
verification through the Update method
or we subscribe to a very specific event, which is triggered independently in the “monitored” component, and is eventually processed.
Subscribing to an event in a component and processing it
There are many drawbacks to this approach, which for the most part are described in the last article. The main common cause of these shortcomings is strong coherence and complex maintenance (the ability to maintain, develop the project, refactor).
Now that you have a system that allows you to weaken the connection between components and the means to create mailings between components, you can get rid of manually checking the values in the general state, as follows:
General condition change notification scheme
In the implementation described in the previous article, the data changes in one place , in the indexer of the SharedState component and therefore it is very easy to control their change.
Indexer in general state
In the indexer setter, we assign state values.
Now, for the SharedState component, you need to add a dependency on SharedEvents , since I’ll use it to send notifications. Add attribute for SharedState
Adding a dependency to SharedState from SharedEvents
And creating a class that inherits from EventData to send data in the state change notification. It will contain the name of the parameter, the state and its new value.
Adding a class that contains information about changes in the general state.
Now add a link to SharedEvents , retrieving it from the game object in the SharedState component .
Getting SharedEvents in the SharedState component.
Now we will change the setter of the indexer to so that at each state change a notification with the name “sharedstatechanged” is created and we will pass an object containing all the data about the change
Changing the indexer setter
Now it remains to subscribe to changes in any component, change the data in another, and check how it works.
Suppose SecondComponent changes state, such as setting «somedata», and the component FirstComponent monitors the state change, Notify
In SecondComponent call parameter change
Call information changes
and is now in the method FirstComponent add handler and output to the console information about the change in the general state of
processing events to change the general states
Now if you start the game, after the general state is changed in the SecondComponent , in the componentFirstComponent we will receive a notification and display the data in the console.
Now that this works, we can refactor a bit and make the code even more convenient. To do this, you need to transfer the subscription to common state change notifications to the SharedStateComponent base class and create an abstract method, implementing which each component will process state changes in it, or not, at the component’s discretion.
Transfer the subscription to the SharedStateComponent
Subscribe to notifications about changes in the general state in the base class
Add an abstract method and call it in the event handler
Add an abstract method to handle the event in the child classes
And now in each child componentFirstComponent and SecondComponent need to implement this method and handle the change in the overall state. But, as before, we just put it into the console.
Implementing an abstract method in the components FirstComponent and SecondComponent
And now when we start the game we will see 2 entries in the console, from both components.
In the previous implementation there was a bug in the SharedEvents class and in order to fix it, you need to change the Subscribe method to:
Reference to the project
Usually, in order to track the change in the data, in some component, a direct link is created, that is, we, either in the Update method, check whether the data has changed there. Frame by frame data
verification through the Update method
or we subscribe to a very specific event, which is triggered independently in the “monitored” component, and is eventually processed.
Subscribing to an event in a component and processing it
There are many drawbacks to this approach, which for the most part are described in the last article. The main common cause of these shortcomings is strong coherence and complex maintenance (the ability to maintain, develop the project, refactor).
Creating a solution "Status Notifications"
Now that you have a system that allows you to weaken the connection between components and the means to create mailings between components, you can get rid of manually checking the values in the general state, as follows:
General condition change notification scheme
In the implementation described in the previous article, the data changes in one place , in the indexer of the SharedState component and therefore it is very easy to control their change.
Indexer in general state
In the indexer setter, we assign state values.
Now, for the SharedState component, you need to add a dependency on SharedEvents , since I’ll use it to send notifications. Add attribute for SharedState
Adding a dependency to SharedState from SharedEvents
And creating a class that inherits from EventData to send data in the state change notification. It will contain the name of the parameter, the state and its new value.
Adding a class that contains information about changes in the general state.
Now add a link to SharedEvents , retrieving it from the game object in the SharedState component .
Getting SharedEvents in the SharedState component.
Now we will change the setter of the indexer to so that at each state change a notification with the name “sharedstatechanged” is created and we will pass an object containing all the data about the change
Changing the indexer setter
Now it remains to subscribe to changes in any component, change the data in another, and check how it works.
Suppose SecondComponent changes state, such as setting «somedata», and the component FirstComponent monitors the state change, Notify
In SecondComponent call parameter change
Call information changes
and is now in the method FirstComponent add handler and output to the console information about the change in the general state of
processing events to change the general states
Now if you start the game, after the general state is changed in the SecondComponent , in the componentFirstComponent we will receive a notification and display the data in the console.
Now that this works, we can refactor a bit and make the code even more convenient. To do this, you need to transfer the subscription to common state change notifications to the SharedStateComponent base class and create an abstract method, implementing which each component will process state changes in it, or not, at the component’s discretion.
Transfer the subscription to the SharedStateComponent
Subscribe to notifications about changes in the general state in the base class
Add an abstract method and call it in the event handler
Add an abstract method to handle the event in the child classes
And now in each child componentFirstComponent and SecondComponent need to implement this method and handle the change in the overall state. But, as before, we just put it into the console.
Implementing an abstract method in the components FirstComponent and SecondComponent
And now when we start the game we will see 2 entries in the console, from both components.
Important!
In the previous implementation there was a bug in the SharedEvents class and in order to fix it, you need to change the Subscribe method to:
Only registered users can participate in the survey. Sign in , please.