All pastes #178433 Raw Edit

Untitled

public text v1 · immutable
#178433 ·published 2006-09-21 09:30 UTC
rendered paste body
/**------------------------------------------------------------------------------------------------
	
	@modifies	Obj
	@brief		Creates a singleton out of any class.
	
-------------------------------------------------------------------------------------------------*/
	
	uses "reflection", "array";
	
/*------------------------------------------------------------------------------------------------*/
	
	class modifies Obj {
		directive Hookable() {
			eval("
			class modifies ${Class.name(self)} {
				static array hookers;
				
				static function addHooker(void hooker, array events) {
					string name = Class.name(hooker);
					
					events.each() using (event) {
						if (!.hookers.keyExists(event)) {
							.hookers['' + event] = [];
						}
						
						.hookers['' + event]['' + name] = hooker;
					};
				}
				
				static function removeHooker(void hooker) {
					array events;
					
					.hookers.eachWithIndex() using (event, index) {
						events.push(.hookers.getName(index));
					};
					
					.removeHooker(hooker, events);
				}
				
				static function removeHooker(void hooker, array events) {
					string name = Class.name(hooker);
					
					events.each() using (event) {
						if (.hookers.keyExists(event)) {
							.hookers['' + event] = .hookers['' + event].subtract([name => '']);
						}
					};
				}
				
				function callHooker(string event, array with) {
					array args = arguments();
					
					if (!Hookable.hookers.keyExists(event)) { return with; }
					
					Hookable.hookers['' + event].each() using (hooker) {
						object hookerClass = new Class(hooker);
						object hookerFunction = hookerClass.getFunction(event);
						
						monitor {
							with = hookerFunction.exec(with);
						} handle (error) {
							object request = new Request();
							
							request.print('' + error.num);
						}
					};
					
					return with;
				}
			}");
		}
	}

/*------------------------------------------------------------------------------------------------*/
	
	class Hookable {
		[Hookable];
		
		function doSomething() {
			object request = new Request();
			string output = "I don't know what to do!";
			array with;
			
			// We need a hooker!
			with = .callHooker("doSomething", [output]);
			
			request.print(with[0] + "<br />");
		}
	}

/*------------------------------------------------------------------------------------------------*/
	
	class Hooker {
		static constructor() {
			
		}
		
		//static function doSomething(array with) {
		static function doSomething() {
			with[0] = "I know what to do!";
			
			// Don't want to handle this anymore!
			Hookable.removeHooker(self);
			
			return with;
		}
	}
	
/*------------------------------------------------------------------------------------------------*/
	
	object hooker = new Hookable();
	
	Hookable.addHooker(Hooker, ["doSomething"]);
	
	hooker.doSomething();
	hooker.doSomething();
	
/*------------------------------------------------------------------------------------------------*/