Page 1 of 1

Monkey patching / Duck Punching - etiquette

Posted: Wed Jan 25, 2012 12:16 pm
by submersible
While building a 1.0 release of Povray Planets - i have found myself attempting to either detect and hook APIs like Deep Horizons, or Famous Planets 2 .. in some cases there just does not seem to be a nice way to trump another OXP - in the case System Demux.homePlanet

For me - this can be the worst kind of action-at-a-distance, so there is logging sprinkled everywhere to indicate what is happening.

Is this done elsewhere ? Examples or suggestions from the OXPlite would be most helpful.

Code: Select all

this.name = "Povray Planets";
this.version = 1.0;
this.author = "Andrew Bramble - a.k.a submersible"
this.copyright = "Creative Commons Attribution-NonCommercial 3.0 Unported License."

this.subsystems = [
	'Povray Planets Galaxy1 Textures',
	'Povray Planets Galaxy2 Textures',
	'Povray Planets Galaxy3 Textures',
	'Povray Planets Galaxy4 Textures',
	'Povray Planets Galaxy5 Textures',
	'Povray Planets Galaxy6 Textures',
	'Povray Planets Galaxy7 Textures',
	'Povray Planets Galaxy8 Textures',
];

this.Log = function(message) { log( this.name , message ) }


this.startUp = function () {
	this.Log( 'Startup');
	var Galaxies = {};

	// Poke code into povray planet galaxy providers
	for (i=0; i < this.subsystems.length ; i++ ) {
		subsys_name = this.subsystems[i];		
		this.Log( subsys_name );
		if (worldScripts[subsys_name])
		{
			this.Log("Monkey patch " + subsys_name );
			target = worldScripts[subsys_name];
			Galaxies[ target.galaxy_index ] = true;
			monkey_curry = this._monkey_patch;
			marshal = this;
			monkey = function() { 
				var texture_name = monkey_curry( marshal,target )
				//log( this.name , texture_name );
				try {
				if ( texture_name ) {
					system.mainPlanet.texture = texture_name;
				}
				} catch (e) { log( this.name , e ) }
			};

			target.shipWillExitWitchspace = monkey;
			target.shipWillLaunchFromStation = monkey;

			// use DH API to exclude home planet
			if (worldScripts["Deep Horizon - Systems API"]) {
				this.Log("Politely ask Deep Horizons to exclude systems for " + subsys_name );
				for (i_planet=0;i_planet<256;i_planet++) {
					worldScripts["Deep Horizon - Systems API"].excludeSystem(
						target.galaxy_index, i_planet,
						{ "TextureMP":true } 
					); 
				}
			}

		}
	}


	// be rude to system demux's homePlanet texturing
	if (worldScripts["System Demux"]) {
		worldScripts["System Demux"]._old_homePlanet = worldScripts["System Demux"].homePlanet;
		worldScripts["System Demux"].homePlanet = 
		function () {
			if ( Galaxies[galaxyNumber] == true ) {
				log( this.name , 'homePlanet disabled by Povray Planets');
				
			} else {
				log( this.name , 'using System Demux homePlanet for this galaxy' );
				this._old_homePlanet;
			}
		};
	}



	delete this.startUp;
}

this._monkey_patch = function(marshal,target) {
  // Bailout if this is not the galaxy we're looking for
  if ( system.info.galaxyID != target.galaxy_index ) { return }
  
  // Ask FP if it desires this system
  if (worldScripts["Famous Planets"])
  {
      if (worldScripts["Famous Planets"].fpCheck( system.info.systemID, system.info.galaxyID )  )
      {
          marshal.Log( "Skipping " + system.info.name + " : belongs to Famous Planets" );
          return; 	
      }
  }



  marshal.Log( "Populating " + system.info.name );
  galNum = target.galaxy_index+1;
  return "gal-" + galNum + "-" + system.info.name + ".png" ;	


}

Re: Monkey patching / Duck Punching - etiquette

Posted: Wed Jan 25, 2012 12:51 pm
by cim
submersible wrote:
While building a 1.0 release of Povray Planets - i have found myself attempting to either detect and hook APIs like Deep Horizons, or Famous Planets 2 .. in some cases there just does not seem to be a nice way to trump another OXP - in the case System Demux.homePlanet

Is this done elsewhere ? Examples or suggestions from the OXPlite would be most helpful.
To disable System Demux entirely for a system (specifically, Lezaer in G3), I use:

Code: Select all

if (worldScripts["System Demux"]) {
				if (!worldScripts["System Demux"].firstLaunch) {
						worldScripts["System Demux"].startUp();
				}
				worldScripts["System Demux"].system_info[517] = 0x0000; // 256*2 + 5
		}
Also removes the Demux moons and secondary planets from the system, though. There doesn't seem to be a nice way to just disable the texturing.

To disable System Redux (again, disables everything for the system) I use:

Code: Select all

if (worldScripts["System Redux"]) {
				if (worldScripts["System Redux"].startUp) {
						// make sure this has started first
						worldScripts["System Redux"].startUp();
				}
				worldScripts["System Redux"].changeSystems([[],[],[5],[],[],[],[],[]]);
		}

Re: Monkey patching / Duck Punching - etiquette

Posted: Wed Jan 25, 2012 2:10 pm
by Cmd. Cheyd
And DH_Systems has a full API created to allow other OXP's to control it's behavior. And as I have mentioned previously, I have an updated script for DH_Systems (intended as v2) that was designed to allow most/all of the planet texturing OXPs to work together. I ran into some issues that I found unacceptable (bloating of the save-game file due to the way system.info() works), but if you want the code, I'll happily share it.

Re: Monkey patching / Duck Punching - etiquette

Posted: Wed Jan 25, 2012 2:20 pm
by Svengali
I'd think Monkeypatches are evil and should be treated as last resort option. Often enough there are other ways. When seeing that more and more OXPs are using it - conflicting behaviours are likely to happen. And it causes more and more additional work for other OXPs which is bad for performance. The same goes for 'global' behaviour changes - this will cause extra work for OXPs and/or adds incompatibilities. For my own OXPs I'm trying to avoid behaviour changes on a global level. If I have to change something I'm trying to do it locally and/or only for a period of time.

But as we have no etiquette (neither for Monkeypatches nor for global behaviour changes) it boils down to your ability/preference. Still - it's best to avoid Monkeypatches. And Cmd. Cheyds API looks like a good thing to sort the planet/moon business without the need of drastical actions.