<commit_before>#include "condor_common.h"
#include <iostream.h>
#include "condor_config.h"
#include "condor_classad.h"
#include "condor_debug.h"
#include "condor_query.h"
#include "condor_q.h"
#include "condor_attributes.h"
#include "match_prefix.h"
#include "my_hostname.h"
#include "get_daemon_addr.h"
#include "files.h"

extern 	"C" int SetSyscalls(int val){return val;}
extern  void short_print(int,int,const char*,int,int,int,int,int,const char *);
static  void processCommandLineArguments(int, char *[]);
extern 	"C" void set_debug_flags( char * );

static	char *_FileName_ = __FILE__;

static 	void short_header (void);
static 	void usage (char *);
static 	void displayJobShort (ClassAd *);
static 	void shorten (char *, int);

static 	int verbose = 0, summarize = 1, global = 0;
static 	int malformed, unexpanded, running, idle;

static	CondorQ 	Q;
static	QueryResult result;
static	CondorQuery	scheddQuery(SCHEDD_AD);
static	CondorQuery submittorQuery(SUBMITTOR_AD);
static	ClassAdList	scheddList;

static	bool		querySchedds 	= false;
static	bool		querySubmittors = false;
static	char		constraint[4096];

extern 	"C"	int		Termlog;

int main (int argc, char **argv)
{
	ClassAd     *job;
	ClassAd		*ad;
	bool		first = true;
	int         numDisplayed = 0;
	char		scheddAddr[64];
	char		scheddName[64];
	char		scheddMachine[64];

	// load up configuration file
	config( 0 );

#if !defined(WIN32)
	install_sig_handler(SIGPIPE, SIG_IGN );
#endif

	// process arguments
	processCommandLineArguments (argc, argv);

	// make sure we are querying schedd's or submittors
	if (!global && !querySchedds && !querySubmittors) {
		char *host = my_full_hostname();
		//localQueue = true;
		querySchedds = true;
		result = scheddQuery.addConstraint (SCHEDD_NAME, host);
		if (result != Q_OK) {
			fprintf(stderr,"Error: Couldn't add constraint Name=\"%s\"\n",host);
			exit (1);
		}
	}

	// if a global queue is required, query the schedds instead of submittors
	if (global) {
		querySchedds = true;
		sprintf( constraint, "%s > 0 || %s > 0", ATTR_TOTAL_RUNNING_JOBS,
				ATTR_TOTAL_IDLE_JOBS );
		result = scheddQuery.addConstraint( constraint );
		if( result != Q_OK ) {
			fprintf( stderr, "Error: Couldn't add constraint %s\n", constraint);
			exit( 1 );
		}
	}

	// get the list of ads from the collector
	result = querySchedds ? scheddQuery.fetchAds(scheddList) :
							submittorQuery.fetchAds(scheddList);
	if (result != Q_OK)
	{
		fprintf (stderr, "Error %d: %s\n", result, getStrQueryResult(result));
		exit(1);
	}

	// get queue from each ScheddIpAddr in ad
	scheddList.Open();
	while ((ad = scheddList.Next()))
	{
		ClassAdList jobs;

		// get the address of the schedd
		if (!ad->LookupString(ATTR_SCHEDD_IP_ADDR, scheddAddr)	||
			!ad->LookupString(ATTR_NAME, scheddName)			||
			!ad->LookupString(ATTR_MACHINE, scheddMachine))
				continue;

		// fetch queue from schedd
		if (Q.fetchQueueFromHost (jobs, scheddAddr) != Q_OK) continue;

		// sort jobs by (cluster.proc)
		jobs.Sort( (SortFunctionType)JobSort );

		// display the jobs from this submittor
		if (jobs.MyLength() != 0 || !global)
		{
			// print header
			if (querySchedds) {
				printf ("\n\n-- Schedd: %s : %s\n", scheddName, scheddAddr);
			} else {
				printf ("\n\n-- Submittor: %s : %s : %s\n", scheddName,
							scheddAddr, scheddMachine);
			}

			// initialize counters
			malformed = 0; idle = 0; running = 0; unexpanded = 0;

			if (verbose)
			{
				jobs.fPrintAttrListList (stdout);
				numDisplayed++;
			}
			else
			{
				short_header ();
				jobs.Open ();
				while (job = jobs.Next())
				{
					displayJobShort (job);
					numDisplayed++;
				}
				jobs.Close ();
			}

			if (summarize)
			{
				printf("\n%d jobs; "
					"%d unexpanded, %d idle, %d running, %d malformed\n",
					unexpanded+idle+running+malformed,unexpanded,idle,running,
					malformed);
			}
		}

		first = false;
	}

	// close list
	scheddList.Close();

	if (first)
	{
		fprintf (stderr,"Error: Collector has no record of schedd/submittor\n");
		exit(1);
	}

	if( !numDisplayed ) {
		printf( "\tNo jobs in the query you requested.\n" );
	}

	return 0;
}

static void
processCommandLineArguments (int argc, char *argv[])
{
	int i, cluster, proc;
	char *arg, *at, *daemonname;

	for (i = 1; i < argc; i++)
	{
		// if the argument begins with a '-', use only the part following
		// the '-' for prefix matches
		if (*argv[i] == '-')
			arg = argv[i]+1;
		else
			arg = argv[i];

		if (match_prefix (arg, "long")) {
			verbose = 1;
			summarize = 0;
		}
		else
		if (match_prefix (arg, "D")) {
			Termlog = 1;
			set_debug_flags( argv[++i] );
		}
		else
		if (match_prefix (arg, "name")) {

			if (querySubmittors) {
				// cannot query both schedd's and submittors
				fprintf (stderr, "Cannot query both schedd's and submittors\n");
				exit(1);
			}

			// make sure we have at least one more argument
			if (argc <= i+1) {
				fprintf( stderr, "Argument -name requires another parameter\n");
				exit(1);
			}

			if( !(daemonname = get_daemon_name(argv[i+1])) ) {
				fprintf( stderr, "%s: unknown host %s\n",
						 argv[0], get_host_part(argv[1+1]) );
				exit(1);
			}
			sprintf (constraint, "%s == \"%s\"", ATTR_NAME, daemonname);

			result = scheddQuery.addConstraint (constraint);
			if (result != Q_OK) {
				fprintf (stderr, "Argument %d (%s): Error %s\n", i, argv[i],
							getStrQueryResult(result));
				exit (1);
			}
			i++;
			querySchedds = true;
		}
		else
		if (match_prefix (arg, "submittor")) {

			if (querySchedds) {
				// cannot query both schedd's and submittors
				fprintf (stderr, "Cannot query both schedd's and submittors\n");
				exit(1);
			}

			// make sure we have at least one more argument
			if (argc <= i+1) {
				fprintf( stderr, "Argument -submittor requires another "
							"parameter\n");
				exit(1);
			}

			i++;
			if ((at = strchr(argv[i],'@'))) {
				// is the name already qualified with a UID_DOMAIN?
				sprintf (constraint, "%s == \"%s\"", ATTR_NAME, argv[i]);
				*at = '\0';
			} else {
				// no ... add UID_DOMAIN
				char *uid_domain = param("UID_DOMAIN");
				if (uid_domain == NULL)
				{
					EXCEPT ("No 'UID_DOMAIN' found in config file");
				}
				sprintf (constraint, "%s == \"%s@%s\"", ATTR_NAME, argv[i],
							uid_domain);
				free (uid_domain);
			}

			// insert the constraints
			result = submittorQuery.addConstraint (constraint);
			if (result != Q_OK) {
				fprintf (stderr, "Argument %d (%s): Error %s\n", i, argv[i],
							getStrQueryResult(result));
				exit (1);
			}

			if (Q.add (CQ_OWNER, argv[i]) != Q_OK) {
				fprintf (stderr, "Error:  Argument %d (%s)\n", i, argv[i]);
				exit (1);
			}

			querySubmittors = true;
		}
		else
		if (match_prefix (arg, "constraint")) {
			// make sure we have at least one more argument
			if (argc <= i+1) {
				fprintf( stderr, "Argument -constraint requires another "
							"parameter\n");
				exit(1);
			}

			if (Q.add (argv[++i]) != Q_OK) {
				fprintf (stderr, "Error:  Argument %d (%s)\n", i, argv[i]);
				exit (1);
			}
			summarize = 0;
		}
		else
		if (sscanf (argv[i], "%d.%d", &cluster, &proc) == 2) {
			sprintf (constraint, "((%s == %d) && (%s == %d))",
									ATTR_CLUSTER_ID, cluster,
									ATTR_PROC_ID, proc);
			Q.add (constraint);
			summarize = 0;
		}
		else
		if (sscanf (argv[i], "%d", &cluster) == 1) {
			sprintf (constraint, "(%s == %d)", ATTR_CLUSTER_ID, cluster);
			Q.add (constraint);
			summarize = 0;
		}
		else
		if (match_prefix (arg, "global")) {
			global = 1;
		}
		else
		if (match_prefix (arg, "help")) {
			usage(argv[0]);
			exit(0);
		}
		else
		{
			// assume name of owner of job
			if (Q.add (CQ_OWNER, argv[i]) != Q_OK) {
				fprintf (stderr, "Error:  Argument %d (%s)\n", i, argv[i]);
				exit (1);
			}
		}
	}
}

static void
displayJobShort (ClassAd *ad)
{
	int cluster, proc, date, status, prio, image_size;
	float utime;
	char owner[64], cmd[2048], args[2048];

	if (!ad->EvalInteger (ATTR_CLUSTER_ID, NULL, cluster)		||
		!ad->EvalInteger (ATTR_PROC_ID, NULL, proc)				||
		!ad->EvalInteger (ATTR_Q_DATE, NULL, date)				||
		!ad->EvalFloat   (ATTR_JOB_REMOTE_USER_CPU, NULL, utime)||
		!ad->EvalInteger (ATTR_JOB_STATUS, NULL, status)		||
		!ad->EvalInteger (ATTR_JOB_PRIO, NULL, prio)			||
		!ad->EvalInteger (ATTR_IMAGE_SIZE, NULL, image_size)	||
		!ad->EvalString  (ATTR_OWNER, NULL, owner)				||
		!ad->EvalString  (ATTR_JOB_CMD, NULL, cmd) )
	{
		printf (" --- ???? --- \n");
		return;
	}

	shorten (owner, 14);
	if (ad->EvalString ("Args", NULL, args)) strcat (cmd, args);
	shorten (cmd, 18);
	short_print (cluster, proc, owner, date, (int)utime, status, prio,
					image_size, cmd);

	switch (status)
	{
		case UNEXPANDED: unexpanded++; break;
		case IDLE:       idle++;       break;
		case RUNNING:    running++;    break;
	}
}

