本文主要是介绍Nebula2探秘12-基于Windows命令行的Nebula控制台,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Nebula2探秘12-基于Windows命令行的Nebula控制台
happykevins文
“工欲善其事,必先利其器!”
本文创建了一个在命令窗口下的Nebula命令控制台.可以直接执行脚本指令,察看当前Nebula的系统状态,察看NOH树及当前工作对象信息,对于调试和控制Nebula2程序非常实用方便!
本来Nebula2在nGui系统中已经实现了一个叫做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;
};
#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--
这篇关于Nebula2探秘12-基于Windows命令行的Nebula控制台的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!