hxScout - Scout alternative proof of concept

386 views
Skip to first unread message

Jeff Ward

unread,
Oct 7, 2014, 2:15:23 AM10/7/14
to haxe...@googlegroups.com
Anybody interested in collaborating / contributing to an Adobe Scout alternative written in Haxe?

I posted my proof of concept work here:  https://github.com/jcward/hxScout

Adobe Scout is a profiling and debugging tool for the Flash Runtimes (flash and AIR), which makes it useful for Haxe/flash projects. But it's only for Windows/OSX and under the Adobe CC subscription.

So far my project is just a socket server that decodes the AMF telemetry data and traces it. I'd like it to present a GUI like Scout's (perhaps HTML, perhaps incorporate a haxenode server or some webview) with profiling and memory usage information.

The first need is figuring out the format of the telemetry data, see the raw dump below. Claus Whalers has some info in a similar project here, but maybe there is a definitive source?

Best,
-Jeff

Server.hx:17: {name => [object InvokeEvent$], value => {ticktimes => [684834,685859,686883,687906,688927,689936,690961,691983,692993,694018,695040,696049,697071,698078,699085,700096], callstack => [575,576,441,440,439], numticks => 16, time => 700706}}
Server.hx:17: {name => [object InvokeEvent$], value => {ticktimes => [701105], callstack => [441,440,439], numticks => 1, time => 701414}}
Server.hx:17: {name => .network.loader.close, value => 1015}
Server.hx:17: {name => .sampler.sample, value => 1003}
Server.hx:17: {name => Sampler_sample, value => 1026}
Server.hx:17: {name => .mem.total, value => 22207}
Server.hx:17: {name => .mem.used, value => 22179}
Server.hx:17: {name => .mem.managed, value => 12900}
Server.hx:17: {name => .mem.managed.used, value => 12012}
Server.hx:17: {name => .mem.telemetry.overhead, value => 2257}
Server.hx:17: {name => ticktimes, value => 0.270592055417253}
Server.hx:17: {name => callstack, delta => 236, span => 165}
Server.hx:17: {name => .sampler.medianInterval, delta => 1}
Server.hx:17: {name => .sampler.averageInterval, delta => 28, span => 21}
Server.hx:17: {name => .sampler.maxInterval, value => 0}
Server.hx:17: {name => .3d.resource.drawCalls, value => 1}
Server.hx:17: {name => [object Function], delta => 3817, span => 3791, value => .player.cpu}
Server.hx:17: {name => .tlm.doplay, delta => 7, span => 3810}
Server.hx:17: {name =>  - seed=1506269906, delta => 22, span => 10}
Server.hx:17: {name => [object BitmapData], delta => 576, span => 539}
Server.hx:17: {name => .swftags, delta => 5, span => 561, value => {name => null, modified => false, ymin => 0, ymax => 768, xmin => 0, xmax => 1024, symbolname => null}}
Server.hx:17: {name => .rend.display.mode, delta => 715, span => 1}
Server.hx:17: {name => fullscreen, delta => 20, span => 5189}
Server.hx:17: {name => .memory.newObject, value => {stackid => 0, size => 40, type => [object AVM1Movie$], time => 705633, id => 216931352}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 412, size => 56, type => [class String], time => 705743, id => 293804592}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 413, size => 32, type => [object Matrix], time => 705750, id => 35805088}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 414, size => 304, type => [object Sprite$], time => 705754, id => 216925184}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 710823, id => 216925184}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 710825, id => 35805088}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 710827, id => 293804592}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 710829, id => 216931352}}
Server.hx:17: {name => .gc.Reap, delta => 58, span => 31}
Server.hx:17: {name => .rend.display.mode, delta => 523, span => 0}
Server.hx:17: {name => [object InvokeEvent$], value => {ticktimes => [706152,707159,708165,709174], callstack => [575,576,441,440,439], numticks => 4, time => 709411}}
Server.hx:17: {name => .network.loader.close, value => 1012}
Server.hx:17: {name => .sampler.sample, value => 1012}
Server.hx:17: {name => Sampler_sample, value => 1013}
Server.hx:17: {name => .mem.used, value => 22183}
Server.hx:17: {name => callstack, delta => 9275, span => 21}
Server.hx:17: {name => .sampler.medianInterval, delta => 1}
Server.hx:17: {name => .sampler.averageInterval, delta => 36, span => 27}
Server.hx:17: {name => .sampler.maxInterval, value => 0}
Server.hx:17: {name => .3d.resource.drawCalls, value => 2}
Server.hx:17: {name => [object Function], delta => 2812, span => 2782, value => .player.cpu}
Server.hx:17: {name => .tlm.doplay, delta => 6, span => 2804}
Server.hx:17: {name =>  - seed=1506269906, delta => 21, span => 9}
Server.hx:17: {name => [object BitmapData], delta => 474, span => 442}
Server.hx:17: {name => .swftags, delta => 4, span => 460, value => {name => null, modified => false, ymin => 0, ymax => 768, xmin => 0, xmax => 1024, symbolname => null}}
Server.hx:17: {name => .rend.display.mode, delta => 592, span => 1}
Server.hx:17: {name => fullscreen, delta => 20, span => 3964}
Server.hx:17: {name => .memory.newObject, value => {stackid => 0, size => 40, type => [object AVM1Movie$], time => 720692, id => 216931352}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 412, size => 56, type => [class String], time => 720725, id => 293804592}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 413, size => 32, type => [object Matrix], time => 720732, id => 35805088}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 414, size => 304, type => [object Sprite$], time => 720736, id => 216925184}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 724666, id => 216925184}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 724669, id => 35805088}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 724671, id => 293804592}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 724673, id => 216931352}}
Server.hx:17: {name => .gc.Reap, delta => 79, span => 52}
Server.hx:17: {name => [object InvokeEvent$], value => {ticktimes => [722723,722732,722734], callstack => [575,576,441,440,439], numticks => 3, time => 723462}}
Server.hx:17: {name => .network.loader.close, value => 1011}
Server.hx:17: {name => .sampler.sample, value => 1010}
Server.hx:17: {name => Sampler_sample, value => 3451}
Server.hx:17: {name => callstack, delta => 17178, span => 23}
Server.hx:17: {name => .sampler.medianInterval, delta => 1}
Server.hx:17: {name => .sampler.averageInterval, delta => 37, span => 25}
Server.hx:17: {name => .sampler.maxInterval, value => 0}
Server.hx:17: {name => .3d.resource.drawCalls, value => 3}
Server.hx:17: {name => [object Function], delta => 2922, span => 2886, value => .player.cpu}
Server.hx:17: {name => .tlm.doplay, delta => 8, span => 2912}
Server.hx:17: {name =>  - seed=1506269906, delta => 28, span => 13}
Server.hx:17: {name => [object BitmapData], delta => 693, span => 643}
Server.hx:17: {name => .swftags, delta => 5, span => 673, value => {name => null, modified => false, ymin => 0, ymax => 768, xmin => 0, xmax => 1024, symbolname => null}}
Server.hx:17: {name => .rend.display.mode, delta => 666, span => 2}
Server.hx:17: {name => fullscreen, delta => 27, span => 4384}
Server.hx:17: {name => .memory.newObject, value => {stackid => 0, size => 40, type => [object AVM1Movie$], time => 741921, id => 216931352}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 412, size => 56, type => [class String], time => 741963, id => 293804592}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 413, size => 32, type => [object Matrix], time => 741971, id => 35805088}}
Server.hx:17: {name => .memory.newObject, value => {stackid => 414, size => 304, type => [object Sprite$], time => 741977, id => 216925184}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 746300, id => 216925184}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 746303, id => 35805088}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 746305, id => 293804592}}
Server.hx:17: {name => .memory.deleteObject, value => {time => 746307, id => 216931352}}
Server.hx:17: {name => .gc.Reap, delta => 71, span => 38}
Server.hx:17: {name => [object InvokeEvent$], value => {ticktimes => [742889,743895], callstack => [575,576,441,440,439], numticks => 2, time => 744795}}
Server.hx:17: {name => .sampler.sample, value => 984}

