Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

CSAction.cpp

Go to the documentation of this file.
00001 #ifdef WIN32
00002 #pragma warning(disable : 4786 )
00003 #endif
00004 
00005 #include "CSAction.h"
00006 #include "SDLMain.h"
00007 #include "CSXMLHelper.h"
00008 
00009 CSActionLoader CSActionLoader::INSTANCE;
00010 const char *CSAction::CLASS = "CSAction";
00011 
00012 CSAction::CSAction(const std::string &filename)
00013 {
00014     static char *functionName="CSAction";
00015     LOG_ENTER 
00016     CSActionData data;
00017     loadActionData(filename, data);
00018     initialize(data);
00019     LOG_EXIT
00020 }
00021 
00022 CSAction::CSAction(const CSAction &action)
00023 {
00024     static char *functionName="CSAction";
00025     LOG_ENTER 
00026     int i;
00027     initialize();
00028     mIsBreakable = action.mIsBreakable;
00029     mRepeatable = action.mRepeatable;
00030     mSizePhases = action.mSizePhases;
00031     mEnvoker = action.mEnvoker;
00032     mType = action.mType;
00033 
00034     mPhases = new unsigned int[mSizePhases];
00035     for (i=0; i<mSizePhases; i++)
00036     {
00037         mPhases[i] = action.mPhases[i];
00038     }
00039 
00040     mAnimations = new CSAnimations();
00041     CSAnimations::const_iterator iter = action.mAnimations->begin();
00042     while (iter != action.mAnimations->end())
00043     {
00044         // animations are singletons!
00045         // that means, we can (and should) re-use the animation we find at
00046         // the action that we copy from
00047         mAnimations->push_back(*iter);  
00048         iter++;
00049     }
00050     mId = strdup(action.mId);
00051     mNextAction = strdup(action.mNextAction);
00052     LOG_EXIT
00053 }
00054 
00055 void CSAction::initialize(void)
00056 {
00057     static char *functionName="initialize";
00058     LOG_ENTER 
00059     mIsBreakable = true;
00060     mRepeatable = CS_REPEATABLE;
00061     mSizePhases = 0;
00062     mPhases = 0;
00063     mType = 0;
00064     mEnvoker = 0;
00065     mId = 0;
00066     mNextAction = 0;
00067     mAnimations = 0;
00068     LOG_EXIT
00069 }
00070 
00071 void CSAction::initialize(const CSActionData &data)
00072 {
00073     static char *functionName="initialize";
00074     LOG_ENTER 
00075     int i;
00076     initialize();
00077 
00078     mType = data.type;
00079     mIsBreakable = data.isBreakable;
00080     mRepeatable = data.repeatable;
00081     mSizePhases = data.sizePhases;
00082     mEnvoker = data.envoker;
00083 
00084     mPhases = new unsigned int[mSizePhases];
00085     for (i=0; i<mSizePhases; i++)
00086     {
00087         mPhases[i] = data.phases[i];
00088     }
00089         
00090     mAnimations = new CSAnimations();
00091     for (StringVector::iterator iter = data.animationNames->begin(); iter != data.animationNames->end(); iter++)
00092     {
00093         char *help = (char *) *iter; 
00094         if (help == NULL)
00095         {
00096             LOG_EXIT
00097             SDLMain::shutdown((std::string)"Char Pointer == 0 Action Loading: " + SDL_GetError(), 1);
00098         }
00099         // create all animations (with ini - filename)
00100         CSAnimation *animation = CSAnimationLoader::INSTANCE.load((char *)(help));
00101         mAnimations->push_back(animation);  
00102     } 
00103 
00104     mId = strdup(data.id);
00105     mNextAction = strdup(data.nextAction);
00106     LOG_EXIT
00107 }
00108 
00109 CSAction::~CSAction()
00110 {
00111     static char *functionName="~CSAction";
00112     LOG_ENTER 
00113     if (mPhases != 0)
00114     {
00115         delete []mPhases;
00116         mPhases = 0;
00117     }
00118 
00119     if (mAnimations != 0)
00120     {
00121         // Animation are singletons -> do not delete them 
00122         // Animation are deleted by CSAnimationLoader!
00123         delete mAnimations;
00124         mAnimations = 0;
00125     }
00126     
00127     if (mId != 0)
00128     {
00129         free(mId);
00130         mId = 0;
00131     }
00132 
00133     if (mNextAction != 0)
00134     {
00135         free(mNextAction);
00136         mNextAction = 0;
00137     }
00138     LOG_EXIT
00139 }
00140 
00141 // build an initial state for this action, sets variables to defaults
00142 ActionState CSAction::buildState()
00143 {
00144     static char *functionName="buildState";
00145     ActionState state;
00146     state.mFinished = false;
00147     state.mForward = true;
00148     if (mSizePhases > 0)
00149     {
00150         state.mCurrentPhase = 0;
00151         state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00152         state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00153         state.mAnimationState = state.mAnimation->buildState();
00154     }
00155     return state;
00156 }
00157 
00158 // resets a state to default values
00159 // doesn't  update mDisplayParams! 
00160 // (this position and mDisplayPicture do not change!)
00161 void CSAction::resetState(ActionState& state)
00162 {
00163     static char *functionName="resetState";
00164     state.mFinished = false;
00165     state.mForward = true;
00166     if (mSizePhases > 0)
00167     {
00168         state.mCurrentPhase = 0;
00169         state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00170         state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00171         state.mAnimation->resetState(state.mAnimationState);
00172     }
00173 }
00174         
00175 // resets a state to start values of this action -> immediately
00176 // - happens when an event for another action occurs or so
00177 void CSAction::startAction(ActionState &state)
00178 {
00179     static char *functionName="startAction";
00180     state.mFinished = false;
00181     state.mForward = true;
00182     if (mSizePhases > 0)
00183     {
00184         state.mCurrentPhase = 0;
00185         state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00186         state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00187         state.mAnimation->startAnimation(state.mAnimationState);
00188     }
00189 }
00190 
00191 // resets a state to start values of this action
00192 // this will not be displayed during next display() call
00193 // - happens when one action ends during update, and a next
00194 // action is initiated - this means the next action is
00195 // active from the start of next update, doesn't interfere with
00196 // current mDisplayParams!
00197 void CSAction::startNextAction(ActionState &state)
00198 {
00199     static char *functionName="startNextAction";
00200     state.mFinished = false;
00201     state.mForward = true;
00202     if (mSizePhases > 0)
00203     {
00204         state.mCurrentPhase = 0;
00205         state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00206         state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00207         state.mAnimation->startNextAnimation(state.mAnimationState);
00208     }
00209 }
00210 
00211 void CSAction::setSecPerFrame(float secPerFrame)
00212 {
00213     static char *functionName="setSecPerFrame";
00214     LOG_ENTER 
00215     CSAnimations::const_iterator iter = mAnimations->begin();
00216     while (iter != mAnimations->end())
00217     {
00218         CSAnimation *animation = *iter;
00219         animation->setSecPerFrame(secPerFrame);
00220         iter++;
00221     }
00222     LOG_EXIT
00223 }
00224 
00225 void CSAction::setAlpha(int alpha)
00226 {
00227     static char *functionName="setAlpha";
00228     LOG_ENTER 
00229     CSAnimations::const_iterator iter = mAnimations->begin();
00230     while (iter != mAnimations->end())
00231     {
00232         CSAnimation *animation = *iter;
00233         animation->setAlpha(alpha);
00234         iter++;
00235     }
00236     LOG_EXIT
00237 }
00238 
00239 // if finished and not repeat -> false, true otherwise
00240 // does not display anything, but prepares (update) for next displaying
00241 bool CSAction::next(ActionState &state)
00242 {
00243     static char *functionName="next";
00244     bool finished = false;
00245     if (state.mFinished)
00246     {
00247         return !state.mFinished;
00248     }
00249 
00250     finished = !(state.mAnimation->next(state.mAnimationState));
00251     if (finished)
00252     {
00253         if (mRepeatable == CS_RANDOM)
00254         {
00255             // TODO
00256         }
00257         else
00258         {
00259             if (state.mForward)
00260             {
00261                 state.mCurrentPhase++;
00262                 if (state.mCurrentPhase == mSizePhases)
00263                 {
00264                     if (mRepeatable == CS_INVERSE_REPEATABLE)
00265                     {
00266                         state.mForward = !state.mForward;
00267                         if (mSizePhases > 1)
00268                         {
00269                             state.mCurrentPhase-=2;
00270                         }
00271                         else
00272                         {
00273                             state.mCurrentPhase--;
00274                         }
00275                     }
00276                     else
00277                     if (mRepeatable == CS_INVERSE_ONCE)
00278                     {
00279                         state.mForward = !state.mForward;
00280                         if (mSizePhases > 1)
00281                         {
00282                             state.mCurrentPhase-=2;
00283                         }
00284                         else
00285                         {
00286                             state.mCurrentPhase--;
00287                         }
00288                     }
00289                     else
00290                     {
00291                         if (mRepeatable == CS_NOT_REPEATABLE)
00292                         {
00293                             state.mFinished = true;
00294                             return !state.mFinished;
00295                         }
00296                         state.mCurrentPhase = 0;
00297                     }
00298                 }
00299             }
00300             else // mForward
00301             {
00302                 state.mCurrentPhase--;
00303                 if (state.mCurrentPhase == -1)
00304                 {
00305                     if (mRepeatable == CS_INVERSE_REPEATABLE)
00306                     {
00307                         state.mForward = !state.mForward;
00308                         if (mSizePhases > 1)
00309                         {
00310                             state.mCurrentPhase+=2;
00311                         }
00312                         else
00313                         {
00314                             state.mCurrentPhase++;
00315                         }
00316                     }
00317                     else
00318                     {
00319                         if (mRepeatable == CS_INVERSE_ONCE)
00320                         {
00321                             state.mFinished = true;
00322                             return !state.mFinished;
00323                         }
00324                         state.mCurrentPhase = 0;
00325                     }
00326 
00327                 }
00328             }
00329 
00330         } // else (mRepeatable == CS_RANDOM)
00331         state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00332         state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00333         state.mAnimation->startAnimation(state.mAnimationState);
00334     } // (mDelayCounter == mDelays[mPhases[mCurrentPhase]])
00335 
00336     return !state.mFinished;
00337 }
00338 
00339 // not much to do here, to display an animation (picture)
00340 void CSAction::display(ActionState &state)
00341 {
00342     static char *functionName="display";
00343     state.mAnimation->display(state.mAnimationState);
00344 }
00345 
00346 bool CSAction::isBreakable(ActionState &state)
00347 {
00348     static char *functionName="isBreakable";
00349     if (!mIsBreakable)
00350     {
00351         return mIsBreakable;
00352     }
00353     return state.mAnimation->isBreakable();
00354 }
00355 
00356 bool CSAction::isAction(char *id)
00357 {
00358     static char *functionName="isAction";
00359     return !(strcmp(id, mId));
00360 }
00361 
00362 // of all pictures belonging to this action 
00363 // return the largest width
00364 unsigned int CSAction::getMaxX()
00365 {
00366     static char *functionName="getMaxX";
00367     unsigned int maxX = 0;
00368     unsigned int x;
00369     for (CSAnimations::iterator iter = mAnimations->begin(); iter != mAnimations->end(); iter++)
00370     {
00371         CSAnimation *ani = *iter;
00372         x = ani->getMaxX(); if (maxX < x) maxX = x;
00373     }
00374     return maxX;
00375 }
00376 
00377 // of all pictures belonging to this action 
00378 // return the largest height
00379 unsigned int CSAction::getMaxY()
00380 {
00381     static char *functionName="getMaxY";
00382     unsigned int maxY = 0;
00383     unsigned int y;
00384 
00385     for (CSAnimations::iterator iter = mAnimations->begin(); iter != mAnimations->end(); iter++)
00386     {
00387         CSAnimation *ani = *iter;
00388         y = ani->getMaxY(); if (maxY < y) maxY = y;
00389     }
00390     return maxY;
00391 }
00392 
00393 void CSAction::loadActionData(const std::string &filename, CSActionData &data)
00394 {
00395     static char *functionName="loadActionData";
00396     LOG_ENTER 
00397     char tmp[10];
00398     
00399     CSXMLHelper xmlSupport(filename, "ACTION");
00400     try
00401     {
00402         if (xmlSupport.getError())
00403         {
00404             LOG_EXIT
00405             throw "error";
00406         }
00407 
00408         data.id = strdup(xmlSupport.getString("ID").c_str());
00409         data.isBreakable = xmlSupport.getInt("IS_BREAKABLE") == 1;
00410         data.type = xmlSupport.getInt("TYPE");
00411         data.repeatable = xmlSupport.getInt("REPEATABLE");
00412 
00413         data.envoker = xmlSupport.getInt("ENVOKER");
00414 
00415         if (xmlSupport.getInt("count(/ACTION/DEFAULT_NEXT_ACTION)") == 1)
00416         {
00417             data.nextAction = strdup(xmlSupport.getString("DEFAULT_NEXT_ACTION").c_str());
00418         }
00419         data.sizePhases = xmlSupport.getInt("count(/ACTION/PHASE)");
00420         data.phases = new unsigned int[data.sizePhases];
00421         for (int i=0; i<data.sizePhases; i++)
00422         {
00423             // i+1, predicates in xpath start with 1
00424             data.phases[i] = xmlSupport.getInt((std::string)"/ACTION/PHASE["+itoa(i+1,tmp,10)+"]");
00425         }
00426 
00427         int animationCount = xmlSupport.getInt("count(/ACTION/ANIMATION)");
00428         data.animationNames = new StringVector();
00429         for (i=0; i<animationCount; i++)
00430         {
00431             // i+1, predicates in xpath start with 1
00432             std::string a = xmlSupport.getString((std::string)"/ACTION/ANIMATION["+itoa(i+1,tmp,10)+"]");
00433             data.animationNames->push_back(strdup(a.c_str()));
00434         }
00435     }
00436     catch(...)
00437     {
00438         LOG_EXIT
00439         SDLMain::shutdown((std::string)"XML error \"" + filename + "\": " + xmlSupport.getErrorMessage().c_str(), 1);
00440     }
00441     LOG_EXIT
00442 }

Generated on Wed Jul 14 00:43:28 2004 for CSLib by doxygen 1.3.6