Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/core/CommandExecutor.cc @ 2736

Last change on this file since 2736 was 2485, checked in by landauf, 16 years ago

Merged objecthierarchy2 into presentation branch

Couln't merge 2 lines in Gamestate.cc and a whole block of code in GSDedicated.cc (it seems like oli implemented in both branches something like a network-tick-limiter but with different approaches)

Not yet tested in network mode and with bots
The SpaceShips movement is also not yet fully adopted to the new physics (see Engine class)

  • Property svn:eol-style set to native
File size: 30.1 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "CommandExecutor.h"
30#include "ConsoleCommand.h"
31#include "util/String.h"
32#include "util/Debug.h"
33#include "Identifier.h"
34#include "Language.h"
35#include "TclBind.h"
36
37namespace orxonox
38{
39    CommandExecutor& CommandExecutor::getInstance()
40    {
41        static CommandExecutor instance;
42        return instance;
43    }
44
45    CommandEvaluation& CommandExecutor::getEvaluation()
46    {
47        return CommandExecutor::getInstance().evaluation_;
48    }
49
50    const CommandEvaluation& CommandExecutor::getLastEvaluation()
51    {
52        return CommandExecutor::getInstance().evaluation_;
53    }
54
55    ConsoleCommand& CommandExecutor::addConsoleCommandShortcut(ConsoleCommand* command, bool bDeleteAtExit)
56    {
57        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(command->getName());
58        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
59        {
60            COUT(2) << "Warning: Overwriting console-command shortcut with name " << command->getName() << "." << std::endl;
61        }
62
63        // Make sure we can also delete the external ConsoleCommands that don't belong to an Identifier
64        if (command && bDeleteAtExit)
65        {
66            CommandExecutor::getInstance().consoleCommandExternals_.insert(command);
67        }
68
69        CommandExecutor::getInstance().consoleCommandShortcuts_[command->getName()] = command;
70        CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(command->getName())] = command;
71        return (*command);
72    }
73
74    /**
75        @brief Returns the executor of a console command shortcut with given name.
76        @brief name The name of the requested console command shortcut
77        @return The executor of the requested console command shortcut
78    */
79    ConsoleCommand* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
80    {
81        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
82        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
83            return (*it).second;
84        else
85            return 0;
86    }
87
88    /**
89        @brief Returns the executor of a console command shortcut with given name in lowercase.
90        @brief name The name of the requested console command shortcut in lowercase
91        @return The executor of the requested console command shortcut
92    */
93    ConsoleCommand* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
94    {
95        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
96        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end())
97            return (*it).second;
98        else
99            return 0;
100    }
101
102    bool CommandExecutor::execute(const std::string& command, bool useTcl)
103    {
104        if (useTcl)
105            return TclBind::eval(command);
106
107        CommandExecutor::parseIfNeeded(command);
108        return CommandExecutor::getEvaluation().execute();
109    }
110
111    std::string CommandExecutor::complete(const std::string& command)
112    {
113        CommandExecutor::parseIfNeeded(command);
114        return CommandExecutor::getEvaluation().complete();
115    }
116
117    std::string CommandExecutor::hint(const std::string& command)
118    {
119        CommandExecutor::parseIfNeeded(command);
120        return CommandExecutor::getEvaluation().hint();
121    }
122
123    CommandEvaluation CommandExecutor::evaluate(const std::string& command)
124    {
125        CommandExecutor::parse(command);
126        CommandExecutor::getEvaluation().evaluateParams();
127        return CommandExecutor::getEvaluation();
128    }
129
130    void CommandExecutor::parseIfNeeded(const std::string& command)
131    {
132        if (CommandExecutor::getEvaluation().state_ == CS_Uninitialized)
133        {
134            CommandExecutor::parse(command);
135        }
136        else if (CommandExecutor::getEvaluation().originalCommand_ != command)
137        {
138            if (CommandExecutor::getEvaluation().command_ == command)
139            {
140                CommandExecutor::parse(command);
141                CommandExecutor::getEvaluation().bNewCommand_ = false;
142            }
143            else
144            {
145                CommandExecutor::parse(command);
146            }
147        }
148    }
149
150    void CommandExecutor::parse(const std::string& command, bool bInitialize)
151    {
152        if (bInitialize)
153            CommandExecutor::getEvaluation().initialize(command);
154
155        CommandExecutor::getEvaluation().commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
156        CommandExecutor::getEvaluation().command_ = command;
157
158        switch (CommandExecutor::getEvaluation().state_)
159        {
160            case CS_Uninitialized:
161            {
162                // Impossible
163                break;
164            }
165            case CS_Empty:
166            {
167                if (CommandExecutor::argumentsGiven() == 0)
168                {
169                    CommandExecutor::createListOfPossibleFunctions("");
170                    CommandExecutor::createListOfPossibleIdentifiers("");
171                    break;
172                }
173                else
174                {
175                    CommandExecutor::getEvaluation().state_ = CS_ShortcutOrIdentifier;
176                    // Move on to next case
177                }
178            }
179            case CS_ShortcutOrIdentifier:
180            {
181                if (CommandExecutor::argumentsGiven() > 1)
182                {
183                    // There's a finished first argument - check if it's a shortcut or a classname
184                    CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
185                    CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
186
187                    if (CommandExecutor::getEvaluation().function_)
188                    {
189                        // It's a shortcut
190                        CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
191                        CommandExecutor::getEvaluation().functionclass_ = 0;
192                        // Move on to next case
193                    }
194                    else if (CommandExecutor::getEvaluation().functionclass_)
195                    {
196                        // It's a functionname
197                        CommandExecutor::getEvaluation().state_ = CS_Function;
198                        CommandExecutor::getEvaluation().function_ = 0;
199                        // Move on to next case
200                    }
201                    else
202                    {
203                        // The first argument is bad
204                        CommandExecutor::getEvaluation().state_ = CS_Error;
205                        AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname");
206                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + " " + GetLocalisation("commandexecutorunknownfirstargument") + ".";
207                        return;
208                    }
209                }
210                else
211                {
212                    // There's no finished first argument - search possible shortcuts or classnames
213                    CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(0));
214                    CommandExecutor::createListOfPossibleIdentifiers(CommandExecutor::getArgument(0));
215
216                    unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
217                    unsigned int num_identifiers = CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.size();
218
219                    if (num_functions == 1 && num_identifiers == 0)
220                    {
221                        // It's a shortcut
222                        std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
223                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname);
224                        if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(0)))
225                        {
226                            // Unfinished shortcut
227                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
228                        }
229                        CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
230                        CommandExecutor::getEvaluation().functionclass_ = 0;
231                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName();
232                        if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
233                        {
234                            CommandExecutor::getEvaluation().command_ += " ";
235                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
236                        }
237                        // Move on to next case
238                    }
239                    else if (num_identifiers == 1 && num_functions == 0)
240                    {
241                        // It's a classname
242                        std::string classname = *(*CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()).first;
243                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(classname);
244                        if (getLowercase(classname) != getLowercase(CommandExecutor::getArgument(0)))
245                        {
246                            // Unfinished classname
247                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
248                        }
249                        CommandExecutor::getEvaluation().state_ = CS_Function;
250                        CommandExecutor::getEvaluation().function_ = 0;
251                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " ";
252                        // Move on to next case
253                    }
254                    else if (num_identifiers == 0 && num_functions == 0)
255                    {
256                        // No possibilities
257                        CommandExecutor::getEvaluation().state_ = CS_Error;
258                        AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with");
259                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + " " + CommandExecutor::getArgument(0) + ".";
260                        return;
261                    }
262                    else
263                    {
264                        // There are several possiblilities
265                        std::list<std::pair<const std::string*, const std::string*> > temp;
266                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.end());
267                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.end());
268                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getCommonBegin(temp);
269                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
270                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
271                        CommandExecutor::getEvaluation().bCommandChanged_ = true;
272                        return;
273                    }
274                }
275            }
276            case CS_Function:
277            {
278                if (CommandExecutor::getEvaluation().functionclass_)
279                {
280                    // There is a classname - search for the commandname
281                    if (CommandExecutor::argumentsGiven() > 2)
282                    {
283                        // There is a finished second argument - check if it's a commandname
284                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
285
286                        if (CommandExecutor::getEvaluation().function_)
287                        {
288                            // It's a function
289                            CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
290                            // Move on to next case
291                        }
292                        else
293                        {
294                            // The second argument is bad
295                            CommandExecutor::getEvaluation().state_ = CS_Error;
296                            AddLanguageEntry("commandexecutorunknownsecondargument", "is not a function of");
297                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(1) + " " + GetLocalisation("commandexecutorunknownsecondargument") + " " + CommandExecutor::getEvaluation().functionclass_->getName() + ".";
298                            return;
299                        }
300                    }
301                    else
302                    {
303                        // There is no finished second argument - search for possibilities
304                        CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
305                        unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
306
307                        if (num_functions == 1)
308                        {
309                            // It's a function
310                            std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
311                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname, CommandExecutor::getEvaluation().functionclass_);
312                            if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(1)))
313                            {
314                                // Unfinished function
315                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
316                            }
317                            CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
318                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getEvaluation().function_->getName();
319                            if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
320                            {
321                                CommandExecutor::getEvaluation().command_ += " ";
322                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
323                            }
324                            // Move on to next case
325                        }
326                        else if (num_functions == 0)
327                        {
328                            // No possibilities
329                            CommandExecutor::getEvaluation().state_ = CS_Error;
330                            AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with");
331                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + " " + GetLocalisation("commandexecutorunknownsecondargumentstart") + " " + CommandExecutor::getArgument(1) + ".";
332                            return;
333                        }
334                        else
335                        {
336                            // There are several possibilities
337                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_);
338                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
339                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
340                            return;
341                        }
342                    }
343                }
344                else
345                {
346                    // There is no classname - move on to CS_ParamPreparation
347                }
348            }
349            case CS_ParamPreparation:
350            {
351                if (CommandExecutor::getEvaluation().function_->getParamCount() == 0 || CommandExecutor::enoughArgumentsGiven(CommandExecutor::getEvaluation().function_))
352                {
353                    CommandExecutor::getEvaluation().state_ = CS_Finished;
354                    return;
355                }
356                else
357                {
358                    unsigned int argumentNumber = CommandExecutor::argumentsGiven() - 2;
359                    if (CommandExecutor::getEvaluation().functionclass_)
360                        argumentNumber -= 1;
361
362                    CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
363                    CommandExecutor::getEvaluation().state_ = CS_Params;
364
365                    if (CommandExecutor::getEvaluation().bCommandChanged_)
366                    {
367                        // Don't do more than one change
368                        return;
369                    }
370                }
371            }
372            case CS_Params:
373            {
374                if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1)
375                {
376                    // There is exactly one possible argument
377                    CommandExecutor::getEvaluation().argument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
378                    CommandExecutor::getEvaluation().possibleArgument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
379                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
380                    return;
381                }
382                else if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 0)
383                {
384                    // The user tries something new - we let him do
385                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
386                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument();
387                    return;
388                }
389                else
390                {
391                    // There are several possibilities
392                    unsigned int argumentNumber = CommandExecutor::argumentsGiven();
393                    if (argumentNumber > 0)
394                        --argumentNumber;
395                    if (CommandExecutor::getEvaluation().functionclass_ && argumentNumber > 0)
396                        --argumentNumber;
397
398                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_);
399                    CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
400                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
401                    return;
402                }
403            }
404            case CS_Finished:
405            {
406                // Nothing more to do
407                break;
408            }
409            case CS_Error:
410            {
411                // Bad, very bad
412                break;
413            }
414        }
415    }
416
417    unsigned int CommandExecutor::argumentsFinished()
418    {
419        unsigned int argumentsGiven = CommandExecutor::argumentsGiven();
420        if (argumentsGiven > 0)
421            return argumentsGiven - 1;
422        else
423            return 0;
424    }
425
426    unsigned int CommandExecutor::argumentsGiven()
427    {
428        if (CommandExecutor::getEvaluation().command_.size() > 0 && CommandExecutor::getEvaluation().command_[CommandExecutor::getEvaluation().command_.size() - 1] == ' ')
429            return CommandExecutor::getEvaluation().commandTokens_.size() + 1;
430        else
431            return CommandExecutor::getEvaluation().commandTokens_.size();
432    }
433
434    bool CommandExecutor::enoughArgumentsGiven(ConsoleCommand* command)
435    {
436        if (CommandExecutor::getEvaluation().functionclass_)
437            return (CommandExecutor::argumentsGiven() > (2 + command->getParamCount()));
438        else
439            return (CommandExecutor::argumentsGiven() > (1 + command->getParamCount()));
440    }
441
442    std::string CommandExecutor::getArgument(unsigned int index)
443    {
444        if (index < (CommandExecutor::getEvaluation().commandTokens_.size()))
445            return CommandExecutor::getEvaluation().commandTokens_[index];
446        else
447            return "";
448    }
449
450    std::string CommandExecutor::getLastArgument()
451    {
452        return CommandExecutor::getArgument(CommandExecutor::argumentsGiven() - 1);
453    }
454
455    void CommandExecutor::createListOfPossibleIdentifiers(const std::string& fragment)
456    {
457        CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.clear();
458        std::string lowercase = getLowercase(fragment);
459        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
460            if ((*it).second->hasConsoleCommands())
461                if ((*it).first.find(lowercase) == 0 || fragment == "")
462                    CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
463    }
464
465    void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
466    {
467        CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear();
468        std::string lowercase = getLowercase(fragment);
469        if (!identifier)
470        {
471            for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
472                if ((*it).first.find(lowercase) == 0 || fragment == "")
473                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
474        }
475        else
476        {
477            for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
478                if ((*it).first.find(lowercase) == 0 || fragment == "")
479                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
480        }
481    }
482
483    void CommandExecutor::createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param)
484    {
485        CommandExecutor::createArgumentCompletionList(command, param);
486
487        CommandExecutor::getEvaluation().listOfPossibleArguments_.clear();
488        std::string lowercase = getLowercase(fragment);
489        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
490        {
491            if ((*it).lowercaseComparison())
492            {
493                if ((*it).getComparable().find(lowercase) == 0 || fragment == "")
494                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
495            }
496            else
497            {
498                if ((*it).getComparable().find(fragment) == 0 || fragment == "")
499                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
500            }
501        }
502    }
503
504    Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name)
505    {
506        std::string lowercase = getLowercase(name);
507        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(lowercase);
508        if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConsoleCommands())
509            return (*it).second;
510
511        return 0;
512    }
513
514    ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier)
515    {
516        std::string lowercase = getLowercase(name);
517        if (!identifier)
518        {
519            std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(lowercase);
520            if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
521                return (*it).second;
522        }
523        else
524        {
525            std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(lowercase);
526            if (it != identifier->getLowercaseConsoleCommandMapEnd())
527                return (*it).second;
528        }
529        return 0;
530    }
531
532    std::string CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
533    {
534        CommandExecutor::createArgumentCompletionList(command, param);
535
536        std::string lowercase = getLowercase(name);
537        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
538        {
539            if ((*it).lowercaseComparison())
540            {
541                if ((*it).getComparable() == lowercase)
542                    return (*it).getString();
543            }
544            else
545            {
546                if ((*it).getComparable() == name)
547                    return (*it).getString();
548            }
549        }
550
551        return "";
552    }
553
554    void CommandExecutor::createArgumentCompletionList(ConsoleCommand* command, unsigned int param)
555    {
556        std::string params[5];
557
558        unsigned int index = 0;
559        unsigned int lowestIndex = 1 + (CommandExecutor::getEvaluation().functionclass_ != 0);
560
561        for (unsigned int i = CommandExecutor::argumentsGiven() - 1; i >= lowestIndex; --i)
562        {
563            params[index] = CommandExecutor::getArgument(i);
564            ++index;
565            if (index >= 5)
566                break;
567        }
568
569        command->createArgumentCompletionList(param, params[0], params[1], params[2], params[3], params[4]);
570    }
571
572    std::string CommandExecutor::getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list)
573    {
574        if (list.size() == 0)
575        {
576            return "";
577        }
578        else if (list.size() == 1)
579        {
580            return ((*(*list.begin()).first) + " ");
581        }
582        else
583        {
584            std::string output = "";
585            for (unsigned int i = 0; true; i++)
586            {
587                char temp = 0;
588                for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
589                {
590                    if ((*(*it).first).size() > i)
591                    {
592                        if (it == list.begin())
593                        {
594                            temp = (*(*it).first)[i];
595                        }
596                        else
597                        {
598                            if (temp != (*(*it).first)[i])
599                                return output;
600                        }
601                    }
602                    else
603                    {
604                        return output;
605                    }
606                }
607                output += temp;
608            }
609            return output;
610        }
611    }
612
613    std::string CommandExecutor::getCommonBegin(const ArgumentCompletionList& list)
614    {
615        if (list.size() == 0)
616        {
617            return "";
618        }
619        else if (list.size() == 1)
620        {
621            return ((*list.begin()).getComparable() + " ");
622        }
623        else
624        {
625            std::string output = "";
626            for (unsigned int i = 0; true; i++)
627            {
628                char temp = 0;
629                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
630                {
631                    std::string argument = (*it).getComparable();
632                    if (argument.size() > i)
633                    {
634                        if (it == list.begin())
635                        {
636                            temp = argument[i];
637                        }
638                        else
639                        {
640                            if (temp != argument[i])
641                                return output;
642                        }
643                    }
644                    else
645                    {
646                        return output;
647                    }
648                }
649                output += temp;
650            }
651            return output;
652        }
653    }
654
655    void CommandExecutor::destroyExternalCommands()
656    {
657        for (std::set<ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandExternals_.begin();
658            it != CommandExecutor::getInstance().consoleCommandExternals_.end(); ++it)
659            delete *it;
660    }
661}
Note: See TracBrowser for help on using the repository browser.