static void
short_header (void)
{
    printf( " %-7s %-14s %11s %12s %-2s %-3s %-4s %-18s\n",
        "ID",
        "OWNER",
        "SUBMITTED",
        "CPU_USAGE",
        "ST",
        "PRI",
        "SIZE",
        "CMD"
    );
}

static void
shorten (char *buff, int len)
{
	if ((unsigned int)strlen (buff) > (unsigned int)len) buff[len] = '\0';
}

static void
usage (char *myName)
{
	printf ("Usage: %s [options]\n\twhere [options] are\n"
		"\t\t-global\t\t\tGet global queue\n"
		"\t\t-submittor <submittor>\tGet queue of specific submittor\n"
		"\t\t-help\t\t\tThis screen\n"
		"\t\t-name <name>\t\tName of schedd\n"
		"\t\t-constraint <expr>\tAdd constraint on classads\n"
		"\t\t-long\t\t\tVerbose output\n"
		"\t\t<cluster>\t\tGet information about specific cluster\n"
		"\t\t<cluster>.<proc>\tGet information about specific job\n"
		"\t\t<owner>\t\t\tInformation about jobs owned by <owner>\n", myName);
}
<commit_msg>+ Made a seperate function that takes a schedd address, schedd name,   and machine name, and displays the queue from that schedd.  This is   called from both the local and remote cases. + When we're displaying the local queue, call get_schedd_addr(NULL) to   get the schedd address (which may not need to query the collector).<commit_after>#include "condor_common.h"
#include <iostream.h>
#include "condor_config.h"
#include "condor_classad.h"
#include "condor_debug.h"
#include "condor_query.h"
#include "condor_q.h"
#include "condor_attributes.h"
#include "match_prefix.h"
#include "my_hostname.h"
#include "get_daemon_addr.h"
#include "files.h"

extern 	"C" int SetSyscalls(int val){return val;}
extern  void short_print(int,int,const char*,int,int,int,int,int,const char *);
static  void processCommandLineArguments(int, char *[]);
extern 	"C" void set_debug_flags( char * );

static	char *_FileName_ = __FILE__;

static 	void short_header (void);
static 	void usage (char *);
static 	void displayJobShort (ClassAd *);
static 	void shorten (char *, int);
static	bool show_queue (char*, char*, char*);

static 	int verbose = 0, summarize = 1, global = 0;
static 	int malformed, unexpanded, running, idle;

static	CondorQ 	Q;
static	QueryResult result;
static	CondorQuery	scheddQuery(SCHEDD_AD);
static	CondorQuery submittorQuery(SUBMITTOR_AD);
static	ClassAdList	scheddList;

static	bool		querySchedds 	= false;
static	bool		querySubmittors = false;
static	char		constraint[4096];

extern 	"C"	int		Termlog;

int main (int argc, char **argv)
{
	ClassAd		*ad;
	bool		first = true;
	char		scheddAddr[64];
	char		scheddName[64];
	char		scheddMachine[64];

	// load up configuration file
	config( 0 );

#if !defined(WIN32)
	install_sig_handler(SIGPIPE, SIG_IGN );
#endif

	// process arguments
	processCommandLineArguments (argc, argv);

	// if we haven't figured out what to do yet, just display the
	// local queue
	if (!global && !querySchedds && !querySubmittors) {
		char *tmp = get_schedd_addr(0);
		if( !tmp ) {
			fprintf( stderr, "Can't find address of local schedd\n" );
			exit( 1 );
		}
		sprintf( scheddAddr, "%s", tmp );
		sprintf( scheddName, "%s", my_daemon_name("SCHEDD") );
		sprintf( scheddMachine, "%s", my_full_hostname() );
		if( show_queue(scheddAddr, scheddName, scheddMachine) ) {
			exit( 0 );
		} else {
			fprintf( stderr, "Can't display queue of local schedd\n" );
			exit( 1 );
		}
	}

	// if a global queue is required, query the schedds instead of submittors
	if (global) {
		querySchedds = true;
		sprintf( constraint, "%s > 0 || %s > 0", ATTR_TOTAL_RUNNING_JOBS,
				ATTR_TOTAL_IDLE_JOBS );
		result = scheddQuery.addConstraint( constraint );
		if( result != Q_OK ) {
			fprintf( stderr, "Error: Couldn't add constraint %s\n", constraint);
			exit( 1 );
		}
	}

	// get the list of ads from the collector
	result = querySchedds ? scheddQuery.fetchAds(scheddList) :
							submittorQuery.fetchAds(scheddList);
	if (result != Q_OK)
	{
		fprintf (stderr, "Error %d: %s\n", result, getStrQueryResult(result));
		exit(1);
	}

	// get queue from each ScheddIpAddr in ad
	scheddList.Open();
	while ((ad = scheddList.Next()))
	{
		// get the address of the schedd
		if (!ad->LookupString(ATTR_SCHEDD_IP_ADDR, scheddAddr)	||
			!ad->LookupString(ATTR_NAME, scheddName)			||
			!ad->LookupString(ATTR_MACHINE, scheddMachine))
				continue;

		show_queue( scheddAddr, scheddName, scheddMachine );
		first = false;
	}

	// close list
	scheddList.Close();

	if (first)
	{
		fprintf (stderr,"Error: Collector has no record of schedd/submittor\n");
		exit(1);
	}

	return 0;
}

static void
processCommandLineArguments (int argc, char *argv[])
{
	int i, cluster, proc;
	char *arg, *at, *daemonname;

	for (i = 1; i < argc; i++)
	{
		// if the argument begins with a '-', use only the part following
		// the '-' for prefix matches
		if (*argv[i] == '-')
			arg = argv[i]+1;
		else
			arg = argv[i];

		if (match_prefix (arg, "long")) {
			verbose = 1;
			summarize = 0;
		}
		else
		if (match_prefix (arg, "D")) {
			Termlog = 1;
			set_debug_flags( argv[++i] );
		}
		else
		if (match_prefix (arg, "name")) {

			if (querySubmittors) {
				// cannot query both schedd's and submittors
				fprintf (stderr, "Cannot query both schedd's and submittors\n");
				exit(1);
			}

			// make sure we have at least one more argument
			if (argc <= i+1) {
				fprintf( stderr, "Argument -name requires another parameter\n");
				exit(1);
			}

			if( !(daemonname = get_daemon_name(argv[i+1])) ) {
				fprintf( stderr, "%s: unknown host %s\n",
						 argv[0], get_host_part(argv[1+1]) );
				exit(1);
			}
			sprintf (constraint, "%s == \"%s\"", ATTR_NAME, daemonname);

			result = scheddQuery.addConstraint (constraint);
			if (result != Q_OK) {
				fprintf (stderr, "Argument %d (%s): Error %s\n", i, argv[i],
							getStrQueryResult(result));
				exit (1);
			}
			i++;
			querySchedds = true;
		}
		else
		if (match_prefix (arg, "submittor")) {

			if (querySchedds) {
				// cannot query both schedd's and submittors
				fprintf (stderr, "Cannot query both schedd's and submittors\n");
				exit(1);
			}

			// make sure we have at least one more argument
			if (argc <= i+1) {
				fprintf( stderr, "Argument -submittor requires another "
							"parameter\n");
				exit(1);
			}

			i++;
			if ((at = strchr(argv[i],'@'))) {
				// is the name already qualified with a UID_DOMAIN?
				sprintf (constraint, "%s == \"%s\"", ATTR_NAME, argv[i]);
				*at = '\0';
			} else {
				// no ... add UID_DOMAIN
				char *uid_domain = param("UID_DOMAIN");
				if (uid_domain == NULL)
				{
					EXCEPT ("No 'UID_DOMAIN' found in config file");
				}
				sprintf (constraint, "%s == \"%s@%s\"", ATTR_NAME, argv[i],
							uid_domain);
				free (uid_domain);
			}

			// insert the constraints
			result = submittorQuery.addConstraint (constraint);
			if (result != Q_OK) {
				fprintf (stderr, "Argument %d (%s): Error %s\n", i, argv[i],
							getStrQueryResult(result));
				exit (1);
			}

			if (Q.add (CQ_OWNER, argv[i]) != Q_OK) {
				fprintf (stderr, "Error:  Argument %d (%s)\n", i, argv[i]);
				exit (1);
			}

			querySubmittors = true;
		}
		else
		if (match_prefix (arg, "constraint")) {
			// make sure we have at least one more argument
			if (argc <= i+1) {
				fprintf( stderr, "Argument -constraint requires another "
							"parameter\n");
				exit(1);
			}

			if (Q.add (argv[++i]) != Q_OK) {
				fprintf (stderr, "Error:  Argument %d (%s)\n", i, argv[i]);
				exit (1);
			}
			summarize = 0;
		}
		else
		if (sscanf (argv[i], "%d.%d", &cluster, &proc) == 2) {
			sprintf (constraint, "((%s == %d) && (%s == %d))",
									ATTR_CLUSTER_ID, cluster,
									ATTR_PROC_ID, proc);
			Q.add (constraint);
			summarize = 0;
		}
		else
		if (sscanf (argv[i], "%d", &cluster) == 1) {
			sprintf (constraint, "(%s == %d)", ATTR_CLUSTER_ID, cluster);
			Q.add (constraint);
			summarize = 0;
		}
		else
		if (match_prefix (arg, "global")) {
			global = 1;
		}
		else
		if (match_prefix (arg, "help")) {
			usage(argv[0]);
			exit(0);
		}
		else
		{
			// assume name of owner of job
			if (Q.add (CQ_OWNER, argv[i]) != Q_OK) {
				fprintf (stderr, "Error:  Argument %d (%s)\n", i, argv[i]);
				exit (1);
			}
		}
	}
}

static void
displayJobShort (ClassAd *ad)
{
	int cluster, proc, date, status, prio, image_size;
	float utime;
	char owner[64], cmd[2048], args[2048];

	if (!ad->EvalInteger (ATTR_CLUSTER_ID, NULL, cluster)		||
		!ad->EvalInteger (ATTR_PROC_ID, NULL, proc)				||
		!ad->EvalInteger (ATTR_Q_DATE, NULL, date)				||
		!ad->EvalFloat   (ATTR_JOB_REMOTE_USER_CPU, NULL, utime)||
		!ad->EvalInteger (ATTR_JOB_STATUS, NULL, status)		||
		!ad->EvalInteger (ATTR_JOB_PRIO, NULL, prio)			||
		!ad->EvalInteger (ATTR_IMAGE_SIZE, NULL, image_size)	||
		!ad->EvalString  (ATTR_OWNER, NULL, owner)				||
		!ad->EvalString  (ATTR_JOB_CMD, NULL, cmd) )
	{
		printf (" --- ???? --- \n");
		return;
	}

	shorten (owner, 14);
	if (ad->EvalString ("Args", NULL, args)) strcat (cmd, args);
	shorten (cmd, 18);
	short_print (cluster, proc, owner, date, (int)utime, status, prio,
					image_size, cmd);

	switch (status)
	{
		case UNEXPANDED: unexpanded++; break;
		case IDLE:       idle++;       break;
		case RUNNING:    running++;    break;
	}
}

