Alright, I am pulling my hair out on this one. Got this problem at around 9 last night and was up until 5 trying to fix it, and then all day so far (it's already about 9 PM again) trying to fix it. I've tried everything I can think of.
Alright, so I'm trying to reference the document object from various classes in my class library. Everything seemed to be going peachy until I started getting this random, weird error. I thought maybe it was Flash acting up all of a sudden but I tried it on my Mac as well and I get the same error.
Basically no matter WHAT I do, I am getting the error:
1195: Attempted access of inaccessible method getSessionHandler through a reference with static type pim:PClient
It's a lot of code, but here is the full code.
// PClient.as
package pim
{
import flash.display.MovieClip;
import pim.gui.PGConsole;
import pim.loader.PCommandLoader;
import pim.loader.PGUILoader;
import pim.loader.PSessionLoader;
/**
* The main client MovieClip for the client
* @author Qix
*/
public class PClient extends MovieClip
{
private var _guiLoader:PGUILoader;
private var _sessionLoader:PSessionLoader;
private var _cmdLoader:PCommandLoader;
private static var _singleton:PClient;
/**
* Constructor
* @author Qix
*/
public function PClient()
{
// Trace
trace("Client(): Client initiated");
// Call super
super();
// Set Singleton instance
PClient._singleton = this;
// Create session handler/loader
_sessionLoader = new PSessionLoader();
// Create command loader
_cmdLoader = new PCommandLoader();
// Create GUI loader + Add to the canvas
_guiLoader = new PGUILoader();
addChild(_guiLoader);
// Call on start
onStart();
}
/**
* Gets the singleton instance of the client
* @author Qix
* @return The singleton instance of the object
*/
public static function getInstance():PClient
{
// Return
return PClient._singleton;
}
/**
* Gets the GUILoader instance
* @author Qix
* @return The GUI Loader instance
*/
public function getGUILoader():PGUILoader
{
// Trace
trace("pim.PClient.getGUILoader():");
// Return
return _guiLoader;
}
/**
* Gets the session handler/loader object
* @author Qix
* @return The session handler/loader object reference
*/
public function getSessionHandler():PSessionLoader
{
// Trace
trace("pim.PClient.getSessionHandler():");
// Return
return _sessionLoader;
}
/**
* Returns the command loader/handler
* @author Qix
* @return Returns the command loader/handler object
*/
public function getCommandHandler():PCommandLoader
{
// Trace
trace("pim.PClient.getCommandHandler():");
// Return
return _cmdLoader;
}
/**
* Called when the client has loaded and is ready to start whatever
* @author Qix
*/
public function onStart():void
{
// Trace
trace("Client.onStart(): Starting startup commands...");
// Create console window
var con:PGConsole = new PGConsole();
_guiLoader.addGUI(con, "console");
// Echo
getCommandHandler().exec("echo hello!");
}
}
}
and...
// PCommandLoader.as
package pim.loader
{
import pim.gui.PGConsole;
import pim.gui.iPGWindow;
import pim.PClient;
/**
* Handles PIM commands
* @author Qix
*/
public final class PCommandLoader
{
private var _funcs:Array;
/**
* Constructor
* @author Qix
*/
public function PCommandLoader()
{
// Trace
trace("PCommandLoader(): Instantiated");
// Instantiate vectors
_funcs = new Array();
// Setup basic commands here
addCMD("echo", c_echo);
addCMD("set", c_set);
addCMD("get", c_get);
}
/**
* Executes a command
* @param cmd
*/
public function exec(cmd:String):void
{
// Trace
trace("PCommandLoader.exec(): " + cmd);
// Get command
var cmdspl:Array = cmd.split(" ");
var cmdn:String = cmdspl[0];
cmdn = cmdn.toLowerCase();
// Construct parameters
var param:String = cmd.substr(cmdn.length + 1);
// Return if command doesn't exist
if (!(cmdn in _funcs))
{
// Trace and return
trace("PCommandLoader.exec(): Command \"" + cmdn + "\" doesn't exist!");
return;
}
// Distribute command
_funcs[cmdn].call(null, param);
}
/**
* Adds a command to the command list
* @param name The name of the command
* @param cb
*/
public function addCMD(name:String, cb:Function):void
{
// Set name to lowercase
name = name.toLowerCase();
// Trace
trace("PCommandLoader.addCMD(): Adding command \"" + name + "\"");
// Warn if already created!
if (name in _funcs)
trace("PCommandLoader.addCMD(): WARNING! Command already created. You are over-riding this
command!");
// Add
_funcs[name] = cb;
}
/**
* Attempts to print to the console
* @author Qix
* @param str The string to print
* @param col The color to make the string
*/
public function conOut(str:String, col:String = "#AAAAAA"):void
{
// Try to get GUI
var p:iPGWindow = PClient.getInstance().getGUILoader().getGUI("console");
// If it doesn't exist...
if (p == null)
return;
// Echo out!
(p as PGConsole).appendText(str, col);
}
/* Basic Command Callbacks */
/**
* CMD: A basic command; Echos out whatever is passed to it.
* @author Qix
*/
private function c_echo(str:String):void
{
// Trace
trace("CMD - ECHO: " + str);
// Output
conOut(str);
}
/**
* CMD: A basic command; Sets a session value
* @author Qix
*/
private function c_set(str:String):void
{
// Get params
var params:Array = str.split(" ");
// If insufficient number of parameters
if (params.length == 1)
{
// Trace and return
trace("CMD - SET: ERROR! Expected 2 parameters, got 1.")
// TODO Echo to console (c_set error)
return;
}
// Trace
trace("CMD - SET: Setting " + params[0] + " to " + params[1]);
// Convert to int if necessary...
var toNum:Number = Number(params[1]);
// Check if the number conversion worked or not and set the value
// Description Resource Path Location Type
//1195: Attempted access of inaccessible method getSessionHandler through a reference with static
type pim:PClient. PCommandLoader.as /PimOnlineClient/[source path] lib/pim/loader line 146 Flex Problem
if (isNaN(toNum))
PClient.getInstance().getSessionHandler().setVal(params[0], params[1]); // String
else
PClient.getInstance().getSessionHandler().setVal(params[0], toNum); //
Number
}
/**
* CMD: A basic command; gets a session value
* @author Qix
*/
private function c_get(str:String):void
{
// Get params
var params:Array = str.split(" ");
// Trace
trace("CMD - GET: Getting the value of \"" + params[0] + "\"");
// Get value
var val:* = PClient.getInstance().getSessionHandler().getVal(params[0]);
// If val is null (failed)
if (val == null)
{
// Trace and return
trace("CMD - GET: ERROR! \"" + params[0] + "\" doesn't exist!");
conOut("\"" + params[0] + "\" does not exist!");
return;
}
// Output
conOut(String(val));
}
}
}
Alright so right now, I have sort of a singleton reference that I'm using so I can reference the document object from any class (without the need to pass the client object to each class that needs to use it). I'm pretty sure I've done this before and had it work, but obviously it is not.
I've even tried passing the client object (this
) to the PCommandLoader
object and it STILL gives this really really strange error (that is WITHOUT the use of any static methods, etc.)
WHAT THE HECK IS GOING ON? I've tried EVERYTHING -- even a class that holds the PClient object reference, which was really messy -- and it still gives this really, really weird message. Even referencing the root
property on movieclips gives me this error. The movie was working great and then magically it started doing this. I backed everything up and undid everything back to pretty much empty script files and it wouldn't let me compile since...
I'm going crazy here! Help?
EDIT Alright, with strict mode set to off, it compiles and works 100% as expected. What gives?
EDIT Here is the describeType on PClient.getInstance() right before the error:
<type name="pim::PClient" base="flash.display::MovieClip" isDynamic="false" isFinal="false" isStatic="false">
<extendsClass type="flash.display::MovieClip"/>
<extendsClass type="flash.display::Sprite"/>
<extendsClass type="flash.display::DisplayObjectContainer"/>
<extendsClass type="flash.display::InteractiveObject"/>
<extendsClass type="flash.display::DisplayObject"/>
<extendsClass type="flash.events::EventDispatcher"/>
<extendsClass type="Object"/>
<implementsInterface type="flash.events::IEventDispatcher"/>
<implementsInterface type="flash.display::IBitmapDrawable"/>
<accessor name="blendShader" access="writeonly" type="flash.display::Shader" declaredBy="flash.display::DisplayObject"/>
<accessor name="scenes" access="readonly" type="Array" declaredBy="flash.display::MovieClip"/>
<accessor name="alpha" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="tabEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/>
<accessor name="currentFrameLabel" access="readonly" type="String" declaredBy="flash.display::MovieClip"/>
<accessor name="currentLabels" access="readonly" type="Array" declaredBy="flash.display::MovieClip"/>
<accessor name="currentLabel" access="readonly" type="String" declaredBy="flash.display::MovieClip"/>
<accessor name="name" access="readwrite" type="String" declaredBy="flash.display::DisplayObject"/>
<accessor name="height" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="buttonMode" access="readwrite" type="Boolean" declaredBy="flash.display::Sprite"/>
<accessor name="dropTarget" access="readonly" type="flash.display::DisplayObject" declaredBy="flash.display::Sprite"/>
<accessor name="hitArea" access="readwrite" type="flash.display::Sprite" declaredBy="flash.display::Sprite"/>
<accessor name="numChildren" access="readonly" type="int" declaredBy="flash.display::DisplayObjectContainer"/>
<accessor name="tabIndex" access="readwrite" type="int" declaredBy="flash.display::InteractiveObject"/>
<accessor name="scaleX" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="scaleY" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="textSnapshot" access="readonly" type="flash.text::TextSnapshot" declaredBy="flash.display::DisplayObjectContainer"/>
<accessor name="tabChildren" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObjectContainer"/>
<accessor name="focusRect" access="readwrite" type="Object" declaredBy="flash.display::InteractiveObject"/>
<accessor name="doubleClickEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/>
<accessor name="accessibilityImplementation" access="readwrite" type="flash.accessibility::AccessibilityImplementation" declaredBy="flash.display::InteractiveObject">
<metadata name="Inspectable">
<arg key="environment" value="none"/>
</metadata>
</accessor>
<accessor name="enabled" access="readwrite" type="Boolean" declaredBy="flash.display::MovieClip"/>
<accessor name="contextMenu" access="readwrite" type="flash.ui::ContextMenu" declaredBy="flash.display::InteractiveObject"/>
<accessor name="parent" access="readonly" type="flash.display::DisplayObjectContainer" declaredBy="flash.display::DisplayObject"/>
<accessor name="useHandCursor" access="readwrite" type="Boolean" declaredBy="flash.display::Sprite"/>
<accessor name="soundTransform" access="readwrite" type="flash.media::SoundTransform" declaredBy="flash.display::Sprite"/>
<accessor name="root" access="readonly" type="flash.display::DisplayObject" declaredBy="flash.display::DisplayObject"/>
<accessor name="x" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="y" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="mask" access="readwrite" type="flash.display::DisplayObject" declaredBy="flash.display::DisplayObject"/>
<accessor name="stage" access="readonly" type="flash.display::Stage" declaredBy="flash.display::DisplayObject"/>
<accessor name="z" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="visible" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObject"/>
<accessor name="mouseChildren" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObjectContainer"/>
<accessor name="scaleZ" access="readwrite" type="Number" declaredBy="flash.display::DisplayOb开发者_如何学JAVAject"/>
<accessor name="graphics" access="readonly" type="flash.display::Graphics" declaredBy="flash.display::Sprite"/>
<accessor name="mouseX" access="readonly" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="mouseY" access="readonly" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="rotation" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="rotationX" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="rotationY" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="rotationZ" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="trackAsMenu" access="readwrite" type="Boolean" declaredBy="flash.display::MovieClip"/>
<accessor name="cacheAsBitmap" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObject"/>
<accessor name="opaqueBackground" access="readwrite" type="Object" declaredBy="flash.display::DisplayObject"/>
<accessor name="scrollRect" access="readwrite" type="flash.geom::Rectangle" declaredBy="flash.display::DisplayObject"/>
<accessor name="filters" access="readwrite" type="Array" declaredBy="flash.display::DisplayObject"/>
<accessor name="blendMode" access="readwrite" type="String" declaredBy="flash.display::DisplayObject"/>
<accessor name="transform" access="readwrite" type="flash.geom::Transform" declaredBy="flash.display::DisplayObject"/>
<accessor name="scale9Grid" access="readwrite" type="flash.geom::Rectangle" declaredBy="flash.display::DisplayObject"/>
<accessor name="currentScene" access="readonly" type="flash.display::Scene" declaredBy="flash.display::MovieClip"/>
<accessor name="currentFrame" access="readonly" type="int" declaredBy="flash.display::MovieClip"/>
<accessor name="framesLoaded" access="readonly" type="int" declaredBy="flash.display::MovieClip"/>
<accessor name="totalFrames" access="readonly" type="int" declaredBy="flash.display::MovieClip"/>
<accessor name="loaderInfo" access="readonly" type="flash.display::LoaderInfo" declaredBy="flash.display::DisplayObject"/>
<accessor name="mouseEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/>
<accessor name="width" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/>
<accessor name="accessibilityProperties" access="readwrite" type="flash.accessibility::AccessibilityProperties" declaredBy="flash.display::DisplayObject"/>
<method name="globalToLocal3D" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Vector3D">
<parameter index="1" type="flash.geom::Point" optional="false"/>
</method>
<method name="play" declaredBy="flash.display::MovieClip" returnType="void"/>
<method name="local3DToGlobal" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Point">
<parameter index="1" type="flash.geom::Vector3D" optional="false"/>
</method>
<method name="addFrameScript" declaredBy="flash.display::MovieClip" returnType="void">
<metadata name="Inspectable">
<arg key="environment" value="none"/>
</metadata>
</method>
<method name="gotoAndStop" declaredBy="flash.display::MovieClip" returnType="void">
<parameter index="1" type="Object" optional="false"/>
<parameter index="2" type="String" optional="true"/>
</method>
<method name="getChildIndex" declaredBy="flash.display::DisplayObjectContainer" returnType="int">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
</method>
<method name="toString" declaredBy="flash.events::EventDispatcher" returnType="String"/>
<method name="setChildIndex" declaredBy="flash.display::DisplayObjectContainer" returnType="void">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
<parameter index="2" type="int" optional="false"/>
</method>
<method name="prevScene" declaredBy="flash.display::MovieClip" returnType="void"/>
<method name="nextScene" declaredBy="flash.display::MovieClip" returnType="void"/>
<method name="addChild" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
</method>
<method name="stop" declaredBy="flash.display::MovieClip" returnType="void"/>
<method name="addEventListener" declaredBy="flash.events::EventDispatcher" returnType="void">
<parameter index="1" type="String" optional="false"/>
<parameter index="2" type="Function" optional="false"/>
<parameter index="3" type="Boolean" optional="true"/>
<parameter index="4" type="int" optional="true"/>
<parameter index="5" type="Boolean" optional="true"/>
</method>
<method name="startDrag" declaredBy="flash.display::Sprite" returnType="void">
<parameter index="1" type="Boolean" optional="true"/>
<parameter index="2" type="flash.geom::Rectangle" optional="true"/>
</method>
<method name="stopDrag" declaredBy="flash.display::Sprite" returnType="void"/>
<method name="startTouchDrag" declaredBy="flash.display::Sprite" returnType="void">
<parameter index="1" type="int" optional="false"/>
<parameter index="2" type="Boolean" optional="true"/>
<parameter index="3" type="flash.geom::Rectangle" optional="true"/>
<metadata name="API">
<arg key="" value="667"/>
</metadata>
</method>
<method name="removeEventListener" declaredBy="flash.events::EventDispatcher" returnType="void">
<parameter index="1" type="String" optional="false"/>
<parameter index="2" type="Function" optional="false"/>
<parameter index="3" type="Boolean" optional="true"/>
</method>
<method name="stopTouchDrag" declaredBy="flash.display::Sprite" returnType="void">
<parameter index="1" type="int" optional="false"/>
<metadata name="API">
<arg key="" value="667"/>
</metadata>
</method>
<method name="willTrigger" declaredBy="flash.events::EventDispatcher" returnType="Boolean">
<parameter index="1" type="String" optional="false"/>
</method>
<method name="dispatchEvent" declaredBy="flash.events::EventDispatcher" returnType="Boolean">
<parameter index="1" type="flash.events::Event" optional="false"/>
</method>
<method name="hasEventListener" declaredBy="flash.events::EventDispatcher" returnType="Boolean">
<parameter index="1" type="String" optional="false"/>
</method>
<method name="getChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject">
<parameter index="1" type="int" optional="false"/>
</method>
<method name="getChildByName" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject">
<parameter index="1" type="String" optional="false"/>
</method>
<method name="getGUILoader" declaredBy="pim::PClient" returnType="pim.loader::PGUILoader"/>
<method name="getSessionHandler" declaredBy="pim::PClient" returnType="pim.loader::PSessionLoader"/>
<method name="getCommandHandler" declaredBy="pim::PClient" returnType="pim.loader::PCommandLoader"/>
<method name="onStart" declaredBy="pim::PClient" returnType="void"/>
<method name="swapChildrenAt" declaredBy="flash.display::DisplayObjectContainer" returnType="void">
<parameter index="1" type="int" optional="false"/>
<parameter index="2" type="int" optional="false"/>
</method>
<method name="contains" declaredBy="flash.display::DisplayObjectContainer" returnType="Boolean">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
</method>
<method name="swapChildren" declaredBy="flash.display::DisplayObjectContainer" returnType="void">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
<parameter index="2" type="flash.display::DisplayObject" optional="false"/>
</method>
<method name="addChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
<parameter index="2" type="int" optional="false"/>
</method>
<method name="removeChild" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
</method>
<method name="getObjectsUnderPoint" declaredBy="flash.display::DisplayObjectContainer" returnType="Array">
<parameter index="1" type="flash.geom::Point" optional="false"/>
</method>
<method name="areInaccessibleObjectsUnderPoint" declaredBy="flash.display::DisplayObjectContainer" returnType="Boolean">
<parameter index="1" type="flash.geom::Point" optional="false"/>
</method>
<method name="removeChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject">
<parameter index="1" type="int" optional="false"/>
</method>
<method name="globalToLocal" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Point">
<parameter index="1" type="flash.geom::Point" optional="false"/>
</method>
<method name="localToGlobal" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Point">
<parameter index="1" type="flash.geom::Point" optional="false"/>
</method>
<method name="getBounds" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Rectangle">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
</method>
<method name="getRect" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Rectangle">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
</method>
<method name="nextFrame" declaredBy="flash.display::MovieClip" returnType="void"/>
<method name="prevFrame" declaredBy="flash.display::MovieClip" returnType="void"/>
<method name="gotoAndPlay" declaredBy="flash.display::MovieClip" returnType="void">
<parameter index="1" type="Object" optional="false"/>
<parameter index="2" type="String" optional="true"/>
</method>
<method name="hitTestPoint" declaredBy="flash.display::DisplayObject" returnType="Boolean">
<parameter index="1" type="Number" optional="false"/>
<parameter index="2" type="Number" optional="false"/>
<parameter index="3" type="Boolean" optional="true"/>
</method>
<method name="hitTestObject" declaredBy="flash.display::DisplayObject" returnType="Boolean">
<parameter index="1" type="flash.display::DisplayObject" optional="false"/>
</method>
</type>
In the event that my comment is buried, I'll formalize it as a response:
Get rid of the static class reference and the quasi-singleton style access to your document class. Instead, use dependency injection like this:
public function PClient()
{
// Trace
trace("Client(): Client initiated");
// Create session handler/loader
_sessionLoader = new PSessionLoader(this);
// Create command loader
_cmdLoader = new PCommandLoader(this);
...
addChild(_guiLoader);
// Call on start
onStart();
}
Rewrite your classes like PCommandLoader to construct with a reference to a PClient, or use an interface reference to pass in PClient's public interface. Or, do this:
_cmdLoader = new PCommandLoader();
_cmdLoader.init(this);
Again, "this" is a reference to your document class object, but it need not be a PClient type variable, it could (arguably should) be an interface type.
It sounds like you've tried this approach, but without seeing the resulting code, it's difficult to be sure you've done exactly what I expect. I would not expect the 1195 error to persist with this approach, since I do it all the time.
getSessionHandler method is not defined as static
public static function getSessionHandler():PSessionLoader
This also explains why strict mode off compiles
[EDIT]
try this.
private static var instance:PClient;
public static function getInstance():PClient{
if (instance == null) {
instance = new PCLient(new PClient());
}
return instance;
}
精彩评论