<commit_before>#include "Core\Context.h"
#include "Core\Engine.h"
#include "Core\Logger.h"
#include "GameFramework\World.h"
#include "GameFramework\Entity.h"
#include "Component\CameraComponent.h"
#include "Component\MeshRenderComponent.h"
#include "Component\LightComponent.h"
#include "Resource\ResourceManager.h"
#include "Resource\Model.h"
#include "Resource\ModelLoader.h"
#include "Resource\Material.h"
#include "Resource\Texture2D.h"
#include "Math\Vector3.h"
#include "MT\ThreadPool.h"
#include "RotateComponent.h"

using namespace Mile;

int main( )
{
   auto context = new Context( );
   auto engine = new Engine( context );

   if ( !engine->Init( ) )
   {
      return 1;
   }

   auto world = context->GetSubSystem<World>( );
   auto resMng = context->GetSubSystem<ResourceManager>( );

   Entity* camera = world->CreateEntity( TEXT( "Camera" ) );
   CameraComponent* camComponent = camera->AddComponent<CameraComponent>( );
   Transform* camTransform = camera->GetTransform( );
   camComponent->SetNearPlane(1.0f);
   camComponent->SetFarPlane(1000.0f);
   camComponent->SetFov(60.0f);
   camTransform->SetPosition(Vector3(0.0f, 0.0f, -5.0f));

   Entity* upperLight = world->CreateEntity(TEXT("Upper Light"));
   LightComponent* upperLightComponent = upperLight->AddComponent<LightComponent>();
   Transform* upperLightTransform = upperLight->GetTransform();
   upperLightComponent->SetLightType(ELightType::Point);
   upperLightComponent->SetRadiance(Vector3(100.0f, 100.0f, 100.0f));
   upperLightTransform->SetPosition(Vector3(0.0f, 10.0f, 0.0f));

   Entity* leftLight = world->CreateEntity(TEXT("Left Light"));
   LightComponent* leftLightComponent = leftLight->AddComponent<LightComponent>();
   Transform* leftLightTransform = leftLight->GetTransform();
   leftLightComponent->SetLightType(ELightType::Point);
   leftLightComponent->SetRadiance(Vector3(0.0f, 50.0f, 0.0f));
   leftLightTransform->SetPosition(Vector3(-15.0f, 0.0f, 0.0f));

   Entity* rightLight = world->CreateEntity(TEXT("Right Light"));
   LightComponent* rightLightComponent = rightLight->AddComponent<LightComponent>();
   Transform* rightLightTransform = rightLight->GetTransform();
   rightLightComponent->SetLightType(ELightType::Point);
   rightLightComponent->SetRadiance(Vector3(0.0f, 0.0f, 50.0f));
   rightLightTransform->SetPosition(Vector3(15.0f, 0.0f, 0.0f));

   Model* damagedHelmetModel = resMng->Load<Model>(TEXT("Contents/Models/DamagedHelmet/DamagedHelmet.gltf"));
   Entity* damagedHelmet = Model::Instantiate(damagedHelmetModel, world, TEXT("DamagedHelmet"));
   Entity* damagedHelmetMesh = damagedHelmet->GetChildren()[0];
   RotateComponent* damagedHelmetRotation = damagedHelmet->AddComponent<RotateComponent>();
   MeshRenderComponent* renderComponent = damagedHelmetMesh->GetComponent<MeshRenderComponent>();
   Material* damagedHelmetMaterial = renderComponent->GetMaterial();
   damagedHelmetMaterial->Save();

   int execute = engine->Execute( );
   //world->Save();
   SafeDelete( context );
   return execute;
}<commit_msg>Slightly modify sample<commit_after>#include "Core\Context.h"
#include "Core\Engine.h"
#include "Core\Logger.h"
#include "GameFramework\World.h"
#include "GameFramework\Entity.h"
#include "Component\CameraComponent.h"
#include "Component\MeshRenderComponent.h"
#include "Component\LightComponent.h"
#include "Resource\ResourceManager.h"
#include "Resource\Model.h"
#include "Resource\ModelLoader.h"
#include "Resource\Material.h"
#include "Resource\Texture2D.h"
#include "Math\Vector3.h"
#include "MT\ThreadPool.h"
#include "RotateComponent.h"

using namespace Mile;

int main( )
{
   auto context = new Context( );
   auto engine = new Engine( context );

   if ( !engine->Init( ) )
   {
      return 1;
   }

   auto world = context->GetSubSystem<World>( );
   auto resMng = context->GetSubSystem<ResourceManager>( );

   Entity* camera = world->CreateEntity( TEXT( "Camera" ) );
   CameraComponent* camComponent = camera->AddComponent<CameraComponent>( );
   Transform* camTransform = camera->GetTransform( );
   camComponent->SetNearPlane(1.0f);
   camComponent->SetFarPlane(1000.0f);
   camComponent->SetFov(60.0f);
   camTransform->SetPosition(Vector3(0.0f, 0.0f, -5.0f));

   Entity* mainLight = world->CreateEntity(TEXT("Upper Light"));
   LightComponent* mainLightComponent = mainLight->AddComponent<LightComponent>();
   Transform* mainLightTransform = mainLight->GetTransform();
   mainLightComponent->SetLightType(ELightType::Point);
   mainLightComponent->SetRadiance(Vector3(200.0f, 200.0f, 200.0f));
   mainLightTransform->SetPosition(Vector3(0.0f, 0.0f, -5.0f));

   Model* damagedHelmetModel = resMng->Load<Model>(TEXT("Contents/Models/DamagedHelmet/DamagedHelmet.gltf"));
   Entity* damagedHelmet = Model::Instantiate(damagedHelmetModel, world, TEXT("DamagedHelmet"));
   Entity* damagedHelmetMesh = damagedHelmet->GetChildren()[0];
   RotateComponent* damagedHelmetRotation = damagedHelmet->AddComponent<RotateComponent>();
   MeshRenderComponent* helmetRenderComponent = damagedHelmetMesh->GetComponent<MeshRenderComponent>();
   Material* damagedHelmetMaterial = helmetRenderComponent->GetMaterial();
   damagedHelmetMaterial->Save();

   Model* lanternModel = resMng->Load<Model>(TEXT("Contents/Models/Lantern/Lantern.gltf"));
   Entity* lantern = Model::Instantiate(lanternModel, world, TEXT("Lantern"));
   Entity* lanternMesh = lantern->GetChildren()[0];
   RotateComponent* lanternRotateComponent = lantern->AddComponent<RotateComponent>();
   MeshRenderComponent* lanternRenderComponent = lanternMesh->GetComponent<MeshRenderComponent>();
   Material* lanternMaterial = lanternRenderComponent->GetMaterial();
   lanternMaterial->Save();

   Transform* lanternTransform = lantern->GetTransform();
   lanternTransform->SetScale(Vector3(0.1f, 0.1f, 0.1f));
   lanternTransform->SetPosition(Vector3(-2.5f, -0.9f, 0.0f));

   Model* metalRoughSpheresModel = resMng->Load<Model>(TEXT("Contents/Models/MetalRoughSpheres/MetalRoughSpheres.gltf"));
   Entity* spheresEntity = Model::Instantiate(metalRoughSpheresModel, world, TEXT("Spheres"));
   Entity* spheresMesh = spheresEntity->GetChildren()[0];
   MeshRenderComponent* spheresRenderComponent = spheresMesh->GetComponent<MeshRenderComponent>();
   Material* spheresMaterial = spheresRenderComponent->GetMaterial();
   spheresMaterial->Save();

   Transform* spheresTransform = spheresEntity->GetTransform();
   //spheresTransform->SetScale(Vector3(0.1f, 0.1f, 0.1f));
   spheresTransform->SetPosition(Vector3(0.0f, 0.0f, 4.0f));

   int execute = engine->Execute( );
   //world->Save();
   SafeDelete( context );
   return execute;
}<|endoftext|>


<commit_before>#include "WebFetcher.h"

/* constructors */
WebFetcher::WebFetcher(Locutus *locutus) {
	this->locutus = locutus;
}

/* destructors */
WebFetcher::~WebFetcher() {
}

/* methods */
void WebFetcher::loadSettings() {
	setting_class_id = locutus->settings->loadClassID(FILEREADER_CLASS, FILEREADER_CLASS_DESCRIPTION);
	puid_min_score = locutus->settings->loadSetting(setting_class_id, PUID_MIN_SCORE_KEY, PUID_MIN_SCORE_VALUE, PUID_MIN_SCORE_DESCRIPTION);
	metadata_min_score = locutus->settings->loadSetting(setting_class_id, METADATA_MIN_SCORE_KEY, METADATA_MIN_SCORE_VALUE, METADATA_MIN_SCORE_DESCRIPTION);
}

void WebFetcher::lookup() {
	for (map<string, vector<Metafile *> >::iterator group = locutus->grouped_files.begin(); group != locutus->grouped_files.end(); ++group) {
		map<string, Album *> albums;
		/* <album_mbid, <tracknumber<filename, Match> > > */
		map<string, vector<map<string, Match> > > scores;
		/* look up puids first */
		/* TODO:
		 * we'll need some sort of handling when:
		 * - no matching tracks
		 * - matching tracks, but no good mbid/metadata match */
		for (vector<Metafile *>::iterator group_file = group->second.begin(); group_file != group->second.end(); ++group_file) {
			Metafile *mf = *group_file;
			if (!mf->puid_lookup)
				continue;
			vector<Metatrack> *tracks = locutus->webservice->searchPUID(mf->puid);
			for (vector<Metatrack>::iterator mt = tracks->begin(); mt != tracks->end(); ++mt) {
				double score = mf->compareWithMetatrack(&(*mt));
				mt->saveToCache();
				saveMatchToCache(mf->filename, mt->track_mbid, score);
				if (score < puid_min_score)
					continue;
				if (albums.find(mt->album_mbid) == albums.end()) {
					Album *album = new Album(locutus);
					if (!album->loadFromCache(mt->album_mbid)) {
						if (album->retrieveFromWebService(mt->album_mbid))
							album->saveToCache();
					}
					if (album->mbid == "") {
						/* hmm, didn't find the album? */
						delete album;
						continue;
					}
					albums[album->mbid] = album;
				}
				int trackcount = (int) albums[mt->album_mbid]->tracks.size();
				if (mt->tracknumber > trackcount || mt->tracknumber <= 0) {
					/* this should never happen */
					locutus->debug(DEBUG_NOTICE, "PUID search returned a tracknumber that doesn't exist on the album. This shouldn't happen, though");
					continue;
				}
				Match m;
				m.mbid_match = false;
				m.puid_match = true;
				m.meta_score = score;
				if ((int) scores[mt->album_mbid].size() < trackcount)
					scores[mt->album_mbid].resize(trackcount);
				scores[mt->album_mbid][mt->tracknumber - 1][mf->filename] = m;
			}
		}
		/* compare all tracks in group with albums loaded so far */
		for (map<string, Album *>::iterator album = albums.begin(); album != albums.end(); ++album)
			compareFilesWithAlbum(&scores, &group->second, album->second);
		/* look up with mbid or search with metadata */
		for (vector<Metafile *>::iterator group_file = group->second.begin(); group_file != group->second.end(); ++group_file) {
			Metafile *mf = *group_file;
			/* mbid lookup */
			if (mf->musicbrainz_albumid.size() == 36 && albums.find(mf->musicbrainz_albumid) == albums.end()) {
				Album *album = new Album(locutus);
				if (!album->loadFromCache(mf->musicbrainz_albumid)) {
					if (album->retrieveFromWebService(mf->musicbrainz_albumid))
						album->saveToCache();
				}
				if (album->mbid == "") {
					/* hmm, didn't find the album? */
					delete album;
					continue;
				}
				albums[album->mbid] = album;
				/* compare the other files in group with this album */
				compareFilesWithAlbum(&scores, &group->second, album);
			}
			/* meta lookup */
			vector<Metatrack> *tracks = locutus->webservice->searchMetadata(makeWSQuery(group->first, mf));
			for (vector<Metatrack>::iterator mt = tracks->begin(); mt != tracks->end(); ++mt) {
				double score = mf->compareWithMetatrack(&(*mt));
				mt->saveToCache();
				saveMatchToCache(mf->filename, mt->track_mbid, score);
				if (score < metadata_min_score)
					continue;
				if (albums.find(mt->album_mbid) == albums.end()) {
					Album *album = new Album(locutus);
					if (!album->loadFromCache(mt->album_mbid)) {
						if (album->retrieveFromWebService(mt->album_mbid))
							album->saveToCache();
					}
					if (album->mbid == "") {
						/* hmm, didn't find the album? */
						delete album;
						continue;
					}
					albums[album->mbid] = album;
				}
				int trackcount = (int) albums[mt->album_mbid]->tracks.size();
				if (mt->tracknumber > trackcount || mt->tracknumber <= 0) {
					/* this should never happen */
					locutus->debug(DEBUG_NOTICE, "Metadata search returned a tracknumber that doesn't exist on the album. This shouldn't happen, though");
					continue;
				}
				Match m;
				m.mbid_match = false;
				m.puid_match = false;
				m.meta_score = score;
				if ((int) scores[mt->album_mbid].size() < trackcount)
					scores[mt->album_mbid].resize(trackcount);
				scores[mt->album_mbid][mt->tracknumber - 1][mf->filename] = m;
				/* compare the other files in group with this album */
				compareFilesWithAlbum(&scores, &group->second, albums[mt->album_mbid]);
			}
		}
		for (map<string, Album *>::iterator album = albums.begin(); album != albums.end(); ++album)
			delete album->second;
		albums.clear();
		scores.clear();
	}
}

