<commit_before>//
//  Engine.swift
//
//  Created by <NAME> on 30/06/2015.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import Foundation

public class Engine {
	
	private var entityNames:Dictionary<String, Entity>;
	
	private var entityList:Set<Entity>;
	
	private var systemList:Set<System>;
	
	private var families:Array<Family>;
	private var familyEntities:Dictionary<Family, EntitySet> = [:];
	
	/**
	* Indicates if the engine is currently in its update loop.
	*/
	public var updating:Bool = false;
	
	/**
	* Dispatched when the update loop ends. If you want to add and remove systems from the
	* engine it is usually best not to do so during the update loop. To avoid this you can
	* listen for this signal and make the change when the signal is dispatched.
	*/
	var updateComplete : Signal<Engine>;
	
	
	public init() {
		self.entityList = Set<Entity>();
		self.entityNames = [String: Entity]();
		self.systemList = Set<System>();
		self.families = [Family]();
		self.updateComplete = Signal<Engine>();
	}
	
	/**
	* Add an entity to the engine.
	*
	* @param entity The entity to add.
	*/
	public func addEntity( entity : Entity ) throws {
		
		if let _ = entityNames[entity.name] {
			throw EntoError.EntityAlreadyInUse
		} else {
			entityList.insert(entity);
			entityNames[ entity.name ] = entity;
			
			entity.componentAdded.listen(self, callback: componentAdded)
			entity.componentRemoved.listen(self, callback: componentRemoved)
			entity.nameChanged.listen(self, callback: entityNameChanged)
			
			// If the entity matches any of the existing families, insert it into
			// the family set for that family.
			for family in self.families {
				if(family.matches(entity)) {
					familyEntities[family]?.insert(entity);
				}
			}			
		}

	}
	
	/**
	* Remove an entity from the engine.
	*
	* @param entity The entity to remove.
	*/
	public func removeEntity( entity : Entity ) {
		
		entity.componentAdded.removeListener(self)
		entity.componentRemoved.removeListener(self)
		entity.nameChanged.removeListener(self)
		
		// If the entity matches any of the families
		// we must remove that entity from the set of entities
		// for that family.
		for family in self.families {
			if(family.matches(entity)) {
				familyEntities[family]?.remove(entity);
			}
		}
		
		self.entityNames.removeValueForKey(entity.name)
		self.entityList.remove(entity)

	}
	
	private func entityNameChanged(payload:EntityNameChanged) {
		if( entityNames[ payload.name ] == payload.entity )	{
			self.entityNames.removeValueForKey(payload.name)
			self.entityNames[payload.entity.name] = payload.entity;
		}
	}
	
	/**
	* Get an entity based n its name.
	*
	* @param name The name of the entity
	* @return The entity, or null if no entity with that name exists on the engine
	*/
	public func getEntityByName( name : String ) -> Entity? {
		return self.entityNames[ name ];<commit_msg>Optimisations<commit_after>//
//  Engine.swift
//
//  Created by <NAME> on 30/06/2015.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import Foundation

public class Engine {
	
	private var entityNames:Dictionary<String, Entity>;
	
	private var entityList:Set<Entity>;
	
	private var systemList:Set<System>;
	
	private var families:Array<Family>;
	private var familyEntities:Dictionary<Family, EntitySet> = [:];
	
	/**
	* Indicates if the engine is currently in its update loop.
	*/
	public var updating:Bool = false;
	
	/**
	* Dispatched when the update loop ends. If you want to add and remove systems from the
	* engine it is usually best not to do so during the update loop. To avoid this you can
	* listen for this signal and make the change when the signal is dispatched.
	*/
	var updateComplete : Signal<Engine>;
	
	
	public init() {
		self.entityList = Set<Entity>();
		self.entityNames = [String: Entity]();
		self.systemList = Set<System>();
		self.families = [Family]();
		self.updateComplete = Signal<Engine>();
	}
	
	/**
	* Add an entity to the engine.
	*
	* @param entity The entity to add.
	*/
	public func addEntity( entity : Entity ) throws {
		
		if let _ = entityNames[entity.name] {
			throw EntoError.EntityAlreadyInUse
		} else {
			entityList.insert(entity);
			entityNames[ entity.name ] = entity;
			
			entity.componentAdded.listen(self, callback: componentAdded)
			entity.componentRemoved.listen(self, callback: componentRemoved)
			entity.nameChanged.listen(self, callback: entityNameChanged)
			
			// If the entity matches any of the existing families, insert it into
			// the family set for that family.
			for family in self.families {
				if(family.matches(entity)) {
					familyEntities[family]?.insert(entity);
				}
			}			
		}

	}
	
	/**
	* Remove an entity from the engine.
	*
	* @param entity The entity to remove.
	*/
	public func removeEntity( entity : Entity ) {
		
		entity.componentAdded.removeListener(self)
		entity.componentRemoved.removeListener(self)
		entity.nameChanged.removeListener(self)
		
		// Remove the entity from any of the entity sets.
		for entitySet:EntitySet in familyEntities.values {
			if(entitySet.contains(entity)) {
				entitySet.remove(entity);
			}
		}	
		
		self.entityNames.removeValueForKey(entity.name)
		self.entityList.remove(entity)

	}
	
	private func entityNameChanged(payload:EntityNameChanged) {
		if( entityNames[ payload.name ] == payload.entity )	{
			self.entityNames.removeValueForKey(payload.name)
			self.entityNames[payload.entity.name] = payload.entity;
		}
	}
	
	/**
	* Get an entity based n its name.
	*
	* @param name The name of the entity
	* @return The entity, or null if no entity with that name exists on the engine
	*/
	public func getEntityByName( name : String ) -> Entity? {
		return self.entityNames[ name ];
{'fraction_non_alphanumeric': 0.10620399579390116, 'fraction_numerical': 0.004206098843322818, 'mean_word_length': 3.5293650793650793, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6785669', 'n_tokens_mistral': 1924, 'n_tokens_neox': 1676, 'n_words': 530}