Nebula2探秘12-基于Windows命令行的Nebula控制台

Nebula2探秘12-基于Windows命令行的Nebula控制台

happykevins文

工欲善其事,必先利其器!”

本文创建了一个在命令窗口下的Nebula命令控制台.可以直接执行脚本指令,察看当前Nebula的系统状态,察看NOH树及当前工作对象信息,对于调试和控制Nebula2程序非常实用方便!

本来Nebula2nGui系统中已经实现了一个叫做nGuiCmdEntry的控件,这个控件就具备即时执行脚本的功能,但我们在实际开发中可能会抛弃nGui而使用其他如CEGUI的界面系统进行替换,所以我们需要一个通用的解决方案:适用Windows控制台作为Nebula控制台的载体,于是就产生了本文的nConConServer

nConConServer中借鉴了nGuiCmdEntry中对用户输入脚本指令的处理方式,并加入了几条实用的全局指令,使用”-help”指令查看全局指令帮助,代码如下:  

 

/* ************************************************************************** */
/*     Nebula2 - Tutorial Utils                                                 */
/*   nConConServer - 控制台下的Nebula2指令控制台                                 */
/*   author: happykevins                                                         */
/* ************************************************************************** */
#pragma  once

#include 
" kernel/nkernelserver.h "
#include 
" kernel/nscriptserver.h "
#include 
" kernel/nautoref.h "

#define  KS_USE_STDOUT
#include 
" nkernelinfo.h "
#undef  KS_USE_STDOUT

#define  LINE_BUF_MAX_SIZE  512
#define  GLOBAL_CMD_TOKEN   '-'

class  nConConServer :  public  nRoot
{
public :
    
///  constructor
    nConConServer();
    
///  destructor
     virtual   ~ nConConServer();
    
///  Toggle Mode
     void  ToggleMode();
    
///  Poll Commands
     void  PollCmd();
    
///  Execute String
     void  ExecuteCommand( const   char *  szCmdStr);

protected :
    
///  set edit line buffer
     void  SetEditLine( const   char *  szCmdBuf);
    
///  execute the current command
     void  ExecuteEditLine();
    
///  checking the char effect
     bool  CheckingChar( char  ch);
    
///  global function check
     void  ExecuteGlobal();
    
///  add current command to history
     void  AddCommandToHistory();
    
///  recall next command in history
     void  RecallNextCommand();
    
///  recall previous command in history
     void  RecallPrevCommand();
    
///  set local cwd
     void  SetCwd(nRoot *  cwd);
    
///  get local cwd (can return 0)
    nRoot *  GetCwd();
    
///  update the tab completion stuff
     void  UpdateTabComplete();
    
///  perform a tab completion
     void  DoTabCompletion();

private :
    nKernelInfoHelper m_info;
    
bool  m_bRecvCmd;

    size_t m_nLineBufPtr;
    
char  m_szLineBuf[LINE_BUF_MAX_SIZE];

    nString editLine;
    
    nAutoRef
< nScriptServer >  refScriptServer;
    nRef
< nRoot >  refCwd;
};

 

//  nconconserver.cpp
#pragma  warning(push)
#pragma  warning(disable: 4267 4244)

#include 
" nconconserver.h "
#include 
" nutildefs.h "
/// ----------------------------------------------------------------------------

///  constructor
nConConServer::nConConServer() :
    m_bRecvCmd(
false ),
    refScriptServer(
" /sys/servers/script " )
{
}

///  destructor
nConConServer:: ~ nConConServer()
{
}

///  Toggle Mode
void  nConConServer::ToggleMode()
{
    m_bRecvCmd 
=   ! m_bRecvCmd;

    
if  ( m_bRecvCmd )
    {
        
//  Welcome Text
        printf( " " );
        printf(
" %s " " ========================= " );
        printf(
" %s " "  ConConServer Welcome :) "  );
        printf(
" %s " " ========================= " );
    }
}

///  Poll Commands
void  nConConServer::PollCmd()
{
    
while  ( m_bRecvCmd )
    {
        printf(
" :> " );
        memset(m_szLineBuf, 
0 , LINE_BUF_MAX_SIZE);
        m_nLineBufPtr 
=   0 ;
        
char  ch;
        
while  ( (ch  =  getchar())  !=   ' '  )
        {
            
if  ( CheckingChar(ch) )
            {
                
continue ;
            }

            m_szLineBuf[m_nLineBufPtr] 
=  ch;
            m_nLineBufPtr
++ ;
        }
        m_szLineBuf[m_nLineBufPtr] 
=   ' \0 ' ;

        ExecuteCommand(m_szLineBuf);
    }
}