/*
void WebFetcher::lookup() {
	for (map<string, vector<int> >::iterator group = locutus->grouped_files.begin(); group != locutus->grouped_files.end(); ++group) {
		map<string, double> album_scores;
		map<string, vector<AlbumMatch> > album_matched;
		for (map<string, map<vector<Metadata>::size_type, vector<Match> > >::iterator album = matches.begin(); album != matches.end(); ++album) {
			AlbumMatch tmp;
			tmp.file = -1;
			tmp.score = 0.0;
			vector<AlbumMatch> matched(group->second.size(), tmp);
			double album_score = 0.0;
			int matched_tracks = 0;
			for (map<vector<Metadata>::size_type, vector<Match> >::iterator tc = album->second.begin(); tc != album->second.end(); ++tc) {
				int best_file = -1;
				int best_track = -1;
				double best_score = 0.0;
				for (map<vector<Metadata>::size_type, vector<Match> >::size_type t = 0; t < album->second.size(); ++t) {
					for (vector<Match>::iterator match = album->second[t].begin(); match != album->second[t].begin(); ++match) {
						if (matched[t].file != -1)
							continue;
						FileMetadata fm = locutus->files[group->second[match->file]];
						double score = 0.0;
						if (fm.puid_lookup && track_puid_match[match->file])
							score = 2.0 + match->meta_score;
						else if (match->mbid_match)
							score = 1.0 + match->meta_score;
						else
							score = match->meta_score;
						if (score > best_score) {
							best_file = match->file;
							best_track = t;
							best_score = score;
						}
					}
				}
				if (best_track != -1) {
					++matched_tracks;
					matched[best_track].file = best_file;
					matched[best_track].score = best_score;
					album_score += best_score;
				}
			}
			if (matched_tracks == (int) group->second.size())
				album_score *= 3;
			else if (matched_tracks == (int) album->second.size())
				album_score *= 2;
			album_scores[album->first] = album_score / album->second.size();
			album_matched[album->first] = matched;
		}
		vector<bool> used_files(group->second.size(), false);
		for (map<string, vector<Metadata> >::iterator album = albums.begin(); album != albums.end(); ++album) {
			double max = -1.0;
			string key = "";
			for (map<string, double>::iterator as = album_scores.begin(); as != album_scores.end(); ++as) {
				if (as->second > max) {
					key = as->first;
					max = as->second;
				}
			}
			if (key == "")
				break;
			for (vector<Metadata>::size_type track = 0; track < album->second.size(); ++track) {
				AlbumMatch am = album_matched[key][track];
				if (am.file == -1 || used_files[am.file])
					continue;
				FileMetadata fm = locutus->files[am.file];
				fm.setValues(albums[key][track]);
				locutus->files[am.file] = fm;
				used_files[am.file] = true;
			}
		}
	}
}
*/

/* private methods */
void WebFetcher::compareFilesWithAlbum(map<string, vector<map<string, Match> > > *scores, vector<Metafile *> *files, Album *album) {
	for (vector<Metafile *>::iterator mf = files->begin(); mf != files->end(); ++mf) {
		for (vector<Track *>::size_type t = 0; t < album->tracks.size(); ++t) {
			if ((*scores)[album->mbid][t].find((*mf)->filename) != (*scores)[album->mbid][t].end())
				continue;
			Match m;
			if (album->tracks[t]->mbid == (*mf)->musicbrainz_trackid)
				m.mbid_match = true;
			else
				m.mbid_match = false;
			m.puid_match = false;
			m.meta_score = (*mf)->compareWithTrack(album->tracks[t]);
			(*scores)[album->mbid][t][(*mf)->filename] = m;
		}
	}
}

string WebFetcher::escapeWSString(string text) {
	/* escape these characters:
	 * + - && || ! ( ) { } [ ] ^ " ~ * ? : \ */
	/* also change "_" to " " */
	ostringstream str;
	for (string::size_type a = 0; a < text.size(); ++a) {
		switch (text[a]) {
			case '+':
			case '-':
			case '!':
			case '(':
			case ')':
			case '{':
			case '}':
			case '[':
			case ']':
			case '^':
			case '"':
			case '~':
			case '*':
			case '?':
			case ':':
			case '\\':
				str << '\\';
				break;

			case '&':
			case '|':
				if (a + 1 < text.size() && text[a + 1] == text[a])
					str << '\\';
				break;

			case '_':
				text[a] = ' ';
				break;

			default:
				break;
		}
		str << text[a];
	}
	return str.str();
}

string WebFetcher::makeWSQuery(string group, Metafile *mf) {
	ostringstream query;
	group = escapeWSString(group);
	string bnwe = escapeWSString(mf->getBaseNameWithoutExtension());
	query << "limit=25&query=";
	query << "tnum:(" << escapeWSString(mf->tracknumber) << " " << bnwe << ") ";
	if (mf->duration > 0) {
		int lower = mf->duration / 1000 - 10;
		int upper = mf->duration / 1000 + 10;
		if (lower < 0)
			lower = 0;
		query << "qdur:[" << lower << " TO " << upper << "] ";
	}
	query << "artist:(" << escapeWSString(mf->artist) << " " << bnwe << " " << group << ") ";
	query << "track:(" << escapeWSString(mf->title) << " " << bnwe << " " << group << ") ";
	query << "release:(" << escapeWSString(mf->album) << " " << bnwe << " " << group << ") ";
	return query.str();
}

bool WebFetcher::saveMatchToCache(string filename, string track_mbid, double score) {
	if (filename == "" || track_mbid.size() != 36)
		return false;
	string e_filename = locutus->database->escapeString(filename);
	string e_track_mbid = locutus->database->escapeString(track_mbid);
	ostringstream query;
	query << "INSERT INTO metadata_match(file_id, metatrack_id, score) SELECT (SELECT file_id FROM file WHERE filename = '" << e_filename << "'), (SELECT metatrack_id FROM metatrack WHERE track_mbid = '" << e_track_mbid << "'), " << score << " WHERE NOT EXISTS (SELECT true FROM metadata_match WHERE file_id = (SELECT file_id FROM file WHERE filename = '" << e_filename << "') AND metatrack_id = (SELECT metatrack_id FROM metatrack WHERE track_mbid = '" << e_track_mbid << "'))";
	if (!locutus->database->query(query.str()))
		locutus->debug(DEBUG_NOTICE, "Unable to save metadata match in cache, query failed. See error above");
	query.str("");
	query << "UPDATE metadata_match SET score = " << score << " WHERE file_id = (SELECT file_id FROM file WHERE filename = '" << e_filename << "') AND metatrack_id = (SELECT metatrack_id FROM metatrack WHERE track_mbid = '" << e_track_mbid << "')";
	if (!locutus->database->query(query.str()))
		locutus->debug(DEBUG_NOTICE, "Unable to save metadata match in cache, query failed. See error above");
	return true;
}
<commit_msg>hoops, it should do metadata lookup if it didn't find an album<commit_after>#include "WebFetcher.h"

/* constructors */
WebFetcher::WebFetcher(Locutus *locutus) {
	this->locutus = locutus;
}

/* destructors */
WebFetcher::~WebFetcher() {
}

/* methods */
void WebFetcher::loadSettings() {
	setting_class_id = locutus->settings->loadClassID(FILEREADER_CLASS, FILEREADER_CLASS_DESCRIPTION);
	puid_min_score = locutus->settings->loadSetting(setting_class_id, PUID_MIN_SCORE_KEY, PUID_MIN_SCORE_VALUE, PUID_MIN_SCORE_DESCRIPTION);
	metadata_min_score = locutus->settings->loadSetting(setting_class_id, METADATA_MIN_SCORE_KEY, METADATA_MIN_SCORE_VALUE, METADATA_MIN_SCORE_DESCRIPTION);
}

