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

Show Posts

* | |

  Show Posts
Pages: [1]
1  PureMVC Manifold / Multicore Version / Re: puremvc with requirejs and or nodejs. on: November 10, 2012, 07:10:09
Since this was created back in June, I think the syntax was using the 1.0 API. Here's some updates for how to add puremvc as a dependency if you are using the requireJS 2.0 API:

If you have the following directory structure:


-+
  |- index.html
  +- js/
  |   +- app/
  |   |   |- controller
  |   |   |- model
  |   |   |- view
  |   |   |- ApplicationFacade.js
  |   |
  |   +- lib/
  |   |   |- require.js
  |   |   |- puremvc.js
  |   |
  |   |- app.js
     




Put the following script tag in your index.html

index.html
:
<script data-main="js/app.js" src="js/lib/require.js" type="text/javascript"></script>

js/app.js
:

requirejs.config({
// By default load any module IDs from js/lib
baseUrl: 'js/lib',
// except, if the module ID starts with "app",
// load it from the js/app directory. paths
// config is relative to the baseUrl, and
// never includes a ".js" extension since
// the paths config could be for a directory.
paths: {
app: '../app'
},
// or if the module begins with "puremvc"
// we will use the global "puremvc" variable
// as the location of the module
shim: {
'puremvc': {
deps: [],
exports: 'puremvc'
}
}
});

// Start the main app logic.
requirejs(
['app/ApplicationFacade'],
function(ApplicationFacade)
{
var app = ApplicationFacade.getInstance(ApplicationFacade.NAME);
app.startup();
}
);


The js/app/ApplicationFacade.js file remains unchanged. Notice that the only real difference is that the shim is now built-in to requireJS. There is no need to wrap prototype as a module since we can setup support for it in the config. Just a simpler way to include other libraries that don't conform to the requireJS pattern for defining modules.

Also, on a side note, these "shim" modules can also have dependencies that they require loaded with the
:
deps: [], property. More info can be found here:

http://requirejs.org/docs/api.html#config-shim

2  Announcements and General Discussion / Architecture / Re: JavaScript HTML5 Game on: November 04, 2012, 03:30:16
You're right, sharing a proxy reference between modules is not the good approach. But sharing data as you thought in the second part of your paragraph may be the right.

You should definitely not pass MVC actors between cores. That defeats the concept of modularity entirely. No core/module should know anything about the contents of another.

Yea, I began to realize that almost immediately after I posted, not a very good idea at all.

A good intermediary solution to have something neat and at minimum cost is simply to use a common proxy class that each module will instantiate in its own environment (not the same instance shared).

Yes!!! So I began reading up more on Proxies and I realized I had been thinking of them all wrong. I have been doing a lot of data management INSIDE the proxies. So, in effect, they had become heavy and data centric when in reality they simply need to expose common methods to access and manipulate data that is managed and stored elsewhere. I don't know how this fact was not realized until now, even the name PROXY should convey the image of a middleman who simply routes the data to and from it's source and destination and doesn't store the data locally.

I have begun converting my ResourceProxy into a common Proxy class that can be instantiated in any module and the ResourceManager is now following the multiton pattern (previously it was just a common class) so that I can retrieve the correct instance of it in every ResourceProxy I create. No need to send requests outside of a module, the module now can have everything it needs internally to retrieve sounds, animations and data.

However, you can always have a 'common' package that multiple cores share. Usually this is done to provide base classes that modules will sublclass and use internally. But you never have Core A referencing Core B's internal MVC actors.

I do have a "common" package for all of my VOs and shared view components. However, is my plan to place the ResourceProxy and DataProxy in the "common" package acceptable architecturally? The shell app will be responsible for initializing the ResourceManager and DataManager and then the two proxies will simply be used by any module that needs to retrieve data or resources.

Passing Value Objects
Just as with the MVC separation, at the modular level, it's often a good idea to separate the service interactions into a separate core/module. A request object might be passed to such a module, which would interpret and act on the request, sending back a message with a value object returned from the service.

