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 "Script.hpp" 00023 #include "ScriptComponent.hpp" 00024 #include "../action/all.hpp" 00025 #include "../thing/Actor.hpp" 00026 #include "../schema/SimSchema.hpp" 00027 #include "util/type/String.hpp" 00028 #include "util/error/Log.hpp" 00029 00030 00031 namespace se_core { 00032 ScriptComponent 00033 ::ScriptComponent(Composite* owner, ActionComponent* consumer) 00034 : Component(sct_SCRIPT, owner) 00035 , currentScript_(0) 00036 , consumer_(consumer) { 00037 scriptStack_[currentScript_] = 0; 00038 consumer_->setActionFeed(this); 00039 } 00040 00041 00042 ScriptComponent 00043 ::ScriptComponent(Composite* owner, const ComponentFactory* factory) 00044 : Component(sct_SCRIPT, owner, factory) 00045 , currentScript_(0) { 00046 consumer_ = static_cast<ActionComponent*>(owner_->component(sct_ACTION)); 00047 Assert(consumer_); 00048 scriptStack_[currentScript_] = 0; 00049 consumer_->setActionFeed(this); 00050 } 00051 00052 ScriptComponent 00053 ::~ScriptComponent() { 00054 cleanup(); 00055 } 00056 00057 void ScriptComponent 00058 ::cleanup() { 00059 if(consumer_) 00060 consumer_->resetActionFeed(); 00061 consumer_ = 0; 00062 clearScripts(); 00063 } 00064 00065 00066 void ScriptComponent 00067 ::nextAction(const ActionComponent& performer, int channel, ActionAndParameter& out) { 00068 nextScriptAction(channel, out); 00069 } 00070 00071 00072 void ScriptComponent 00073 ::nextScriptAction(short channel, ActionAndParameter& aap) { 00074 if(!script()) return; 00075 //Parameter& p = aap.parameter(); 00076 //const Action* a = script()->nextAction(*this, channel, scriptData(), p); 00077 //ActionAndParameter aap; 00078 script()->nextAction(*this, channel, scriptData(), aap); 00079 00080 int s = currentScript_; 00081 while(!aap.hasAction() && s > 0 && scriptStack_[ s ]->isTransparent()) { 00082 --s; 00083 scriptStack_[ s ]->nextAction(*this, channel, scriptData_[ s ], aap); 00084 } 00085 00086 /* 00087 if(aap.hasAction()) { 00088 //aap.setAction(*a); 00089 out.set(aap); 00090 } 00091 */ 00092 } 00093 00094 00095 void ScriptComponent 00096 ::setDefaultScript(const Script* s) { 00097 if(!isActive() || currentScript_ != 0) { 00098 if(scriptStack_[0]) { 00099 scriptStack_[0]->release(scriptData_[0]); 00100 } 00101 scriptStack_[0] = s; 00102 scriptData_[0] = scriptStack_[0]->init(*this); 00103 return; 00104 } 00105 00106 if(script()) script()->release(scriptData_[currentScript_]); 00107 scriptStack_[0] = s; 00108 scriptData_[0] = scriptStack_[0]->init(*this); 00109 consumer_->setScriptActive(true); 00110 } 00111 00112 00113 void ScriptComponent 00114 ::clearScripts() { 00115 // TODO: 00116 //if(showingCutscene_) { 00117 // removeFromShowingCutscene(); 00118 //} 00119 while(currentScript_ > 0) { 00120 scriptStack_[ currentScript_ ]->release( scriptData_[ currentScript_ ] ); 00121 scriptStack_[ currentScript_-- ] = 0; 00122 } 00123 if(scriptStack_[0] != 0) { 00124 scriptStack_[ 0 ]->release( scriptData_[ 0 ] ); 00125 scriptStack_[ 0 ] = 0; 00126 } 00127 } 00128 00129 00130 void ScriptComponent 00131 ::pushScript(const char* name) { 00132 const Script* s = Script::lookup(name); 00133 pushScript(s); 00134 } 00135 00136 00137 void ScriptComponent 00138 ::pushScript(const Script* s) { 00139 //consumer_->setScriptActive(false); 00140 00141 // If there already is a script running... 00142 if(script() && !script()->isStacker()) { 00143 // Release script data 00144 popScript(); 00145 } 00146 00147 if(scriptStack_[currentScript_] != 0) { 00148 ++currentScript_; 00149 } 00150 00151 Assert(currentScript_ < SCRIPT_STACK_SIZE); 00152 // Set the new script 00153 scriptStack_[currentScript_] = s; 00154 // Init script data 00155 scriptData_[currentScript_] = script()->init(*this); 00156 00157 // If owner is active 00158 if(owner()->isActive()) 00159 consumer_->setScriptActive(true); 00160 } 00161 00162 00163 void ScriptComponent 00164 ::popScript() { 00165 // Asser(!isDead_); 00166 const char* popScript = script()->name(); 00167 00168 //bool isTransparent = script()->isTransparent(); 00169 consumer_->setScriptActive(false); 00170 00171 if(currentScript_ == 0) { 00172 Assert(script()); 00173 script()->release(scriptData_[currentScript_]); 00174 scriptData_[currentScript_] = 0; 00175 scriptStack_[currentScript_] = 0; 00176 return; 00177 } 00178 00179 if(script()) script()->release(scriptData_[currentScript_]); 00180 --currentScript_; 00181 if(!script()) return; 00182 00183 script()->reinitPop(*this, scriptData(), popScript); 00184 00185 if(isActive()) { 00186 consumer_->setScriptActive(true); 00187 } 00188 } 00189 00190 00191 void ScriptComponent 00192 ::stopScript() { 00193 //TODO: 00194 //if(showingCutscene_) { 00195 // removeFromShowingCutscene(); 00196 //} 00197 //else { 00198 Assert(script()); 00199 script()->release(scriptData_[currentScript_]); 00200 scriptData_[currentScript_] = 0; 00201 currentScript_ = 0; 00202 scriptStack_[0] = 0; 00203 //TODO: 00204 consumer_->disrupt(); 00205 //} 00206 } 00207 00208 00209 void ScriptComponent 00210 ::setActive(bool state) { 00211 /* 00212 // Setting to active?? 00213 //if(isActive()) { 00214 if(state) { 00215 // Start script 00216 if(script()) { 00217 LogWarning(owner()->name()); 00218 // Init (or reinit) scripts data block 00219 script()->reinit(*this, scriptData()); 00220 // Start script in all action channels 00221 consumer_->setScriptActive(true); 00222 } 00223 } 00224 */ 00225 } 00226 00227 00228 void ScriptComponent 00229 ::touch(void* param) { 00230 script()->touched(*this, scriptData(), param); 00231 } 00232 00233 void ScriptComponent 00234 ::touchDefault(void* param) { 00235 Assert(currentScript_ >= 0); 00236 const Script* s = scriptStack_[0]; 00237 Assert(s); 00238 s->touched(*this, scriptData(), param); 00239 } 00240 00241 00242 void ScriptComponent 00243 ::feedbackEvent(const ActionComponent& source, int type) { 00244 if(hasActiveScript()) { 00245 script()->feedbackEvent(*this, scriptData(), type); 00246 } 00247 } 00248 00249 }
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:12 2007 by Doxygen version 1.3.9.1.