void WebFetcher::lookup() {
	for (map<string, vector<Metafile *> >::iterator group = locutus->grouped_files.begin(); group != locutus->grouped_files.end(); ++group) {
		map<string, Album *> albums;
		/* <album_mbid, <tracknumber<filename, Match> > > */
		map<string, vector<map<string, Match> > > scores;
		/* look up puids first */
		/* TODO:
		 * we'll need some sort of handling when:
		 * - no matching tracks
		 * - matching tracks, but no good mbid/metadata match */
		for (vector<Metafile *>::iterator group_file = group->second.begin(); group_file != group->second.end(); ++group_file) {
			Metafile *mf = *group_file;
			if (!mf->puid_lookup)
				continue;
			vector<Metatrack> *tracks = locutus->webservice->searchPUID(mf->puid);
			for (vector<Metatrack>::iterator mt = tracks->begin(); mt != tracks->end(); ++mt) {
				double score = mf->compareWithMetatrack(&(*mt));
				mt->saveToCache();
				saveMatchToCache(mf->filename, mt->track_mbid, score);
				if (score < puid_min_score)
					continue;
				if (albums.find(mt->album_mbid) == albums.end()) {
					Album *album = new Album(locutus);
					if (!album->loadFromCache(mt->album_mbid)) {
						if (album->retrieveFromWebService(mt->album_mbid))
							album->saveToCache();
					}
					if (album->mbid == "") {
						/* hmm, didn't find the album? */
						delete album;
						continue;
					}
					albums[album->mbid] = album;
				}
				int trackcount = (int) albums[mt->album_mbid]->tracks.size();
				if (mt->tracknumber > trackcount || mt->tracknumber <= 0) {
					/* this should never happen */
					locutus->debug(DEBUG_NOTICE, "PUID search returned a tracknumber that doesn't exist on the album. This shouldn't happen, though");
					continue;
				}
				Match m;
				m.mbid_match = false;
				m.puid_match = true;
				m.meta_score = score;
				if ((int) scores[mt->album_mbid].size() < trackcount)
					scores[mt->album_mbid].resize(trackcount);
				scores[mt->album_mbid][mt->tracknumber - 1][mf->filename] = m;
			}
		}
		/* compare all tracks in group with albums loaded so far */
		for (map<string, Album *>::iterator album = albums.begin(); album != albums.end(); ++album)
			compareFilesWithAlbum(&scores, &group->second, album->second);
		/* look up with mbid or search with metadata */
		for (vector<Metafile *>::iterator group_file = group->second.begin(); group_file != group->second.end(); ++group_file) {
			Metafile *mf = *group_file;
			/* mbid lookup */
			if (mf->musicbrainz_albumid.size() == 36 && albums.find(mf->musicbrainz_albumid) == albums.end()) {
				Album *album = new Album(locutus);
				if (!album->loadFromCache(mf->musicbrainz_albumid)) {
					if (album->retrieveFromWebService(mf->musicbrainz_albumid))
						album->saveToCache();
				}
				if (album->mbid == "") {
					/* hmm, didn't find the album? */
					delete album;
				} else {
					albums[album->mbid] = album;
					/* compare the other files in group with this album */
					compareFilesWithAlbum(&scores, &group->second, album);
					continue;
				}
			}
			/* meta lookup */
			vector<Metatrack> *tracks = locutus->webservice->searchMetadata(makeWSQuery(group->first, mf));
			for (vector<Metatrack>::iterator mt = tracks->begin(); mt != tracks->end(); ++mt) {
				double score = mf->compareWithMetatrack(&(*mt));
				mt->saveToCache();
				saveMatchToCache(mf->filename, mt->track_mbid, score);
				if (score < metadata_min_score)
					continue;
				if (albums.find(mt->album_mbid) == albums.end()) {
					Album *album = new Album(locutus);
					if (!album->loadFromCache(mt->album_mbid)) {
						if (album->retrieveFromWebService(mt->album_mbid))
							album->saveToCache();
					}
					if (album->mbid == "") {
						/* hmm, didn't find the album? */
						delete album;
						continue;
					}
					albums[album->mbid] = album;
				}
				int trackcount = (int) albums[mt->album_mbid]->tracks.size();
				if (mt->tracknumber > trackcount || mt->tracknumber <= 0) {
					/* this should never happen */
					locutus->debug(DEBUG_NOTICE, "Metadata search returned a tracknumber that doesn't exist on the album. This shouldn't happen, though");
					continue;
				}
				Match m;
				m.mbid_match = false;
				m.puid_match = false;
				m.meta_score = score;
				if ((int) scores[mt->album_mbid].size() < trackcount)
					scores[mt->album_mbid].resize(trackcount);
				scores[mt->album_mbid][mt->tracknumber - 1][mf->filename] = m;
				/* compare the other files in group with this album */
				compareFilesWithAlbum(&scores, &group->second, albums[mt->album_mbid]);
			}
		}
		for (map<string, Album *>::iterator album = albums.begin(); album != albums.end(); ++album)
			delete album->second;
		albums.clear();
		scores.clear();
	}
}

/*
void WebFetcher::lookup() {
	for (map<string, vector<int> >::iterator group = locutus->grouped_files.begin(); group != locutus->grouped_files.end(); ++group) {
		map<string, double> album_scores;
		map<string, vector<AlbumMatch> > album_matched;
		for (map<string, map<vector<Metadata>::size_type, vector<Match> > >::iterator album = matches.begin(); album != matches.end(); ++album) {
			AlbumMatch tmp;
			tmp.file = -1;
			tmp.score = 0.0;
			vector<AlbumMatch> matched(group->second.size(), tmp);
			double album_score = 0.0;
			int matched_tracks = 0;
			for (map<vector<Metadata>::size_type, vector<Match> >::iterator tc = album->second.begin(); tc != album->second.end(); ++tc) {
				int best_file = -1;
				int best_track = -1;
				double best_score = 0.0;
				for (map<vector<Metadata>::size_type, vector<Match> >::size_type t = 0; t < album->second.size(); ++t) {
					for (vector<Match>::iterator match = album->second[t].begin(); match != album->second[t].begin(); ++match) {
						if (matched[t].file != -1)
							continue;
						FileMetadata fm = locutus->files[group->second[match->file]];
						double score = 0.0;
						if (fm.puid_lookup && track_puid_match[match->file])
							score = 2.0 + match->meta_score;
						else if (match->mbid_match)
							score = 1.0 + match->meta_score;
						else
							score = match->meta_score;
						if (score > best_score) {
							best_file = match->file;
							best_track = t;
							best_score = score;
						}
					}
				}
				if (best_track != -1) {
					++matched_tracks;
					matched[best_track].file = best_file;
					matched[best_track].score = best_score;
					album_score += best_score;
				}
			}
			if (matched_tracks == (int) group->second.size())
				album_score *= 3;
			else if (matched_tracks == (int) album->second.size())
				album_score *= 2;
			album_scores[album->first] = album_score / album->second.size();
			album_matched[album->first] = matched;
		}
		vector<bool> used_files(group->second.size(), false);
		for (map<string, vector<Metadata> >::iterator album = albums.begin(); album != albums.end(); ++album) {
			double max = -1.0;
			string key = "";
			for (map<string, double>::iterator as = album_scores.begin(); as != album_scores.end(); ++as) {
				if (as->second > max) {
					key = as->first;
					max = as->second;
				}
			}
			if (key == "")
				break;
			for (vector<Metadata>::size_type track = 0; track < album->second.size(); ++track) {
				AlbumMatch am = album_matched[key][track];
				if (am.file == -1 || used_files[am.file])
					continue;
				FileMetadata fm = locutus->files[am.file];
				fm.setValues(albums[key][track]);
				locutus->files[am.file] = fm;
				used_files[am.file] = true;
			}
		}
	}
}
*/

/* private methods */
void WebFetcher::compareFilesWithAlbum(map<string, vector<map<string, Match> > > *scores, vector<Metafile *> *files, Album *album) {
	for (vector<Metafile *>::iterator mf = files->begin(); mf != files->end(); ++mf) {
		for (vector<Track *>::size_type t = 0; t < album->tracks.size(); ++t) {
			if ((*scores)[album->mbid][t].find((*mf)->filename) != (*scores)[album->mbid][t].end())
				continue;
			Match m;
			if (album->tracks[t]->mbid == (*mf)->musicbrainz_trackid)
				m.mbid_match = true;
			else
				m.mbid_match = false;
			m.puid_match = false;
			m.meta_score = (*mf)->compareWithTrack(album->tracks[t]);
			(*scores)[album->mbid][t][(*mf)->filename] = m;
		}
	}
}

string WebFetcher::escapeWSString(string text) {
	/* escape these characters:
	 * + - && || ! ( ) { } [ ] ^ " ~ * ? : \ */
	/* also change "_" to " " */
	ostringstream str;
	for (string::size_type a = 0; a < text.size(); ++a) {
		switch (text[a]) {
			case '+':
			case '-':
			case '!':
			case '(':
			case ')':
			case '{':
			case '}':
			case '[':
			case ']':
			case '^':
			case '"':
			case '~':
			case '*':
			case '?':
			case ':':
			case '\\':
				str << '\\';
				break;

			case '&':
			case '|':
				if (a + 1 < text.size() && text[a + 1] == text[a])
					str << '\\';
				break;

			case '_':
				text[a] = ' ';
				break;

			default:
				break;
		}
		str << text[a];
	}
	return str.str();
}

string WebFetcher::makeWSQuery(string group, Metafile *mf) {
	ostringstream query;
	group = escapeWSString(group);
	string bnwe = escapeWSString(mf->getBaseNameWithoutExtension());
	query << "limit=25&query=";
	query << "tnum:(" << escapeWSString(mf->tracknumber) << " " << bnwe << ") ";
	if (mf->duration > 0) {
		int lower = mf->duration / 1000 - 10;
		int upper = mf->duration / 1000 + 10;
		if (lower < 0)
			lower = 0;
		query << "qdur:[" << lower << " TO " << upper << "] ";
	}
	query << "artist:(" << escapeWSString(mf->artist) << " " << bnwe << " " << group << ") ";
	query << "track:(" << escapeWSString(mf->title) << " " << bnwe << " " << group << ") ";
	query << "release:(" << escapeWSString(mf->album) << " " << bnwe << " " << group << ") ";
	return query.str();
}

