Originally posted by MadGypsy
View Post
Here was the "class" that forced errors and recorded warnings. Understand that these custom messages are intended to make sure that MY code is being used the way I intended and to spit out warnings that can help you track down missing properties in YOUR MAP.
In other words. A whole lot of this is stuff that a stack trace isn't going to report.
In other words. A whole lot of this is stuff that a stack trace isn't going to report.
Code:
// Gypsy:Gnome - Exceptions Manager | build 20130513-14:39cn float ERR_GNOMENAME = 1; float ERR_MODELPATH = 2; float ERR_SOUNDPATH = 3; float ERR_EFFECTNAME = 4; float ERR_ANIMATOR = 5; float ERR_ID = 6; float ERR_TARGET = 7; float ERR_TARGETNAME = 8; float ERR_STATIC_NOMODELPATH = 9; float ERR_NOHEALTH_DMG = 10; float ERR_HEALTH_NODMG = 11; float ERR_VIEW_OFS = 12; float ERR_URGENT = 13; float ERR_NOINTERFACE = 14; float ERR_INTERFACEONLY = 15; float ERR_PNTS = 16; float ERR_WEAPON = 17; float ERR_PASSEDFLOOR = 18; float ERR_NODATA2WRITE = 19; float ERR_MOVEDIR = 20; float ERR_SPEED = 21; float ERR_NODIMS = 22; float ERR_TYPE = 23; float ERR_NOTARGETS = 24; float ERR_GROUP = 25; float ERR_GROUPNAME = 26; void(float err) ThrowException = { //hint to the object dprint("\n\n"); dprint("GNOME PHUQUP: an exception was thrown by: "); dprint(self.classname); dprint(" at: "); dprint(vtos(self.origin)); dprint("\n"); switch(err) { case ERR_GNOMENAME: dprint("ERR_GNOMENAME: It is mandatory to set the classname field.\n"); break; case ERR_MODELPATH: dprint("ERR_MODELPATH: It is mandatory to set the model field.\n"); break; case ERR_SOUNDPATH: dprint("ERR_SOUNDPATH: It is mandatory to set the sound field.\n"); break; case ERR_EFFECTNAME: dprint("ERR_EFFECTNAME: It is mandatory to set the effectname field.\n"); break; case ERR_ANIMATOR: dprint("ERR_ANIMATOR: It is mandatory to set the animator field.\n"); break; case ERR_ID: dprint("ERR_ID: It is mandatory to set the id field.\n"); break; case ERR_TARGET: dprint("ERR_TARGET: It is mandatory to set the target field.\n"); break; case ERR_TARGETNAME: dprint("ERR_TARGETNAME: It is mandatory to set the targetname field.\n"); break; case ERR_STATIC_NOMODELPATH: dprint("ERR_STATIC_NOMODELPATH: You tried to turn an empty into a static. set the model field.\n"); break; case ERR_NOHEALTH_DMG: dprint("ERR_NOHEALTH_DMG: You gave a damagable entity no health.\n"); break; case ERR_HEALTH_NODMG: dprint("ERR_HEALTH_NODMG: You gave health to a non-damagable entity.\n"); break; case ERR_VIEW_OFS: dprint("ERR_VIEW_OFS: It is mandatory to set the view_ofs field.\n"); break; case ERR_URGENT: dprint("ERR_URGENT: This entity is being instantiated by an incompatible entity.\n"); break; case ERR_NOINTERFACE: dprint("ERR_NOINTERFACE: This entity cannot be subclassed in another entity.\n"); break; case ERR_INTERFACEONLY: dprint("ERR_INTERFACEONLY: This entity must be subclassed in another entity.\n"); break; case ERR_PNTS: dprint("ERR_PNTS: It is mandatory that both the mins and maxs fields are set.\n"); break; case ERR_WEAPON: dprint("ERR_WEAPON: This entity must be subclassed in another entity.\n"); break; case ERR_PASSEDFLOOR: dprint("ERR_PASSEDFLOOR: It is mandatory that both the mins and maxs fields are set.\n"); break; case ERR_NODATA2WRITE: dprint("ERR_NODATA2WRITE: There was no data to write to the file.\n"); break; case ERR_MOVEDIR: dprint("ERR_MOVEDIR: The movedir field was not set for this entity.\n"); break; case ERR_SPEED: dprint("ERR_SPEED: There was no speed set for this entity.\n"); break; case ERR_NODIMS: dprint("ERR_NODIMS: This entity has no dimensions.\n"); break; case ERR_TYPE: dprint("ERR_TYPE: It is mandatory that the type field is set for this entity.\n"); break; case ERR_NOTARGETS: dprint("ERR_NOTARGETS: It is mandatory that this entity have available targets.\n"); break; case ERR_GROUP: dprint("ERR_GROUP: It is mandatory that the group field is set for this entity.\n"); break; case ERR_GROUPNAME: dprint("ERR_GROUPNAME: It is mandatory that the groupname field is set for this entity.\n"); break; default: dprint(ftos(err)); dprint(" is not a recognized error number.\n"); break; } self.urgent = err; } // Gypsy - force a structure into the code // factor = 0: The entity canNOT be included in another entity // factor = 1: The entity can ONLY be included in another entity void(string match, float factor) InstanceRules = { if(!factor) { if(self.classname != match) { ThrowException(ERR_NOINTERFACE); self.urgent = ERR_NOINTERFACE; return; } } else { if(self.classname == match) { ThrowException(ERR_INTERFACEONLY); self.urgent = ERR_INTERFACEONLY; return; } } } // Gypsy:Gnome - Notification Manager | build 20130513-12:37cn float WARN_GNOMENAME = 1; float WARN_MODELPATH = 2; float WARN_SOUNDPATH = 3; float WARN_EFFECTNAME = 4; float WARN_ANIMATOR = 5; float WARN_ID = 6; float WARN_TARGET = 7; float WARN_TARGETNAME = 8; float WARN_STATIC_EFFNAME = 9; float WARN_SOLID = 10; float WARN_SOLIDNOT_HEALTH = 11; float WARN_HEALTH_NODMG = 12; float WARN_TAKEDAMAGE = 13; float WARN_MOVETYPE = 14; float WARN_VOLUME = 15; float WARN_ATTENUATION = 16; float WARN_VIEW_OFS = 17; float WARN_OVERRIDE_PNTS = 18; float WARN_ABS_PNTS = 19; float WARN_FILE = 20; float WARN_FILE_READ = 21; float WARN_FILE_COMPLETE = 23; float WARN_DMGSETNO = 24; float WARN_ORFIELDSPREAD = 25; //returns the appropriatre string back to an array index that matches the warning number string(float info) get_notice = { local string temp; temp = string_null; //compiler switch(info) { case WARN_GNOMENAME: temp = "gnomename field has not been set.\n"; break; case WARN_MODELPATH: temp = "model field has not been set. this entity must be a brush or empty. \n"; break; case WARN_SOUNDPATH: temp = "sound field has not been set.\n"; break; case WARN_EFFECTNAME: temp = "effectname field has not been set.\n"; break; case WARN_ANIMATOR: temp = "no animator was assigned.\n"; break; case WARN_ID: temp = "id field has not been set.\n"; break; case WARN_TARGET: temp = "target field has not been set.\n"; break; case WARN_TARGETNAME: temp = "targetname field has not been set.\n"; break; case WARN_MOVETYPE: temp = "movetype field was not set and defaulted to MOVETYPE_NONE.\n"; break; case WARN_TAKEDAMAGE: temp = "takedamage field was not set and defaulted to DAMAGE_NO.\n"; break; case WARN_SOLID: temp = "solid field was not set and defaulted to SOLID_NOT.\n"; break; case WARN_VIEW_OFS: temp = "view_ofs has not been set. the eye level of your model is assigned to it's origin point.\n"; break; case WARN_VOLUME: temp = "volume field was not set and defaulted to 0.5\n"; break; case WARN_ATTENUATION: temp = "attenuation field was not set and defaulted to ATTN_NONE\n"; break; case WARN_STATIC_EFFNAME: temp = "you cannot set an effect on static entities. your entity was defaulted to SOLID_NOT and MOVETYPE_NONE to allow the effect.\n"; break; case WARN_SOLIDNOT_HEALTH: temp = "you have health on a SOLID_NOT\n"; break; case WARN_OVERRIDE_PNTS: temp = "you are overriding the absmin/max properties.\n"; break; case WARN_ABS_PNTS: temp = "you are using absmin/max values for your bbox. \n"; break; case WARN_FILE: temp = "some file interaction didn't complete. \n"; break; case WARN_FILE_READ: temp = "couldn't read the file data \n"; break; case WARN_FILE_COMPLETE: temp = "the file interaction completed successfully. \n"; break; case WARN_HEALTH_NODMG: temp = "you have health on a non-damageable entity. \n"; break; case WARN_DMGSETNO: temp = "DAMAGE_NO was set for this entity. \n"; break; case WARN_ORFIELDSPREAD: temp = "you are overriding the default .fieldspread. \n"; break; } if(temp != string_null) self.notify[0] = "1"; else temp = strcat("A notification number that does not exist [", ftos(info), "] was attempted here.\n"); return temp; } /* I use an array here because treating it like a flag made the number rack up too fast. Now I can count in succession and keep the value very low. */ void(float info) manage_notifications = { cfg_var = CFG_ALLOW_NOTIFY; if( self.cfg_notify && cfg_var && !check_string(self.notify[info]) ) { self.notify[info] = get_notice(info); } }; string(string file, float typ, string str) file_manager = { cfg_var = CFG_WRITE_LOGS; //constants can't be placed directly into a conditional without a compiler warning //so let's assign the value to a global float and use that instead if(!cfg_var) { str = string_null; FILES_WRITABLE = 0; } else { local float fhandle = fopen(file, typ);//open a file if(!fhandle) { str = string_null; manage_notifications(WARN_FILE); //it's not a crisis so we just add it to notify[WARN_FILE] //notify[] should be empty - either it was wiped or never existed //this means WARN_FILE should now be the only notice FILES_WRITABLE = 0; //turn off writing ThrowNotifications(); //send the report to the console, which will not try to write again //ending any possible loop. } else { if(typ < 1) { str = fgets(fhandle); if( !check_string(str) ) { manage_notifications(WARN_FILE_READ); FILES_WRITABLE = 0; ThrowNotifications(); } } else { if( check_string(str) ) { fputs(fhandle,str); manage_notifications(WARN_FILE_COMPLETE); FILES_WRITABLE = 0; ThrowNotifications(); } else ThrowException(ERR_NODATA2WRITE); } fclose(fhandle); //close the file if(!FILES_WRITABLE) FILES_WRITABLE = 1; //turn writing back on } } return str; }; //prints a header and then spits out every stored notification void() ThrowNotifications = { local string temp; temp = string_null; if ( check_string(self.notify[0]) ) { //hint to the object temp = strcat("\n\nGNOME NOTIFIER: accumulated field notifications for ",self.classname," at: ",vtos(self.origin),"\n"); local float i; for (i=1; i<32; ++i) { if( check_string(self.notify[i]) ) { temp = strcat(temp,self.notify[i]); //building log string self.notify[i] = string_null; //reset } } dprint( strcat(temp,"\n") ); } cfg_var = CFG_WRITE_LOGS; if(FILES_WRITABLE && cfg_var) file_manager("notify.txt", FILE_APPEND, temp); }
I do have some background in C, but that only because I recently read the "C guide for dummies." It was surprisingly good, I'm going to be re-reading it soon. You gotta start somewhere.
This looks like really good stuff MadGypsy. I'll be using it as a resource as get better. Thank you for sharing, it looks amazing.
Comment