Monkey patching / Duck Punching - etiquette
Posted: Wed Jan 25, 2012 12:16 pm
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.
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" ;
}