<commit_before>/*
 * File:  PPTest.cpp
 * Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
 */

#include <ios>
#include <sstream>

#include "common/sedna.h"

#include "tr/executor/xqops/PPTest.h"
#include "tr/executor/base/dm_accessors.h"
#include "tr/executor/base/visitor/PPVisitor.h"
#include "tr/strings/strings.h"
#include "tr/pstr/pstr.h"

using namespace std;
//#include <atlstr.h>
//#define USE_DTSEARCH_NAMESPACE
//#include <dtsfc.h>
//#include "FTsearch.h"
//#include "FTindex.h"
//op_str_buf req_buf;
//SednaSearchJob sj;
bool fit;
//#include <dtsfclib.h>

PPTest::PPTest(dynamic_context *_cxt_,
               operation_info _info_,
               PPOpIn _seq_) : PPIterator(_cxt_, _info_),
                               seq(_seq_)
{
	this->test_fun=&PPTest::checkTreeConsistency;
}

PPTest::~PPTest()
{
	delete seq.op;
	seq.op = NULL;

}

void PPTest::do_open ()
{
    seq.op->open();
}

void PPTest::do_reopen()
{
    seq.op->reopen();
}

void PPTest::do_close()
{
    seq.op->close();
}
void PPTest::do_next (tuple &t)
{
	tuple t1(seq.ts);
	seq.op->next(t1);
	//Preliminary node analysis
	if (t1.is_eos())
	{
		t.set_eos();
		return;
	}
	tuple_cell& tc= t1.cells[0];
	if (!tc.is_node())
	{
		throw XQUERY_EXCEPTION(SE2031);
	}
	xptr node=tc.get_node();
	CHECKP(node);
	std::ostringstream strg;
	strg<< "checking the node: xptr=(" << node.layer<< ",0x"<< hex << node.addr <<")\n";
	try
	{
		(this->*test_fun)(node);
		strg<<"true";

	}
	catch(SednaException &e)
	{
       strg << e.getMsg() << endl;
	   throw ;
    }
	t.copy(tuple_cell::atomic_deep(xs_string,strg.str().c_str())) ;

	/*while (true)
	{
		seq.op->next(t);
		//Preliminary node analysis
		if (t.is_eos())
		{
			//t.set_eos();
			return;
		}
		tuple_cell& tc= t.cells[0];
		if (!tc.is_node())
		{
			//throw USER_EXCEPTION(SE2031);
			req_buf.set(tc);
		}
		else
		{
			xptr node=tc.get_node();
			CHECKP(node);
			if (checkFT(node)) return;
		}
	}*/
	/*if (fit)
	{
		seq.op->next(t);
		//Preliminary node analysis
		if (t.is_eos())
		{
			//t.set_eos();
			return;
		}
		tuple_cell& tc= t.cells[0];
		int command;
		if (!tc.is_node())
		{
			//throw USER_EXCEPTION(SE2031);
			command=tc.get_xs_integer();
		}
		seq.op->next(t);
		//Preliminary node analysis
		if (t.is_eos())
		{
			//t.set_eos();
			return;
		}
		tc= t.cells[0];
		if (!tc.is_node())
		{
			//throw USER_EXCEPTION(SE2031);
			if (command==1)
			{
				req_buf.set(tc);
				sj=se_new SednaSearchJob(&seq);
				sj->set_request(tc);
			}
			else if (command==2)
			{
				req_buf.set(tc);
				sj=se_new SednaSearchJob();
				sj->set_request(tc);
				seq.op->next(t);
				tc= t.cells[0];
				sj->set_index(tc);
			}
			else
			{
				req_buf.set(tc);
				SednaIndexJob si(&seq);
				si.set_index_name(tc);
				si.create_index();
				si.SetActionCompress();
				si.Execute();
				t.set_eos();
				return;
			}
		}
		fit=false;
	}
	sj->get_next_result(t);
	if (t.is_eos())
		fit=true;
	//int res= checkFT(seq);
	//t.copy(tuple_cell::atomic(res));
	*/
}

PPIterator* PPTest::do_copy(dynamic_context *_cxt_)
{
	PPTest *res ;
	res = se_new PPTest(_cxt_, info, seq);
	res->seq.op = seq.op->copy(_cxt_);
	return res;
}
xptr get_root (xptr node)
{
	CHECKP(node);
	xptr tmp=node;
	while (true)
	{
      if (((n_dsc*)XADDR(tmp))->pdsc==XNULL) return tmp;
	  tmp=removeIndirection(((n_dsc*)XADDR(tmp))->pdsc);
	}
}
bool is_same_root(xptr x, xptr y)
{
	return get_root(x)==get_root(y);
}
/*
bool PPTest::checkFT(xptr node)
{
	dtsSearchJob *searchJob = se_new dtsSearchJob;
	dtsSearchResults *results = se_new dtsSearchResults();
    searchJob->resultsHandle = results->getHandle();
	//searchJob->pReportCallBack = SearchingCallback;
	SampleDataSource sample(node) ;
	dtsDataSource dataSource;
	sample.makeInterface(dataSource);
	searchJob->dataSourceToSearch = &dataSource;
	searchJob->action.searchFiles = true;
	strcpy(searchJob->request, req_buf.c_str());
	short result = 0;
    dtssDoSearchJob(*searchJob, result);
    delete searchJob;
	bool res=results->getCount()>0;
	delete results;
	return res;
}
int PPTest::checkFT(PPOpIn _seq_)
{
	dtsSearchJob *searchJob = se_new dtsSearchJob;
	dtsSearchResults *results = se_new dtsSearchResults();
    searchJob->resultsHandle = results->getHandle();
	//searchJob->pReportCallBack = SearchingCallback;
	SampleDataSource2 sample(_seq_) ;
	dtsDataSource dataSource;
	sample.makeInterface(dataSource);
	searchJob->dataSourceToSearch = &dataSource;
	searchJob->action.searchFiles = true;
	strcpy(searchJob->request, req_buf.c_str());
	short result = 0;
    dtssDoSearchJob(*searchJob, result);
	int res=results->getCount();
	delete searchJob;

	delete results;
	return res;
}*/
void PPTest::checkTreeConsistency(xptr node)
{
	CHECKP(node);
	n_dsc* node_d=(n_dsc*)XADDR(node);
	t_nid nd=node_d->nid;
	schema_node_cptr scn=(GETBLOCKBYNODE(node))->snode;
	node_blk_hdr* n_blk=GETBLOCKBYNODE(node);
#ifdef DESC_CONSIST
	if (node_d->desc_prev!=0)
	{
		n_dsc* pr_n=(n_dsc*)((char*)n_blk + node_d->desc_prev );
		if (pr_n->desc_next!=CALCSHIFT(node_d,n_blk) || pr_n==node_d)
			throw XQUERY_EXCEPTION(SE2030);
	}
	if (node_d->desc_next!=0)
	{
		n_dsc* pr_n=(n_dsc*)((char*)n_blk + node_d->desc_next );
		if (pr_n->desc_prev!=CALCSHIFT(node_d,n_blk) || pr_n==node_d)
			throw XQUERY_EXCEPTION(SE2030);
	}

	//1. indirection test
	xptr indir=node_d->indir;
	if (removeIndirection(indir)!=node)
		throw XQUERY_EXCEPTION(SE2030);
	//2. parent test
	CHECKP(node);
	xptr par_indir=node_d->pdsc;
	xptr parent;
	n_dsc* prev_dsc=getPreviousDescriptorOfSameSort(node_d);
	xptr prev_x=(prev_dsc==NULL)?XNULL:ADDR2XPTR(prev_dsc);
    if (par_indir!=XNULL)
	{
		parent=removeIndirection(par_indir);
		if (!nid_ancestor(parent,node))
			throw XQUERY_EXCEPTION(SE2025);
		if (prev_dsc==NULL|| prev_dsc->pdsc!=par_indir)
		{
			CHECKP(parent);
			xptr* ptr=elementContainsChild((n_dsc*)XADDR(parent),scn->name,scn->type,scn->get_xmlns());
			if (ptr==NULL || *ptr!=node)
				throw XQUERY_EXCEPTION(SE2026);
		}
	}
	//3. left siblings + nid comparison
	CHECKP(node);
	xptr left=node_d->ldsc;
	if (left!=XNULL)
	{
		CHECKP(left);
		if (((n_dsc*)XADDR(left))->rdsc!=node)
			throw XQUERY_EXCEPTION(SE2027);
		if (nid_cmp(left,node)>=0)
			throw XQUERY_EXCEPTION(SE2028);
	}
	//4. descriptor's order
	if (prev_x!=XNULL && scn->type!=document)
	{
		bool lt=nid_cmp(prev_x,node)<0;
		CHECKP(prev_x);
		if (!lt || getNextDescriptorOfSameSort(prev_dsc)!=node_d   )
		{
			if (is_same_root(prev_x,node))
				throw XQUERY_EXCEPTION(SE2029);
		}
	}
#endif
#ifdef PSTR_CONSIST
	//5.1 nid pstr consistency
	CHECKP(node);
	if (nd.size==0&& is_last_shft_in_blk(*((xptr*)nd.prefix)))
			check_blk_consistency(*((xptr*)nd.prefix));
	//5.2 nid pstr consistency
	CHECKP(node);
	if ( scn->textcnt && isPstr((t_dsc*)node_d) && is_last_shft_in_blk(((t_dsc*)node_d)->data.lsp.p)) {
		CHECKP(node);
		check_blk_consistency(((t_dsc*)node_d)->data.lsp.p);
	}
#endif
	//recursive walkthrough
	CHECKP(node);
	xptr child=giveFirstByOrderChild(node,CHILDCOUNT(node));
	while (child!=XNULL)
	{
		checkTreeConsistency(child);
		CHECKP(child);
		child=((n_dsc*)XADDR(child))->rdsc;
	}
}

void PPTest::do_accept(PPVisitor &v)
{
    v.visit (this);
    v.push  (this);
    seq.op->accept(v);
    v.pop();
}
<commit_msg>fixes in PPTest<commit_after>/*
 * File:  PPTest.cpp
 * Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
 */

#include <ios>
#include <sstream>

#include "common/sedna.h"

#include "tr/executor/xqops/PPTest.h"
#include "tr/executor/base/dm_accessors.h"
#include "tr/executor/base/visitor/PPVisitor.h"
#include "tr/strings/strings.h"
#include "tr/pstr/pstr.h"

using namespace std;
//#include <atlstr.h>
//#define USE_DTSEARCH_NAMESPACE
//#include <dtsfc.h>
//#include "FTsearch.h"
//#include "FTindex.h"
//op_str_buf req_buf;
//SednaSearchJob sj;
bool fit;
//#include <dtsfclib.h>

PPTest::PPTest(dynamic_context *_cxt_,
               operation_info _info_,
               PPOpIn _seq_) : PPIterator(_cxt_, _info_),
                               seq(_seq_)
{
	this->test_fun=&PPTest::checkTreeConsistency;
}

PPTest::~PPTest()
{
	delete seq.op;
	seq.op = NULL;

}

void PPTest::do_open ()
{
    seq.op->open();
}

void PPTest::do_reopen()
{
    seq.op->reopen();
}

void PPTest::do_close()
{
    seq.op->close();
}
void PPTest::do_next (tuple &t)
{
	tuple t1(seq.ts);
	seq.op->next(t1);
	//Preliminary node analysis
	if (t1.is_eos())
	{
		t.set_eos();
		return;
	}
	tuple_cell& tc= t1.cells[0];
	if (!tc.is_node())
	{
		throw XQUERY_EXCEPTION(SE2031);
	}
	xptr node=tc.get_node();
	CHECKP(node);
	std::ostringstream strg;
	strg<< "checking the node: xptr=(" << node.layer<< ",0x"<< hex << node.addr <<")\n";
	try
	{
		(this->*test_fun)(node);
		strg<<"true";

	}
	catch(SednaException &e)
	{
       strg << e.getMsg() << endl;
	   throw ;
    }
	t.copy(tuple_cell::atomic_deep(xs_string,strg.str().c_str())) ;

	/*while (true)
	{
		seq.op->next(t);
		//Preliminary node analysis
		if (t.is_eos())
		{
			//t.set_eos();
			return;
		}
		tuple_cell& tc= t.cells[0];
		if (!tc.is_node())
		{
			//throw USER_EXCEPTION(SE2031);
			req_buf.set(tc);
		}
		else
		{
			xptr node=tc.get_node();
			CHECKP(node);
			if (checkFT(node)) return;
		}
	}*/
	/*if (fit)
	{
		seq.op->next(t);
		//Preliminary node analysis
		if (t.is_eos())
		{
			//t.set_eos();
			return;
		}
		tuple_cell& tc= t.cells[0];
		int command;
		if (!tc.is_node())
		{
			//throw USER_EXCEPTION(SE2031);
			command=tc.get_xs_integer();
		}
		seq.op->next(t);
		//Preliminary node analysis
		if (t.is_eos())
		{
			//t.set_eos();
			return;
		}
		tc= t.cells[0];
		if (!tc.is_node())
		{
			//throw USER_EXCEPTION(SE2031);
			if (command==1)
			{
				req_buf.set(tc);
				sj=se_new SednaSearchJob(&seq);
				sj->set_request(tc);
			}
			else if (command==2)
			{
				req_buf.set(tc);
				sj=se_new SednaSearchJob();
				sj->set_request(tc);
				seq.op->next(t);
				tc= t.cells[0];
				sj->set_index(tc);
			}
			else
			{
				req_buf.set(tc);
				SednaIndexJob si(&seq);
				si.set_index_name(tc);
				si.create_index();
				si.SetActionCompress();
				si.Execute();
				t.set_eos();
				return;
			}
		}
		fit=false;
	}
	sj->get_next_result(t);
	if (t.is_eos())
		fit=true;
	//int res= checkFT(seq);
	//t.copy(tuple_cell::atomic(res));
	*/
}