bool WebFetcher::saveMatchToCache(string filename, string track_mbid, double score) {
	if (filename == "" || track_mbid.size() != 36)
		return false;
	string e_filename = locutus->database->escapeString(filename);
	string e_track_mbid = locutus->database->escapeString(track_mbid);
	ostringstream query;
	query << "INSERT INTO metadata_match(file_id, metatrack_id, score) SELECT (SELECT file_id FROM file WHERE filename = '" << e_filename << "'), (SELECT metatrack_id FROM metatrack WHERE track_mbid = '" << e_track_mbid << "'), " << score << " WHERE NOT EXISTS (SELECT true FROM metadata_match WHERE file_id = (SELECT file_id FROM file WHERE filename = '" << e_filename << "') AND metatrack_id = (SELECT metatrack_id FROM metatrack WHERE track_mbid = '" << e_track_mbid << "'))";
	if (!locutus->database->query(query.str()))
		locutus->debug(DEBUG_NOTICE, "Unable to save metadata match in cache, query failed. See error above");
	query.str("");
	query << "UPDATE metadata_match SET score = " << score << " WHERE file_id = (SELECT file_id FROM file WHERE filename = '" << e_filename << "') AND metatrack_id = (SELECT metatrack_id FROM metatrack WHERE track_mbid = '" << e_track_mbid << "')";
	if (!locutus->database->query(query.str()))
		locutus->debug(DEBUG_NOTICE, "Unable to save metadata match in cache, query failed. See error above");
	return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "WebInspector.h"

#include "WebKitDLL.h"
#include "WebView.h"
#pragma warning(push, 0)
#include <WebCore/InspectorController.h>
#include <WebCore/Page.h>
#pragma warning(pop)
#include <wtf/Assertions.h>

using namespace WebCore;

WebInspector* WebInspector::createInstance(WebView* webView)
{
    WebInspector* inspector = new WebInspector(webView);
    inspector->AddRef();
    return inspector;
}

WebInspector::WebInspector(WebView* webView)
    : m_refCount(0)
    , m_webView(webView)
{
    ASSERT_ARG(webView, webView);

    gClassCount++;
    gClassNameCount.add("WebInspector");
}

WebInspector::~WebInspector()
{
    gClassCount--;
    gClassNameCount.remove("WebInspector");
}

void WebInspector::webViewClosed()
{
    m_webView = 0;
}

HRESULT STDMETHODCALLTYPE WebInspector::QueryInterface(REFIID riid, void** ppvObject)
{
    *ppvObject = 0;
    if (IsEqualGUID(riid, IID_IWebInspector))
        *ppvObject = static_cast<IWebInspector*>(this);
    else if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebInspector*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG STDMETHODCALLTYPE WebInspector::AddRef(void)
{
    return ++m_refCount;
}

ULONG STDMETHODCALLTYPE WebInspector::Release(void)
{
    ULONG newRef = --m_refCount;
    if (!newRef)
        delete this;

    return newRef;
}

HRESULT STDMETHODCALLTYPE WebInspector::show()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->show();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::showConsole()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->showPanel(InspectorController::ConsolePanel);

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::unused1()
{
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::close()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->close();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::attach()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->attachWindow();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::detach()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->detachWindow();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::isDebuggingJavaScript(BOOL* isDebugging)
{
    if (!isDebugging)
        return E_POINTER;

    *isDebugging = FALSE;

    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    *isDebugging = page->inspectorController()->debuggerEnabled();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::toggleDebuggingJavaScript()
{
    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    InspectorController* inspector = page->inspectorController();

    if (inspector->debuggerEnabled())
        inspector->disableDebugger();
    else {
        inspector->showPanel(InspectorController::ScriptsPanel);
        inspector->enableDebugger();
    }

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::isProfilingJavaScript(BOOL* isProfiling)
{
    if (!isProfiling)
        return E_POINTER;

    *isProfiling = FALSE;

    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    *isProfiling = page->inspectorController()->isRecordingUserInitiatedProfile();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::toggleProfilingJavaScript()
{
    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    InspectorController* inspector = page->inspectorController();

    if (inspector->isRecordingUserInitiatedProfile()) {
        inspector->stopUserInitiatedProfiling();
        inspector->showPanel(InspectorController::ProfilesPanel);
    } else
        inspector->startUserInitiatedProfiling();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::isJavaScriptProfilingEnabled(BOOL* isProfilingEnabled)
{
    if (!isProfiling)
        return E_POINTER;

    *isProfiling = FALSE;

    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    *isProfilingEnabled = page->inspectorController()->profilerEnabled();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::setJavaScriptProfilingEnabled(BOOL enabled)
{
    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    if (enabled)
        page->inspectorController()->enableProfiler();
    else
        page->inspectorController()->disableProfiler();

    return S_OK;
}
<commit_msg>Windows build fix.<commit_after>/*
 * Copyright (C) 2007 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "WebInspector.h"

#include "WebKitDLL.h"
#include "WebView.h"
#pragma warning(push, 0)
#include <WebCore/InspectorController.h>
#include <WebCore/Page.h>
#pragma warning(pop)
#include <wtf/Assertions.h>

using namespace WebCore;

WebInspector* WebInspector::createInstance(WebView* webView)
{
    WebInspector* inspector = new WebInspector(webView);
    inspector->AddRef();
    return inspector;
}

WebInspector::WebInspector(WebView* webView)
    : m_refCount(0)
    , m_webView(webView)
{
    ASSERT_ARG(webView, webView);

    gClassCount++;
    gClassNameCount.add("WebInspector");
}

WebInspector::~WebInspector()
{
    gClassCount--;
    gClassNameCount.remove("WebInspector");
}

void WebInspector::webViewClosed()
{
    m_webView = 0;
}

HRESULT STDMETHODCALLTYPE WebInspector::QueryInterface(REFIID riid, void** ppvObject)
{
    *ppvObject = 0;
    if (IsEqualGUID(riid, IID_IWebInspector))
        *ppvObject = static_cast<IWebInspector*>(this);
    else if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebInspector*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG STDMETHODCALLTYPE WebInspector::AddRef(void)
{
    return ++m_refCount;
}

ULONG STDMETHODCALLTYPE WebInspector::Release(void)
{
    ULONG newRef = --m_refCount;
    if (!newRef)
        delete this;

    return newRef;
}

HRESULT STDMETHODCALLTYPE WebInspector::show()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->show();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::showConsole()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->showPanel(InspectorController::ConsolePanel);

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::unused1()
{
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::close()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->close();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::attach()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->attachWindow();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::detach()
{
    if (m_webView)
        if (Page* page = m_webView->page())
            page->inspectorController()->detachWindow();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::isDebuggingJavaScript(BOOL* isDebugging)
{
    if (!isDebugging)
        return E_POINTER;

    *isDebugging = FALSE;

    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    *isDebugging = page->inspectorController()->debuggerEnabled();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::toggleDebuggingJavaScript()
{
    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    InspectorController* inspector = page->inspectorController();

    if (inspector->debuggerEnabled())
        inspector->disableDebugger();
    else {
        inspector->showPanel(InspectorController::ScriptsPanel);
        inspector->enableDebugger();
    }

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::isProfilingJavaScript(BOOL* isProfiling)
{
    if (!isProfiling)
        return E_POINTER;

    *isProfiling = FALSE;

    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    *isProfiling = page->inspectorController()->isRecordingUserInitiatedProfile();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::toggleProfilingJavaScript()
{
    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    InspectorController* inspector = page->inspectorController();

    if (inspector->isRecordingUserInitiatedProfile()) {
        inspector->stopUserInitiatedProfiling();
        inspector->showPanel(InspectorController::ProfilesPanel);
    } else
        inspector->startUserInitiatedProfiling();

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::isJavaScriptProfilingEnabled(BOOL* isProfilingEnabled)
{
    if (!isProfilingEnabled)
        return E_POINTER;

    *isProfilingEnabled = FALSE;

    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    *isProfilingEnabled = page->inspectorController()->profilerEnabled();
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebInspector::setJavaScriptProfilingEnabled(BOOL enabled)
{
    if (!m_webView)
        return S_OK;

    Page* page = m_webView->page();
    if (!page)
        return S_OK;

    if (enabled)
        page->inspectorController()->enableProfiler();
    else
        page->inspectorController()->disableProfiler();

    return S_OK;
}
<|endoftext|>


<commit_before>// Copyright (c) 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 "chrome/browser/sync/glue/search_engine_data_type_controller.h"

#include "base/metrics/histogram.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/sync/api/syncable_service.h"
#include "chrome/browser/sync/profile_sync_components_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/public/browser/notification_source.h"

using content::BrowserThread;

namespace browser_sync {

SearchEngineDataTypeController::SearchEngineDataTypeController(
    ProfileSyncComponentsFactory* profile_sync_factory,
    Profile* profile,
    ProfileSyncService* sync_service)
    : UIDataTypeController(syncable::SEARCH_ENGINES,
                           profile_sync_factory,
                           profile,
                           sync_service) {
}

SearchEngineDataTypeController::~SearchEngineDataTypeController() {
}

void SearchEngineDataTypeController::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK_EQ(chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED, type);
  registrar_.RemoveAll();
  DCHECK_EQ(state_, MODEL_STARTING);
  state_ = ASSOCIATING;
  Associate();
}

// We want to start the TemplateURLService before we begin associating.
bool SearchEngineDataTypeController::StartModels() {
  // If the TemplateURLService is loaded, continue with association.
  TemplateURLService* turl_service =
      TemplateURLServiceFactory::GetForProfile(profile_);
  if (turl_service && turl_service->loaded()) {
    return true;  // Continue to Associate().
  }

  // Add an observer and continue when the TemplateURLService is loaded.
  registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
                 content::Source<TemplateURLService>(turl_service));
  return false;  // Don't continue Start.
}

// Cleanup for our extra registrar usage.
void SearchEngineDataTypeController::StopModels() {
  registrar_.RemoveAll();
}

}  // namespace browser_sync
<commit_msg>Have sync initialization kick off TemplateURLService's lazy load.<commit_after>// Copyright (c) 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 "chrome/browser/sync/glue/search_engine_data_type_controller.h"

#include "base/metrics/histogram.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/sync/api/syncable_service.h"
#include "chrome/browser/sync/profile_sync_components_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/public/browser/notification_source.h"

using content::BrowserThread;

namespace browser_sync {

SearchEngineDataTypeController::SearchEngineDataTypeController(
    ProfileSyncComponentsFactory* profile_sync_factory,
    Profile* profile,
    ProfileSyncService* sync_service)
    : UIDataTypeController(syncable::SEARCH_ENGINES,
                           profile_sync_factory,
                           profile,
                           sync_service) {
}

SearchEngineDataTypeController::~SearchEngineDataTypeController() {
}

void SearchEngineDataTypeController::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK_EQ(chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED, type);
  registrar_.RemoveAll();
  DCHECK_EQ(state_, MODEL_STARTING);
  state_ = ASSOCIATING;
  Associate();
}

// We want to start the TemplateURLService before we begin associating.
bool SearchEngineDataTypeController::StartModels() {
  // If the TemplateURLService is loaded, continue with association. We force
  // a load here to prevent the rest of Sync from waiting on
  // TemplateURLService's lazy load.
  TemplateURLService* turl_service =
      TemplateURLServiceFactory::GetForProfile(profile_);
  DCHECK(turl_service);
  turl_service->Load();
  if (turl_service->loaded()) {
    return true;  // Continue to Associate().
  }

  // Add an observer and continue when the TemplateURLService is loaded.
  registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
                 content::Source<TemplateURLService>(turl_service));
  return false;  // Don't continue Start.
}

// Cleanup for our extra registrar usage.
void SearchEngineDataTypeController::StopModels() {
  registrar_.RemoveAll();
}

}  // namespace browser_sync
<|endoftext|>


<commit_before><commit_msg>softbody fix #445<commit_after><|endoftext|>


<commit_before>#include "memtransfer_android.h"

#include <dlfcn.h>

#include "../../common/tools.h"

using namespace ogles_gpgpu;

// necessary definitions for Android GraphicBuffer

enum {
    /* buffer is never read in software */
    GRALLOC_USAGE_SW_READ_NEVER   = 0x00000000,
    /* buffer is rarely read in software */
    GRALLOC_USAGE_SW_READ_RARELY  = 0x00000002,
    /* buffer is often read in software */
    GRALLOC_USAGE_SW_READ_OFTEN   = 0x00000003,
    /* mask for the software read values */
    GRALLOC_USAGE_SW_READ_MASK    = 0x0000000F,

    /* buffer is never written in software */
    GRALLOC_USAGE_SW_WRITE_NEVER  = 0x00000000,
    /* buffer is never written in software */
    GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020,
    /* buffer is never written in software */
    GRALLOC_USAGE_SW_WRITE_OFTEN  = 0x00000030,
    /* mask for the software write values */
    GRALLOC_USAGE_SW_WRITE_MASK   = 0x000000F0,

    /* buffer will be used as an OpenGL ES texture */
    GRALLOC_USAGE_HW_TEXTURE      = 0x00000100,
    /* buffer will be used as an OpenGL ES render target */
    GRALLOC_USAGE_HW_RENDER       = 0x00000200,
    /* buffer will be used by the 2D hardware blitter */
    GRALLOC_USAGE_HW_2D           = 0x00000400,
    /* buffer will be used with the framebuffer device */
    GRALLOC_USAGE_HW_FB           = 0x00001000,
    /* mask for the software usage bit-mask */
    GRALLOC_USAGE_HW_MASK         = 0x00001F00,
};

enum {
    HAL_PIXEL_FORMAT_RGBA_8888          = 1,
    HAL_PIXEL_FORMAT_RGBX_8888          = 2,
    HAL_PIXEL_FORMAT_RGB_888            = 3,
    HAL_PIXEL_FORMAT_RGB_565            = 4,
    HAL_PIXEL_FORMAT_BGRA_8888          = 5,
    HAL_PIXEL_FORMAT_RGBA_5551          = 6,
    HAL_PIXEL_FORMAT_RGBA_4444          = 7,
};

#define OG_DL_FUNC(hndl, fn, type) (type)dlsym(hndl, fn)
#define OG_DL_FUNC_CHECK(hndl, fn_ptr, fn) if (!fn_ptr) { OG_LOGERR("MemTransferAndroid", "could not dynamically link func '%s': %s", fn, dlerror()); dlclose(hndl); return false; }

#pragma mark static initializations and methods

GraphicBufferFnCtor MemTransferAndroid::graBufCreate = NULL;
GraphicBufferFnDtor MemTransferAndroid::graBufDestroy = NULL;
GraphicBufferFnGetNativeBuffer MemTransferAndroid::graBufGetNativeBuffer = NULL;
GraphicBufferFnLock MemTransferAndroid::graBufLock = NULL;
GraphicBufferFnUnlock MemTransferAndroid::graBufUnlock = NULL;

EGLExtFnCreateImage MemTransferAndroid::imageKHRCreate = NULL;
EGLExtFnDestroyImage MemTransferAndroid::imageKHRDestroy = NULL;

bool MemTransferAndroid::initPlatformOptimizations() {
    // load necessary EGL extension functions
    void *dlEGLhndl = dlopen("libEGL.so", RTLD_LAZY);
    if (!dlEGLhndl) {
        OG_LOGERR("MemTransferAndroid", "could not load EGL library: %s", dlerror());
        return false;
    }

    imageKHRCreate = OG_DL_FUNC(dlEGLhndl, "eglCreateImageKHR", EGLExtFnCreateImage);
    OG_DL_FUNC_CHECK(dlEGLhndl, imageKHRCreate, "eglCreateImageKHR");

    imageKHRDestroy = OG_DL_FUNC(dlEGLhndl, "eglDestroyImageKHR", EGLExtFnDestroyImage);
    OG_DL_FUNC_CHECK(dlEGLhndl, imageKHRDestroy, "eglDestroyImageKHR");

    dlclose(dlEGLhndl);

    // load necessary Android GraphicBuffer functions
    void *dlUIhndl = dlopen("libui.so", RTLD_LAZY);
    if (!dlUIhndl) {
        OG_LOGERR("MemTransferAndroid", "could not load Android UI library: %s", dlerror());
        return false;
    }

    graBufCreate = OG_DL_FUNC(dlUIhndl, "_ZN7android13GraphicBufferC1Ejjij", GraphicBufferFnCtor);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufCreate, "_ZN7android13GraphicBufferC1Ejjij");

    graBufDestroy = OG_DL_FUNC(dlUIhndl, "_ZN7android13GraphicBufferD1Ev", GraphicBufferFnDtor);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufDestroy, "_ZN7android13GraphicBufferD1Ev");

    graBufGetNativeBuffer = OG_DL_FUNC(dlUIhndl, "_ZNK7android13GraphicBuffer15getNativeBufferEv", GraphicBufferFnGetNativeBuffer);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufGetNativeBuffer, "_ZNK7android13GraphicBuffer15getNativeBufferEv");

    graBufLock = OG_DL_FUNC(dlUIhndl, "_ZN7android13GraphicBuffer4lockEjPPv", GraphicBufferFnLock);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufLock, "_ZN7android13GraphicBuffer4lockEjPPv");

    graBufUnlock = OG_DL_FUNC(dlUIhndl, "_ZN7android13GraphicBuffer6unlockEv", GraphicBufferFnUnlock);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufUnlock, "_ZN7android13GraphicBuffer6unlockEv");

    dlclose(dlUIhndl);

    // all done
    OG_LOGINF("MemTransferAndroid", "static init completed");

    return true;
}

#pragma mark constructor / deconstructor

MemTransferAndroid::~MemTransferAndroid() {
    // release in- and outputs
    releaseInput();
    releaseOutput();
}

#pragma mark public methods

void MemTransferAndroid::releaseInput() {
    // release input image
    if (inputImage) {
        OG_LOGINF("MemTransferAndroid", "releasing input image");
        imageKHRDestroy(EGL_DEFAULT_DISPLAY, inputImage);
        free(inputImage);
        inputImage = NULL;
    }

    // release android graphic buffer handle for input
    if (inputGraBufHndl) {
        OG_LOGINF("MemTransferAndroid", "releasing graphic buffer handle for input");
        graBufDestroy(inputGraBufHndl);
        free(inputGraBufHndl);

        inputGraBufHndl = NULL;
        inputNativeBuf = NULL;  // reset weak-ref pointer to NULL
    }
}

void MemTransferAndroid::releaseOutput() {
    // release output image
    if (outputImage) {
        OG_LOGINF("MemTransferAndroid", "releasing output image");
        imageKHRDestroy(EGL_DEFAULT_DISPLAY, outputImage);
        free(outputImage);
        outputImage = NULL;
    }

    // release android graphic buffer handle for output
    if (outputGraBufHndl) {
        OG_LOGINF("MemTransferAndroid", "releasing graphic buffer handle for output");
        graBufDestroy(outputGraBufHndl);
        free(outputGraBufHndl);

        outputGraBufHndl = NULL;
        outputNativeBuf = NULL;  // reset weak-ref pointer to NULL
    }
}

void MemTransferAndroid::init() {
    assert(!initialized);

    // call parent init
    MemTransfer::init();
}

GLuint MemTransferAndroid::prepareInput(int inTexW, int inTexH, GLenum inputPxFormat, void *inputDataPtr) {
    assert(initialized && inTexW > 0 && inTexH > 0);

    if (inputDataPtr == NULL && inputW == inTexW && inputH == inTexH && inputPixelFormat == inputPxFormat) {
        return inputTexId; // no change
    }

    if (preparedInput) {    // already prepared -- release buffers!
        releaseInput();
    }

    // set attributes
    inputW = inTexW;
    inputH = inTexH;
    inputPixelFormat = inputPxFormat;

    // generate texture id for input
    glGenTextures(1, &inputTexId);

    if (inputTexId <= 0) {
        OG_LOGERR("MemTransferAndroid", "error generating input texture id");
        return 0;
    }

    // handle input pixel format
    int nativePxFmt = HAL_PIXEL_FORMAT_RGBA_8888;
    if (inputPixelFormat != GL_RGBA) {
        OG_LOGERR("MemTransferAndroid", "warning: only GL_RGBA is valid as input pixel format");
    }

    // create graphic buffer
    inputGraBufHndl = malloc(OG_ANDROID_GRAPHIC_BUFFER_SIZE);
    graBufCreate(inputGraBufHndl, inputW, inputH, nativePxFmt,
                 GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_WRITE_OFTEN);  // is used as OpenGL texture and will be written often

    // get window buffer
    inputNativeBuf = (struct ANativeWindowBuffer *)graBufGetNativeBuffer(inputGraBufHndl);

    if (!inputNativeBuf) {
        OG_LOGERR("MemTransferAndroid", "error getting native window buffer for input");
        return 0;
    }

    // create image for reading back the results
    EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };
    inputImage = imageKHRCreate(eglGetDisplay(EGL_DEFAULT_DISPLAY),
                                EGL_NO_CONTEXT,
                                EGL_NATIVE_BUFFER_ANDROID,
                                (EGLClientBuffer)inputNativeBuf,
                                eglImgAttrs);	// or NULL as last param?

    if (!inputImage) {
        OG_LOGERR("MemTransferAndroid", "error creating image KHR for input");
        return 0;
    }

    preparedInput = true;

    OG_LOGINF("MemTransferAndroid", "successfully prepared input with texture id %d", inputTexId);

    return inputTexId;
}

GLuint MemTransferAndroid::prepareOutput(int outTexW, int outTexH) {
    assert(initialized && outTexW > 0 && outTexH > 0);

    if (outputW == outTexW && outputH == outTexH) {
        return outputTexId; // no change
    }

    if (preparedOutput) {    // already prepared -- release buffers!
        releaseOutput();
    }

    // set attributes
    outputW = outTexW;
    outputH = outTexH;

    // generate texture id for input
    glGenTextures(1, &outputTexId);

    if (outputTexId <= 0) {
        OG_LOGERR("MemTransferAndroid", "error generating output texture id");
        return 0;
    }

    // will bind the texture, too:
    setCommonTextureParams(outputTexId);

    Tools::checkGLErr("MemTransferAndroid", "fbo texture parameters");

    // create empty texture space on GPU
    glTexImage2D(GL_TEXTURE_2D, 0,
                 GL_RGBA,
                 outputW, outputH, 0,
                 inputPixelFormat, GL_UNSIGNED_BYTE,
                 NULL);	// we do not need to pass texture data -> it will be generated!

    Tools::checkGLErr("MemTransferAndroid", "fbo texture creation");

    // create graphic buffer
    outputGraBufHndl = malloc(OG_ANDROID_GRAPHIC_BUFFER_SIZE);
    graBufCreate(outputGraBufHndl, outputW, outputH, HAL_PIXEL_FORMAT_RGBA_8888,
                 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_SW_READ_OFTEN);    // is render target and will be read often

    // get window buffer
    outputNativeBuf = (struct ANativeWindowBuffer *)graBufGetNativeBuffer(outputGraBufHndl);

    if (!outputNativeBuf) {
        OG_LOGERR("MemTransferAndroid", "error getting native window buffer for output");
        return 0;
    }

    // create image for reading back the results
    EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };
    outputImage = imageKHRCreate(eglGetDisplay(EGL_DEFAULT_DISPLAY),
                                 EGL_NO_CONTEXT,
                                 EGL_NATIVE_BUFFER_ANDROID,
                                 (EGLClientBuffer)outputNativeBuf,
                                 eglImgAttrs);	// or NULL as last param?

    if (!outputImage) {
        OG_LOGERR("MemTransferAndroid", "error creating image KHR for output");
        return 0;
    }

    preparedOutput = true;

    OG_LOGINF("MemTransferAndroid", "successfully prepared output with texture id %d", outputTexId);

    return outputTexId;
}

