Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

DialogStack.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  */
00009 #include "DialogStack.h"
00010 
00011 #include "Dialog.h"
00012 #include "ResDialogPack.h"
00013 #include "PlannedDialog.h"
00014 #include "StringTool.h"
00015 
00016 //-----------------------------------------------------------------
00017 DialogStack::DialogStack()
00018 {
00019     m_dialogs = new ResDialogPack();
00020     m_activeDialog = NULL;
00021 }
00022 //-----------------------------------------------------------------
00023 /**
00024  * Releases resources and stops all cycling dialogs.
00025  */
00026 DialogStack::~DialogStack()
00027 {
00028     removeAll();
00029     delete m_dialogs;
00030 }
00031 //-----------------------------------------------------------------
00032 /**
00033  * Removes finished dialogs from stack.
00034  */
00035     void
00036 DialogStack::updateStack()
00037 {
00038     removeFirstNotTalking();
00039 }
00040 //-----------------------------------------------------------------
00041 /**
00042  * Store new dialog.
00043  */
00044     void
00045 DialogStack::addDialog(const std::string &name, Dialog *dialog)
00046 {
00047     m_dialogs->addRes(name, dialog);
00048 }
00049 //-----------------------------------------------------------------
00050 /**
00051  * Run talk.
00052  * Dialog name could contain "name@arg1@arg2..."
00053  * to fill %1, %2, ... in subtitles.
00054  *
00055  * @param actor actor index
00056  * @param name dialog name
00057  * @param volume dialog volume
00058  * @param loops number of loops, 0=play once, 1=play twice, -1=play infinite
00059  * @param dialogFlag whether it is blocking dialog
00060  */
00061     void
00062 DialogStack::actorTalk(int actor, const std::string &name,
00063         int volume, int loops, bool dialogFlag)
00064 {
00065     StringTool::t_args args = StringTool::split(name, '@');
00066 
00067     const Dialog *subtitle = m_dialogs->findDialogHard(args[0]);
00068     if (subtitle) {
00069         subtitle->runSubtitle(args);
00070 
00071         const Dialog *dialog = m_dialogs->findDialogSpeech(args[0]);
00072         if (dialog) {
00073             PlannedDialog *talker = new PlannedDialog(actor, dialog,
00074                 subtitle->getMinTime());
00075             talker->talk(volume, loops);
00076 
00077             if (loops == -1) {
00078                 m_cycling.push_back(talker);
00079             }
00080             else {
00081                 m_running.push_back(talker);
00082             }
00083 
00084             if (dialogFlag) {
00085                 m_activeDialog = talker;
00086             }
00087         }
00088     }
00089 }
00090 //-----------------------------------------------------------------
00091     bool
00092 DialogStack::isTalking(int actor) const
00093 {
00094     return isTalkingIn(actor, m_running) ||
00095         isTalkingIn(actor, m_cycling);
00096 }
00097 //-----------------------------------------------------------------
00098     bool
00099 DialogStack::isTalkingIn(int actor, const t_running &fifo) const
00100 {
00101     t_running::const_iterator end = fifo.end();
00102     for (t_running::const_iterator i = fifo.begin(); i != end; ++i) {
00103         if ((*i)->equalsActor(actor) && (*i)->isTalking()) {
00104             return true;
00105         }
00106     }
00107     return false;
00108 }
00109 //-----------------------------------------------------------------
00110 /**
00111  * Remove first not talking dialog from m_running.
00112  */
00113     void
00114 DialogStack::removeFirstNotTalking()
00115 {
00116     t_running::iterator end = m_running.end();
00117     for (t_running::iterator i = m_running.begin(); i != end; ++i) {
00118         if (!(*i)->isTalking()) {
00119             releaseDialog(*i);
00120             m_running.erase(i);
00121             return;
00122         }
00123     }
00124 }
00125 //-----------------------------------------------------------------
00126 /**
00127  * Delete all running dialogs made by this actor.
00128  */
00129     void
00130 DialogStack::killSound(int actor)
00131 {
00132     killSoundIn(actor, m_running);
00133     killSoundIn(actor, m_cycling);
00134 }
00135 //-----------------------------------------------------------------
00136 void
00137 DialogStack::killSoundIn(int actor, t_running &fifo)
00138 {
00139     //NOTE: erase on list invalidates only the erased iterator
00140     t_running::iterator run_end = fifo.end();
00141     for (t_running::iterator i = fifo.begin(); i != run_end; /* empty */) {
00142         t_running::iterator toKill = i;
00143         ++i;
00144 
00145         if ((*toKill)->equalsActor(actor)) {
00146             releaseDialog(*toKill);
00147             fifo.erase(toKill);
00148         }
00149     }
00150 }
00151 
00152 //-----------------------------------------------------------------
00153 /**
00154  * Kill all running dialogs.
00155  */
00156     void
00157 DialogStack::killTalks()
00158 {
00159     killTalksIn(m_running);
00160     killTalksIn(m_cycling);
00161 }
00162 //-----------------------------------------------------------------
00163 void
00164 DialogStack::killTalksIn(t_running &fifo)
00165 {
00166     t_running::iterator end = fifo.end();
00167     for (t_running::iterator i = fifo.begin(); i != end; ++i) {
00168         releaseDialog(*i);
00169     }
00170     fifo.clear();
00171 }
00172 //-----------------------------------------------------------------
00173 void
00174 DialogStack::releaseDialog(PlannedDialog *dialog)
00175 {
00176     if (dialog == m_activeDialog) {
00177         m_activeDialog = NULL;
00178     }
00179     dialog->killTalk();
00180     delete dialog;
00181 }
00182 //-----------------------------------------------------------------
00183 /**
00184  * Delete all shared dialogs and kill talks.
00185  */
00186     void
00187 DialogStack::removeAll()
00188 {
00189     killTalks();
00190     m_dialogs->removeAll();
00191 }
00192 //-----------------------------------------------------------------
00193 /**
00194  * Returns true when there is active dialog.
00195  */
00196 bool
00197 DialogStack::isDialog() const
00198 {
00199     return m_activeDialog && m_activeDialog->isTalking();
00200 }
00201 

Generated on Wed Jun 1 09:54:30 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2