<commit_before>// SendDlg.cpp : ʵļ
//

#include "stdafx.h"
#include "DacrsUI.h"
#include "SendDlg.h"
#include "afxdialogex.h"

// CSendDlg Ի

IMPLEMENT_DYNAMIC(CSendDlg, CDialogBar)

CSendDlg::CSendDlg()
{
	m_pBmp = NULL ;
}

CSendDlg::~CSendDlg()
{
	if( NULL != m_pBmp ) {
		DeleteObject(m_pBmp) ;
		m_pBmp = NULL ;
	}
}

void CSendDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogBar::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON_ADDBOOK , m_rBtnAddbook);
	DDX_Control(pDX, IDC_SENDTRNSFER , m_rBtnSend);
	DDX_Control(pDX, IDC_STATIC_XM , m_strTx1);
	DDX_Control(pDX, IDC_COMBO_ADDR_OUT , m_addrbook);
}

BEGIN_MESSAGE_MAP(CSendDlg, CDialogBar)
	ON_BN_CLICKED(IDC_SENDTRNSFER, &CSendDlg::OnBnClickedSendtrnsfer)
	ON_CBN_SELCHANGE(IDC_COMBO_ADDR_OUT, &CSendDlg::OnCbnSelchangeCombo1)
	ON_MESSAGE(MSG_USER_SEND_UI , &CSendDlg::OnShowListaddrData  )
	ON_WM_CREATE()
	ON_WM_ERASEBKGND()
	ON_BN_CLICKED(IDC_BUTTON_ADDBOOK, &CSendDlg::OnBnClickedButtonAddbook)
END_MESSAGE_MAP()

// CTransfer Ϣ

void CSendDlg::SetBkBmpNid( UINT nBitmapIn )
{
	if( NULL != m_pBmp ) {
		::DeleteObject( m_pBmp ) ;
		m_pBmp = NULL ;
	}
	m_pBmp	= NULL ;
	HINSTANCE	hInstResource = NULL;
	hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmapIn), RT_BITMAP);
	if( NULL != hInstResource ) {
		m_pBmp = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapIn), IMAGE_BITMAP, 0, 0, 0);
	}
}

