A colleague points me to this blog by Justin Wopitz (Maiden Rulezzzz!), a good summary of what the mx_internal namespace is used for. I’ve actually already had to make use of mx_internal, because I implemented a custom logger that allows me to select where to send log messages (local trace log, back to the server, or both) and configure the queuing of server-bound messages for support and performance purposes.
I don’t want to make this a whole dissertation on logging (though with the frequency I blog I probably should; it’d improve my average monthly word count), but take a look at LineFormattedTarget. If you want to write your own log target without reinventing the wheel, LineFormattedTarget is probably the best place to extend from. It has a bunch of handy stuff already set up for you that its parent, AbstractTarget, does not, but leaves the nitty gritty of exactly what to write and where to its subclass implementations, which in the framework are TraceTarget and MiniDebugTarget.
TraceTarget and MiniDebugTarget accomplish this by overriding the LineTarget.internalLog(), which is exactly as follows:
mx_internal function internalLog(message:String):void{
// override this method to perform the redirection to the desired output
}
Solid advice! But for those new to using namespaces as access modifiers–and I was, when I got into this, following the suggestion can be a little bit off-putting.
As Wopitz noted, Adobe dissuades you from using mx_internal yourself:
This namespace is used for undocumented APIs — usually implementation details — which can’t be private because they need to visible to other classes. APIs in this namespace are completely unsupported and are likely to change in future versions of Flex.
Boo! But what are you gonna do? internalLog() is called from within logEvent(), also in LineFormattedTarget, so if I don’t use mx_internal to override and implement internalLog(), I instead have to override logEvent(). logEvent() is an event handler for a LogEvent and is really the entry point into the log target framework. It does a bunch of stuff and I didn’t want to copy and paste the whole thing just so I could change the very last line from
internalLog(date + level + category + event.message);
to
myInternalLog(date + level + category + event.message);
So, fate was cast and the dice were sealed. Or something:
override mx_internal function internalLog(message : String) : void {
if (traceOn) {
trace(message);
}
if (captureOn) {
logHistory.push(message);
if (logHistory.length >= messageThreshold) {
transmitLog();
flush();
}
}
}
(No, I’m not posting the whole log-transmitting thing. It’s not really that fancy, but it’s my company’s property, not mine–until somebody says “Chris, go ahead and put all that crap you wrote on your dinky blog, we don’t care,” I’m going to keep the interesting stuff to myselfmy employer’s self.)
I hope this little bit of elaboration helps somebody, either with mx_internal or logging. I’m happy to take comments or questions, though can’t guarantee that I’ll be any help whatsoever.
Chris do you know of anymore info resoruces on mx_internal?
Really, I think Wopitz’ blog is the best all-around introduction I’ve seen; it’s especially key to understand that access modifiers (public, private, etc) are really just reserved namespaces that are treated specially by the compiler and AVM. If you have a more specific question I’ll certainly try to answer it, though there are no guarantees that I can.
[...] Components Reference Adobe’s Flex 2 Language Reference Flex and ActionScript Error Codes Wiki Good, Fast, Cheap Oscar Trelles jwopitz – flex/flash [...]
Wow, thanks for the tip!
Chris: just peek into the source of the flex framework and then you can see that the only thing you need to start overriding the mx_internal behavior of Flex components is just these two lines:
import mx.core.mx_internal;
use namespace mx_internal;
Cheers,
Viktor
Viktor,
Yeah, how to do it—once you grok namespaces as access modifiers—is pretty easy. I think the issue is more of first figuring out that you actually need to to solve your problem, and then asking yourself “am I really supposed to be doing this?”
Thanks,
Chris