Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Operator2Expr.cpp

Go to the documentation of this file.
00001 // Operator2Expr.cpp: implementation of the COperator2Expr class.
00002 /*
00003  * Copyright (c) 1996-2000 Erwin Coumans <[email protected]>

00004  *
00005  * Permission to use, copy, modify, distribute and sell this software

00006  * and its documentation for any purpose is hereby granted without fee,

00007  * provided that the above copyright notice appear in all copies and

00008  * that both that copyright notice and this permission notice appear

00009  * in supporting documentation.  Erwin Coumans makes no

00010  * representations about the suitability of this software for any

00011  * purpose.  It is provided "as is" without express or implied warranty.

00012  *
00013  */
00014 // 31 dec 1998 - big update: try to use the cached data for updating, instead of
00015 // rebuilding completely it from left and right node. Modified flags and bounding boxes
00016 // have to do the trick
00017 // when expression is cached, there will be a call to UpdateCalc() instead of Calc()
00018 
00019 
00020 
00021 #include "Operator2Expr.h"
00022 #include "StringValue.h"
00023 #include "VoidValue.h"
00024 //#include "FactoryManager.h"
00026 // Construction/Destruction
00028 
00029 COperator2Expr::COperator2Expr(VALUE_OPERATOR op, CExpression *lhs, CExpression *rhs)
00030 :       
00031 m_cached_calculate(NULL),
00032 m_op(op),
00033 m_lhs(lhs),
00034 m_rhs(rhs)
00035 /*
00036 pre:

00037 effect: constucts a COperator2Expr with op, lhs and rhs in it

00038 */
00039 {
00040 
00041 }
00042 
00043 COperator2Expr::COperator2Expr():
00044 m_cached_calculate(NULL),
00045 m_lhs(NULL),
00046 m_rhs(NULL)
00047 
00048 /*
00049 pre:

00050 effect: constucts an empty COperator2Expr

00051 */
00052 {
00053         
00054 }
00055 
00056 COperator2Expr::~COperator2Expr()
00057 /*
00058 pre:

00059 effect: deletes the object

00060 */
00061 {
00062         if (m_lhs)
00063                 m_lhs->Release();
00064         if (m_rhs)
00065                 m_rhs->Release();
00066         if (m_cached_calculate)
00067                 m_cached_calculate->Release();
00068         
00069 }
00070 CValue* COperator2Expr::Calculate()
00071 /*
00072 pre:

00073 ret: a new object containing the result of applying operator m_op to m_lhs

00074 and m_rhs

00075 */
00076 {
00077         
00078         bool leftmodified,rightmodified;
00079         leftmodified = m_lhs->NeedsRecalculated();
00080         rightmodified = m_rhs->NeedsRecalculated();
00081         
00082         // if no modifications on both left and right subtree, and result is already calculated
00083         // then just return cached result...
00084         if (!leftmodified && !rightmodified && (m_cached_calculate))
00085         {
00086                 // not modified, just return m_cached_calculate
00087         } else {
00088                 // if not yet calculated, or modified...
00089                 
00090                 
00091                 if (m_cached_calculate) {
00092                         m_cached_calculate->Release();
00093                         m_cached_calculate=NULL;
00094                 }
00095                 
00096                 CValue* ffleft = m_lhs->Calculate();
00097                 CValue* ffright = m_rhs->Calculate();
00098                 
00099                 ffleft->SetOwnerExpression(this);//->m_pOwnerExpression=this;
00100                 ffright->SetOwnerExpression(this);//->m_pOwnerExpression=this;
00101                 
00102                 m_cached_calculate = ffleft->Calc(m_op,ffright);
00103                 
00104                 //if (m_cached_calculate)                               
00105                 //      m_cached_calculate->Action(CValue::SETOWNEREXPR,&CVoidValue(this,false,CValue::STACKVALUE));
00106 
00107                 ffleft->Release();
00108                 ffright->Release();
00109         }
00110         
00111         return m_cached_calculate->AddRef();
00112         
00113 }
00114 
00115 /*
00116 bool COperator2Expr::IsInside(float x, float y, float z,bool bBorderInclude)

00117 {

00118         bool inside;

00119         inside = false;

00120         

00121         switch (m_op) 

00122         {

00123         case VALUE_ADD_OPERATOR: {

00124         //      inside = first || second; // optimized with early out if first is inside

00125                 // todo: calculate smallest leaf first ! is much faster...

00126                         

00127                 bool second;//first ;//,second;

00128                 

00129                 //first = m_lhs->IsInside(x,y,z) ;

00130                 second = m_rhs->IsInside(x,y,z,bBorderInclude) ;

00131                 if (second)

00132                         return true; //early out

00133         

00134         //      second = m_rhs->IsInside(x,y,z) ;

00135 
00136                 return m_lhs->IsInside(x,y,z,bBorderInclude) ;

00137                         

00138                 break;

00139                                                          }

00140                 

00141         case VALUE_SUB_OPERATOR: {

00142                 //inside = first && !second; // optimized with early out

00143                 // todo: same as with add_operator: calc smallest leaf first

00144 
00145                 bool second;//first ;//,second;

00146                 //first = m_lhs->IsInside(x,y,z) ;

00147                 second = m_rhs->IsInside(x,y,z,bBorderInclude);

00148                 if (second)

00149                         return false;

00150 
00151                 // second space get subtracted -> negate!

00152                 //second = m_rhs->IsInside(x,y,z);

00153 
00154                 return (m_lhs->IsInside(x,y,z,bBorderInclude));

00155 
00156                 

00157                 break;

00158                                                          }

00159         default:{

00160                 assert(false);

00161                 // not yet implemented, only add or sub csg operations

00162                         }

00163         }

00164         

00165         return inside;  

00166 }

00167 
00168 
00169 
00170 bool COperator2Expr::IsRightInside(float x, float y, float z,bool bBorderInclude) {

00171         

00172         return m_rhs->IsInside(x,y,z,bBorderInclude) ;

00173         

00174 }

00175 
00176 bool COperator2Expr::IsLeftInside(float x, float y, float z,bool bBorderInclude) {

00177         return m_lhs->IsInside(x,y,z,bBorderInclude);

00178 }

00179 */
00180 bool COperator2Expr::NeedsRecalculated() {
00181         // added some lines, just for debugging purposes, it could be a one-liner :)
00182         //bool modleft
00183         //bool modright;
00184         assertd(m_lhs);
00185         assertd(m_rhs);
00186 
00187         //modright = m_rhs->NeedsRecalculated();
00188         if (m_rhs->NeedsRecalculated()) // early out
00189                 return true;
00190         return m_lhs->NeedsRecalculated();
00191         //modleft = m_lhs->NeedsRecalculated();
00192         //return (modleft || modright);
00193         
00194 }
00195 
00196 
00197 
00198 CExpression* COperator2Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) {
00199 // if both children are 'dead', return NULL
00200 // if only one child is alive, return that child
00201 // if both childresn are alive, return this
00202 
00203 
00204         bool leftalive = true,rightalive=true;
00205         assertd(false);
00206         assert(m_lhs);
00207         assert(m_rhs);
00208 /*
00209         if (m_cached_calculate)

00210                 m_cached_calculate->Action(CValue::REFRESH_CACHE);

00211         

00212         CExpression* newlhs = m_lhs->CheckLink(brokenlinks);

00213         CExpression* newrhs = m_rhs->CheckLink(brokenlinks);

00214 
00215         if (m_lhs != newlhs)

00216         {

00217                 brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs));

00218         }

00219 
00220         if (m_rhs != newrhs)

00221         {

00222                 brokenlinks.push_back(new CBrokenLinkInfo(&m_rhs,m_rhs));

00223         }

00224 
00225 
00226 
00227         m_lhs = newlhs;

00228         m_rhs = newrhs;

00229 
00230         if (m_lhs && m_rhs) {

00231                 return this;

00232         }

00233         

00234         AddRef();

00235         if (m_lhs) 

00236                 return Release(m_lhs->AddRef());

00237         

00238         if (m_rhs)

00239                 return Release(m_rhs->AddRef());

00240 /               

00241 
00242   */
00243   return Release();
00244 
00245   
00246         
00247 }
00248 
00249 
00250 bool COperator2Expr::MergeExpression(CExpression *otherexpr)

00251 {
00252         if (m_lhs)
00253         {
00254                 if (m_lhs->GetExpressionID() == CExpression::CCONSTEXPRESSIONID)
00255                 {
00256                         // cross fingers ;) replace constexpr by new tree...
00257                         m_lhs->Release();
00258                         m_lhs = otherexpr->AddRef();
00259                         return true;
00260                 }
00261         }
00262 
00263         assertd(false);
00264         return false;
00265 }
00266 
00267 
00268 void COperator2Expr::BroadcastOperators(VALUE_OPERATOR op)

00269 {
00270         if (m_lhs)
00271                 m_lhs->BroadcastOperators(m_op);
00272         if (m_rhs)
00273                 m_rhs->BroadcastOperators(m_op);
00274 }

Generated at Thu Feb 1 13:03:08 2001 for Ketsji Game Engine by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000