Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: ActionScript Developers Guide to PureMVC  (Read 13573 times)
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« on: December 28, 2011, 08:16:48 »

I started reading the e-book a few days ago, and as I usually do with other books as well, I skipped the Preface, anxious to get to the core of the matter. But I was also curious to see how the application works and spent a lot of time going through the code, then running the app and clicking all the buttons before really knowing what they were supposed to do. This way I found a little bug and later a temporarily fix for it. Looking at the code, without reading the accompanying explanations from the book, allowed me to get an uninfluenced first impression: well structured (good hierarchy of packages), self explanatory variables, methods, classes, and packages names, helpful comments throughout the code.
I got a general idea of the responsibilities of the classes, and even though the code is pretty complex, I could identify the repeating behavioural patterns or the intended functionality.
 
I was glad that I found something not working as expected, because, in trying to find the bug, I got involved in the details of the code, which in turn, allowed me to better understand the logic behind some classes and methods and the relations/collaborations between them. I switched from a passive observer to an active investigator (err.. something like that)
Then, when I continued reading the book I was pleasantly surprised to find that each class discussed in the book was accompanied by a description of its responsibilities and collaborations! This way I could easily verify my understanding of the code. Im not done reading yet, but with every page in the book the haze keeps dispersing and the contours of the app are becoming increasingly clear. From what Ive seen so far in the book I like that the main focus is put on

a.   the boundaries of the application , domain logic and views
b.   the process of planning,  architecting the app, the steps described
c.   responsibilities and collaborations of a classes

Because of that it is an almost framework-independent approach, which is a really good thing, especially in the light of today's rapid changes in our world of software development or technology in general.


My initial intention was to share my opinions first after reading the entire book. But yesterday, when I wanted to continue reading it, instead of going to chapter 5, I started from the beginning, absent mindedly flipping through pages, and...well.. no one saw me, but Im sure that the huge surprise made me look utterly funny when I stumbled upon the mention under Collaborations!
First of all, I want to thank you, Cliff! I know it wasnt easy to decide who to put on that list or rather who to omit. I dont think that what I did or said in here could be considered as a contribution at all. There are others whove contributed more substantially to the framework or the community, so what I did was infinitesimally small in comparison with their work. Since yesterday Im having mixed feelings of joy and a kind of guilt at the same time, because I think I didnt really deserve to be mentioned.
So, to correct the situation let me put it in another light: in an open source project like this everyone is part of the project. Every single answer, every demo, example, shared code, and/or utility is a contribution to the project.
Even every question asked on a forum, even if it has been asked before zillions of times, is a valuable resource for learning, or for identifying the weakness of a project, or for seeing a large variety of use cases, or just for keeping your mind alert and fresh, in a state that Id like to call Beginners Mind (keeping oneself free from preconceived ideas, open to dialog).
In this light, mentioning someone like me as a contributor is a very considerate and compassionate gesture, and it is a proof of fairness. But I want to take it rather symbolic than personal, meaning that I represent all the others users who thought their contributions were insignificant. In fact it is a matter of interweaved efforts/actions/nodes where the single nodes can weigh more or less, but without them there wouldnt be a net.
In other words:
-   an open source project is a collaboration of many minds, more or less great, more or less perceptible
-   contributing to an open source project in any form or way is rewarding, the more so when you dont expect it or when your actions werent driven by it
-   the process of learning goes two ways: from the advanced users to the beginners and back

I could continue with my interpretations about open source projects, but Im aware of the fact that such a discourse sounds a little pathetic ;-)

So, Id better go back to talking about the bugs, of course only if you want me to and if this forum is the right place for it. As I said I found a solution, not sure yet if it is the right one, because Im still in the process of understanding the code and its overall logic and maybe later Ill see another way to achieve the same. Let me know if you want to see it (its a gist on github)


Cheers,
Ondina
Logged

~ Ondina ~
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: December 28, 2011, 08:51:10 »

Hi Ondina,

Glad to hear you're enjoying the book. Please do post about any bugs and fixes you might have for them.

Also, it would be helpful when you finish the book if you could post a short review on the O'Reilly or Amazon site for the book.