static void
short_header (void)
{
    printf( " %-7s %-14s %11s %12s %-2s %-3s %-4s %-18s\n",
        "ID",
        "OWNER",
        "SUBMITTED",
        "CPU_USAGE",
        "ST",
        "PRI",
        "SIZE",
        "CMD"
    );
}

static void
shorten (char *buff, int len)
{
	if ((unsigned int)strlen (buff) > (unsigned int)len) buff[len] = '\0';
}

static void
usage (char *myName)
{
	printf ("Usage: %s [options]\n\twhere [options] are\n"
		"\t\t-global\t\t\tGet global queue\n"
		"\t\t-submittor <submittor>\tGet queue of specific submittor\n"
		"\t\t-help\t\t\tThis screen\n"
		"\t\t-name <name>\t\tName of schedd\n"
		"\t\t-constraint <expr>\tAdd constraint on classads\n"
		"\t\t-long\t\t\tVerbose output\n"
		"\t\t<cluster>\t\tGet information about specific cluster\n"
		"\t\t<cluster>.<proc>\tGet information about specific job\n"
		"\t\t<owner>\t\t\tInformation about jobs owned by <owner>\n", myName);
}

static bool
show_queue( char* scheddAddr, char* scheddName, char* scheddMachine )
{
	ClassAdList jobs;
	ClassAd		*job;

		// fetch queue from schedd
	if( Q.fetchQueueFromHost(jobs, scheddAddr) != Q_OK ) return false;

		// sort jobs by (cluster.proc)
	jobs.Sort( (SortFunctionType)JobSort );

		// display the jobs from this submittor
	if( jobs.MyLength() != 0 || !global ) {
			// print header
		if( querySchedds ) {
			printf ("\n\n-- Schedd: %s : %s\n", scheddName, scheddAddr);
		} else {
			printf ("\n\n-- Submittor: %s : %s : %s\n", scheddName,
					scheddAddr, scheddMachine);
		}

			// initialize counters
		malformed = 0; idle = 0; running = 0; unexpanded = 0;

		if( verbose ) {
			jobs.fPrintAttrListList( stdout );
		} else {
			short_header();
			jobs.Open();
			while( job = jobs.Next() ) {
				displayJobShort( job );
			}
			jobs.Close();
		}

		if( summarize ) {
			printf( "\n%d jobs; "
					"%d unexpanded, %d idle, %d running, %d malformed\n",
					unexpanded+idle+running+malformed,unexpanded,idle,running,
					malformed);
		}
	}
	return true;
}
<|endoftext|>


<commit_before>#include <QDebug>
#include <QCoreApplication>

#include <sstream>
#include <iostream>

#include "DownloadManager.h"

#include "Util.h"
#include "Downloader.h"
using namespace efdl;

DownloadManager::DownloadManager(bool connProg)
  : connProg{connProg}, chksum{false}, conns{0}, chunksAmount{0},
  chunksFinished{0}, size{0}, offset{0}, bytesDown{0},
  hashAlg{QCryptographicHash::Sha3_512}, downloader{nullptr}
{ }

DownloadManager::~DownloadManager() {
  cleanup();
  qDeleteAll(queue);
}

void DownloadManager::add(Downloader *entry) {
  queue << entry;
}

void DownloadManager::createChecksum(QCryptographicHash::Algorithm hashAlg) {
  this->hashAlg = hashAlg;
  chksum = true;
}

void DownloadManager::start() {
  next();
}

void DownloadManager::next() {
  static bool first{true};
  if (!first) {
    // Update progress with total download time with no connection
    // lines.
    bool tmp{connProg};
    connProg = false;
    updateProgress();
    connProg = tmp;

    if (chksum) printChecksum();

    // Separate each download with a newline.
    if (!queue.isEmpty()) qDebug();
  }
  if (first) first = false;

  if (queue.isEmpty()) {
    emit finished();
    return;
  }

  cleanup();

  downloader = queue.dequeue();
  qDebug() << "Downloading" << qPrintable(downloader->getUrl().toString());
  connect(downloader, &Downloader::finished, this, &DownloadManager::next);
  connect(downloader, &Downloader::information,
          this, &DownloadManager::onInformation);
  connect(downloader, &Downloader::chunkStarted,
          this, &DownloadManager::onChunkStarted);
  connect(downloader, &Downloader::chunkProgress,
          this, &DownloadManager::onChunkProgress);
  connect(downloader, &Downloader::chunkFinished,
          this, &DownloadManager::onChunkFinished);
  connect(downloader, &Downloader::chunkFailed,
          this, &DownloadManager::onChunkFailed);
  downloader->start();

  started = QDateTime::currentDateTime();
}
void DownloadManager::onInformation(const QString &outputPath, qint64 size,
                                    int chunksAmount, int conns,
                                    qint64 offset) {
  this->outputPath = outputPath;
  this->size = size;
  this->chunksAmount = chunksAmount;
  this->conns = conns;
  this->offset = offset;
  updateProgress();
}

void DownloadManager::onChunkStarted(int num) {
  connsMap[num] = Range{0, 0};
  updateConnsMap();
  updateProgress();
}

void DownloadManager::onChunkProgress(int num, qint64 received, qint64 total) {
  const Range &r = connsMap[num];
  bytesDown += received - r.first;
  connsMap[num] = Range{received, total};
  updateConnsMap();
  updateProgress();
}

void DownloadManager::onChunkFinished(int num, Range range) {
  chunksFinished++;
  updateConnsMap();
  updateProgress();
}

void DownloadManager::onChunkFailed(int num, Range range, int httpCode,
                                    QNetworkReply::NetworkError error) {
  qCritical() << "Chunk" << num << "failed on range" << range;
  qCritical() << "HTTP code:" << httpCode;
  qCritical() << "Error:" << qPrintable(Util::getErrorString(error));
  qCritical() << "Aborting..";

  cleanup();
  QCoreApplication::exit(-1);
}

void DownloadManager::cleanup() {
  chunksAmount = chunksFinished = size = offset = bytesDown = 0;
  connsMap.clear();

  if (downloader) {
    downloader->disconnect();
    downloader->deleteLater();
    downloader = nullptr;
  }
}

void DownloadManager::updateConnsMap() {
  if (connsMap.size() <= conns) {
    return;
  }

  bool rem = false;
  foreach (const auto &key, connsMap.keys()) {
    const auto &value = connsMap[key];
    if (value.first > 0 && value.first == value.second) {
      rem = true;
      connsMap.remove(key);
      break;
    }
  }
  if (!rem) {
    connsMap.remove(connsMap.firstKey());
  }

  if (connsMap.size() > conns) {
    updateConnsMap();
  }
}

void DownloadManager::updateProgress() {
  using namespace std;
  stringstream sstream;

  // Set fixed float formatting to one decimal digit.
  sstream.precision(1);
  sstream.setf(ios::fixed, ios::floatfield);

  sstream << "[ ";

  if (bytesDown == 0) {
    sstream << "Starting up download..";
  }
  else {
    bool done = (bytesDown + offset == size);
    QDateTime now{QDateTime::currentDateTime()};
    qint64 secs{started.secsTo(now)}, bytesPrSec{0}, secsLeft{0};
    if (secs > 0) {
      bytesPrSec = bytesDown / secs;
      if (bytesPrSec > 0) {
        secsLeft = (!done ? (size - bytesDown - offset) / bytesPrSec
                    : secs);
      }
    }

    float perc = (long double)(bytesDown + offset) / (long double)size * 100.0;

    sstream << perc << "% | "
            << Util::formatSize(bytesDown + offset, 1).toStdString() << " / "
            << Util::formatSize(size, 1).toStdString() << " @ "
            << Util::formatSize(bytesPrSec, 1).toStdString() << "/s | "
            << Util::formatTime(secsLeft).toStdString() << " "
            << (!done ? "left" : "total") << " | "
            << "chunk " << chunksFinished << " / " << chunksAmount;
  }

  sstream << " ]";

  if (connProg) {
    foreach (const int &num, connsMap.keys()) {
      const auto &value = connsMap[num];
      qint64 received = value.first, total = value.second;
      float perc{0};
      if (received > 0 && total > 0) {
        perc = (long double) received / (long double) total * 100.0;
      }
      sstream << "\n{ chunk #" << num << ": " << perc << "% ";
      if (total > 0) {
        sstream << "| " << Util::formatSize(received, 1).toStdString() << " / "
                << Util::formatSize(total, 1).toStdString() << " ";
      }
      sstream << "}";
    }
  }

  sstream << '\n';

  static int lastLines{0};
  string msg{sstream.str()};

  // Remove additional lines, if any.
  for (int i = 0; i < lastLines; i++) {
    cout << "\033[A" // Go up a line (\033 = ESC, [ = CTRL).
         << "\033[2K"; // Clear line.
  }

  // Rewind to beginning with carriage return and write actual
  // message.
  cout << '\r' << msg;
  cout.flush();

  lastLines = QString(msg.c_str()).split("\n").size() - 1;
}

void DownloadManager::printChecksum() {
  QCryptographicHash hasher{hashAlg};
  QFile file{outputPath};
  if (!file.open(QIODevice::ReadOnly)) {
    qCritical() << "ERROR Checksum generation failed: could not open output"
                << "file for reading.";
     return;
  }
  if (!hasher.addData(&file)) {
    qCritical() << "ERROR Failed to do checksum of file.";
     return;
  }
  qDebug() << "Checksum:" << qPrintable(hasher.result().toHex());
}
<commit_msg>Only output progress to STDOUT every half second.<commit_after>#include <QDebug>
#include <QCoreApplication>

#include <sstream>
#include <iostream>

#include "DownloadManager.h"

#include "Util.h"
#include "Downloader.h"
using namespace efdl;

DownloadManager::DownloadManager(bool connProg)
  : connProg{connProg}, chksum{false}, conns{0}, chunksAmount{0},
  chunksFinished{0}, size{0}, offset{0}, bytesDown{0},
  hashAlg{QCryptographicHash::Sha3_512}, downloader{nullptr}
{ }

