Codejie's C++ Space

Using C++

OutputAgentObject:用于Log输出的对象

Log的输出问题是程序设计需要在设计初期就要计划的一个模块,其接口和功能的设计,会直接影响整体程序的调试和信息输出等方面。
    wxDeMPQ在初期,计划通过其StatusBar作为Log输出,并简单封装了一个函数,但在实际使用中,由于急于实现功能和DLL等的引入,加上VC方便的调试,导致完全废弃了当初的想法,这也是的wxDeMPQ在后期实现上没有任何的Log输出,这对于Debug的程序来说,是--灾难和活该。
    对于类似Log输出的模块,在实现时需要考虑的是使用时的易融合性和灵活性。简单地说,一来此模块的引入不应影响原代码的执行;二来要考虑信息输出的不确定性,就是说你可能无法预知程序会最终通过什么方式输出,文件?Console?或者一个EditCtrl?这两点我认为是需要在初期着重考虑的。
    下面是一个简单Log输出模块的实现,通过Adapter方式,连接输入和输出。
#pragma once

#include 
<string>

#ifdef OUTPUTAGENTLIBRARY_EXPORTS
#define OUTPUTAGENTLIBRARY_API __declspec(dllexport)
#else
#define OUTPUTAGENTLIBRARY_API __declspec(dllimport)
#endif

namespace OUTPUT
{

class OUTPUTAGENTLIBRARY_API COutputBase
{
public:
    COutputBase() {}
    
virtual ~COutputBase() {}

    
virtual void Output(const std::wstring& info) = 0;
};

const unsigned int LEVEL_DEBUG        =    1;
const unsigned int LEVEL_INFO        =    2;
const unsigned int LEVEL_WARN        =    4;
const unsigned int LEVEL_ERROR        =    8;

const unsigned int LEVEL_ALL        =    0xFFFFFFFF;

class OUTPUTAGENTLIBRARY_API COutputAgentObject
{
public:
    COutputAgentObject();
    
virtual ~COutputAgentObject();

    
void SetLevel(unsigned int level);
    unsigned 
int GetLevel() const;
    
void SetOutput(COutputBase* output);
    COutputBase 
* GetOutput() const;

    
void Output(unsigned int level, const std::wstring& info);
protected:
    COutputBase
* _output;
    unsigned 
int _level;
};

}

//#define OUTPUT(outputptr, level, info) \
//{\
//    if(outputptr != NULL) \
//    {\
//        std::wostringstream ostr; \
//        ostr << info; \
//        outputptr->Output(level, ostr.c_str()); \
//    }\
//}

#include "stdafx.h"

#include 
"OutputAgentObject.h"

namespace OUTPUT
{

COutputAgentObject::COutputAgentObject()
: _output(NULL), _level(LEVEL_ALL)
{
}

COutputAgentObject::
~COutputAgentObject()
{
}

void COutputAgentObject::SetLevel(unsigned int level)
{
    _level 
= level;
}

unsigned 
int COutputAgentObject::GetLevel() const
{
    
return _level;
}

void COutputAgentObject::SetOutput(COutputBase* output)
{
    _output 
= output;
}

COutputBase
* COutputAgentObject::GetOutput() const
{
    
return _output;
}

void COutputAgentObject::Output(unsigned int level, const std::wstring& info)
{
    
if(_output == NULL)
        
return;
    
if((level & _level) == 0)
        
return;
    _output
->Output(info);
}


}

    下面是一段测试代码,用于展示如何使用。
#pragma once

#include 
<string>
#include 
<sstream>

#include 
"wx/wx.h"

#include 
"OutputAgentObject.h"

class COutput : public OUTPUT::COutputBase
{
public:
    COutput(wxTextCtrl
* text)
        :_text(text)
    {
    }
    
virtual ~COutput() {}

    
virtual void Output(const std::wstring& info)
    {
        
if(_text != NULL)
        {
            _text
->AppendText(WString2wxString(info));
        }
    }
protected:
    
const wxString WString2wxString(const std::wstring& str)
    {
        
return wxString(str.c_str(), wxConvISO8859_1);
    }
private:
    wxTextCtrl
* _text;
};

OUTPUT::COutputAgentObject g_stOutputAgent;

#define OUTPUT(level, info) \
{\
    std::wostringstream ostr; \
    ostr 
<< info; \
    g_stOutputAgent.Output(level, ostr.str());\
}

    _output = new COutput(m_textOutput);

    g_stOutputAgent.SetOutput(_output);

    OUTPUT(OUTPUT::LEVEL_INFO, L"Level:" << g_stOutputAgent.GetLevel() << std::endl);


   简单实现,很多因素并不考虑,如Thread Safe问题等,源码和测试代码在这里。测试程序模样如下:


posted on 2009-06-09 10:52 codejie 阅读(253) 评论(0)  编辑 收藏 引用 所属分类: C++


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

Using C++

导航

统计

留言簿(73)

随笔分类(513)

积分与排名

最新评论

阅读排行榜

评论排行榜