void MemTransferAndroid::toGPU(const unsigned char *buf) {
    assert(preparedInput && inputPixelBuffer && inputTexId > 0 && buf);

    // bind the input texture
    glBindTexture(GL_TEXTURE_2D, inputTexId);

    // activate the image KHR for the input
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, inputImage);

    Tools::checkGLErr("MemTransferAndroid", "call to glEGLImageTargetTexture2DOES() for input");

    // lock the graphics buffer at graphicsPtr
    unsigned char *graphicsPtr = (unsigned char *)lockBufferAndGetPtr(BUF_TYPE_INPUT);

    // copy whole image from "buf" to "graphicsPtr"
    memcpy(graphicsPtr, buf, inputW * inputH * 4);

    // unlock the graphics buffer again
    unlockBuffer(BUF_TYPE_INPUT);

}

void MemTransferAndroid::fromGPU(unsigned char *buf) {
    assert(preparedOutput && outputPixelBuffer && outputTexId > 0 && buf);

    // bind the output texture
    glBindTexture(GL_TEXTURE_2D, outputTexId);

    // activate the image KHR for the output
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, outputImage);

    Tools::checkGLErr("MemTransferAndroid", "call to glEGLImageTargetTexture2DOES() for output");

    // lock the graphics buffer at graphicsPtr
    const unsigned char *graphicsPtr = (const unsigned char *)lockBufferAndGetPtr(BUF_TYPE_OUTPUT);

    // copy whole image from "graphicsPtr" to "buf"
    memcpy(buf, graphicsPtr, outputW * outputH * 4);

    // unlock the graphics buffer again
    unlockBuffer(BUF_TYPE_OUTPUT);
}

