Debugging multiple script files

Any idea when the capability to debug scripts that include other scripts will be added? Man would that be helpful for tracking down issues!

Comments

  • jag11jag11 Posts: 885

    As for the question, I have no idea, but if scripts are your own, I suggest you create a bundle with all the required scripts.

    As my rig is Windoze based I use Visual Studio Community to code my Daz Scripts, inside VS I have intellisense, strong type checking and on successful build it automagically generates muy bundle file, ready to be run inside Daz Studio.

     

  • djigneodjigneo Posts: 283

    I would certainly like to get there. I think I could get VS to edit *.dsa files with a JavaScript editor. That would be close, for sure. I'm already using TFS Online to source control my scripts.

    When you say "strong type checking", how does intellisense know about the DAZ Script / Qt / etc types?

    Making sure I understand your process correctly, you have a build that resolves import commands by concatenating the files together? That would indeed be a slick workaround for the debug issue, although fixing something in a "library" script would imply you'd have to recompile all scripts which use it.

  • jag11jag11 Posts: 885
    edited November 2015

    Requirements

    • Visual Studio 215 Community.

    The workflow involves the following,

    1. Create an empty project
    2. Add TypeScript file(s) where you'll be writing your code a la C#
    3. Compile your script to .js
    4. Select yout .js files and create the bundle bundle
    5. Add a post build action to rename the bundled file to .DSA
    6. Map you target .DSA folder in Daz Studio to run it from the content Library

    TypeScript? From the home page:

    TypeScript lets you write JavaScript the way you really want to.
    TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
    Any browser. Any host. Any OS. Open Source.

    TypeScript is part of VS.

    You don't need to use any include or import statements, you just create a bundle which get updated according to your changes.

    As for the strong type checking, I did some reflect like script to create the class declarations out of Daz runtime objects, at first started doing it manually but managed to make some time to develop something more usefull. Right now I have  close to 180 classes. But even if you don't have any previous classes intellisense guesses as you type.

    The obvious advantage is you end up writing more solid code, No more lengthy scripts, you can separate scripts, reuse, etc.

    TypeScript class declarations look like this:

    declare class DzLabel extends QWidget {
        /* Properties */
        alignment: number; // 129
        hasSelectedText: boolean; // false
        indent: number; // -1
        openExternalLinks: boolean; // false
        pixmap: QPixmap; // 
        scaledContents: boolean; // false
        selectedText: string; // 
        text: QString; // 
        textFormat: number; // 2
        textInteractionFlags: number; // 4
        wordWrap: boolean; // false
    
        /* Methods */
        constructor(parent: DzWidget);
        clear(): any;
        buddy(): any;
        setBuddy(widget: DzWidget): any;
    }
    
    declare class DzTextEdit {
        /* Properties */
        text: string | ((para: number) => string); //
        documentTitle: string; // 
        blockCount: number; // 1
        paragraphs: number; // 1
        lines: number; // 1
        length: number; // 1
        italic: boolean; // false
        bold: boolean; // false
        underline: boolean; // false
        color: QColor;
        linkUnderline: boolean; // false
        pointSize: number; // 0
    
        /* Methods */
        constructor(parent: DzWidget);
        hasSelectedText(): boolean;
        selectedText(): String;
        selectionStart(): number;
        selectionEnd(): number;
        selectionParaStart(): number;
        selectionIndexStart(): number;
        selectionParaEnd(): number;
        selectionIndexEnd(): number;
        append(text: String): void;
        clear(): void;
    }
    

    An example application class:

    class ApplicationBase {
        START_TIME = Scene.getTime();
        APPLICATION_NAME = "Application name";
        SCRIPT_NAME: String;
        SHIFT_PRESSED = shiftPressed();
        CONTROL_PRESSED = ctrlPressed();
        MARGIN = 6;
        SPACING = 6;
        dialog: DzDialog = null;
        tabContainer: DzTabWidget = null;
        messages: DzTextEdit;
        s: string = null;
    
        constructor(appName?: string) {
            this.APPLICATION_NAME = appName || this.APPLICATION_NAME;
            var file = new DzFile(getScriptFileName());
            this.SCRIPT_NAME = String("%1.%2").arg(file.baseName()).arg(file.extension());
        }
    
        run() {
            this.initialize();
            if (this.s) {
                this.messages.text = this.s;
            }
            if (this.dialog.exec()) {
    
            }
            App.flushLogBuffer();
        }
    
        initialize() {
            this.dialog = new DzDialog();
            this.dialog.caption = String("%1").arg(this.APPLICATION_NAME);
            this.dialog.width = 600;
            this.dialog.height = 400;
    
            var dialogLayout = new DzGridLayout(this.dialog);
            dialogLayout.margin = this.MARGIN;
            dialogLayout.spacing = this.SPACING;
            this.tabContainer = new DzTabWidget(this.dialog);
            dialogLayout.addMultiCellWidget(this.tabContainer, 0, 0, 0, 2);
            this.tabContainer.addTab((() => {
                var t = new DzVGroupBox(this.tabContainer);
                t.flat = true;
                t.insideMargin = this.MARGIN;
                t.insideSpacing = this.SPACING;
                this.messages = new DzTextEdit(t);
                return t;
            })(), "CONSOLE");
        }
    }
    

    Ends up compiled into:

    var ApplicationBase = (function () {
        function ApplicationBase(appName) {
            this.START_TIME = Scene.getTime();
            this.APPLICATION_NAME = "Application name";
            this.SHIFT_PRESSED = shiftPressed();
            this.CONTROL_PRESSED = ctrlPressed();
            this.MARGIN = 6;
            this.SPACING = 6;
            this.dialog = null;
            this.tabContainer = null;
            this.s = null;
            this.APPLICATION_NAME = appName || this.APPLICATION_NAME;
            var file = new DzFile(getScriptFileName());
            this.SCRIPT_NAME = String("%1.%2").arg(file.baseName()).arg(file.extension());
        }
        ApplicationBase.prototype.run = function () {
            this.initialize();
            if (this.s) {
                this.messages.text = this.s;
            }
            if (this.dialog.exec()) {
            }
            App.flushLogBuffer();
        };
        ApplicationBase.prototype.initialize = function () {
            var _this = this;
            this.dialog = new DzDialog();
            this.dialog.caption = String("%1").arg(this.APPLICATION_NAME);
            this.dialog.width = 600;
            this.dialog.height = 400;
            var dialogLayout = new DzGridLayout(this.dialog);
            dialogLayout.margin = this.MARGIN;
            dialogLayout.spacing = this.SPACING;
            this.tabContainer = new DzTabWidget(this.dialog);
            dialogLayout.addMultiCellWidget(this.tabContainer, 0, 0, 0, 2);
            this.tabContainer.addTab((function () {
                var t = new DzVGroupBox(_this.tabContainer);
                t.flat = true;
                t.insideMargin = _this.MARGIN;
                t.insideSpacing = _this.SPACING;
                _this.messages = new DzTextEdit(t);
                return t;
            })(), "CONSOLE");
        };
        return ApplicationBase;
    })();
    

    Let me know if you need more info.

    Post edited by jag11 on
  • djigneodjigneo Posts: 283

    Thanks, that's pretty slick. I haven't used Typescript before, but it seems pretty handy. Do you have any links for self-study on the "bundle bundle" step you mentioned? I think that's the only part I'm "thick" on. The rest seems fairly clear with a little internet searching.

    Any chance I could trick you into open sourcing / adding me to your project for the DAZScript -> TypeScript definition code? That seems incredibly useful and I'd rather not reinvent the wheel if I don't have to.

  • jag11jag11 Posts: 885

    You need to download the Bundler & Minifier extension from here

    The tutorial for creating a bundle is here

    I'll post the Daz Script typescript definitions later. Maybe we can join efforts to incorporate even more classes.

  • djigneodjigneo Posts: 283

    You're a boss, thanks. I am certainly interested. I'm no stranger to programming, but have only been using DAZ Script (and really, JavaScript) for a short while. Definitely looking forward to getting to the level of automation & sanity checking you're at.

  • jag11jag11 Posts: 885

    On the provided link you'll find the current TypeScript type definitions for Daz Scripting projects.

    You need to create an empty solution, with an empty project, add the "typings" folder and drop the provided definitions there. After that, add one or many typescript files for your project, and later bundle them.

    Download from here

    As you are typing you'll notice intellisense in action.

     

    intellisense1.png
    533 x 374 - 16K
    intellisense2.png
    1031 x 285 - 16K
  • djigneodjigneo Posts: 283

    Thanks, I'm-a playing with them. I'll need a little time to get familiar with TypeScript, but I think I've already found a few bugs in some of my pre-existing scripts, so that's awesome!

    I think I see a few areas in the typings which could use adjusting, and some classes I'm using are missing. I'll have to play with this a bit more later, I figure I'll bring up suggested adjustments in a PM.

    You're the man!

  • jag11jag11 Posts: 885

    No problem, keep in mind that this a WIP, right now I'am in the class collecting stage, so, might be a lot missing. In the next stage I'll be polishing classes, incorporate comments from what is documented so intellisense can show it. The beaty of this is that if you don't have a class an you need it badly, declare it as type any and you can access it like in the old fashioned Daz Script.

    In case you need  to create an instance of a undeclared class just:

    declare class DzFooClass { }
    var foo: any = new DzFooClass();
    foo.fooProperty = 10;
    foo.barMethod();
    
Sign In or Register to comment.