Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/world_entities/weapons/weapon.cc @ 5701

Last change on this file since 5701 was 5671, checked in by bensch, 19 years ago

orxonox/trunk: renamed class LoadParam to CLoadParam and Macro LoadParamNew to LoadParam

File size: 19.4 KB
RevLine 
[3573]1
[4597]2/*
[3573]3   orxonox - the future of 3D-vertical-scrollers
4
5   Copyright (C) 2004 orx
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
[4826]12### File Specific
[3573]13   main-programmer: Patrick Boenzli
[4832]14   co-programmer: Benjamin Grauer
[4885]15
16   2005-07-15: Benjamin Grauer: restructurating the entire Class
[3573]17*/
18
[4885]19#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
20
[4828]21#include "weapon.h"
22
[5355]23#include "fast_factory.h"
[4834]24#include "projectile.h"
25
[5143]26#include "resource_manager.h"
[4894]27#include "class_list.h"
[4834]28#include "load_param.h"
[4828]29#include "state.h"
[4948]30#include "sound_engine.h"
[4885]31#include "animation3d.h"
[4948]32#include "vector.h"
[3573]33
[4892]34////////////////////
35// INITAILISATION //
36// SETTING VALUES //
37////////////////////
[3870]38/**
[4885]39 * standard constructor
40 *
41 * creates a new weapon
[3575]42*/
[4955]43Weapon::Weapon (WeaponManager* weaponManager)
[3620]44{
[4885]45  this->init();
[4955]46  this->setWeaponManager(weaponManager);
[3620]47}
[3573]48
[3575]49/**
[4885]50 * standard deconstructor
[3575]51*/
[4597]52Weapon::~Weapon ()
[3573]53{
[4885]54  for (int i = 0; i < WS_STATE_COUNT; i++)
[4894]55    if (this->animation[i] && ClassList::exists(animation[i], CL_ANIMATION))  //!< @todo this should check animation3D
[4885]56      delete this->animation[i];
57  for (int i = 0; i < WA_ACTION_COUNT; i++)
[5302]58    if (this->soundBuffers[i] != NULL && ClassList::exists(this->soundBuffers[i], CL_SOUND_BUFFER))
[4885]59      ResourceManager::getInstance()->unload(this->soundBuffers[i]);
[4959]60
61  if (ClassList::exists(this->soundSource, CL_SOUND_SOURCE))
62    delete this->soundSource;
[4885]63}
[4597]64
[4885]65/**
66 * initializes the Weapon with ALL default values
[5498]67 *
68 * This Sets the default values of the Weapon
[4885]69 */
70void Weapon::init()
71{
[5498]72  this->currentState     = WS_INACTIVE;            //< Normaly the Weapon is Inactive
73  this->requestedAction  = WA_NONE;                //< No action is requested by default
74  this->stateDuration    = 0.0;                    //< All the States have zero duration
75  for (int i = 0; i < WS_STATE_COUNT; i++)         //< Every State has:
[4885]76    {
[5498]77      this->times[i] = 0.0;                        //< An infinitesimal duration
78      this->animation[i] = NULL;                   //< No animation
[4885]79    }
80  for (int i = 0; i < WA_ACTION_COUNT; i++)
[5498]81    this->soundBuffers[i] = NULL;                  //< No Sounds
[3888]82
[5498]83  this->soundSource = new SoundSource(this);       //< Every Weapon has exacty one SoundSource.
84  this->emissionPoint.setParent(this);             //< One EmissionPoint, that is a PNode connected to the weapon. You can set this to the exitting point of the Projectiles
[4885]85
[5498]86  this->projectile = CL_NULL;                      //< No Projectile Class is Connected to this weapon
87  this->projectileFactory = NULL;                  //< No Factory generating Projectiles is selected.
[4885]88
[5498]89  this->hideInactive = true;                       //< The Weapon will be hidden if it is inactive (by default)
[4906]90
[5498]91  this->minCharge = 1.0;                           //< The minimum charge the Weapon can hold is 1 unit.
92  this->maxCharge = 1.0;                           //< The maximum charge is also one unit.
[4927]93
[5498]94  this->energyLoaded = .0;                         //< How much energy is loaded in the Gun. (Weapons must be charged befor usage)
95  this->energyLoadedMax = 5.0;                     //< Each Weapon has a Maximum energy that can be charged onto it
96  this->energy = .0;                               //< The secondary Buffer (before we have to reload)
97  this->energyMax = 10.0;                          //< How much energy can be carried
98  this->capability = WTYPE_ALL;                    //< The Weapon has all capabilities @see W_Capability.
[4955]99
[5498]100  this->setWeaponManager(NULL);                    //< By default the Weapon is free, and unhandled by a WeaponManager (this is good for small enemies).
[3573]101}
102
[5498]103/**
104 * loads the Parameters of a Weapon
105 * @param root the XML-Element to load the Weapons settings from
106 */
[4972]107void Weapon::loadParams(const TiXmlElement* root)
108{
109  static_cast<WorldEntity*>(this)->loadParams(root);
110
[5671]111  LoadParam(root, "projectile", this, Weapon, setProjectileType)
[4972]112      .describe("Sets the name of the Projectile to load onto the Entity");
113
[5671]114  LoadParam(root, "emission-point", this, Weapon, setEmissionPoint)
[4972]115      .describe("Sets the Point of emission of this weapon");
116
[5671]117  LoadParam(root, "state-duration", this, Weapon, setStateDuration)
[4972]118      .describe("Sets the duration of a given state (1: state-Name; 2: duration in seconds)");
119
[5671]120  LoadParam(root, "action-sound", this, Weapon, setActionSound)
[4972]121      .describe("Sets a given sound to an action (1: action-Name; 2: name of the sound (relative to the Data-Path))");
122}
123
[4947]124/**
125 * sets the Projectile to use for this weapon.
126 * @param projectile The ID of the Projectile to use
[4950]127 * @returns true, if it was sucessfull, false on error
[4947]128 *
[5498]129 * be aware, that this function does not create Factories, as this is job of Projecitle/Bullet-classes.
130 * What it does, is telling the Weapon what Projectiles it can Emit.
[4947]131 */
[5356]132void Weapon::setProjectileType(ClassID projectile)
[4947]133{
134  if (projectile == CL_NULL)
[4972]135    return;
[4947]136  this->projectile = projectile;
137  this->projectileFactory = FastFactory::searchFastFactory(projectile);
138  if (this->projectileFactory == NULL)
[4979]139  {
140    PRINTF(1)("unable to find FastFactory for the Projectile.\n");
[4972]141    return;
[4979]142  }
[4948]143  else
144  {
145    // grabbing Parameters from the Projectile to have them at hand here.
146    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
147    this->minCharge = pj->getEnergyMin();
148    this->maxCharge = pj->getEnergyMax();
149    this->chargeable = pj->isChageable();
[4979]150    this->projectileFactory->kill(pj);
[4948]151  }
[4979]152}
[3573]153
[4891]154/**
[4950]155 * @see bool Weapon::setProjectile(ClassID projectile)
156 * @param projectile the Name of the Projectile.
157 */
[5356]158void Weapon::setProjectileType(const char* projectile)
[4950]159{
160  if (projectile == NULL)
[4972]161    return;
[4950]162  FastFactory* tmpFac = FastFactory::searchFastFactory(projectile);
163  if (tmpFac != NULL)
164  {
[5356]165    this->setProjectileType(tmpFac->getStoredID());
[4950]166  }
[4972]167  else
168  {
[5356]169    PRINTF(1)("Projectile %s does not exist for weapon %s\n", projectile, this->getName());
[4972]170  }
[4950]171}
172
173/**
[5356]174 * prepares Projectiles of the Weapon
[5498]175 * @param count how many Projectiles to create (they will be stored in the ProjectileFactory)
[5356]176 */
177void Weapon::prepareProjectiles(unsigned int count)
178{
[5357]179  if (likely(this->projectileFactory != NULL))
[5356]180    projectileFactory->prepare(count);
181  else
[5357]182    PRINTF(2)("unable to create %d projectile for Weapon %s (%s)\n", count, this->getName(), this->getClassName());
[5356]183}
184
185/**
186 * resurects and returns a Projectile
[5498]187 * @returns a Projectile on success, NULL on error
188 *
189 * errors: 1. (ProjectileFastFactory not Found)
190 *         2. No more Projectiles availiable.
[5356]191 */
192Projectile* Weapon::getProjectile()
193{
[5357]194  if (likely (this->projectileFactory != NULL))
[5356]195    return dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
196  else
197  {
[5498]198    PRINTF(2)("No projectile defined for Weapon %s(%s) can't return any\n", this->getName(), this->getClassName());
[5356]199    return NULL;
200  }
201}
202
203
204/**
[4892]205 * sets the emissionPoint's relative position from the Weapon
206 * @param point the Point relative to the mass-point of the Weapon
207 */
208void Weapon::setEmissionPoint(const Vector& point)
209{
210  this->emissionPoint.setRelCoor(point);
211}
212
213/**
[4891]214 * assigns a Sound-file to an action
215 * @param action the action the sound should be assigned too
216 * @param soundFile the soundFile's relative position to the data-directory (will be looked for by the ResourceManager)
217 */
[4885]218void Weapon::setActionSound(WeaponAction action, const char* soundFile)
219{
220  if (action >= WA_ACTION_COUNT)
221    return;
[4930]222  if (this->soundBuffers[action] != NULL)
223    ResourceManager::getInstance()->unload(this->soundBuffers[action]);
224
[4885]225  else if (soundFile != NULL)
226  {
227    this->soundBuffers[action] = (SoundBuffer*)ResourceManager::getInstance()->load(soundFile, WAV);
228    if (this->soundBuffers[action] != NULL)
229    {
[4967]230      PRINTF(4)("Loaded sound %s to action %s.\n", soundFile, actionToChar(action));
[4885]231    }
232    else
233    {
[5041]234      PRINTF(2)("Failed to load sound %s to %s.\n.", soundFile, actionToChar(action));
[4885]235    }
236  }
237  else
238    this->soundBuffers[action] = NULL;
239}
240
[4893]241/**
[4895]242 * creates/returns an Animation3D for a certain State.
243 * @param state what State should the Animation be created/returned for
244 * @param node the node this Animation should apply to. (NULL is fine if the animation was already created)
245 * @returns The created animation.Animation(), NULL on error (or if the animation does not yet exist).
[4893]246 *
247 * This function does only generate the Animation Object, and if set it will
248 * automatically be executed, when a certain State is reached.
249 * What this does not do, is set keyframes, you have to operate on the returned animation.
250 */
[4895]251Animation3D* Weapon::getAnimation(WeaponState state, PNode* node)
[4893]252{
[4895]253  if (state >= WS_STATE_COUNT) // if the state is not known
[4893]254    return NULL;
255
[4895]256  if (unlikely(this->animation[state] == NULL)) // if the animation does not exist yet create it.
[4893]257  {
[4895]258    if (likely(node != NULL))
259      return this->animation[state] = new Animation3D(node);
260    else
261    {
262      PRINTF(2)("Node not defined for the Creation of the 3D-animation of state %s\n", stateToChar(state));
263      return NULL;
264    }
[4893]265  }
[4895]266  else
267    return this->animation[state];
[4893]268}
269
[4892]270/////////////////
271//  EXECUTION  //
272// GAME ACTION //
273/////////////////
[4597]274/**
[4885]275 * request an action that should be executed,
276 * @param action the next action to take
277 *
278 * This function must be called instead of the actions (like fire/reload...)
279 * to make all the checks needed to have a usefull WeaponSystem.
280 */
281void Weapon::requestAction(WeaponAction action)
282{
[4906]283  if (likely(this->isActive()))
[4885]284  {
[4906]285    if (this->requestedAction != WA_NONE)
286      return;
[5041]287    PRINTF(5)("next action will be %s in %f seconds\n", actionToChar(action), this->stateDuration);
[4885]288    this->requestedAction = action;
289  }
[4906]290  //else
291  else if (unlikely(action == WA_ACTIVATE))
292  {
293    this->currentState = WS_ACTIVATING;
[4926]294    this->requestedAction = WA_ACTIVATE;
[4906]295  }
[4885]296}
[3577]297
[4890]298/**
299 * adds energy to the Weapon
300 * @param energyToAdd The amount of energy
301 * @returns the amount of energy we did not pick up, because the weapon is already full
302 */
303float Weapon::increaseEnergy(float energyToAdd)
304{
305  float maxAddEnergy = this->energyMax - this->energy;
306
307  if (maxAddEnergy >= energyToAdd)
308  {
309    this->energy += energyToAdd;
310    return 0.0;
311  }
312  else
313  {
314    this->energy += maxAddEnergy;
315    return energyToAdd - maxAddEnergy;
316  }
317}
318
[5498]319////////////////////////////////////////////////////////////
320// WEAPON INTERNALS                                       //
321// These are functions, that no other Weapon should over- //
322// write. No class has direct Access to them, as it is    //
323// quite a complicated process, handling a Weapon from    //
324// the outside                                            //
325////////////////////////////////////////////////////////////
[4891]326/**
327 * executes an action, and with it starts a new State.
328 * @return true, if it worked, false otherwise
329 *
330 * This function checks, wheter the possibility of executing an action is valid,
331 * and does all the necessary stuff, to execute them. If an action does not succeed,
332 * it tries to go around it. (ex. shoot->noAmo->reload()->wait until shoot comes again)
333 */
[4885]334bool Weapon::execute()
[3583]335{
[4906]336#if DEBUG > 4
[4885]337  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
338  this->debug();
[4906]339#endif
[4885]340
[4926]341  WeaponAction action = this->requestedAction;
342  this->requestedAction = WA_NONE;
343
344  switch (action)
[4885]345  {
346    case WA_SHOOT:
[4894]347      return this->fireW();
[4885]348      break;
349    case WA_CHARGE:
[4894]350      return this->chargeW();
[4885]351      break;
352    case WA_RELOAD:
[4894]353      return this->reloadW();
[4885]354      break;
355    case WA_DEACTIVATE:
[4894]356      return this->deactivateW();
[4885]357      break;
358    case WA_ACTIVATE:
[4894]359      return this->activateW();
[4885]360      break;
361  }
[3583]362}
[3577]363
[4597]364/**
[4894]365 * checks and activates the Weapon.
366 * @return true on success.
[4892]367 */
368bool Weapon::activateW()
[3583]369{
[4926]370//  if (this->currentState == WS_INACTIVE)
[4892]371  {
372        // play Sound
[4893]373    if (likely(this->soundBuffers[WA_ACTIVATE] != NULL))
[4892]374      this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
375        // activate
[4895]376    PRINTF(4)("Activating the Weapon %s\n", this->getName());
[4892]377    this->activate();
[4895]378    // setting up for next action
[4926]379    this->enterState(WS_ACTIVATING);
[4892]380  }
[3583]381}
[3577]382
[4597]383/**
[4894]384 * checks and deactivates the Weapon
385 * @return true on success.
[4892]386 */
387bool Weapon::deactivateW()
[3583]388{
[4949]389//  if (this->currentState != WS_INACTIVE)
[4892]390  {
391    PRINTF(4)("Deactivating the Weapon %s\n", this->getName());
392        // play Sound
393    if (this->soundBuffers[WA_DEACTIVATE] != NULL)
394      this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
[4926]395    // deactivate
[4892]396    this->deactivate();
[4926]397    this->enterState(WS_DEACTIVATING);
[4892]398  }
[3583]399}
[3577]400
[4892]401/**
[4894]402 * checks and charges the Weapon
403 * @return true on success.
[4892]404 */
405bool Weapon::chargeW()
[4885]406{
[4892]407  if ( this->currentState != WS_INACTIVE && this->energyLoaded >= this->minCharge)
408  {
409        // playing Sound
410    if (this->soundBuffers[WA_CHARGE] != NULL)
411      this->soundSource->play(this->soundBuffers[WA_CHARGE]);
[4893]412
[4892]413        // charge
414    this->charge();
415        // setting up for the next state
[4926]416    this->enterState(WS_CHARGING);
[4892]417  }
418  else // deactivate the Weapon if we do not have enough energy
419  {
420    this->requestAction(WA_RELOAD);
421  }
[4885]422}
[3573]423
[4892]424/**
[4894]425 * checks and fires the Weapon
426 * @return true on success.
[4892]427 */
428bool Weapon::fireW()
[3575]429{
[4892]430     //if (likely(this->currentState != WS_INACTIVE))
431  if (this->minCharge <= this->energyLoaded)
432  {
433          // playing Sound
434    if (this->soundBuffers[WA_SHOOT] != NULL)
435      this->soundSource->play(this->soundBuffers[WA_SHOOT]);
436          // fire
437    this->fire();
438    this->energyLoaded -= this->minCharge;
439          // setting up for the next state
[4926]440    this->enterState(WS_SHOOTING);
[4892]441  }
442  else  // reload if we still have the charge
443  {
444    this->requestAction(WA_RELOAD);
[4930]445    this->execute();
[4892]446  }
447}
448
449/**
[4894]450 * checks and Reloads the Weapon
451 * @return true on success.
[4892]452 */
453bool Weapon::reloadW()
454{
[4885]455  PRINTF(4)("Reloading Weapon %s\n", this->getName());
[4892]456  if (unlikely(this->energy + this->energyLoaded < this->minCharge))
[4885]457  {
458    this->requestAction(WA_DEACTIVATE);
[4930]459    this->execute();
[4892]460    return false;
[4885]461  }
[3573]462
[4885]463  float chargeSize = this->energyLoadedMax - this->energyLoaded;       //!< The energy to be charged
[3573]464
[4892]465  if (this->soundBuffers[WA_RELOAD] != NULL)
466    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
467
[4885]468  if (chargeSize > this->energy)
469  {
470    this->energyLoaded += this->energy;
471    this->energy = 0.0;
[5041]472    PRINT(5)("Energy depleted\n");
[4885]473  }
474  else
475  {
[5041]476    PRINTF(5)("Loaded %f energy into the Guns Buffer\n", chargeSize);
[4885]477    this->energyLoaded += chargeSize;
478    this->energy -= chargeSize;
479  }
[4892]480  this->reload();
[4926]481  this->enterState(WS_RELOADING);
482}
[3575]483
[4926]484/**
485 * enters the requested State, plays back animations updates the timing.
486 * @param state the state to enter.
487 */
488inline void Weapon::enterState(WeaponState state)
489{
[5041]490  PRINTF(4)("ENTERING STATE %s\n", stateToChar(state));
[4926]491  // playing animation if availiable
492  if (likely(this->animation[state] != NULL))
493    this->animation[state]->replay();
494
495  this->stateDuration = this->times[state] + this->stateDuration;
496  this->currentState = state;
[3575]497}
498
[4927]499///////////////////
500//  WORLD-ENTITY //
501// FUNCTIONALITY //
502///////////////////
[3575]503/**
[4885]504 * tick signal for time dependent/driven stuff
[3575]505*/
[4906]506void Weapon::tickW(float dt)
[4885]507{
[4934]508  //printf("%s ", stateToChar(this->currentState));
[4910]509
[4885]510  // setting up the timing properties
511  this->stateDuration -= dt;
[3575]512
[4949]513  if (this->stateDuration <= 0.0)
[4885]514  {
[4949]515    if (unlikely (this->currentState == WS_DEACTIVATING))
[4885]516    {
[4949]517      this->currentState = WS_INACTIVE;
518      return;
519    }
520    else
521      this->currentState = WS_IDLE;
[4906]522
[4949]523    if (this->requestedAction != WA_NONE)
524    {
525      this->stateDuration = -dt;
526      this->execute();
[4885]527    }
528  }
[4906]529  tick(dt);
[4885]530}
531
[3575]532/**
[4885]533 *  this will draw the weapon
[3575]534*/
[5500]535void Weapon::draw () const
[3575]536{}
537
538
539
540
[3576]541
[4885]542//////////////////////
543// HELPER FUNCTIONS //
544//////////////////////
[3576]545/**
[4891]546 * checks wether all the Weapons functions are valid, and if it is possible to go to action with it.
[5498]547 * @todo IMPLEMENT the Weapons Check
[4891]548 */
549bool Weapon::check() const
550{
551  bool retVal = true;
552
[4947]553//  if (this->projectile == NULL)
[4891]554  {
[5041]555    PRINTF(1)("There was no projectile assigned to the Weapon.\n");
[4891]556    retVal = false;
557  }
558
559
560
561
562  return retVal;
563}
564
565/**
[4885]566 * some nice debugging information about this Weapon
567 */
568void Weapon::debug() const
569{
[5041]570  PRINT(3)("Weapon-Debug %s, state: %s, nextAction: %s\n", this->getName(), Weapon::stateToChar(this->currentState), Weapon::actionToChar(requestedAction));
[4885]571  PRINT(3)("Energy: max: %f; current: %f;  loadedMax: %f; loadedCurrent: %f; chargeMin: %f, chargeMax %f\n",
572            this->energyMax, this->energy, this->energyLoadedMax, this->energyLoaded, this->minCharge, this->maxCharge);
[4967]573
574
[4885]575}
[3575]576
[5498]577////////////////////////////////////////////////////////
578// static Definitions (transormators for readability) //
579////////////////////////////////////////////////////////
[4885]580/**
581 * Converts a String into an Action.
582 * @param action the String input holding the Action.
583 * @return The Action if known, WA_NONE otherwise.
584 */
585WeaponAction Weapon::charToAction(const char* action)
586{
587  if (!strcmp(action, "none"))
588    return WA_NONE;
589  else if (!strcmp(action, "shoot"))
590    return WA_SHOOT;
591  else if (!strcmp(action, "charge"))
592    return WA_CHARGE;
593  else if (!strcmp(action, "reload"))
594    return WA_RELOAD;
595  else if (!strcmp(action, "acitvate"))
596    return WA_ACTIVATE;
597  else if (!strcmp(action, "deactivate"))
598    return WA_DEACTIVATE;
599  else if (!strcmp(action, "special1"))
600    return WA_SPECIAL1;
601  else
602    {
603      PRINTF(2)("action %s could not be identified.\n", action);
604      return WA_NONE;
605    }
606}
[3575]607
608/**
[4885]609 * converts an action into a String
610 * @param action the action to convert
611 * @return a String matching the name of the action
612 */
613const char* Weapon::actionToChar(WeaponAction action)
614{
615  switch (action)
616  {
617    case WA_SHOOT:
618      return "shoot";
619      break;
620    case WA_CHARGE:
621      return "charge";
622      break;
623    case WA_RELOAD:
624      return "reload";
625      break;
626    case WA_ACTIVATE:
627      return "activate";
628      break;
629    case WA_DEACTIVATE:
630      return "deactivate";
631      break;
632    case WA_SPECIAL1:
633      return "special1";
634      break;
635    default:
636      return "none";
637      break;
638  }
639}
[3577]640
641/**
[4885]642 * Converts a String into a State.
643 * @param state the String input holding the State.
644 * @return The State if known, WS_NONE otherwise.
645 */
646WeaponState Weapon::charToState(const char* state)
647{
648  if (!strcmp(state, "none"))
649    return WS_NONE;
650  else if (!strcmp(state, "shooting"))
651    return WS_SHOOTING;
652  else if (!strcmp(state, "charging"))
653    return WS_CHARGING;
654  else if (!strcmp(state, "reloading"))
655    return WS_RELOADING;
656  else if (!strcmp(state, "activating"))
657    return WS_ACTIVATING;
658  else if (!strcmp(state, "deactivating"))
659    return WS_DEACTIVATING;
660  else if (!strcmp(state, "inactive"))
661    return WS_INACTIVE;
662  else if (!strcmp(state, "idle"))
663    return WS_IDLE;
664  else
665    {
666      PRINTF(2)("state %s could not be identified.\n", state);
667      return WS_NONE;
668    }
669}
[3583]670
671/**
[4885]672 * converts a State into a String
673 * @param state the state to convert
674 * @return a String matching the name of the state
675 */
676const char* Weapon::stateToChar(WeaponState state)
677{
678  switch (state)
679  {
680    case WS_SHOOTING:
681      return "shooting";
682      break;
683    case WS_CHARGING:
684      return "charging";
685      break;
686    case WS_RELOADING:
687      return "reloading";
688      break;
689    case WS_ACTIVATING:
690      return "activating";
691      break;
692    case WS_DEACTIVATING:
693      return "deactivating";
694      break;
695    case WS_IDLE:
696      return "idle";
697      break;
[4906]698    case WS_INACTIVE:
699      return "inactive";
700      break;
[4885]701    default:
702      return "none";
703      break;
704  }
705}
Note: See TracBrowser for help on using the repository browser.