Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

MathCore.cpp

Go to the documentation of this file.
00001 
00002 // MathCore = a WYSIWYG equation editor + a powerful math engine     //
00003 // Copyright (C) 2003 by Francesco Montorsi                          //
00004 //                                                                   //
00005 // This library is free software; you can redistribute it and/or     //
00006 // modify it under the terms of the GNU Lesser General Public        //
00007 // License as published by the Free Software Foundation; either      //
00008 // version 2.1 of the License, or (at your option) any later         //
00009 // version.                                                          //
00010 //                                                                   //
00011 // This library is distributed in the hope that it will be useful,   //
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of    //
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the      //
00014 // GNU Lesser General Public License for more details.               //
00015 //                                                                   //
00016 // You should have received a copy of the GNU Lesser General Public  //
00017 // License along with this program; if not, write to the Free        //
00018 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,   //
00019 // MA 02111-1307, USA.                                               //
00020 //                                                                   //
00021 // For any comment, suggestion or feature request, please contact    //
00022 // the administrator of the project at frm@users.sourceforge.net     //
00023 //                                                                   //
00030 
00031 
00032 // optimization for GCC compiler
00033 #ifdef __GNUG__
00034 #pragma implementation "MathCore.h"
00035 #endif
00036 
00037 // includes
00038 #include "mc/mcprec.h"
00039 #ifdef __BORLANDC__
00040     #pragma hdrstop
00041 #endif
00042 
00043 #ifndef mcPRECOMP
00044  #include "mc/MathCore.h"
00045  #include "mc/EmptyBox.h"
00046  #include "mc/Number.h"
00047  #include "mc/Bracket.h"
00048  #include "mc/Fraction.h"
00049  #include "mc/Function.h"
00050  #include "mc/Radical.h"
00051  #include "mc/Text.h"
00052  #include "mc/Symbol.h"
00053  #include "mc/Operator.h"
00054  #include "mc/AddSubOp.h" 
00055  #include "mc/MultDivOp.h" 
00056  #include "mc/Monomial.h"
00057  #include "mc/MathMng.h"
00058  #include "mc/Parenthesis.h"
00059  
00060  #include "mc/PolySolver.h"  // solvers
00061  #include "mc/BisectSolver.h"
00062  #include "mc/GenericSolver.h"
00063 #endif
00064 
00065 
00066 // Definition of the STATIC variables of mcMathCore
00067 mcMathCore *mcMathCore::g_pTheInstance = NULL;
00068 void (*mcMathCore::OnError)(const wxString &) = NULL;
00069 mcSolverArray mcMathCore::arrSolvers;
00070 
00071 #ifdef mcDETECT_MEMORY_LEAKS
00072  HFILE mcMathCore::m_hLogFile = NULL;
00073  FILE *mcMathCore::m_fLogAllocFile = NULL;
00074  char mcMathCore::m_szMsg[];
00075 #endif
00076 
00077 
00078 
00079 
00080 // ---------------------
00081 // mcMATHCORE
00082 // ---------------------
00083 
00084 mcMathCore::mcMathCore()
00085 {
00086  m_bIOEnabled = m_bGUIEnabled = m_bMathEnabled = FALSE;
00087 
00088  // the number of spaces used to indent debug output
00089  m_nIndentationStep = 4;
00090  m_nMaxSharing = -1;
00091 }
00092 
00093 mcMathCore::~mcMathCore()
00094 {
00095  // shutdown subsystems: order is important !!!
00096  if (isGUIEnabled()) CleanupGUI();
00097  if (isIOEnabled()) CleanupIO();
00098  if (isMathEnabled()) CleanupMath();
00099 
00100  wxLog *logtarget = wxLog::SetActiveTarget(NULL);
00101  mcSAFE_DELETE(logtarget);
00102 }
00103 
00104 // this one is static
00105 mcMathCore *mcMathCore::Get()
00106 {
00107  mcASSERT(g_pTheInstance != NULL,
00108   wxT("Before using mcMathCore::Get() you must call mcMathCore::Setup()"));
00109  return g_pTheInstance;
00110 }
00111 
00112 // this one is static
00113 void mcMathCore::Set(mcMathCore *p)
00114 {
00115  if (g_pTheInstance != NULL)
00116   delete g_pTheInstance;
00117  g_pTheInstance = p;
00118 }
00119 
00120 void mcMathCore::Setup(bool bIO, bool bMath, bool bGUI)
00121 {
00122  // create the global instance of the class
00123  mcMathCore::g_pTheInstance = new mcMathCore();
00124 
00125  // and then, init it
00126  // (this step cannot be done in the constructor of mcMathCore
00127  // because it generates calls to mcMathCore::Get() which needs
00128  // a working mcMathCore::g_pTheInstance pointer...)
00129  mcMathCore::g_pTheInstance->Init(bIO, bMath, bGUI);
00130 }
00131 
00132 void mcMathCore::Init(bool bIO, bool bMath, bool bGUI)
00133 {
00134 #ifdef mcENABLE_LOG
00135  wxLog::SetActiveTarget(new mcLog());
00136 #endif
00137 
00138  // the order is important !!!
00139  if (bMath) SetupMath();
00140  if (bIO) SetupIO();
00141  if (bGUI) SetupGUI(NULL);
00142 
00143  mcElementHelpers::Init();
00144 }
00145 
00146 void mcMathCore::Cleanup()
00147 {
00148  // delete the global istance of this class
00149  mcSAFE_DELETE(mcMathCore::g_pTheInstance);
00150 
00151 #if 0 //def mcENABLE_LOG
00152  wxLog *p = wxLog::GetActiveTarget();
00153  wxLog::SetActiveTarget(NULL);
00154  mcSAFE_DELETE(p); 
00155 #endif
00156 }
00157 
00158 void mcMathCore::SetupIO()
00159 {
00160  m_bIOEnabled = TRUE;
00161 
00162  wxXml2::Init();
00163  //data_UpdateElemArray();
00164 }
00165 
00166 void mcMathCore::CleanupIO()
00167 {
00168  wxXml2::Cleanup();
00169 
00170  m_bIOEnabled = FALSE;
00171  //data_UpdateElemArray();
00172 }
00173 
00174 void mcMathCore::SetupMath()
00175 {
00176  m_bMathEnabled = TRUE;
00177 
00178  // first of all init mcRealValue class
00179  mcRealValue::Init();
00180 
00181  // init mcSymbol arrays
00182  mcSymbol::InitSymbols();
00183 
00184  // set the default step threshold
00185  mcMathCore::m_fStepThreshold = mcDEFAULT_STEP_THRESHOLD;
00186 
00187  // load parameters, constants, unknowns and functions
00188  //
00189  // FIXME: do we have to load any standard function/symbol, or
00190  //        we leave this task to the user ?
00191  //mcSymbol::LoadSymbols();
00192  //mcFunction::LoadFunctions();
00193  //mcSymbol::CheckSymbols();
00194 
00195  // init the interpreter
00196 #ifdef mcUSE_WXSCRIPT
00197  wxScriptInterpreter::Init();
00198 #endif
00199 
00200  // create some useful objects
00201  mcNumberHelpers::smath_pFour = new mcNumber(4.0);
00202  mcNumberHelpers::smath_pTwo = new mcNumber(2.0);
00203  mcNumberHelpers::smath_pOne = new mcNumber(1.0); 
00204  mcNumberHelpers::smath_pMinusOne = new mcNumber(-1.0);
00205  mcNumberHelpers::smath_pZero = new mcNumber(0.0);
00206 
00207  mcMonomialHelpers::smath_pZero = new mcMonomial;
00208  mcMonomialHelpers::smath_pZero->math_WrapNumber(0.0);
00209  mcMonomialHelpers::smath_pOne = new mcMonomial;
00210  mcMonomialHelpers::smath_pOne->math_WrapSimple(*mcNumberHelpers::smath_pOne);
00211 
00212  mcPolynomialHelpers::smath_pEmpty = new mcPolynomial;
00213  mcPolynomialHelpers::smath_pOne = new mcPolynomial;
00214  mcPolynomialHelpers::smath_pOne->math_WrapSimple(*mcNumberHelpers::smath_pOne);
00215  
00216  
00217  // check them
00218  mcMonomialHelpers::smath_pZero->data_Check();
00219  mcMonomialHelpers::smath_pOne->data_Check();
00220  mcPolynomialHelpers::smath_pEmpty->data_Check();
00221  mcPolynomialHelpers::smath_pOne->data_Check();
00222 /* mcRange::pR = new mcRange(*mcRealValue::pNegInf, *mcRealValue::pPosInf, mcSET_N);
00223  mcExtRange::pR = new mcExtRange(*mcRange::pR);
00224 */
00225  mcTextHelpers::smath_pEmpty = new mcText();
00226 
00227  // init random generator with the number of
00228  // of seconds since GMT 00:00:00 Jan 1st 1970
00229  srand(wxGetUTCTime());
00230 
00231  // no functions using the mcMathCore::pElem array should be
00232  // called in the SetupXXX() functions 
00233 }
00234 
00235 void mcMathCore::CleanupMath()
00236 {
00237  m_bMathEnabled = FALSE;
00238  
00239  // close the interpreter
00240 #ifdef mcUSE_WXSCRIPT
00241  wxScriptInterpreter::Cleanup();
00242 #endif
00243 
00244  // delete the STATIC objects
00245  mcSAFE_DELETE(mcNumberHelpers::smath_pOne);
00246  mcSAFE_DELETE(mcNumberHelpers::smath_pTwo);
00247  mcSAFE_DELETE(mcNumberHelpers::smath_pFour);
00248  mcSAFE_DELETE(mcNumberHelpers::smath_pMinusOne);
00249  mcSAFE_DELETE(mcNumberHelpers::smath_pZero);
00250  mcSAFE_DELETE(mcPolynomialHelpers::smath_pOne);
00251  mcSAFE_DELETE(mcPolynomialHelpers::smath_pEmpty);
00252  mcSAFE_DELETE(mcMonomialHelpers::smath_pOne);
00253  mcSAFE_DELETE(mcMonomialHelpers::smath_pZero);
00254 
00255  mcSAFE_DELETE(mcRange::pR);
00256  mcSAFE_DELETE(mcExtRange::pR);
00257  mcSAFE_DELETE(mcTextHelpers::smath_pEmpty);
00258 
00259  // clear math arrays
00260  arrSolvers.data_Clear();
00261  mcSymbol::CleanupSymbols();
00262 
00263  // de-init mcRealValue classes
00264  mcRealValue::Cleanup();
00265  mcElementHelpers::Cleanup();
00266 
00267  // delete pElem array
00268  //data_UpdateElemArray();
00269 }
00270 
00271 void mcMathCore::SetupGUI(void (*OnErrorFnc)(const wxString &))
00272 {
00273  m_bGUIEnabled = TRUE;
00274 
00275  // be sure that also wxWidgets' GUI is correctly init...
00276  // if the wxXXXXX colors are okay, then the GUI should have been set up
00277  mcASSERT(wxWHITE != NULL, wxT("wxWidgets' GUI seems to be offline..."));
00278 
00279  //strMathMLOp[0] = { wxT("plus"), wxT("minus"), wxT("times"), "divide" };
00280 
00281  // setup STATIC variables
00282  mcElementHelpers::sgui_pSelectionBrush = new wxBrush(wxColour(0x40ffff), wxSOLID);
00283  mcElementHelpers::sgui_pActivationBrush = new wxBrush(wxColour(0xfadcb4), wxSOLID);
00284  mcElementArrayHelpers::sgui_pSelectionPen = new wxPen(wxColour(0, 0, 0), 1, wxDOT);
00285  mcEmptyBoxHelpers::sgui_pEmptyBoxBrush = new wxBrush(wxColour(0xfad2be), wxSOLID);
00286  mcEmptyBoxHelpers::sgui_pNewEmptyBox = new mcKey(wxT("x+127"));
00287  mcFractionHelpers::sgui_pNewFraction = new mcKey(wxString::Format(wxT("cx+%d"), wxT('f')));
00288  mcFunctionHelpers::sgui_pNewFunction = new mcKey(wxString::Format(wxT("csx+%d"), wxT('f')));
00289  mcRadicalHelpers::sgui_pNewRadical = new mcKey(wxString::Format(wxT("cx+%d"), wxT('r')));
00290 
00291  // create some standard keys required by mcElementHelpers::sgui_Input()
00292  // functions;
00293  m_pDeleteKey = new mcKey(wxString::Format(wxT("+%d"), WXK_BACK));
00294  m_pCancelKey = new mcKey(wxString::Format(wxT("+%d"), WXK_DELETE));
00295  m_pNewLineKey = new mcKey(wxString::Format(wxT("+%d"), WXK_RETURN));
00296 
00297  // those are special keys...
00298  m_pEditExpKey = new mcKey(wxString::Format(wxT("x+%d"), WXK_RETURN));
00299  m_pEditSubscriptKey = new mcKey(wxString::Format(wxT("cx+%d"), WXK_RETURN));
00300 
00301  // set the error handler function pointer
00302  OnError = OnErrorFnc;
00303 
00304  // initialize the styles of mcElementGUI
00305  mcElementHelpers::gui_InitDefaultStyles();
00306  mcMathMngHelpers::gui_InitStyles();
00307 
00308  //data_UpdateElemArray();
00309 }
00310 
00311 void mcMathCore::CleanupGUI()
00312 {
00313  m_bGUIEnabled = FALSE;
00314 
00315  // delete mcMathCore variables
00316  mcSAFE_DELETE(m_pDeleteKey);
00317  mcSAFE_DELETE(m_pCancelKey);
00318  mcSAFE_DELETE(m_pNewLineKey);
00319 
00320  mcSAFE_DELETE(m_pEditExpKey);
00321  mcSAFE_DELETE(m_pEditSubscriptKey);
00322 
00323 
00324  // delete the STATIC pointers allocated by the various classes
00325  // we must be sure all customizable pointers have been deleted: they can be deleted
00326  // only here because when a mcFraction, mcRadical, mcEmptyBox, ..., is deleted,
00327  // it cannot know if the customizable resource will be required by another
00328  // element....
00329  mcSAFE_DELETE(mcElementHelpers::sgui_pSelectionBrush);
00330  mcSAFE_DELETE(mcElementHelpers::sgui_pActivationBrush);
00331  mcSAFE_DELETE(mcElementArrayHelpers::sgui_pSelectionPen);
00332  mcSAFE_DELETE(mcEmptyBoxHelpers::sgui_pEmptyBoxBrush);
00333  mcSAFE_DELETE(mcEmptyBoxHelpers::sgui_pNewEmptyBox);
00334  mcSAFE_DELETE(mcFractionHelpers::sgui_pNewFraction);
00335  mcSAFE_DELETE(mcFunctionHelpers::sgui_pNewFunction);
00336  mcSAFE_DELETE(mcRadicalHelpers::sgui_pNewRadical);
00337 
00338 
00339  // delete the style array and mark it as empty
00340  mcElementHelpers::gui_DeleteDefaultStyles();
00341  mcMathMngHelpers::gui_DeleteStyles();
00342 
00343  //data_UpdateElemArray();
00344 }
00345 
00346 
00347 
00348 
00349 
00350 // --------------------------------
00351 // mcMATHCORE - miscellaneous
00352 // --------------------------------
00353 
00354 bool mcMathCore::isGUIEnabled() const
00355 { return m_bGUIEnabled; }
00356 
00357 bool mcMathCore::isMathEnabled() const
00358 { return m_bMathEnabled; }
00359 
00360 bool mcMathCore::isIOEnabled() const
00361 { return m_bIOEnabled; }
00362 
00363 bool mcMathCore::MatchEditKeys(const mcKey &key)
00364 {
00365  return m_pDeleteKey->MatchKey(key) ||
00366    m_pCancelKey->MatchKey(key) ||
00367    m_pEditSubscriptKey->MatchKey(key) ||
00368    m_pEditExpKey->MatchKey(key);
00369 }
00370 
00371 void mcMathCore::SyntaxError(wxString str)
00372 {
00373  // just send a message to the 'on error' registered function
00374  if (OnError != NULL)
00375   OnError(str);
00376 }
00377 
00378 
00379 
00380 
00381 
00382 // --------------------------------
00383 // mcMATHCORE - math functions
00384 // --------------------------------
00385 
00386 #define mcSAFE_ADD(x)     \
00387  { mcSolver *toadd = new x();  \
00388    if (!arrSolvers.math_Add(toadd)) \
00389     delete toadd; }
00390 
00391 
00392 void mcMathCore::LoadDefaultSolvers()
00393 {
00394  // generic solvers
00395  mcSAFE_ADD(mcSimplifySolver);
00396  mcSAFE_ADD(mcExpandSolver);
00397 
00398  // the polynomial solver
00399  mcSAFE_ADD(mcPolySolver);
00400 
00401  // the approximated bisection solver
00402  mcSAFE_ADD(mcBisectSolver);
00403 }
00404 


Documentation generated with Doxygen on Sun Feb 6 17:10:47 2005
Visit MathStudio home page for more info

[ Top ]