SRL Archive - SRL Suggestions

MasterCrimez's FailSaveHandler !!


Master BAW

2012-06-19 09:39:38

EDIT: Sorry for mis-spelling the title :P lol
And check this thread that I made earlier: http://villavu.com/forum/showthread.php?t=84533
It's about the same but then it doesnt work! :P



—————-
Hello everyone,

I have just made a FailSafeHandler include function. It makes it easier for you to make failsafes. To make clear what I mean, I will start from the beginning:


I am making a very big script that needs a lot of failsafes. A failsafe has two functions;
1 - it will repeat a piece of code if the result isn't what you wanted
2 - it will stop the script when you repeat the piece of code too often

making the second function of the failsafe is often the harder part, the first function can easily be done with something like this:


program new;

function mainloop;
begin
if random(3) = 0 then //fail (to simplify the example: suppose 1 in 3 times the scripts fails to do something)
begin
writeln('a theoretical error occured');
exit;
end else writeln('it worked');
end;

begin
repeat mainloop until false;
end.

The second function is harder because you have to work with variables. When you have multiple failsafes needed in one function, you have to make a lot of variables and it will become a mess when you do this.

I find that very frustrating and then I thought of a "FailSafeHandler".
I made this:

INCLUDE:

Type
FailSafeHandling = Record
ErrorCode, ErrorExplanation : string;
ErrorTimes, ErrorMaxTimes : integer;
end;

Const
SeeErrorsMode = True;

Var
FailSafe: Array of FailSafeHandling;
ErrorCount : integer;

Procedure StopScript(Text: string);
begin
Writeln(Text);
Writeln('Stopping Script!');
TerminateScript;
//Add things if you like! Maybe you even only want to let the script idle for a while (wait) and then restart from that point!
end;


Procedure NewError(var ErrorCount: integer; ErrorCodeV, ErrorExplanationV: string; ErrorMaxTimesV: integer);
Begin
SetLength(FailSafe,ErrorCount+1);


if FailSafe[ErrorCount].ErrorCode <> ErrorCodeV then //The Error isn't the same as the previous error. --> new error
begin


inc(ErrorCount);
if SeeErrorsMode = True then Writeln('#' + IntToStr(ErrorCount) + ' New: [' + ErrorCodeV + ']');
SetLength(FailSafe,ErrorCount+1);

FailSafe[ErrorCount].ErrorCode := ErrorCodeV;
FailSafe[ErrorCount].ErrorExplanation := ErrorExplanationV;
FailSafe[ErrorCount].ErrorTimes := 1;
FailSafe[ErrorCount].ErrorMaxTimes := ErrorMaxTimesV;


end else
begin

if SeeErrorsMode = True then Writeln('#' + IntToStr(ErrorCount) + ' Repeat (' + IntToStr(FailSafe[ErrorCount].ErrorTimes) + '): [' + ErrorCodeV + ']');

inc(FailSafe[ErrorCount].ErrorTimes);

if((FailSafe[ErrorCount].ErrorTimes >= FailSafe[ErrorCount].ErrorMaxTimes) and (FailSafe[ErrorCount].ErrorMaxTimes <> -1)) then
StopScript('#' + IntToStr(ErrorCount) + ' Repeat too many times (' + IntToStr(FailSafe[ErrorCount].ErrorTimes) + '): [' + FailSafe[ErrorCount].ErrorCode + ']: ' + FailSafe[ErrorCount].ErrorExplanation + '.');

end;


end;

Procedure SolvedError(ErrorCodeV: string);
begin
SetLength(FailSafe,ErrorCount+1);


if(FailSafe[ErrorCount].ErrorCode = ErrorCodeV) then //has just been solved. Add solved error!
begin
NewError(ErrorCount, 'S>'+ErrorCodeV, 'This error could happen this time, but didn''t: ' + FailSafe[ErrorCount].ErrorExplanation, -1);
end;


end;


EXAMPLE USE:



{FailSafeHandling include example.

To-Do:
- write the errors (or only repeated errors) into a text-file!
- More idea's? Post on my topic!}


program TestFailSafeHandler;

{$i FailSafeHandler.simba}

Procedure TestProc;
begin

if(random(3) = 0) then
begin
NewError(ErrorCount,'E001','Testing Error...', 5);
exit;

end else
begin

SolvedError('E001');

end;

if(random(3) = 0) then
begin

NewError(ErrorCount,'E002','Other Error...', 5);
exit;

end else
begin

SolvedError('E002');

end;


end;





begin
ClearDebug;

Repeat TestProc until false;

end.



What does it do?
It stops the script (and shows why) when the script gets into a loop and repeats it too many times (x times).

How does it work?
Include the includer file, and all you have to do is call the procedure NewError, and exit the main loop after it fails. If it doesn't fail, you have to put the procedure SolvedError into your code.


Why is this usefull?
I haven't put it into a bigger script to test it yet, but I think it will make your messy script a lot cleaner and this will prevent you to make a lot of mistakes :) Also the script will become shorter!


How to use it?
Just see the example and i'm sure you're smart enough to figure out what the variables mean!



If you have a suggestion or addition, please PM me or post it here, or even add me on my skype if you really like the idea and think this will become something: 'wijnandkarsens'. I hope I help the community with this. :D



Beware: I might edit this!

Greetz,
MasterCrimeZ

Imagine

2012-06-19 10:04:43

Sometimes with a failsafe though, you may want to do something else other than stop the script. I.E. if you're writing a superheating script, and it's not letting you cast the spell because there are 'not enough nature runes', then you want to withdraw the naturs instead of just terminating the script.

Master BAW

2012-06-19 10:13:21

From: Imagine
Sometimes with a failsafe though, you may want to do something else other than stop the script. I.E. if you're writing a superheating script, and it's not letting you cast the spell because there are 'not enough nature runes', then you want to withdraw the naturs instead of just terminating the script.


Yeah I have thought of that, but I think if you structure your script differently you won't need to call that function . I don't know how to explain it, and I am too tired right now, so maybe this isn't true what I say.
But if it isn't true, maybe I can make another variable in the function NewError. If the function didnt work 5 times, it will call the function that's put into that variable. Does taht sound nice? :)

anyway I'm not sure if this is needed at all , because you might be able to structure your script differently, as in put all your functions in the right order into your mainloop.


maybe I can explain it with an example:


Program new;

function mainloop;
begin
if OutOfRunes = True then //you have no runes, just like you said.
begin
NewError(ErrorCount,'E001','Out of nature runes', 3);
GetNewRunesOutOfYourBank;
exit;
end else begin
SolvedError('E001');
end;

if random(3) = 0 then //fail (to simplify the example: suppose 1 in 3 times the scripts fails to do something)
begin
NewError(ErrorCount,'E002','The other thing happens', 5);
DoThisToFixE002;
exit;
end else begin
SolvedError('E002');
writeln('it worked');
end;


end;//end mainloop

begin
repeat mainloop until false;
end.



sorry for the badly long awsnser but I'm thinking while I type.

Edit: put the script inthere … I hope this makes it clear but I mean you just do all your errors after eachother and if something doesnt work, you will exit the mainloop, and then it will start doing the first thing agian… (if that makes sense)

Kyle Undefined

2012-06-19 11:00:31

You could also pass in a function into the failsafe procedure ;)

Master BAW

2012-06-19 11:20:18

From: Kyle Undefined
You could also pass in a function into the failsafe procedure ;)


yeah I believe that's possible but I don't need it yet, so I keep it like this first, until I see the use for that. :)

But don't you think this is a use full way to prevent your bot from getting into an unlimited loop? :D Because that kind of loops are loops where you can be banned from :)