MCA2 Calculator Tutorial Chapter 4

From Mca2
Revision as of 12:32, 26 November 2010 by Badruduja (Talk | contribs)

Jump to: navigation, search

Now that a pocket calculator with only one calculation type is very poor we implement some more functionality. Create three further modules. One for subtraction, one for multiplication and one for division. Concretely:

     new_module.py -C projects/calculator/ "Subtract"
     new_module.py -C projects/calculator/ "Multiply"
     new_module.py -C projects/calculator/ "Divide"

Enter the header files of each module and create two ControllerInputs eCI_VALUE1 and eCI_VALUE2 and one SensorOutput eSO_RESULT. Remember to add a member variable of type double named m result. Go to the Control() functions in each .cpp file of the new modules. Read the values from the ControllerInputs and store them in m_result. Add code to the Sensor-functions to write m result to the SensorOutput as we did within mAdd.cpp. When finished, add the new modules to the SConscript.

     pcalc.AddSourceFiles( ”””
     pPocketCalc.cpp
     gPocketCalc.cpp
     mAdd.cpp
     mSubtract.cpp
     mMultiply.cpp
     mDivide.cpp
     ””” )

Afterwards open the gPocketCalc.cpp. Include the header-files of the new modules:

     #include "calculator / mSubtract.h "
     #include " calculator / mMultiply.h "
     #include " calculator / mDivide.h "

Create one object per module and save the memory adresses in pointers:

     mSubtract ∗ subtraction = new mSubtract ( this ) ;
     mMultiply ∗ multiplication = new mMultiply ( this ) ;
     mDivide ∗ division = new mDivide ( this ) ;

Add the down edges from the ControllerInputs of the group to the ControllerInputs of the modules.

     AddEdgeDown ( this , subtraction , 2 ,
                   eCI_VALUE1 , mSubtract::eCI VALUE1 ,
                   eCI_VALUE2 , mSubtract::eCI VALUE2 ) ;

     AddEdgeDown ( this , multiplication , 2 ,
                   eCI VALUE1 , mMultiply : : eCI VALUE1 ,
                   eCI VALUE2 , mMultiply : : eCI VALUE2 ) ;
     
     AddEdgeDown ( this , division , 2 ,
                   eCI_VALUE1 , mDivide : : eCI_VALUE1 ,
                   eCI_VALUE2 , mDivide : : eCI_VALUE2 ) ;

Although it is possible to connect the same ControllerInputs of the group to the ControllerInputs of several modules, this must not be done with the SensorOutputs of the modules and the SensorOut- put of the group. The reason is crucial: All modules would overwrite each other’s SensorOutput and which of the results the group would be able to read is not deterministic. So always when you are going to connect outputs of modules or groups with inputs of other modules or groups, you should think about if it is possible or if it would cause the outputs to overwrite others. The solution for this problem is to use a multiplexer. A multiplexer is a prebuilt module that comes with mca2 and can be found in the library mcal general. The multiplexer module is ca- pable of multiplexing in several ways. What we need here is a multiplexer from SensorInput to SensorOutput.

We now define some enums in gPocketCalc.h to name the inputs and outputs of the multiplexer. Add to the public-declaration area:

     enum {
            eMP_SI_ADD ,
            eMP_SI_SUBTRACT ,
            eMP_SI_MULTIPLY ,
            eMP_SI_DIVIDE ,
            eMP_SI_DIMENSION /∗!< Endmarker and Dimension ∗/
           };
     DESCR( static , gPocketCalc , mmpsodescription , 7 , Natural , cDATA_VECTOR_END_MARKER );
     enum {
            eMP SO RESULT ,
            eMP SO DIMENSION /∗!< Endmarker and Dimension ∗/
          };

The DESCRiption is for naming purposes in a similar way the ControllerInput enums are named. You can ignore it for the moment and focus on the multiplexer, which we create by including the header file in the group

     #include "general/mMultiplexer.h"

and calling the constructor of mMultiplexer. Here it is we can specify the functionality of the multiplexer.

     mMultiplexer ∗mux = new mMultiplexer ( this , mMultiplexer :: eMM SI2SO ,
                  mMultiplexer :: eCM_CI , eMP_SO_DIMENSION , eMP_SI_DIMENSION ,
                  m_mp_so_description , " Calculation Type MUX " , true ) ;


The parameters of the constructor are: • the parent-pointer • the multiplexing mode – here we define it by using an enum out of the namespace mMultiplthat matches our purposes of multiplexing from SensorInput to SensorOutput • the place (ControllerInput or SensorInput) where we want wo have a selector to tellmultiplexer which of the SensorInputs should be passed • the dimension we want to multiplex – here eMP SO DIMENSION = 1 because we only multipthe eSO RESULT-SensorOutputs of the four modules • the number of between how many modules we want to multiplex – here eMP SI DIMENS= 4 because of 4 modules • the description to name the SensorIn- and Outputs of the Multiplexer with “Result” • the name of the multiplexer to be shown in mcabrowser • and fixit – which is for fixing edges and you can ignore it’s meaning for the moment.

Personal tools