void CSendDlg::OnBnClickedSendtrnsfer()
{
	// TODO: ڴӿؼ֪ͨ
	if (m_mapAddrInfo.size() == 0)
	{
		::MessageBox( this->GetSafeHwnd() ,_T("͵ַ") , _T("ʾ") , MB_ICONINFORMATION ) ;
		return;
	}
	CString text;
	m_addrbook.GetWindowText(text) ;
	uistruct::LISTADDR_t data;
	if(text!=_T(""))
	{
		if(m_mapAddrInfo.count(text)<=0)
		{
			//::MessageBox( this->GetSafeHwnd() ,_T("͵ַ") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}
		//uistruct::LISTADDR_t te = m_pListaddrInfo[text];
		data = m_mapAddrInfo[text];

	}

		CString strCommand , strMaddress , strMoney;
		if(!data.bSign)
		{
			::MessageBox( this->GetSafeHwnd() ,_T("͵ַδ") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}

		GetDlgItem(IDC_EDIT_DESADDRESS)->GetWindowTextA(strMaddress);
		if (strMaddress == _T(""))
		{
			::MessageBox( this->GetSafeHwnd() ,_T("ַܵδ") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}
		if(!strcmp(strMaddress.GetString(), data.address))
		{
			::MessageBox( this->GetSafeHwnd() ,_T("͵ַĿĵַͬ") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}

		GetDlgItem(IDC_EDIT_MONEY)->GetWindowTextA(strMoney);
		double dSendMoney = atof(strMoney);
		if(dSendMoney > data.fMoney || ( data.fMoney>-0.0000001 && data.fMoney< 0.000001 ))
		{
			::MessageBox( this->GetSafeHwnd() ,_T("˻") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}

		if(_T("") == strMoney.GetString() || (dSendMoney >-0.0000001 && dSendMoney< 0.000001))
		{
			::MessageBox( this->GetSafeHwnd() ,_T("ͽΪ0") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}
		strCommand.Format(_T("%s %s %s %lld"),_T("sendtoaddress") ,data.address ,strMaddress ,REAL_MONEY(dSendMoney));
		CStringA strShowData ;

		CSoyPayHelp::getInstance()->SendRpc(strCommand,strShowData);

		Json::Reader reader;
		Json::Value root;

		if (!reader.parse(strShowData.GetString(), root))
		{
			::MessageBox( this->GetSafeHwnd() ,strShowData , _T("ʾ") , MB_ICONINFORMATION ) ;
			return  ;
		}
		BOOL bRes = FALSE ;
		CString strGettxdetail;
		int pos = strShowData.Find("hash");
		if ( pos >=0 ) {
			//뵽ݿ
			CString strHash,strHash1 ;
			strHash.Format(_T("'%s'") , root["hash"].asCString() );
			strHash1.Format(_T("%s") , root["hash"].asCString() );
			theApp.cs_SqlData.Lock();
			int nItem =  theApp.m_SqliteDeal.FindDB(_T("revtransaction") , strHash1 ,_T("hash") ) ;
			theApp.cs_SqlData.Unlock();

			if ( 0 == nItem ) {

				CPostMsg postmsg(MSG_USER_GET_UPDATABASE,WM_REVTRANSACTION);
				postmsg.SetData(strHash);
				theApp.m_MsgQueue.push(postmsg);
			}
		}

		CString strData;
		if ( pos >=0 ) {
			strData.Format( _T("ת˳ɹ\n%s") , root["hash"].asCString() ) ;
		}else{
			strData.Format( _T("תʧ!") ) ;
		}
		::MessageBox( this->GetSafeHwnd() ,strData , _T("ʾ") , MB_ICONINFORMATION ) ;

}

void CSendDlg::OnCbnSelchangeCombo1()
{
	// TODO: ڴӿؼ֪ͨ
	if (m_mapAddrInfo.size() == 0)
	{
		return;
	}
	CString text;
	m_addrbook.GetWindowText(text) ;
	if(text!=_T(""))
	{
	   if(m_mapAddrInfo.count(text)<=0)
	   {
		   TRACE("map OnCbnSelchangeCombo1 error");
		   return;
	   }
	//uistruct::LISTADDR_t te = m_pListaddrInfo[text];
	CString strshow;
	strshow.Format(_T("%.8f"),m_mapAddrInfo[text].fMoney);
	((CStatic*)GetDlgItem(IDC_STATIC_XM))->SetWindowText(strshow);
	Invalidate();
	}

}
BOOL CSendDlg::AddListaddrDataBox(){

	theApp.cs_SqlData.Lock();
	theApp.m_SqliteDeal.GetListaddrData(&m_mapAddrInfo);
	theApp.cs_SqlData.Unlock();

	if ( 0 == m_mapAddrInfo.size() ) return FALSE ;

	//ComBoxؼ
	((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->ResetContent();
	//صComBoxؼ
	int nItem = 0;
	std::map<CString,uistruct::LISTADDR_t>::const_iterator const_it;
	for ( const_it = m_mapAddrInfo.begin() ; const_it != m_mapAddrInfo.end() ; const_it++ ) {

		((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->InsertString(nItem , const_it->first );
		//((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->SetItemData(nItem, (DWORD_PTR)&(*const_it));
		nItem++;
	}
	((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->SetCurSel(0);

	CString address;
	m_addrbook.GetWindowText(address);
	std::map<CString,uistruct::LISTADDR_t>::const_iterator item = m_mapAddrInfo.find(address);
	//uistruct::LISTADDR_t pListAddr = m_pListaddrInfo.find(address);

	uistruct::LISTADDR_t *pListAddr = (uistruct::LISTADDR_t*)(((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->GetItemData(((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->GetCurSel())) ;

	if ( m_mapAddrInfo.end()!= item ) {
		uistruct::LISTADDR_t addrstruc = item->second;
	//	double money = CSoyPayHelp::getInstance()->GetAccountBalance(pListAddr->address);
		CString strshow;
		strshow.Format(_T("%.8f"),addrstruc.fMoney);
		m_strTx1.SetWindowText(strshow);
		//((CStatic*)GetDlgItem(IDC_STATIC_XM))->SetWindowText(strshow);
		Invalidate();
	}
	return TRUE ;
}

LRESULT CSendDlg::OnShowListaddrData( WPARAM wParam, LPARAM lParam )
{
	//
	int type = (int)wParam;
	switch(type)
	{
	case WM_UP_ADDRESS:
		{
			ModifyComboxItem();
			break;
		}
		break;
	case WM_UP_NEWADDRESS:
		{
			InsertComboxIitem();
			break;
		}
		break;
	default:
		break;

	}
	return 0 ;
}
// CSendDlg Ϣ

BOOL CSendDlg::Create(CWnd* pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID)
{
	// TODO: ڴרô/û

	BOOL bRes =   CDialogBar::Create(pParentWnd, nIDTemplate, nStyle, nID);
	if (bRes)
	{
		//m_rBtnSend.LoadBitmaps(IDB_BITMAP_BOTTON_SEND1,IDB_BITMAP_BOTTON_SEND2,IDB_BITMAP_BOTTON_SEND3,IDB_BITMAP_BOTTON_SEND3);
		m_rBtnAddbook.LoadBitmaps(IDB_BITMAP_ADDBOOK,IDB_BITMAP_ADDBOOK,IDB_BITMAP_ADDBOOK,IDB_BITMAP_ADDBOOK);
		UpdateData(0);
		m_strTx1.SetFont(120, _T(""));				//ʾʹС
		m_strTx1.SetWindowText(_T(""));
		AddListaddrDataBox();

		m_rBtnSend.SetBitmaps( IDB_BITMAP_BUTTON , RGB(255, 255, 0) , IDB_BITMAP_BUTTON , RGB(255, 255, 255) );
		m_rBtnSend.SetAlign(CButtonST::ST_ALIGN_OVERLAP);
		m_rBtnSend.SetWindowText("") ;
		m_rBtnSend.SetFontEx(24 , _T("΢ź"));
		m_rBtnSend.SetColor(CButtonST::BTNST_COLOR_FG_OUT , RGB(0, 0, 0));
		m_rBtnSend.SetColor(CButtonST::BTNST_COLOR_FG_IN , RGB(200, 75, 60));
		m_rBtnSend.SetColor(CButtonST::BTNST_COLOR_FG_FOCUS, RGB(0, 0, 0));
		m_rBtnSend.SetColor(CButtonST::BTNST_COLOR_BK_IN, RGB(0, 0, 0));
		m_rBtnSend.SizeToContent();

		theApp.SubscribeMsg( theApp.GetMtHthrdId() , GetSafeHwnd() , MSG_USER_SEND_UI ) ;
		((CComboBox*)GetDlgItem(IDC_COMBO2))->SetCurSel(0);

	}
	return bRes;
}

int CSendDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialogBar::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  ڴרõĴ
	SetBkBmpNid(IDB_BITMAP_SENDUI_BJ);

	return 0;
}

BOOL CSendDlg::OnEraseBkgnd(CDC* pDC)
{
	// TODO: ڴϢ/Ĭֵ
	CRect   rect;
	GetClientRect(&rect);

	if(m_pBmp   !=   NULL) {
		BITMAP   bm;
		CDC   dcMem;
		::GetObject(m_pBmp,sizeof(BITMAP),   (LPVOID)&bm);
		dcMem.CreateCompatibleDC(NULL);
		HBITMAP     pOldBitmap   =(HBITMAP   )   dcMem.SelectObject(m_pBmp);
		pDC-> StretchBlt(rect.left,rect.top-1,rect.Width(),rect.Height(),   &dcMem,   0,   0,bm.bmWidth-1,bm.bmHeight-1,   SRCCOPY);

		dcMem.SelectObject(pOldBitmap);
		dcMem.DeleteDC();
	} else
		CWnd::OnEraseBkgnd(pDC);

	return 1;
}

void CSendDlg::OnBnClickedButtonAddbook()
{
	// TODO: ڴӿؼ֪ͨ
}
void CSendDlg::ModifyComboxItem(){
	CPostMsg postmsg;
	if (!theApp.m_UiSendDlgQueue.pop(postmsg))
	{
		return ;
	}

	uistruct::LISTADDR_t addr;
	string strTemp = postmsg.GetData();
	addr.JsonToStruct(strTemp.c_str());

	CString addressd;
	addressd.Format(_T("%s"),addr.address);

	if(m_mapAddrInfo.count(addressd)<=0)
	{
		TRACE("map ModifyComboxItem error");
		return;
	}
	m_mapAddrInfo[addressd]=addr;

}
void CSendDlg::InsertComboxIitem()
{
	CPostMsg postmsg;
	if (!theApp.m_UiSendDlgQueue.pop(postmsg))
	{
		return ;
	}

	uistruct::LISTADDR_t addr;
	string strTemp = postmsg.GetData();
	addr.JsonToStruct(strTemp.c_str());

	CString addressd;
	addressd.Format(_T("%s"),addr.address);

	if(m_mapAddrInfo.count(addressd)>0)
	{
		TRACE("map InsertComboxIitem error");
		return;
	}
	m_mapAddrInfo[addressd]=addr;

	int item = m_addrbook.GetCount();
	m_addrbook.InsertString(item,addressd);
}
<commit_msg>modify OnCbnSelchangeCombo1 funciton<commit_after>// SendDlg.cpp : ʵļ
//

#include "stdafx.h"
#include "DacrsUI.h"
#include "SendDlg.h"
#include "afxdialogex.h"

// CSendDlg Ի

IMPLEMENT_DYNAMIC(CSendDlg, CDialogBar)

CSendDlg::CSendDlg()
{
	m_pBmp = NULL ;
}

CSendDlg::~CSendDlg()
{
	if( NULL != m_pBmp ) {
		DeleteObject(m_pBmp) ;
		m_pBmp = NULL ;
	}
}

void CSendDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogBar::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON_ADDBOOK , m_rBtnAddbook);
	DDX_Control(pDX, IDC_SENDTRNSFER , m_rBtnSend);
	DDX_Control(pDX, IDC_STATIC_XM , m_strTx1);
	DDX_Control(pDX, IDC_COMBO_ADDR_OUT , m_addrbook);
}

BEGIN_MESSAGE_MAP(CSendDlg, CDialogBar)
	ON_BN_CLICKED(IDC_SENDTRNSFER, &CSendDlg::OnBnClickedSendtrnsfer)
	ON_CBN_SELCHANGE(IDC_COMBO_ADDR_OUT, &CSendDlg::OnCbnSelchangeCombo1)
	ON_MESSAGE(MSG_USER_SEND_UI , &CSendDlg::OnShowListaddrData  )
	ON_WM_CREATE()
	ON_WM_ERASEBKGND()
	ON_BN_CLICKED(IDC_BUTTON_ADDBOOK, &CSendDlg::OnBnClickedButtonAddbook)
END_MESSAGE_MAP()

// CTransfer Ϣ

void CSendDlg::SetBkBmpNid( UINT nBitmapIn )
{
	if( NULL != m_pBmp ) {
		::DeleteObject( m_pBmp ) ;
		m_pBmp = NULL ;
	}
	m_pBmp	= NULL ;
	HINSTANCE	hInstResource = NULL;
	hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmapIn), RT_BITMAP);
	if( NULL != hInstResource ) {
		m_pBmp = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapIn), IMAGE_BITMAP, 0, 0, 0);
	}
}

void CSendDlg::OnBnClickedSendtrnsfer()
{
	// TODO: ڴӿؼ֪ͨ
	if (m_mapAddrInfo.size() == 0)
	{
		::MessageBox( this->GetSafeHwnd() ,_T("͵ַ") , _T("ʾ") , MB_ICONINFORMATION ) ;
		return;
	}
	CString text;
	m_addrbook.GetWindowText(text) ;
	uistruct::LISTADDR_t data;
	if(text!=_T(""))
	{
		if(m_mapAddrInfo.count(text)<=0)
		{
			//::MessageBox( this->GetSafeHwnd() ,_T("͵ַ") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}
		//uistruct::LISTADDR_t te = m_pListaddrInfo[text];
		data = m_mapAddrInfo[text];

	}

		CString strCommand , strMaddress , strMoney;
		if(!data.bSign)
		{
			::MessageBox( this->GetSafeHwnd() ,_T("͵ַδ") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}

		GetDlgItem(IDC_EDIT_DESADDRESS)->GetWindowTextA(strMaddress);
		if (strMaddress == _T(""))
		{
			::MessageBox( this->GetSafeHwnd() ,_T("ַܵδ") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}
		if(!strcmp(strMaddress.GetString(), data.address))
		{
			::MessageBox( this->GetSafeHwnd() ,_T("͵ַĿĵַͬ") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}

		GetDlgItem(IDC_EDIT_MONEY)->GetWindowTextA(strMoney);
		double dSendMoney = atof(strMoney);
		if(dSendMoney > data.fMoney || ( data.fMoney>-0.0000001 && data.fMoney< 0.000001 ))
		{
			::MessageBox( this->GetSafeHwnd() ,_T("˻") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}

		if(_T("") == strMoney.GetString() || (dSendMoney >-0.0000001 && dSendMoney< 0.000001))
		{
			::MessageBox( this->GetSafeHwnd() ,_T("ͽΪ0") , _T("ʾ") , MB_ICONINFORMATION ) ;
			return;
		}
		strCommand.Format(_T("%s %s %s %lld"),_T("sendtoaddress") ,data.address ,strMaddress ,REAL_MONEY(dSendMoney));
		CStringA strShowData ;

		CSoyPayHelp::getInstance()->SendRpc(strCommand,strShowData);

		Json::Reader reader;
		Json::Value root;

		if (!reader.parse(strShowData.GetString(), root))
		{
			::MessageBox( this->GetSafeHwnd() ,strShowData , _T("ʾ") , MB_ICONINFORMATION ) ;
			return  ;
		}
		BOOL bRes = FALSE ;
		CString strGettxdetail;
		int pos = strShowData.Find("hash");
		if ( pos >=0 ) {
			//뵽ݿ
			CString strHash,strHash1 ;
			strHash.Format(_T("'%s'") , root["hash"].asCString() );
			strHash1.Format(_T("%s") , root["hash"].asCString() );
			theApp.cs_SqlData.Lock();
			int nItem =  theApp.m_SqliteDeal.FindDB(_T("revtransaction") , strHash1 ,_T("hash") ) ;
			theApp.cs_SqlData.Unlock();

			if ( 0 == nItem ) {

				CPostMsg postmsg(MSG_USER_GET_UPDATABASE,WM_REVTRANSACTION);
				postmsg.SetData(strHash);
				theApp.m_MsgQueue.push(postmsg);
			}
		}

		CString strData;
		if ( pos >=0 ) {
			strData.Format( _T("ת˳ɹ\n%s") , root["hash"].asCString() ) ;
		}else{
			strData.Format( _T("תʧ!") ) ;
		}
		::MessageBox( this->GetSafeHwnd() ,strData , _T("ʾ") , MB_ICONINFORMATION ) ;

}

void CSendDlg::OnCbnSelchangeCombo1()
{
	// TODO: ڴӿؼ֪ͨ
	if (m_mapAddrInfo.size() == 0)
	{
		return;
	}
	CString text;
	int sel = m_addrbook.GetCurSel();
	m_addrbook.GetLBText(sel,text);

	//m_addrbook.GetWindowText(text) ;
	if(text!=_T(""))
	{
	   if(m_mapAddrInfo.count(text)<=0)
	   {
		   TRACE("map OnCbnSelchangeCombo1 error");
		   return;
	   }
	//uistruct::LISTADDR_t te = m_pListaddrInfo[text];
	CString strshow;
	strshow.Format(_T("%.8f"),m_mapAddrInfo[text].fMoney);
	((CStatic*)GetDlgItem(IDC_STATIC_XM))->SetWindowText(strshow);
	Invalidate();
	}

}
BOOL CSendDlg::AddListaddrDataBox(){

	theApp.cs_SqlData.Lock();
	theApp.m_SqliteDeal.GetListaddrData(&m_mapAddrInfo);
	theApp.cs_SqlData.Unlock();

	if ( 0 == m_mapAddrInfo.size() ) return FALSE ;

	//ComBoxؼ
	((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->ResetContent();
	//صComBoxؼ
	int nItem = 0;
	std::map<CString,uistruct::LISTADDR_t>::const_iterator const_it;
	for ( const_it = m_mapAddrInfo.begin() ; const_it != m_mapAddrInfo.end() ; const_it++ ) {

		((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->InsertString(nItem , const_it->first );
		//((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->SetItemData(nItem, (DWORD_PTR)&(*const_it));
		nItem++;
	}
	((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->SetCurSel(0);

	CString address;
	m_addrbook.GetWindowText(address);
	std::map<CString,uistruct::LISTADDR_t>::const_iterator item = m_mapAddrInfo.find(address);
	//uistruct::LISTADDR_t pListAddr = m_pListaddrInfo.find(address);

	uistruct::LISTADDR_t *pListAddr = (uistruct::LISTADDR_t*)(((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->GetItemData(((CComboBox*)GetDlgItem(IDC_COMBO_ADDR_OUT))->GetCurSel())) ;

	if ( m_mapAddrInfo.end()!= item ) {
		uistruct::LISTADDR_t addrstruc = item->second;
	//	double money = CSoyPayHelp::getInstance()->GetAccountBalance(pListAddr->address);
		CString strshow;
		strshow.Format(_T("%.8f"),addrstruc.fMoney);
		m_strTx1.SetWindowText(strshow);
		//((CStatic*)GetDlgItem(IDC_STATIC_XM))->SetWindowText(strshow);
		Invalidate();
	}
	return TRUE ;
}

LRESULT CSendDlg::OnShowListaddrData( WPARAM wParam, LPARAM lParam )
{
	//
	int type = (int)wParam;
	switch(type)
	{
	case WM_UP_ADDRESS:
		{
			ModifyComboxItem();
			break;
		}
		break;
	case WM_UP_NEWADDRESS:
		{
			InsertComboxIitem();
			break;
		}
		break;
	default:
		break;

	}
	return 0 ;
}
// CSendDlg Ϣ

BOOL CSendDlg::Create(CWnd* pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID)
{
	// TODO: ڴרô/û

	BOOL bRes =   CDialogBar::Create(pParentWnd, nIDTemplate, nStyle, nID);
	if (bRes)
	{
		//m_rBtnSend.LoadBitmaps(IDB_BITMAP_BOTTON_SEND1,IDB_BITMAP_BOTTON_SEND2,IDB_BITMAP_BOTTON_SEND3,IDB_BITMAP_BOTTON_SEND3);
		m_rBtnAddbook.LoadBitmaps(IDB_BITMAP_ADDBOOK,IDB_BITMAP_ADDBOOK,IDB_BITMAP_ADDBOOK,IDB_BITMAP_ADDBOOK);
		UpdateData(0);
		m_strTx1.SetFont(120, _T(""));				//ʾʹС
		m_strTx1.SetWindowText(_T(""));
		AddListaddrDataBox();

		m_rBtnSend.SetBitmaps( IDB_BITMAP_BUTTON , RGB(255, 255, 0) , IDB_BITMAP_BUTTON , RGB(255, 255, 255) );
		m_rBtnSend.SetAlign(CButtonST::ST_ALIGN_OVERLAP);
		m_rBtnSend.SetWindowText("") ;
		m_rBtnSend.SetFontEx(24 , _T("΢ź"));
		m_rBtnSend.SetColor(CButtonST::BTNST_COLOR_FG_OUT , RGB(0, 0, 0));
		m_rBtnSend.SetColor(CButtonST::BTNST_COLOR_FG_IN , RGB(200, 75, 60));
		m_rBtnSend.SetColor(CButtonST::BTNST_COLOR_FG_FOCUS, RGB(0, 0, 0));
		m_rBtnSend.SetColor(CButtonST::BTNST_COLOR_BK_IN, RGB(0, 0, 0));
		m_rBtnSend.SizeToContent();

		theApp.SubscribeMsg( theApp.GetMtHthrdId() , GetSafeHwnd() , MSG_USER_SEND_UI ) ;
		((CComboBox*)GetDlgItem(IDC_COMBO2))->SetCurSel(0);

	}
	return bRes;
}

int CSendDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialogBar::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  ڴרõĴ
	SetBkBmpNid(IDB_BITMAP_SENDUI_BJ);

	return 0;
}

BOOL CSendDlg::OnEraseBkgnd(CDC* pDC)
{
	// TODO: ڴϢ/Ĭֵ
	CRect   rect;
	GetClientRect(&rect);

	if(m_pBmp   !=   NULL) {
		BITMAP   bm;
		CDC   dcMem;
		::GetObject(m_pBmp,sizeof(BITMAP),   (LPVOID)&bm);
		dcMem.CreateCompatibleDC(NULL);
		HBITMAP     pOldBitmap   =(HBITMAP   )   dcMem.SelectObject(m_pBmp);
		pDC-> StretchBlt(rect.left,rect.top-1,rect.Width(),rect.Height(),   &dcMem,   0,   0,bm.bmWidth-1,bm.bmHeight-1,   SRCCOPY);

		dcMem.SelectObject(pOldBitmap);
		dcMem.DeleteDC();
	} else
		CWnd::OnEraseBkgnd(pDC);

	return 1;
}

void CSendDlg::OnBnClickedButtonAddbook()
{
	// TODO: ڴӿؼ֪ͨ
}
void CSendDlg::ModifyComboxItem(){
	CPostMsg postmsg;
	if (!theApp.m_UiSendDlgQueue.pop(postmsg))
	{
		return ;
	}

	uistruct::LISTADDR_t addr;
	string strTemp = postmsg.GetData();
	addr.JsonToStruct(strTemp.c_str());

	CString addressd;
	addressd.Format(_T("%s"),addr.address);

	if(m_mapAddrInfo.count(addressd)<=0)
	{
		TRACE("map ModifyComboxItem error");
		return;
	}
	m_mapAddrInfo[addressd]=addr;

}
void CSendDlg::InsertComboxIitem()
{
	CPostMsg postmsg;
	if (!theApp.m_UiSendDlgQueue.pop(postmsg))
	{
		return ;
	}

	uistruct::LISTADDR_t addr;
	string strTemp = postmsg.GetData();
	addr.JsonToStruct(strTemp.c_str());

	CString addressd;
	addressd.Format(_T("%s"),addr.address);

	if(m_mapAddrInfo.count(addressd)>0)
	{
		TRACE("map InsertComboxIitem error");
		return;
	}
	m_mapAddrInfo[addressd]=addr;

	int item = m_addrbook.GetCount();
	m_addrbook.InsertString(item,addressd);
}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief ThreadCommon class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-11-13
 */

#ifndef INCLUDE_DISTORTOS_THREADCOMMON_HPP_
#define INCLUDE_DISTORTOS_THREADCOMMON_HPP_

#include "distortos/Semaphore.hpp"
#include "distortos/Thread.hpp"

namespace distortos
{

/// ThreadCommon class implements common functionality of threads
class ThreadCommon : public Thread
{
public:

	/// unique_ptr (with deleter) to storage for stack
	using StackStorageUniquePointer = architecture::Stack::StorageUniquePointer;

	/**
	 * \brief ThreadCommon's constructor
	 *
	 * \param [in] stackStorageUniquePointer is a rvalue reference to StackStorageUniquePointer with storage for stack
	 * (\a size bytes long) and appropriate deleter
	 * \param [in] size is the size of stack's storage, bytes
	 * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
	 * \param [in] schedulingPolicy is the scheduling policy of the thread
	 * \param [in] threadGroupControlBlock is a pointer to scheduler::ThreadGroupControlBlock to which this object will
	 * be added, nullptr to inherit thread group from currently running thread
	 * \param [in] signalsReceiver is a pointer to SignalsReceiver object for this thread, nullptr to disable reception
	 * of signals for this thread
	 */

	ThreadCommon(StackStorageUniquePointer&& stackStorageUniquePointer, size_t size, uint8_t priority,
			SchedulingPolicy schedulingPolicy, scheduler::ThreadGroupControlBlock* threadGroupControlBlock,
			SignalsReceiver* signalsReceiver);

	/**
	 * \brief ThreadCommon's constructor
	 *
	 * \param [in] stack is an rvalue reference to architecture::Stack object which will be adopted for this thread
	 * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
	 * \param [in] schedulingPolicy is the scheduling policy of the thread
	 * \param [in] threadGroupControlBlock is a pointer to scheduler::ThreadGroupControlBlock to which this object will
	 * be added, nullptr to inherit thread group from currently running thread
	 * \param [in] signalsReceiver is a pointer to SignalsReceiver object for this thread, nullptr to disable reception
	 * of signals for this thread
	 */

	ThreadCommon(architecture::Stack&& stack, uint8_t priority, SchedulingPolicy schedulingPolicy,
			scheduler::ThreadGroupControlBlock* threadGroupControlBlock, SignalsReceiver* signalsReceiver);

	/**
	 * \brief Generates signal for thread.
	 *
	 * Similar to pthread_kill() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html
	 *
	 * Adds the signalNumber to set of pending signals. If this thread is currently waiting for this signal, it will be
	 * unblocked.
	 *
	 * \param [in] signalNumber is the signal that will be generated, [0; 31]
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - \a signalNumber value is invalid;
	 * - ENOTSUP - reception of signals is disabled for this thread;
	 */

	virtual int generateSignal(uint8_t signalNumber) override;

	/**
	 * \return effective priority of thread
	 */

	virtual uint8_t getEffectivePriority() const override;

	/**
	 * \brief Gets set of currently pending signals.
	 *
	 * Similar to sigpending() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpending.html
	 *
	 * This function shall return the set of signals that are blocked from delivery and are pending on the thread.
	 *
	 * \return set of currently pending signals
	 */

	virtual SignalSet getPendingSignalSet() const override;

	/**
	 * \return priority of thread
	 */

	virtual uint8_t getPriority() const override;

	/**
	 * \return scheduling policy of the thread
	 */

	virtual SchedulingPolicy getSchedulingPolicy() const override;

	/**
	 * \return current state of thread
	 */

	virtual scheduler::ThreadControlBlock::State getState() const override;

	/**
	 * \brief Waits for thread termination.
	 *
	 * Similar to std::thread::join() - http://en.cppreference.com/w/cpp/thread/thread/join
	 * Similar to POSIX pthread_join() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html
	 *
	 * Blocks current thread until this thread finishes its execution. The results of multiple simultaneous calls to
	 * join() on the same target thread are undefined.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EDEADLK - deadlock condition was detected,
	 * - EINVAL - this thread is not joinable,
	 * - ...
	 */

	virtual int join() override;

	/**
	 * \brief Queues signal for thread.
	 *
	 * Similar to sigqueue() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigqueue.html
	 *
	 * Adds the signalNumber and signal value (sigval union) to queue of SignalInformation objects. If this thread is
	 * currently waiting for this signal, it will be unblocked.
	 *
	 * \param [in] signalNumber is the signal that will be queued, [0; 31]
	 * \param [in] value is the signal value
	 *
	 * \return 0 on success, error code otherwise:
	 * - EAGAIN - no resources are available to queue the signal, maximal number of signals is already queued in
	 * associated queue of SignalInformation objects;
	 * - EINVAL - \a signalNumber value is invalid;
	 * - ENOTSUP - reception or queuing of signals are disabled for this thread;
	 */

	virtual int queueSignal(uint8_t signalNumber, sigval value) override;

	/**
	 * \brief Changes priority of thread.
	 *
	 * If the priority really changes, the position in the thread list is adjusted and context switch may be requested.
	 *
	 * \param [in] priority is the new priority of thread
	 * \param [in] alwaysBehind selects the method of ordering when lowering the priority
	 * - false - the thread is moved to the head of the group of threads with the new priority (default),
	 * - true - the thread is moved to the tail of the group of threads with the new priority.
	 */

	virtual void setPriority(uint8_t priority, bool alwaysBehind = {}) override;

	/**
	 * param [in] schedulingPolicy is the new scheduling policy of the thread
	 */

	virtual void setSchedulingPolicy(SchedulingPolicy schedulingPolicy) override;

	/**
	 * \brief Starts the thread.
	 *
	 * This operation can be performed on threads in "New" state only.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - thread is already started;
	 * - error codes returned by scheduler::Scheduler::add();
	 */

	virtual int start() override;

protected:

	/**
	 * \return reference to internal ThreadControlBlock object
	 */

	scheduler::ThreadControlBlock& getThreadControlBlock();

	/**
	 * \return const reference to internal ThreadControlBlock object
	 */

	const scheduler::ThreadControlBlock& getThreadControlBlock() const;

private:

	/**
	 * \brief Termination hook function of thread
	 *
	 * This function is called after run() completes, from Scheduler::remove().
	 */

	virtual void terminationHook() override;

	/// internal ThreadControlBlock object
	scheduler::ThreadControlBlock threadControlBlock_;

	/// semaphore used by join()
	Semaphore joinSemaphore_;
};

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_THREADCOMMON_HPP_
<commit_msg>ThreadCommon: explicitly make the class move-constructible<commit_after>/**
 * \file
 * \brief ThreadCommon class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-11-13
 */

#ifndef INCLUDE_DISTORTOS_THREADCOMMON_HPP_
#define INCLUDE_DISTORTOS_THREADCOMMON_HPP_

#include "distortos/Semaphore.hpp"
#include "distortos/Thread.hpp"

namespace distortos
{

/// ThreadCommon class implements common functionality of threads
class ThreadCommon : public Thread
{
public:

	/// unique_ptr (with deleter) to storage for stack
	using StackStorageUniquePointer = architecture::Stack::StorageUniquePointer;

	/**
	 * \brief ThreadCommon's constructor
	 *
	 * \param [in] stackStorageUniquePointer is a rvalue reference to StackStorageUniquePointer with storage for stack
	 * (\a size bytes long) and appropriate deleter
	 * \param [in] size is the size of stack's storage, bytes
	 * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
	 * \param [in] schedulingPolicy is the scheduling policy of the thread
	 * \param [in] threadGroupControlBlock is a pointer to scheduler::ThreadGroupControlBlock to which this object will
	 * be added, nullptr to inherit thread group from currently running thread
	 * \param [in] signalsReceiver is a pointer to SignalsReceiver object for this thread, nullptr to disable reception
	 * of signals for this thread
	 */

	ThreadCommon(StackStorageUniquePointer&& stackStorageUniquePointer, size_t size, uint8_t priority,
			SchedulingPolicy schedulingPolicy, scheduler::ThreadGroupControlBlock* threadGroupControlBlock,
			SignalsReceiver* signalsReceiver);

	/**
	 * \brief ThreadCommon's constructor
	 *
	 * \param [in] stack is an rvalue reference to architecture::Stack object which will be adopted for this thread
	 * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
	 * \param [in] schedulingPolicy is the scheduling policy of the thread
	 * \param [in] threadGroupControlBlock is a pointer to scheduler::ThreadGroupControlBlock to which this object will
	 * be added, nullptr to inherit thread group from currently running thread
	 * \param [in] signalsReceiver is a pointer to SignalsReceiver object for this thread, nullptr to disable reception
	 * of signals for this thread
	 */

	ThreadCommon(architecture::Stack&& stack, uint8_t priority, SchedulingPolicy schedulingPolicy,
			scheduler::ThreadGroupControlBlock* threadGroupControlBlock, SignalsReceiver* signalsReceiver);

	/**
	 * \brief Generates signal for thread.
	 *
	 * Similar to pthread_kill() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html
	 *
	 * Adds the signalNumber to set of pending signals. If this thread is currently waiting for this signal, it will be
	 * unblocked.
	 *
	 * \param [in] signalNumber is the signal that will be generated, [0; 31]
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - \a signalNumber value is invalid;
	 * - ENOTSUP - reception of signals is disabled for this thread;
	 */

	virtual int generateSignal(uint8_t signalNumber) override;

	/**
	 * \return effective priority of thread
	 */

	virtual uint8_t getEffectivePriority() const override;

	/**
	 * \brief Gets set of currently pending signals.
	 *
	 * Similar to sigpending() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpending.html
	 *
	 * This function shall return the set of signals that are blocked from delivery and are pending on the thread.
	 *
	 * \return set of currently pending signals
	 */

	virtual SignalSet getPendingSignalSet() const override;

	/**
	 * \return priority of thread
	 */

	virtual uint8_t getPriority() const override;

	/**
	 * \return scheduling policy of the thread
	 */

	virtual SchedulingPolicy getSchedulingPolicy() const override;

	/**
	 * \return current state of thread
	 */

	virtual scheduler::ThreadControlBlock::State getState() const override;

	/**
	 * \brief Waits for thread termination.
	 *
	 * Similar to std::thread::join() - http://en.cppreference.com/w/cpp/thread/thread/join
	 * Similar to POSIX pthread_join() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html
	 *
	 * Blocks current thread until this thread finishes its execution. The results of multiple simultaneous calls to
	 * join() on the same target thread are undefined.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EDEADLK - deadlock condition was detected,
	 * - EINVAL - this thread is not joinable,
	 * - ...
	 */

	virtual int join() override;

	/**
	 * \brief Queues signal for thread.
	 *
	 * Similar to sigqueue() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigqueue.html
	 *
	 * Adds the signalNumber and signal value (sigval union) to queue of SignalInformation objects. If this thread is
	 * currently waiting for this signal, it will be unblocked.
	 *
	 * \param [in] signalNumber is the signal that will be queued, [0; 31]
	 * \param [in] value is the signal value
	 *
	 * \return 0 on success, error code otherwise:
	 * - EAGAIN - no resources are available to queue the signal, maximal number of signals is already queued in
	 * associated queue of SignalInformation objects;
	 * - EINVAL - \a signalNumber value is invalid;
	 * - ENOTSUP - reception or queuing of signals are disabled for this thread;
	 */

	virtual int queueSignal(uint8_t signalNumber, sigval value) override;

	/**
	 * \brief Changes priority of thread.
	 *
	 * If the priority really changes, the position in the thread list is adjusted and context switch may be requested.
	 *
	 * \param [in] priority is the new priority of thread
	 * \param [in] alwaysBehind selects the method of ordering when lowering the priority
	 * - false - the thread is moved to the head of the group of threads with the new priority (default),
	 * - true - the thread is moved to the tail of the group of threads with the new priority.
	 */

	virtual void setPriority(uint8_t priority, bool alwaysBehind = {}) override;

	/**
	 * param [in] schedulingPolicy is the new scheduling policy of the thread
	 */

	virtual void setSchedulingPolicy(SchedulingPolicy schedulingPolicy) override;

	/**
	 * \brief Starts the thread.
	 *
	 * This operation can be performed on threads in "New" state only.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - thread is already started;
	 * - error codes returned by scheduler::Scheduler::add();
	 */

	virtual int start() override;

	ThreadCommon(const ThreadCommon&) = delete;
	ThreadCommon(ThreadCommon&&) = default;
	const ThreadCommon& operator=(const ThreadCommon&) = delete;
	ThreadCommon& operator=(ThreadCommon&&) = delete;

protected:

	/**
	 * \return reference to internal ThreadControlBlock object
	 */

	scheduler::ThreadControlBlock& getThreadControlBlock();

	/**
	 * \return const reference to internal ThreadControlBlock object
	 */

	const scheduler::ThreadControlBlock& getThreadControlBlock() const;

private:

	/**
	 * \brief Termination hook function of thread
	 *
	 * This function is called after run() completes, from Scheduler::remove().
	 */

	virtual void terminationHook() override;

	/// internal ThreadControlBlock object
	scheduler::ThreadControlBlock threadControlBlock_;

	/// semaphore used by join()
	Semaphore joinSemaphore_;
};

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_THREADCOMMON_HPP_
<|endoftext|>


<commit_before>#ifndef ITKGLCMIMAGECALCULATOR_HXX
#define ITKGLCMCIMAGEALCULATOR_HXX

#include "itkGLCMImageCalculator.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "itkNumericTraits.h"

namespace itk
{
namespace Statistics
{

template< typename TInputImage, typename TGLCMType >
GLCMImageCalculator< TInputImage, TGLCMType >
::GLCMImageCalculator():
  m_Image(TInputImage::New()),
  m_RegionSetByUser(false),
  m_CooccurrenceMatrix(GLCMType::New())
{}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::Compute(void)
{
  if(m_MatrixSize != m_CooccurrenceMatrix->GetSize())
    {
    this->m_CooccurrenceMatrix->SetSize(m_MatrixSize);
    }

  if ( !m_RegionSetByUser )
    {
    m_Region = m_Image->GetRequestedRegion();
    }

  if(!m_Image->GetBufferedRegion().IsInside(m_Region))
    {
     itkExceptionMacro( << "The requested region is outside of the buffered region" );
    }

  itkDebugMacro( << "Processing region: " << m_Region );

  itk::ImageRegionConstIteratorWithIndex< ImageType > iterator(m_Image, m_Region);
  PixelType centerPixelIntensity, offsetPixelIntensity;
  typename ImageType::IndexType centerPixelIndex, offsetPixelIndex;
  typename OffsetVectorType::ConstIterator off_it, off_it_begin = m_Offsets->Begin(), off_it_end = m_Offsets->End();

  iterator.GoToBegin();
  while(!iterator.IsAtEnd())
  {
    centerPixelIndex = iterator.GetIndex();

    itkDebugMacro( << "Processing pixel at " << centerPixelIndex );

    centerPixelIntensity = m_Image->GetPixel(centerPixelIndex);
    // don't put a pixel in the histogram if the value is out of bound
    if ( centerPixelIntensity >= 0 && centerPixelIntensity < m_MatrixSize )
      {
      for ( off_it = off_it_begin; off_it != off_it_end; ++off_it )
        {
        offsetPixelIndex = centerPixelIndex + off_it.Value();

        itkDebugMacro( << "\tProcessing pixel at " << offsetPixelIndex );

        if(m_Region.IsInside(offsetPixelIndex))
          {
          offsetPixelIntensity = m_Image->GetPixel(offsetPixelIndex);

          // don't put a pixel in the histogram if the value is out-of-bounds.
          if ( offsetPixelIntensity >= 0 && offsetPixelIntensity < m_MatrixSize )
            {
            m_CooccurrenceMatrix->IncrementCounter(centerPixelIntensity, offsetPixelIntensity);
            m_CooccurrenceMatrix->IncrementCounter(offsetPixelIntensity, centerPixelIntensity);
            }
          else
            {
              itkExceptionMacro( << "Value (" << offsetPixelIntensity << ") out of bound [0; " << m_MatrixSize << "[" );
            }
          }
        }
      }
      else
      {
        itkExceptionMacro( << "Value (" << centerPixelIntensity << ") out of bound [0; " << m_MatrixSize << "[" );
      }

    ++iterator;
  }
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::SetRegion(const RegionType & region)
{
  m_Region = region;
  m_RegionSetByUser = true;
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::ResetMatrix()
{
  m_CooccurrenceMatrix->SetToZero();
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::SetOffsets(const OffsetVectorType * os)
{
  itkDebugMacro("setting offsets to " << os);
  this->m_Offsets = os;
  this->Modified();
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::SetOffset(const OffsetType offset)
{
  OffsetVectorPointer offsetVector = OffsetVectorType::New();

  offsetVector->push_back(offset);
  this->SetOffsets(offsetVector);

  this->Modified();
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "Image: " << std::endl;
  m_Image->Print( os, indent.GetNextIndent() );
  os << indent << "Region: " << std::endl;
  m_Region.Print( os, indent.GetNextIndent() );
  os << indent << "Region set by User: " << m_RegionSetByUser << std::endl;
}

} // end namespace Statistics
} // end namespace itk

#endif /* ITKGLCMIMAGECALCULATOR_HXX */
<commit_msg>Ajoute un appel manquant à modified() dans le calculateur de matrice de cooccurrence.<commit_after>#ifndef ITKGLCMIMAGECALCULATOR_HXX
#define ITKGLCMCIMAGEALCULATOR_HXX

#include "itkGLCMImageCalculator.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "itkNumericTraits.h"

namespace itk
{
namespace Statistics
{

template< typename TInputImage, typename TGLCMType >
GLCMImageCalculator< TInputImage, TGLCMType >
::GLCMImageCalculator():
  m_Image(TInputImage::New()),
  m_RegionSetByUser(false),
  m_CooccurrenceMatrix(GLCMType::New())
{}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::Compute(void)
{
  if(m_MatrixSize != m_CooccurrenceMatrix->GetSize())
    {
    this->m_CooccurrenceMatrix->SetSize(m_MatrixSize);
    }

  if ( !m_RegionSetByUser )
    {
    m_Region = m_Image->GetRequestedRegion();
    }

  if(!m_Image->GetBufferedRegion().IsInside(m_Region))
    {
     itkExceptionMacro( << "The requested region is outside of the buffered region" );
    }

  itkDebugMacro( << "Processing region: " << m_Region );

  itk::ImageRegionConstIteratorWithIndex< ImageType > iterator(m_Image, m_Region);
  PixelType centerPixelIntensity, offsetPixelIntensity;
  typename ImageType::IndexType centerPixelIndex, offsetPixelIndex;
  typename OffsetVectorType::ConstIterator off_it, off_it_begin = m_Offsets->Begin(), off_it_end = m_Offsets->End();

  iterator.GoToBegin();
  while(!iterator.IsAtEnd())
  {
    centerPixelIndex = iterator.GetIndex();

    itkDebugMacro( << "Processing pixel at " << centerPixelIndex );

    centerPixelIntensity = m_Image->GetPixel(centerPixelIndex);
    // don't put a pixel in the histogram if the value is out of bound
    if ( centerPixelIntensity >= 0 && centerPixelIntensity < m_MatrixSize )
      {
      for ( off_it = off_it_begin; off_it != off_it_end; ++off_it )
        {
        offsetPixelIndex = centerPixelIndex + off_it.Value();

        itkDebugMacro( << "\tProcessing pixel at " << offsetPixelIndex );

        if(m_Region.IsInside(offsetPixelIndex))
          {
          offsetPixelIntensity = m_Image->GetPixel(offsetPixelIndex);

          // don't put a pixel in the histogram if the value is out-of-bounds.
          if ( offsetPixelIntensity >= 0 && offsetPixelIntensity < m_MatrixSize )
            {
            m_CooccurrenceMatrix->IncrementCounter(centerPixelIntensity, offsetPixelIntensity);
            m_CooccurrenceMatrix->IncrementCounter(offsetPixelIntensity, centerPixelIntensity);
            }
          else
            {
              itkExceptionMacro( << "Value (" << offsetPixelIntensity << ") out of bound [0; " << m_MatrixSize << "[" );
            }
          }
        }
      }
      else
      {
        itkExceptionMacro( << "Value (" << centerPixelIntensity << ") out of bound [0; " << m_MatrixSize << "[" );
      }

    ++iterator;
  }
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::SetRegion(const RegionType & region)
{
  m_Region = region;
  m_RegionSetByUser = true;

  this->Modified();
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::ResetMatrix()
{
  m_CooccurrenceMatrix->SetToZero();
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::SetOffsets(const OffsetVectorType * os)
{
  itkDebugMacro("setting offsets to " << os);
  this->m_Offsets = os;
  this->Modified();
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::SetOffset(const OffsetType offset)
{
  OffsetVectorPointer offsetVector = OffsetVectorType::New();

  offsetVector->push_back(offset);
  this->SetOffsets(offsetVector);

  this->Modified();
}

template< typename TInputImage, typename TGLCMType >
void
GLCMImageCalculator< TInputImage, TGLCMType >
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "Image: " << std::endl;
  m_Image->Print( os, indent.GetNextIndent() );
  os << indent << "Region: " << std::endl;
  m_Region.Print( os, indent.GetNextIndent() );
  os << indent << "Region set by User: " << m_RegionSetByUser << std::endl;
}

} // end namespace Statistics
} // end namespace itk

#endif /* ITKGLCMIMAGECALCULATOR_HXX */
<|endoftext|>


<commit_before>// Copyright 2021 The Cross-Media Measurement Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "wfa/virtual_people/core/model/utils/distributed_consistent_hashing.h"

#include "absl/container/flat_hash_map.h"
#include "absl/memory/memory.h"
#include "absl/status/statusor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "src/test/cc/testutil/matchers.h"
#include "src/test/cc/testutil/status_macros.h"

namespace wfa_virtual_people {
namespace {

using ::testing::DoubleNear;
using ::testing::Pair;
using ::testing::UnorderedElementsAre;
using ::wfa::StatusIs;

constexpr int kSeedNumber = 10000;

TEST(DistributedConsistentHashingTest, TestEmptyDistribution) {
  std::vector<DistributionChoice> distribution;
  EXPECT_THAT(
      DistributedConsistentHashing::Build(std::move(distribution)).status(),
      StatusIs(absl::StatusCode::kInvalidArgument, ""));
}

TEST(DistributedConsistentHashingTest, TestZeroProbabilitiesSum) {
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0}),
    DistributionChoice({1, 0})
  });
  EXPECT_THAT(
      DistributedConsistentHashing::Build(std::move(distribution)).status(),
      StatusIs(absl::StatusCode::kInvalidArgument, ""));
}

TEST(DistributedConsistentHashingTest, TestNegativeProbability) {
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, -1})
  });
  EXPECT_THAT(
      DistributedConsistentHashing::Build(std::move(distribution)).status(),
      StatusIs(absl::StatusCode::kInvalidArgument, ""));
}

TEST(DistributedConsistentHashingTest, TestOutputDistribution) {
  // Distribution:
  // choice_id probability
  // 0         0.4
  // 1         0.2
  // 2         0.2
  // 3         0.2
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0.4}),
    DistributionChoice({1, 0.2}),
    DistributionChoice({2, 0.2}),
    DistributionChoice({3, 0.2})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  absl::flat_hash_map<int32_t, double> output_counts;
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    int32_t output = hashing->Hash(std::to_string(seed));
    if (output_counts.find(output) == output_counts.end()) {
      output_counts[output] = 0;
    }
    ++output_counts[output];
  }
  for (auto& [key, value] : output_counts) {
    value /= static_cast<double>(kSeedNumber);
  }
  // Absolute error more than 2% is very unlikely.
  EXPECT_THAT(output_counts, UnorderedElementsAre(
      Pair(0, DoubleNear(0.4, 0.02)),
      Pair(1, DoubleNear(0.2, 0.02)),
      Pair(2, DoubleNear(0.2, 0.02)),
      Pair(3, DoubleNear(0.2, 0.02))));
}

TEST(DistributedConsistentHashingTest, TestNormalize) {
  // Distribution:
  // choice_id probability_before_normalized normalized_probability
  // 0         0.8                           0.4
  // 1         0.4                           0.2
  // 2         0.4                           0.2
  // 3         0.4                           0.2
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0.8}),
    DistributionChoice({1, 0.4}),
    DistributionChoice({2, 0.4}),
    DistributionChoice({3, 0.4})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  absl::flat_hash_map<int32_t, double> output_counts;
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    int32_t output = hashing->Hash(std::to_string(seed));
    if (output_counts.find(output) == output_counts.end()) {
      output_counts[output] = 0;
    }
    ++output_counts[output];
  }
  for (auto& [key, value] : output_counts) {
    value /= static_cast<double>(kSeedNumber);
  }
  // Absolute error more than 2% is very unlikely.
  EXPECT_THAT(output_counts, UnorderedElementsAre(
      Pair(0, DoubleNear(0.4, 0.02)),
      Pair(1, DoubleNear(0.2, 0.02)),
      Pair(2, DoubleNear(0.2, 0.02)),
      Pair(3, DoubleNear(0.2, 0.02))));
}

TEST(DistributedConsistentHashingTest, TestZeroProbability) {
  // Distribution:
  // choice_id probability
  // 0         0
  // 1         1
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0}),
    DistributionChoice({1, 1})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    EXPECT_EQ(hashing->Hash(std::to_string(seed)), 1);
  }
}

TEST(DistributedConsistentHashingTest, TestZeroAfterNormalization) {
  // Distribution:
  // choice_id probability_before_normalized       normalized_probability
  // 0         std::numeric_limits<double>::min()  0
  // 1         std::numeric_limits<double>::max()  1
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, std::numeric_limits<double>::min()}),
    DistributionChoice({1, std::numeric_limits<double>::max()})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    EXPECT_EQ(hashing->Hash(std::to_string(seed)), 1);
  }
}

TEST(DistributedConsistentHashingTest,
     TestOutputDistribution_NonConsecutiveChoiceId) {
  // Distribution:
  // choice_id probability
  // 0         0.4
  // 2         0.2
  // 4         0.2
  // 6         0.2
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0.4}),
    DistributionChoice({2, 0.2}),
    DistributionChoice({4, 0.2}),
    DistributionChoice({6, 0.2})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  absl::flat_hash_map<int32_t, double> output_counts;
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    int32_t output = hashing->Hash(std::to_string(seed));
    if (output_counts.find(output) == output_counts.end()) {
      output_counts[output] = 0;
    }
    ++output_counts[output];
  }
  for (auto& [key, value] : output_counts) {
    value /= static_cast<double>(kSeedNumber);
  }
  // Absolute error more than 2% is very unlikely.
  EXPECT_THAT(output_counts, UnorderedElementsAre(
      Pair(0, DoubleNear(0.4, 0.02)),
      Pair(2, DoubleNear(0.2, 0.02)),
      Pair(4, DoubleNear(0.2, 0.02)),
      Pair(6, DoubleNear(0.2, 0.02))));
}

TEST(DistributedConsistentHashingTest, TestOutputChangeCount) {
  // Distributions:
  // choice_id probability_1 probability_2
  // 0         0.4           0.2
  // 1         0.2           0.2
  // 2         0.2           0.2
  // 3         0.2           0.4
  std::vector<DistributionChoice> distribution_1({
    DistributionChoice({0, 0.4}),
    DistributionChoice({1, 0.2}),
    DistributionChoice({2, 0.2}),
    DistributionChoice({3, 0.2})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing_1,
      DistributedConsistentHashing::Build(std::move(distribution_1)));
  std::vector<DistributionChoice> distribution_2({
    DistributionChoice({0, 0.2}),
    DistributionChoice({1, 0.2}),
    DistributionChoice({2, 0.2}),
    DistributionChoice({3, 0.4})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing_2,
      DistributedConsistentHashing::Build(std::move(distribution_2)));

  int diff_output_count = 0;
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    int32_t output_1 = hashing_1->Hash(std::to_string(seed));
    int32_t output_2 = hashing_2->Hash(std::to_string(seed));
    if (output_1 != output_2) {
      ++diff_output_count;
    }
  }
  // The number of outputs different between 2 hashings is guaranteed to be less
  // than L1 distance of the 2 distributions, which is 40% of total counts here.
  EXPECT_LE(diff_output_count, kSeedNumber * 0.4);
}

}  // namespace
}  // namespace wfa_virtual_people
<commit_msg>Remove underscore in tests name.<commit_after>// Copyright 2021 The Cross-Media Measurement Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "wfa/virtual_people/core/model/utils/distributed_consistent_hashing.h"

#include "absl/container/flat_hash_map.h"
#include "absl/memory/memory.h"
#include "absl/status/statusor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "src/test/cc/testutil/matchers.h"
#include "src/test/cc/testutil/status_macros.h"

namespace wfa_virtual_people {
namespace {

using ::testing::DoubleNear;
using ::testing::Pair;
using ::testing::UnorderedElementsAre;
using ::wfa::StatusIs;

constexpr int kSeedNumber = 10000;

TEST(DistributedConsistentHashingTest, TestEmptyDistribution) {
  std::vector<DistributionChoice> distribution;
  EXPECT_THAT(
      DistributedConsistentHashing::Build(std::move(distribution)).status(),
      StatusIs(absl::StatusCode::kInvalidArgument, ""));
}

TEST(DistributedConsistentHashingTest, TestZeroProbabilitiesSum) {
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0}),
    DistributionChoice({1, 0})
  });
  EXPECT_THAT(
      DistributedConsistentHashing::Build(std::move(distribution)).status(),
      StatusIs(absl::StatusCode::kInvalidArgument, ""));
}

TEST(DistributedConsistentHashingTest, TestNegativeProbability) {
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, -1})
  });
  EXPECT_THAT(
      DistributedConsistentHashing::Build(std::move(distribution)).status(),
      StatusIs(absl::StatusCode::kInvalidArgument, ""));
}

TEST(DistributedConsistentHashingTest, TestOutputDistribution) {
  // Distribution:
  // choice_id probability
  // 0         0.4
  // 1         0.2
  // 2         0.2
  // 3         0.2
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0.4}),
    DistributionChoice({1, 0.2}),
    DistributionChoice({2, 0.2}),
    DistributionChoice({3, 0.2})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  absl::flat_hash_map<int32_t, double> output_counts;
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    int32_t output = hashing->Hash(std::to_string(seed));
    if (output_counts.find(output) == output_counts.end()) {
      output_counts[output] = 0;
    }
    ++output_counts[output];
  }
  for (auto& [key, value] : output_counts) {
    value /= static_cast<double>(kSeedNumber);
  }
  // Absolute error more than 2% is very unlikely.
  EXPECT_THAT(output_counts, UnorderedElementsAre(
      Pair(0, DoubleNear(0.4, 0.02)),
      Pair(1, DoubleNear(0.2, 0.02)),
      Pair(2, DoubleNear(0.2, 0.02)),
      Pair(3, DoubleNear(0.2, 0.02))));
}