DownloadManager::~DownloadManager() {
  cleanup();
  qDeleteAll(queue);
}

void DownloadManager::add(Downloader *entry) {
  queue << entry;
}

void DownloadManager::createChecksum(QCryptographicHash::Algorithm hashAlg) {
  this->hashAlg = hashAlg;
  chksum = true;
}

void DownloadManager::start() {
  next();
}

void DownloadManager::next() {
  static bool first{true};
  if (!first) {
    // Update progress with total download time with no connection
    // lines.
    bool tmp{connProg};
    connProg = false;
    updateProgress();
    connProg = tmp;

    if (chksum) printChecksum();

    // Separate each download with a newline.
    if (!queue.isEmpty()) qDebug();
  }
  if (first) first = false;

  if (queue.isEmpty()) {
    emit finished();
    return;
  }

  cleanup();

  downloader = queue.dequeue();
  qDebug() << "Downloading" << qPrintable(downloader->getUrl().toString());
  connect(downloader, &Downloader::finished, this, &DownloadManager::next);
  connect(downloader, &Downloader::information,
          this, &DownloadManager::onInformation);
  connect(downloader, &Downloader::chunkStarted,
          this, &DownloadManager::onChunkStarted);
  connect(downloader, &Downloader::chunkProgress,
          this, &DownloadManager::onChunkProgress);
  connect(downloader, &Downloader::chunkFinished,
          this, &DownloadManager::onChunkFinished);
  connect(downloader, &Downloader::chunkFailed,
          this, &DownloadManager::onChunkFailed);
  downloader->start();

  started = QDateTime::currentDateTime();
}
void DownloadManager::onInformation(const QString &outputPath, qint64 size,
                                    int chunksAmount, int conns,
                                    qint64 offset) {
  this->outputPath = outputPath;
  this->size = size;
  this->chunksAmount = chunksAmount;
  this->conns = conns;
  this->offset = offset;
  updateProgress();
}

void DownloadManager::onChunkStarted(int num) {
  connsMap[num] = Range{0, 0};
  updateConnsMap();
  updateProgress();
}

void DownloadManager::onChunkProgress(int num, qint64 received, qint64 total) {
  const Range &r = connsMap[num];
  bytesDown += received - r.first;
  connsMap[num] = Range{received, total};
  updateConnsMap();
  updateProgress();
}

void DownloadManager::onChunkFinished(int num, Range range) {
  chunksFinished++;
  updateConnsMap();
  updateProgress();
}

void DownloadManager::onChunkFailed(int num, Range range, int httpCode,
                                    QNetworkReply::NetworkError error) {
  qCritical() << "Chunk" << num << "failed on range" << range;
  qCritical() << "HTTP code:" << httpCode;
  qCritical() << "Error:" << qPrintable(Util::getErrorString(error));
  qCritical() << "Aborting..";

  cleanup();
  QCoreApplication::exit(-1);
}

void DownloadManager::cleanup() {
  chunksAmount = chunksFinished = size = offset = bytesDown = 0;
  connsMap.clear();

  if (downloader) {
    downloader->disconnect();
    downloader->deleteLater();
    downloader = nullptr;
  }
}

void DownloadManager::updateConnsMap() {
  if (connsMap.size() <= conns) {
    return;
  }

  bool rem = false;
  foreach (const auto &key, connsMap.keys()) {
    const auto &value = connsMap[key];
    if (value.first > 0 && value.first == value.second) {
      rem = true;
      connsMap.remove(key);
      break;
    }
  }
  if (!rem) {
    connsMap.remove(connsMap.firstKey());
  }

  if (connsMap.size() > conns) {
    updateConnsMap();
  }
}

void DownloadManager::updateProgress() {
  // Only update progress every half second.
  static QDateTime lastUpdate;
  QDateTime now{QDateTime::currentDateTime()};
  if (!lastUpdate.isNull() && lastUpdate.msecsTo(now) < 500) {
    return;
  }
  lastUpdate = now;

  using namespace std;
  stringstream sstream;

  // Set fixed float formatting to one decimal digit.
  sstream.precision(1);
  sstream.setf(ios::fixed, ios::floatfield);

  sstream << "[ ";

  if (bytesDown == 0) {
    sstream << "Starting up download..";
  }
  else {
    bool done = (bytesDown + offset == size);
    qint64 secs{started.secsTo(now)}, bytesPrSec{0}, secsLeft{0};
    if (secs > 0) {
      bytesPrSec = bytesDown / secs;
      if (bytesPrSec > 0) {
        secsLeft = (!done ? (size - bytesDown - offset) / bytesPrSec
                    : secs);
      }
    }

    float perc = (long double)(bytesDown + offset) / (long double)size * 100.0;

    sstream << perc << "% | "
            << Util::formatSize(bytesDown + offset, 1).toStdString() << " / "
            << Util::formatSize(size, 1).toStdString() << " @ "
            << Util::formatSize(bytesPrSec, 1).toStdString() << "/s | "
            << Util::formatTime(secsLeft).toStdString() << " "
            << (!done ? "left" : "total") << " | "
            << "chunk " << chunksFinished << " / " << chunksAmount;
  }

  sstream << " ]";

  if (connProg) {
    foreach (const int &num, connsMap.keys()) {
      const auto &value = connsMap[num];
      qint64 received = value.first, total = value.second;
      float perc{0};
      if (received > 0 && total > 0) {
        perc = (long double) received / (long double) total * 100.0;
      }
      sstream << "\n{ chunk #" << num << ": " << perc << "% ";
      if (total > 0) {
        sstream << "| " << Util::formatSize(received, 1).toStdString() << " / "
                << Util::formatSize(total, 1).toStdString() << " ";
      }
      sstream << "}";
    }
  }

  sstream << '\n';

  static int lastLines{0};
  string msg{sstream.str()};

  // Remove additional lines, if any.
  for (int i = 0; i < lastLines; i++) {
    cout << "\033[A" // Go up a line (\033 = ESC, [ = CTRL).
         << "\033[2K"; // Clear line.
  }

  // Rewind to beginning with carriage return and write actual
  // message.
  cout << '\r' << msg;
  cout.flush();

  lastLines = QString(msg.c_str()).split("\n").size() - 1;
}

void DownloadManager::printChecksum() {
  QCryptographicHash hasher{hashAlg};
  QFile file{outputPath};
  if (!file.open(QIODevice::ReadOnly)) {
    qCritical() << "ERROR Checksum generation failed: could not open output"
                << "file for reading.";
     return;
  }
  if (!hasher.addData(&file)) {
    qCritical() << "ERROR Failed to do checksum of file.";
     return;
  }
  qDebug() << "Checksum:" << qPrintable(hasher.result().toHex());
}
<|endoftext|>


<commit_before>#include <Doremi/Core/Include/PlayerHandlerClient.hpp>

#include <Doremi/Core/Include/EntityComponent/EntityHandler.hpp>

#include <Doremi/Core/Include/NetworkEventReceiver.hpp>
#include <Doremi/Core/Include/FrequencyBufferHandler.hpp>

#include <Doremi/Core/Include/EventHandler/EventHandler.hpp>
#include <Doremi/Core/Include/EventHandler/Events/PlayerCreationEvent.hpp>
#include <Doremi/Core/Include/EventHandler/Events/GunFireToggleEvent.hpp>
#include <Doremi/Core/Include/EventHandler/Events/PlayerRespawnEvent.hpp>
#include <Doremi/Core/Include/EventHandler/Events/ChangeMenuState.hpp>

#include <DoremiEngine/Input/Include/InputModule.hpp>
#include <Doremi/Core/Include/EventHandler/Events/PlaySoundEvent.hpp>
#include <Doremi/Core/Include/EntityComponent/Components/AudioComponent.hpp>

// AI
#include <DoremiEngine/AI/Include/AIModule.hpp>
#include <DoremiEngine/AI/Include/Interface/SubModule/PotentialFieldSubModule.hpp>
#include <DoremiEngine/AI/Include/Interface/PotentialField/PotentialFieldActor.hpp>

// Physics
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <DoremiEngine/Physics/Include/RigidBodyManager.hpp>
#include <DoremiEngine/Physics/Include/CharacterControlManager.hpp>
#include <DoremiEngine/Physics/Include/PhysicsMaterialManager.hpp>

// Components
#include <EntityComponent/Components/PhysicsMaterialComponent.hpp>
#include <EntityComponent/Components/PotentialFieldComponent.hpp>
#include <EntityComponent/Components/PressureParticleComponent.hpp>
#include <EntityComponent/Components/TransformComponent.hpp>
#include <EntityComponent/Components/HealthComponent.hpp>

#include <Doremi/Core/Include/InputHandlerClient.hpp>

#include <Doremi/Core/Include/Streamers/NetworkStreamer.hpp>
#include <Doremi/Core/Include/EventInterpeter.hpp>

// Timing
#include <Timing/TimerManager.hpp>

#include <iostream>

// Logging
#include <DoremiEngine/Logging/Include/LoggingModule.hpp>
#include <DoremiEngine/Logging/Include/SubmoduleManager.hpp>
#include <DoremiEngine/Logging/Include/Logger/Logger.hpp>

// Configuration
#include <DoremiEngine/Configuration/Include/ConfigurationModule.hpp>

namespace Doremi
{
    namespace Core
    {
        PlayerHandlerClient::PlayerHandlerClient(const DoremiEngine::Core::SharedContext& p_sharedContext)
            : PlayerHandler(p_sharedContext), m_logger(nullptr), m_lastJoinEventRead(0), m_maxNumEvents(0)
        {
            EventHandler::GetInstance()->Subscribe(EventType::GunFireToggle, this);
            EventHandler::GetInstance()->Subscribe(EventType::PlayerRespawn, this);
            EventHandler::GetInstance()->Subscribe(EventType::EntityCreated, this);
            EventHandler::GetInstance()->Subscribe(EventType::SetHealth, this);
            EventHandler::GetInstance()->Subscribe(EventType::SetTransform, this);
            m_logger = &m_sharedContext.GetLoggingModule().GetSubModuleManager().GetLogger();

            InputHandlerClient* m_inputHandler = new InputHandlerClient(p_sharedContext);
            NetworkEventReceiver* newNetworkEventReceiver = new NetworkEventReceiver();
            FrequencyBufferHandler* newFrequencyHandler = new FrequencyBufferHandler();

            // Create player object thing
            m_player = new PlayerClient(0, m_inputHandler, newFrequencyHandler, newNetworkEventReceiver);
            m_player->m_turnSpeed = m_sharedContext.GetConfigurationModule().GetAllConfigurationValues().TurnSpeed;
            m_maxPitch = m_sharedContext.GetConfigurationModule().GetAllConfigurationValues().MaxPitch;
            m_minPitch = m_sharedContext.GetConfigurationModule().GetAllConfigurationValues().MinPitch;
        }

