cdflags.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  *\file cdflags.cpp
00004  *\brief Implementation for CDFlags class
00005  *
00006  * Author: Clark Barrett
00007  *
00008  * Created: Thu Jan 26 16:53:28 2006
00009  *
00010  * <hr>
00011  * Copyright (C) 2006 by the Board of Trustees of Leland Stanford
00012  * Junior University and by New York University. 
00013  *
00014  * License to use, copy, modify, sell and/or distribute this software
00015  * and its documentation for any purpose is hereby granted without
00016  * royalty, subject to the terms and conditions defined in the \ref
00017  * LICENSE file provided with this distribution.  In particular:
00018  *
00019  * - The above copyright notice and this permission notice must appear
00020  * in all copies of the software and related documentation.
00021  *
00022  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00023  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00024  * 
00025  * <hr>
00026  * 
00027  */
00028 /*****************************************************************************/
00029 
00030 
00031 #include "cdflags.h"
00032 
00033 
00034 using namespace CVCL;
00035 using namespace std;
00036 
00037 
00038 void CDFlags::update(unsigned mask, int scope, bool setMask)
00039 {
00040   DebugAssert(mask && (mask & (mask-1)) == 0, "Expected single bit mask");
00041   if (scope < 0 || d_scope->level() <= scope) {
00042     makeCurrent(scope);
00043     if (setMask) d_flags = d_flags | mask;
00044     else d_flags = d_flags & ~mask;
00045   }
00046   else {
00047     // Kind of ugly: have to "change the past", but that's the price we pay for
00048     // keeping all the flags in one word for efficiency.
00049     IF_DEBUG(bool on = (d_flags & mask);)
00050 
00051     // Update current object
00052     if (setMask) d_flags = d_flags | mask;
00053     else d_flags = d_flags & ~mask;
00054 
00055     ContextObjChain** lastPtr = &d_restore;
00056     CDFlags* pastFlags;
00057     Scope* lastScope = d_scope;
00058     bool done = false;
00059 
00060     // Update past objects
00061     while (true) {
00062       pastFlags = (CDFlags*)((*lastPtr)->d_data);
00063       if (pastFlags->d_scope->level() >= scope) {
00064         DebugAssert(on && (pastFlags->d_flags & mask) ||
00065                     !on && !(pastFlags->d_flags & mask),
00066                     "Expected no change in flag since scope");
00067         if (setMask) {
00068           pastFlags->d_flags = pastFlags->d_flags | mask;
00069         }
00070         else {
00071           pastFlags->d_flags = pastFlags->d_flags & ~mask;
00072         }
00073         if (pastFlags->d_scope->level() == scope) {
00074           done = true; break;
00075         }
00076         lastScope = pastFlags->d_scope;
00077       } else break;
00078       lastPtr = &((*lastPtr)->d_restore);
00079       DebugAssert(*lastPtr != NULL, "Should always be object at scope 0");
00080     }
00081     if (done) return;
00082 
00083     // No past object exists at the target scope: create one
00084     DebugAssert(lastScope != NULL &&
00085                 lastScope->level() > scope,
00086                 "Expected lastScope to be above target scope");
00087     while (lastScope->level() > scope) lastScope = lastScope->prevScope();
00088     ContextObj* data = (*lastPtr)->d_data->makeCopy();
00089     data->d_scope = lastScope;
00090     data->d_restore = NULL;
00091     ContextObjChain* obj = new ContextObjChain(data, this, *lastPtr);
00092     *lastPtr = obj;
00093     lastScope->addToChain(obj);
00094   }
00095 }

Generated on Thu Apr 13 16:57:29 2006 for CVC Lite by  doxygen 1.4.4