Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 10, 2008, 1:37:36 AM (16 years ago)
Author:
rgrieder
Message:

merged gui back to trunk.
update the media repository!

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/core/input/Button.cc

    r1747 r1755  
    2828
    2929/**
    30  @file
    31  @brief Implementation of the different input handlers.
    32  */
     30@file
     31@brief
     32    Implementation of the different input handlers.
     33*/
    3334
    3435#include "Button.h"
     
    4445namespace orxonox
    4546{
    46   void Button::clear()
    47   {
    48     for (unsigned int j = 0; j < 3; j++)
    49     {
    50       if (nCommands_[j])
    51       {
    52         // delete all commands and the command pointer array
    53         for (unsigned int i = 0; i < nCommands_[j]; i++)
    54           delete commands_[j][i];
    55         delete[] commands_[j];
    56         commands_[j] = 0;
    57         nCommands_[j] = 0;
    58       }
    59       else
    60       {
    61         commands_[j] = 0;
    62       }
    63     }
    64   }
    65 
    66   void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
    67   {
    68     if (isEmpty(bindingString_))
    69     {
    70       clear();
    71       return;
    72     }
    73 
    74     // use std::vector for a temporary dynamic array
    75     std::vector<BaseCommand*> commands[3];
    76 
    77 
    78     // separate the commands
    79     SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
    80         '\\', false, '"', false, '(', ')', false, '\0');
    81 
    82     for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
    83     {
    84       if (commandStrings[iCommand] != "")
    85       {
    86         SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
     47    void Button::clear()
     48    {
     49        for (unsigned int j = 0; j < 3; j++)
     50        {
     51            if (nCommands_[j])
     52            {
     53                // delete all commands and the command pointer array
     54                for (unsigned int i = 0; i < nCommands_[j]; i++)
     55                    delete commands_[j][i];
     56                delete[] commands_[j];
     57                commands_[j] = 0;
     58                nCommands_[j] = 0;
     59            }
     60            else
     61            {
     62                commands_[j] = 0;
     63            }
     64        }
     65    }
     66
     67    void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
     68    {
     69        if (isEmpty(bindingString_))
     70        {
     71            clear();
     72            return;
     73        }
     74
     75        // use std::vector for a temporary dynamic array
     76        std::vector<BaseCommand*> commands[3];
     77
     78
     79        // separate the commands
     80        SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
    8781            '\\', false, '"', false, '(', ')', false, '\0');
    8882
    89         unsigned int iToken = 0;
    90 
    91         // for real axes, we can feed a ButtonThreshold argument as entire command
    92         if (getLowercase(tokens[0]) == "buttonthreshold")
    93         {
    94           if (tokens.size() == 1)
    95             continue;
    96           // may fail, but doesn't matter
    97           convertValue(&buttonThreshold_, tokens[1]);
    98           continue;
    99         }
    100 
    101         // first argument can be OnPress, OnHold OnRelease or nothing
    102         KeybindMode::Enum mode = KeybindMode::None;
    103         if (getLowercase(tokens[iToken]) == "onpress")
    104           mode = KeybindMode::OnPress,   iToken++;
    105         if (getLowercase(tokens[iToken]) == "onrelease")
    106           mode = KeybindMode::OnRelease, iToken++;
    107         if (getLowercase(tokens[iToken]) == "onhold")
    108           mode = KeybindMode::OnHold,    iToken++;
    109 
    110         if (iToken == tokens.size())
    111           continue;
    112 
    113         // second argument can be the amplitude for the case it as an axis command
    114         // default amplitude is 1.0f
    115         float paramModifier = 1.0f;
    116         if (getLowercase(tokens[iToken]) == "scale")
    117         {
    118           iToken++;
    119           if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
    120           {
    121             COUT(2) << "Error while parsing key binding " << name_
    122                 << ". Numeric expression expected afer 'AxisAmp', switching to default value" << std::endl;
    123             if (iToken == tokens.size())
    124               continue;
    125           }
    126           iToken++;
    127         }
    128 
    129         // no more arguments expected except for the actual command
    130         if (iToken == tokens.size())
    131           continue;
    132 
    133         std::string commandStr;
    134         while (iToken != tokens.size())
    135           commandStr += tokens[iToken++] + " ";
    136 
    137         // evaluate the command
    138         CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
    139         if (!eval.isValid())
    140           continue;
    141 
    142         // check for param command
    143         int paramIndex = eval.getConsoleCommand()->getAxisParamIndex();
    144         if (paramIndex >= 0)
    145         {
    146           // parameter supported command
    147           ParamCommand* cmd = new ParamCommand();
    148           cmd->paramModifier_ = paramModifier;
    149           cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative();
    150 
    151           // add command to the buffer if not yet existing
    152           for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
    153           {
    154             if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getOriginalCommand())
    155                 == getLowercase(commandStr))
    156             {
    157               // already in list
    158               cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
    159               break;
    160             }
    161           }
    162           if (cmd->paramCommand_ == 0)
    163           {
    164             cmd->paramCommand_ = new BufferedParamCommand();
    165             paramCommandBuffer.push_back(cmd->paramCommand_);
    166             cmd->paramCommand_->evaluation_ = eval;
    167             cmd->paramCommand_->paramIndex_ = paramIndex;
    168           }
    169 
    170 
    171           // we don't know whether this is an actual axis or just a button
    172           if (mode == KeybindMode::None)
    173           {
    174             if (!addParamCommand(cmd))
    175             {
    176               mode = eval.getConsoleCommand()->getKeybindMode();
    177               commands[mode].push_back(cmd);
    178             }
    179           }
     83        for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
     84        {
     85            if (commandStrings[iCommand] != "")
     86            {
     87                SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
     88                    '\\', false, '"', false, '(', ')', false, '\0');
     89
     90                KeybindMode::Enum mode = KeybindMode::None;
     91                float paramModifier = 1.0f;
     92                std::string commandStr = "";
     93
     94                for (unsigned int iToken = 0; iToken < tokens.size(); ++iToken)
     95                {
     96                    std::string token = getLowercase(tokens[iToken]);
     97
     98                    if (token == "onpress")
     99                        mode = KeybindMode::OnPress;
     100                    else if (token == "onrelease")
     101                        mode = KeybindMode::OnRelease;
     102                    else if (token == "onhold")
     103                        mode = KeybindMode::OnHold;
     104                    else if (token == "buttonthreshold")
     105                    {
     106                        // for real axes, we can feed a ButtonThreshold argument
     107                        ++iToken;
     108                        if (iToken == tokens.size())
     109                            continue;
     110                        // may fail, but doesn't matter (default value already set)
     111                        if (!convertValue(&buttonThreshold_, tokens[iToken + 1]))
     112                            parseError("Could not parse 'ButtonThreshold' argument. \
     113                                Switching to default value.", true);
     114                    }
     115                    else if (token == "scale")
     116                    {
     117                        ++iToken;
     118                        if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
     119                            parseError("Could not parse 'scale' argument. Switching to default value.", true);
     120                    }
     121                    else
     122                    {
     123                        // no input related argument
     124                        // we interpret everything from here as a command string
     125                        while (iToken != tokens.size())
     126                            commandStr += tokens[iToken++] + " ";
     127                    }
     128                }
     129
     130                if (commandStr == "")
     131                {
     132                    parseError("No command string given.", false);
     133                    continue;
     134                }
     135
     136                // evaluate the command
     137                CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
     138                if (!eval.isValid())
     139                {
     140                    parseError("Command evaluation failed.", true);
     141                    continue;
     142                }
     143
     144                // check for param command
     145                int paramIndex = eval.getConsoleCommand()->getAxisParamIndex();
     146                if (paramIndex >= 0)
     147                {
     148                    // parameter supported command
     149                    ParamCommand* cmd = new ParamCommand();
     150                    cmd->paramModifier_ = paramModifier;
     151                    cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative();
     152
     153                    // add command to the buffer if not yet existing
     154                    for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
     155                    {
     156                        if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getOriginalCommand())
     157                            == getLowercase(commandStr))
     158                        {
     159                            // already in list
     160                            cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
     161                            break;
     162                        }
     163                    }
     164                    if (cmd->paramCommand_ == 0)
     165                    {
     166                        cmd->paramCommand_ = new BufferedParamCommand();
     167                        paramCommandBuffer.push_back(cmd->paramCommand_);
     168                        cmd->paramCommand_->evaluation_ = eval;
     169                        cmd->paramCommand_->paramIndex_ = paramIndex;
     170                    }
     171
     172
     173                    // we don't know whether this is an actual axis or just a button
     174                    if (mode == KeybindMode::None)
     175                    {
     176                        if (!addParamCommand(cmd))
     177                        {
     178                            mode = eval.getConsoleCommand()->getKeybindMode();
     179                            commands[mode].push_back(cmd);
     180                        }
     181                    }
     182                }
     183                else
     184                {
     185                    SimpleCommand* cmd = new SimpleCommand();
     186                    cmd->evaluation_ = eval;
     187
     188                    if (mode == KeybindMode::None)
     189                        mode = eval.getConsoleCommand()->getKeybindMode();
     190
     191                    commands[mode].push_back(cmd);
     192                }
     193            }
     194        }
     195
     196        for (unsigned int j = 0; j < 3; j++)
     197        {
     198            nCommands_[j] = commands[j].size();
     199            if (nCommands_[j])
     200            {
     201                commands_[j] = new BaseCommand*[nCommands_[j]];
     202                for (unsigned int i = 0; i < commands[j].size(); i++)
     203                    commands_[j][i] = commands[j][i];
     204            }
     205            else
     206                commands_[j] = 0;
     207        }
     208    }
     209
     210    bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
     211    {
     212        // execute all the parsed commands in the string
     213        for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
     214            commands_[mode][iCommand]->execute(abs, rel);
     215        return true;
     216    }
     217
     218    inline void Button::parseError(std::string message, bool serious)
     219    {
     220        if (serious)
     221        {
     222            COUT(2) << "Error while parsing binding for button/axis" << this->name_ << ". "
     223                << message << std::endl;
    180224        }
    181225        else
    182226        {
    183           SimpleCommand* cmd = new SimpleCommand();
    184           cmd->evaluation_ = eval;
    185 
    186           if (mode == KeybindMode::None)
    187             mode = eval.getConsoleCommand()->getKeybindMode();
    188 
    189           commands[mode].push_back(cmd);
    190         }
    191       }
    192     }
    193 
    194     for (unsigned int j = 0; j < 3; j++)
    195     {
    196       nCommands_[j] = commands[j].size();
    197       if (nCommands_[j])
    198       {
    199         commands_[j] = new BaseCommand*[nCommands_[j]];
    200         for (unsigned int i = 0; i < commands[j].size(); i++)
    201           commands_[j][i] = commands[j][i];
    202       }
    203       else
    204         commands_[j] = 0;
    205     }
    206   }
    207 
    208   bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
    209   {
    210     // execute all the parsed commands in the string
    211     for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
    212       commands_[mode][iCommand]->execute(abs, rel);
    213     return true;
    214   }
     227            COUT(3) << "Warning while parsing binding for button/axis" << this->name_ << ". "
     228                << message << std::endl;
     229        }
     230    }
    215231}
Note: See TracChangeset for help on using the changeset viewer.