interpreter.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:12k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * interpreter.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 VideoLAN
  5.  * $Id: interpreter.cpp 8524 2004-08-25 21:32:15Z ipkiss $
  6.  *
  7.  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
  8.  *          Olivier Teuli鑢e <ipkiss@via.ecp.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. #include "interpreter.hpp"
  25. #include "expr_evaluator.hpp"
  26. #include "../commands/cmd_playlist.hpp"
  27. #include "../commands/cmd_dialogs.hpp"
  28. #include "../commands/cmd_dummy.hpp"
  29. #include "../commands/cmd_layout.hpp"
  30. #include "../commands/cmd_quit.hpp"
  31. #include "../commands/cmd_minimize.hpp"
  32. #include "../commands/cmd_input.hpp"
  33. #include "../commands/cmd_fullscreen.hpp"
  34. #include "../commands/cmd_on_top.hpp"
  35. #include "../commands/cmd_show_window.hpp"
  36. #include "../src/theme.hpp"
  37. #include "../src/var_manager.hpp"
  38. #include "../src/vlcproc.hpp"
  39. Interpreter::Interpreter( intf_thread_t *pIntf ): SkinObject( pIntf )
  40. {
  41.     /// Create the generic commands
  42. #define REGISTER_CMD( name, cmd ) 
  43.     m_commandMap[name] = CmdGenericPtr( new cmd( getIntf() ) );
  44.     REGISTER_CMD( "none", CmdDummy )
  45.     REGISTER_CMD( "dialogs.changeSkin()", CmdDlgChangeSkin )
  46.     REGISTER_CMD( "dialogs.fileSimple()", CmdDlgFileSimple )
  47.     REGISTER_CMD( "dialogs.file()", CmdDlgFile )
  48.     REGISTER_CMD( "dialogs.disc()", CmdDlgDisc )
  49.     REGISTER_CMD( "dialogs.net()", CmdDlgNet )
  50.     REGISTER_CMD( "dialogs.messages()", CmdDlgMessages )
  51.     REGISTER_CMD( "dialogs.prefs()", CmdDlgPrefs )
  52.     REGISTER_CMD( "dialogs.fileInfo()", CmdDlgFileInfo )
  53.     REGISTER_CMD( "dialogs.popup()", CmdDlgShowPopupMenu )
  54.     REGISTER_CMD( "playlist.load()", CmdDlgPlaylistLoad )
  55.     REGISTER_CMD( "playlist.save()", CmdDlgPlaylistSave )
  56.     REGISTER_CMD( "playlist.add()", CmdDlgAdd )
  57.     VarList &rVar = VlcProc::instance( getIntf() )->getPlaylistVar();
  58.     m_commandMap["playlist.del()"] =
  59.         CmdGenericPtr( new CmdPlaylistDel( getIntf(), rVar ) );
  60.     REGISTER_CMD( "playlist.next()", CmdPlaylistNext )
  61.     REGISTER_CMD( "playlist.previous()", CmdPlaylistPrevious )
  62.     REGISTER_CMD( "playlist.sort()", CmdPlaylistSort )
  63.     m_commandMap["playlist.setRandom(true)"] =
  64.         CmdGenericPtr( new CmdPlaylistRandom( getIntf(), true ) );
  65.     m_commandMap["playlist.setRandom(false)"] =
  66.         CmdGenericPtr( new CmdPlaylistRandom( getIntf(), false ) );
  67.     m_commandMap["playlist.setLoop(true)"] =
  68.         CmdGenericPtr( new CmdPlaylistLoop( getIntf(), true ) );
  69.     m_commandMap["playlist.setLoop(false)"] =
  70.         CmdGenericPtr( new CmdPlaylistLoop( getIntf(), false ) );
  71.     m_commandMap["playlist.setRepeat(true)"] =
  72.         CmdGenericPtr( new CmdPlaylistRepeat( getIntf(), true ) );
  73.     m_commandMap["playlist.setRepeat(false)"] =
  74.         CmdGenericPtr( new CmdPlaylistRepeat( getIntf(), false ) );
  75.     REGISTER_CMD( "vlc.fullscreen()", CmdFullscreen )
  76.     REGISTER_CMD( "vlc.play()", CmdPlay )
  77.     REGISTER_CMD( "vlc.pause()", CmdPause )
  78.     REGISTER_CMD( "vlc.stop()", CmdStop )
  79.     REGISTER_CMD( "vlc.faster()", CmdFaster )
  80.     REGISTER_CMD( "vlc.slower()", CmdSlower )
  81.     REGISTER_CMD( "vlc.mute()", CmdMute )
  82.     REGISTER_CMD( "vlc.minimize()", CmdMinimize )
  83.     REGISTER_CMD( "vlc.onTop()", CmdOnTop )
  84.     REGISTER_CMD( "vlc.quit()", CmdQuit )
  85.     // Register the constant bool variables in the var manager
  86.     VarManager *pVarManager = VarManager::instance( getIntf() );
  87.     VarBool *pVarTrue = new VarBoolTrue( getIntf() );
  88.     pVarManager->registerVar( VariablePtr( pVarTrue ), "true" );
  89.     VarBool *pVarFalse = new VarBoolFalse( getIntf() );
  90.     pVarManager->registerVar( VariablePtr( pVarFalse ), "false" );
  91. }
  92. Interpreter *Interpreter::instance( intf_thread_t *pIntf )
  93. {
  94.     if( ! pIntf->p_sys->p_interpreter )
  95.     {
  96.         Interpreter *pInterpreter;
  97.         pInterpreter = new Interpreter( pIntf );
  98.         if( pInterpreter )
  99.         {
  100.             pIntf->p_sys->p_interpreter = pInterpreter;
  101.         }
  102.     }
  103.     return pIntf->p_sys->p_interpreter;
  104. }
  105. void Interpreter::destroy( intf_thread_t *pIntf )
  106. {
  107.     if( pIntf->p_sys->p_interpreter )
  108.     {
  109.         delete pIntf->p_sys->p_interpreter;
  110.         pIntf->p_sys->p_interpreter = NULL;
  111.     }
  112. }
  113. CmdGeneric *Interpreter::parseAction( const string &rAction, Theme *pTheme )
  114. {
  115.     // Try to find the command in the global command map
  116.     if( m_commandMap.find( rAction ) != m_commandMap.end() )
  117.     {
  118.         return m_commandMap[rAction].get();
  119.     }
  120.     CmdGeneric *pCommand = NULL;
  121.     if( rAction.find( ".setLayout(" ) != string::npos )
  122.     {
  123.         int leftPos = rAction.find( ".setLayout(" );
  124.         string windowId = rAction.substr( 0, leftPos );
  125.         // 11 is the size of ".setLayout("
  126.         int rightPos = rAction.find( ")", windowId.size() + 11 );
  127.         string layoutId = rAction.substr( windowId.size() + 11,
  128.                                           rightPos - (windowId.size() + 11) );
  129.         pCommand = new CmdLayout( getIntf(), windowId, layoutId );
  130.     }
  131.     else if( rAction.find( ".show()" ) != string::npos )
  132.     {
  133.         int leftPos = rAction.find( ".show()" );
  134.         string windowId = rAction.substr( 0, leftPos );
  135.         TopWindow *pWin = pTheme->getWindowById( windowId );
  136.         if( pWin )
  137.         {
  138.             pCommand = new CmdShowWindow( getIntf(), pTheme->getWindowManager(),
  139.                                           *pWin );
  140.         }
  141.         else
  142.         {
  143.             msg_Err( getIntf(), "Unknown window (%s)", windowId.c_str() );
  144.         }
  145.     }
  146.     else if( rAction.find( ".hide()" ) != string::npos )
  147.     {
  148.         int leftPos = rAction.find( ".hide()" );
  149.         string windowId = rAction.substr( 0, leftPos );
  150.         TopWindow *pWin = pTheme->getWindowById( windowId );
  151.         if( pWin )
  152.         {
  153.             pCommand = new CmdHideWindow( getIntf(), pTheme->getWindowManager(),
  154.                                           *pWin );
  155.         }
  156.         else
  157.         {
  158.             msg_Err( getIntf(), "Unknown window (%s)", windowId.c_str() );
  159.         }
  160.     }
  161.     if( pCommand )
  162.     {
  163.         // Add the command in the pool
  164.         pTheme->m_commands.push_back( CmdGenericPtr( pCommand ) );
  165.     }
  166.     return pCommand;
  167. }
  168. VarBool *Interpreter::getVarBool( const string &rName, Theme *pTheme )
  169. {
  170.     VarManager *pVarManager = VarManager::instance( getIntf() );
  171.    // Convert the expression into Reverse Polish Notation
  172.     ExprEvaluator *pEvaluator = new ExprEvaluator( getIntf() );
  173.     pEvaluator->parse( rName );
  174.     list<VarBool*> varStack;
  175.     // Get the first token from the RPN stack
  176.     string token = pEvaluator->getToken();
  177.     while( !token.empty() )
  178.     {
  179.         if( token == "and" )
  180.         {
  181.             // Get the 2 last variables on the stack
  182.             if( varStack.empty() )
  183.             {
  184.                 msg_Err( getIntf(), "Invalid boolean expression: %s",
  185.                          rName.c_str());
  186.                 return NULL;
  187.             }
  188.             VarBool *pVar1 = varStack.back();
  189.             varStack.pop_back();
  190.             if( varStack.empty() )
  191.             {
  192.                 msg_Err( getIntf(), "Invalid boolean expression: %s",
  193.                          rName.c_str());
  194.                 return NULL;
  195.             }
  196.             VarBool *pVar2 = varStack.back();
  197.             varStack.pop_back();
  198.             // Create a composite boolean variable
  199.             VarBool *pNewVar = new VarBoolAndBool( getIntf(), *pVar1, *pVar2 );
  200.             varStack.push_back( pNewVar );
  201.             // Register this variable in the manager
  202.             pVarManager->registerVar( VariablePtr( pNewVar ) );
  203.         }
  204.         else if( token == "or" )
  205.         {
  206.             // Get the 2 last variables on the stack
  207.             if( varStack.empty() )
  208.             {
  209.                 msg_Err( getIntf(), "Invalid boolean expression: %s",
  210.                          rName.c_str());
  211.                 return NULL;
  212.             }
  213.             VarBool *pVar1 = varStack.back();
  214.             varStack.pop_back();
  215.             if( varStack.empty() )
  216.             {
  217.                 msg_Err( getIntf(), "Invalid boolean expression: %s",
  218.                          rName.c_str());
  219.                 return NULL;
  220.             }
  221.             VarBool *pVar2 = varStack.back();
  222.             varStack.pop_back();
  223.             // Create a composite boolean variable
  224.             VarBool *pNewVar = new VarBoolOrBool( getIntf(), *pVar1, *pVar2 );
  225.             varStack.push_back( pNewVar );
  226.             // Register this variable in the manager
  227.             pVarManager->registerVar( VariablePtr( pNewVar ) );
  228.         }
  229.         else if( token == "not" )
  230.         {
  231.             // Get the last variable on the stack
  232.             if( varStack.empty() )
  233.             {
  234.                 msg_Err( getIntf(), "Invalid boolean expression: %s",
  235.                          rName.c_str());
  236.                 return NULL;
  237.             }
  238.             VarBool *pVar = varStack.back();
  239.             varStack.pop_back();
  240.             // Create a composite boolean variable
  241.             VarBool *pNewVar = new VarNotBool( getIntf(), *pVar );
  242.             varStack.push_back( pNewVar );
  243.             // Register this variable in the manager
  244.             pVarManager->registerVar( VariablePtr( pNewVar ) );
  245.         }
  246.         else if( token.find( ".isVisible" ) != string::npos )
  247.         {
  248.             int leftPos = token.find( ".isVisible" );
  249.             string windowId = token.substr( 0, leftPos );
  250.             TopWindow *pWin = pTheme->getWindowById( windowId );
  251.             if( pWin )
  252.             {
  253.                 // Push the visibility variable on the stack
  254.                 varStack.push_back( &pWin->getVisibleVar() );
  255.             }
  256.             else
  257.             {
  258.                 msg_Err( getIntf(), "Unknown window (%s)", windowId.c_str() );
  259.                 return NULL;
  260.             }
  261.         }
  262.         else
  263.         {
  264.             // Try to get the variable from the variable manager
  265.             VarBool *pVar = (VarBool*)pVarManager->getVar( token, "bool" );
  266.             if( !pVar )
  267.             {
  268.                 msg_Err( getIntf(), "Cannot resolve boolean variable: %s",
  269.                          token.c_str());
  270.                 return NULL;
  271.             }
  272.             varStack.push_back( pVar );
  273.         }
  274.         // Get the first token from the RPN stack
  275.         token = pEvaluator->getToken();
  276.     }
  277.     // The stack should contain a single variable
  278.     if( varStack.size() != 1 )
  279.     {
  280.         msg_Err( getIntf(), "Invalid boolean expression: %s", rName.c_str() );
  281.         return NULL;
  282.     }
  283.     return varStack.back();
  284. }
  285. VarPercent *Interpreter::getVarPercent( const string &rName, Theme *pTheme )
  286. {
  287.     // Try to get the variable from the variable manager
  288.     VarManager *pVarManager = VarManager::instance( getIntf() );
  289.     VarPercent *pVar = (VarPercent*)pVarManager->getVar( rName, "percent" );
  290.     return pVar;
  291. }
  292. VarList *Interpreter::getVarList( const string &rName, Theme *pTheme )
  293. {
  294.     // Try to get the variable from the variable manager
  295.     VarManager *pVarManager = VarManager::instance( getIntf() );
  296.     VarList *pVar = (VarList*)pVarManager->getVar( rName, "list" );
  297.     return pVar;
  298. }