Presentation
KapInspect is based on a plugin architecture for the various inspectors.
The inspectors provided with KapInspect are compiled in the libraries provided, and it is also possible to create new inspectors through development of a simple module.
You will refer to the provided plugin example, that takes snapshots of the application (not very usefull anyhow)
How to develop a new plugin
- Create a Flex Application project in FlexBuilder
- Import KapInspect.swc
- Create a new module with the FlexBuilder project wizard, that will extend KapInspectModule
- Override registerComponents method in the module, in order to register you plugin(s)
- Create a new plugin component, that will implement IKapInspectComponent. You may also directly extend AbstractKapInspectComponent class (that itself extends VBox)
- Define a public static string variable "NAME" that will be a unique key for your component (generally name of the class)
- Define another static variable "LABEL" to give a readable name to your component
- Implements a static function to create the factory for your component, you will specify name, label, class, icon and accept function for your component
- override the commitProperties method to update your view (see below), with _target member
- if required, implement an accept function for your component: you will accept an object dependind on its type, or any other property
Deploy and run your plugin
- Compile your flex project (in FlexBuilder, you will need a dummy application in order to compile the project)
- Your inspection module will be compiled as a SWF that is created under bin directory, inside folders that match the package of the plugin
- Copy the SWF into your application deployment directory, local or remote
- Import your plugin into KapInspect, (with "pluginModules" attribute). You will declare your modules in a coma separated list, without any extension
- Run your application and invoke KapInspect: you should see a new button in the toolbar, with its specific icon (if defined) and the label you chossed as its tooltip
Example
Module class
The following code is the one of MemoryPlugin module. It is very simple, extends KapInspectModule, and its main function is to register the inspectors of the plugin. A single module may register several inspectors, that will become new buttons and context menu entries in KapInspect.
<?xml version="1.0" encoding="utf-8"?>
<module:KapInspectModule xmlns:mx="http: layout="vertical" xmlns:module="fr.kapit.module.*">
<mx:Script>
<![CDATA[
import fr.kapit.introspection.component.ComponentManager;
override public function registerComponents():void {
ComponentManager.instance.registerComponent(MemoryLeakInspector)
}
]]>
</mx:Script>
</module:KapInspectModule>
Inspector class
The following code is an extract of the MemoryLeakInspector class, used in the MemoryLeak plugin of KapInspect.
It shows you how to create the inspector so that it will be recognized by KapInspect.
<?xml version="1.0" encoding="utf-8"?>
<AbstractKapInspectComponent xmlns="fr.kapit.introspection.component.*"
xmlns:mx="http: xmlns:tree="fr.kapit.tree.*" horizontalScrollPolicy="off" creationComplete="_onCreationComplete()">
<mx:Script>
<![CDATA[
[Embed('resources/icons/components/PluginIcon.png')]
private static var _icon:Class
public static var NAME:String = "MemoryLeakInspector"
public static var LABEL:String = "Memory Leak Inspector"
public static var IS_GLOBAL : Boolean = false
public var globalPanelName:String = "Memory leaks"
/* The signature of this function is:
public function KapInspectComponentFactory(name:String,label:String,componentClass:Class, iconOn:Class=null,iconOff:Class=null,iconOver:Class=null, isAcceptable:Function=null,shortcut:KapInspectShortcut=null)
iconOn, iconOff, iconOver are icons for the button in the toolbar
isAcceptable is a function whose prototype is :
private static function _isTargetAcceptable(target:Object) : Boolean{
}
This function will be called with the object targetted by the inspector, and will return false if the object is not accepted by it (ex the display list inspector only accepts DisplayObject). If not defined, then true will be always the default and all objects will be accepted.
shortcut defines a custom shortcut:
public function KapInspectShortcut(alt : Boolean, ctrl : Boolean, shift : Boolean, keyCode : uint, name : String), see ASDoc for more information
*/
public static function get factory():KapInspectComponentFactory {
return new KapInspectComponentFactory(NAME,LABEL,MemoryLeakInspector,null,null,null,null, new KapInspectShortcut(false, true, false, 0x4D /*Ctrl+M*/, NAME))
}
override protected function commitProperties():void {
super.commitProperties()
...
}
You see that this class extends AbstractKapInspectComponent, which is a convenient method to implement your plugin.
The source of this class is displayed below:
package fr.kapit.introspection.component
{
import fr.kapit.introspection.ClassUtils;
import mx.containers.VBox;
public class AbstractKapInspectComponent extends VBox implements IKapInspectComponent
{
[Bindable] protected var _target:Object
protected var _targetChanged : Boolean
public var targetName:String
public var host:Object
private var _class : Class
public function AbstractKapInspectComponent()
{
super();
_class = ClassUtils.getObjectClass(this)
}
public function get componentName() : String {
return _class["NAME"]
}
public function get componentLabel() : String {
return _class["LABEL"]
}
public function get target() : Object
{
return _target
}
public function setRoot(target:Object, name:String="", host:Object = null) : void
{
this.targetName = name
this.host = host
this.target = target
}
public function set target(target:Object) : void
{
if ( target != _target ) {
var factory:KapInspectComponentFactory = ComponentManager.instance.getComponentFactory(componentName)
if ( factory && factory.canAccept(target)) {
_target = target
_targetChanged = true
invalidateProperties()
invalidateDisplayList()
}
}
}
public function dispose() : void {
}
}
}
This class exposes the "_target" protected property, that contains the object to be inspected.
When the user invokes an inspector with a new object, the target setter is invoked, and _target member is updated. Then properties are invalidated.
The clean way to develop your plugin is to override commitProperties in the following way:
override protected method commitProperties() : void {
super.commitProperties()
if ( _targetChanged ) {
_targetChanged = false
}
}
The cinematic of inspector is the following:
- setRoot() is called at first opening of the inspector
- set target() is called with the object to be inspected, that has been selected by the user so that the inspector may refresh itself.
Note that in KapInspect, the target object will be setted only once, ie when the inspector is created, because KapInspect keeps a separate inspector for every object inspected.
The only method to be overriden is actually commitProperties.