PPIterator* PPTest::do_copy(dynamic_context *_cxt_)
{
	PPTest *res ;
	res = se_new PPTest(_cxt_, info, seq);
	res->seq.op = seq.op->copy(_cxt_);
	return res;
}
xptr get_root (xptr node)
{
	CHECKP(node);
	xptr tmp=node;
	while (true)
	{
            CHECKP(tmp);
            if (((n_dsc*)XADDR(tmp))->pdsc==XNULL) return tmp;
            tmp=removeIndirection(((n_dsc*)XADDR(tmp))->pdsc);
	}
}
bool is_same_root(xptr x, xptr y)
{
	return get_root(x)==get_root(y);
}
/*
bool PPTest::checkFT(xptr node)
{
	dtsSearchJob *searchJob = se_new dtsSearchJob;
	dtsSearchResults *results = se_new dtsSearchResults();
    searchJob->resultsHandle = results->getHandle();
	//searchJob->pReportCallBack = SearchingCallback;
	SampleDataSource sample(node) ;
	dtsDataSource dataSource;
	sample.makeInterface(dataSource);
	searchJob->dataSourceToSearch = &dataSource;
	searchJob->action.searchFiles = true;
	strcpy(searchJob->request, req_buf.c_str());
	short result = 0;
    dtssDoSearchJob(*searchJob, result);
    delete searchJob;
	bool res=results->getCount()>0;
	delete results;
	return res;
}
int PPTest::checkFT(PPOpIn _seq_)
{
	dtsSearchJob *searchJob = se_new dtsSearchJob;
	dtsSearchResults *results = se_new dtsSearchResults();
    searchJob->resultsHandle = results->getHandle();
	//searchJob->pReportCallBack = SearchingCallback;
	SampleDataSource2 sample(_seq_) ;
	dtsDataSource dataSource;
	sample.makeInterface(dataSource);
	searchJob->dataSourceToSearch = &dataSource;
	searchJob->action.searchFiles = true;
	strcpy(searchJob->request, req_buf.c_str());
	short result = 0;
    dtssDoSearchJob(*searchJob, result);
	int res=results->getCount();
	delete searchJob;

	delete results;
	return res;
}*/
void PPTest::checkTreeConsistency(xptr node)
{
	CHECKP(node);
	n_dsc* node_d=(n_dsc*)XADDR(node);
	t_nid nd=node_d->nid;
	schema_node_cptr scn=(GETBLOCKBYNODE(node))->snode;
	node_blk_hdr* n_blk=GETBLOCKBYNODE(node);
#ifdef DESC_CONSIST
	if (node_d->desc_prev!=0)
	{
		n_dsc* pr_n=(n_dsc*)((char*)n_blk + node_d->desc_prev );
		if (pr_n->desc_next!=CALCSHIFT(node_d,n_blk) || pr_n==node_d)
			throw XQUERY_EXCEPTION(SE2030);
	}
	if (node_d->desc_next!=0)
	{
		n_dsc* pr_n=(n_dsc*)((char*)n_blk + node_d->desc_next );
		if (pr_n->desc_prev!=CALCSHIFT(node_d,n_blk) || pr_n==node_d)
			throw XQUERY_EXCEPTION(SE2030);
	}

	//1. indirection test
	xptr indir=node_d->indir;
	if (removeIndirection(indir)!=node)
		throw XQUERY_EXCEPTION(SE2030);
	//2. parent test
	CHECKP(node);
	xptr par_indir=node_d->pdsc;
	xptr parent;
	n_dsc* prev_dsc=getPreviousDescriptorOfSameSort(node_d);
	xptr prev_x=(prev_dsc==NULL)?XNULL:ADDR2XPTR(prev_dsc);
    if (par_indir!=XNULL)
	{
		parent=removeIndirection(par_indir);
		if (!nid_ancestor(parent,node))
			throw XQUERY_EXCEPTION(SE2025);
		if(prev_x != XNULL) CHECKP(prev_x);
		if (prev_dsc==NULL|| prev_dsc->pdsc!=par_indir)
		{
			CHECKP(parent);
			xptr* ptr=elementContainsChild((n_dsc*)XADDR(parent),scn->name,scn->type,scn->get_xmlns());
			if (ptr==NULL || *ptr!=node)
				throw XQUERY_EXCEPTION(SE2026);
		}
	}
	//3. left siblings + nid comparison
	CHECKP(node);
	xptr left=node_d->ldsc;
	if (left!=XNULL)
	{
		CHECKP(left);
		if (((n_dsc*)XADDR(left))->rdsc!=node)
			throw XQUERY_EXCEPTION(SE2027);
		if (nid_cmp(left,node)>=0)
			throw XQUERY_EXCEPTION(SE2028);
	}
	//4. descriptor's order
	if (prev_x!=XNULL && scn->type!=document)
	{
		bool lt=nid_cmp(prev_x,node)<0;
		CHECKP(prev_x);
		if (!lt || getNextDescriptorOfSameSort(prev_dsc)!=node_d   )
		{
			if (is_same_root(prev_x,node))
				throw XQUERY_EXCEPTION(SE2029);
		}
	}
#endif
#ifdef PSTR_CONSIST
	//5.1 nid pstr consistency
	CHECKP(node);
	if (nd.size==0&& is_last_shft_in_blk(*((xptr*)nd.prefix)))
			check_blk_consistency(*((xptr*)nd.prefix));
	//5.2 nid pstr consistency
	CHECKP(node);
	if ( scn->textcnt && isPstr((t_dsc*)node_d) && is_last_shft_in_blk(((t_dsc*)node_d)->data.lsp.p)) {
		CHECKP(node);
		check_blk_consistency(((t_dsc*)node_d)->data.lsp.p);
	}
#endif
	//recursive walkthrough
	CHECKP(node);
	xptr child=giveFirstByOrderChild(node,CHILDCOUNT(node));
	while (child!=XNULL)
	{
		checkTreeConsistency(child);
		CHECKP(child);
		child=((n_dsc*)XADDR(child))->rdsc;
	}
}

void PPTest::do_accept(PPVisitor &v)
{
    v.visit (this);
    v.push  (this);
    seq.op->accept(v);
    v.pop();
}
<|endoftext|>


<commit_before>#include "LogobotText.h"

// local copy of critical command defines - for space optimisation
#define LOGO_CMD_BZ			8
#define LOGO_CMD_PU			9
#define LOGO_CMD_PD			10

namespace LogobotText
{
	// Namespace containing private functions
	namespace
	{
		float fontSize;  // =em, equal to line spacing (between baselines), text sizes derived from this
		float capHeight;
		float letterSpacing;
		float w;

		CommandQueue * _cmdQ;

		void pushCmd(String cmd)
		{
			_cmdQ->enqueue(cmd, 0xff);
		}

		void pushPU() {
			_cmdQ->enqueue("", LOGO_CMD_PU);
		}

		void pushPD() {
			_cmdQ->enqueue("", LOGO_CMD_PD);
		}

		void pushTo(float x, float y)
		{
			String s = "TO ";
			s += x;
			s += " ";
			s += y;
			pushCmd(s);
		}

		// Alphabet
		void writeA(float x, float y)
		{
			pushPD();
			pushTo(x + w/2, y + capHeight);
			pushTo(x + w, y);
			pushPU();
			pushTo(x + w / 4, y + capHeight / 2);
			pushPD();
			pushTo(x + 3 * w / 4, y + capHeight / 2 );
		}

		void writeB(float x, float y)
		{
			pushPD();
			pushTo(x + 2 * w / 3, y);
			pushTo(x + w, y + capHeight / 4);
			pushTo(x + 2 * w / 3, y + capHeight / 2);
			pushTo(x + w, y + 3 * capHeight / 4);
			pushTo(x + 2 * w / 3, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x, y);
		}

		void writeC(float x, float y)
		{
			pushTo(x + w, y + capHeight);
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x, y);
			pushTo(x + w, y);
		}

		void writeD(float x, float y)
		{
			pushPD();
			pushTo(x + 3 * w / 4, y);
			pushTo(x + w, y + capHeight / 4);
			pushTo(x + w, y + 3 * capHeight / 4);
			pushTo(x + 3 * w / 4, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x, y);
		}

		void writeE(float x, float y)
		{
			writeC(x, y);
			pushPU();
			pushTo(x, y + capHeight / 2);
			pushPD();
			pushTo(x + w, y + capHeight /2);
		}

		void writeF(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x + w, y + capHeight);
			pushPU();
			pushTo(x + w, y + capHeight / 2);
			pushPD();
			pushTo(x, y + capHeight / 2);
		}

		void writeG(float x, float y)
		{
			pushTo(x + w, y + capHeight);
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x, y);
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight/3);
			pushTo(x + w/3, y + capHeight/3);
		}

		void writeH(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x, y + capHeight / 2);
			pushTo(x + w, y + capHeight / 2);
			pushTo(x + w, y + capHeight);
			pushTo(x + w, y);
		}

		void writeI(float x, float y)
		{
			pushTo(x + w / 2, y);
			pushPD();
			pushTo(x + w / 2, y + capHeight);
		}

		void writeJ(float x, float y)
		{
			pushTo(x, y + capHeight / 4);
			pushPD();
			pushTo(x, y);
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight);
		}

		void writeK(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushPU();
			pushTo(x + w, y + capHeight);
			pushPD();
			pushTo(x, y + capHeight / 2);
			pushTo(x + w, y);
		}

		void writeL(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x,y);
			pushTo(x + w, y);
		}

		void writeM(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x + w / 2, y + capHeight / 2);
			pushTo(x + w, y + capHeight);
			pushTo(x + w, y);
		}

		void writeN(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight);

		}

		void writeO(float x, float y)
		{
			pushPD();
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x, y);
		}

		void writeP(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x + w, y + capHeight);
			pushTo(x + w, y + capHeight / 2);
			pushTo(x, y + capHeight / 2);
		}

		void writeQ(float x, float y)
		{
			pushPD();
			pushTo(x + w / 2, y);
			pushTo(x + w, y + capHeight / 2);
			pushTo(x + w, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x, y);
			pushPU();
			pushTo(x + w / 2, y + capHeight / 2);
			pushPD();
			pushTo(x + w, y);
		}

		void writeR(float x, float y)
		{
			writeP(x, y);
			pushTo(x + w, y);
		}

		void writeS(float x, float y)
		{
			pushPD();
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight / 2);
			pushTo(x, y + capHeight / 2);
			pushTo(x, y + capHeight);
			pushTo(x + w, y + capHeight);
		}

		void writeT(float x, float y)
		{
			pushTo(x + w/2, y);
			pushPD();
			pushTo(x + w/2, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x + w, y + capHeight);
		}

		void writeU(float x, float y)
		{
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x, y);
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight);
		}

		void writeV(float x, float y)
		{
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w / 2, y);
			pushTo(x + w, y + capHeight);
		}

		void writeW(float x, float y)
		{
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w / 4, y);
			pushTo(x + w / 2, y + capHeight / 2);
			pushTo(x + 3 * w / 4, y);
			pushTo(x + w, y + capHeight);
		}

		void writeX(float x, float y)
		{
			pushPD();
			pushTo(x + w, y + capHeight);
			pushPU();
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w, y);
		}

		void writeY(float x, float y)
		{
			pushPD();
			pushTo(x + w, y + capHeight);
			pushPU();
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w / 2, y + capHeight / 2);
		}

		void writeZ(float x, float y)
		{
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w, y + capHeight);
			pushTo(x, y);
			pushTo(x + w, y);
		}

		void writeColon(float x, float y)
		{
			pushTo(x + w/3, y + capHeight/3);
			pushPD();
			pushTo(x + 2*w/3, y + capHeight/3);
			pushPU();
			pushTo(x + 2*w/3, y + 2*capHeight/3);
			pushPD();
			pushTo(x + w/3, y + 2*capHeight/3);
		}

		void writeCloseBracket(float x, float y)
		{
			pushTo(x + w/3, y);
			pushPD();
			pushTo(x + 2*w/3, y + capHeight/4);
			pushTo(x + w, y + capHeight/2);
			pushTo(x + 2*w/3, y + 3*capHeight/4);
			pushTo(x + w/3, y + capHeight);
		}

		void writeHash(float x, float y)
		{
			pushTo(x, y + capHeight/3);
			pushPD();
			pushTo(x + w, y + capHeight/3);
			pushPU();
			pushTo(x + w, y + 2*capHeight/3);
			pushPD();
			pushTo(x, y + 2*capHeight/3);
			pushPU();

			pushTo(x + w/3, y + capHeight);
			pushPD();
			pushTo(x + w/3, y);
			pushPU();
			pushTo(x + 2*w/3, y);
			pushPD();
			pushTo(x + 2*w/3, y + capHeight);
		}
	}
	// End private namespace functions

	// Logobot text public functions
	void begin(CommandQueue& cmdQ)
	{
		_cmdQ = &cmdQ;
		setFontSize(20);
	}

	void setFontSize(float size)
	{
		fontSize = size;
		capHeight = fontSize * 0.7;
		letterSpacing = fontSize * 0.1;
		w = fontSize * 0.5;
	}

	void writeChar(char c, float x, float y)
	{
		switch (c) {
			case 'A':
				writeA(x, y);
				break;
			case 'B':
				writeB(x, y);
				break;
			case 'C':
				writeC(x, y);
				break;
			case 'D':
				writeD(x, y);
				break;
			case 'E':
				writeE(x, y);
				break;
			case 'F':
				writeF(x, y);
				break;
			case 'G':
				writeG(x, y);
				break;
			case 'H':
				writeH(x, y);
				break;
			case 'I':
				writeI(x, y);
				break;
			case 'J':
				writeJ(x, y);
				break;
			case 'K':
				writeK(x, y);
				break;
			case 'L':
				writeL(x, y);
				break;
			case 'M':
				writeM(x, y);
				break;
			case 'N':
				writeN(x, y);
				break;
			case 'O':
				writeO(x, y);
				break;
			case 'P':
				writeP(x, y);
				break;
			case 'Q':
				writeQ(x, y);
				break;
			case 'R':
				writeR(x, y);
				break;
			case 'S':
				writeS(x, y);
				break;
			case 'T':
				writeT(x, y);
				break;
			case 'U':
				writeU(x, y);
				break;
			case 'V':
				writeV(x, y);
				break;
			case 'W':
				writeW(x, y);
				break;
			case 'X':
				writeX(x, y);
				break;
			case 'Y':
				writeY(x, y);
				break;
			case 'Z':
				writeZ(x, y);
				break;
			case ' ':
				// nothing to do, just move to next letter
				break;
			case ':':
				writeColon(x,y);
				break;
			case ')':
				writeCloseBracket(x,y);
				break;
			case '#':
				writeHash(x,y);
				break;

			default:
				_cmdQ->enqueue("500",LOGO_CMD_BZ);
				//pushCmd("BZ 500");
				return;
		}

		pushPU();
		pushTo(x + w + letterSpacing, y);
	}
}
<commit_msg>Fix bug following space op<commit_after>#include "LogobotText.h"