Nicolas Cannasse

unread,
Oct 7, 2014, 11:30:32 AM10/7/14
to haxe...@googlegroups.com
Le 07/10/2014 08:15, Jeff Ward a écrit :
> Anybody interested in collaborating / contributing to an Adobe Scout
> alternative written in Haxe?
>
> I posted my proof of concept work here: https://github.com/jcward/hxScout

That's nice, would love to see this complete, but not for the same reaon
as you :) I found Scout UI to be quite nice already, but it would be
interesting to be able to implement its protocol on other platforms
(hxcpp for instance).

Best,
Nicolas


Philippe Elsass

unread,
Oct 7, 2014, 11:50:35 AM10/7/14
to haxe...@googlegroups.com
Leveraging Scout for C++ targets would be really cool...




--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
--- You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.



--
Philippe

Jeff Ward

unread,
Oct 7, 2014, 1:08:01 PM10/7/14
to haxe...@googlegroups.com
Yes, keeping the serialization format abstract (AMF or haxe.Serializer) and standardizing on some subset of telemetry metrics, with others potentially being platform-specific... I'd like to design with hxcpp support in mind as well, if possible.

Do you have any pointers for where in the code one could implement hxcpp hooks for memory usage, object allocation, frame timing and the like?

Best,
-Jeff

Jeff Ward

unread,
Oct 9, 2014, 1:54:01 AM10/9/14
to haxe...@googlegroups.com
I've added a suite of AIR app testcases for generating sample .flm data at various verbosity levels (aka, telemetry configuraitons -- basic, sampler, cpu, etc) to review this data for information to extract.  So far, the frame timing seems pretty straightforward (though I need to figure out what 'span' is).