void *MemTransferAndroid::lockBufferAndGetPtr(BufType bufType) {
    void *hndl;
    int usage;
    unsigned char *memPtr;

    if (bufType == BUF_TYPE_INPUT) {
        hndl = inputGraBufHndl;
        usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
    } else {
        hndl = outputGraBufHndl;
        usage = GRALLOC_USAGE_SW_READ_OFTEN;
    }

    // lock and get pointer
    graBufLock(hndl, usage, &memPtr);

    // check for valid pointer
    if (!memPtr) {
        OG_LOGERR("MemTransferAndroid", "GraphicBuffer lock returned invalid pointer");
    }

    return (void *)memPtr;
}

void MemTransferAndroid::unlockBuffer(BufType bufType) {
    void *hndl = (bufType == BUF_TYPE_INPUT) ? inputGraBufHndl : outputGraBufHndl;

    graBufUnlock(hndl);
}
<commit_msg>Change assertions to fix debug android compilation: {input,output}PixelBuffer => {input,output}Image<commit_after>#include "memtransfer_android.h"

#include <dlfcn.h>

#include "../../common/tools.h"

using namespace ogles_gpgpu;

// necessary definitions for Android GraphicBuffer

enum {
    /* buffer is never read in software */
    GRALLOC_USAGE_SW_READ_NEVER   = 0x00000000,
    /* buffer is rarely read in software */
    GRALLOC_USAGE_SW_READ_RARELY  = 0x00000002,
    /* buffer is often read in software */
    GRALLOC_USAGE_SW_READ_OFTEN   = 0x00000003,
    /* mask for the software read values */
    GRALLOC_USAGE_SW_READ_MASK    = 0x0000000F,

    /* buffer is never written in software */
    GRALLOC_USAGE_SW_WRITE_NEVER  = 0x00000000,
    /* buffer is never written in software */
    GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020,
    /* buffer is never written in software */
    GRALLOC_USAGE_SW_WRITE_OFTEN  = 0x00000030,
    /* mask for the software write values */
    GRALLOC_USAGE_SW_WRITE_MASK   = 0x000000F0,

    /* buffer will be used as an OpenGL ES texture */
    GRALLOC_USAGE_HW_TEXTURE      = 0x00000100,
    /* buffer will be used as an OpenGL ES render target */
    GRALLOC_USAGE_HW_RENDER       = 0x00000200,
    /* buffer will be used by the 2D hardware blitter */
    GRALLOC_USAGE_HW_2D           = 0x00000400,
    /* buffer will be used with the framebuffer device */
    GRALLOC_USAGE_HW_FB           = 0x00001000,
    /* mask for the software usage bit-mask */
    GRALLOC_USAGE_HW_MASK         = 0x00001F00,
};

enum {
    HAL_PIXEL_FORMAT_RGBA_8888          = 1,
    HAL_PIXEL_FORMAT_RGBX_8888          = 2,
    HAL_PIXEL_FORMAT_RGB_888            = 3,
    HAL_PIXEL_FORMAT_RGB_565            = 4,
    HAL_PIXEL_FORMAT_BGRA_8888          = 5,
    HAL_PIXEL_FORMAT_RGBA_5551          = 6,
    HAL_PIXEL_FORMAT_RGBA_4444          = 7,
};

#define OG_DL_FUNC(hndl, fn, type) (type)dlsym(hndl, fn)
#define OG_DL_FUNC_CHECK(hndl, fn_ptr, fn) if (!fn_ptr) { OG_LOGERR("MemTransferAndroid", "could not dynamically link func '%s': %s", fn, dlerror()); dlclose(hndl); return false; }

#pragma mark static initializations and methods

GraphicBufferFnCtor MemTransferAndroid::graBufCreate = NULL;
GraphicBufferFnDtor MemTransferAndroid::graBufDestroy = NULL;
GraphicBufferFnGetNativeBuffer MemTransferAndroid::graBufGetNativeBuffer = NULL;
GraphicBufferFnLock MemTransferAndroid::graBufLock = NULL;
GraphicBufferFnUnlock MemTransferAndroid::graBufUnlock = NULL;

EGLExtFnCreateImage MemTransferAndroid::imageKHRCreate = NULL;
EGLExtFnDestroyImage MemTransferAndroid::imageKHRDestroy = NULL;

bool MemTransferAndroid::initPlatformOptimizations() {
    // load necessary EGL extension functions
    void *dlEGLhndl = dlopen("libEGL.so", RTLD_LAZY);
    if (!dlEGLhndl) {
        OG_LOGERR("MemTransferAndroid", "could not load EGL library: %s", dlerror());
        return false;
    }

    imageKHRCreate = OG_DL_FUNC(dlEGLhndl, "eglCreateImageKHR", EGLExtFnCreateImage);
    OG_DL_FUNC_CHECK(dlEGLhndl, imageKHRCreate, "eglCreateImageKHR");

    imageKHRDestroy = OG_DL_FUNC(dlEGLhndl, "eglDestroyImageKHR", EGLExtFnDestroyImage);
    OG_DL_FUNC_CHECK(dlEGLhndl, imageKHRDestroy, "eglDestroyImageKHR");

    dlclose(dlEGLhndl);

    // load necessary Android GraphicBuffer functions
    void *dlUIhndl = dlopen("libui.so", RTLD_LAZY);
    if (!dlUIhndl) {
        OG_LOGERR("MemTransferAndroid", "could not load Android UI library: %s", dlerror());
        return false;
    }

    graBufCreate = OG_DL_FUNC(dlUIhndl, "_ZN7android13GraphicBufferC1Ejjij", GraphicBufferFnCtor);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufCreate, "_ZN7android13GraphicBufferC1Ejjij");

    graBufDestroy = OG_DL_FUNC(dlUIhndl, "_ZN7android13GraphicBufferD1Ev", GraphicBufferFnDtor);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufDestroy, "_ZN7android13GraphicBufferD1Ev");

    graBufGetNativeBuffer = OG_DL_FUNC(dlUIhndl, "_ZNK7android13GraphicBuffer15getNativeBufferEv", GraphicBufferFnGetNativeBuffer);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufGetNativeBuffer, "_ZNK7android13GraphicBuffer15getNativeBufferEv");

    graBufLock = OG_DL_FUNC(dlUIhndl, "_ZN7android13GraphicBuffer4lockEjPPv", GraphicBufferFnLock);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufLock, "_ZN7android13GraphicBuffer4lockEjPPv");

    graBufUnlock = OG_DL_FUNC(dlUIhndl, "_ZN7android13GraphicBuffer6unlockEv", GraphicBufferFnUnlock);
    OG_DL_FUNC_CHECK(dlUIhndl, graBufUnlock, "_ZN7android13GraphicBuffer6unlockEv");

    dlclose(dlUIhndl);

    // all done
    OG_LOGINF("MemTransferAndroid", "static init completed");

    return true;
}

#pragma mark constructor / deconstructor

MemTransferAndroid::~MemTransferAndroid() {
    // release in- and outputs
    releaseInput();
    releaseOutput();
}

#pragma mark public methods

void MemTransferAndroid::releaseInput() {
    // release input image
    if (inputImage) {
        OG_LOGINF("MemTransferAndroid", "releasing input image");
        imageKHRDestroy(EGL_DEFAULT_DISPLAY, inputImage);
        free(inputImage);
        inputImage = NULL;
    }

    // release android graphic buffer handle for input
    if (inputGraBufHndl) {
        OG_LOGINF("MemTransferAndroid", "releasing graphic buffer handle for input");
        graBufDestroy(inputGraBufHndl);
        free(inputGraBufHndl);

        inputGraBufHndl = NULL;
        inputNativeBuf = NULL;  // reset weak-ref pointer to NULL
    }
}

void MemTransferAndroid::releaseOutput() {
    // release output image
    if (outputImage) {
        OG_LOGINF("MemTransferAndroid", "releasing output image");
        imageKHRDestroy(EGL_DEFAULT_DISPLAY, outputImage);
        free(outputImage);
        outputImage = NULL;
    }

    // release android graphic buffer handle for output
    if (outputGraBufHndl) {
        OG_LOGINF("MemTransferAndroid", "releasing graphic buffer handle for output");
        graBufDestroy(outputGraBufHndl);
        free(outputGraBufHndl);

        outputGraBufHndl = NULL;
        outputNativeBuf = NULL;  // reset weak-ref pointer to NULL
    }
}

void MemTransferAndroid::init() {
    assert(!initialized);

    // call parent init
    MemTransfer::init();
}

GLuint MemTransferAndroid::prepareInput(int inTexW, int inTexH, GLenum inputPxFormat, void *inputDataPtr) {
    assert(initialized && inTexW > 0 && inTexH > 0);

    if (inputDataPtr == NULL && inputW == inTexW && inputH == inTexH && inputPixelFormat == inputPxFormat) {
        return inputTexId; // no change
    }

    if (preparedInput) {    // already prepared -- release buffers!
        releaseInput();
    }

    // set attributes
    inputW = inTexW;
    inputH = inTexH;
    inputPixelFormat = inputPxFormat;

    // generate texture id for input
    glGenTextures(1, &inputTexId);

    if (inputTexId <= 0) {
        OG_LOGERR("MemTransferAndroid", "error generating input texture id");
        return 0;
    }

    // handle input pixel format
    int nativePxFmt = HAL_PIXEL_FORMAT_RGBA_8888;
    if (inputPixelFormat != GL_RGBA) {
        OG_LOGERR("MemTransferAndroid", "warning: only GL_RGBA is valid as input pixel format");
    }

    // create graphic buffer
    inputGraBufHndl = malloc(OG_ANDROID_GRAPHIC_BUFFER_SIZE);
    graBufCreate(inputGraBufHndl, inputW, inputH, nativePxFmt,
                 GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_WRITE_OFTEN);  // is used as OpenGL texture and will be written often

    // get window buffer
    inputNativeBuf = (struct ANativeWindowBuffer *)graBufGetNativeBuffer(inputGraBufHndl);

    if (!inputNativeBuf) {
        OG_LOGERR("MemTransferAndroid", "error getting native window buffer for input");
        return 0;
    }

    // create image for reading back the results
    EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };
    inputImage = imageKHRCreate(eglGetDisplay(EGL_DEFAULT_DISPLAY),
                                EGL_NO_CONTEXT,
                                EGL_NATIVE_BUFFER_ANDROID,
                                (EGLClientBuffer)inputNativeBuf,
                                eglImgAttrs);	// or NULL as last param?

    if (!inputImage) {
        OG_LOGERR("MemTransferAndroid", "error creating image KHR for input");
        return 0;
    }

    preparedInput = true;

    OG_LOGINF("MemTransferAndroid", "successfully prepared input with texture id %d", inputTexId);

    return inputTexId;
}

