making-readme-more-tutorial-like #6
20
README.md
20
README.md
@@ -20,6 +20,7 @@ The power button does what it says either turns the phone off or on, the lock bu
|
||||
|
||||
And you want the inter-action between these states to work as follows:
|
||||
|
||||
#### state diagram
|
||||
```
|
||||
pwr : power button pressed
|
||||
lck : lock button pressed
|
||||
@@ -91,6 +92,7 @@ Therefor due to this mess of unmaintainable and heavily coupled code, you decide
|
||||
|
||||
So to start implement this pattern we first draw up a uml diagram of how it should go together. We can see we have the device itself and which is composed of a device state, and the entered string. This "class" also has 3 methods pressPwrButton, pressStrInputButton, and pressLockButton. These methods are used to create an abstraction from the device state so the underlying state can change while using the same input functions. This means that the state field will change its self when one of the transition functions is called. These transition functions are the ones defined within the interface and the ones defined within the `Device_t` struct with the ones in the `Device_t` struct just calling the functions that are implemented by the `DeviceState_t`. To give and example when the devices `pressPwrButton` method is called this calls the `DeviceState_t` `pressPwrMethod`.
|
||||
|
||||
#### uml diagram
|
||||
```
|
||||
---------------------------------- UML Diagram ----------------------------------
|
||||
|
||||
@@ -131,7 +133,7 @@ So to start implement this pattern we first draw up a uml diagram of how it shou
|
||||
} Device_t;
|
||||
```
|
||||
|
||||
2. Next we will implement the [methods](/src/device.h#L34) which in this case will be an [interface](https://en.wikipedia.org/wiki/Interface_(object-oriented_programming)). These methods are all the changes that can be made to the device i.e. Your [inputs](#inputs).
|
||||
2. Next we will implement the [device interface](/src/device.h#L34) which as the name implies is an [interface](https://en.wikipedia.org/wiki/Interface_(object-oriented_programming)) bascially a struct that holds methods that creates a common set of functions that both structs need to implement. This means the [device interface](/src/device.h#L34) will defined 3 methods all relating to these transition functions which are all the changes that can be made to the device i.e. Your [inputs](#inputs).
|
||||
|
||||
```c
|
||||
// device.h
|
||||
@@ -143,7 +145,7 @@ So to start implement this pattern we first draw up a uml diagram of how it shou
|
||||
```
|
||||
|
||||
|
||||
3. And finally we will implement the [struct to hold the actual state](/src/device.h#L52) of the device. (note there is some funkiness in c with implementing this since you will need forward decls)
|
||||
3. And finally we will implement the [struct to hold the actual state](/src/device.h#L52) of the device. (note there is some funkiness in c with implementing this since you will need forward declaration)
|
||||
```c
|
||||
// device.h
|
||||
typedef struct DeviceState_s{
|
||||
@@ -151,7 +153,7 @@ So to start implement this pattern we first draw up a uml diagram of how it shou
|
||||
DeviceInterface_t methods;
|
||||
}DeviceState_t;
|
||||
```
|
||||
4. Now we need to implement the 3 functions for device inputs, ive implemented one here as the rest are very [similar](/src/device.c#L14). So this function takes the given device and then uses the methods defined within the device state to change the current state of the device.
|
||||
4. Now we need to implement the 3 transition functions for device inputs, ive implemented one here as the rest are very [similar](/src/device.c#L14). So this function takes the given device and then uses the methods defined within the device state to change the current state of the device as defined within the [uml diagram](#uml-diagram).
|
||||
```c
|
||||
// device.c
|
||||
void pressPwrButton(Device_t *device) {
|
||||
@@ -166,7 +168,7 @@ So to start implement this pattern we first draw up a uml diagram of how it shou
|
||||
void setDeviceStateToLock(Device_t *device);
|
||||
void setDeviceStateToOff(Device_t *device);
|
||||
```
|
||||
6. Now we can implement one of these states as the rest of them should be fairly self explanatory. The state we will be implementing is the [lock state](/src/states/lock_state.c) as this should show off most of the different transitions. We will first start out with implementing the set state function. This function takes the given device and sets that devices state to this new state.
|
||||
6. Now we can implement one of these states as the rest of them should be fairly self explanatory. The state we will be implementing is the [lock state](/src/states/lock_state.c) as defined within the [state diagram](#state-diagram) since this should show off most of the different transitions. We will first start out with implementing the [set state function](/src/states/lock_state.c#L36). This function takes the given device and sets that devices state to this new state.
|
||||
```c
|
||||
// lock_state.h
|
||||
void setDeviceStateToLock(Device_t *device) {
|
||||
@@ -180,7 +182,7 @@ So to start implement this pattern we first draw up a uml diagram of how it shou
|
||||
};
|
||||
}
|
||||
```
|
||||
7. Now that we have the function for setting this state we can now implement the functions for what this functions does depending on the inputs we will first start with the power button function. This is one of the simplest when the power button is press i.e. When the function is called we set the devices state to off.
|
||||
7. Now that we have the function for setting this state we can now implement the functions defined within the [device interface](/src/device.h#L34). To start we will implement the simplest transition function, the [function](/src/states/lock_state.c#L10) called when the power button is press i.e. When the function is called we set the devices state to off.
|
||||
```c
|
||||
// lock_state.c
|
||||
static void pressPwrMethod(Device_t *device) {
|
||||
@@ -189,7 +191,7 @@ So to start implement this pattern we first draw up a uml diagram of how it shou
|
||||
}
|
||||
|
||||
```
|
||||
8. Now we will implement the next function the lock button which in the lock state will do nothing.
|
||||
8. Now we will implement the next transition function, this time the [function](/src/states/lock_state.c#L31) is called when the lock button is pressed, which in the lock state will do nothing.
|
||||
```c
|
||||
// lock_state.c
|
||||
static void pressLockMethod(Device_t *device) {
|
||||
@@ -198,7 +200,7 @@ So to start implement this pattern we first draw up a uml diagram of how it shou
|
||||
}
|
||||
```
|
||||
|
||||
9. Finally we create the function for handling the text input, this function will check the entered string to see if its either "dbg", or "pwd" and if it is enter debug or unlock respectively.
|
||||
9. Finally we create the transition function for handling the text input, this [function](/src/states/lock_state.c#L15) will check the entered string to see if its either "dbg", or "pwd" and if it is enter debug or unlock respectively.
|
||||
```c
|
||||
static void pressStrInputMethod(Device_t *device) {
|
||||
if (strcmp(device->entered_string, "dbg") == 0) {
|
||||
@@ -215,14 +217,14 @@ So to start implement this pattern we first draw up a uml diagram of how it shou
|
||||
}
|
||||
```
|
||||
10. Now we just need to implement the other [states](#states) in the same way we implemented this first one.
|
||||
11. Finally we need to test our device. Firstly within main we create a new device and set its initial state to off.
|
||||
11. Finally we need to test our device. Firstly within [main](/src/main.c) we create a new device and set its initial state to off.
|
||||
```c
|
||||
// arrange:
|
||||
Device_t device;
|
||||
initDevice(&device);
|
||||
setDeviceStateToOff(&device);
|
||||
```
|
||||
12. Now we can test that the device correctly travels through each state, by pressing one of the buttons ([invoking the input method functions](/src/device.h#L34)) then checking that the `state_name` is equal to the set state name.
|
||||
12. Now we can test that the device correctly travels through each [state](#state-diagram), by pressing one of the buttons ([invoking the input method functions](/src/device.h#L34)) then checking that the `state_name` is equal to the set state name.
|
||||
```c
|
||||
// act :
|
||||
// turn on the device
|
||||
|
||||
Reference in New Issue
Block a user