TEST(DistributedConsistentHashingTest, TestNormalize) {
  // Distribution:
  // choice_id probability_before_normalized normalized_probability
  // 0         0.8                           0.4
  // 1         0.4                           0.2
  // 2         0.4                           0.2
  // 3         0.4                           0.2
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0.8}),
    DistributionChoice({1, 0.4}),
    DistributionChoice({2, 0.4}),
    DistributionChoice({3, 0.4})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  absl::flat_hash_map<int32_t, double> output_counts;
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    int32_t output = hashing->Hash(std::to_string(seed));
    if (output_counts.find(output) == output_counts.end()) {
      output_counts[output] = 0;
    }
    ++output_counts[output];
  }
  for (auto& [key, value] : output_counts) {
    value /= static_cast<double>(kSeedNumber);
  }
  // Absolute error more than 2% is very unlikely.
  EXPECT_THAT(output_counts, UnorderedElementsAre(
      Pair(0, DoubleNear(0.4, 0.02)),
      Pair(1, DoubleNear(0.2, 0.02)),
      Pair(2, DoubleNear(0.2, 0.02)),
      Pair(3, DoubleNear(0.2, 0.02))));
}

TEST(DistributedConsistentHashingTest, TestZeroProbability) {
  // Distribution:
  // choice_id probability
  // 0         0
  // 1         1
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0}),
    DistributionChoice({1, 1})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    EXPECT_EQ(hashing->Hash(std::to_string(seed)), 1);
  }
}