// local copy of critical command defines - for space optimisation
#define LOGO_CMD_TO			4
#define LOGO_CMD_BZ			8
#define LOGO_CMD_PU			9
#define LOGO_CMD_PD			10

namespace LogobotText
{
	// Namespace containing private functions
	namespace
	{
		float fontSize;  // =em, equal to line spacing (between baselines), text sizes derived from this
		float capHeight;
		float letterSpacing;
		float w;

		CommandQueue * _cmdQ;

		void pushPU() {
			_cmdQ->enqueue("", LOGO_CMD_PU);
		}

		void pushPD() {
			_cmdQ->enqueue("", LOGO_CMD_PD);
		}

		void pushTo(float x, float y)
		{
			String s = String(x);
			s += " ";
			s += y;
			_cmdQ->enqueue(s, LOGO_CMD_TO);
		}

		// Alphabet
		void writeA(float x, float y)
		{
			pushPD();
			pushTo(x + w/2, y + capHeight);
			pushTo(x + w, y);
			pushPU();
			pushTo(x + w / 4, y + capHeight / 2);
			pushPD();
			pushTo(x + 3 * w / 4, y + capHeight / 2 );
		}

		void writeB(float x, float y)
		{
			pushPD();
			pushTo(x + 2 * w / 3, y);
			pushTo(x + w, y + capHeight / 4);
			pushTo(x + 2 * w / 3, y + capHeight / 2);
			pushTo(x + w, y + 3 * capHeight / 4);
			pushTo(x + 2 * w / 3, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x, y);
		}

		void writeC(float x, float y)
		{
			pushTo(x + w, y + capHeight);
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x, y);
			pushTo(x + w, y);
		}

		void writeD(float x, float y)
		{
			pushPD();
			pushTo(x + 3 * w / 4, y);
			pushTo(x + w, y + capHeight / 4);
			pushTo(x + w, y + 3 * capHeight / 4);
			pushTo(x + 3 * w / 4, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x, y);
		}

		void writeE(float x, float y)
		{
			writeC(x, y);
			pushPU();
			pushTo(x, y + capHeight / 2);
			pushPD();
			pushTo(x + w, y + capHeight /2);
		}

		void writeF(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x + w, y + capHeight);
			pushPU();
			pushTo(x + w, y + capHeight / 2);
			pushPD();
			pushTo(x, y + capHeight / 2);
		}

		void writeG(float x, float y)
		{
			pushTo(x + w, y + capHeight);
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x, y);
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight/3);
			pushTo(x + w/3, y + capHeight/3);
		}

		void writeH(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x, y + capHeight / 2);
			pushTo(x + w, y + capHeight / 2);
			pushTo(x + w, y + capHeight);
			pushTo(x + w, y);
		}

		void writeI(float x, float y)
		{
			pushTo(x + w / 2, y);
			pushPD();
			pushTo(x + w / 2, y + capHeight);
		}

		void writeJ(float x, float y)
		{
			pushTo(x, y + capHeight / 4);
			pushPD();
			pushTo(x, y);
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight);
		}

		void writeK(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushPU();
			pushTo(x + w, y + capHeight);
			pushPD();
			pushTo(x, y + capHeight / 2);
			pushTo(x + w, y);
		}

		void writeL(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x,y);
			pushTo(x + w, y);
		}

		void writeM(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x + w / 2, y + capHeight / 2);
			pushTo(x + w, y + capHeight);
			pushTo(x + w, y);
		}

		void writeN(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight);

		}

		void writeO(float x, float y)
		{
			pushPD();
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x, y);
		}

		void writeP(float x, float y)
		{
			pushPD();
			pushTo(x, y + capHeight);
			pushTo(x + w, y + capHeight);
			pushTo(x + w, y + capHeight / 2);
			pushTo(x, y + capHeight / 2);
		}

		void writeQ(float x, float y)
		{
			pushPD();
			pushTo(x + w / 2, y);
			pushTo(x + w, y + capHeight / 2);
			pushTo(x + w, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x, y);
			pushPU();
			pushTo(x + w / 2, y + capHeight / 2);
			pushPD();
			pushTo(x + w, y);
		}

		void writeR(float x, float y)
		{
			writeP(x, y);
			pushTo(x + w, y);
		}

		void writeS(float x, float y)
		{
			pushPD();
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight / 2);
			pushTo(x, y + capHeight / 2);
			pushTo(x, y + capHeight);
			pushTo(x + w, y + capHeight);
		}

		void writeT(float x, float y)
		{
			pushTo(x + w/2, y);
			pushPD();
			pushTo(x + w/2, y + capHeight);
			pushTo(x, y + capHeight);
			pushTo(x + w, y + capHeight);
		}

		void writeU(float x, float y)
		{
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x, y);
			pushTo(x + w, y);
			pushTo(x + w, y + capHeight);
		}

		void writeV(float x, float y)
		{
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w / 2, y);
			pushTo(x + w, y + capHeight);
		}

		void writeW(float x, float y)
		{
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w / 4, y);
			pushTo(x + w / 2, y + capHeight / 2);
			pushTo(x + 3 * w / 4, y);
			pushTo(x + w, y + capHeight);
		}

		void writeX(float x, float y)
		{
			pushPD();
			pushTo(x + w, y + capHeight);
			pushPU();
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w, y);
		}

		void writeY(float x, float y)
		{
			pushPD();
			pushTo(x + w, y + capHeight);
			pushPU();
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w / 2, y + capHeight / 2);
		}

		void writeZ(float x, float y)
		{
			pushTo(x, y + capHeight);
			pushPD();
			pushTo(x + w, y + capHeight);
			pushTo(x, y);
			pushTo(x + w, y);
		}

		void writeColon(float x, float y)
		{
			pushTo(x + w/3, y + capHeight/3);
			pushPD();
			pushTo(x + 2*w/3, y + capHeight/3);
			pushPU();
			pushTo(x + 2*w/3, y + 2*capHeight/3);
			pushPD();
			pushTo(x + w/3, y + 2*capHeight/3);
		}

		void writeCloseBracket(float x, float y)
		{
			pushTo(x + w/3, y);
			pushPD();
			pushTo(x + 2*w/3, y + capHeight/4);
			pushTo(x + w, y + capHeight/2);
			pushTo(x + 2*w/3, y + 3*capHeight/4);
			pushTo(x + w/3, y + capHeight);
		}

		void writeHash(float x, float y)
		{
			pushTo(x, y + capHeight/3);
			pushPD();
			pushTo(x + w, y + capHeight/3);
			pushPU();
			pushTo(x + w, y + 2*capHeight/3);
			pushPD();
			pushTo(x, y + 2*capHeight/3);
			pushPU();

			pushTo(x + w/3, y + capHeight);
			pushPD();
			pushTo(x + w/3, y);
			pushPU();
			pushTo(x + 2*w/3, y);
			pushPD();
			pushTo(x + 2*w/3, y + capHeight);
		}
	}
	// End private namespace functions

	// Logobot text public functions
	void begin(CommandQueue& cmdQ)
	{
		_cmdQ = &cmdQ;
		setFontSize(20);
	}

	void setFontSize(float size)
	{
		fontSize = size;
		capHeight = fontSize * 0.7;
		letterSpacing = fontSize * 0.1;
		w = fontSize * 0.5;
	}

	void writeChar(char c, float x, float y)
	{
		switch (c) {
			case 'A':
				writeA(x, y);
				break;
			case 'B':
				writeB(x, y);
				break;
			case 'C':
				writeC(x, y);
				break;
			case 'D':
				writeD(x, y);
				break;
			case 'E':
				writeE(x, y);
				break;
			case 'F':
				writeF(x, y);
				break;
			case 'G':
				writeG(x, y);
				break;
			case 'H':
				writeH(x, y);
				break;
			case 'I':
				writeI(x, y);
				break;
			case 'J':
				writeJ(x, y);
				break;
			case 'K':
				writeK(x, y);
				break;
			case 'L':
				writeL(x, y);
				break;
			case 'M':
				writeM(x, y);
				break;
			case 'N':
				writeN(x, y);
				break;
			case 'O':
				writeO(x, y);
				break;
			case 'P':
				writeP(x, y);
				break;
			case 'Q':
				writeQ(x, y);
				break;
			case 'R':
				writeR(x, y);
				break;
			case 'S':
				writeS(x, y);
				break;
			case 'T':
				writeT(x, y);
				break;
			case 'U':
				writeU(x, y);
				break;
			case 'V':
				writeV(x, y);
				break;
			case 'W':
				writeW(x, y);
				break;
			case 'X':
				writeX(x, y);
				break;
			case 'Y':
				writeY(x, y);
				break;
			case 'Z':
				writeZ(x, y);
				break;
			case ' ':
				// nothing to do, just move to next letter
				break;
			case ':':
				writeColon(x,y);
				break;
			case ')':
				writeCloseBracket(x,y);
				break;
			case '#':
				writeHash(x,y);
				break;

			default:
				_cmdQ->enqueue("500",LOGO_CMD_BZ);
				//pushCmd("BZ 500");
				return;
		}

		pushPU();
		pushTo(x + w + letterSpacing, y);
	}
}
<|endoftext|>


<commit_before>// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/output/delegating_renderer.h"

#include <set>
#include <string>
#include <vector>

#include "base/debug/trace_event.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/quads/checkerboard_draw_quad.h"
#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/render_pass.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/quads/yuv_video_draw_quad.h"
#include "cc/resources/resource_provider.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/gpu_memory_allocation.h"
#include "third_party/khronos/GLES2/gl2ext.h"

