Under the hood: AutoCAD’s JavaScript API

Under the hoodBeing here in San Rafael, it seemed like a good opportunity to put pen to paper on the internals of the JavaScript API introduced in AutoCAD 2014. It's a topic I've been meaning to get to for some time, and sitting in the cube next to Albert Szilvasy helps me get information straight from the horse's mouth, as it were (no offence, Albert ;-).

For those of you who don't know Albert, he's someone who has had an incredible impact on the AutoCAD product, over the years, particularly from a platform perspective. Albert was the person to architect and introduce AutoCAD's .NET API, and is now doing the same for JavaScript.

Albert and I go back a looong way. I first met Albert in 1996 (I think), when I was in the "Developer Consulting Group" (a former incarnation of "Developer Technical Services" โ€“ or DevTech โ€“ the technical arm of the ADN team). I was presenting at the first Eastern European developer conference we'd held, in Brno in the Czech Republic. I was presenting on AutoCAD's APIs with a particular focus on ARX (before it was known as ObjectARX), and there was one extremely sharp guy โ€“ Albert, of course โ€“ in the audience asking very pointed questions. He was still at university in Hungary, at the time, and was sharing his experience of implementing a robotics-related project inside AutoCAD using ARX. We shared more than a few drinks after the event, and I was delighted when Albert eventually ended up joining the ADN team in San Rafael. Albert later transitioned into the AutoCAD Engineering team, and the rest is history (and trust me when I say that the AutoCAD product is far better for it).

But I digress: let's get back to talking about JavaScript inside AutoCADโ€ฆ

To get JavaScript working inside AutoCAD, we've integrated the open source Chromium component into the product. This gives us the all-important V8 environment for executing JavaScript as well as a WebKit-based browser for rendering HTML content. You may have heard that Google is forking WebKit to continue development on their Blink rendering engine. This shouldn't change anything for us, moving forwards: we may well choose to โ€“ at some point โ€“ move to a newer version of Chromium, and it'll happen to be based on Blink.

One of the main reasons for going with Chromium rather than WebKit is that its JavaScript engine โ€“ V8 โ€“ is extensible. This allows us to add our AutoCAD-specific JavaScript APIs into the engine, making them available to code being executed by it.

Chromium is hosted in a separate process to AutoCAD: AcWebBrowser.exe. This process communicates back to AutoCAD via IPC โ€“ which should be just fine even for interactive processes such as jigs (where we have to pass a point from AutoCAD to our JavaScript code for each mouse movement). That's not to say there isn't some marshalling overhead associated with this communication โ€“ there is โ€“ but the benefits of having a separate process executing the code โ€“ particular around fault isolation โ€“ led to us making this trade-off.

The browser component loads what's known as the JavaScript Shaping Layer when it starts. This is a generic API implementation layer that communicates with the host environment โ€“ in our case AutoCAD โ€“ via a small number of entry/exit points: exec(), execAsync() and registerCallback(). Any arguments that are needed for these functions โ€“ such as the options provided to the getInteger() method โ€“ will be encoded in JSON to be communicated via the IPC mechanism.

The beauty of limiting the implementation to make use of these few functions is that it becomes much more easy to translate across to other platforms โ€“ the layer itself is portable and having fewer connection points will reduce the amount of native development needed on each platform. At least that's our expectation. That doesn't mean, of course, that no work is needed to actually fill out the implementation behind these entry/exit points โ€“ that is work that clearly needs to happen โ€“ but we're keeping the number of core connection points down to a small number and designing them to be as streamlined as possible, which should also help minimise the impact felt by the IPC marshalling overhead.

This marshalling happens between a native proxy inside AcWebBrowser.exe process and a native stub inside AutoCAD. With โ€“ as mentioned earlier โ€“ the marshalling of data happening via JSON.

Something that's interesting for developers โ€“ and I know Philippe Leefsma has been looking into this and will no doubt post something soon on the AutoCAD DevBlog โ€“ is the ability to use acjsDefun() to register your own stub functions that can be recipients of the calls coming in via IPC. You'll presumably need to essentially extend the Shaping Layer with your complementary JavaScript code that makes use of exec(), execAsync() and/or registerCallback() calls, but you won't need to implement native code to extend the proxy implementation inside the browser process.

One thing that's worth mentioning about the JavaScript Shaping Layer we've created: it's being written in TypeScript, which gives us the ability to work in a more object-oriented fashion than JavaScript inherently provides, before compiling it to JavaScript and publishing the output. This is certainly something that people using the JavaScript API will want to look at doing themselves, depending on the complexity of the application they're working on.

I think that's probably enough information for today (I wonder if anyone actually made it down this far โ€“ please post a comment if you did! :-). I'll follow up on more information about this new API capability as I discover (or uncover) it.

photo credit: cking via photopin cc