TEST(DistributedConsistentHashingTest, TestZeroAfterNormalization) {
  // Distribution:
  // choice_id probability_before_normalized       normalized_probability
  // 0         std::numeric_limits<double>::min()  0
  // 1         std::numeric_limits<double>::max()  1
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, std::numeric_limits<double>::min()}),
    DistributionChoice({1, std::numeric_limits<double>::max()})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    EXPECT_EQ(hashing->Hash(std::to_string(seed)), 1);
  }
}

TEST(DistributedConsistentHashingTest,
     TestOutputDistributionNonConsecutiveChoiceId) {
  // Distribution:
  // choice_id probability
  // 0         0.4
  // 2         0.2
  // 4         0.2
  // 6         0.2
  std::vector<DistributionChoice> distribution({
    DistributionChoice({0, 0.4}),
    DistributionChoice({2, 0.2}),
    DistributionChoice({4, 0.2}),
    DistributionChoice({6, 0.2})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing,
      DistributedConsistentHashing::Build(std::move(distribution)));
  absl::flat_hash_map<int32_t, double> output_counts;
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    int32_t output = hashing->Hash(std::to_string(seed));
    if (output_counts.find(output) == output_counts.end()) {
      output_counts[output] = 0;
    }
    ++output_counts[output];
  }
  for (auto& [key, value] : output_counts) {
    value /= static_cast<double>(kSeedNumber);
  }
  // Absolute error more than 2% is very unlikely.
  EXPECT_THAT(output_counts, UnorderedElementsAre(
      Pair(0, DoubleNear(0.4, 0.02)),
      Pair(2, DoubleNear(0.2, 0.02)),
      Pair(4, DoubleNear(0.2, 0.02)),
      Pair(6, DoubleNear(0.2, 0.02))));
}