The Server.hx app is now collecting telemetry data into Frame object summaries with durations, and I've setup a proof-of-concept client view. The following is screenshot of a testcase that changes the stage framerate and performs some numeric calculations in the background:

Here's a testcase that maintains a steady framerate and makes wasteful allocations on each frame (incurring GC time throughout):

Unfortunately I don't expect the as3 profiling and memory allocation data will be as easy to decipher, nor will the UI be easy to design, but I am excited about the rapid prototyping progress so far.

Best,
-Jeff

Jeff Ward

unread,
Nov 12, 2014, 1:38:06 AM11/12/14
to haxe...@googlegroups.com
A quick update on hxScout - I hit a nice milestone by getting FLM data all the way from AIR through the pure-haxe Server to the OpenFL client GUI, as can be seen here:


Obviously there's a lot of information still to flesh out, especially AS3 sampler data, and some that I may never get to (rendering / Stage3D), but this completed flow is encouraging.

As for hxcpp, I think I've found some profiling information that may help me in producing a library -- the goal would be to dispatch hxcpp debug information in FLM format, such that it would be usable in either hxScout or Adobe Scout.

Sadly, progress is never fast when you're working just for fun after hours.  =)

Cheers,
-Jeff

David Elahee

unread,
Nov 12, 2014, 3:29:06 AM11/12/14
to haxe...@googlegroups.com
Impressive !

--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.



--
David Elahee


Brennan Kinney

unread,
Nov 12, 2014, 6:42:53 PM11/12/14
to haxe...@googlegroups.com
I've been using Jetbrains Webstorm lately for node.js development. They have this neat feature called spy-js, it wraps your classes via proxy to pull it's information. You'd get an interface similar to Scout, just a little more basic and without the timeline. What I liked about it though was being able to jump into your source code and see the current/last value of variables/objects by just mousing over or popping up a window to see it's nested values. It also has a way to let you view how it progressed through source code by highlighting the code that was executed. It'd then provide more relevant/smarter completion while coding, though not sure if that'd be as useful to Haxe. The other features though, would it be possible for hxScout be able to communicate with IDEs like FlashDevelop to provide features like spy-js?

Jeff Ward

unread,
Nov 13, 2014, 1:21:48 AM11/13/14
to haxe...@googlegroups.com
Tonight's progress, UI for multi-session support (left-side menu) and prototype UI for navigation (i.e. dragging the top mini timeline.)


@Brennan - interesting. Yes, while profiling is the primary focus of scout / hxscout, it would be cool to add debugging features. I'll have to look at what type of stack information is available... Maybe possible with hxcpp and gdb ???, but it's probably a little beyond the scope of what I'm looking to do, at least for now.  =)  I have used the HScript library, which as an interpreted script, gives you the ability to poke at your objects live and in-situ, which is really pretty cool.

Cheers,
-Jeff

Jeff Ward

unread,
Dec 3, 2014, 10:37:01 AM12/3/14
to haxe...@googlegroups.com
FYI, you may have seen it on Twitter: hxScout is really coming together, tons of new UI, mostly-accurate data:

A few people asked if this is Flash-only. The answer is - for now, the Flash runtimes (player/AIR) are the only things that generate the telemetry data stream, but I'm looking at hxcpp's Debug.cpp, and it seems like hxcpp support should be possible.

Best,
-Jeff

Philippe Elsass

unread,
Dec 3, 2014, 11:21:16 AM12/3/14
to haxe...@googlegroups.com
Brilliant!

--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.



--
Philippe

Franco Ponticelli

unread,
Dec 3, 2014, 11:55:13 AM12/3/14
to haxe...@googlegroups.com
That is awesome!

Tarwin Stroh-Spijer

unread,
Dec 3, 2014, 1:15:39 PM12/3/14
to haxe...@googlegroups.com

Very awesome indeed! How are you doing the UI?

Marcelo de Moraes Serpa

unread,
Dec 3, 2014, 1:37:33 PM12/3/14
to haxe...@googlegroups.com
+1... and the UI looks great!

Jeff Ward

unread,
Dec 5, 2014, 10:59:31 AM12/5/14
to haxe...@googlegroups.com
Thanks, guys!  The UI is all just custom-written using the OpenFL's excellent implementation of the Flash API - beginGradientFill, scrollRect, MouseEvent, bueno!  =D

The other big questions I get is - is it only for Flash? Right now, the Flash runtimes themselves (Flash player, AIR) are the only things that generate FLM telemetry data, so yes. But I'm looking at hxcpp and see where I could hook a profiler (Debug.cpp) and maybe an object tracker (GC.cpp), so it's possible I could write a CPP Haxe FLM telemetry generator. I plan on looking into this.

Cheers,
-Jeff
Reply all
Reply to author
Forward
0 new messages