20 responses to “Under the hood: AutoCAD’s JavaScript API”

  1. I suggest you first have to. NET API functionality directly change the DXF codes. Sometimes, the modification of the API is not effective or bring side effects in the form of unwanted change some DXF codes.

  2. Sorry - it's not clear what you're asking for, here. Please post your request with a bit more information to the AutoCAD .NET Discussion Group.

    Kean

  3. I've made it through the text :p I think the JS-Api is pretty interesting and I'm already looking forward to use it in our applications ๐Ÿ™‚

    Best Regards

    Christian

  4. Thanks, Christian - it's reassuring to know at least one person made it through to the end. ๐Ÿ™‚

    Kean

  5. I mean fine-tuning one API before you start to make new ones. The problem I described: forums.autodesk.com/t5/NET/Howto-modify-DXF-codes-inside-entities/td-p/3874836

  6. If I understand this correctly, you'd rather we didn't invest in new APIs before existing ones are 100% complete.

    What's interesting is that you're basically asking for a DXF-code manipulation capability that's pretty fundamentally at odds with the concept behind ObjectARX and .NET: having an OO API to AutoCAD lets us get away from working with implementation-specific group codes. The "right" fix to your problem would (IMO) be to expose the property you're looking for via ObjectARX and .NET (assuming it's not there - I haven't looked into the specifics).

    I'd also suggest it makes more sense to develop functionality when it's needed to address scenarios that are strategically important, rather than only when minor bugs in existing (and frankly not at all comparable) capabilities are ironed out.

    Kean

  7. Kean,

    From a web designer/ elec designer stand point this is very exciting... I'm really interested to get my hands on it and see how i can intergrate it with jQuery... This will be fun!!' Btw, I made it through the post ๐Ÿ˜‰ hahaha...

    Trae - Houston.

  8. at least two actually!
    I was waiting forward this post since your former one on this topic!
    I'm investigating to find a way to upgrade a part of my application that use IE ActiveX to extend javascript, injecting a kind of "MyCadApp" object in it (in case you didn't remember my comments on your previous posts).
    I was, at a first glance a bit disappointed to see that acad web engine only exposes a very small interface to to extend this engine (ie acjsDefun...), reading your post, I now understand this choice.

    If I understand correctly, exposing object instances (I mean as Acad.Application or "MyCadApp" for instance), requires developing a js proxy code (as Javascript Shaping Layer is) and a set of native stub functions.
    - The js proxy code has to call registered funcs serializing arguments and return values with JSON, this seems to be hugely simplified by the use of TypeScript (*)
    - The native stub implementation, it is actually a set of "flattened" methods (as 'Ac_Application_activedocument_addobjectreactor' I found in Autodesk.AutoCAD.js) that de-serialize args an relay calls to wrapped object.

    This isn't as straightforward as I expected but it sounds good enough for my needs.

    Please tell me if I'm on the right way

    Thank you!

    (Thanks to all ADN team as well for all posts around this topic, it makes this API even more attractive.)

    (*) BTW, I've curiously never heard about TypeScript before, typed-class-enabled javascript looks cool!

  9. And please fix the app id problem before any new anything ๐Ÿ™‚
    Kidding aside, what is the big picture use of this API? There was likely some key problem you wanted to solve, maybe you mentioned it but I missed it. thanks

  10. ๐Ÿ™‚

    In a nutshell: write-once, use-anywhere AutoCAD applications. For now it's Windows desktop-centric, but we're hoping it'll be possible to expose this API on other desktop as well as web and mobile platforms, too.

    ("You may say I'm a dreamer, but I'm not the only one..." ๐Ÿ˜‰

    Kean

  11. That sounds about right - we'll both know more as we look into it over time. ๐Ÿ™‚

    BTW - we don't have plans right now to extend the object model for actual drawing database objects, right now. The idea is that JavaScript applications will use custom graphics (jigs, transient graphics) to capture user input and then launch commands to generate the db-resident geometry. I'll definitely also be looking at this area more in the coming weeks.

    Kean

  12. I take your remark as an important guideline - or best practice. Good to know how and why an API has been initially designed.

    BTW, I hope this feature will be enabled in OEM (my app is OEM based)

  13. Good question... I can imagine the tricky part with JavaScript in OEM would be securing the file, to make sure it doesn't get changed (perhaps a checksum is adequate).

    But I have't been involved in discussions around the plan for OEM, so there's a lot I don't know.

    You might try checking in via ADN - Fenton would know, I'm sure.

    Kean

  14. I just want to allow the user to choose: Use of the features API or not. It is bad to tell you: You have to act in a specific way that we impose on you. The user has to decide on how to fix the problem.

  15. Stephan Kaiser Avatar

    Kean,

    interesting stuff indeed. Mainly with automated QA in mind, we've recently implemented an IPC meachnism (within AutoCAD) using marshalled JSON, connecting our test controllers and all to-be-tested applications (via JSON-over-HTTP or JSON-over-ProtoBuf and a broker). I'll have a look at the JS API. Maybe there's some overlap that we can leverage.

    Cheers

  16. Thanks for commenting, Stephan.

    It'd certainly be interesting to see how else this mechanism might be used...

    Kean

  17. Hi Kean, this javascript api looks interesting. I can't say I understood too much of what was written in this post. but a question I have is what added benefit is there in using the javascript API vs the .net and objectARX ones which already exist?

    1. Kean Walmsley Avatar

      The main idea behind this effort was to provide an API that could eventually be used across various platforms (desktop, web, mobile). I would not invest much time and effort in this API, right now, as my understanding is that the AutoCAD team has shifted their focus onto a different approach for solving this.

      Kean

  18. I have just installed Autocad 2021 and the javascript API stopped working. The debug console says:

    Autodesk.AutoCAD.js:6012 Uncaught ReferenceError: exec is not defined

    line 6012 is: var jsonStr = exec(JSON.stringify({

    It seems that AcWebBrowser.exe was replaced for a newer version in the Autocad 2021 release. Is there any workaround so that we can keep using the javascript API in Autocad 2021?

    1. Kean Walmsley Avatar

      Please post to one of the AutoCAD forums for technical support.

      Thanks,

      Kean

Leave a Reply to Ignacio S Cancel reply

Your email address will not be published. Required fields are marked *