TEST(DistributedConsistentHashingTest, TestOutputChangeCount) {
  // Distributions:
  // choice_id probability_1 probability_2
  // 0         0.4           0.2
  // 1         0.2           0.2
  // 2         0.2           0.2
  // 3         0.2           0.4
  std::vector<DistributionChoice> distribution_1({
    DistributionChoice({0, 0.4}),
    DistributionChoice({1, 0.2}),
    DistributionChoice({2, 0.2}),
    DistributionChoice({3, 0.2})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing_1,
      DistributedConsistentHashing::Build(std::move(distribution_1)));
  std::vector<DistributionChoice> distribution_2({
    DistributionChoice({0, 0.2}),
    DistributionChoice({1, 0.2}),
    DistributionChoice({2, 0.2}),
    DistributionChoice({3, 0.4})
  });
  ASSERT_OK_AND_ASSIGN(
      std::unique_ptr<DistributedConsistentHashing> hashing_2,
      DistributedConsistentHashing::Build(std::move(distribution_2)));

  int diff_output_count = 0;
  for (int seed = 0; seed < kSeedNumber; ++seed) {
    int32_t output_1 = hashing_1->Hash(std::to_string(seed));
    int32_t output_2 = hashing_2->Hash(std::to_string(seed));
    if (output_1 != output_2) {
      ++diff_output_count;
    }
  }
  // The number of outputs different between 2 hashings is guaranteed to be less
  // than L1 distance of the 2 distributions, which is 40% of total counts here.
  EXPECT_LE(diff_output_count, kSeedNumber * 0.4);
}

}  // namespace
}  // namespace wfa_virtual_people
<|endoftext|>


