实现cs中的控制台

原创 2005年04月25日 12:58:00
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 )
{
       ... ...
}
};


全文完
           

Unity: ExampleGameInput.cs

from https://gist.github.com/talecrafter/35fb1441fd3ba0ff7ae9 using UnityEngine; using System.C...
  • zhangbp
  • zhangbp
  • 2016年03月10日 14:41
  • 335

Flash CS5 多次添加同一个显示对象例子

同一个显示对象不论被代码加入显示列表多少次,在屏幕上只会有一个显示对象。例:文档类SampleAdd中生成一个星星显示对象star,两个容器conA和conB。ConA坐标没有位置,默认是(0,0),...
  • ttbat
  • ttbat
  • 2011年07月15日 16:23
  • 729

CS游戏控制台命令大全(来自网络)

以前常玩CS(反恐精英),有很玩家都用控制台命令,但因为自已不会给自己玩游戏代来很多不便,这里我找了一下命令大全,要进入游戏后按“`”(1键左边的那个键)和“Tab”来一起用会很方便。下面就是我找到的...

C# 控制台应用程序--随机数

一.实验要求 `1)这是一个实际的项目衍生出来的核心算法之一。防伪码是我们现在经常在商品上看到的防伪手段之一,现在需要编写一个防伪码生成器,按照输入参数生成防伪码,并且把生成的时间及指定的防伪码输出...

空挡接龙C语言控制台实现

  • 2008年09月06日 16:33
  • 11KB
  • 下载

CentOS6.5菜鸟之旅:文件权限详解 一、前言                                 Linux下所有资源、设备均被视作文件来操作,而文件权限则是决定用户可各文件

CentOS6.5菜鸟之旅:文件权限详解 一、前言                                   Linux下所有资源、设备均被视作文件来操作,而文件权限则是...
  • cdnight
  • cdnight
  • 2017年05月31日 19:49
  • 350

UDP C/S版基础实现 VS2008 控制台APP

  • 2013年04月25日 18:49
  • 5.95MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章: 实现cs中的控制台
举报原因:
原因补充:

(最多只允许输入30个字)