Ultrashock Forums > Flash > ActionScript > OOP
App: MVC Gallery
Member Blogs
 
Post Reply | View first unread | Rating: Thread Rating: 6 votes, 4.50 average. Search this Thread | Thread Tools | Display Modes
<<|<|2|3|4|5|6|> Page 4 of 6
dan_vegas dan_vegas is offline 2007-05-06 #121 Old  
Hi CM, thanks for the offer of help. I may need to take you up on it.
I've found a work around using another MVC class for the time being (all though yours is much better!!)
I need to get a project finished quickly so will use this for the time being......just need to find some time to learn Cairngorm now!
Reply With Quote  
myIP myIP is offline myIP lives in United States 2007-05-16 #122 Old  
Codemonkey, I am still coding away on this project that I mentioned on my last post here! I am really enjoying this MVC pattern.
I have another question, in your example you used a static instance factory to attach some assets to the stage. Since some of my movieclips are mainly empty at compile time I have tried to create an emptyMovieClip in the newInstance(). However when I try to invoke a function in this instance from the ControlsView.update() it fails silently. It doesn’t seem to find the instance. But when I check the SWF using XRAY I am able to see the new emptyMovieClip on stage.
Do you know the reason behind this? Is it a limitation in the type system or am I doing something incorrect.
Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 5 Blog Entries 2007-05-16 #123 Old  
do you have classes associated with those movieclips you are attaching, and are they exported in 1st frame?
Reply With Quote  
myIP myIP is offline myIP lives in United States 2007-05-16 #124 Old  
Yes.
But I traced the instance of this class in the ControlsView class (this is where I created the instance) and it returns 'null'.
Reply With Quote  
myIP myIP is offline myIP lives in United States 2007-05-16 #125 Old  
Well, this is working for me currently;
Instead of having a ‘static instance factory’ I am using a Singleton. And when invoke a function inside of the Singleton instance, that is were I create my empty movieclip.
Perhaps I don’t know exactly what a ‘static instance factory’ is. Do you have a references on this subject you prefer?
Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 5 Blog Entries 2007-05-16 #126 Old  
It's not actually a 'written' term, it's more like a description describing what it doesn: a static method that creates instances of the class (just like a factory).

could you show me some of the code of your version that didn't seem to work?
Reply With Quote  
myIP myIP is offline myIP lives in United States 2007-05-16 #127 Old  
Last edited by Codemonkey : 2007-05-17 at 01:44.
The code below has 2 sections, the first half is code that I tried to change to make it work and the other half is the current code that is working. The createInterface method resides in the ControlView class. All other methods for both examples below are in the Header class (a class that just renders a picture and a title). Again for the first half of the code, the header variable was returning ‘null’.

ActionScript Code:
  1. //////////////////////////////////////////////////////
  2. //code that did'nt work for me
  3. //////////////////////////////////////////////////////
  4. public function createInterface(target)
  5. {
  6.     header = Header.newInstance(target, "header", this);
  7. }
  8.  
  9. public static function newInstance(target:MovieClip, name:String, controlsview:ControlsView):Header
  10. {
  11.     var depth:Number = target.getNextHighestDepth();
  12.     var header:Header =  Header(target.createEmptyMovieClip(name, depth));
  13.     header.controlsview = controlsview;
  14.     return header;
  15. }
  16.  
  17.  
  18.  
  19.  
  20.  
  21. //////////////////////////////////////////////////////
  22. //code that is currently working for me
  23. //////////////////////////////////////////////////////
  24. public function createInterface(target)
  25. {
  26.     header =  Header.getInstance();
  27.     header.createHolder(target);
  28. }
  29.  
  30. public static function getInstance():Header
  31. {
  32.     if(header == null){
  33.         header =  new Header();
  34.     }
  35.     return header;   
  36. }
  37.  
  38. public function createHolder(target:MovieClip)
  39. {
  40.     var depth = target.getNextHighestDepth();
  41.     header_mc = target.createEmptyMovieClip("header_mc", depth);
  42. }
Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 5 Blog Entries 2007-05-17 #128 Old  
A couple of things go wrong with the code that didn't work for you. I'll break it down in steps.