namespace cc {

scoped_ptr<DelegatingRenderer> DelegatingRenderer::Create(
    RendererClient* client,
    const LayerTreeSettings* settings,
    OutputSurface* output_surface,
    ResourceProvider* resource_provider) {
  scoped_ptr<DelegatingRenderer> renderer(new DelegatingRenderer(
      client, settings, output_surface, resource_provider));
  if (!renderer->Initialize())
    return scoped_ptr<DelegatingRenderer>();
  return renderer.Pass();
}

DelegatingRenderer::DelegatingRenderer(RendererClient* client,
                                       const LayerTreeSettings* settings,
                                       OutputSurface* output_surface,
                                       ResourceProvider* resource_provider)
    : Renderer(client, settings),
      output_surface_(output_surface),
      resource_provider_(resource_provider),
      visible_(true) {
  DCHECK(resource_provider_);
}

bool DelegatingRenderer::Initialize() {
  capabilities_.using_partial_swap = false;
  capabilities_.max_texture_size = resource_provider_->max_texture_size();
  capabilities_.best_texture_format = resource_provider_->best_texture_format();
  capabilities_.allow_partial_texture_updates = false;
  capabilities_.using_offscreen_context3d = false;

  if (!output_surface_->context_provider()) {
    capabilities_.using_shared_memory_resources = true;
    capabilities_.using_map_image = settings_->use_map_image;
    return true;
  }

  const ContextProvider::Capabilities& caps =
      output_surface_->context_provider()->ContextCapabilities();

  DCHECK(!caps.gpu.iosurface || caps.gpu.texture_rectangle);

  capabilities_.using_egl_image = caps.gpu.egl_image_external;
  capabilities_.using_map_image =
      settings_->use_map_image && caps.gpu.map_image;

  capabilities_.allow_rasterize_on_demand = false;

  return true;
}

DelegatingRenderer::~DelegatingRenderer() {}

const RendererCapabilitiesImpl& DelegatingRenderer::Capabilities() const {
  return capabilities_;
}

bool DelegatingRenderer::CanReadPixels() const { return false; }

static ResourceProvider::ResourceId AppendToArray(
    ResourceProvider::ResourceIdArray* array,
    ResourceProvider::ResourceId id) {
  array->push_back(id);
  return id;
}

void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
                                   ContextProvider* offscreen_context_provider,
                                   float device_scale_factor,
                                   const gfx::Rect& device_viewport_rect,
                                   const gfx::Rect& device_clip_rect,
                                   bool disable_picture_quad_image_filtering) {
  TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame");

  DCHECK(!delegated_frame_data_);

  delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData);
  DelegatedFrameData& out_data = *delegated_frame_data_;
  // Move the render passes and resources into the |out_frame|.
  out_data.render_pass_list.swap(*render_passes_in_draw_order);

  // Collect all resource ids in the render passes into a ResourceIdArray.
  ResourceProvider::ResourceIdArray resources;
  DrawQuad::ResourceIteratorCallback append_to_array =
      base::Bind(&AppendToArray, &resources);
  for (size_t i = 0; i < out_data.render_pass_list.size(); ++i) {
    RenderPass* render_pass = out_data.render_pass_list.at(i);
    for (size_t j = 0; j < render_pass->quad_list.size(); ++j)
      render_pass->quad_list[j]->IterateResources(append_to_array);
  }
  resource_provider_->PrepareSendToParent(resources, &out_data.resource_list);
}

void DelegatingRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
  TRACE_EVENT0("cc,benchmark", "DelegatingRenderer::SwapBuffers");
  CompositorFrame compositor_frame;
  compositor_frame.metadata = metadata;
  compositor_frame.delegated_frame_data = delegated_frame_data_.Pass();
  output_surface_->SwapBuffers(&compositor_frame);
}

void DelegatingRenderer::GetFramebufferPixels(void* pixels,
                                              const gfx::Rect& rect) {
  NOTREACHED();
}

void DelegatingRenderer::ReceiveSwapBuffersAck(
    const CompositorFrameAck& ack) {
  resource_provider_->ReceiveReturnsFromParent(ack.resources);
}

bool DelegatingRenderer::IsContextLost() {
  ContextProvider* context_provider = output_surface_->context_provider();
  if (!context_provider)
    return false;
  return context_provider->IsContextLost();
}

void DelegatingRenderer::SetVisible(bool visible) {
  if (visible == visible_)
    return;

  visible_ = visible;
  ContextProvider* context_provider = output_surface_->context_provider();
  if (!visible_) {
    TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources");
    resource_provider_->ReleaseCachedData();
    if (context_provider)
      context_provider->ContextGL()->Flush();
  }
  // We loop visibility to the GPU process, since that's what manages memory.
  // That will allow it to feed us with memory allocations that we can act
  // upon.
  if (context_provider)
    context_provider->ContextSupport()->SetSurfaceVisible(visible);
}

void DelegatingRenderer::SendManagedMemoryStats(size_t bytes_visible,
                                                size_t bytes_visible_and_nearby,
                                                size_t bytes_allocated) {
  ContextProvider* context_provider = output_surface_->context_provider();
  if (!context_provider) {
    // TODO(piman): software path.
    NOTIMPLEMENTED();
    return;
  }
  gpu::ManagedMemoryStats stats;
  stats.bytes_required = bytes_visible;
  stats.bytes_nice_to_have = bytes_visible_and_nearby;
  stats.bytes_allocated = bytes_allocated;
  stats.backbuffer_requested = false;

  context_provider->ContextSupport()->SendManagedMemoryStats(stats);
}

}  // namespace cc
<commit_msg>Remove NOTIMPLEMENTED from DelegatingRenderer::SendManagedMemoryStats<commit_after>// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/output/delegating_renderer.h"

#include <set>
#include <string>
#include <vector>

#include "base/debug/trace_event.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/quads/checkerboard_draw_quad.h"
#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/render_pass.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/quads/yuv_video_draw_quad.h"
#include "cc/resources/resource_provider.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/gpu_memory_allocation.h"
#include "third_party/khronos/GLES2/gl2ext.h"

namespace cc {

scoped_ptr<DelegatingRenderer> DelegatingRenderer::Create(
    RendererClient* client,
    const LayerTreeSettings* settings,
    OutputSurface* output_surface,
    ResourceProvider* resource_provider) {
  scoped_ptr<DelegatingRenderer> renderer(new DelegatingRenderer(
      client, settings, output_surface, resource_provider));
  if (!renderer->Initialize())
    return scoped_ptr<DelegatingRenderer>();
  return renderer.Pass();
}

DelegatingRenderer::DelegatingRenderer(RendererClient* client,
                                       const LayerTreeSettings* settings,
                                       OutputSurface* output_surface,
                                       ResourceProvider* resource_provider)
    : Renderer(client, settings),
      output_surface_(output_surface),
      resource_provider_(resource_provider),
      visible_(true) {
  DCHECK(resource_provider_);
}

bool DelegatingRenderer::Initialize() {
  capabilities_.using_partial_swap = false;
  capabilities_.max_texture_size = resource_provider_->max_texture_size();
  capabilities_.best_texture_format = resource_provider_->best_texture_format();
  capabilities_.allow_partial_texture_updates = false;
  capabilities_.using_offscreen_context3d = false;

  if (!output_surface_->context_provider()) {
    capabilities_.using_shared_memory_resources = true;
    capabilities_.using_map_image = settings_->use_map_image;
    return true;
  }

  const ContextProvider::Capabilities& caps =
      output_surface_->context_provider()->ContextCapabilities();

  DCHECK(!caps.gpu.iosurface || caps.gpu.texture_rectangle);

  capabilities_.using_egl_image = caps.gpu.egl_image_external;
  capabilities_.using_map_image =
      settings_->use_map_image && caps.gpu.map_image;

  capabilities_.allow_rasterize_on_demand = false;

  return true;
}

DelegatingRenderer::~DelegatingRenderer() {}

const RendererCapabilitiesImpl& DelegatingRenderer::Capabilities() const {
  return capabilities_;
}

bool DelegatingRenderer::CanReadPixels() const { return false; }

static ResourceProvider::ResourceId AppendToArray(
    ResourceProvider::ResourceIdArray* array,
    ResourceProvider::ResourceId id) {
  array->push_back(id);
  return id;
}

void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
                                   ContextProvider* offscreen_context_provider,
                                   float device_scale_factor,
                                   const gfx::Rect& device_viewport_rect,
                                   const gfx::Rect& device_clip_rect,
                                   bool disable_picture_quad_image_filtering) {
  TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame");

  DCHECK(!delegated_frame_data_);

  delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData);
  DelegatedFrameData& out_data = *delegated_frame_data_;
  // Move the render passes and resources into the |out_frame|.
  out_data.render_pass_list.swap(*render_passes_in_draw_order);

  // Collect all resource ids in the render passes into a ResourceIdArray.
  ResourceProvider::ResourceIdArray resources;
  DrawQuad::ResourceIteratorCallback append_to_array =
      base::Bind(&AppendToArray, &resources);
  for (size_t i = 0; i < out_data.render_pass_list.size(); ++i) {
    RenderPass* render_pass = out_data.render_pass_list.at(i);
    for (size_t j = 0; j < render_pass->quad_list.size(); ++j)
      render_pass->quad_list[j]->IterateResources(append_to_array);
  }
  resource_provider_->PrepareSendToParent(resources, &out_data.resource_list);
}

void DelegatingRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
  TRACE_EVENT0("cc,benchmark", "DelegatingRenderer::SwapBuffers");
  CompositorFrame compositor_frame;
  compositor_frame.metadata = metadata;
  compositor_frame.delegated_frame_data = delegated_frame_data_.Pass();
  output_surface_->SwapBuffers(&compositor_frame);
}

void DelegatingRenderer::GetFramebufferPixels(void* pixels,
                                              const gfx::Rect& rect) {
  NOTREACHED();
}

void DelegatingRenderer::ReceiveSwapBuffersAck(
    const CompositorFrameAck& ack) {
  resource_provider_->ReceiveReturnsFromParent(ack.resources);
}

bool DelegatingRenderer::IsContextLost() {
  ContextProvider* context_provider = output_surface_->context_provider();
  if (!context_provider)
    return false;
  return context_provider->IsContextLost();
}

void DelegatingRenderer::SetVisible(bool visible) {
  if (visible == visible_)
    return;

  visible_ = visible;
  ContextProvider* context_provider = output_surface_->context_provider();
  if (!visible_) {
    TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources");
    resource_provider_->ReleaseCachedData();
    if (context_provider)
      context_provider->ContextGL()->Flush();
  }
  // We loop visibility to the GPU process, since that's what manages memory.
  // That will allow it to feed us with memory allocations that we can act
  // upon.
  if (context_provider)
    context_provider->ContextSupport()->SetSurfaceVisible(visible);
}

void DelegatingRenderer::SendManagedMemoryStats(size_t bytes_visible,
                                                size_t bytes_visible_and_nearby,
                                                size_t bytes_allocated) {
  ContextProvider* context_provider = output_surface_->context_provider();
  if (!context_provider) {
    // In the software path each child process manages its memory separately,
    // so memory stats don't have to be sent anywhere.
    return;
  }
  gpu::ManagedMemoryStats stats;
  stats.bytes_required = bytes_visible;
  stats.bytes_nice_to_have = bytes_visible_and_nearby;
  stats.bytes_allocated = bytes_allocated;
  stats.backbuffer_requested = false;

  context_provider->ContextSupport()->SendManagedMemoryStats(stats);
}

}  // namespace cc
<|endoftext|>


<commit_before>//
// Copyright Renga Software LLC, 2016. All rights reserved.
//
// Renga Software LLC PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// Renga Software LLC  DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//

#include "stdafx.h"
#include "PropertyView.h"
#include "GuidUtils.h"

#include <qteditorfactory.h>
#include "PropertyViewModelObjectSource.h"

PropertyView::PropertyView(QWidget* pParent, Renga::IApplicationPtr pApplication) :
  QtTreePropertyBrowser(pParent),
  m_pApplication(pApplication),
  m_propertyViewMode(CategoryMode)
{
  m_pGroupManager = new QtGroupPropertyManager(this);

  initPropertyManagers();
}

void PropertyView::showProperties(IPropertyViewSourceObject* pSourceObject)
{
  m_pSourceObject.reset(pSourceObject);

  buildPropertyView(pSourceObject);
}

void PropertyView::changeMode(PropertyView::Mode newMode)
{
  m_propertyViewMode = newMode;

  buildPropertyView(m_pSourceObject.get());
}

void PropertyView::initPropertyManagers()
{
  m_propertyManagers.init(this);

   // handle user attributes changes

  {
    auto& mngr = m_propertyManagers.m_parameters;
    QObject::connect(mngr.m_pBoolManager, SIGNAL(valueChanged(QtProperty*, const QString&)), this, SLOT(parameterBoolChanged(QtProperty*, const QString&)));
    QObject::connect(mngr.m_pIntManager, SIGNAL(valueChanged(QtProperty*, const QString&)), this, SLOT(parameterIntChanged(QtProperty*, const QString&)));
    QObject::connect(mngr.m_pDoubleManager, SIGNAL(valueChanged(QtProperty*, const QString&)), this, SLOT(parameterDoubleChanged(QtProperty*, const QString&)));
    QObject::connect(mngr.m_pStringManager, SIGNAL(valueChanged(QtProperty*, const QString&)), this, SLOT(parameterStringChanged(QtProperty*, const QString&)));
  }

   QObject::connect(
     m_propertyManagers.m_properties.m_pDoubleManager, SIGNAL(valueChanged(QtProperty*, const QString&)),
     this, SLOT(userDoubleAttributeChanged(QtProperty*, const QString&)));
   QObject::connect(
     m_propertyManagers.m_properties.m_pStringManager, SIGNAL(valueChanged(QtProperty*, const QString&)),
     this, SLOT(userStringAttributeChanged(QtProperty*, const QString&)));
}

