ActionComponent.cpp

Go to the documentation of this file.
00001 /*
00002 SagaEngine library
00003 Copyright (c) 2002-2006 Skalden Studio AS
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to distribute the library under the terms of the 
00010 Q Public License version 1.0. Be sure to read and understand the license
00011 before using the library. It should be included here, or you may read it
00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl
00013 
00014 The original version of this library can be located at:
00015 http://www.sagaengine.com/
00016 
00017 Rune Myrland
00018 rune@skalden.com
00019 */
00020 
00021 
00022 #include "ActionComponent.hpp"
00023 #include "ActionAndParameter.hpp"
00024 #include "../schema/SimSchema.hpp"
00025 
00026 
00027 namespace se_core {
00028 
00029     ActionComponent
00030     ::ActionComponent(Composite* owner)
00031         : Component(sct_ACTION, owner), feed_(0) {
00032         for(int i = 0; i < CHANNEL_COUNT; ++i) {
00033             presentActionScheduledComplete_[i] = 0;
00034         }
00035     }
00036 
00037 
00038     ActionComponent
00039     ::~ActionComponent() {
00040     }
00041 
00042 
00043     void ActionComponent
00044 	::cleanup() {
00045         for(int i = 0; i < CHANNEL_COUNT; ++i) {
00046             clearPlannedAction(i);
00047         }
00048         disrupt();
00049     }
00050 
00051 
00052     void ActionComponent
00053     ::scheduleNextAction(short channel) {
00054         // Actions still in action queue after
00055         // scheduleForDestruction may try to plan
00056         // further actions
00057         if(isDead()) return;
00058         Assert(plannedAction_[channel].hasAction());
00059         presentAction_[channel] = plannedAction_[channel];
00060         plannedAction_[channel].resetAction();
00061 
00062         // Add to action queue
00063         const Action* a = presentAction_[channel].action();
00064         Parameter& p = presentAction_[channel].parameter();
00065         p.resetActionStage();
00066         p.setChannel(channel);
00067         // 
00068         a->prepare(*this, p);
00069         if(!a->doPause(*this, p)) {
00070             presentActionScheduledComplete_[channel]
00071                     = SimSchema::actionQueue[channel].add(*this, a->duration(*this, p));
00072         }
00073         //
00074     }
00075 
00076 
00077     void ActionComponent
00078     ::continueAction(long when, short channel) {
00079         // Add to action queue
00080         const Action* a = presentAction_[channel].action();
00081         Parameter& p = presentAction_[channel].parameter();
00082         p.incrActionStage();
00083         if(!a->doPause(*this, p)) {
00084             presentActionScheduledComplete_[channel]
00085                 = SimSchema::actionQueue[channel].add(*this, a->duration(*this, p));
00086         }
00087     }
00088 
00089 
00090     void ActionComponent
00091     ::unpause(short channel) {
00092         const Action* a = presentAction_[channel].action();
00093         Parameter& p = presentAction_[channel].parameter();
00094         presentActionScheduledComplete_[channel]
00095             = SimSchema::actionQueue[channel].add(*this, a->duration(*this, p));
00096     }
00097 
00098     void ActionComponent
00099     ::planAction(short channel, const Action& action, const Parameter* parameter) const {
00100         plannedAction_[channel].setAction(action);
00101         if(parameter) {
00102             plannedAction_[channel].copyParameter(*parameter);
00103         }
00104         if(!presentAction_[channel].hasAction() && plannedAction_[channel].hasAction()) {
00105             const_cast<ActionComponent&>(*this).scheduleNextAction(channel);
00106         }
00107     }
00108 
00109 
00110     void ActionComponent
00111     ::planAction(short channel, const ActionAndParameter& action) const {
00112         if(!action.hasAction())
00113             return;
00114         plannedAction_[channel].set(action);
00115         if(!presentAction_[channel].hasAction() && plannedAction_[channel].hasAction()) {
00116             const_cast<ActionComponent&>(*this).scheduleNextAction(channel);
00117         }
00118     }
00119 
00120 
00121     void ActionComponent
00122     ::planActionIfNone(short channel, const ActionAndParameter& action) const {
00123         if(!plannedAction_[ channel ].hasAction())
00124             planAction(channel, action);
00125     }
00126 
00127 
00128     void ActionComponent
00129     ::clearPlannedAction(short channel) const {
00130         plannedAction_[channel].resetAction();
00131     }
00132 
00133 
00134     void ActionComponent
00135     ::disrupt() {
00136         for(int i = 0; i < CHANNEL_COUNT; ++i) {
00137             disrupt(i);
00138         }
00139     }
00140 
00141 
00142     void ActionComponent
00143     ::resume() {
00144         for(int i = 0; i < CHANNEL_COUNT; ++i) {
00145             presentAction_[ i ].setDisrupted(false);
00146             if(!presentAction_[ i ].hasAction()) {
00147                 nextScriptAction(i);
00148                 if(plannedAction_[i].hasAction()) {
00149                     scheduleNextAction(i);
00150                 }
00151             }
00152         }
00153     }
00154 
00155 
00156     bool ActionComponent
00157     ::disrupt(short channel) {
00158         if(!presentAction_[ channel ].hasAction()) return true;
00159         // Actions are only removed from ActionQueue if it is in a future
00160         // initiative. If it is in the initiative presently performed, it
00161         // will not be touched...
00162         bool didDisrupt = SimSchema::actionQueue[ channel ].disrupt(*this);
00163         if(didDisrupt) {
00164             const Action* a = presentAction_[channel].action();
00165             Parameter& p = presentAction_[channel].parameter();
00166             a->disrupt(*this, p);
00167             presentAction_[channel].resetAction();
00168         }
00169         presentAction_[ channel ].setDisrupted(true);
00170         return didDisrupt;
00171     }
00172 
00173 
00174     void ActionComponent
00175     ::nextScriptAction(short channel) {
00176         if(!feed_) return;
00177         ActionAndParameter& aap = plannedAction_[channel];
00178         feed_->nextAction(*this, channel, aap);
00179         if(aap.hasAction()) {
00180             if(!presentAction_[channel].hasAction()) {
00181                 scheduleNextAction(channel);
00182             }
00183         }
00184     }
00185 
00186 
00187     void ActionComponent
00188     ::setActionFeed(ActionFeed* feed) {
00189         AssertFatal(feed_ == 0,  "Should only have one action feed");
00190         feed_ = feed;
00191     }
00192 
00193 
00194     void ActionComponent
00195     ::setScriptActive(bool state) {
00196         if(state) {
00197             if(feed_) {
00198                 for(int i = 0; i < CHANNEL_COUNT; ++i) {
00199                     presentAction_[i].setDisrupted(false);
00200                     nextScriptAction(i);
00201                 }
00202             }
00203         }
00204         else {
00205             // Clear action in all channels
00206             for(int i = 0; i < CHANNEL_COUNT; ++i) {
00207                 clearPlannedAction(i);
00208             }
00209             // Disrupt actions in progress
00210             //disrupt();
00211         }
00212     }
00213 
00214 
00215     void ActionComponent
00216     ::setActive(bool state) {
00217         LogDetail(owner_->name() << " " << state);
00218         setScriptActive(state);
00219     }
00220 
00221 
00222     void ActionComponent
00223     ::castFeedbackEvent(int type) {
00224         for(int i = 0; i < CHANNEL_COUNT; ++i) {
00225             if(presentAction_[ i ].hasAction()) {
00226                 const Action* a = presentAction_[i].action();
00227                 Parameter& p = presentAction_[i].parameter();
00228                 a->feedbackEvent(*this, p, type);
00229             }
00230         }
00231     }
00232 }

Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:10 2007 by Doxygen version 1.3.9.1.

SourceForge.net Logo