ActionScript Code:
  1. // 1
  2. public function createInterface(target) { // 2
  3.         header = Header.newInstance(target, "header", this);
  4. }
  5.  
  6. public static function newInstance(target:MovieClip, name:String, controlsview:ControlsView):Header {
  7.         var depth:Number = target.getNextHighestDepth();
  8.         var header:Header =  Header(target.createEmptyMovieClip(name, depth)); // 3
  9.         header.controlsview = controlsview;
  10.         return header;
  11. }
At 1. the class is extending MovieClip? If so, you already need an instance to be able to call createInterface() at 2., which is creating an instance. That doesn't make much sense to me, because you are calling that method because you want an instance of it, because you don't have one yet. So, call to createInterface should be replaced with calls to Header.newInstance().

At 3. you are creating an emptyMovieClip with just a name. That movieclip does *not* have a class associated with it, and in Flash such an instantiated movieclip doesn't finish initializing the next frame. That means you can't call its methods or use its properties right after creating it. Casting it to Header won't work because it's not a Header... it's a simple MovieClip with not class attached to it.
Reply With Quote  
myIP myIP is offline myIP lives in United States 2007-05-17 #129 Old  
Last edited by myIP : 2007-05-18 at 13:53.
Thanks again for your time, I appreciate it.
No, I just realize it doesn’t extend a movieclip. Perhaps I was thinking that header would be a header and not a Movieclip as you pointed out in the second paragraph. However can you clarify the first half of your post? I am still confused on it.

Also, now I am adding a Preloader (more of a loading indicator) to the project. I see how you did yours in the PreloadImage, with is quite beautiful. But in my project, instead of having a Preloader instance nested into a PreloadImage in author-time as you have, I would like my preloader to be nested into a movie clip dynamically. So again, I am trying to make the code below work. The preloader.attach() is called from the second half of the code in the MCLoader class( which is analogous to your PreloadImage). And the Preloader symbol is associated with the Preloader class. Also both classes extends a MovieClip.