void PropertyView::clearPropertyManagers()
{
  m_propertyManagers.clear();
  m_pGroupManager->clear();
}

void PropertyView::buildPropertyViewAsList(PropertyList& parameters, PropertyList& parametersEx, PropertyList& calculated, PropertyList& userDefinedProperties)
{
  // show in list mode
  PropertyList allProperties;
  allProperties.splice(allProperties.end(), parameters);
  allProperties.splice(allProperties.end(), parametersEx);
  allProperties.splice(allProperties.end(), calculated);
  allProperties.splice(allProperties.end(), userDefinedProperties);

  allProperties.sort([](QtProperty* left, QtProperty* right) -> bool
                    {
                    return left->propertyName() < right->propertyName();
                    });

  for (auto it = allProperties.begin(); it != allProperties.end(); ++it)
    addProperty(*it);
}

void PropertyView::buildPropertyViewSingleCategory(const QString& categoryName, const PropertyList& categoryProperties)
{
  if(categoryProperties.empty())
    return;

  QtProperty* pCategoryProperty = m_pGroupManager->addProperty(categoryName);
  pCategoryProperty->setBold(true);

  PropertyList singleCategoryProperties(categoryProperties);
  singleCategoryProperties.sort([](QtProperty* left, QtProperty* right) -> bool
                               {
                                 return left->propertyName() < right->propertyName();
                               });

  for (auto it = singleCategoryProperties.begin(); it != singleCategoryProperties.end(); ++it)
    pCategoryProperty->addSubProperty(*it);

  addProperty(pCategoryProperty);
}

void PropertyView::buildPropertyView(IPropertyViewSourceObject* pSourceObject)
{
  clearPropertyManagers();

  if (pSourceObject == nullptr)
    return;

  auto propertyViewBuilder = pSourceObject->createPropertyViewBuilder(&m_propertyManagers);

  PropertyList integratedParameters;

  PropertyList parameters;
  PropertyList quantities;
  PropertyList properties;

  if (!createProperties(propertyViewBuilder.get(), integratedParameters, parameters, quantities, properties))
    return;

  if (m_propertyViewMode == Mode::ListMode)
    buildPropertyViewAsList(integratedParameters, parameters, quantities, properties);
  else
    buildPropertyViewByCategory(integratedParameters, parameters, quantities, properties);
}

void PropertyView::buildPropertyViewByCategory(const PropertyList& integratedParameters, PropertyList& parameters, const PropertyList& quantities, const PropertyList& properties)
{
  buildPropertyViewSingleCategory(QApplication::translate("me_propertyView", "Object parameters"), integratedParameters);
  buildPropertyViewSingleCategory(QApplication::translate("me_propertyView", "Object parameters ex"), parameters);
  buildPropertyViewSingleCategory(QApplication::translate("me_propertyView", "Calculated characteristics"), quantities);
  buildPropertyViewSingleCategory(QApplication::translate("me_propertyView", "Object properties"), properties);
}

bool PropertyView::createProperties(
  IPropertyViewBuilder* pObjectPropertyViewBuilder,
  PropertyList& integratedParameters,
  PropertyList& parameters,
  PropertyList& quantities,
  PropertyList& properties)
{
  if (pObjectPropertyViewBuilder == nullptr)
    return false;

  integratedParameters.clear();

  parameters.clear();
  quantities.clear();

  pObjectPropertyViewBuilder->createIntegratedParameters(integratedParameters);

  pObjectPropertyViewBuilder->createParameters(parameters);
  pObjectPropertyViewBuilder->createQuantities(quantities);

  properties = pObjectPropertyViewBuilder->createProperties();

  return true;
}

void PropertyView::parameterBoolChanged(QtProperty* pProperty, const QString& newValue)
{
  //if (!newValue.isEmpty())
  //{
  //  bool ok = false;
  //  double newDoubleValue = QLocale::system().toBool(newValue, &ok);
  //  if (ok)
  //  {
  //    const auto parameterId = GuidFromString(pProperty->data().toStdString());

  //    auto pParameter = m_pSourceObject->getParameter(parameterId);
  //    if (!pParameter)
  //      return;

  //    if (pParameter->GetValueType() != Renga::ParameterValueType::ParameterValueType_Bool)
  //      return;

  //    if (auto pOperation = createOperation())
  //    {
  //      pOperation->Start();
  //      pParameter->SetDoubleValue(newDoubleValue);
  //      pOperation->Apply();
  //    }
  //  }
  //}
}

void PropertyView::parameterIntChanged(QtProperty* pProperty, const QString& newValue)
{
  if (!newValue.isEmpty())
  {
    bool ok = false;
    double newDoubleValue = QLocale::system().toInt(newValue, &ok);
    if (ok)
    {
      const auto parameterId = GuidFromString(pProperty->data().toStdString());

      auto pParameter = m_pSourceObject->getParameter(parameterId);
      if (!pParameter)
        return;

      if (pParameter->GetValueType() != Renga::ParameterValueType::ParameterValueType_Int)
        return;

      if (auto pOperation = createOperation())
      {
        pOperation->Start();
        pParameter->SetDoubleValue(newDoubleValue);
        pOperation->Apply();
      }
    }
  }
}

void PropertyView::parameterDoubleChanged(QtProperty* pProperty, const QString& newValue)
{
  if (!newValue.isEmpty())
  {
    bool ok = false;
    double newDoubleValue = QLocale::system().toDouble(newValue, &ok);
    if (ok)
    {
      const auto parameterId = GuidFromString(pProperty->data().toStdString());

      auto pParameter = m_pSourceObject->getParameter(parameterId);
      if (!pParameter)
        return;

      if (pParameter->GetValueType() != Renga::ParameterValueType::ParameterValueType_Double)
        return;

      if (auto pOperation = createOperation())
      {
        pOperation->Start();
        pParameter->SetDoubleValue(newDoubleValue);
        pOperation->Apply();
      }
    }
  }
}

void PropertyView::parameterStringChanged(QtProperty* pProperty, const QString& newValue)
{
  const auto parameterId = GuidFromString(pProperty->data().toStdString());

  auto pParameter = m_pSourceObject->getParameter(parameterId);
  if (!pParameter)
    return;

  if (pParameter->GetValueType() != Renga::ParameterValueType::ParameterValueType_String)
    return;

  if (auto pOperation = createOperation())
  {
    pOperation->Start();
    pParameter->SetStringValue(newValue.toStdWString().c_str());
    pOperation->Apply();
  }
}

void PropertyView::userDoubleAttributeChanged(QtProperty* userAttributeProperty, const QString& newValue)
{
  if (newValue.isEmpty())
    resetUserAttribute(userAttributeProperty); // will reset the attribute value
  else
  {
    bool ok = false;
    double newDoubleValue = QLocale::system().toDouble(newValue, &ok);
    if (ok)
      changeUserAttribute(userAttributeProperty, newDoubleValue);
  }
}

void PropertyView::userStringAttributeChanged(QtProperty* userAttributeProperty, const QString& newValue)
{
  if (newValue.isEmpty())
    resetUserAttribute(userAttributeProperty); // will reset the attribute value
  else
    changeUserAttribute(userAttributeProperty, newValue.toStdWString());
}

Renga::IPropertyPtr PropertyView::getProperty(QtProperty* userAttributeProperty)
{
  if (m_pSourceObject == nullptr)
    return nullptr;

  const auto propertyId = GuidFromString(userAttributeProperty->data().toStdString());

  return m_pSourceObject->getUserDefinedProperty(propertyId);
}

Renga::IOperationPtr PropertyView::createOperation()
{
  auto pProject = m_pApplication->GetProject();
  auto pModel = pProject->GetModel();
  return pModel->CreateOperation();
}

void PropertyView::resetUserAttribute(QtProperty* userAttributeProperty)
{
  auto pProperty = getProperty(userAttributeProperty);
  if (!pProperty)
    return;

  auto pOperation = createOperation();
  pOperation->Start();

  pProperty->ResetValue();

  pOperation->Apply();
}

void PropertyView::changeUserAttribute(QtProperty* userAttributeProperty, const double value)
{
  auto pProperty = getProperty(userAttributeProperty);
  if (!pProperty)
    return;

  if (pProperty->GetType() != Renga::PropertyType::PropertyType_Double)
    return;

  auto pOperation = createOperation();

  pOperation->Start();
  pProperty->SetDoubleValue(value);
  pOperation->Apply();
}

void PropertyView::changeUserAttribute(QtProperty* userAttributeProperty, const std::wstring& value)
{
  auto pProperty = getProperty(userAttributeProperty);
  if (!pProperty)
    return;

  if (pProperty->GetType() != Renga::PropertyType::PropertyType_String)
    return;

  auto pOperation = createOperation();

  pOperation->Start();
  pProperty->SetStringValue(value.c_str());
  pOperation->Apply();
}
<commit_msg>Fix for update model object parameters<commit_after>//
// Copyright Renga Software LLC, 2016. All rights reserved.
//
// Renga Software LLC PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// Renga Software LLC  DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//

#include "stdafx.h"
#include "PropertyView.h"
#include "GuidUtils.h"

#include <qteditorfactory.h>
#include "PropertyViewModelObjectSource.h"

PropertyView::PropertyView(QWidget* pParent, Renga::IApplicationPtr pApplication) :
  QtTreePropertyBrowser(pParent),
  m_pApplication(pApplication),
  m_propertyViewMode(CategoryMode)
{
  m_pGroupManager = new QtGroupPropertyManager(this);

  initPropertyManagers();
}

void PropertyView::showProperties(IPropertyViewSourceObject* pSourceObject)
{
  m_pSourceObject.reset(pSourceObject);

  buildPropertyView(pSourceObject);
}

void PropertyView::changeMode(PropertyView::Mode newMode)
{
  m_propertyViewMode = newMode;

  buildPropertyView(m_pSourceObject.get());
}

void PropertyView::initPropertyManagers()
{
  m_propertyManagers.init(this);

   // handle user attributes changes

  {
    auto& mngr = m_propertyManagers.m_parameters;
    QObject::connect(mngr.m_pBoolManager, SIGNAL(valueChanged(QtProperty*, const QString&)), this, SLOT(parameterBoolChanged(QtProperty*, const QString&)));
    QObject::connect(mngr.m_pIntManager, SIGNAL(valueChanged(QtProperty*, const QString&)), this, SLOT(parameterIntChanged(QtProperty*, const QString&)));
    QObject::connect(mngr.m_pDoubleManager, SIGNAL(valueChanged(QtProperty*, const QString&)), this, SLOT(parameterDoubleChanged(QtProperty*, const QString&)));
    QObject::connect(mngr.m_pStringManager, SIGNAL(valueChanged(QtProperty*, const QString&)), this, SLOT(parameterStringChanged(QtProperty*, const QString&)));
  }

   QObject::connect(
     m_propertyManagers.m_properties.m_pDoubleManager, SIGNAL(valueChanged(QtProperty*, const QString&)),
     this, SLOT(userDoubleAttributeChanged(QtProperty*, const QString&)));
   QObject::connect(
     m_propertyManagers.m_properties.m_pStringManager, SIGNAL(valueChanged(QtProperty*, const QString&)),
     this, SLOT(userStringAttributeChanged(QtProperty*, const QString&)));
}

void PropertyView::clearPropertyManagers()
{
  m_propertyManagers.clear();
  m_pGroupManager->clear();
}

void PropertyView::buildPropertyViewAsList(PropertyList& parameters, PropertyList& parametersEx, PropertyList& calculated, PropertyList& userDefinedProperties)
{
  // show in list mode
  PropertyList allProperties;
  allProperties.splice(allProperties.end(), parameters);
  allProperties.splice(allProperties.end(), parametersEx);
  allProperties.splice(allProperties.end(), calculated);
  allProperties.splice(allProperties.end(), userDefinedProperties);

  allProperties.sort([](QtProperty* left, QtProperty* right) -> bool
                    {
                    return left->propertyName() < right->propertyName();
                    });

  for (auto it = allProperties.begin(); it != allProperties.end(); ++it)
    addProperty(*it);
}

void PropertyView::buildPropertyViewSingleCategory(const QString& categoryName, const PropertyList& categoryProperties)
{
  if(categoryProperties.empty())
    return;

  QtProperty* pCategoryProperty = m_pGroupManager->addProperty(categoryName);
  pCategoryProperty->setBold(true);

  PropertyList singleCategoryProperties(categoryProperties);
  singleCategoryProperties.sort([](QtProperty* left, QtProperty* right) -> bool
                               {
                                 return left->propertyName() < right->propertyName();
                               });

  for (auto it = singleCategoryProperties.begin(); it != singleCategoryProperties.end(); ++it)
    pCategoryProperty->addSubProperty(*it);

  addProperty(pCategoryProperty);
}

