实现cs中的控制台

cs中的控制台是不是很cool
输入1个命令就可以执行某个操作(有点像回到了dos的时代了 呵呵~)
有人会想 不如直接实现1个GUI
但是要实现1个GUI可能会比实现1个控制台要难得多
有时在功能上和速度上都不如控制台

1个控制台
首先要能把信息(就是1大堆字符串)显示出来
最简单的方法就是用cout输出
也可以就直接从窗口中显示
但是每个人实现的方法都不同
我也不能硬性规定什么(如果这个搞得不好就会增加耦合性)
所以我把这部分的内容写成1个接口函数 
void PrintLog( const std::string& str, unsigned long LogLevel );
参数是1个字符串和1个LogLevel 
LogLevel 的作用就是比较这个字符串的重要程度
可能是错误信息哟~
这样就可以用不同的方发来显示信息
至于怎样显示
就留给读者去干了

接着就是输入的命令
当然是用字符串
但是我们同常都是1个个字符输入(废话=。=)
但是程序内部调用就可以直接用字符串啦
所以这里就要实现两个函数了
void InputCommand( const std::string & strCommand );
void InputCommand( char Command );

最后就是执行命令
怎样执行??
当然是某个调用函数啦
但首先就是要把函数和命令加载到1个容器里
这个容器最好是用hash_map
好处就是寻找是速度快
缺点就是插入时慢
我们需要的就是执行命令是要快
而插入通常都是在程序开始时进行的

另1个问题来了
调用函数是普通的函数就容易
但调用的是成员函数就嘛烦多了
有人会想可以继承1个虚基类啊
然后把所有要调用成员函数的类都继承这个虚基类
但是这样做是不是有点难看啊
但是又放弃了普通的函数
难道又继承这个虚基类 然后在实现时调用这个普通函数
但是有的类是不能改动的或是已经写好的呢?
用这个方法也可以做到
但只能用1个字来形容 就是"烦"

但是有没有更好的方法呢??
当然有
如果各位有看我上1篇文章的话就会觉得这1切都变得无比得简单了
上1编文章说的是"委托"
其实就是1个范化仿函数
其他1些库都有这个东西
但我用的是我的方法
当然是简单的方法啦^_^

容器就是这样子了hash_map< std::string, Delegate>

仿函数的参数当然可以自行设定

而我设定的参数是(const std::string&,  std::string& )
返回值是unsigned long 是信息的类型(例如错误信息)

第1个参数是输入的是命令
我们在敲打键盘输入命令时都会在后面加几个参数之类的
然后就可以在被调用的函数种处理
第2个是返回的信息
可以立即的显示出来

仿函数就是这样子了Delegate<unsigned long, const std::string&, std::string& > 


先来1段代码

template

class Functor

class FunctorManager
{
public:
typedef Functor Functor;
public:

    bool RegisterFunctor(const std::string & strName, Functor& function)
{
return m_Functor_List.insert(
std::make_pair(strName, function)).second;
}


bool UnregisterFunctor(const std::string & strFunctorName )
{
return m_Functor_List.erase(strFunctorName) == 1;
}


Functor* ActivationFunctor( const std::string & strFunctorName )
{
Functor_List_Iterator_t i = m_Functor_List.find(strFunctorName);
if (i == m_Functor_List.end())
{
return 0;
}
return &((*i).second);
}

protected:
typedef std::hash_map< std::string, Functor> Functor_List_t;
typedef typename std::hash_map< std::string,Functor>::iterator Functor_List_Iterator_t;
Functor_List_t m_Functor_List;

};
看名字就是到管理仿函数的class 是1个base class

template

class PrintPolicy
>
class Console : public FunctorManager<
Delegate
<
unsigned long, 
const std::string&, 
std::string& 

>
{
public:
typedef Console<PrintPolicy> MyType;
typedef PrintPolicy PrintType;
typedef Delegate
<
unsigned long,
const std::string&,
std::string& 
> Function_t;
enum
{
CONSOLE_LOG_LEVEL_INFORMATION,

CONSOLE_LOG_LEVEL_COMMAND,

CONSOLE_LOG_LEVEL_WARNING,

CONSOLE_LOG_LEVEL_ERROR
};

public:
               //构造函数 CommandSign 是命令也要有个表记吧 
               // 还用先注册自己1个成员函数 输出所有命令的名称
Console(char CommandSign = '/')
:m_CommandSign(CommandSign)
{
Function_t __PrintAllCommand(this,Console::PrintAllCommand);

bool b = RegisterFunctor( "Print All Command", __PrintAllCommand);
assert(b);
}
~Console(){}
public:
               //输入命令
void InputCommand( const std::string & strCommand )
{
                                //把this转换成派生类的this
                                //这样就可以不用设成虚函数就可以调用派生类的函数
PrintPolicy* pT = static_cast<PrintPolicy*>(this);

                                 //命令是否为空
if(strCommand.empty())
{
return;
}
                                //命令的第1个字符是否"/"
if( strCommand[0] != m_CommandSign )
{
pT->PrintLog( strCommand,CONSOLE_LOG_LEVEL_WARNING );
return;
}

pT->PrintLog(strCommand, CONSOLE_LOG_LEVEL_COMMAND);
                                //把命令和参数分开
std::string::size_type next_space = strCommand.find(' ');
std::string CommandHead = strCommand.substr(1, next_space-1-1);

                                //执行命令调用的函数
Function_t* pfun = ActivationFunctor(strCommand);
if (pfun)
{
std::string OutLog;
unsigned long LogLevel = (*pfun)(strCommand,OutLog);

pT->PrintLog( OutLog, LogLevel );
}
else
{
pT->PrintLog("Have no this Command ",CONSOLE_LOG_LEVEL_WARNING);
}
}

protected:
                //把所以的命令的名称都打印出来
unsigned long PrintAllCommand( const std::string& in, std::string& out)
{
assert( in == "Print All Command" );

Functor_List_Iterator_t i = m_Functor_List.begin();
Functor_List_Iterator_t iend = m_Functor_List.end();
for(; i != iend; ++i)
{
static_cast<PrintPolicy*>(this)->PrintLog( (*i).first, CONSOLE_LOG_LEVEL_INFORMATION );
}

out = "Print All Command Complete .";
return CONSOLE_LOG_LEVEL_INFORMATION;
}

private:
const char m_CommandSign;//命令的表记
};


实现的代码是不是很简单 呵呵~这就是全靠STL和我的范化仿函数了
(有时真不感想象没有STL的日子会是怎样过=.=)


用发很简单
继承这个class 然后实现PrintLog就可以了
class MyConsole : public Console<MyConsole>
{
void PrintLog( const std::string& str, unsigned long LogLevel )
{
       ... ...
}
};


全文完
           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值