///  Execute String
void  nConConServer::ExecuteCommand( const   char *  szCmdStr)
{
    SetEditLine(m_szLineBuf);
    ExecuteEditLine();
}

///  set edit line buffer
void  nConConServer::SetEditLine( const   char *  szCmdBuf)
{
    editLine.Set(szCmdBuf);
}

///  execute the current command
void  nConConServer::ExecuteEditLine()
{
    
//  check and run global function
     if  ( GLOBAL_CMD_TOKEN  ==  editLine[ 0 ] )
    {
        ExecuteGlobal();
        
return ;
    }

    
//  check if script server is ok
     if  (  ! refScriptServer.isvalid() )
    {
        printf(
" Error: Script Server is not Startup! " );
        
return ;
    }

    nScriptServer
*  scriptServer  =   this -> refScriptServer. get ();

    
//  make local cwd global
    nKernelServer::Instance() -> PushCwd( this -> GetCwd());

    
//  and run the command through the script server
    nString result  =   0 ;
    
bool  failOnError  =  scriptServer -> GetFailOnError();
    scriptServer
-> SetFailOnError( false );
    scriptServer
-> Run( this -> editLine.Get(), result);
    scriptServer
-> SetFailOnError(failOnError);
    
if  (result.IsValid())
    {
        printf(
" %s " , result.Get());
    }
    
this -> AddCommandToHistory();
    
this -> editLine.Clear();

    
//  set new local cwd
    nRoot *  newCwd  =  nKernelServer::Instance() -> GetCwd();
    
if  (newCwd  !=   this -> GetCwd())
    {
        
this -> SetCwd(nKernelServer::Instance() -> GetCwd());
        
this -> UpdateTabComplete();
    }

    
//  restore previous cwd
    nKernelServer::Instance() -> PopCwd();
}

///  checking the char effect
bool  nConConServer::CheckingChar( char  ch)
{
    
return   false ;
}

///  global function check
void  nConConServer::ExecuteGlobal()
{
    
char *  szRealCmd  =  m_szLineBuf  +   1 ;

    
if  (  0   ==  strcmp( " help " , szRealCmd) )
    {
        printf(
" %s " " ========================= " );
        printf(
" %s " " ConConServer Help List :) " );
        printf(
" %s " " ========================= " );
        printf(
" %s " " *Command List:            " );
        printf(
" %s " " help: Show this Text! " );
        printf(
" %s " " exit: Exit ConConServer Mode. " );
        printf(
" %s " " noh : Display a Tree View of Nebula NOH. " );
        printf(
" %s " " cls : Show Current Registered Class List. " );
        printf(
" %s " " cwd : Show Current Working Object Info. " );
        printf(
" %s " " mtd : Show the Methods that Current Working Object Support. " );
    }
    
else   if  (  0   ==  strcmp( " exit " , szRealCmd) )
    {
        ToggleMode();
    }
    
else   if  (  0   ==  strcmp( " noh " , szRealCmd) )
    {
        m_info.LogNOH(
this -> GetCwd() -> GetFullName().Get());
    }
    
else   if  (  0   ==  strcmp( " cls " , szRealCmd) )
    {
        m_info.LogCLS();
    }
    
else   if  (  0   ==  strcmp( " cwd " , szRealCmd) )
    {
        printf(
" CWD   : %s " this -> GetCwd() -> GetFullName().Get() );
        printf(
" Class : %s " this -> GetCwd() -> GetClass() -> GetProperName() );
        printf(
" Parent: %s " this -> GetCwd() -> GetClass() -> GetSuperClass() -> GetProperName() );
    }
    
else   if  (  0   ==  strcmp( " mtd " , szRealCmd) )
    {
        nHashList
*  obj  =   this -> GetCwd() -> GetClass() -> GetCmdList();

        nCmdProto
*  node  =  (nCmdProto * )obj -> GetHead();

        
do
        {
            printf(
" %s " , node -> GetProtoDef());
        } 
while  ( (node  =  (nCmdProto * )node -> GetSucc()) );
    }
    
else
    {
        printf(
" %s " " Error: '-' follows Unkown Globle Command! " );
    }
}

///  add current command to history
void  nConConServer::AddCommandToHistory()
{
    
//  empty.
}
///  recall next command in history
void  nConConServer::RecallNextCommand()
{
    
//  empty.
}
///  recall previous command in history
void  nConConServer::RecallPrevCommand()
{
    
//  empty.
}
///  set local cwd
void  nConConServer::SetCwd(nRoot *  cwd)
{
    
this -> refCwd  =  cwd;
}
///  get local cwd (can return 0)
nRoot *  nConConServer::GetCwd()
{
    
if  (  ! this -> refCwd.isvalid() )
    {
        
this -> SetCwd(nKernelServer::Instance() -> GetCwd());
    }
    
return   this -> refCwd. get ();
}
///  update the tab completion stuff
void  nConConServer::UpdateTabComplete()
{
    
//  ...
}
///  perform a tab completion
void  nConConServer::DoTabCompletion()
{
    
//  ...
}