void PropertyView::buildPropertyView(IPropertyViewSourceObject* pSourceObject)
{
  clearPropertyManagers();

  if (pSourceObject == nullptr)
    return;

  auto propertyViewBuilder = pSourceObject->createPropertyViewBuilder(&m_propertyManagers);

  PropertyList integratedParameters;

  PropertyList parameters;
  PropertyList quantities;
  PropertyList properties;

  if (!createProperties(propertyViewBuilder.get(), integratedParameters, parameters, quantities, properties))
    return;

  if (m_propertyViewMode == Mode::ListMode)
    buildPropertyViewAsList(integratedParameters, parameters, quantities, properties);
  else
    buildPropertyViewByCategory(integratedParameters, parameters, quantities, properties);
}

void PropertyView::buildPropertyViewByCategory(const PropertyList& integratedParameters, PropertyList& parameters, const PropertyList& quantities, const PropertyList& properties)
{
  buildPropertyViewSingleCategory(QApplication::translate("me_propertyView", "Object parameters"), integratedParameters);
  buildPropertyViewSingleCategory(QApplication::translate("me_propertyView", "Object parameters ex"), parameters);
  buildPropertyViewSingleCategory(QApplication::translate("me_propertyView", "Calculated characteristics"), quantities);
  buildPropertyViewSingleCategory(QApplication::translate("me_propertyView", "Object properties"), properties);
}

bool PropertyView::createProperties(
  IPropertyViewBuilder* pObjectPropertyViewBuilder,
  PropertyList& integratedParameters,
  PropertyList& parameters,
  PropertyList& quantities,
  PropertyList& properties)
{
  if (pObjectPropertyViewBuilder == nullptr)
    return false;

  integratedParameters.clear();

  parameters.clear();
  quantities.clear();

  pObjectPropertyViewBuilder->createIntegratedParameters(integratedParameters);

  pObjectPropertyViewBuilder->createParameters(parameters);
  pObjectPropertyViewBuilder->createQuantities(quantities);

  properties = pObjectPropertyViewBuilder->createProperties();

  return true;
}

void PropertyView::parameterBoolChanged(QtProperty* pProperty, const QString& newValue)
{
  if (!newValue.isEmpty())
  {
    bool newBoolValue = (newValue != "false") && (newValue != "False");

    const auto parameterId = GuidFromString(pProperty->data().toStdString());

    auto pParameter = m_pSourceObject->getParameter(parameterId);
    if (!pParameter)
      return;

    if (pParameter->GetValueType() != Renga::ParameterValueType::ParameterValueType_Bool)
      return;

    if (auto pOperation = createOperation())
    {
      pOperation->Start();
      pParameter->SetBoolValue(newBoolValue);
      pOperation->Apply();
    }
  }
}

void PropertyView::parameterIntChanged(QtProperty* pProperty, const QString& newValue)
{
  if (!newValue.isEmpty())
  {
    bool ok = false;
    int newIntValue = QLocale::system().toInt(newValue, &ok);
    if (ok)
    {
      const auto parameterId = GuidFromString(pProperty->data().toStdString());

      auto pParameter = m_pSourceObject->getParameter(parameterId);
      if (!pParameter)
        return;

      if (pParameter->GetValueType() != Renga::ParameterValueType::ParameterValueType_Int)
        return;

      if (auto pOperation = createOperation())
      {
        pOperation->Start();
        pParameter->SetIntValue(newIntValue);
        pOperation->Apply();
      }
    }
  }
}

void PropertyView::parameterDoubleChanged(QtProperty* pProperty, const QString& newValue)
{
  if (!newValue.isEmpty())
  {
    bool ok = false;
    double newDoubleValue = QLocale::system().toDouble(newValue, &ok);
    if (ok)
    {
      const auto parameterId = GuidFromString(pProperty->data().toStdString());

      auto pParameter = m_pSourceObject->getParameter(parameterId);
      if (!pParameter)
        return;

      if (pParameter->GetValueType() != Renga::ParameterValueType::ParameterValueType_Double)
        return;

      if (auto pOperation = createOperation())
      {
        pOperation->Start();
        pParameter->SetDoubleValue(newDoubleValue);
        pOperation->Apply();
      }
    }
  }
}

void PropertyView::parameterStringChanged(QtProperty* pProperty, const QString& newValue)
{
  const auto parameterId = GuidFromString(pProperty->data().toStdString());

  auto pParameter = m_pSourceObject->getParameter(parameterId);
  if (!pParameter)
    return;

  if (pParameter->GetValueType() != Renga::ParameterValueType::ParameterValueType_String)
    return;

  if (auto pOperation = createOperation())
  {
    pOperation->Start();
    pParameter->SetStringValue(newValue.toStdWString().c_str());
    pOperation->Apply();
  }
}

void PropertyView::userDoubleAttributeChanged(QtProperty* userAttributeProperty, const QString& newValue)
{
  if (newValue.isEmpty())
    resetUserAttribute(userAttributeProperty); // will reset the attribute value
  else
  {
    bool ok = false;
    double newDoubleValue = QLocale::system().toDouble(newValue, &ok);
    if (ok)
      changeUserAttribute(userAttributeProperty, newDoubleValue);
  }
}

void PropertyView::userStringAttributeChanged(QtProperty* userAttributeProperty, const QString& newValue)
{
  if (newValue.isEmpty())
    resetUserAttribute(userAttributeProperty); // will reset the attribute value
  else
    changeUserAttribute(userAttributeProperty, newValue.toStdWString());
}

Renga::IPropertyPtr PropertyView::getProperty(QtProperty* userAttributeProperty)
{
  if (m_pSourceObject == nullptr)
    return nullptr;

  const auto propertyId = GuidFromString(userAttributeProperty->data().toStdString());

  return m_pSourceObject->getUserDefinedProperty(propertyId);
}

Renga::IOperationPtr PropertyView::createOperation()
{
  auto pProject = m_pApplication->GetProject();
  auto pModel = pProject->GetModel();
  return pModel->CreateOperation();
}

void PropertyView::resetUserAttribute(QtProperty* userAttributeProperty)
{
  auto pProperty = getProperty(userAttributeProperty);
  if (!pProperty)
    return;

  auto pOperation = createOperation();
  pOperation->Start();

  pProperty->ResetValue();

  pOperation->Apply();
}

void PropertyView::changeUserAttribute(QtProperty* userAttributeProperty, const double value)
{
  auto pProperty = getProperty(userAttributeProperty);
  if (!pProperty)
    return;

  if (pProperty->GetType() != Renga::PropertyType::PropertyType_Double)
    return;

  auto pOperation = createOperation();

  pOperation->Start();
  pProperty->SetDoubleValue(value);
  pOperation->Apply();
}

void PropertyView::changeUserAttribute(QtProperty* userAttributeProperty, const std::wstring& value)
{
  auto pProperty = getProperty(userAttributeProperty);
  if (!pProperty)
    return;

  if (pProperty->GetType() != Renga::PropertyType::PropertyType_String)
    return;

  auto pOperation = createOperation();

  pOperation->Start();
  pProperty->SetStringValue(value.c_str());
  pOperation->Apply();
}
<|endoftext|>


<commit_before>#include <htl_stdinc.hpp>

// system
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
#include <inttypes.h>

// socket
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// dns
#include <netdb.h>

#include <string>
using namespace std;

#include <htl_core_error.hpp>
#include <htl_core_log.hpp>

#include <htl_os_st.hpp>

StStatistic::StStatistic(){
    starttime = StUtility::GetCurrentTime();
    threads = alive = 0;
    nread = nwrite = 0;
    tasks = err_tasks = sub_tasks = err_sub_tasks = 0;
}

StStatistic::~StStatistic(){
}

void StStatistic::OnRead(int /*tid*/, ssize_t nread){
    this->nread += nread;
}

void StStatistic::OnWrite(int /*tid*/, ssize_t nwrite){
    this->nwrite += nwrite;
}

void StStatistic::OnThreadRun(int /*tid*/){
    threads++;
}

void StStatistic::OnThreadQuit(int /*tid*/){
    threads--;
}

void StStatistic::OnTaskStart(int /*tid*/, std::string /*task_url*/){
    alive++;
    tasks++;
}

void StStatistic::OnTaskError(int /*tid*/){
    alive--;
    err_tasks++;
}

void StStatistic::OnTaskEnd(int /*tid*/){
    alive--;
}

void StStatistic::OnSubTaskStart(int /*tid*/, std::string /*sub_task_url*/){
    sub_tasks++;
}

void StStatistic::OnSubTaskError(int /*tid*/){
    err_sub_tasks++;
}

void StStatistic::OnSubTaskEnd(int /*tid*/){
}

void StStatistic::DoReport(double sleep_ms){
    for(;;){
        int64_t duration = StUtility::GetCurrentTime() - starttime;
        double read_mbps = 0, write_mbps = 0;

        if(duration > 0){
            read_mbps = nread * 8.0 / duration / 1000;
            write_mbps = nwrite * 8.0 / duration / 1000;
        }

        LReport("[report] [%d] threads:%d alive:%d duration:%.0f nread:%.2f nwrite:%.2f "
            "tasks:%"PRId64" etasks:%"PRId64" stasks:%"PRId64" estasks:%"PRId64,
            getpid(), threads, alive, duration/1000.0, read_mbps, write_mbps,
            tasks, err_tasks, sub_tasks, err_sub_tasks);

        st_usleep(sleep_ms * 1000);
    }
}

StStatistic* statistic = new StStatistic();

StTask::StTask(){
    static int _id = 0;
    id = ++_id;
}

StTask::~StTask(){
}

int StTask::GetId(){
    return id;
}

StFarm::StFarm(){
}

StFarm::~StFarm(){
}

int StFarm::Initialize(double report){
    int ret = ERROR_SUCCESS;

    report_seconds = report;

    // use linux epoll.
    if(st_set_eventsys(ST_EVENTSYS_ALT) == -1){
        ret = ERROR_ST_INITIALIZE;
        Error("st_set_eventsys use linux epoll failed. ret=%d", ret);
        return ret;
    }

    if(st_init() != 0){
        ret = ERROR_ST_INITIALIZE;
        Error("st_init failed. ret=%d", ret);
        return ret;
    }

    StUtility::InitRandom();

    return ret;
}

int StFarm::Spawn(StTask* task){
    int ret = ERROR_SUCCESS;

    if(st_thread_create(st_thread_function, task, 0, 0) == NULL){
        ret = ERROR_ST_THREAD_CREATE;
        Error("crate st_thread failed, ret=%d", ret);
        return ret;
    }

    Trace("create thread for task #%d success", task->GetId());

    return ret;
}

int StFarm::WaitAll(){
    int ret = ERROR_SUCCESS;

    // main thread turn to a report therad.
    statistic->DoReport(report_seconds * 1000);

    st_thread_exit(NULL);

    return ret;
}

void* StFarm::st_thread_function(void* args){
    StTask* task = (StTask*)args;

    context->SetId(task->GetId());

    statistic->OnThreadRun(task->GetId());

    int ret = task->Process();

    statistic->OnThreadQuit(task->GetId());

    if(ret != ERROR_SUCCESS){
        Warn("st task terminate with ret=%d", ret);
    }
    else{
        Trace("st task terminate with ret=%d", ret);
    }

    delete task;

    return NULL;
}

StSocket::StSocket(){
    sock_nfd = NULL;
    status = SocketInit;
}

StSocket::~StSocket(){
    Close();
}

SocketStatus StSocket::Status(){
    return status;
}

int StSocket::Connect(const char* ip, int port){
    int ret = ERROR_SUCCESS;

    Close();

    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock == -1){
        ret = ERROR_SOCKET;
        Error("create socket error. ret=%d", ret);
        return ret;
    }

    int reuse_socket = 1;
    if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse_socket, sizeof(int)) == -1){
        ret = ERROR_SOCKET;
        Error("setsockopt reuse-addr error. ret=%d", ret);
        return ret;
    }

    int optlen, optval0, optval1, recv_buf_size = HTTP_BODY_BUFFER*10;
    getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &optval0, (socklen_t*)&optlen);
    if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &recv_buf_size, sizeof(recv_buf_size)) == -1){
        ret = ERROR_SOCKET;
        Error("setsockopt recvbuf error. ret=%d", ret);
        return ret;
    }
    getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &optval1, (socklen_t*)&optlen);
    Trace("socket buff size %d set to %d, current is %d", optval0, recv_buf_size, optval1);

    sock_nfd = st_netfd_open_socket(sock);
    if(sock_nfd == NULL){
        ret = ERROR_OPEN_SOCKET;
        Error("st_netfd_open_socket failed. ret=%d", ret);
        return ret;
    }
    Info("create socket(%d) success", sock);

    // connect to server
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);

    if(st_connect(sock_nfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){
        ret = ERROR_CONNECT;
        Error("connect to server(%s:%d) error. ret=%d", ip, port, ret);
        return ret;
    }
    Info("connec to server %s at port %d success", ip, port);

    status = SocketConnected;

    return ret;
}

