justincinmd / ruby-ev3

Ruby Gem for Lego EV3
MIT License
8 stars 6 forks source link

Rethinking Commands #4

Open rscottm opened 10 years ago

rscottm commented 10 years ago

I'm working on expanding on the initial input (button pressed) to cover more inputs (e.g., ports). In doing this, I rethinking the 1 command per class route for a few reasons: 1) there is a lot of overhead (in lines of code needed to maintain the module/class structure and to override methods); 2) we're going to need a large number of commands to cover all of the functionality; and 3) batching of commands will be common (e.g., read all of the button states at once) requiring more classes to cover those options.

I'm thinking that we could get away with:

1) One class to handle each call (e.g., Command or Message). It would get set up to be either System or Direct, with or without a reply. It would be responsible for constructing the header and possibly handling the response. It would manage one or more sub commands (getting the bytes to send and assigning the appropriate parts of any response).

2) A subcommand class or hierarchy of classes. Each sub command needs:

I don't think we'll need one class per subcommand. It seems like it might be enough to pair up physical object with a class used for getting and setting its information (motor, port, button, ui), and perhaps some extra classes for more batch commands (reading all the ports at once, or starting two motors at the same time).

I think the subcommand should be responsible for querying the necessary information from the object (e.g., port id, layer, mode) and then assigning information returned (raw_value = X).

3) The "Model" object in this case would be responsible for creating the command, holding values, and firing of any procedures based on changes detected.

Thoughts?

rscottm commented 10 years ago

I pushed some code to do this to a separate branch (rethink_commands) in my fork (rscottm/ruby-ev3). It's not perfect or polished, but it works and is much easier to expand.

Command: Manages a single message to, and reply from, the EV3. It manages the messiness of complex commands. It can figure out if it is a reply or not based on the components added.

CommandComponent: One piece of a message. Add parameters (with type) and replies (with type). Many Commands will be one Component, but there are definitely some that will need multiple (e.g., polling the state of all of the ports).

Action Module: One module for each EV3 physical entity (brick, motor, button, etc.). Builds CommandComponents to send or receive information. This could have been individual classes, but seemed to make sense for it to just encapsulate the building of CommandComponents while still being closely tied to the entity it represents.

I should note that, as I look at this code, it would be easy to completely separate out most of the EV3 specific code. In that case, it would be feasible to create a library that could work for both EV3 and NXT. I'm not sure if that would be useful or not.

https://github.com/rscottm/ruby-ev3 https://github.com/rscottm/ruby-ev3/tree/rethink_commands