        PlayerHandlerClient::~PlayerHandlerClient()
        {
            // Do not delete m_logger, internally handled by loggingmodule
        }

        void PlayerHandlerClient::StartPlayerHandlerClient(const DoremiEngine::Core::SharedContext& p_sharedContext)
        {
            if(m_singleton != nullptr)
            {
                std::runtime_error("PlayerHandler StartPlayerHandler called multiple times.");
            }
            m_singleton = new PlayerHandlerClient(p_sharedContext);
        }

        EntityID PlayerHandlerClient::GetPlayerEntityID() { return m_player->m_playerEntityID; }

        InputHandlerClient* PlayerHandlerClient::GetInputHandler() { return static_cast<InputHandlerClient*>(m_player->m_inputHandler); }

        FrequencyBufferHandler* PlayerHandlerClient::GetFrequencyBufferHandler() { return m_player->m_frequencyBufferHandler; }

        void PlayerHandlerClient::Update(double p_dt)
        {
            TIME_FUNCTION_START

            // If player is created we can update it
            if(m_player->IsCreated)
            {
                UpdatePlayerPositions(m_player);
                UpdatePlayerRotations(m_player);
                UpdateFiring(m_player);
            }

            // Check to exit TODO move place of code
            if(m_player->m_inputHandler->CheckForOnePress(static_cast<uint32_t>(UserCommandPlaying::ExitGame)))
            {
                ChangeMenuState* t_newEvent = new ChangeMenuState();
                t_newEvent->state = DoremiGameStates::MAINMENU;

                EventHandler::GetInstance()->BroadcastEvent(t_newEvent);
            }

            TIME_FUNCTION_STOP
        }

        void PlayerHandlerClient::UpdatePlayerRotations(Player* p_player)
        {
            TIME_FUNCTION_START

            InputHandlerClient* inputHandler = (InputHandlerClient*)p_player->m_inputHandler;

            EntityID entityID = p_player->m_playerEntityID;

            if(EntityHandler::GetInstance().HasComponents(entityID, (int)ComponentType::CharacterController | (int)ComponentType::Transform))
            {
                /// Handle mouse input
                m_jaw += inputHandler->GetMouseMovementX() * p_player->m_turnSpeed;
                m_pitch += inputHandler->GetMouseMovementY() * p_player->m_turnSpeed;

                // Check if we are looking outside of bounds
                if(m_pitch > m_maxPitch)
                {
                    m_pitch = m_maxPitch;
                }
                else if(m_pitch < m_minPitch)
                {
                    m_pitch = m_minPitch;
                }

                // Create and save rotation
                XMMATRIX rotationMat = XMMatrixRotationRollPitchYaw(m_pitch, m_jaw, 0);
                XMFLOAT4 newOrientation;
                XMStoreFloat4(&newOrientation, XMQuaternionRotationMatrix(rotationMat));
                TransformComponent* transComp = EntityHandler::GetInstance().GetComponentFromStorage<TransformComponent>(entityID);
                transComp->rotation = newOrientation;
            }

            TIME_FUNCTION_STOP
        }

        void PlayerHandlerClient::UpdatePlayerInputs()
        {
            TIME_FUNCTION_START
            m_sharedContext.GetInputModule().Update();

            // Update the inputhandler
            InputHandlerClient* inputHandler = static_cast<InputHandlerClient*>(m_player->m_inputHandler);
            inputHandler->Update();

            // If player is created, I think we want to logg input
            if(m_player->IsCreated)
            {
                using namespace Doremi::Utilities::Logging;
                m_logger->DebugLog(LogTag::INPUT, LogLevel::MASS_DATA_PRINT, "X, %d\nY, %d\nM, %d", inputHandler->GetMouseMovementX(),
                    inputHandler->GetMouseMovementY(), inputHandler->GetInputBitMask());
            }

            TIME_FUNCTION_STOP
        }

        void PlayerHandlerClient::SetNewPlayerEntityID(const EntityID& p_entityID)
        {
            if(m_player->IsCreated)
            {
                std::runtime_error("Player created multiple times");
            }

            // Set id and set it created
            m_player->IsCreated = true;
            m_player->m_playerEntityID = p_entityID;

            // Create event
            PlayerCreationEvent* playerCreateEvent = new PlayerCreationEvent(p_entityID);

            // Broadcast event
            // TODOXX If we create this event on server and send this might be removed
            EventHandler::GetInstance()->BroadcastEvent(playerCreateEvent);
        }

        NetworkEventReceiver* PlayerHandlerClient::GetNetworkEventReceiver() { return m_player->m_networkEventReceiver; }

        void PlayerHandlerClient::ReadEventsForJoin(NetworkStreamer& p_streamer, const uint32_t& p_bufferSize, uint32_t& op_bytesRead)
        {
            // Get eventhandler for later use
            EventHandler* t_eventHandler = EventHandler::GetInstance();

            // Read the first event to be read
            uint32_t t_messageStartEvent = p_streamer.ReadUnsignedInt32();
            op_bytesRead += sizeof(uint32_t);

            // Read the number of events to be read
            uint32_t t_numOfEvents = p_streamer.ReadUnsignedInt32();
            op_bytesRead += sizeof(uint32_t);

            // Here is a thing, because we know all event exists beforehand, and because they are bunched to be sent according to acks
            // We can make the assumption that if we've already read the first one here, we've read all in the message
            uint32_t t_bitsRead = 0;
            if(t_messageStartEvent < m_lastJoinEventRead)
            {
                for(size_t i = 0; i < t_numOfEvents; i++)
                {
                    // Read but ignore all events
                    Event* t_newEvent = InterpetEvent(p_streamer, t_bitsRead);

                    // TODO better way of creating, destroying events?(not just this place)
                    // delete them right away
                    delete t_newEvent;
                }
            }
            else
            {
                for(size_t i = 0; i < t_numOfEvents; i++)
                {
                    // Read but ignore all events
                    Event* t_newEvent = InterpetEvent(p_streamer, t_bitsRead);

                    t_eventHandler->BroadcastEvent(t_newEvent);
                }
                m_lastJoinEventRead += t_numOfEvents;
            }

            // Exclude duplicates
            op_bytesRead += ceil(t_bitsRead / 8.0f);

            // Set position back
            p_streamer.SetReadWritePosition(op_bytesRead);
        }

        bool PlayerHandlerClient::PlayerExists() { return m_player->IsCreated; }

        void PlayerHandlerClient::RemovePlayer()
        {
            m_player->IsCreated = false;
            m_player->m_networkEventReceiver->Reset();
            m_player->m_frequencyBufferHandler->Reset();
            m_lastJoinEventRead = 0;
            m_maxNumEvents = 0;
        }

        void PlayerHandlerClient::SetMaximumNumberOfJoinEvents(uint32_t p_maxNumOfJoinEvents) { m_maxNumEvents = p_maxNumOfJoinEvents; }

        void PlayerHandlerClient::OnEvent(Event* p_event)
        {
            if(p_event->eventType == EventType::GunFireToggle)
            {
                GunFireToggleEvent* t_gunFireToggleEvent = static_cast<GunFireToggleEvent*>(p_event);

                // If it's not ourselves we fire
                if(m_player->IsCreated && t_gunFireToggleEvent->entityID != m_player->m_playerEntityID)
                {
                    if(t_gunFireToggleEvent->isFiring)
                    {
                        m_gunController.StartFireGun(t_gunFireToggleEvent->entityID, m_sharedContext);
                    }
                    else
                    {
                        m_gunController.StopFireGun(t_gunFireToggleEvent->entityID, m_sharedContext);
                    }
                }
            }
            else if(p_event->eventType == EventType::PlayerRespawn)
            {
                PlayerRespawnEvent* t_playerSpawnerEvent = static_cast<PlayerRespawnEvent*>(p_event);

                // Reset health for show
                HealthComponent* t_healthComp = GetComponent<HealthComponent>(t_playerSpawnerEvent->entityID);
                t_healthComp->currentHealth = t_healthComp->maxHealth;

                // Play respawn sound
                EventHandler::GetInstance()->BroadcastEvent(new PlaySoundEvent(t_playerSpawnerEvent->entityID, static_cast<int32_t>(AudioCompEnum::Death)));
            }
            else if(p_event->eventType == Doremi::Core::EventType::SetHealth)
            {
                SetHealthEvent* t_setHealthEvent = static_cast<SetHealthEvent*>(p_event);

                GetComponent<HealthComponent>(t_setHealthEvent->entityID)->currentHealth = t_setHealthEvent->health;
            }
            else if(p_event->eventType == Doremi::Core::EventType::SetTransform)
            {
                SetTransformEvent* t_setTransformEvent = static_cast<SetTransformEvent*>(p_event);

                EntityHandler& t_entityHandler = EntityHandler::GetInstance();

                // If char controller or rigid body, set position to physics
                if(t_entityHandler.HasComponents(t_setTransformEvent->entityID, static_cast<uint32_t>(ComponentType::RigidBody)))
                {
                    DoremiEngine::Physics::RigidBodyManager& t_rigidBodyManager = m_sharedContext.GetPhysicsModule().GetRigidBodyManager();

                    t_rigidBodyManager.SetBodyPosition(t_setTransformEvent->entityID, t_setTransformEvent->position, t_setTransformEvent->orientation);
                }
                else if(t_entityHandler.HasComponents(t_setTransformEvent->entityID, static_cast<uint32_t>(ComponentType::CharacterController)))
                {
                    DoremiEngine::Physics::CharacterControlManager& t_characterControlManager = m_sharedContext.GetPhysicsModule().GetCharacterControlManager();

                    t_characterControlManager.SetPosition(t_setTransformEvent->entityID, t_setTransformEvent->position);
                }

                // Set transform to components
                TransformComponent* transComp = GetComponent<TransformComponent>(t_setTransformEvent->entityID);
                transComp->position = t_setTransformEvent->position;
                transComp->rotation = t_setTransformEvent->orientation;

                // Set copy data to other transform components
                memcpy(GetComponent<TransformComponentNext>(t_setTransformEvent->entityID), transComp, sizeof(TransformComponent));
                memcpy(GetComponent<TransformComponentPrevious>(t_setTransformEvent->entityID), transComp, sizeof(TransformComponent));
                *GetComponent<TransformComponentSnapshotNext>(t_setTransformEvent->entityID) =
                    TransformComponentSnapshotNext(*GetComponent<TransformComponentNext>(t_setTransformEvent->entityID));
                *GetComponent<TransformComponentSnapshotPrevious>(t_setTransformEvent->entityID) =
                    TransformComponentSnapshotPrevious(*GetComponent<TransformComponentNext>(t_setTransformEvent->entityID));
            }
        }
    }
}
<commit_msg>Fixed no rotation in debug bug<commit_after>#include <Doremi/Core/Include/PlayerHandlerClient.hpp>