int StSocket::Read(const void* buf, size_t size, ssize_t* nread){
    int ret = ERROR_SUCCESS;

    *nread = st_read(sock_nfd, (void*)buf, size, ST_UTIME_NO_TIMEOUT);

    if(*nread <= 0){
        if(errno == ETIME){
            errno = EAGAIN;
        }

        ret = ERROR_READ;
        status = SocketDisconnected;
    }

    if(*nread > 0){
        statistic->OnRead(context->GetId(), *nread);
    }

    return ret;
}

int StSocket::Write(const void* buf, size_t size, ssize_t* nwrite){
    int ret = ERROR_SUCCESS;

    *nwrite = st_write(sock_nfd, (void*)buf, size, ST_UTIME_NO_TIMEOUT);

    if(*nwrite <= 0){
        if(errno == ETIME){
            errno = EAGAIN;
        }

        ret = ERROR_SEND;
        status = SocketDisconnected;
    }

    if(*nwrite > 0){
        statistic->OnWrite(context->GetId(), *nwrite);
    }

    return ret;
}

int StSocket::Close(){
    int ret = ERROR_SUCCESS;

    if(sock_nfd == NULL){
        return ret;
    }

    if(st_netfd_close(sock_nfd) != 0){
        ret = ERROR_CLOSE;
    }

    sock_nfd = NULL;
    status = SocketDisconnected;

    return ret;
}

int64_t StUtility::GetCurrentTime(){
    timeval now;

    int ret = gettimeofday(&now, NULL);

    if(ret == -1){
        Warn("gettimeofday error, ret=%d", ret);
    }

    // we must convert the tv_sec/tv_usec to int64_t.
    return ((int64_t)now.tv_sec)*1000 + ((int64_t)now.tv_usec) / 1000;
}

void StUtility::InitRandom(){
    timeval now;

    if(gettimeofday(&now, NULL) == -1){
        srand(0);
        return;
    }

    srand(now.tv_sec * 1000000 + now.tv_usec);
}

st_utime_t StUtility::BuildRandomMTime(double sleep_seconds){
    if(sleep_seconds <= 0){
        return 0 * 1000;
    }

    // 80% consts value.
    // 40% random value.
    // to get more graceful random time to mocking HLS client.
    st_utime_t sleep_ms = (int)(sleep_seconds * 1000 * 0.8) + rand() % (int)(sleep_seconds * 1000 * 0.4);

    return sleep_ms;
}

int StUtility::DnsResolve(string host, string& ip){
    int ret = ERROR_SUCCESS;

    if(inet_addr(host.c_str()) != INADDR_NONE){
        ip = host;
        Info("dns resolve %s to %s", host.c_str(), ip.c_str());

        return ret;
    }

    hostent* answer = gethostbyname(host.c_str());
    if(answer == NULL){
        ret = ERROR_DNS_RESOLVE;
        Error("dns resolve host %s error. ret=%d", host.c_str(), ret);
        return ret;
    }

    char ipv4[16];
    memset(ipv4, 0, sizeof(ipv4));
    for(int i = 0; i < answer->h_length; i++){
        inet_ntop(AF_INET, answer->h_addr_list[i], ipv4, sizeof(ipv4));
        Info("dns resolve host %s to %s.", host.c_str(), ipv4);
        break;
    }

    ip = ipv4;
    Info("dns resolve %s to %s", host.c_str(), ip.c_str());

    return ret;
}

StLogContext::StLogContext(){
}

StLogContext::~StLogContext(){
}

void StLogContext::SetId(int id){
    cache[st_thread_self()] = id;
}

int StLogContext::GetId(){
    return cache[st_thread_self()];
}
<commit_msg>donot set socket buffer size.<commit_after>#include <htl_stdinc.hpp>

// system
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
#include <inttypes.h>

// socket
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// dns
#include <netdb.h>

#include <string>
using namespace std;

#include <htl_core_error.hpp>
#include <htl_core_log.hpp>

#include <htl_os_st.hpp>

StStatistic::StStatistic(){
    starttime = StUtility::GetCurrentTime();
    threads = alive = 0;
    nread = nwrite = 0;
    tasks = err_tasks = sub_tasks = err_sub_tasks = 0;
}

StStatistic::~StStatistic(){
}

void StStatistic::OnRead(int /*tid*/, ssize_t nread){
    this->nread += nread;
}

void StStatistic::OnWrite(int /*tid*/, ssize_t nwrite){
    this->nwrite += nwrite;
}

void StStatistic::OnThreadRun(int /*tid*/){
    threads++;
}

void StStatistic::OnThreadQuit(int /*tid*/){
    threads--;
}

void StStatistic::OnTaskStart(int /*tid*/, std::string /*task_url*/){
    alive++;
    tasks++;
}

void StStatistic::OnTaskError(int /*tid*/){
    alive--;
    err_tasks++;
}

void StStatistic::OnTaskEnd(int /*tid*/){
    alive--;
}

void StStatistic::OnSubTaskStart(int /*tid*/, std::string /*sub_task_url*/){
    sub_tasks++;
}

void StStatistic::OnSubTaskError(int /*tid*/){
    err_sub_tasks++;
}

void StStatistic::OnSubTaskEnd(int /*tid*/){
}

void StStatistic::DoReport(double sleep_ms){
    for(;;){
        int64_t duration = StUtility::GetCurrentTime() - starttime;
        double read_mbps = 0, write_mbps = 0;

        if(duration > 0){
            read_mbps = nread * 8.0 / duration / 1000;
            write_mbps = nwrite * 8.0 / duration / 1000;
        }

        LReport("[report] [%d] threads:%d alive:%d duration:%.0f nread:%.2f nwrite:%.2f "
            "tasks:%"PRId64" etasks:%"PRId64" stasks:%"PRId64" estasks:%"PRId64,
            getpid(), threads, alive, duration/1000.0, read_mbps, write_mbps,
            tasks, err_tasks, sub_tasks, err_sub_tasks);

        st_usleep(sleep_ms * 1000);
    }
}

StStatistic* statistic = new StStatistic();

StTask::StTask(){
    static int _id = 0;
    id = ++_id;
}

StTask::~StTask(){
}

int StTask::GetId(){
    return id;
}

StFarm::StFarm(){
}

StFarm::~StFarm(){
}

int StFarm::Initialize(double report){
    int ret = ERROR_SUCCESS;

    report_seconds = report;

    // use linux epoll.
    if(st_set_eventsys(ST_EVENTSYS_ALT) == -1){
        ret = ERROR_ST_INITIALIZE;
        Error("st_set_eventsys use linux epoll failed. ret=%d", ret);
        return ret;
    }

    if(st_init() != 0){
        ret = ERROR_ST_INITIALIZE;
        Error("st_init failed. ret=%d", ret);
        return ret;
    }

    StUtility::InitRandom();

    return ret;
}

int StFarm::Spawn(StTask* task){
    int ret = ERROR_SUCCESS;

    if(st_thread_create(st_thread_function, task, 0, 0) == NULL){
        ret = ERROR_ST_THREAD_CREATE;
        Error("crate st_thread failed, ret=%d", ret);
        return ret;
    }

    Trace("create thread for task #%d success", task->GetId());

    return ret;
}

int StFarm::WaitAll(){
    int ret = ERROR_SUCCESS;

    // main thread turn to a report therad.
    statistic->DoReport(report_seconds * 1000);

    st_thread_exit(NULL);

    return ret;
}

void* StFarm::st_thread_function(void* args){
    StTask* task = (StTask*)args;

    context->SetId(task->GetId());

    statistic->OnThreadRun(task->GetId());

    int ret = task->Process();

    statistic->OnThreadQuit(task->GetId());

    if(ret != ERROR_SUCCESS){
        Warn("st task terminate with ret=%d", ret);
    }
    else{
        Trace("st task terminate with ret=%d", ret);
    }

    delete task;

    return NULL;
}

StSocket::StSocket(){
    sock_nfd = NULL;
    status = SocketInit;
}

StSocket::~StSocket(){
    Close();
}

SocketStatus StSocket::Status(){
    return status;
}

int StSocket::Connect(const char* ip, int port){
    int ret = ERROR_SUCCESS;

    Close();

    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock == -1){
        ret = ERROR_SOCKET;
        Error("create socket error. ret=%d", ret);
        return ret;
    }

    int reuse_socket = 1;
    if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse_socket, sizeof(int)) == -1){
        ret = ERROR_SOCKET;
        Error("setsockopt reuse-addr error. ret=%d", ret);
        return ret;
    }

    sock_nfd = st_netfd_open_socket(sock);
    if(sock_nfd == NULL){
        ret = ERROR_OPEN_SOCKET;
        Error("st_netfd_open_socket failed. ret=%d", ret);
        return ret;
    }
    Info("create socket(%d) success", sock);

    // connect to server
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);

    if(st_connect(sock_nfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){
        ret = ERROR_CONNECT;
        Error("connect to server(%s:%d) error. ret=%d", ip, port, ret);
        return ret;
    }
    Info("connec to server %s at port %d success", ip, port);

    status = SocketConnected;

    return ret;
}

int StSocket::Read(const void* buf, size_t size, ssize_t* nread){
    int ret = ERROR_SUCCESS;

    *nread = st_read(sock_nfd, (void*)buf, size, ST_UTIME_NO_TIMEOUT);

    if(*nread <= 0){
        if(errno == ETIME){
            errno = EAGAIN;
        }

        ret = ERROR_READ;
        status = SocketDisconnected;
    }

    if(*nread > 0){
        statistic->OnRead(context->GetId(), *nread);
    }

    return ret;
}

int StSocket::Write(const void* buf, size_t size, ssize_t* nwrite){
    int ret = ERROR_SUCCESS;

    *nwrite = st_write(sock_nfd, (void*)buf, size, ST_UTIME_NO_TIMEOUT);

    if(*nwrite <= 0){
        if(errno == ETIME){
            errno = EAGAIN;
        }

        ret = ERROR_SEND;
        status = SocketDisconnected;
    }

    if(*nwrite > 0){
        statistic->OnWrite(context->GetId(), *nwrite);
    }

    return ret;
}

int StSocket::Close(){
    int ret = ERROR_SUCCESS;

    if(sock_nfd == NULL){
        return ret;
    }

    if(st_netfd_close(sock_nfd) != 0){
        ret = ERROR_CLOSE;
    }

    sock_nfd = NULL;
    status = SocketDisconnected;

    return ret;
}

int64_t StUtility::GetCurrentTime(){
    timeval now;

    int ret = gettimeofday(&now, NULL);

    if(ret == -1){
        Warn("gettimeofday error, ret=%d", ret);
    }

    // we must convert the tv_sec/tv_usec to int64_t.
    return ((int64_t)now.tv_sec)*1000 + ((int64_t)now.tv_usec) / 1000;
}

void StUtility::InitRandom(){
    timeval now;

    if(gettimeofday(&now, NULL) == -1){
        srand(0);
        return;
    }

    srand(now.tv_sec * 1000000 + now.tv_usec);
}

st_utime_t StUtility::BuildRandomMTime(double sleep_seconds){
    if(sleep_seconds <= 0){
        return 0 * 1000;
    }

    // 80% consts value.
    // 40% random value.
    // to get more graceful random time to mocking HLS client.
    st_utime_t sleep_ms = (int)(sleep_seconds * 1000 * 0.8) + rand() % (int)(sleep_seconds * 1000 * 0.4);

    return sleep_ms;
}

int StUtility::DnsResolve(string host, string& ip){
    int ret = ERROR_SUCCESS;

    if(inet_addr(host.c_str()) != INADDR_NONE){
        ip = host;
        Info("dns resolve %s to %s", host.c_str(), ip.c_str());

        return ret;
    }

    hostent* answer = gethostbyname(host.c_str());
    if(answer == NULL){
        ret = ERROR_DNS_RESOLVE;
        Error("dns resolve host %s error. ret=%d", host.c_str(), ret);
        return ret;
    }

    char ipv4[16];
    memset(ipv4, 0, sizeof(ipv4));
    for(int i = 0; i < answer->h_length; i++){
        inet_ntop(AF_INET, answer->h_addr_list[i], ipv4, sizeof(ipv4));
        Info("dns resolve host %s to %s.", host.c_str(), ipv4);
        break;
    }

    ip = ipv4;
    Info("dns resolve %s to %s", host.c_str(), ip.c_str());

    return ret;
}

StLogContext::StLogContext(){
}

StLogContext::~StLogContext(){
}

void StLogContext::SetId(int id){
    cache[st_thread_self()] = id;
}

int StLogContext::GetId(){
    return cache[st_thread_self()];
}
<|endoftext|>


<commit_before><commit_msg>Threading the threads.<commit_after><|endoftext|>


<commit_before>#include "clientconn.h"

