Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   Code Gallery (https://forums.graalonline.com/forums/forumdisplay.php?f=179)
-   -   Debugger (https://forums.graalonline.com/forums/showthread.php?t=134257103)

fowlplay4 11-28-2009 09:50 PM

Debugger
 
1 Attachment(s)
Well after doing some work in PowerBuilder (I know a lot of IDE's have that kind of functionality as well), I got to use the debugger and breakpoints and found them quite useful.

So I created a debugger class that you can attach to any of your scripts.

PHP Code:

/*
   Core Debugger Functions: 
   
     Avoid overwriting these functions in your scripts.
   
     - onInitializeDebugger()
     - onCreateDebuggerGUI(title)
     - onChangeDebuggerScope(obj)
     - onDebuggerCall(obj)
     - onResumeDebuggingCode(obj)
     - onResumingCode()
   
   Debugging Functions:
   
     Call these in your scripts to use the debugger.
   
     - debug_breakPoint(temp.time)
     - debug_updateVariables(temp.scope)
   
*/
//#CLIENTSIDE

function onCreated() {
  
// Control Debug Access
  
temp.debuggers = {
    
"fowlplay4"
  
};
  if (
player.account in temp.debuggers) {
    
onInitializeDebugger();
  }
}

function 
onInitializeDebugger() {
  
// Initialize Debugger GUI
  
onCreateDebuggerGUI(this.name);
}

function 
onCreateDebuggerGUI(title) {
  
// Creates Simple Debugger GUI
  
new GuiWindowCtrl("Debugger_" title) {
    
profile GuiBlueWindowProfile;
    
clientrelative true;
    
clientextent "173,262";
    
canmove true;
    
canresize false;
    
closequery false;
    
canminimize canmaximize false;
    
destroyonhide true;
    
visible true;
    
text "Debugging:" SPC title;
    
screenwidth 200;
    
7;

    new 
GuiTextCtrl("Debugger_" title "Text1") {
      
profile GuiBlueTextProfile;
      
height 20;
      
text "Variables";
      
width 46;
      
11;
    }
    new 
GuiScrollCtrl("Debugger_" title "_Scroll") {
      
profile GuiBlueScrollProfile;
      
height 192;
      
hscrollbar "alwaysOff";
      
vscrollbar "dynamic";
      
width 163;
      
5;
      
19;
      new 
GuiTextListCtrl("Debugger_" title "_List") {
        
profile GuiBlueTextListProfile;
        
height 32;
        
horizsizing "width";
        
width 159;
        
temp.varlist this;
      }
    }
    new 
GuiTextEditCtrl("Debugger_" title "_Scope") {
      
profile GuiBlueTextEditProfile;
      
height 20;
      
width 126;
      
42;
      
214;
      
text "this.";
      
this.varslist temp.varlist;
      
thiso.catchevent(name"onAction""onChangeDebuggerScope");
      
hint "Press enter to change debugger's variable scope.";
    }
    new 
GuiTextCtrl("Debugger_" title "_Text2") {
      
profile GuiBlueTextProfile;
      
height 20;
      
text "Scope";
      
width 31;
      
7;
      
213;
    }
    new 
GuiTextCtrl("Debugger_" title "_Text3") {
      
profile GuiBlueTextProfile;
      
height 20;
      
text "Call";
      
width 17;
      
11;
      
238;
    }
    new 
GuiTextEditCtrl("Debugger_" title "_Call") {
      
profile GuiBlueTextEditProfile;
      
height 20;
      
width 126;
      
42;
      
239;
      
thiso.catchevent(name"onAction""onDebuggerCall");
      
hint "Press enter to call a certain function in the script.";
    }
  }
  
// Populate Variable List
  
debug_updateVariables();
}

function 
onChangeDebuggerScope(obj) {
  
// Clear List
  
temp.list = obj.varslist;
  
temp.list.clearrows();
  
// Determine Scope
  
temp.scope obj.text;
  
temp.scope temp.scope.ends(".") ? temp.scope : (temp.scope ".");
  
// Locate Variables
  
temp.variablez getstringkeys(temp.scope);
  
// Determine Functions
  
temp.functionz this.getfunctions();
  
// List Variables
  
for (temp.var: variablez) {
    
// Filter out Functions
    
if (temp.var in temp.functionz) continue;
    
// Get Value of Variable
    
temp.value makevar(temp.scope temp.var);
    
// Add Row to Variable List
    
temp.data temp.scope temp.var @ ": " temp.value;
    
temp.row = list.addrow(0temp.data);
    
temp.row.hint temp.value;
  }
}

function 
onDebuggerCall(obj) {
  
// Determine Call
  
temp.call obj.text;
  
// Call Object
  
if (call.starts("on")) this.trigger(call.substring(2), "");
  else 
this.(@call)();
}

function 
onResumeDebuggingCode(obj) {
  
// Decrease Window Size
  
with (makevar("Debugger_" thiso.name)) {
    
height -= 32;
  }
  
// Destroy Button
  
obj.destroy();
  
// Resume Code
  
this.trigger("onResumingCode""");
}

/*
   Halts the script and places the resume button on the
   debugger.
   
   temp.time - The length in seconds to halt script for.
               If unspecified, defaults to 24 hours.
*/

function debug_breakPoint(temp.time) {
  
// Check for Debugger Window
  
if (!isObject("Debugger_" this.name)) return;
  
// Create Resume Button 
  
with (makevar("Debugger_" this.name)) {
    if (!
isObject("Debugger_" thiso.name "_Resume")) {
      
height += 32;
      new 
GuiButtonCtrl("Debugger_" thiso.name "_Resume") {
        
4;
        
239 22;
        
width 164;
        
text "Resume Code";
        
profile "GuiBlueButtonProfile";
        
thiso.catchevent(name"onAction""onResumeDebuggingCode");
      }
    }
  }
  
// Update Variable List based on Scope
  
debug_updateVariables();
  
// Begin Wait
  
waitfor(this"onResumingCode", (temp.time temp.time 3600 24));
}

/*
   Updates the variable list.
   
   temp.scope - If specified it overwrites the scope in
                the text box, and updates accordingly.
*/

function debug_updateVariables(temp.scope) {
  
// Determine Scope Object
  
temp.obj_scope makevar("Debugger_" this.name "_Scope");
  
// Update Scope Text if neccesary
  
temp.obj_scope.text temp.scope temp.scope temp.obj_scope.text;
  
// Update Variable List
  
onChangeDebuggerScope(temp.obj_scope);


It's very simple to use, adjust the account access array in the created event of the debugger class so you have access then add the following to the top of your script:

PHP Code:

function onCreated() {
  
// Assuming you named the class debugger
  
join("debugger");


You can join it on the client-side as well but depending on the method that you use you'll have to update the script twice or reconnect to get the debugger to appear.

If you joined it on the server-side you have to use the following code to remove it:

PHP Code:

function onCreated() {
  
join("debugger");
  
leave("debugger");


Here's some example usage of what the debugger can do so far:

PHP Code:

function onCreated() {
  
// Assuming you named the class debugger
  
join("debugger");
}

//#CLIENTSIDE
function onCreated() {
  
// Call Example Function
  
someCrazyScript();
}

function 
someCrazyScript() {
  
// Example Code
  
this.something 1;
  
this.lolol true;
  
// Pause Script for Debugger
  
debug_breakPoint();
  
// Example Code Continued
  
this.something 2;
  
// Update Variable List for Debugger
  
debug_updateVariables("this.");


At the moment it's quite simple but I may look into adding/improving features like:

- Serverside Functionality
- Editing Values in Debugger
- Improved GUI
- External Windows (when the v6 Beta comes)

Here's an image of it in action, I inserted a break point in the script when the player reaches the peak of the jump in my gravity script.

cbk1994 11-28-2009 09:52 PM

Ha, that's pretty cool. Nice work.

WhiteDragon 11-28-2009 09:54 PM

Wow!! Great work!

Stickyy

fowlplay4 11-29-2009 12:57 AM

Thanks.

Due to this bug:
http://forums.graalonline.com/forums...00#post1541000

To remove the debugger class from the weapon script if you joined it on the server-side do the following:

PHP Code:

function onCreated() {
  
join("debugger");
  
leave("debugger");



Chompy 11-29-2009 03:56 PM

This needs to be stickied.

Codein 11-29-2009 04:27 PM

Nice work :)

There is one thing that bugs me though, and I know this is probably a personal-preference thing, is the way you name your functions. I'd have thought it'd be logical to reserve the prefix "on" for events, which is how your debugger seems to work aswell, but you seem to be using them for standard functions.

Of course, it may seem like I'm nitpicking. Either way, it's a great system and I'll definitely be using it.

rep++

Soala 11-29-2009 05:02 PM

Great work you've done here. rep++

fowlplay4 11-29-2009 08:18 PM

Quote:

Originally Posted by Codein (Post 1541143)
Nice work :)

There is one thing that bugs me though, and I know this is probably a personal-preference thing, is the way you name your functions. I'd have thought it'd be logical to reserve the prefix "on" for events, which is how your debugger seems to work aswell, but you seem to be using them for standard functions.

Of course, it may seem like I'm nitpicking. Either way, it's a great system and I'll definitely be using it.

rep++

I enjoy the ability of being to trigger, and scheduling the functions I make so that's why I name them the way I do.

Riot 11-29-2009 08:50 PM

Nice, reminds me of around 4 years ago when Stefan said "online debugging was planned" but then I never heard anything else from it.

Codein 11-29-2009 09:06 PM

Quote:

Originally Posted by fowlplay4 (Post 1541202)
I enjoy the ability of being to trigger, and scheduling the functions I make so that's why I name them the way I do.

Understandable.

Samposse 12-08-2009 01:59 PM

Nice ^^ like it :)

adam 02-28-2010 07:33 AM

yeah, makes me sad that I still make my own showtext box in the corner to do that. ..

.. Geez, that's exactly the kind of script I was working on too, the one in the screenshot LOL

Crono 02-28-2010 03:40 PM

is u workin on a platforming project :>?

coreys 02-28-2010 07:49 PM

Quote:

Originally Posted by Crono (Post 1559608)
is u workin on a platforming project :>?

Looks more like a gravity event.

fowlplay4 02-28-2010 08:14 PM

Quote:

Originally Posted by coreys (Post 1559635)
Looks more like a gravity event.

Yep, but that script is now being used in Zodiac's other gravity event now.


All times are GMT +2. The time now is 11:16 AM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.