#include <Doremi/Core/Include/EntityComponent/EntityHandler.hpp>

#include <Doremi/Core/Include/NetworkEventReceiver.hpp>
#include <Doremi/Core/Include/FrequencyBufferHandler.hpp>

#include <Doremi/Core/Include/EventHandler/EventHandler.hpp>
#include <Doremi/Core/Include/EventHandler/Events/PlayerCreationEvent.hpp>
#include <Doremi/Core/Include/EventHandler/Events/GunFireToggleEvent.hpp>
#include <Doremi/Core/Include/EventHandler/Events/PlayerRespawnEvent.hpp>
#include <Doremi/Core/Include/EventHandler/Events/ChangeMenuState.hpp>

#include <DoremiEngine/Input/Include/InputModule.hpp>
#include <Doremi/Core/Include/EventHandler/Events/PlaySoundEvent.hpp>
#include <Doremi/Core/Include/EntityComponent/Components/AudioComponent.hpp>

// AI
#include <DoremiEngine/AI/Include/AIModule.hpp>
#include <DoremiEngine/AI/Include/Interface/SubModule/PotentialFieldSubModule.hpp>
#include <DoremiEngine/AI/Include/Interface/PotentialField/PotentialFieldActor.hpp>

// Physics
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <DoremiEngine/Physics/Include/RigidBodyManager.hpp>
#include <DoremiEngine/Physics/Include/CharacterControlManager.hpp>
#include <DoremiEngine/Physics/Include/PhysicsMaterialManager.hpp>

// Components
#include <EntityComponent/Components/PhysicsMaterialComponent.hpp>
#include <EntityComponent/Components/PotentialFieldComponent.hpp>
#include <EntityComponent/Components/PressureParticleComponent.hpp>
#include <EntityComponent/Components/TransformComponent.hpp>
#include <EntityComponent/Components/HealthComponent.hpp>

#include <Doremi/Core/Include/InputHandlerClient.hpp>

#include <Doremi/Core/Include/Streamers/NetworkStreamer.hpp>
#include <Doremi/Core/Include/EventInterpeter.hpp>

// Timing
#include <Timing/TimerManager.hpp>

#include <iostream>

// Logging
#include <DoremiEngine/Logging/Include/LoggingModule.hpp>
#include <DoremiEngine/Logging/Include/SubmoduleManager.hpp>
#include <DoremiEngine/Logging/Include/Logger/Logger.hpp>

// Configuration
#include <DoremiEngine/Configuration/Include/ConfigurationModule.hpp>

namespace Doremi
{
    namespace Core
    {
        PlayerHandlerClient::PlayerHandlerClient(const DoremiEngine::Core::SharedContext& p_sharedContext)
            : PlayerHandler(p_sharedContext), m_logger(nullptr), m_lastJoinEventRead(0), m_maxNumEvents(0), m_jaw(0), m_pitch(0)
        {
            EventHandler::GetInstance()->Subscribe(EventType::GunFireToggle, this);
            EventHandler::GetInstance()->Subscribe(EventType::PlayerRespawn, this);
            EventHandler::GetInstance()->Subscribe(EventType::EntityCreated, this);
            EventHandler::GetInstance()->Subscribe(EventType::SetHealth, this);
            EventHandler::GetInstance()->Subscribe(EventType::SetTransform, this);
            m_logger = &m_sharedContext.GetLoggingModule().GetSubModuleManager().GetLogger();

            InputHandlerClient* m_inputHandler = new InputHandlerClient(p_sharedContext);
            NetworkEventReceiver* newNetworkEventReceiver = new NetworkEventReceiver();
            FrequencyBufferHandler* newFrequencyHandler = new FrequencyBufferHandler();

            // Create player object thing
            m_player = new PlayerClient(0, m_inputHandler, newFrequencyHandler, newNetworkEventReceiver);
            m_player->m_turnSpeed = m_sharedContext.GetConfigurationModule().GetAllConfigurationValues().TurnSpeed;
            m_maxPitch = m_sharedContext.GetConfigurationModule().GetAllConfigurationValues().MaxPitch;
            m_minPitch = m_sharedContext.GetConfigurationModule().GetAllConfigurationValues().MinPitch;
        }

        PlayerHandlerClient::~PlayerHandlerClient()
        {
            // Do not delete m_logger, internally handled by loggingmodule
        }

        void PlayerHandlerClient::StartPlayerHandlerClient(const DoremiEngine::Core::SharedContext& p_sharedContext)
        {
            if(m_singleton != nullptr)
            {
                std::runtime_error("PlayerHandler StartPlayerHandler called multiple times.");
            }
            m_singleton = new PlayerHandlerClient(p_sharedContext);
        }

        EntityID PlayerHandlerClient::GetPlayerEntityID() { return m_player->m_playerEntityID; }

        InputHandlerClient* PlayerHandlerClient::GetInputHandler() { return static_cast<InputHandlerClient*>(m_player->m_inputHandler); }

        FrequencyBufferHandler* PlayerHandlerClient::GetFrequencyBufferHandler() { return m_player->m_frequencyBufferHandler; }

        void PlayerHandlerClient::Update(double p_dt)
        {
            TIME_FUNCTION_START

            // If player is created we can update it
            if(m_player->IsCreated)
            {
                UpdatePlayerPositions(m_player);
                UpdatePlayerRotations(m_player);
                UpdateFiring(m_player);
            }

            // Check to exit TODO move place of code
            if(m_player->m_inputHandler->CheckForOnePress(static_cast<uint32_t>(UserCommandPlaying::ExitGame)))
            {
                ChangeMenuState* t_newEvent = new ChangeMenuState();
                t_newEvent->state = DoremiGameStates::MAINMENU;

                EventHandler::GetInstance()->BroadcastEvent(t_newEvent);
            }

            TIME_FUNCTION_STOP
        }

        void PlayerHandlerClient::UpdatePlayerRotations(Player* p_player)
        {
            TIME_FUNCTION_START

            InputHandlerClient* inputHandler = (InputHandlerClient*)p_player->m_inputHandler;

            EntityID entityID = p_player->m_playerEntityID;

            if(EntityHandler::GetInstance().HasComponents(entityID, (int)ComponentType::CharacterController | (int)ComponentType::Transform))
            {
                /// Handle mouse input
                m_jaw += inputHandler->GetMouseMovementX() * p_player->m_turnSpeed;
                m_pitch += inputHandler->GetMouseMovementY() * p_player->m_turnSpeed;

                // Check if we are looking outside of bounds
                if(m_pitch > m_maxPitch)
                {
                    m_pitch = m_maxPitch;
                }
                else if(m_pitch < m_minPitch)
                {
                    m_pitch = m_minPitch;
                }

                // Create and save rotation
                XMMATRIX rotationMat = XMMatrixRotationRollPitchYaw(m_pitch, m_jaw, 0);
                XMFLOAT4 newOrientation;
                XMStoreFloat4(&newOrientation, XMQuaternionRotationMatrix(rotationMat));
                TransformComponent* transComp = EntityHandler::GetInstance().GetComponentFromStorage<TransformComponent>(entityID);
                transComp->rotation = newOrientation;
            }

            TIME_FUNCTION_STOP
        }

        void PlayerHandlerClient::UpdatePlayerInputs()
        {
            TIME_FUNCTION_START
            m_sharedContext.GetInputModule().Update();

            // Update the inputhandler
            InputHandlerClient* inputHandler = static_cast<InputHandlerClient*>(m_player->m_inputHandler);
            inputHandler->Update();

            // If player is created, I think we want to logg input
            if(m_player->IsCreated)
            {
                using namespace Doremi::Utilities::Logging;
                m_logger->DebugLog(LogTag::INPUT, LogLevel::MASS_DATA_PRINT, "X, %d\nY, %d\nM, %d", inputHandler->GetMouseMovementX(),
                    inputHandler->GetMouseMovementY(), inputHandler->GetInputBitMask());
            }

            TIME_FUNCTION_STOP
        }

        void PlayerHandlerClient::SetNewPlayerEntityID(const EntityID& p_entityID)
        {
            if(m_player->IsCreated)
            {
                std::runtime_error("Player created multiple times");
            }

            // Set id and set it created
            m_player->IsCreated = true;
            m_player->m_playerEntityID = p_entityID;

            // Create event
            PlayerCreationEvent* playerCreateEvent = new PlayerCreationEvent(p_entityID);

            // Broadcast event
            // TODOXX If we create this event on server and send this might be removed
            EventHandler::GetInstance()->BroadcastEvent(playerCreateEvent);
        }

        NetworkEventReceiver* PlayerHandlerClient::GetNetworkEventReceiver() { return m_player->m_networkEventReceiver; }

        void PlayerHandlerClient::ReadEventsForJoin(NetworkStreamer& p_streamer, const uint32_t& p_bufferSize, uint32_t& op_bytesRead)
        {
            // Get eventhandler for later use
            EventHandler* t_eventHandler = EventHandler::GetInstance();

            // Read the first event to be read
            uint32_t t_messageStartEvent = p_streamer.ReadUnsignedInt32();
            op_bytesRead += sizeof(uint32_t);

            // Read the number of events to be read
            uint32_t t_numOfEvents = p_streamer.ReadUnsignedInt32();
            op_bytesRead += sizeof(uint32_t);

            // Here is a thing, because we know all event exists beforehand, and because they are bunched to be sent according to acks
            // We can make the assumption that if we've already read the first one here, we've read all in the message
            uint32_t t_bitsRead = 0;
            if(t_messageStartEvent < m_lastJoinEventRead)
            {
                for(size_t i = 0; i < t_numOfEvents; i++)
                {
                    // Read but ignore all events
                    Event* t_newEvent = InterpetEvent(p_streamer, t_bitsRead);

                    // TODO better way of creating, destroying events?(not just this place)
                    // delete them right away
                    delete t_newEvent;
                }
            }
            else
            {
                for(size_t i = 0; i < t_numOfEvents; i++)
                {
                    // Read but ignore all events
                    Event* t_newEvent = InterpetEvent(p_streamer, t_bitsRead);

                    t_eventHandler->BroadcastEvent(t_newEvent);
                }
                m_lastJoinEventRead += t_numOfEvents;
            }

            // Exclude duplicates
            op_bytesRead += ceil(t_bitsRead / 8.0f);

            // Set position back
            p_streamer.SetReadWritePosition(op_bytesRead);
        }