As to the value of your input on the project, you contributed significantly to the last release of the DesktopCitizen utility; a level of effort worthy of mention, I thought. Doesn't matter if that was done through the forums, really, since the end result of your efforts ended up improving the utility for everyone!

Cheers,
-=Cliff>
Logged
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #2 on: December 29, 2011, 06:35:18 »

Thanks for the reassurance, Cliff!

Ok, I will post a review for the book, when Im done reading it.

The Bugs:

1.
RangeError: Error #1125: The index -1 is out of range 0.
at ...\StoryArchitect\src\com\futurescale\sa\controller\command\story\EditStoryCommand.as:42]

In Details/ItemInfo View: If you keep deleting all the items until just the parent (Story) remains, then you go on and save the changes, when you try to edit the story again it throws an error like the one above. 
Thats the case of a Simple Story, where a Scene is the direct descendant of a Story. story.scenes.length is 0, therefore story.scenes.length-1 is -1. And thats because the xml file contains no Scenes, just a Cast and a Milieu.

The same happens with a Normal and/or a Complex Story, but this time the arrays in question are story.chapters and story.parts, the first descendants of a Story that EditStoryCommand is trying to set.

- So my first workaround was concentrated on EditStoryCommand and I simply checked the length of the arrays and if it was 0 I added the missing parts to their parents.
For a Simple Story it would look like this:
if (story.scenes.length == 0)
{
scene=new SceneVO();
story.addScene(scene);
}
else
{
scene=story.scenes[story.scenes.length - 1];
}
Here the modified code for EditStoryCommand: https://gist.github.com/1524621

- Then I saw that StoryVO has these methods: getNewScene(),getNewChapter(),getNewPart() and I used them like this:
https://gist.github.com/1533524
It solves the problem, but it doesnt feel quite right.

When you create new stories the flow looks like this:
Simple
StoryVO.getNewScene()
SceneVO.getNewDraft()
SceneVO.addDraft(draft)
StoryVO.addScene(scene)

Normal
StoryVO.getNewChapter()
ChapterVO.getNewScene()
SceneVO.getNewDraft()
SceneVO.addDraft(draft)
ChapterVO.addScene(scene)
StoryVO.addChapter(chapter)

Complex
StoryVO.getNewPart()
PartVO.getNewChapter()
ChapterVO.getNewScene()
SceneVO.getNewDraft()
SceneVO.addDraft(draft)
ChapterVO.addScene(scene)
PartVO.addChapter(chapter)
StoryVO.addPart(part)

So it should be enough to call
scene=story.getNewScene();when story.scenes.length == 0  for a simple story,

chapter=story.getNewChapter (); when story.chapters.length == 0 for a normal story,

or part=story.getNewPart(); when story.parts.length == 0 for a complex story

like when you create a new Story.
But it doesnt work, and right now I cant see why. As I said, Im not familiar enough with the code yet, so I just modified EditStoryCommand to make it work .

Anyway, I think that I made the changes in the wrong class.
Maybe the real solution would be to prevent saving an empty Story in the first place?  Does it make sense to have a Story with no Scene or Chapter or Part, depending on the type of the Story?

I will investigate this chain:
ItemInfo.deleteItem()
DeleteItemCommand
StoryVO.deletePart
StoryTile.changeStorySelection(selection)
StoryTile.removeTiles()
StoryTile.createTiles()

to see what happens in the VOs after deleting an item.

Im sure there is a very simple and more elegant solution to this and Im curious to hear it from you.

2.
Then there were the following situations, which I cant reproduce anymore right now:
a. a totally empty XML file has been saved on the hard disk. If you try to edit it, a new Story, called Story 0, gets created and the xml file is empty. Now there are 2 empty stories, which cannot be deleted or edited (RTE)
Also in StoryProxy. loadStory() storyStub.uid is the id listed in index.xml while story.uid is different (a new uid). I dont understand the logic in there yet.
Quick and dirty solution(no idea if it wont produce other bugs elsewhere):
if (storyStub.uid == story.uid)
cacheProxy=new Proxy(story.uid, story);
else
cacheProxy=new Proxy(storyStub.uid, storyStub);