<commit_before>#pragma once

#include <agency/detail/tuple.hpp>
#include <utility>

namespace agency
{
namespace detail
{

template<class T, class... Args>
class factory
{
  public:
    __AGENCY_ANNOTATION
    factory() : args_() {}

    __AGENCY_ANNOTATION
    factory(const tuple<Args...>& args)
      : args_(args)
    {}

    // XXX eliminate me!
    __AGENCY_ANNOTATION
    T make() const &
    {
      return __tu::make_from_tuple<T>(args_);
    }

    // XXX eliminate me!
    __AGENCY_ANNOTATION
    T make() &&
    {
      return __tu::make_from_tuple<T>(std::move(args_));
    }

    __AGENCY_ANNOTATION
    T operator()() const &
    {
      return make();
    }

    __AGENCY_ANNOTATION
    T operator()() &&
    {
      return std::move(*this).make();
    }

  private:
    tuple<Args...> args_;
};

template<class T>
__AGENCY_ANNOTATION
factory<T,T> make_factory(const T& arg)
{
  return factory<T,T>{detail::make_tuple(arg)};
}

struct unit {};

struct unit_factory : factory<unit> {};

template<class... Factories>
struct zip_factory
{
  tuple<Factories...> factory_tuple_;

  zip_factory(const tuple<Factories...>& factories) : factory_tuple_(factories) {}

  template<size_t... Indices>
  __AGENCY_ANNOTATION
  agency::detail::tuple<
    typename std::result_of<Factories()>::type...
  >
    impl(agency::detail::index_sequence<Indices...>)
  {
    return agency::detail::make_tuple(detail::get<Indices>(factory_tuple_)()...);
  }

  __AGENCY_ANNOTATION
  agency::detail::tuple<
    typename std::result_of<Factories()>::type...
  >
    operator()()
  {
    return impl(index_sequence_for<Factories...>());
  }
};

template<class... Factories>
__AGENCY_ANNOTATION
zip_factory<Factories...> make_zip_factory(const tuple<Factories...>& factory_tuple)
{
  return zip_factory<Factories...>(factory_tuple);
}

} // end detail
} // end agency

<commit_msg>Add result_of_factory & result_of_factory_t<commit_after>#pragma once

#include <agency/detail/tuple.hpp>
#include <utility>
#include <type_traits>

namespace agency
{
namespace detail
{

template<class Factory>
struct result_of_factory : std::result_of<Factory()> {};

template<class Factory>
using result_of_factory_t = typename result_of_factory<Factory>::type;

template<class T, class... Args>
class factory
{
  public:
    __AGENCY_ANNOTATION
    factory() : args_() {}

    __AGENCY_ANNOTATION
    factory(const tuple<Args...>& args)
      : args_(args)
    {}

    // XXX eliminate me!
    __AGENCY_ANNOTATION
    T make() const &
    {
      return __tu::make_from_tuple<T>(args_);
    }

    // XXX eliminate me!
    __AGENCY_ANNOTATION
    T make() &&
    {
      return __tu::make_from_tuple<T>(std::move(args_));
    }

    __AGENCY_ANNOTATION
    T operator()() const &
    {
      return make();
    }

    __AGENCY_ANNOTATION
    T operator()() &&
    {
      return std::move(*this).make();
    }

  private:
    tuple<Args...> args_;
};

template<class T>
__AGENCY_ANNOTATION
factory<T,T> make_factory(const T& arg)
{
  return factory<T,T>{detail::make_tuple(arg)};
}

struct unit {};

struct unit_factory : factory<unit> {};

template<class... Factories>
struct zip_factory
{
  tuple<Factories...> factory_tuple_;

  zip_factory(const tuple<Factories...>& factories) : factory_tuple_(factories) {}

  template<size_t... Indices>
  __AGENCY_ANNOTATION
  agency::detail::tuple<
    typename std::result_of<Factories()>::type...
  >
    impl(agency::detail::index_sequence<Indices...>)
  {
    return agency::detail::make_tuple(detail::get<Indices>(factory_tuple_)()...);
  }

  __AGENCY_ANNOTATION
  agency::detail::tuple<
    typename std::result_of<Factories()>::type...
  >
    operator()()
  {
    return impl(index_sequence_for<Factories...>());
  }
};

template<class... Factories>
__AGENCY_ANNOTATION
zip_factory<Factories...> make_zip_factory(const tuple<Factories...>& factory_tuple)
{
  return zip_factory<Factories...>(factory_tuple);
}

} // end detail
} // end agency

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_TEXT_SYMBOLIZER_HPP
#define MAPNIK_TEXT_SYMBOLIZER_HPP

// mapnik
#include <mapnik/color.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/text_placements.hpp>

// boost
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

// stl
#include <string>

namespace mapnik
{

struct MAPNIK_DECL text_symbolizer : public symbolizer_base
{
    // Note - we do not use boost::make_shared below as VC2010 is
	// not able to compile make_shared used within a constructor
	text_symbolizer(expression_ptr name, std::string const& face_name,
                    float size, color const& fill,
                    text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
                    );
    text_symbolizer(expression_ptr name, float size, color const& fill,
                    text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
                    );
    text_symbolizer(text_symbolizer const& rhs);
    text_symbolizer& operator=(text_symbolizer const& rhs);
    expression_ptr get_name() const;
    void set_name(expression_ptr expr);