/// ----------------------------------------------------------------------------

///  声明为Nebula2脚本支持类
nNebulaScriptModule(nConConServer, nconconserver,  " nroot " );

///  ConConServer开关
static   void  n_toggle( void *  slf, nCmd *  cmd);
///  执行控制台指令
static   void  n_exec( void *  slf, nCmd *  cmd);

///  Regist Commands
void  nNebulaScriptInitCmds(nconconserver) (nClass *  cl)
{
    cl
-> BeginCmds();
    cl
-> AddCmd( " v_toggle_v " ,     ' TOGL ' ,    n_toggle);
    cl
-> AddCmd( " v_exec_s " ,         ' EXEC ' ,    n_exec);
    cl
-> EndCmds();
}

///  ToggleMode的脚本支持
static   void  n_toggle( void *  slf, nCmd *  cmd)
{
    nConConServer
*  self  =  (nConConServer * ) slf;
    self
-> ToggleMode();
}

///  ExecCommand的脚本支持
static   void  n_exec( void *  slf, nCmd *  cmd)
{
    nConConServer
*  self  =  (nConConServer * ) slf;
    
const   char *  szCmdStr  =  cmd -> In() -> GetS();
    self
-> ExecuteCommand(szCmdStr);
}

/// ----------------------------------------------------------------------------
#pragma  warning(pop)

 

    其中ToggleMode()方法是切换到控制台模式的开关,已经加入了对脚本的支持,可以直接通过InputServer映射到一个按键上。

    PollCmd()命令用于阻塞接受用户输入的指令。由于是以Windows控制台实现,所以只能以阻塞模式接受用户输入,在执行PollCmd()函数后应用程序会停止运行,直到用户在控制台中输入-exit指令,nConConServer才会把控制权释放掉。

    下面给出nConConServer的使用事例代码:

/* ************************************************************************** */
/*     Nebula2 - Tutorial 12                                                     */
/*   A Console Server for Console                                             */
/*   author: happykevins                                                         */
/* ************************************************************************** */

/// ----------------------------------------------------------------------------
///  +必要头文件

//  nebula2 includes
#include  " kernel/nkernelserver.h "
#include 
" script/ntclserver.h "

//  ConConServer头文件
#include  " ../NebulaUtils/nConConServer.h "

//  Tutorial工具库:一些通用的宏定义
#include  " ../NebulaUtils/nutildefs.h "

///  -必要头文件
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
///  +链接库
#pragma  comment(lib, "wsock32.lib")
#pragma  comment(lib, "d_nkernel.lib")
#pragma  comment(lib, "d_nnebula.lib")
#pragma  comment(lib, "d_microtcl.lib")
///  -链接库
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
///  +声明使用的Nebula2 Package&Module
nNebulaUseModule(ntclserver);
///  -声明使用的Nebula2 Package&Module
/// ----------------------------------------------------------------------------
nKernelServer *  ks  =  NULL;

/// ----------------------------------------------------------------------------
///  +初始化环境,创建需要的Server
///
bool  InitApp()
{
    
///  创建KernelServer
    ks  =  n_new(nKernelServer);

    
/// ----------------------------------------------------------------------------
    
///     +向KernelServer中添加Package&Module
    nNebulaAddModule(ntclserver);
    
///     +向KernelServer中添加Package&Module
    
/// ----------------------------------------------------------------------------
    ks -> New( " ntclserver " ,             " /sys/servers/script " );

    
return   true ;
}
///
///  -初始化环境,创建需要的Server
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
///  +退出程序,清理资源
///
bool  CloseApp()
{
    
///  销毁KernelServer
    n_delete(ks);

    
return   true ;
}
///
///  -退出程序,清理资源
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
///  +Application
int  main( int  argc,  const   char **  argv)
{
    
///  初始化Application
     if  (  ! InitApp() )
    {
        n_error(
" 程序初始化失败! " );
        
return   0 ;
    }
    
    
///  ConConServer
    nConConServer console;

    
///  切出ConConServer
    console.ToggleMode();
    
///  轮训控制台指令,(阻塞模式)
    console.PollCmd();

    
///  释放资源
     if  (  ! CloseApp() )
    {
        n_error(
" 释放资源失败! " );
        
return   0 ;
    }

    
return   0 ;
}
///  -Application
/// ----------------------------------------------------------------------------

--The End--

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1412709


你可能感兴趣的:(windows)