        bool PlayerHandlerClient::PlayerExists() { return m_player->IsCreated; }

        void PlayerHandlerClient::RemovePlayer()
        {
            m_player->IsCreated = false;
            m_player->m_networkEventReceiver->Reset();
            m_player->m_frequencyBufferHandler->Reset();
            m_lastJoinEventRead = 0;
            m_maxNumEvents = 0;
        }

        void PlayerHandlerClient::SetMaximumNumberOfJoinEvents(uint32_t p_maxNumOfJoinEvents) { m_maxNumEvents = p_maxNumOfJoinEvents; }

        void PlayerHandlerClient::OnEvent(Event* p_event)
        {
            if(p_event->eventType == EventType::GunFireToggle)
            {
                GunFireToggleEvent* t_gunFireToggleEvent = static_cast<GunFireToggleEvent*>(p_event);

                // If it's not ourselves we fire
                if(m_player->IsCreated && t_gunFireToggleEvent->entityID != m_player->m_playerEntityID)
                {
                    if(t_gunFireToggleEvent->isFiring)
                    {
                        m_gunController.StartFireGun(t_gunFireToggleEvent->entityID, m_sharedContext);
                    }
                    else
                    {
                        m_gunController.StopFireGun(t_gunFireToggleEvent->entityID, m_sharedContext);
                    }
                }
            }
            else if(p_event->eventType == EventType::PlayerRespawn)
            {
                PlayerRespawnEvent* t_playerSpawnerEvent = static_cast<PlayerRespawnEvent*>(p_event);

                // Reset health for show
                HealthComponent* t_healthComp = GetComponent<HealthComponent>(t_playerSpawnerEvent->entityID);
                t_healthComp->currentHealth = t_healthComp->maxHealth;

                // Play respawn sound
                EventHandler::GetInstance()->BroadcastEvent(new PlaySoundEvent(t_playerSpawnerEvent->entityID, static_cast<int32_t>(AudioCompEnum::Death)));
            }
            else if(p_event->eventType == Doremi::Core::EventType::SetHealth)
            {
                SetHealthEvent* t_setHealthEvent = static_cast<SetHealthEvent*>(p_event);

                GetComponent<HealthComponent>(t_setHealthEvent->entityID)->currentHealth = t_setHealthEvent->health;
            }
            else if(p_event->eventType == Doremi::Core::EventType::SetTransform)
            {
                SetTransformEvent* t_setTransformEvent = static_cast<SetTransformEvent*>(p_event);

                EntityHandler& t_entityHandler = EntityHandler::GetInstance();

                // If char controller or rigid body, set position to physics
                if(t_entityHandler.HasComponents(t_setTransformEvent->entityID, static_cast<uint32_t>(ComponentType::RigidBody)))
                {
                    DoremiEngine::Physics::RigidBodyManager& t_rigidBodyManager = m_sharedContext.GetPhysicsModule().GetRigidBodyManager();

                    t_rigidBodyManager.SetBodyPosition(t_setTransformEvent->entityID, t_setTransformEvent->position, t_setTransformEvent->orientation);
                }
                else if(t_entityHandler.HasComponents(t_setTransformEvent->entityID, static_cast<uint32_t>(ComponentType::CharacterController)))
                {
                    DoremiEngine::Physics::CharacterControlManager& t_characterControlManager = m_sharedContext.GetPhysicsModule().GetCharacterControlManager();

                    t_characterControlManager.SetPosition(t_setTransformEvent->entityID, t_setTransformEvent->position);
                }

                // Set transform to components
                TransformComponent* transComp = GetComponent<TransformComponent>(t_setTransformEvent->entityID);
                transComp->position = t_setTransformEvent->position;
                transComp->rotation = t_setTransformEvent->orientation;

                // Set copy data to other transform components
                memcpy(GetComponent<TransformComponentNext>(t_setTransformEvent->entityID), transComp, sizeof(TransformComponent));
                memcpy(GetComponent<TransformComponentPrevious>(t_setTransformEvent->entityID), transComp, sizeof(TransformComponent));
                *GetComponent<TransformComponentSnapshotNext>(t_setTransformEvent->entityID) =
                    TransformComponentSnapshotNext(*GetComponent<TransformComponentNext>(t_setTransformEvent->entityID));
                *GetComponent<TransformComponentSnapshotPrevious>(t_setTransformEvent->entityID) =
                    TransformComponentSnapshotPrevious(*GetComponent<TransformComponentNext>(t_setTransformEvent->entityID));
            }
        }
    }
}
<|endoftext|>


<commit_before>#include    <string>

#include    "FTGLTextureFont.h"
#include    "FTTextureGlyph.h"

inline GLuint NextPowerOf2( GLuint in)
{
     in -= 1;

     in |= in >> 16;
     in |= in >> 8;
     in |= in >> 4;
     in |= in >> 2;
     in |= in >> 1;

     return in + 1;
}

FTGLTextureFont::FTGLTextureFont()
:   maxTextSize(0),
    textureWidth(0),
    textureHeight(0),
    numTextures(0),
    textMem(0),
    glyphHeight(0),
    glyphWidth(0),
    padding(1),
    remGlyphs(0),
    xOffset(0),
    yOffset(0)
{}

FTGLTextureFont::~FTGLTextureFont()
{
    glDeleteTextures( numTextures, (const GLuint*)glTextureID);
}

FTGlyph* FTGLTextureFont::MakeGlyph( unsigned int g)
{
    FT_Glyph* ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING);

    if( ftGlyph)
    {
        // Estimate the glyph size size - global bbox
        glyphHeight = static_cast<int>( charSize.Height());
        glyphWidth = static_cast<int>( charSize.Width());

        // Is there a current texture
        if( numTextures == 0)
        {
            glTextureID[0] = CreateTexture();
            xOffset = yOffset = padding;
            ++numTextures;
        }

        // will it fit in the current texture
        if( xOffset > ( textureWidth - glyphWidth))
        {
            xOffset = padding;
            yOffset += glyphHeight;

            if( yOffset > ( textureHeight - glyphHeight))
            {
                // no - make a new texture
                glTextureID[numTextures] = CreateTexture();
                yOffset = padding;
                ++numTextures;
            }
        }

        // yes - load the glyph
        FTTextureGlyph* tempGlyph = new FTTextureGlyph( *ftGlyph, glTextureID[numTextures - 1],
                                                        xOffset, yOffset, textureWidth, textureHeight);

        // FIXME ceiling
        xOffset += static_cast<int>( tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding);

        --remGlyphs;
        return tempGlyph;
    }

    err = face.Error();
    return NULL;
}

bool FTGLTextureFont::MakeGlyphList()
{
    if( !maxTextSize)
        glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);

    remGlyphs = numGlyphs;

    return FTFont::MakeGlyphList();
}

void FTGLTextureFont::GetSize()
{
    //work out the max width. Most likely maxTextSize
    textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + padding * 2);
    if( textureWidth > maxTextSize)
    {
        textureWidth = maxTextSize;
    }

    int h = static_cast<int>( (textureWidth - padding * 2) / glyphWidth);

    textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight);
    textureHeight = textureHeight > maxTextSize ? maxTextSize : textureHeight;
}

int FTGLTextureFont::CreateTexture()
{
    // calc the size
    GetSize();

    // allocate some mem and clear it to black
    int totalMem = textureWidth * textureHeight;
    textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
    memset( textMem, 0, totalMem);

    // Create the blank texture
    int textID;
    glGenTextures( 1, (GLuint*)&textID);

    glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
    glBindTexture( GL_TEXTURE_2D, textID);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textMem);

    delete [] textMem;

    return textID;
}

void FTGLTextureFont::render( const char* string)
{
    glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

    FTFont::render( string);

    glPopAttrib();
}

void FTGLTextureFont::render( const wchar_t* string)
{
    glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

    FTFont::render( string);

    glPopAttrib();
}

<commit_msg>Had to increase padding now that FTBBox uses floats.<commit_after>#include    <string>

#include    "FTGLTextureFont.h"
#include    "FTTextureGlyph.h"

inline GLuint NextPowerOf2( GLuint in)
{
     in -= 1;

     in |= in >> 16;
     in |= in >> 8;
     in |= in >> 4;
     in |= in >> 2;
     in |= in >> 1;

     return in + 1;
}

FTGLTextureFont::FTGLTextureFont()
:   maxTextSize(0),
    textureWidth(0),
    textureHeight(0),
    numTextures(0),
    textMem(0),
    glyphHeight(0),
    glyphWidth(0),
    padding(3),
    remGlyphs(0),
    xOffset(0),
    yOffset(0)
{}

FTGLTextureFont::~FTGLTextureFont()
{
    glDeleteTextures( numTextures, (const GLuint*)glTextureID);
}

FTGlyph* FTGLTextureFont::MakeGlyph( unsigned int g)
{
    FT_Glyph* ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING);

    if( ftGlyph)
    {
        // Estimate the glyph size size - global bbox
        glyphHeight = static_cast<int>( charSize.Height());
        glyphWidth = static_cast<int>( charSize.Width());

        // Is there a current texture
        if( numTextures == 0)
        {
            glTextureID[0] = CreateTexture();
            xOffset = yOffset = padding;
            ++numTextures;
        }

        // will it fit in the current texture
        if( xOffset > ( textureWidth - glyphWidth))
        {
            xOffset = padding;
            yOffset += glyphHeight;

            if( yOffset > ( textureHeight - glyphHeight))
            {
                // no - make a new texture
                glTextureID[numTextures] = CreateTexture();
                yOffset = padding;
                ++numTextures;
            }
        }

        // yes - load the glyph
        FTTextureGlyph* tempGlyph = new FTTextureGlyph( *ftGlyph, glTextureID[numTextures - 1],
                                                        xOffset, yOffset, textureWidth, textureHeight);

        // FIXME ceiling
        xOffset += static_cast<int>( tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding);

        --remGlyphs;
        return tempGlyph;
    }

    err = face.Error();
    return NULL;
}

bool FTGLTextureFont::MakeGlyphList()
{
    if( !maxTextSize)
        glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);

    remGlyphs = numGlyphs;

    return FTFont::MakeGlyphList();
}