ClientConn::ClientConn() {
    status = clientStatus::Closed;
    sock = nullptr;
}

ClientConn::ClientConn(QObject *parent) : QObject(parent) {
    new (this) ClientConn();
}

void ClientConn::start(QString name) {
    if (status != clientStatus::Closed) return;

    threadListener = new ClientConnListener();
    threadListener->start();

    status = clientStatus::Started;

    this->name = name;
}

bool ClientConn::connect(Conn server) {
    if (status != clientStatus::Started) return;

    sock = new QTcpSocket();
    sock->connectToHost(server->addr, ServerClientPort);

    if (sock->waitForConnected(ConnectPackageTimeOut)) {
        auto fr = LRSBasicLayerFrame(LRSBasicLayerFrame::frameType::Data, QByteArray(name));
        sock->write(fr);

        status = clientStatus::Connected;
        while (threadListener->isRunning()) ;
        delete threadListener;
        threadListener = nullptr;

        return true;
    } else {
        delete sock;
        sock = nullptr;

        return false;
    }
}

void ClientConn::disconnect() {
    if (status != clientStatus::Connected) return;

    sock->disconnectFromHost();
    sock->close();

    delete sock;
    sock = nullptr;

    threadListener = new ClientConnListener();
    threadListener->start();

    status = clientStatus::Started;
}

void ClientConn::close() {
    if (status == clientStatus::Closed) return;
    if (status == clientStatus::Connected) { disconnect(); return; }

    status = clientStatus::Closed;
    while (threadListener->isRunning()) ;
    delete threadListener;
    threadListener = nullptr;
}

void ClientConn::sendData(byteseq data, int length) {
    if (status != clientStatus::Connected) return;

    sock->write(data, length);
}

ClientConn::ServerList ClientConn::getServers() {
    return &servers;
}

ClientConnListener::ClientConnListener(QObject *parent, ClientConn *conn) : QThread(parent), conn(conn) { ; }

void ClientConnListener::run() {
    int counter = 8;
    QUdpSocket* recv = new QUdpSocket(this);

    while (conn->status != ClientConn::clientStatus::Started) ;

    recv->bind(ServerBroadcastRecvPort);

    while (conn->status == ClientConn::clientStatus::Started) {
        if (recv->waitForReadyRead(ServerBroadcastRecvInterval)) {
            if (recv->hasPendingDatagrams()) {
                auto data = QByteArray();
                QHostAddress serverAddr;
                data.resize(recv->pendingDatagramSize());
                recv->readDatagram(data.data(), data.size(), &serverAddr);

                auto fr = LRSBasicLayerFrame::FromQByteArray(data);
                if (fr.type != LRSBasicLayerFrame::frameType::Broadcast) continue;

                int id = counter++;
                QString name = QString(fr.data);

                auto cnn = new _Conn;
                cnn->id = id; cnn->name = name; cnn->addr = serverAddr;

                conn->servers.insert(cnn);
            }
        }
    }

    delete recv;
}
<commit_msg>network fix.1<commit_after>#include "clientconn.h"

ClientConn::ClientConn() {
    status = clientStatus::Closed;
    sock = nullptr;
}

ClientConn::ClientConn(QObject *parent) : QObject(parent) {
    new (this) ClientConn();
}

void ClientConn::start(QString name) {
    if (status != clientStatus::Closed) return;

    threadListener = new ClientConnListener();
    threadListener->start();

    status = clientStatus::Started;

    this->name = name;
}

bool ClientConn::connect(Conn server) {
    if (status != clientStatus::Started) return false;

    sock = new QTcpSocket();
    sock->connectToHost(server->addr, ServerClientPort);

    if (sock->waitForConnected(ConnectPackageTimeOut)) {
        auto fr = LRSBasicLayerFrame(LRSBasicLayerFrame::frameType::Data, QByteArray(name));
        sock->write(fr);

        status = clientStatus::Connected;
        while (threadListener->isRunning()) ;
        delete threadListener;
        threadListener = nullptr;

        return true;
    } else {
        delete sock;
        sock = nullptr;

        return false;
    }
}

void ClientConn::disconnect() {
    if (status != clientStatus::Connected) return;

    sock->disconnectFromHost();
    sock->close();

    delete sock;
    sock = nullptr;

    threadListener = new ClientConnListener();
    threadListener->start();

    status = clientStatus::Started;
}

void ClientConn::close() {
    if (status == clientStatus::Closed) return;
    if (status == clientStatus::Connected) { disconnect(); return; }

    status = clientStatus::Closed;
    while (threadListener->isRunning()) ;
    delete threadListener;
    threadListener = nullptr;
}

void ClientConn::sendData(byteseq data, int length) {
    if (status != clientStatus::Connected) return;

    sock->write(data, length);
}

ClientConn::ServerList ClientConn::getServers() {
    return &servers;
}

ClientConnListener::ClientConnListener(QObject *parent, ClientConn *conn) : QThread(parent), conn(conn) { ; }

void ClientConnListener::run() {
    int counter = 8;
    QUdpSocket* recv = new QUdpSocket(this);

    while (conn->status != ClientConn::clientStatus::Started) ;

    recv->bind(ServerBroadcastRecvPort);

    while (conn->status == ClientConn::clientStatus::Started) {
        if (recv->waitForReadyRead(ServerBroadcastRecvInterval)) {
            if (recv->hasPendingDatagrams()) {
                auto data = QByteArray();
                QHostAddress serverAddr;
                data.resize(recv->pendingDatagramSize());
                recv->readDatagram(data.data(), data.size(), &serverAddr);

                auto fr = LRSBasicLayerFrame::FromQByteArray(data);
                if (fr.type != LRSBasicLayerFrame::frameType::Broadcast) continue;

                int id = counter++;
                QString name = QString(fr.data);

                auto cnn = new _Conn;
                cnn->id = id; cnn->name = name; cnn->addr = serverAddr;

                conn->servers.insert(cnn);
            }
        }
    }

    delete recv;
}
<|endoftext|>


<commit_before>#include "common/PosixThreadImpl.h"

extern "C"
{
void* rho_nativethread_start();
void rho_nativethread_end(void*);
}

namespace rho
{
namespace common
{

IMPLEMENT_LOGCLASS(CPosixThreadImpl, "RhoThread");

CPosixThreadImpl::CPosixThreadImpl()
    :m_stop_wait(false)
{
#if defined(OS_ANDROID)
    // Android has no pthread_condattr_xxx API
    pthread_cond_init(&m_condSync, NULL);
#else
    pthread_condattr_t sync_details;
    pthread_condattr_init(&sync_details);
    pthread_cond_init(&m_condSync, &sync_details);
    pthread_condattr_destroy(&sync_details);
#endif
}

CPosixThreadImpl::~CPosixThreadImpl()
{
    pthread_cond_destroy(&m_condSync);
}

void *runProc(void *pv)
{
    IRhoRunnable *p = static_cast<IRhoRunnable *>(pv);
    void *pData = rho_nativethread_start();
    p->runObject();
    rho_nativethread_end(pData);
    return 0;
}

void CPosixThreadImpl::start(IRhoRunnable *pRunnable, IRhoRunnable::EPriority ePriority)
{
    pthread_attr_t  attr;
    int return_val = pthread_attr_init(&attr);
    //return_val = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    RHO_ASSERT(!return_val);

    if ( ePriority != IRhoRunnable::epNormal)
    {
        sched_param param;
        return_val = pthread_attr_getschedparam (&attr, &param);
        param.sched_priority = ePriority == IRhoRunnable::epLow ? 20 : 100; //TODO: sched_priority
        return_val = pthread_attr_setschedparam (&attr, &param);
    }

    int thread_error = pthread_create(&m_thread, &attr, &runProc, pRunnable);
    return_val = pthread_attr_destroy(&attr);
    RHO_ASSERT(!return_val);
    RHO_ASSERT(thread_error==0);
}

void CPosixThreadImpl::stop(unsigned int nTimeoutToKill)
{
    stopWait();

    //TODO: wait for nTimeoutToKill and kill thread
    void* status;
    pthread_join(m_thread,&status);
}

void CPosixThreadImpl::wait(unsigned int nTimeout)
{
    struct timespec   ts;
    struct timeval    tp;
    gettimeofday(&tp, NULL);
    /* Convert from timeval to timespec */
    ts.tv_sec  = tp.tv_sec;
    ts.tv_nsec = tp.tv_usec * 1000;

    common::CMutexLock oLock(m_mxSync);

    while (!m_stop_wait)
    {
        if ( (unsigned)ts.tv_sec + nTimeout < (unsigned)ts.tv_sec )
            pthread_cond_wait(&m_condSync, m_mxSync.getNativeMutex() );
        else
        {
            ts.tv_sec += nTimeout;
            pthread_cond_timedwait(&m_condSync, m_mxSync.getNativeMutex(), &ts);
        }
    }
    m_stop_wait = false;
}

void CPosixThreadImpl::sleep(unsigned int nTimeout)
{
    ::usleep(1000*nTimeout);
}

void CPosixThreadImpl::stopWait()
{
    common::CMutexLock oLock(m_mxSync);
    m_stop_wait = true;
    pthread_cond_broadcast(&m_condSync);
}

} // namespace common
} // namespace rho

<commit_msg>Fix thread wait on POSIX (iPhone, Android)<commit_after>#include "common/PosixThreadImpl.h"

extern "C"
{
void* rho_nativethread_start();
void rho_nativethread_end(void*);
}

namespace rho
{
namespace common
{

IMPLEMENT_LOGCLASS(CPosixThreadImpl, "RhoThread");

CPosixThreadImpl::CPosixThreadImpl()
    :m_stop_wait(false)
{
#if defined(OS_ANDROID)
    // Android has no pthread_condattr_xxx API
    pthread_cond_init(&m_condSync, NULL);
#else
    pthread_condattr_t sync_details;
    pthread_condattr_init(&sync_details);
    pthread_cond_init(&m_condSync, &sync_details);
    pthread_condattr_destroy(&sync_details);
#endif
}

CPosixThreadImpl::~CPosixThreadImpl()
{
    pthread_cond_destroy(&m_condSync);
}

void *runProc(void *pv)
{
    IRhoRunnable *p = static_cast<IRhoRunnable *>(pv);
    void *pData = rho_nativethread_start();
    p->runObject();
    rho_nativethread_end(pData);
    return 0;
}

void CPosixThreadImpl::start(IRhoRunnable *pRunnable, IRhoRunnable::EPriority ePriority)
{
    pthread_attr_t  attr;
    int return_val = pthread_attr_init(&attr);
    //return_val = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    RHO_ASSERT(!return_val);

    if ( ePriority != IRhoRunnable::epNormal)
    {
        sched_param param;
        return_val = pthread_attr_getschedparam (&attr, &param);
        param.sched_priority = ePriority == IRhoRunnable::epLow ? 20 : 100; //TODO: sched_priority
        return_val = pthread_attr_setschedparam (&attr, &param);
    }

    int thread_error = pthread_create(&m_thread, &attr, &runProc, pRunnable);
    return_val = pthread_attr_destroy(&attr);
    RHO_ASSERT(!return_val);
    RHO_ASSERT(thread_error==0);
}

void CPosixThreadImpl::stop(unsigned int nTimeoutToKill)
{
    stopWait();

    //TODO: wait for nTimeoutToKill and kill thread
    void* status;
    pthread_join(m_thread,&status);
}

void CPosixThreadImpl::wait(unsigned int nTimeout)
{
    struct timespec   ts;
    struct timeval    tp;
    gettimeofday(&tp, NULL);
    /* Convert from timeval to timespec */
    ts.tv_sec  = tp.tv_sec;
    ts.tv_nsec = tp.tv_usec * 1000;

    unsigned long long max;
    bool timed_wait;
    if ( (unsigned)ts.tv_sec + nTimeout >= (unsigned)ts.tv_sec )
    {
        timed_wait = true;
        ts.tv_sec += nTimeout;
        max = ((unsigned long long)tp.tv_sec + nTimeout)*1000000 + tp.tv_usec;
    }
    else
        timed_wait = false;

    common::CMutexLock oLock(m_mxSync);

    while (!m_stop_wait)
    {
        if (timed_wait) {
            pthread_cond_timedwait(&m_condSync, m_mxSync.getNativeMutex(), &ts);

            gettimeofday(&tp, NULL);
            unsigned long long now = ((unsigned long long)tp.tv_sec)*1000000 + tp.tv_usec;
            if (now > max)
                m_stop_wait = true;
        }
        else
            pthread_cond_wait(&m_condSync, m_mxSync.getNativeMutex());
    }
    m_stop_wait = false;
}

void CPosixThreadImpl::sleep(unsigned int nTimeout)
{
    ::usleep(1000*nTimeout);
}

void CPosixThreadImpl::stopWait()
{
    common::CMutexLock oLock(m_mxSync);
    m_stop_wait = true;
    pthread_cond_broadcast(&m_condSync);
}

} // namespace common
} // namespace rho

<|endoftext|>