GLuint MemTransferAndroid::prepareOutput(int outTexW, int outTexH) {
    assert(initialized && outTexW > 0 && outTexH > 0);

    if (outputW == outTexW && outputH == outTexH) {
        return outputTexId; // no change
    }

    if (preparedOutput) {    // already prepared -- release buffers!
        releaseOutput();
    }

    // set attributes
    outputW = outTexW;
    outputH = outTexH;

    // generate texture id for input
    glGenTextures(1, &outputTexId);

    if (outputTexId <= 0) {
        OG_LOGERR("MemTransferAndroid", "error generating output texture id");
        return 0;
    }

    // will bind the texture, too:
    setCommonTextureParams(outputTexId);

    Tools::checkGLErr("MemTransferAndroid", "fbo texture parameters");

    // create empty texture space on GPU
    glTexImage2D(GL_TEXTURE_2D, 0,
                 GL_RGBA,
                 outputW, outputH, 0,
                 inputPixelFormat, GL_UNSIGNED_BYTE,
                 NULL);	// we do not need to pass texture data -> it will be generated!

    Tools::checkGLErr("MemTransferAndroid", "fbo texture creation");

    // create graphic buffer
    outputGraBufHndl = malloc(OG_ANDROID_GRAPHIC_BUFFER_SIZE);
    graBufCreate(outputGraBufHndl, outputW, outputH, HAL_PIXEL_FORMAT_RGBA_8888,
                 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_SW_READ_OFTEN);    // is render target and will be read often

    // get window buffer
    outputNativeBuf = (struct ANativeWindowBuffer *)graBufGetNativeBuffer(outputGraBufHndl);

    if (!outputNativeBuf) {
        OG_LOGERR("MemTransferAndroid", "error getting native window buffer for output");
        return 0;
    }

    // create image for reading back the results
    EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };
    outputImage = imageKHRCreate(eglGetDisplay(EGL_DEFAULT_DISPLAY),
                                 EGL_NO_CONTEXT,
                                 EGL_NATIVE_BUFFER_ANDROID,
                                 (EGLClientBuffer)outputNativeBuf,
                                 eglImgAttrs);	// or NULL as last param?

    if (!outputImage) {
        OG_LOGERR("MemTransferAndroid", "error creating image KHR for output");
        return 0;
    }

    preparedOutput = true;

    OG_LOGINF("MemTransferAndroid", "successfully prepared output with texture id %d", outputTexId);

    return outputTexId;
}

void MemTransferAndroid::toGPU(const unsigned char *buf) {
    assert(preparedInput && inputImage && inputTexId > 0 && buf);

    // bind the input texture
    glBindTexture(GL_TEXTURE_2D, inputTexId);

    // activate the image KHR for the input
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, inputImage);

    Tools::checkGLErr("MemTransferAndroid", "call to glEGLImageTargetTexture2DOES() for input");

    // lock the graphics buffer at graphicsPtr
    unsigned char *graphicsPtr = (unsigned char *)lockBufferAndGetPtr(BUF_TYPE_INPUT);

    // copy whole image from "buf" to "graphicsPtr"
    memcpy(graphicsPtr, buf, inputW * inputH * 4);

    // unlock the graphics buffer again
    unlockBuffer(BUF_TYPE_INPUT);

}

void MemTransferAndroid::fromGPU(unsigned char *buf) {
    assert(preparedOutput && outputImage && outputTexId > 0 && buf);

    // bind the output texture
    glBindTexture(GL_TEXTURE_2D, outputTexId);

    // activate the image KHR for the output
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, outputImage);

    Tools::checkGLErr("MemTransferAndroid", "call to glEGLImageTargetTexture2DOES() for output");

    // lock the graphics buffer at graphicsPtr
    const unsigned char *graphicsPtr = (const unsigned char *)lockBufferAndGetPtr(BUF_TYPE_OUTPUT);

    // copy whole image from "graphicsPtr" to "buf"
    memcpy(buf, graphicsPtr, outputW * outputH * 4);

    // unlock the graphics buffer again
    unlockBuffer(BUF_TYPE_OUTPUT);
}

void *MemTransferAndroid::lockBufferAndGetPtr(BufType bufType) {
    void *hndl;
    int usage;
    unsigned char *memPtr;

    if (bufType == BUF_TYPE_INPUT) {
        hndl = inputGraBufHndl;
        usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
    } else {
        hndl = outputGraBufHndl;
        usage = GRALLOC_USAGE_SW_READ_OFTEN;
    }

    // lock and get pointer
    graBufLock(hndl, usage, &memPtr);

    // check for valid pointer
    if (!memPtr) {
        OG_LOGERR("MemTransferAndroid", "GraphicBuffer lock returned invalid pointer");
    }

    return (void *)memPtr;
}