b. the story/index.xml contains stories that dont exist in that folder. Of course, when you try to load such a story it throws an error.
So my quick and dirty workaround was this:
AbstractProxy
private function readFile(file:File, voStub:ValueObject=null):XML
{
var stream:FileStream=new FileStream();
var xml:XML=new XML();
if (file.exists)
{
stream.open(file, FileMode.READ);
xml=XML(stream.readUTFBytes(stream.bytesAvailable));
stream.close();
}
return xml;
}
I think something goes wrong with the updating of the index file (synchronisation between the list of stories in the index and the files on disk) 

Im sorry that I cant provide more accurate info at this stage. I know that my solutions arent good, and they only show how limited my understanding of the code is, but at least youll have some hints at the vulnerable parts of the app.

Ondina
Logged

~ Ondina ~
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: December 29, 2011, 09:21:16 »

Wow! Thanks for the massive Q/A efforts.

As the book carries you through the 'first iteration' of development, it did not include any Q/A hammering. I'm planning to continue with development of the app, so this is some great feedback. I've not yet run into any of these problems, but then, the developer should rarely be in charge of Q/A :)

I had a look at your gist. I see what you mean about it working but not 'feeling right'. I'd still like to keep the building of the default story inside the VOs themselves if possible, but it may not be. As possible has been done to encapsulate the responsibility for data integrity in the VOs themselves, but ultimately it may require logic like this in a Command.

Hoping to have some time this weekend to bang around on the app, so this will be a handy post to come back to .

Thanks again,
-=Cliff>
Logged
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #4 on: December 29, 2011, 09:22:41 »

Last changes: https://gist.github.com/1534767

In case the xml file for this story is empty or if the xml file doesnt exist storyStub.type is null
if (!storyStub.type)
   populateEmptyStory(storyStub);
What do you think? Better?
Logged

~ Ondina ~
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #5 on: December 29, 2011, 09:32:27 »

Youre welcome, Cliff :)
I agree, the encapsulation should be preserved.
I really should read the book before making any other changes.
It will take me a while though.

Cheers,
Ondina
Logged

~ Ondina ~
normc
Newbie
*
Posts: 5


View Profile Email
« Reply #6 on: February 14, 2012, 12:22:40 »

Greetings,
I've downloaded the companion source code from http://examples.oreilly.com/0636920022459/  (the zip extracts to 3 folders: StoryArchitect, StoryArchitectModel, StoryArchitectTests)

I had these issues:
-  Unzipping on Win7: got several errors due to path names being too long. Used WinRar instead.
-  After importing the StoryArchitect project into Flex Builder 3 (and using 4.5 sdk), I had an error regarding missing StoryArchitectModel.swc. That file did not come with the download.
-  As a workaround, I copied the model folder from folder StoryArchitectModel to StoryArchitect, and also needed to copy over PrepareModelCommand.as

Now I am stuck with an error relating to NoteVO when it's a Vector type. Please see attached.

Running the app would really help in understanding the code, rather than trying to imagine how the app flows. Thanks.

Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #7 on: February 14, 2012, 12:50:33 »

StoryArchitect and StoryArchitectModel is a separate projects. You need to set up StoryArchitectModel as a Flex Library project, and in StoryArchitect, under Project->Properties->Flex Build Path, add the  StoryArchitectModel project.

As for the error, the NoteVO is present in the StoryArchitectModel project, is it possible you deleted it when you merged the model lib into the application project? It's possible that Flex Builder failed to include it in the build. Go into Project->Properties->Flex Build Path and make sure all the source classes are selected. Actually, I'd suggest deleting the merged project altogether and creating the two projects as I described above instead.

BTW, in the book we start out with a single project, but in Advanced Model Topics, we split it into the separate project so that the unit tests and the application can both use the model. On page 189 of the book, this process is described, and you see what you're supposed to end up with in your workspace after that refactor, which is what you've downloaded from O'Reilly.

Cheers,
-=Cliff>
« Last Edit: February 14, 2012, 12:54:34 by puremvc » Logged
Pages: [1]
Print