ActionScript Code:
  1. ////////////////////////////////////////////////
  2. //in the Preloader Class
  3. ///////////////////////////////////////////////
  4. class accessories.Preloader extends MovieClip
  5. {
  6.     private var mcloader:MCLoader
  7.     private function Preloader()
  8.     {
  9.     }
  10.    
  11.     public static function attach(target:MovieClip, mcloader:MCLoader)
  12.     {
  13.        
  14.         var depth:Number = target.getNextHighestDepth();
  15.         var preloader:Preloader = Preloader(target.attachMovie("Preloader", "progress_mc", depth));
  16.         preloader.mcloader = mcloader;
  17.         return preloader;
  18.     }
  19.  
  20. .....[i]more code not shown[/i]
  21.  
  22.  
  23.  
  24.  
  25.  
  26. ////////////////////////////////////////////////
  27. //in the MCLoader Class
  28. ///////////////////////////////////////////////
  29.  
  30. preloader = Preloader.attach(targetMC, this)
Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 5 Blog Entries 2007-05-19 #130 Old  
I had to lookup PreloadImage to refresh my memory a bit. I can see I wrote the comments in an allnighter
Originally posted by myIP
Thanks again for your time, I appreciate it.
No, I just realize it doesn’t extend a movieclip. Perhaps I was thinking that header would be a header and not a Movieclip as you pointed out in the second paragraph. However can you clarify the first half of your post? I am still confused on it.
Well it seemed to me you are trying to create an instance of Header, using an instance method... which is ofcourse impossible, because you would actually already need an instance to call it on. Unless, createInterface is meant to do something else that is...

As to your second problem, I'm not sure. It seems ok, but one thing that seems odd to me is that you store a reference to MCLoader on the preloader, while in my PreloadImage, it's the other way around (except if you store it to later call a method onComplete() on MCLoader or something).
Reply With Quote  
myIP myIP is offline myIP lives in United States 2007-05-19 #131 Old  
I can see I wrote the comments in an allnighter
hehe...

Wait, do you know, createInterface() is in a different class then Header’s static newInstance()? If not I think that is where the confusion is.

For the second problem I will try to have the mcloader to have preloader property in it. Thanks for pointing that out.
Reply With Quote  
wraevn's Avatar wraevn wraevn is offline wraevn lives in United States 2007-09-06 #132 Old  
First off - thanks Codemonkey for putting this out there for us to learn from.

I'm building my first AS3 project. It happens to be an image gallery/slideshow - so I thought I'd kill 3 birds w/ one stone:

1. learn AS3
2. learn the MVC pattern
3. get paid for my learning

I built a UML diagram using Grant Skinner's gModeler (http://www.gskinner.com/gmodeler/). I based the class structure off of Codemonkey's gallery_mvc class structure. I only included inheritance (extends) relational links for readability.

I'd appreciate any comments on how I've set it up so far, if it looks like I'm headed down the right path, pitfalls I may encounter doing this way etc.

Here is a screen-cap of the UML: http://www.wraevn.com/sample/SampleUML.jpg
Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 5 Blog Entries 2007-09-07 #133 Old  
Looking good; You've established how functionality is spread among the class structure. You should also create a diagram of all the uses relationships (perhaps only the leaf classes) that clarifies how that functionality is used by whom, so you can look back at it lateron.

You may want to consider how the interface was solved in my gallery, since it deals with the quirks of AS2 and may be solved much better with AS3.0 (NavBar PreloadImage, ViewArea and the spread assets in the library etc.).
Reply With Quote  
Nutrox's Avatar Nutrox Nutrox is online now Nutrox lives in United Kingdom 1 Blog Entries 13 Creative Assets 2007-09-09 #134 Old  
I'm back, and I'm still having a problem with the idea of using the MVC pattern within a MovieClip based Flash application.

Here's the thing: The idea behind the MVC pattern (separating the data, user input, and visual layers) is perfectly valid and I have no problem with that. However, problems arise when trying to stick to the structure of the MVC pattern in Flash because of the nature of Flash's time lines and the use of class extended library assets. I'm going to try and explain what I am going on about here so bare with me.


Let's take the following situation. You have a Flash movie that contains two MovieClips in the library. The first MovieClip extends the LittleMonkey class and the second MovieClip extends the BigMonkey class, both classes contain a monkeySize property. Problem no.1 is right there, the monkeySize property is not contained in a Model (unless you consider each MovieClip to be a Model). Both LittleMonkey and BigMonkey need to change size when the user clicks on them so we will throw a few more classes into the mix.

Model class. Contains littleSound and bigSound properties (strings) which are used to play a sound depending on which monkey is clicked.

View class. A display object which is used to display the monkeys. View is given a reference to the Model.

Controller class. Registers an event listener with the stage to catch mouse clicks. Controller is given a reference to the Model.

Ok, so everything is setup and ready to go. The classes have been initialised and the monkeys have been attached to the View class (display object). The user clicks the mouse on LittleMonkey, Controller catches that event and passes a LittleMonkey reference over to Model letting Model know that LittleMonkey has been clicked. In turn Model passes the littleSound value over a sound management class and the sound is played. Great, all is fine and dandy up until this point. The only way that Model is now able to change LittleMonkey's monkeySize property is by accessing LittleMonkey directly to retrieve the value (problem no.2)... then what happens?

Does Model adjust and set the monkeySize property directly causing LittleMonkey to change size? If that happens then wouldn't LittleMonkey be acting as a Model and a View?

Does Model pass the new monkeySize value and a LittleMonkey reference to View (after a request from View) which in turn updates LittleMonkey's monkeySize property allows LittleMonkey to adjust it's own size based on the new value? Again it seems that LittleMonkey would be acting as a Model and a View.


Unless I have completely got the wrong end of the stick here it would seem that any data initially stored in a library asset class (and not in the Model) breaks the MVC pattern unless you consider each library asset to be a Model, and also consider each library asset to be a View if those assets adjust their own position or visual state in any way which a lot of components and other assets do... and don't say that none of your Flash assets ever do that.

If I'm wrong here could someone put me on the right path and explain how this situation would in fact be classed as MVC. As far as I can tell the MVC pattern cannot be used with Flash if you want to take advantage of a lot of the features and functionality that Flash offers.


Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 5 Blog Entries 2007-09-10 #135 Old  
Last edited by Codemonkey : 2007-10-01 at 11:41.
Ok, everything in Flash that has properties and a visual representation managed by Flash (ie. a MovieClip) inherently is a model with its own view. Just look at the code in UIcomponent and related classes and you'll see there is a host of properties read out by the visual representation code on an interval when the model is being 'invalidated'. The seperation is not as clear as in MVC, but it is there. That's just code you can actually change (you're not supposed to, but you can); the code behind a MovieClip is safely tucked away in Flash' engine, but you can bet it works similar.

You can't actually separate the MovieClip properties from the visual display, because, as you know, it is maintained by Flash itself. It's like any component in Flash; they are all fullblown with their own event handling for visual interactivity response (scrollbar for example). But this goes for any programming language; at some point you call upon some native API that makes the visual change happen. That doesn't mean you can't have MVC there.

Remember, this is not the same kind of model/view as in MVC, where you want to separate responsibilities with your own new codebase, using universal building blocks like MovieClips, which on its own is a native model/view, except you don't care about it. It's not violating MVC because you simply delegate the responsibility to physically update the visuals to the MovieClip, to Flash.

Originally posted by Nutrox
As far as I can tell the MVC pattern cannot be used with Flash if you want to take advantage of a lot of the features and functionality that Flash offers.
You have a point there, but this greatly depends on the granularity of how much responsibility you want to take out of flash' hands. You can for example decide to catch each and every event from a component, make it go through your controller, model and then view, which in turn updates the component (you can manage a scrollbar in its entirety this way). But you don't want this. You need to decide which features of Flash you want to be autonomous and which to manage yourself. This is the granularity I meant.

MVC is not about is not about handling aspect of every Flash object. It is about regulating responsibilities to a certain degree (granularity again here). So in the example you describe, MVC is still valid, because it does exactly that and simply utilizes isolated functionality by delegating some responsibility to it (your monkySize example).
Reply With Quote  
Nutrox's Avatar Nutrox Nutrox is online now Nutrox lives in United Kingdom 1 Blog Entries 13 Creative Assets 2007-09-10 #136 Old  
That makes sense, and makes things a lot clearer.

Just one more quick question relating to that example I posted: Would the Model or the View update the monkeySize property, and would the View or LittleMonkey handle the physical resizing of LittleMonkey?

Thanks for the reply mate.
Reply With Quote  
Codemonkey's Avatar Codemonkey Codemonkey is offline Super Moderator Codemonkey lives in Netherlands 5 Blog Entries 2007-09-10 #137 Old  
Good question. Depends.

Is the monkeySize part of the model's logic? Ask yourself this question: "If I would replace the current view I have with a completely different one, would monkeySize still exist?". It helps you to determine if the monkey is a reflection of the model like with a view or whether the monkey property is an intrinsic property to the model; the first case means the view sets the monkeySize, the latter case means the model sets the monkeySize and the view uses it to reflect this change somehow, possibly by actually having a monkey mc and setting its size.

However:
If monkeySize belongs to an object that is a subclass of MovieClip it becomes a different scenario, because the model shouldn't be allowed to set its properties that way. Remember, the point of a model and a view is to seperate any direct link allowing you to use a different view, multiple views or no views at all. Not any of them are garantueed to have the monkey movieclip with this property on stage, which would mean the model could have some kind of invalid object with a monkeySize property and the point of seperation that makes MVC what it is completely missed. really the model should be completely isolated from the stage and any of the clips in it.
Reply With Quote  
Nutrox's Avatar Nutrox Nutrox is online now Nutrox lives in United Kingdom 1 Blog Entries 13 Creative Assets 2007-09-10 #138 Old