home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / samples / visbuild / calculat / cppwv13 / icalcpu.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-16  |  7.7 KB  |  296 lines

  1. /******************************************************************************
  2. * .FILE:        icalcpu.cpp                                                   *
  3. *                                                                             *
  4. * .DESCRIPTION: Implementation for the class, ICalcPU                         *
  5. *                                                                             *
  6. * .CLASSES:     ICalcPU                                                       *
  7. *                                                                             *
  8. * .COPYRIGHT:                                                                 *
  9. *    Licensed Material - Program-Property of IBM                              *
  10. *    (C) Copyright IBM Corp. 1992, 1996 - All Rights Reserved                 *
  11. *                                                                             *
  12. * .DISCLAIMER:                                                                *
  13. *   The following [enclosed] code is sample code created by IBM               *
  14. *   Corporation.  This sample code is not part of any standard IBM product    *
  15. *   and is provided to you solely for the purpose of assisting you in the     *
  16. *   development of your applications.  The code is provided 'AS IS',          *
  17. *   without warranty of any kind.  IBM shall not be liable for any damages    *
  18. *   arising out of your use of the sample code, even if they have been        *
  19. *   advised of the possibility of such damages.                               *
  20. *                                                                             *
  21. * .NOTE: WE RECOMMEND USING A FIXED SPACE FONT TO LOOK AT THE SOURCE          *
  22. *                                                                             *
  23. ******************************************************************************/
  24.  
  25. #include <stdio.h>                    //for sprintf
  26. #include "icalcpu.hpp"                //ICalcPU header
  27. #include "icalcop.hpp"                //ICalcOperator header
  28. #include "icalcfnc.hpp"               //ICalcFunction header
  29. #include <inotifev.hpp>
  30.  
  31. //
  32. // Events
  33. //
  34.  
  35. INotificationId ICalcPU :: bufferId = "ICalcPU::buffer";
  36. INotificationId ICalcPU :: evaluateId = "ICalcPU::evaluate";
  37.  
  38. /*******************************************************************
  39.  * Contructors/Destructors
  40.  *******************************************************************/
  41.  
  42. ICalcPU :: ICalcPU() :
  43.         dBuffer(""),
  44.         dCurrentReg(none),
  45.         dR2SetFromDisplay(false),
  46.         dExpectNewOperand(false),
  47.         dPendingOp(0)
  48. {
  49. }
  50.  
  51. ICalcPU :: ~ICalcPU()
  52. {
  53. }
  54.  
  55. /*******************************************************************
  56.  * Access Member Functions (Part Actions)
  57.  *******************************************************************/
  58.  
  59. //
  60. // The Buffer attribute represents calculator display
  61. //
  62.  
  63. IString ICalcPU :: buffer () const
  64. {
  65.   return dBuffer;
  66. }
  67.  
  68.  
  69. ICalcPU & ICalcPU :: setBuffer
  70.   (const char * iBuffer)
  71. {
  72.  
  73.   if (dBuffer != iBuffer)
  74.   {
  75.     dBuffer = iBuffer;                  //Set class.attribute
  76.     notifyObservers(INotificationEvent(bufferId,*this));
  77.   }
  78.  
  79.   return *this;
  80.  
  81. }
  82.  
  83.  
  84. /*******************************************************************
  85.  * Implementor Member Functions (Part Actions)
  86.  *******************************************************************/
  87.  
  88.  
  89. //
  90. // Process each digit input to the PU
  91. //
  92.  
  93. ICalcPU & ICalcPU :: processDigit (IString iCurrentDigit)
  94. {
  95.   IString tempString;
  96.  
  97.   //
  98.   // If expecting a new input number or if the display has been cleared,
  99.   // start a new number. Otherwise get the current buffer contents and
  100.   // add the new digit to what is already there.
  101.   //
  102.  
  103.   if (dExpectNewOperand || dBuffer == "")
  104.   {
  105.      tempString = "";
  106.      dExpectNewOperand = false;
  107.   }
  108.  
  109.   else tempString = dBuffer;
  110.  
  111.   tempString += iCurrentDigit;   // Add to the current buffer contents
  112.   setBuffer(tempString);         // Want event, bufferId(), to get
  113.                                  //   signalled, so call set to display.
  114.   return *this;
  115.  
  116. }
  117.  
  118.  
  119. //
  120. // Process each binary operator key input to the PU
  121. //
  122.  
  123. ICalcPU & ICalcPU :: processOperator (ICalcOperator *iCurrentOp)
  124. {
  125.  
  126.   //
  127.   // Set display contents into the current register.
  128.   // If the current register is register 2, evaluate the pending
  129.   // operation.
  130.   // Set the current operation as the pending operation and wait for
  131.   // a new operand to be entered.
  132.   //
  133.  
  134.   setCurrentRegFromDisplay ();
  135.  
  136.   if (dCurrentReg == R2) evaluateIt();
  137.  
  138.   dPendingOp = iCurrentOp;
  139.   dExpectNewOperand = true;
  140.   return *this;
  141.  
  142. }
  143.  
  144.  
  145. //
  146. // Process the results of any binary operation.
  147. //
  148.  
  149. ICalcPU & ICalcPU :: processOperatorResult (double iAccumulator)
  150. {
  151.  
  152.   //
  153.   // Get the result of come operation, set it into register 1,
  154.   // display the results,and wait for the next operand to be entered.
  155.   //
  156.  
  157.   dCurrentReg = R1;
  158.   dRegisters[dCurrentReg] = iAccumulator;
  159.   dExpectNewOperand = true;
  160.   setDisplayFromAccumulator(iAccumulator);
  161.   return *this;
  162.  
  163. }
  164.  
  165.  
  166. //
  167. // Process each function key input to the PU
  168. //
  169.  
  170. ICalcPU & ICalcPU :: processFunction (ICalcFunction *iCurrentFunc)
  171. {
  172.  
  173.   //
  174.   // Invoke the specified unary function
  175.   //
  176.  
  177.   iCurrentFunc->perform(*this);
  178.   return *this;
  179.  
  180. }
  181.  
  182.  
  183. //
  184. // Evaluate any pending binary operation
  185. //
  186.  
  187. double ICalcPU :: evaluateOperation ()
  188. {
  189.  
  190.   //
  191.   // Invoke the pending operation
  192.   //
  193.  
  194.   return dPendingOp->evaluate (dRegisters[R1], dRegisters[R2]);
  195.  
  196. }
  197.  
  198.  
  199. //
  200. // Clear the calculator PU
  201. //
  202.  
  203. ICalcPU & ICalcPU :: clearCalc ()
  204. {
  205.  
  206.   setBuffer("");
  207.   dCurrentReg = none;
  208.   dExpectNewOperand = false;
  209.   dR2SetFromDisplay = false;  //reinit R2 has been set flag
  210.   dRegisters[R1] = 0;
  211.   dRegisters[R2] = 0;
  212.  
  213.   return *this;
  214.  
  215. }
  216.  
  217.  
  218. /*******************************************************************
  219.  * Implementor Member Functions (not Part Actions)
  220.  *******************************************************************/
  221.  
  222. ICalcPU & ICalcPU :: evaluateOperator ()
  223. {
  224.  
  225.    setCurrentRegFromDisplay ();
  226.  
  227.    if (dR2SetFromDisplay) evaluateIt();
  228.  
  229.    dExpectNewOperand = true;
  230.    return *this;
  231.  
  232. }
  233.  
  234.  
  235. /*******************************************************************
  236.  * Helping Member Functions (Not Part Actions)
  237.  *******************************************************************/
  238.  
  239. ICalcPU & ICalcPU :: evaluateIt ()
  240. {
  241.    notifyObservers(INotificationEvent(evaluateId,*this));
  242.    return *this;
  243. }
  244.  
  245.  
  246. ICalcPU & ICalcPU ::
  247.   setDisplayFromAccumulator (double iAccumulator)
  248. {
  249.   char tempString[20];
  250.   signed long tempAccum = iAccumulator;
  251.  
  252.   //
  253.   // Convert the accumulator value to a string and display it
  254.   //
  255.  
  256.   if (iAccumulator != tempAccum)
  257.      sprintf(tempString, "%f", iAccumulator);
  258.  
  259.   else
  260.      sprintf(tempString, "%d", tempAccum);
  261.  
  262.   setBuffer ( tempString );             //want the event, bufferId(),
  263.                                         //to be signalled, so call set
  264.   return *this;
  265.  
  266. }
  267.  
  268.  
  269. ICalcPU & ICalcPU ::
  270.   setCurrentRegFromDisplay ()           
  271. {
  272.  
  273.   /*****************************************************************
  274.    * As a precaution, only set the current register if dBuffer,
  275.    * which represents the calculator display, is not a nullstring.
  276.    * NOTE:  dBuffer should never be a nullstring as long as the
  277.    *        entry field that maps to it (i.e., that represents
  278.    *        the calculator display) is always a display-only field.
  279.    *****************************************************************/
  280.  
  281.   if (dBuffer.size() && !dExpectNewOperand)
  282.   {
  283.      dRegisters[++dCurrentReg] = dBuffer.asDouble();
  284.  
  285.      if ((dCurrentReg == R2) && (!dR2SetFromDisplay)) 
  286.      {
  287.         dR2SetFromDisplay = true;
  288.      }
  289.  
  290.   }
  291.  
  292.   return *this;
  293.  
  294. }
  295.  
  296.