I feel like using the pipeline to send requests for resources and data might be a bit to much for this application (it's really just a single player puzzle game for mobile devices). I can totally see how isolating services to a module adds another layer of portability to the application. With the asynchronous behavior of pipes, you can easily begin to add modules for server communication and the modules will have no idea whether they are being used in a multiplayer game or a local game.

I do plan on implementing the passing of ViewComponents to the shell, thanks for helping me clarify how that is done properly. It makes sense that the module informs the shell when and how it wishes to be displayed. I was kinda stuck envisioning how to retrieve the correct view component from the module and how to tell if a module needs display. So here's a basic step-by-step procedure for adding a new module and having it update the shell display, please let me know if it makes sense.

#1 - The shell is told to add a new module. (this could be coming as a pipe message from a different module for exmaple)
#2 - The shell creates the module instance.
#3 - The shell calls the startup function on the module's facade, this preps the modules models and views.
#4 - The shell connects the module to the standard input and output pipes.
#5 - The shell sends the module a message to inform it that it's ready for communication.
#6 - The module then decides if it wants to take control of the main display. If it does, it sends a message to the shell passing itself as a view component. (not the facade, but the main view component of the module).
#7 - The shell then performs the necessary transition (perhaps specified in the previous message) removing the old view component and inserting the new one.


Tekool and Cliff, you guys rock! If either of you have iOS devices, I would absolutely love to have you included in my BETA. I will PM you both with a link to signup for my TestFlight team. Thanks!

Oh and here's a link to the Facebook site for the game:

http://www.facebook.com/CutieCrush
3  PureMVC Manifold / Multicore Version / Re: Give us feedback on the native port's simple 'class inheritance' facility on: November 03, 2012, 12:58:11
I too ran into the same issue as benjiaminid. When overriding a method, I wanted/needed to be able to call the parent method. In AS3 this is accomplished by using the super keyword when inside a overridden method.

PrototypeJS allows me to do something similar with the $super keyword, so I decided to adjust the native port to support Prototype's implementation of inheritance. The only adjustment needed was to replace all of the strings ".constructor" with ".initialize". This allows for the default constructor to be found by PrototypeJS so that it can keep track of the super class.

Say, for example, I have a BaseMediator that is going to be extended by other mediators.

BaseMediator:
:
var BaseMediator = Class.create(
  puremvc.Mediator,
  {
    initialize: function($super, name, viewComponent)
    {
      $super(name, viewComponent);
    },
   
    listNotificationInterests: function()
    {
      return [
        ApplicationFacade.NOTIFICATION_A
      ];
    },
   
    handleNotification: function(notification)
    {
      switch(notification.getName()) {
        case ApplicationFacade.NOTIFICATION_A:
          // do stuff for A
          break;
      }
    }
  }
);

ExtendedMediator:
:
var ExtendedMediator = Class.create(
  BaseMediator,
  {
    initialize: function($super, name, viewComponent)
    {
      $super(name, viewComponent);
    },
   
    listNotificationInterests: function($super)
    {
      var interests = $super();
      interests.push(ApplicationFacade.NOTIFICATION_B);
      return interests;
    },
   
    handleNotification: function($super, notification)
    {
      switch(notification.getName()) {
        case ApplicationFacade.NOTIFICATION_B:
          // do stuff for B
          break;
        default:
          // let the super class handle it
          $super(notification);
          break;
      }
    }
  }
);
ExtendedMediator.NAME = "ExtendedMediator";

I'm sure there are other frameworks out there that allow you to do something similar, however, I'm most familiar with Prototype inheritance so it works for me.

Does anyone know if the NativePort is going to support something similar to the $super keyword ever?
4  Announcements and General Discussion / Architecture / Re: JavaScript HTML5 Game on: November 03, 2012, 11:51:33
Alright guys, I'm very close to getting this new "multicore" version up and running! Here are some details on my new implementation so far:

Shell Core:

The Shell Core behaves as the "mother brain" of the application. All modules are registered and piped in to the shell. The shell also handles the "Shell" view which is a basically a class that wraps a div element where the HTML5 application resides. The shell also manages most of the proxies. For example, it has a "DataProxy" which is used to retrieve level data from JSON files and user data from local storage. It also has a "ResourceProxy" which loads in sprite, animation and sound resources from a "ResourceManager".

Another feature I plan on adding to the shell is a transition system. The purpose of the transition system is to provide various ways to visually transition between module cores that have control over the display. The plan is to code several transitions such as "fade to black", "fade to white", "slide in" etc. These transitions will be called after a new display module has been initialized and is ready to take over.

Module Cores:

Module Cores can be any piece of the game that I want to isolate and modularize. For example, I am planning on modularizing my menu system, this includes the following views: "Title", "StageSelect", "LevelSelect". All of the business logic for these views will be contained in the "Menu Module". Any endpoints of the module will communicate with the shell core to transition the application to the next module. In the "Title" view, I could have a button that controls the application settings. If the user clicks on the settings button, I would then communicate with the shell that I wish to transition to the "Settings Module." The "Settings Module" will then be constructed, the transition applied and the old module will be destructed.

My current plan is to only allow one module to maintain control of the main display at a time. However, this doesn't mean that we can only have one module loaded at a time. It should be possible to have modules that do not have a main display to be loaded in as well. For example, I might want to implement a "Achievement Module" that does not require control over the display, but can inject view elements to a layer on top of the main display.

TBD:

So far this plan has been working out for me without much issue. I now have a basic understanding of how to construct and destruct pipes, however, I still might need some guidance on what constitutes a proper pipe message. I understand that requests for module creation, transition and destruction are definitely viable pipe messages, but what about requests for ProxyData? Due to the one way communication of pipes, I feel like requesting for level data or resources through the pipeline might not be the best way to go.

In my previous application design, requests for data and resources happened in the view construction process. I had a command for each view that would retrieve all of the data that the view needs. For example, the "LoadStageSelectCommand" requested stage/level VOs directly from the "DataProxy". Since the "StageSelect" view is now in it's own module (Menu Module) and the "DataProxy" is managed by the shell, what would be the best way to access the data without breaking encapsulation?

One solution I came up with was providing a way for each module to define the proxies it wants a reference to from the shell. When the shell creates the module, it can pass these proxies to the module. I could then treat these proxies almost as an external API that I could access from each module, perhaps having a proxy to abstract them from the module. I kinda feel like this type of a solution causes to much interdependence between a module and the shell. Any thoughts?
5  Announcements and General Discussion / Architecture / Re: JavaScript HTML5 Game on: October 30, 2012, 10:35:17
Hey Cliff,

Thanks for the tips so far. I have already extracted most of my display code into a stand alone library kinda similar to flash. I have display objects and event dispatching that works nicely in canvas now.

My next step it extracting all the view code into a stand alone core. I am hung up a bit on the communication between cores. Are there any examples of communication between cores in JavaScript? I looked into pipes a little bit but I was unable to find any concrete examples.
6  Announcements and General Discussion / Architecture / JavaScript HTML5 Game on: October 26, 2012, 07:24:48
Hello All,

I have been creeping on this forum for the past couple weeks. I'm not a beginner to PureMVC, but I still have some more learning to do. Before I go into my questions, I should probably explain where I am coming from.

Over the past few six months or so i have been gradually iterating my side project, a HTML5 mobile game with PhoneGap. When I first setup the project, the NativeJS port wasn't available and it wasn't Multicore. I ended up using the PrototypeJS port since I was already familiar with classes and inheritance in PrototypeJS. Right now, my project is nearly at BETA. It utilizes the Canvas API in HTML5 and runs very nicely at 60 FPS.

I am looking to do some refactoring and utilize the Multicore NativeJS, and possibly a framework that supports namespacing. I have used Multicore in AS3, but not in Javascript. I also only have experience with using interfaces for Multicore communication, not pipes. OK on to the questions!

#1 - Should I abstract the view rendering of the application to a stand alone core so that I can switch it out as needed (for ex: different rendering cores for different platforms)? For this project my current target is iOS with future support for Android. Since I was using a single core, I ended up doing some dynamic view component loading. Basically I have a ViewProxy that will load in JS files dynamically as needed. For Android targets, I will provide different view components based upon the device resolution. With this approach I could create high-res iPad versions of the app as well that have a completely different layout than other versions.

#2 - Should I also move my game engine to a separate core? I envision this core containing all of the game simulation data and accepting input and other data from the user and pushing events to the display core. Currently the game display objects hold references to the game objects that they need to render and update the location every frame. I am not really using an Entity/Component based system and the scope of this game doesn't really necessitate it. However, if I WERE to use one down the road, I would hope that it would be fairly easy to plug it in when the game is encapsulated from the rest of the system. How the game simulation behaves internally should be of no consequence to the rest of the app.

I know I have more questions but I need to review my code to refresh my memory, so for now these will suffice. Thanks!
Pages: [1]