void FTGLTextureFont::GetSize()
{
    //work out the max width. Most likely maxTextSize
    textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + padding * 2);
    if( textureWidth > maxTextSize)
    {
        textureWidth = maxTextSize;
    }

    int h = static_cast<int>( (textureWidth - padding * 2) / glyphWidth);

    textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight);
    textureHeight = textureHeight > maxTextSize ? maxTextSize : textureHeight;
}

int FTGLTextureFont::CreateTexture()
{
    // calc the size
    GetSize();

    // allocate some mem and clear it to black
    int totalMem = textureWidth * textureHeight;
    textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
    memset( textMem, 0, totalMem);

    // Create the blank texture
    int textID;
    glGenTextures( 1, (GLuint*)&textID);

    glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
    glBindTexture( GL_TEXTURE_2D, textID);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textMem);

    delete [] textMem;

    return textID;
}

void FTGLTextureFont::render( const char* string)
{
    glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

    FTFont::render( string);

    glPopAttrib();
}

void FTGLTextureFont::render( const wchar_t* string)
{
    glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

    FTFont::render( string);

    glPopAttrib();
}

<|endoftext|>


<commit_before>/****************************************************************
Purpose:
	The checkpoint (a.out) file transferred from the submitting machine
	should be a valid ULTRIX executable file, and should have been linked
	with the Condor remote execution library.  Here we check the
	magic numbers to determine if we have a valid executable file, and
	also look for a well known symbol from the Condor library (MAIN)
	to ensure proper linking.

Note : The file has been modified for the Solaris platform by :
	   Dhaval N. Shah
	   University of Wisconsin, Computer Sciences Department.

Portability:
	This code depends upon the executable format for ULTRIX.4.2 systems,
	and is not portable to other systems.
******************************************************************/

#define _ALL_SOURCE

#if defined(Solaris)
#include <sys/exechdr.h>
#endif

#include "condor_common.h"
#include "condor_debug.h"
#include "condor_constants.h"
#include "condor_jobqueue.h"
#include <sys/file.h>
#include <sys/exec.h>
#include "proto.h"
#include <nlist.h>

static char *_FileName_ = __FILE__;     /* Used by EXCEPT (see except.h)     */

extern "C" {
#if defined(Solaris)
	int nlist( const char *FileName, struct nlist *nl);
#else
	int nlist( char *FileName, struct nlist *nl);
#endif
}

int magic_check( char *a_out )
{
	int		exec_fd;
	struct exec	header;
	int		nbytes;

	if( (exec_fd=open(a_out,O_RDONLY,0)) < 0 ) {
		dprintf( D_ALWAYS, "open(%s,O_RDONLY,0)", a_out );
		return -1;
	}
	dprintf( D_ALWAYS, "Opened file \"%s\", fd = %d\n", a_out, exec_fd );

	errno = 0;
	nbytes = read( exec_fd, (char *)&header, sizeof(header) );
	if( nbytes != sizeof(header) ) {
		dprintf(D_ALWAYS,
			"Error on read(%d,0x%x,%d), nbytes = %d, errno = %d\n",
			exec_fd, (char *)&header, sizeof(header), nbytes, errno
		);
		close( exec_fd );
		return -1;
	}

	close( exec_fd );

	if( header.a_magic != ZMAGIC ) {
		dprintf( D_ALWAYS, "\"%s\": BAD MAGIC NUMBER\n", a_out );
		return -1;
	}
	if( header.a_machtype != M_SPARC ) {
		dprintf( D_ALWAYS,
			"\"%s\": NOT COMPILED FOR SPARC ARCHITECTURE\n", a_out
		);
		return -1;
	}
	if( header.a_dynamic ) {
		dprintf( D_ALWAYS, "\"%s\": LINKED FOR DYNAMIC LOADING\n", a_out );
		return -1;
	}

	return 0;
}

/*
Check to see that the checkpoint file is linked with the Condor
library by looking for the symbol "MAIN".
*/
int symbol_main_check( char *name )
{
	int	status;
	struct nlist nl[2];

	nl[0].n_name = "_MAIN";
	nl[1].n_name = "__condor_prestart";
	nl[2].n_name = "";

		/* If nlist fails just return TRUE - executable may be stripped. */
	status = nlist( name, nl );
	if( status < 0 ) {
		dprintf(D_ALWAYS, "Error: nlist(\"%s\",0x%x) returns %d, errno = %d\n",
													name, nl, status, errno);
		return(0);
	}

	if( nl[0].n_type == 0 ) {
		dprintf( D_ALWAYS, "No symbol \"MAIN\" in executable(%s)\n", name );
		return(-1);
	}

	if( nl[1].n_type == 0 ) {
		dprintf( D_ALWAYS,
				"No symbol \"_condor_prestart\" in executable(%s)\n", name );
		return(-1);
	}

	dprintf( D_ALWAYS, "Symbol MAIN check - OK\n" );
	return 0;
}

int
calc_hdr_blocks()
{
	return (sizeof(struct exec) + 1023) / 1024;
}

int
calc_text_blocks( char *a_out )
{
	int		exec_fd;
	struct exec	header;

	if( (exec_fd=open(a_out,O_RDONLY,0)) < 0 ) {
		dprintf( D_ALWAYS, "open(%s,O_RDONLY,0)", a_out );
		return -1;
	}

	if( read(exec_fd,(char *)&header,sizeof(header)) != sizeof(header) ) {
		dprintf(D_ALWAYS,
			"read(%d,0x%x,%d)", exec_fd, (char *)&header, sizeof(header)
		);
		close( exec_fd );
		return -1;
	}

	close( exec_fd );

	return header.a_text / 1024;
}
<commit_msg>Modified to use correct magic number for Solaris executables.<commit_after>/****************************************************************
Purpose:
	The checkpoint (a.out) file transferred from the submitting machine
	should be a valid ULTRIX executable file, and should have been linked
	with the Condor remote execution library.  Here we check the
	magic numbers to determine if we have a valid executable file, and
	also look for a well known symbol from the Condor library (MAIN)
	to ensure proper linking.

Note : The file has been modified for the Solaris platform by :
	   Dhaval N. Shah
	   University of Wisconsin, Computer Sciences Department.

Portability:
	This code depends upon the executable format for ULTRIX.4.2 systems,
	and is not portable to other systems.
******************************************************************/

#define _ALL_SOURCE

#include "condor_common.h"
#include "condor_debug.h"
#include "condor_constants.h"
#include "condor_jobqueue.h"
#include <sys/file.h>
#include <sys/exec.h>
#include <sys/exechdr.h>
#include "proto.h"
#include <nlist.h>

static char *_FileName_ = __FILE__;     /* Used by EXCEPT (see except.h)     */

#define SOLARIS_MAGIC 046106

extern "C" {
#if defined(Solaris)
	int nlist( const char *FileName, struct nlist *nl);
#else
	int nlist( char *FileName, struct nlist *nl);
#endif
}

int magic_check( char *a_out )
{
	int		exec_fd;
	struct exec	header;
	int		nbytes;

	if( (exec_fd=open(a_out,O_RDONLY,0)) < 0 ) {
		dprintf( D_ALWAYS, "open(%s,O_RDONLY,0)", a_out );
		return -1;
	}
	dprintf( D_ALWAYS, "Opened file \"%s\", fd = %d\n", a_out, exec_fd );

	errno = 0;
	nbytes = read( exec_fd, (char *)&header, sizeof(header) );
	if( nbytes != sizeof(header) ) {
		dprintf(D_ALWAYS,
			"Error on read(%d,0x%x,%d), nbytes = %d, errno = %d\n",
			exec_fd, (char *)&header, sizeof(header), nbytes, errno
		);
		close( exec_fd );
		return -1;
	}

	close( exec_fd );

	if( header.a_magic != SOLARIS_MAGIC ) {
		dprintf( D_ALWAYS, "\"%s\": BAD MAGIC NUMBER\n", a_out );
		dprintf( D_ALWAYS, "0x%x != 0x%x\n", header.a_magic, SOLARIS_MAGIC );
		dprintf( D_ALWAYS, "0%o != 0%o\n", header.a_magic, SOLARIS_MAGIC );
		dprintf( D_ALWAYS, "%d != %d\n", header.a_magic, SOLARIS_MAGIC );
		return -1;
	}
	if( header.a_machtype != 69 ) {
		dprintf( D_ALWAYS,
			"\"%s\": NOT COMPILED FOR SPARC ARCHITECTURE\n", a_out
		);
		dprintf( D_ALWAYS, "%d != %d\n", header.a_machtype, 69 );
		return -1;
	}
#if (!defined Solaris)
	if( header.a_dynamic ) {
		dprintf( D_ALWAYS, "\"%s\": LINKED FOR DYNAMIC LOADING\n", a_out );
		return -1;
	}
#endif
	return 0;
}

/*
Check to see that the checkpoint file is linked with the Condor
library by looking for the symbol "MAIN".
*/
int symbol_main_check( char *name )
{
	int	status;
	struct nlist nl[2];

	/* Unlike on some other architectures, we want to look for
	   MAIN and _condor_prestart on Solaris, not _MAIN and
	   __condor_prestart.  -Jim B. */

	nl[0].n_name = "MAIN";
	nl[1].n_name = "_condor_prestart";
	nl[2].n_name = "";

		/* If nlist fails just return TRUE - executable may be stripped. */
	status = nlist( name, nl );
	if( status < 0 ) {
		dprintf(D_ALWAYS, "Error: nlist(\"%s\",0x%x) returns %d, errno = %d\n",
													name, nl, status, errno);
		return(0);
	}

	if( nl[0].n_type == 0 ) {
		dprintf( D_ALWAYS, "No symbol \"MAIN\" in executable(%s)\n", name );
		return(-1);
	}

	if( nl[1].n_type == 0 ) {
		dprintf( D_ALWAYS,
				"No symbol \"_condor_prestart\" in executable(%s)\n", name );
		return(-1);
	}

	dprintf( D_ALWAYS, "Symbol MAIN check - OK\n" );
	return 0;
}

int
calc_hdr_blocks()
{
	return (sizeof(struct exec) + 1023) / 1024;
}

int
calc_text_blocks( char *a_out )
{
	int		exec_fd;
	struct exec	header;

	if( (exec_fd=open(a_out,O_RDONLY,0)) < 0 ) {
		dprintf( D_ALWAYS, "open(%s,O_RDONLY,0)", a_out );
		return -1;
	}

	if( read(exec_fd,(char *)&header,sizeof(header)) != sizeof(header) ) {
		dprintf(D_ALWAYS,
			"read(%d,0x%x,%d)", exec_fd, (char *)&header, sizeof(header)
		);
		close( exec_fd );
		return -1;
	}

	close( exec_fd );

	return header.a_text / 1024;
}
<|endoftext|>