    expression_ptr get_orientation() const; // orienation (rotation angle atm)
    void set_orientation(expression_ptr expr);

    unsigned get_text_ratio() const; // target ratio for text bounding box in pixels
    void set_text_ratio(unsigned ratio);
    unsigned get_wrap_width() const; // width to wrap text at, or trigger ratio
    void set_wrap_width(unsigned ratio);
    unsigned char get_wrap_char() const; // character used to wrap lines
    std::string get_wrap_char_string() const; // character used to wrap lines as std::string
    void set_wrap_char(unsigned char character);
    void set_wrap_char_from_string(std::string const& character);
    text_transform_e get_text_transform() const; // text conversion on strings before display
    void set_text_transform(text_transform_e convert);
    unsigned get_line_spacing() const; // spacing between lines of text
    void set_line_spacing(unsigned spacing);
    unsigned get_character_spacing() const; // spacing between characters in text
    void set_character_spacing(unsigned spacing);
    unsigned get_label_spacing() const; // spacing between repeated labels on lines
    void set_label_spacing(unsigned spacing);
    unsigned get_label_position_tolerance() const; //distance the label can be moved on the line to fit, if 0 the default is used
    void set_label_position_tolerance(unsigned tolerance);
    bool get_force_odd_labels() const; // try render an odd amount of labels
    void set_force_odd_labels(bool force);
    double get_max_char_angle_delta() const; // maximum change in angle between adjacent characters
    void set_max_char_angle_delta(double angle);
    float get_text_size() const;
    void set_text_size(float size);
    std::string const& get_face_name() const;
    void set_face_name(std::string face_name);
    font_set const& get_fontset() const;
    void set_fontset(font_set const& fset);
    color const& get_fill() const;
    void set_fill(color const& fill);
    void set_halo_fill(color const& fill);
    color const& get_halo_fill() const;
    void set_halo_radius(double radius);
    double get_halo_radius() const;
    void set_label_placement(label_placement_e label_p);
    label_placement_e get_label_placement() const;
    void set_vertical_alignment(vertical_alignment_e valign);
    vertical_alignment_e get_vertical_alignment() const;
    void set_anchor(double x, double y);
    position const& get_anchor() const;
    void set_displacement(double x, double y);
    void set_displacement(position const& p);
    position const& get_displacement() const;
    void set_avoid_edges(bool avoid);
    bool get_avoid_edges() const;
    void set_minimum_distance(double distance);
    double get_minimum_distance() const;
    void set_minimum_padding(double distance);
    double get_minimum_padding() const;
    void set_minimum_path_length(double size);
    double get_minimum_path_length() const;
    void set_allow_overlap(bool overlap);
    bool get_allow_overlap() const;
    void set_text_opacity(double opacity);
    double get_text_opacity() const;
    bool get_wrap_before() const; // wrap text at wrap_char immediately before current work
    void set_wrap_before(bool wrap_before);
    void set_horizontal_alignment(horizontal_alignment_e valign);
    horizontal_alignment_e get_horizontal_alignment() const;
    void set_justify_alignment(justify_alignment_e valign);
    justify_alignment_e get_justify_alignment() const;
    text_placements_ptr get_placement_options() const;
    void set_placement_options(text_placements_ptr placement_options);

private:
    expression_ptr name_;
    expression_ptr orientation_;
    std::string face_name_;
    font_set fontset_;
    unsigned text_ratio_;
    unsigned wrap_width_;
    unsigned char wrap_char_;
    text_transform_e text_transform_;
    unsigned line_spacing_;
    unsigned character_spacing_;
    unsigned label_spacing_;
    unsigned label_position_tolerance_;
    bool force_odd_labels_;
    double max_char_angle_delta_;
    color fill_;
    color halo_fill_;
    double halo_radius_;
    label_placement_e label_p_;
    position anchor_;
    bool avoid_edges_;
    double minimum_distance_;
    double minimum_padding_;
    double minimum_path_length_;
    bool overlap_;
    double text_opacity_;
    bool wrap_before_;
    text_placements_ptr placement_options_;
};
}

#endif // MAPNIK_TEXT_SYMBOLIZER_HPP
<commit_msg>add vc++ 2008 to the list.<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_TEXT_SYMBOLIZER_HPP
#define MAPNIK_TEXT_SYMBOLIZER_HPP

// mapnik
#include <mapnik/color.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/text_placements.hpp>

// boost
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

// stl
#include <string>

namespace mapnik
{

struct MAPNIK_DECL text_symbolizer : public symbolizer_base
{
    // Note - we do not use boost::make_shared below as VC2008 and VC2010 are
    // not able to compile make_shared used within a constructor
    text_symbolizer(expression_ptr name, std::string const& face_name,
                    float size, color const& fill,
                    text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
                    );
    text_symbolizer(expression_ptr name, float size, color const& fill,
                    text_placements_ptr placements = text_placements_ptr(new text_placements_dummy)
                    );
    text_symbolizer(text_symbolizer const& rhs);
    text_symbolizer& operator=(text_symbolizer const& rhs);
    expression_ptr get_name() const;
    void set_name(expression_ptr expr);

    expression_ptr get_orientation() const; // orienation (rotation angle atm)
    void set_orientation(expression_ptr expr);

    unsigned get_text_ratio() const; // target ratio for text bounding box in pixels
    void set_text_ratio(unsigned ratio);
    unsigned get_wrap_width() const; // width to wrap text at, or trigger ratio
    void set_wrap_width(unsigned ratio);
    unsigned char get_wrap_char() const; // character used to wrap lines
    std::string get_wrap_char_string() const; // character used to wrap lines as std::string
    void set_wrap_char(unsigned char character);
    void set_wrap_char_from_string(std::string const& character);
    text_transform_e get_text_transform() const; // text conversion on strings before display
    void set_text_transform(text_transform_e convert);
    unsigned get_line_spacing() const; // spacing between lines of text
    void set_line_spacing(unsigned spacing);
    unsigned get_character_spacing() const; // spacing between characters in text
    void set_character_spacing(unsigned spacing);
    unsigned get_label_spacing() const; // spacing between repeated labels on lines
    void set_label_spacing(unsigned spacing);
    unsigned get_label_position_tolerance() const; //distance the label can be moved on the line to fit, if 0 the default is used
    void set_label_position_tolerance(unsigned tolerance);
    bool get_force_odd_labels() const; // try render an odd amount of labels
    void set_force_odd_labels(bool force);
    double get_max_char_angle_delta() const; // maximum change in angle between adjacent characters
    void set_max_char_angle_delta(double angle);
    float get_text_size() const;
    void set_text_size(float size);
    std::string const& get_face_name() const;
    void set_face_name(std::string face_name);
    font_set const& get_fontset() const;
    void set_fontset(font_set const& fset);
    color const& get_fill() const;
    void set_fill(color const& fill);
    void set_halo_fill(color const& fill);
    color const& get_halo_fill() const;
    void set_halo_radius(double radius);
    double get_halo_radius() const;
    void set_label_placement(label_placement_e label_p);
    label_placement_e get_label_placement() const;
    void set_vertical_alignment(vertical_alignment_e valign);
    vertical_alignment_e get_vertical_alignment() const;
    void set_anchor(double x, double y);
    position const& get_anchor() const;
    void set_displacement(double x, double y);
    void set_displacement(position const& p);
    position const& get_displacement() const;
    void set_avoid_edges(bool avoid);
    bool get_avoid_edges() const;
    void set_minimum_distance(double distance);
    double get_minimum_distance() const;
    void set_minimum_padding(double distance);
    double get_minimum_padding() const;
    void set_minimum_path_length(double size);
    double get_minimum_path_length() const;
    void set_allow_overlap(bool overlap);
    bool get_allow_overlap() const;
    void set_text_opacity(double opacity);
    double get_text_opacity() const;
    bool get_wrap_before() const; // wrap text at wrap_char immediately before current work
    void set_wrap_before(bool wrap_before);
    void set_horizontal_alignment(horizontal_alignment_e valign);
    horizontal_alignment_e get_horizontal_alignment() const;
    void set_justify_alignment(justify_alignment_e valign);
    justify_alignment_e get_justify_alignment() const;
    text_placements_ptr get_placement_options() const;
    void set_placement_options(text_placements_ptr placement_options);

private:
    expression_ptr name_;
    expression_ptr orientation_;
    std::string face_name_;
    font_set fontset_;
    unsigned text_ratio_;
    unsigned wrap_width_;
    unsigned char wrap_char_;
    text_transform_e text_transform_;
    unsigned line_spacing_;
    unsigned character_spacing_;
    unsigned label_spacing_;
    unsigned label_position_tolerance_;
    bool force_odd_labels_;
    double max_char_angle_delta_;
    color fill_;
    color halo_fill_;
    double halo_radius_;
    label_placement_e label_p_;
    position anchor_;
    bool avoid_edges_;
    double minimum_distance_;
    double minimum_padding_;
    double minimum_path_length_;
    bool overlap_;
    double text_opacity_;
    bool wrap_before_;
    text_placements_ptr placement_options_;
};
}

#endif // MAPNIK_TEXT_SYMBOLIZER_HPP
<|endoftext|>


<commit_before><commit_msg>coverity#1311653 Uninitialized scalar field<commit_after><|endoftext|>


