Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Best practice for class communication

LEGEND ,
Apr 12, 2011 Apr 12, 2011

Hi all,

I'm trying to get my head around how to communicate through scope. I hope/think this is a pretty basic question but I'm pretty stuck in the AS2 mentality.

To make a simple example, say I have 2 classes, ClassA and ClassB. ClassA loads an instance of ClassB:

package

{

  public class ClassA

  {

     private var _classB:ClassB;


     public function ClassA

     {

         _classB:ClassB = new ClassB();

     }

  }


  class ClassB {} 

}

Now I want ClassB to communicate with ClassA. It's easy for ClassA to invoke a method on ClassB, _classB.somePublicMethod();, but how does ClassB communicate back up to ClassA?

I know one method is making a custom event and adding a listenor in ClassA that binds to ClassB while having ClassB dispatch that custom event. Is there any easier way I'm not aware of? Some kind of parent/super/etc method of talking to the class that instantiated ClassB?

edit:

Incase it matters or changes the approach someone would recommend, what I'm trying to do is make some touchscreen-esque scrolling functionality. The same stuff built into any smartphone. If you touch the screen and drag the touchscreen in certain contexts knows you want to scroll the information you're looking at. If you just tap something however it knows that you want to interact with what you tapped. That's what I'm trying to figure out how to do in as3.

I have a touchscreen and I have navigation that doesn't fit all on the same screen. I'm trying to allow the user to scroll the navigation up/down to see all of the options but also let the user tap a nav item to let them select it. So I'm making a reusable class that's pretty abstract on the concept of allowing me to point to an object and say this object can be clicked, but if the user drags they intend to scroll a display.

The actual end use of this is, as a personal learning exercise, I'm trying to duplicate a doodle/paint program my 3yr old son has in flash. He has a touchscreen laptop and he can scroll through a long list of artwork he can touch and it paints it on the screen. I'm trying to mimic that functionality where I try to determine if someone is trying to drag/scroll a list or select something in the list.

That said, in that context ClassA is the painting app and ClassB is a reuable class that's applied to a navigation area whose job is to inform ClassA if the user intends to drag or select something. I make my nav items in ClassA and then instantiate ClassB. Because I need to 'wait' until ClassB tells ClassA what the user is doing, it's not a return value type of situation. I have to wait for ClassB to figure out if the person is trying to click or drag, then communicate that back to ClassA so it knows how to handle it.

TOPICS
ActionScript
814
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Apr 12, 2011 Apr 12, 2011

try 'parent'

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Apr 13, 2011 Apr 13, 2011

One way you can do it is by making sure that your object B has a reference to your object A. something like this:

package

{

  public class ClassA

  {

     private var _classB:ClassB;


     public function ClassA

     {

         _classB:ClassB = new ClassB(this);

     }

  }


  class ClassB {

     private var _a:A;

     public function ClassB(a:ClassA){

        _a=a;

    }


now - this works fine but creates circular references which are generally a sign of bad design. however - some design patterns even require circular references and in some cases they make complete sense.

Another, clean way is as you mentioned to use events.

Another way is to use the 'Function' object. You can pass a function from objectA to objectB by using the 'Function" class. However - if you need to pass memberfunctions (this is, functions that are not static) your object B still needs a reference to object A (because it needs to pass a pointer to object A as the first argument when calling the function).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2011 Apr 13, 2011

Definitely use Event. Full stop

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Apr 13, 2011 Apr 13, 2011

Definitely use Event. Full stop

wouldn't agree fully to that. Events make your life easy while programming and they are also very flexible - but they make your life hard if you try to understand code or to change something about a system. If too much in a system is eventdriven, bugs may get very hard to track and making changes to the system may get more difficult (although events have the advantage that when changing something, less classes need to be touched).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 13, 2011 Apr 13, 2011

Thanks for the tips!

I figured the event was going to be it. Seems cleanest but I'm so used to the old hacky ways of AS2 where you can pretty much do everything in 19 ways, I'm just looking for the most advisably flexible method.

Is it overkill to do a custom event? Is it advisable to use the bubble and bind a mouse click to that classes instance overall or is that even possible? I'm thinking that because classA has containers that have classB elements in, will clicks bubble from B back to A with reliable information on what item was clicked in B? or just what got clicked in A? (does this even make sense? haha)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2011 Apr 13, 2011

There are many ways and there are no single "correct" way, but I would capture the MouseEvents in B and dispatch a custom Event, which A listens.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 13, 2011 Apr 13, 2011
LATEST

I will definitely use an event. I've never made a custom event but the top google search (always a blog) has good comments on the approach so I'm using this approach at it.

Anyone think that approach is bad/outdated/refineable?

edit:

Man, it's just one of those days. This is all working fine and well but I can honestly say in no project have I ever needed to make a custom event and I've been using flash since the early 90s with nothing but telltarget.....

I do have one question, because I (admittedly) spent a freaking hour (*sigh*) on trying to figure out why I'd dispatch an event and it wasn't picked up.

A quick psuedo example:

package{

  public class ClassA {

    private var _classB:ClassB = new ClassB();


    public function ClassA() {

        this.addEventListener(CustomEvent.WHATEVER, _doSomething);

    }


    // _doSomething func......

  }


  class ClassB {

    parent.dispatchEvent(CustomEvent(CustomEvent.WHATEVER, { foo:"bar" }));

  }


  class CustomEvent extends Event

  {

    public static const WHATEVER:String = "whatever";

    public function CustomEvent(type:String, params:Object, bubbles:Boolean = false, cancelable:Boolean = false)  {

            super(type, bubbles, cancelable);
            this.params = params;
    }


     // clone/tostring overrides.....

  }

}

Is it better symantics to do it that way with parent.dispatchEvent() or should I have done _classB.addEventListener(...) and then in ClassB I this.dispatchEvent()?

What screwed me up for an hour was I was just this.dispatchEvent() instead of parent.dispatchEvent() and the event was never seen in the parent. It (hindsight) makes obvious sense I need to dispatch the event in the scope of whatever is looking for the event but somehow that wasn't really explained to me in the tutorials (like I linked). Their examples made the event, listener and dispatcher in the same place. I'm dispatching the event from a separate class so it didn't occur to me I needed to send that event back to the scope the listener existed in... Oy.. vey....

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines