Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on May 4, 2019. It is now read-only.

Refactoring: Prefer script-driven approach over function-driven approach #12

Merged
merged 8 commits into from
Oct 28, 2017

Conversation

MrPointer
Copy link
Member

As discussed earlier in #10 the project's dev team has come to a conclusion that the project should be refactored.

Initialization Refactoring

I started the process by extracting the very first steps taken in the build configuration, which is the initialization of the Arduino platform. However, during my work I noticed that there are two possible approaches here, both having their own pros and cons. Let's take a look:

Function-driven approach

Similar to Functional programming where different behavior is implemented by a number of if-else blocks in a dedicated function.
For example: A calculate_area function to calculate the area of various data structures. Each data structure is a shape, defining only basic information about the shape, without implementing any behavior.
In our scenario, it can be achieved by defining functions to handle various tasks, split to files by their responsibility. For example: Setup of required C Flags can be done by calling the function setup_c_flags, passing it some parameters for extensibility.

Script-driven approach

Similar to Object-oriented_programming where different behavior is implemented through Polymorphism.
For example: A base, abstract class named Shape declares a method named calculate_area. For the code to implement different behavior for different shape types, we should derive from the Shape class and override its calculate_area method. It allows us to add new data types quicker, mostly suitable for a growing system.
In our scenario, it can be achieved by extracting behavior into script, where each script is part of a bigger script, including one into another as necessary. It allows developers to add new behavior as required simply by creating a new script file, referencing the existing code to use it instead of the current one.
For example: Setup of required C Flags will be a script, included where needed in the calling script (Probably the one which setups the system). To change those flags drastically, a new script file can be created and included instead, keeping the old one for compatibility or usual cases.

Summary

Honestly, I prefer the script-driven approach, at least at the stage of system initialization.
I've also accomplished more work on this branch, almost completing the refactoring process of this part.

Instead of calling functions located in dedicated files, those files became script parts themselves, allowing to simply include them in the script using CMake's 'include' command.
Also extracted the 'register_hardware_platform' function to a script named 'RegisterHardwarePlatform.cmake', which sets the platform path explicitly, causing less modular code yet simpler in that there's no other use of this function through the entire project.
Further extracted the script to separate files, leading to a super-small initialization script - just as a clean, modular system should be.
It made the '${CMAKE_CURRENT_LIST_DIR}' prefix unnecessary in various 'include' commands. Note that their '.cmake' suffixes has also been removed.
Until now the function wrote an entire CMake script as a hardcoded string to a cached file, in order to calculate a target's firmware size.
This commit changes it by extracting the hardcoded string into a valid, readable and easily editable CMake script, named 'CalculateFirmwareSize.cmake', located under the 'Extras' directory.
Added another initializing script to completely replace the need for the function, including a script part instead, named 'SetupFirmwareSizeScript.cmake'.
…functions.

It sticks with the script-driven approach, providing consistency.
Moved the 'find_file' command used to find SDK's version file to the 'DetectVersion' script. This results in an 'Initializer' script that only includes other script parts.
This is the last part that still was in the 'Arduino' script, now extracted to a script named 'LoadArduinoPlatformSettings' under the 'Initialization' directory.
@MrPointer MrPointer changed the title Prefer script-driven approach over function-driven Refactoring: Prefer script-driven approach over function-driven approach Oct 13, 2017
The script is named 'SetupExampleCategories', located under the 'Initialization' directory.
Also renamed the cached variable 'ARDUINO_EXAMPLES_CATEGORIES' to 'ARDUINO_EXAMPLE_CATEGORIES'.
@MrPointer
Copy link
Member Author

@JonasProgrammer Can you please review this?

@JonasProgrammer
Copy link

Sorry for letting you down; I expected to have more freetime in the last weeks, but things turned out a little differently. That being said, now that a long weekend approaches, I should finally find some time.

Sorrybeing aside, I'm astonished by the progress made here. Looking at it now, it feels like you can tweak things without fearing the whole Arduino.cmake building collapsing on you.
That being said, I generally like the script-driven approach. Functional programming has it's purpose, but given the mess that arduino is at some points (upload reset, anyone?), I feel like that approach would yield even less readable if-cascades on the long run.

@MrPointer MrPointer merged commit 2ef930e into feature/refactoring Oct 28, 2017
This was referenced Oct 31, 2017
@MrPointer MrPointer deleted the feature/refactoring-script-driven branch December 1, 2017 12:28
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants