Using Design Patterns with FP


(Thawfeek_Yahya) #1

Hi,

I am trying to make a game using Design Patterns. Currently I am using factory method pattern to create my UI items, But i am getting an Error on Entity Class at

“_class = Class(getDefinitionByName(getQualifiedClassName(this)));” Line no : 75

My original UI Class items which extends Entity ,which i have set it access modifier to internal, then using an Creator class which is Public within the same package i am creating new instance of UI item.As because the UI class’s access modifier is made to internal i am getting error at the above line.

Is there any way to create instance of UI Class , without making its access modifier to public ?


(azrafe7) #2

Are you saying that changing the access to public fixes it?

By the way showing some minimal code to reproduce the error should help in clarify things.


(Thawfeek_Yahya) #3

Hey, Sorry for the late reply,.

And here’s my code…

//Concrete Class

package com.thawfeek.skydefender.ui.uielements {

     import flash.geom.Point;
     import net.flashpunk.Entity;
     import net.flashpunk.FP;

internal class UIMsgBox extends Entity implements IUserInterfaceItem {


    private var msgTxt:Text;

    public function UIMsgBox(msg:String,pos:Point) {
        msgTxt = new Text(msg);
        this.x = pos.x;
        this.y = pos.y;
        msgTxt.width = 300;
        msgTxt.wordWrap = true;
//        msgTxt.x = (icon.width >> 1 - titleText.textWidth >> 1);
        msgTxt.text = msg;
    }

    public function show():void {
        FP.world.add(this);
    }

    public function hide():void {
        FP.world.remove(this);
    }

    public function enable():void {

    }

    public function disable():void {
    }

    public function setText(val:String):void {
        msgTxt.text = val;
    }

    public function setPosition(val:Point):void {
        this.x = val.x;
        this.y = val.y;
    }

//Creator Class

package com.thawfeek.skydefender.ui.uielements {

public class MsgBoxCreator {

public function getMsgBox():IUserInterfaceItem {

return new UIMsgBox("Msg",new Point());
}
}
}

//Main Class

package com.thawfeek.skydefender.ui {
import com.thawfeek.skydefender.ui.uielements.IUserInterfaceItem;
import com.thawfeek.skydefender.ui.uielements.UIInfo;

import net.flashpunk.graphics.Image;

public class UICreator {

    public function UICreator() {
    }

    public static function createInfoUI(graphic:Image,title:String):IUserInterfaceItem {
        var creator:MsgBoxCreator =  new MsgBoxCreator();
        var uiInfoItem:IUserInterfaceItem = creator.getMsgBox();
        return uiInfoItem;
    }
}
}

The code is messy. But this what i am trying to do .

Concrete Class & Creator Class were in one package ( com.thawfeek.skydefender.ui.uielements )

And the Main Class is at ( com.thawfeek.skydefender.ui ) package .

And now when i use this Main Class , i get that error !!


(Helios) #4

it looks like your MsgBoxCreator class has no constructor, nor does it have any static classes. So in the line where you are calling new MsgBoxCreator(), main has no constructor to apply

Is your idea to layer a singleton pattern on your factory pattern? That’s what I’m doing in my game. If so, there’s a very specific process for implementing singletons in actionscript.


(Thawfeek_Yahya) #5

At this line i am calling the the new instance of MsgBoxCreator at Main Class, Even Though i don’t have a constructor in MsgBoxCreator, It should be called implicitly !.

What i doubt is this error happens at the line at Entity Class’s constructor

_class = Class(getDefinitionByName(getQualifiedClassName(this)));" Line no : 75

because here the class is created by getDefinitionByName() method, and because of the original class’s access modifier made to internal , i think its throwing error !

Any Clues ??

Thanks


(Ultima2876) #6

Why not try making the class public? I don’t think internal can be used the way you are trying to use it (internal is for properties only).


(Helios) #7

He wants it to be internal because he wants to enforce the factory pattern. He doesn’t want to have the capability to instantiate the class outside of the creator.

That I understand. However, like I said, Thawfeek-Yahya, flash is very picky about making things public. You have to use tricks like the one I linked to enforce compile time checking of pattern enforcing techniques.

edit: don’t get me wrong. it may be possible to use internal in that way. I’m just saying, the beauty of patterns is allowing for flexible implementations for different languages. However, if you do find a way to make the internal approach work, let me know.


(Thawfeek_Yahya) #8

@Helios, Hey thanks for the reply, Looks like i have to dig deeper in code, . Sure , I will let guys know if i get lucky.!!


(Ultima2876) #9

Yeah, disregard what I said. I’ve been javascripting for a while and seem to be losing touch on AS3 - classes can indeed be internal, and this is the default.

Maybe give it an internal constructor instead of making the class itself internal?


(Jacob Albano) #10

Constructors in AS3 can only be public. It’s too bad; that’s the best approach for this type of problem.


(Ultima2876) #11

Aaah yeah, that must be where I was getting mixed up!


(Thawfeek_Yahya) #12

Hi folks,

I tried to do this with internal class but no luck, i had to follow the singleton technique . what i did is that , i created a Dummy Class (internal) inside my ui.elements package and in the creator class (which is public), when calling the Creator Class,The Dummy Class should be passed as the first argument and thus enforcing the factory method pattern.

here’s the code

//Main Class

package com.thawfeek.skydefender.ui.uielements {

import flash.geom.
import net.flashpunk.graphics.Image;

public class UICreator {

    public function UICreator() {
    }

    public static function createInfoUI(graphic:Image,title:String):IUserInterfaceItem {
        var uiInfoItem:IUserInterfaceItem = new UIInfo(new Dummy(),graphic,title);
        return uiInfoItem;
    }

    public static function createMsgBoxUI(text:String, point:Point):IUserInterfaceItem {
        return new UIMsgBox(new Dummy(),text,point);
    }
}
}