<commit_before>/**
 * @file lldrawpoolsimple.cpp
 * @brief LLDrawPoolSimple class implementation
 *
 * $LicenseInfo:firstyear=2002&license=viewergpl$
 *
 * Copyright (c) 2002-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "lldrawpoolsimple.h"

#include "llviewercamera.h"
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
#include "pipeline.h"
#include "llspatialpartition.h"
#include "llviewershadermgr.h"
#include "llrender.h"

static LLGLSLShader* simple_shader = NULL;
static LLGLSLShader* fullbright_shader = NULL;

static LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple");
static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");

void LLDrawPoolGlow::render(S32 pass)
{
	LLFastTimer t(FTM_RENDER_GLOW);
	LLGLEnable blend(GL_BLEND);
	LLGLDisable test(GL_ALPHA_TEST);
	gGL.setSceneBlendType(LLRender::BT_ADD);

	U32 shader_level = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);

	if (shader_level > 0 && fullbright_shader)
	{
		fullbright_shader->bind();
	}
	else
	{
		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
	}

	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
	gGL.setColorMask(false, true);
	renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask());

	gGL.setColorMask(true, false);
	gGL.setSceneBlendType(LLRender::BT_ALPHA);

	if (shader_level > 0 && fullbright_shader)
	{
		fullbright_shader->unbind();
	}
}

void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
{
	glColor4ubv(params.mGlowColor.mV);
	LLRenderPass::pushBatch(params, mask, texture);
}

LLDrawPoolSimple::LLDrawPoolSimple() :
	LLRenderPass(POOL_SIMPLE)
{
}

void LLDrawPoolSimple::prerender()
{
	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}

void LLDrawPoolSimple::beginRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_SIMPLE);

	if (LLPipeline::sUnderWaterRender)
	{
		simple_shader = &gObjectSimpleWaterProgram;
	}
	else
	{
		simple_shader = &gObjectSimpleProgram;
	}

	if (mVertexShaderLevel > 0)
	{
		simple_shader->bind();
	}
	else
	{
		// don't use shaders!
		if (gGLManager.mHasShaderObjects)
		{
			LLGLSLShader::bindNoShader();
		}
	}
}

void LLDrawPoolSimple::endRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_SIMPLE);
	LLRenderPass::endRenderPass(pass);

	if (mVertexShaderLevel > 0){

		simple_shader->unbind();
	}
}

void LLDrawPoolSimple::render(S32 pass)
{
	LLGLDisable blend(GL_BLEND);
	LLGLDisable alpha_test(GL_ALPHA_TEST);

	{ //render simple
		LLFastTimer t(FTM_RENDER_SIMPLE);
		gPipeline.enableLightsDynamic();
		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());

		if (LLPipeline::sRenderDeferred)
		{
			renderTexture(LLRenderPass::PASS_BUMP, getVertexDataMask());
		}
	}
}

//===============================
//DEFERRED IMPLEMENTATION
//===============================

void LLDrawPoolSimple::beginDeferredPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED);
	gDeferredDiffuseProgram.bind();
}

void LLDrawPoolSimple::endDeferredPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED);
	LLRenderPass::endRenderPass(pass);

	gDeferredDiffuseProgram.unbind();
}

void LLDrawPoolSimple::renderDeferred(S32 pass)
{
	LLGLDisable blend(GL_BLEND);
	LLGLDisable alpha_test(GL_ALPHA_TEST);

	{ //render simple
		LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED);
		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());
	}
}

// grass drawpool
LLDrawPoolGrass::LLDrawPoolGrass() :
 LLRenderPass(POOL_GRASS)
{

}

void LLDrawPoolGrass::prerender()
{
	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}

void LLDrawPoolGrass::beginRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_GRASS);

	if (LLPipeline::sUnderWaterRender)
	{
		simple_shader = &gObjectSimpleWaterProgram;
	}
	else
	{
		simple_shader = &gObjectSimpleProgram;
	}

	if (mVertexShaderLevel > 0)
	{
		simple_shader->bind();
	}
	else
	{
		// don't use shaders!
		if (gGLManager.mHasShaderObjects)
		{
			LLGLSLShader::bindNoShader();
		}
	}
}

void LLDrawPoolGrass::endRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_GRASS);
	LLRenderPass::endRenderPass(pass);

	if (mVertexShaderLevel > 0)
	{
		simple_shader->unbind();
	}
}

void LLDrawPoolGrass::render(S32 pass)
{
	LLGLDisable blend(GL_BLEND);
	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);

	{
		LLFastTimer t(FTM_RENDER_GRASS);
		LLGLEnable test(GL_ALPHA_TEST);
		gGL.setSceneBlendType(LLRender::BT_ALPHA);
		//render grass
		LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
	}

	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}

void LLDrawPoolGrass::beginDeferredPass(S32 pass)
{

}

void LLDrawPoolGrass::endDeferredPass(S32 pass)
{

}

void LLDrawPoolGrass::renderDeferred(S32 pass)
{
	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);

	{
		LLFastTimer t(FTM_RENDER_GRASS_DEFERRED);
		gDeferredTreeProgram.bind();
		LLGLEnable test(GL_ALPHA_TEST);
		//render grass
		LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
	}

	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}

// Fullbright drawpool
LLDrawPoolFullbright::LLDrawPoolFullbright() :
	LLRenderPass(POOL_FULLBRIGHT)
{
}

void LLDrawPoolFullbright::prerender()
{
	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}

void LLDrawPoolFullbright::beginRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_FULLBRIGHT);

	if (LLPipeline::sUnderWaterRender)
	{
		fullbright_shader = &gObjectFullbrightWaterProgram;
	}
	else
	{
		fullbright_shader = &gObjectFullbrightProgram;
	}
}

void LLDrawPoolFullbright::endRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_FULLBRIGHT);
	LLRenderPass::endRenderPass(pass);

	if (mVertexShaderLevel > 0)
	{
		fullbright_shader->unbind();
	}
}

void LLDrawPoolFullbright::render(S32 pass)
{ //render fullbright
	LLFastTimer t(FTM_RENDER_FULLBRIGHT);
	if (mVertexShaderLevel > 0)
	{
		fullbright_shader->bind();
		fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
	}
	else
	{
		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
	}

	//gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f);

	//LLGLEnable test(GL_ALPHA_TEST);
	//LLGLEnable blend(GL_BLEND);
	gGL.setSceneBlendType(LLRender::BT_ALPHA);
	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
	renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);

	//gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}

S32 LLDrawPoolFullbright::getNumPasses()
{
	return 1;
}

<commit_msg>Stop z-fighting in glow pass.<commit_after>/**
 * @file lldrawpoolsimple.cpp
 * @brief LLDrawPoolSimple class implementation
 *
 * $LicenseInfo:firstyear=2002&license=viewergpl$
 *
 * Copyright (c) 2002-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "lldrawpoolsimple.h"

#include "llviewercamera.h"
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
#include "pipeline.h"
#include "llspatialpartition.h"
#include "llviewershadermgr.h"
#include "llrender.h"

static LLGLSLShader* simple_shader = NULL;
static LLGLSLShader* fullbright_shader = NULL;

static LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple");
static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");

void LLDrawPoolGlow::render(S32 pass)
{
	LLFastTimer t(FTM_RENDER_GLOW);
	LLGLEnable blend(GL_BLEND);
	LLGLDisable test(GL_ALPHA_TEST);
	gGL.flush();
	/// Get rid of z-fighting with non-glow pass.
	LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(-1.0f, -1.0f);
	gGL.setSceneBlendType(LLRender::BT_ADD);

	U32 shader_level = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);

	if (shader_level > 0 && fullbright_shader)
	{
		fullbright_shader->bind();
	}
	else
	{
		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
	}

	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
	gGL.setColorMask(false, true);
	renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask());

	gGL.setColorMask(true, false);
	gGL.setSceneBlendType(LLRender::BT_ALPHA);

	if (shader_level > 0 && fullbright_shader)
	{
		fullbright_shader->unbind();
	}
}

void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
{
	glColor4ubv(params.mGlowColor.mV);
	LLRenderPass::pushBatch(params, mask, texture);
}

LLDrawPoolSimple::LLDrawPoolSimple() :
	LLRenderPass(POOL_SIMPLE)
{
}

void LLDrawPoolSimple::prerender()
{
	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}

void LLDrawPoolSimple::beginRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_SIMPLE);

	if (LLPipeline::sUnderWaterRender)
	{
		simple_shader = &gObjectSimpleWaterProgram;
	}
	else
	{
		simple_shader = &gObjectSimpleProgram;
	}

	if (mVertexShaderLevel > 0)
	{
		simple_shader->bind();
	}
	else
	{
		// don't use shaders!
		if (gGLManager.mHasShaderObjects)
		{
			LLGLSLShader::bindNoShader();
		}
	}
}

void LLDrawPoolSimple::endRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_SIMPLE);
	LLRenderPass::endRenderPass(pass);

	if (mVertexShaderLevel > 0){

		simple_shader->unbind();
	}
}

void LLDrawPoolSimple::render(S32 pass)
{
	LLGLDisable blend(GL_BLEND);
	LLGLDisable alpha_test(GL_ALPHA_TEST);

	{ //render simple
		LLFastTimer t(FTM_RENDER_SIMPLE);
		gPipeline.enableLightsDynamic();
		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());

		if (LLPipeline::sRenderDeferred)
		{
			renderTexture(LLRenderPass::PASS_BUMP, getVertexDataMask());
		}
	}
}

//===============================
//DEFERRED IMPLEMENTATION
//===============================

void LLDrawPoolSimple::beginDeferredPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED);
	gDeferredDiffuseProgram.bind();
}

void LLDrawPoolSimple::endDeferredPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED);
	LLRenderPass::endRenderPass(pass);

	gDeferredDiffuseProgram.unbind();
}

void LLDrawPoolSimple::renderDeferred(S32 pass)
{
	LLGLDisable blend(GL_BLEND);
	LLGLDisable alpha_test(GL_ALPHA_TEST);

	{ //render simple
		LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED);
		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());
	}
}

// grass drawpool
LLDrawPoolGrass::LLDrawPoolGrass() :
 LLRenderPass(POOL_GRASS)
{

}

void LLDrawPoolGrass::prerender()
{
	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}

void LLDrawPoolGrass::beginRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_GRASS);

	if (LLPipeline::sUnderWaterRender)
	{
		simple_shader = &gObjectSimpleWaterProgram;
	}
	else
	{
		simple_shader = &gObjectSimpleProgram;
	}

	if (mVertexShaderLevel > 0)
	{
		simple_shader->bind();
	}
	else
	{
		// don't use shaders!
		if (gGLManager.mHasShaderObjects)
		{
			LLGLSLShader::bindNoShader();
		}
	}
}

void LLDrawPoolGrass::endRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_GRASS);
	LLRenderPass::endRenderPass(pass);

	if (mVertexShaderLevel > 0)
	{
		simple_shader->unbind();
	}
}

void LLDrawPoolGrass::render(S32 pass)
{
	LLGLDisable blend(GL_BLEND);
	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);

	{
		LLFastTimer t(FTM_RENDER_GRASS);
		LLGLEnable test(GL_ALPHA_TEST);
		gGL.setSceneBlendType(LLRender::BT_ALPHA);
		//render grass
		LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
	}

	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}

void LLDrawPoolGrass::beginDeferredPass(S32 pass)
{

}

void LLDrawPoolGrass::endDeferredPass(S32 pass)
{

}

void LLDrawPoolGrass::renderDeferred(S32 pass)
{
	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);

	{
		LLFastTimer t(FTM_RENDER_GRASS_DEFERRED);
		gDeferredTreeProgram.bind();
		LLGLEnable test(GL_ALPHA_TEST);
		//render grass
		LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
	}

	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}

// Fullbright drawpool
LLDrawPoolFullbright::LLDrawPoolFullbright() :
	LLRenderPass(POOL_FULLBRIGHT)
{
}

void LLDrawPoolFullbright::prerender()
{
	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}

void LLDrawPoolFullbright::beginRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_FULLBRIGHT);

	if (LLPipeline::sUnderWaterRender)
	{
		fullbright_shader = &gObjectFullbrightWaterProgram;
	}
	else
	{
		fullbright_shader = &gObjectFullbrightProgram;
	}
}

void LLDrawPoolFullbright::endRenderPass(S32 pass)
{
	LLFastTimer t(FTM_RENDER_FULLBRIGHT);
	LLRenderPass::endRenderPass(pass);

	if (mVertexShaderLevel > 0)
	{
		fullbright_shader->unbind();
	}
}

void LLDrawPoolFullbright::render(S32 pass)
{ //render fullbright
	LLFastTimer t(FTM_RENDER_FULLBRIGHT);
	if (mVertexShaderLevel > 0)
	{
		fullbright_shader->bind();
		fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
	}
	else
	{
		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
	}

	//gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f);

	//LLGLEnable test(GL_ALPHA_TEST);
	//LLGLEnable blend(GL_BLEND);
	gGL.setSceneBlendType(LLRender::BT_ALPHA);
	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
	renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);

	//gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}

S32 LLDrawPoolFullbright::getNumPasses()
{
	return 1;
}

<|endoftext|>