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

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

happykevins文

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

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

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

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

/* ************************************************************************** */
/* Nebula2-TutorialUtils */
/* 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_SIZE512
#define GLOBAL_CMD_TOKEN'-'

class nConConServer: public nRoot
{
public :
/// constructor
nConConServer();
/// destructor
virtual ~ nConConServer();
/// ToggleMode
void ToggleMode();
/// PollCommands
void PollCmd();
/// ExecuteString
void ExecuteCommand( const char * szCmdStr);

protected :
/// seteditlinebuffer
void SetEditLine( const char * szCmdBuf);
/// executethecurrentcommand
void ExecuteEditLine();
/// checkingthechareffect
bool CheckingChar( char ch);
/// globalfunctioncheck
void ExecuteGlobal();
/// addcurrentcommandtohistory
void AddCommandToHistory();
/// recallnextcommandinhistory
void RecallNextCommand();
/// recallpreviouscommandinhistory
void RecallPrevCommand();
/// setlocalcwd
void SetCwd(nRoot * cwd);
/// getlocalcwd(canreturn0)
nRoot * GetCwd();
/// updatethetabcompletionstuff
void UpdateTabComplete();
/// performatabcompletion
void DoTabCompletion();

private :
nKernelInfoHelperm_info;
bool m_bRecvCmd;

size_tm_nLineBufPtr;
char m_szLineBuf[LINE_BUF_MAX_SIZE];

nStringeditLine;

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

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

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

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

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

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

if (m_bRecvCmd)
{
// WelcomeText
printf( " " );
printf(
" %s " , " ========================= " );
printf(
" %s " , " ConConServerWelcome:) " );
printf(
" %s " , " ========================= " );
}
}

/// PollCommands
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);
}
}

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

/// seteditlinebuffer
void nConConServer::SetEditLine( const char * szCmdBuf)
{
editLine.Set(szCmdBuf);
}

/// executethecurrentcommand
void nConConServer::ExecuteEditLine()
{
// checkandrunglobalfunction
if (GLOBAL_CMD_TOKEN == editLine[ 0 ])
{
ExecuteGlobal();
return ;
}

// checkifscriptserverisok
if ( ! refScriptServer.isvalid())
{
printf(
" Error:ScriptServerisnotStartup! " );
return ;
}

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

// makelocalcwdglobal
nKernelServer::Instance() -> PushCwd( this -> GetCwd());

// andrunthecommandthroughthescriptserver
nStringresult = 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();

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

// restorepreviouscwd
nKernelServer::Instance() -> PopCwd();
}

/// checkingthechareffect
bool nConConServer::CheckingChar( char ch)
{
return false ;
}

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

if ( 0 == strcmp( " help " ,szRealCmd))
{
printf(
" %s " , " ========================= " );
printf(
" %s " , " ConConServerHelpList:) " );
printf(
" %s " , " ========================= " );
printf(
" %s " , " *CommandList: " );
printf(
" %s " , " help:ShowthisText! " );
printf(
" %s " , " exit:ExitConConServerMode. " );
printf(
" %s " , " noh:DisplayaTreeViewofNebulaNOH. " );
printf(
" %s " , " cls:ShowCurrentRegisteredClassList. " );
printf(
" %s " , " cwd:ShowCurrentWorkingObjectInfo. " );
printf(
" %s " , " mtd:ShowtheMethodsthatCurrentWorkingObjectSupport. " );
}
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:'-'followsUnkownGlobleCommand! " );
}
}

/// addcurrentcommandtohistory
void nConConServer::AddCommandToHistory()
{
// empty.
}
/// recallnextcommandinhistory
void nConConServer::RecallNextCommand()
{
// empty.
}
/// recallpreviouscommandinhistory
void nConConServer::RecallPrevCommand()
{
// empty.
}
/// setlocalcwd
void nConConServer::SetCwd(nRoot * cwd)
{
this -> refCwd = cwd;
}
/// getlocalcwd(canreturn0)
nRoot * nConConServer::GetCwd()
{
if ( ! this -> refCwd.isvalid())
{
this -> SetCwd(nKernelServer::Instance() -> GetCwd());
}
return this -> refCwd. get ();
}
/// updatethetabcompletionstuff
void nConConServer::UpdateTabComplete()
{
// ...
}
/// performatabcompletion
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);

/// RegistCommands
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-Tutorial12 */
/* AConsoleServerforConsole */
/* author:happykevins */
/* ************************************************************************** */

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

// nebula2includes
#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")
/// -链接库
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
/// +声明使用的Nebula2Package&Module
nNebulaUseModule(ntclserver);
/// -声明使用的Nebula2Package&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
nConConServerconsole;

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

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

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

--The End--

你可能感兴趣的:(windows,脚本)