void MemTransferAndroid::unlockBuffer(BufType bufType) {
    void *hndl = (bufType == BUF_TYPE_INPUT) ? inputGraBufHndl : outputGraBufHndl;

    graBufUnlock(hndl);
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "GameManager.h"
#include "GameRoom.h"
#include "Game.h"
#include "Player.h"
#include "Unit.h"
#include "ClientManager.h"
#include "ClientSession.h"
#include "ContactListener.h"
#include "Scheduler.h"
#include "Config.h"

GameManager* GGameManager = nullptr;

///////////////////////////////////////////////////////////////////////////
/*
    GameRoom 관련
*/
///////////////////////////////////////////////////////////////////////////
GameRoom* GameManager::CreateRoom()
{
    if (m_MakeRoomNum == 0)
        LowTick();

    if (m_RoomList.find(m_MakeRoomNum) != m_RoomList.end())
    {
        DeleteRoom(m_MakeRoomNum);
    }
    GameRoom* room = new GameRoom(++m_MakeRoomNum);
    m_RoomList[m_MakeRoomNum] = room;
    return room;
}

void GameManager::DeleteRoom(int roomId)
{
    if (roomId < 0)
    {
        printf(" - DeleteRoom Failed ! : roomId is invalid \n");
        return;
    }
    auto room = m_RoomList.find(roomId);
    if (room == m_RoomList.end())
    {
        printf(" - DeleteRoom Failed ! : relevant room isn't \n");
        return;
    }
    delete room->second;
    m_RoomList.erase(room);
    printf(" - Destroy %d Room ! \n", roomId);
}

GameRoom* GameManager::SearchRoom(int roomId)
{
    if (roomId < 0)
    {
        printf(" - SearchRoom Failed ! : roomId is invalid \n");
        return nullptr;
    }
    auto room = m_RoomList.find(roomId);
    if (room == m_RoomList.end())
    {
        printf(" - SearchRoom Failed ! : relevant room isn't \n");
        return nullptr;
    }
    return room->second;
}

int GameManager::SearchEmptyRoom()
{
    for (auto& room : m_RoomList)
    {
        if (room.second->IsJoinAble())
        {
            return room.second->GetRoomID();
        }
    }
    printf(" - No Room ! \n");
    return -1;
}

void GameManager::JoinRoom(int roomId, Player* player)
{
    if (roomId < 0 || player == nullptr)
    {
        printf(" - JoinRoom Failed ! : invalid info \n");
        return;
    }
    m_RoomList[roomId]->JoinPlayer(player);
}

void GameManager::OutPlayer(int roomId, int playerId)
{
    if (roomId < 0 || playerId < 0)
    {
        printf(" - OutPlayer Failed ! : invalid ID \n");
        return;
    }
    auto game = m_GameList.find(roomId);
    if (game != m_GameList.end())
    {
        game->second->OutPlayer(playerId);
        if (game->second->GetPlayerList().size() == 0)
        {
            DeleteGame(roomId);
        }
    }
    auto room = m_RoomList.find(roomId);
    if (room != m_RoomList.end())
    {
        room->second->OutPlayer(playerId);
        if (room->second->GetPlayerList().size() == 0)
        {
            DeleteRoom(roomId);
        }
    }
}

///////////////////////////////////////////////////////////////////////////
/*
    Game 관련
*/
///////////////////////////////////////////////////////////////////////////
Game* GameManager::SearchGame(int gameId)
{
    if (gameId < 0)
    {
        printf(" - SearchGame Failed ! : gameId is invalid \n");
        return nullptr;
    }
    auto game = m_GameList.find(gameId);
    if (game == m_GameList.end())
    {
        printf(" - SearchGame Failed ! : relevant game isn't \n");
        return nullptr;
    }
    return game->second;
}

void GameManager::CreateGame(int gameId)
{
    if (gameId < 0)
    {
        printf(" - CreateGame Failed ! : gameId is invalid \n");
        return;
    }
    auto room = m_RoomList.find(gameId);
    if (room == m_RoomList.end())
    {
        printf(" - CreateGame Failed ! : room info is invalid \n");
        return;
    }
    if (m_GameList.find(gameId) != m_GameList.end())
    {
        DeleteGame(gameId);
    }
    Game* game = new Game(room->second);
    DeleteRoom(gameId);
    m_GameList[gameId] = game;
    game->InitGame();
}

void GameManager::DeleteGame(int gameId)
{
    if (gameId < 0)
    {
        printf(" - DeleteGame Failed ! : gameId is invalid \n");
        return;
    }
    auto game = m_GameList.find(gameId);
    if (game == m_GameList.end())
    {
        printf(" - DeleteGame Failed ! : relevant game isn't \n");
        return;
    }
    delete game->second;
    m_GameList.erase(game);
    printf(" - Destroy %d Game ! \n", gameId);
}

///////////////////////////////////////////////////////////////////////////
/*
    Player 관련
*/
///////////////////////////////////////////////////////////////////////////
Player* GameManager::SearchPlayer(int playerId)
{
    if (playerId < 0)
    {
        printf(" - SearchPlayer Failed ! : playerId is invalid \n");
        return nullptr;
    }
    for (auto& game : m_GameList)
    {
        for (auto& player : game.second->GetPlayerList())
        {
            if (player.first == playerId)
            {
                return player.second;
            }
        }
    }
    printf(" - SearchPlayer Failed ! : relevant player isn't \n");
    return nullptr;
}

void GameManager::PlayerOut(int playerId)
{
    if (playerId < 0)
    {
        printf(" - PlayerOut Failed ! : playerId is invalid \n");
        return;
    }
    auto player = SearchPlayer(playerId);
    if (player == nullptr)
    {
        printf(" - PlayerOut Failed ! : relevant player isn't \n");
        return;
    }
    OutPlayer(player->GetRoomID(), playerId);
}

///////////////////////////////////////////////////////////////////////////
/*
    매 프레임마다 실행
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::Tick(float dt)
{
    m_World->Step(dt, 8, 3);

    for (auto& room : m_RoomList)
    {
        if (room.second->IsAllReady())
        {
            // 게임 구동 시작!;
            printf(" - All Player is Ready ! :: %d Room is Game Start !! \n", room.first);

            CallFuncAfter(MANAGER_UPDATE_INTERVAL, this, &GameManager::CreateGame, room.first);
            room.second->SetIsGameExist(true);

            room.second->InitReady();
        }
    }

    for (auto& game : m_GameList)
    {
		if (game.second != NULL || game.second->IsEnd())
		{
			continue;
		}

        for (auto& player : game.second->GetPlayerList())
        {
            auto client = GClientManager->GetClient(player.first);
            if (client == nullptr)
            {
                PlayerOut(player.first);
                continue;
            }

            if (client->GetPlayer()->GetMyHero()->GetUnitHp() <= 0)
            {
				client->GameOverCast(client->GetPlayer()->GetPlayerID());
                game.second->EndGame();
                //DeleteGame(game.second->GetGameID());
                break;
            }

            if (game.second->IsReady())
            {
                CallFuncAfter(MANAGER_UPDATE_INTERVAL, client, &ClientSession::ServerRunComplete);
                game.second->SetIsReady(false);
            }

            if (!game.second->IsStart() && game.second->GetLoadedPlayerNum() >= 2)
            {
                client->StartGame();
                game.second->SetIsStart(true);
            }

            if (!game.second->IsStart())
                continue;

            for (auto& unit : player.second->GetUnitList())
            {
                unit.second->Movement();
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////
/*
    낮은 주기로 반복 실행
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::LowTick()
{
    int i = 0, j = 0;
    for (b2Body* b = m_World->GetBodyList(); b; b = b->GetNext())
    {
        if (!b->IsAwake())
        {
            auto unit = static_cast<Unit*>(b->GetUserData());
            unit->Crashing(false);
            ++j;
        }
        ++i;
    }
    printf(" - Total Sleeping Body Num [%2d/%2d] \n", j, i);
    CallFuncAfter(MANAGER_UPDATE_INTERVAL*3, this, &GameManager::LowTick);
}

///////////////////////////////////////////////////////////////////////////
/*
    데미지 계산 함수들
*/
///////////////////////////////////////////////////////////////////////////
bool GameManager::ApplyDamage(Unit* unitA, Unit* unitB)
{
    if (unitA->GetPlayerID() == unitB->GetPlayerID())
    {
        return false;
    }
    else
    {
        return true;
    }
}

void GameManager::ExchangeDamage(Unit* unitA, Unit* unitB)
{
    int damageA = unitA->GetUnitDamage();
    int damageB = unitB->GetUnitDamage();
    int unitAHp = unitA->GetUnitHp() - damageB;
    int unitBHp = unitB->GetUnitHp() - damageA;

    unitA->SetUnitHp(unitAHp);
    unitB->SetUnitHp(unitBHp);

    int AplayerId = unitA->GetPlayerID();
    int BplayerId = unitB->GetPlayerID();

    GClientManager->GetClient(AplayerId)->HpBroadCast(AplayerId, unitA->GetUnitID(), unitAHp);
    GClientManager->GetClient(BplayerId)->HpBroadCast(BplayerId, unitB->GetUnitID(), unitBHp);
}

///////////////////////////////////////////////////////////////////////////
/*
    물리세계 구축
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::InitPhyWorld()
{
    b2Vec2 gravity(0.0f, 0.0f);
    m_World = new b2World(gravity);

    m_World->SetAllowSleeping(true);
    m_World->SetContinuousPhysics(true);

    m_Contact = new ContactListener();
    m_World->SetContactListener((b2ContactListener*)m_Contact);
}

void GameManager::DeletePhyWorld()
{
    delete m_World;
    delete m_Contact;
}
<commit_msg>[S]서버 문제 수정<commit_after>#include "stdafx.h"
#include "GameManager.h"
#include "GameRoom.h"
#include "Game.h"
#include "Player.h"
#include "Unit.h"
#include "ClientManager.h"
#include "ClientSession.h"
#include "ContactListener.h"
#include "Scheduler.h"
#include "Config.h"

GameManager* GGameManager = nullptr;

///////////////////////////////////////////////////////////////////////////
/*
    GameRoom 관련
*/
///////////////////////////////////////////////////////////////////////////
GameRoom* GameManager::CreateRoom()
{
    if (m_MakeRoomNum == 0)
        LowTick();

    if (m_RoomList.find(m_MakeRoomNum) != m_RoomList.end())
    {
        DeleteRoom(m_MakeRoomNum);
    }
    GameRoom* room = new GameRoom(++m_MakeRoomNum);
    m_RoomList[m_MakeRoomNum] = room;
    return room;
}

void GameManager::DeleteRoom(int roomId)
{
    if (roomId < 0)
    {
        printf(" - DeleteRoom Failed ! : roomId is invalid \n");
        return;
    }
    auto room = m_RoomList.find(roomId);
    if (room == m_RoomList.end())
    {
        printf(" - DeleteRoom Failed ! : relevant room isn't \n");
        return;
    }
    delete room->second;
    m_RoomList.erase(room);
    printf(" - Destroy %d Room ! \n", roomId);
}

GameRoom* GameManager::SearchRoom(int roomId)
{
    if (roomId < 0)
    {
        printf(" - SearchRoom Failed ! : roomId is invalid \n");
        return nullptr;
    }
    auto room = m_RoomList.find(roomId);
    if (room == m_RoomList.end())
    {
        printf(" - SearchRoom Failed ! : relevant room isn't \n");
        return nullptr;
    }
    return room->second;
}

int GameManager::SearchEmptyRoom()
{
    for (auto& room : m_RoomList)
    {
        if (room.second->IsJoinAble())
        {
            return room.second->GetRoomID();
        }
    }
    printf(" - No Room ! \n");
    return -1;
}

void GameManager::JoinRoom(int roomId, Player* player)
{
    if (roomId < 0 || player == nullptr)
    {
        printf(" - JoinRoom Failed ! : invalid info \n");
        return;
    }
    m_RoomList[roomId]->JoinPlayer(player);
}

void GameManager::OutPlayer(int roomId, int playerId)
{
    if (roomId < 0 || playerId < 0)
    {
        printf(" - OutPlayer Failed ! : invalid ID \n");
        return;
    }
    auto game = m_GameList.find(roomId);
    if (game != m_GameList.end())
    {
        game->second->OutPlayer(playerId);
        if (game->second->GetPlayerList().size() == 0)
        {
            DeleteGame(roomId);
        }
    }
    auto room = m_RoomList.find(roomId);
    if (room != m_RoomList.end())
    {
        room->second->OutPlayer(playerId);
        if (room->second->GetPlayerList().size() == 0)
        {
            DeleteRoom(roomId);
        }
    }
}

///////////////////////////////////////////////////////////////////////////
/*
    Game 관련
*/
///////////////////////////////////////////////////////////////////////////
Game* GameManager::SearchGame(int gameId)
{
    if (gameId < 0)
    {
        printf(" - SearchGame Failed ! : gameId is invalid \n");
        return nullptr;
    }
    auto game = m_GameList.find(gameId);
    if (game == m_GameList.end())
    {
        printf(" - SearchGame Failed ! : relevant game isn't \n");
        return nullptr;
    }
    return game->second;
}

void GameManager::CreateGame(int gameId)
{
    if (gameId < 0)
    {
        printf(" - CreateGame Failed ! : gameId is invalid \n");
        return;
    }
    auto room = m_RoomList.find(gameId);
    if (room == m_RoomList.end())
    {
        printf(" - CreateGame Failed ! : room info is invalid \n");
        return;
    }
    if (m_GameList.find(gameId) != m_GameList.end())
    {
        DeleteGame(gameId);
    }
    Game* game = new Game(room->second);
    DeleteRoom(gameId);
    m_GameList[gameId] = game;
    game->InitGame();
}

void GameManager::DeleteGame(int gameId)
{
    if (gameId < 0)
    {
        printf(" - DeleteGame Failed ! : gameId is invalid \n");
        return;
    }
    auto game = m_GameList.find(gameId);
    if (game == m_GameList.end())
    {
        printf(" - DeleteGame Failed ! : relevant game isn't \n");
        return;
    }
    delete game->second;
    m_GameList.erase(game);
    printf(" - Destroy %d Game ! \n", gameId);
}

///////////////////////////////////////////////////////////////////////////
/*
    Player 관련
*/
///////////////////////////////////////////////////////////////////////////
Player* GameManager::SearchPlayer(int playerId)
{
    if (playerId < 0)
    {
        printf(" - SearchPlayer Failed ! : playerId is invalid \n");
        return nullptr;
    }
    for (auto& game : m_GameList)
    {
        for (auto& player : game.second->GetPlayerList())
        {
            if (player.first == playerId)
            {
                return player.second;
            }
        }
    }
    printf(" - SearchPlayer Failed ! : relevant player isn't \n");
    return nullptr;
}

void GameManager::PlayerOut(int playerId)
{
    if (playerId < 0)
    {
        printf(" - PlayerOut Failed ! : playerId is invalid \n");
        return;
    }
    auto player = SearchPlayer(playerId);
    if (player == nullptr)
    {
        printf(" - PlayerOut Failed ! : relevant player isn't \n");
        return;
    }
    OutPlayer(player->GetRoomID(), playerId);
}

///////////////////////////////////////////////////////////////////////////
/*
    매 프레임마다 실행
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::Tick(float dt)
{
    m_World->Step(dt, 8, 3);

    for (auto& room : m_RoomList)
    {
        if (room.second->IsAllReady())
        {
            // 게임 구동 시작!;
            printf(" - All Player is Ready ! :: %d Room is Game Start !! \n", room.first);

            CallFuncAfter(MANAGER_UPDATE_INTERVAL, this, &GameManager::CreateGame, room.first);
            room.second->SetIsGameExist(true);

            room.second->InitReady();
        }
    }

    for (auto& game : m_GameList)
    {
		if (game.second->IsEnd())
		{
			continue;
		}

        for (auto& player : game.second->GetPlayerList())
        {
            auto client = GClientManager->GetClient(player.first);
            if (client == nullptr)
            {
                PlayerOut(player.first);
                continue;
            }

            if (client->GetPlayer()->GetMyHero()->GetUnitHp() <= 0)
            {
				client->GameOverCast(client->GetPlayer()->GetPlayerID());
                game.second->EndGame();
                //DeleteGame(game.second->GetGameID());
                break;
            }

            if (game.second->IsReady())
            {
                CallFuncAfter(MANAGER_UPDATE_INTERVAL, client, &ClientSession::ServerRunComplete);
                game.second->SetIsReady(false);
            }

            if (!game.second->IsStart() && game.second->GetLoadedPlayerNum() >= 2)
            {
                client->StartGame();
                game.second->SetIsStart(true);
            }

            if (!game.second->IsStart())
                continue;

            for (auto& unit : player.second->GetUnitList())
            {
                unit.second->Movement();
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////
/*
    낮은 주기로 반복 실행
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::LowTick()
{
    int i = 0, j = 0;
    for (b2Body* b = m_World->GetBodyList(); b; b = b->GetNext())
    {
        if (!b->IsAwake())
        {
            auto unit = static_cast<Unit*>(b->GetUserData());
            unit->Crashing(false);
            ++j;
        }
        ++i;
    }
    printf(" - Total Sleeping Body Num [%2d/%2d] \n", j, i);
    CallFuncAfter(MANAGER_UPDATE_INTERVAL*3, this, &GameManager::LowTick);
}

///////////////////////////////////////////////////////////////////////////
/*
    데미지 계산 함수들
*/
///////////////////////////////////////////////////////////////////////////
bool GameManager::ApplyDamage(Unit* unitA, Unit* unitB)
{
    if (unitA->GetPlayerID() == unitB->GetPlayerID())
    {
        return false;
    }
    else
    {
        return true;
    }
}

void GameManager::ExchangeDamage(Unit* unitA, Unit* unitB)
{
    int damageA = unitA->GetUnitDamage();
    int damageB = unitB->GetUnitDamage();
    int unitAHp = unitA->GetUnitHp() - damageB;
    int unitBHp = unitB->GetUnitHp() - damageA;

    unitA->SetUnitHp(unitAHp);
    unitB->SetUnitHp(unitBHp);

    int AplayerId = unitA->GetPlayerID();
    int BplayerId = unitB->GetPlayerID();

    GClientManager->GetClient(AplayerId)->HpBroadCast(AplayerId, unitA->GetUnitID(), unitAHp);
    GClientManager->GetClient(BplayerId)->HpBroadCast(BplayerId, unitB->GetUnitID(), unitBHp);
}

///////////////////////////////////////////////////////////////////////////
/*
    물리세계 구축
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::InitPhyWorld()
{
    b2Vec2 gravity(0.0f, 0.0f);
    m_World = new b2World(gravity);

    m_World->SetAllowSleeping(true);
    m_World->SetContinuousPhysics(true);

    m_Contact = new ContactListener();
    m_World->SetContactListener((b2ContactListener*)m_Contact);
}

void GameManager::DeletePhyWorld()
{
    delete m_World;
    delete m_Contact;
}
<|endoftext|>