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  Announcements and General Discussion / Architecture / Model/View separation again on: October 09, 2011, 03:41:53
I have a WorldProxy.  The WorldProxy is responsible for managing WorldObjects, that includes their spatial structure, their lifetimes, their current state, and is also responsible for updating all of them at a set interval.  This all ticks, excuse the pun, along nicely.

When it comes to rendering the objects, I have a WorldMediator which uses the database held in the WorldProxy.  It takes care of visibility, a camera, all the stuff that's render related.

Historically, all of my WorldObjects would have a tick() and a render().  Currently they have a tick(), which is what makes everything work, however, I can't have a class that has one foot in the Model layer, and the other in the View layer.

The trouble is, the WorldObject really should render itself, because it knows about its internal state, which assets belong to it, etc.  If I had a separate class to render the WorldObject, it would be an outsider looking in, breaking encapsulation.

The only other way I can think of doing this, the PureMVC way, is to have the WorldProxy do nothing except hold the state data, then have the spatial structure held in the WorldMediator.  This feels wrong to me though, given the role of the Model in my case is to be a database.

How is this dual life usually handled in PureMVC?

- Shane

2  Announcements and General Discussion / Architecture / Multiple StateMachine instances on: September 26, 2011, 11:51:24
Hi Cliff,

I've modified my local version of the StateMachine utility to support multiple instances:

1. StateMachine constructor takes a name, with a null default.  The default lets it act as it does now.
2. Changed FSMInjector to support a name in the XML definition, which is passed to the StateMachine constructor.

e.g.
:
<fsm name="GameFSM" initial={AppFacade.STATE_BOOT}>
Works well.  The only gotcha is that the user has to be careful to keep the actions/states exclusive to each FSM.  If they do, then each FSM will ignore the states and actions of other FSMs.  I haven't found this an issue, but just thought I'd throw it out there.  One way around this could be to mangle a namespace into each set of actions/states.

What do you think?  Sound ok?

Cheers,
Shane



3  Announcements and General Discussion / Architecture / Naming/structure conventions on: September 11, 2011, 09:25:15
Hi,

Getting through the second week with PureMVC, and still really liking it.  I have another question, though:

Q: How do you name VO objects?

The issue I keep running into, making me feel all weird and uncomfortable, is that I find myself adding VO to the end of all of my data classes.

e.g.
- TextureProxy creates TextureVO objects.
- ShaderProxy creates ShaderVO objects
- SoundProxy creates SoundVO objects
- LoaderProxy creates LoaderVO objects

the list goes on.  This how I had it previously:

- TextureManager creates Texture objects.
- ShaderManager creates Shader objects
- SoundManager creates Sound objects
- LoaderManager creates Loader objects

So basically where I would have had 'naked' classes before, I've got VO appended to everything.

I can live with this, however here are some more examples of where it starts to get weird for me:

- WorldProxy creates and manages:
  EntityProxy, which manages EntityVO objects, MapVO, CollisionVO etc classes.

Now... EntityVO objects aggregate other, non-trivial, data objects that are really outside the realm of MVC.  They're game specific utility classes, amongst other things, that makes sense to that Entity.  So I'm not appending VO to them, because their logic will always stay in the Proxy domain (i.e. not be used in Commands or Mediators).

So, in short:

I've been appending VO to class names that tend to be created directly in the Proxy and exposed to the outside world (Commands/Mediators/Views), and everything else is under a 'do' (Data Object) folder under Proxies.  Is this how it's supposed to be done?

e.g. Here's a modified/trimmed version of what I'm doing:

:
- root
  - util (This is the namespace for all non MVC related code.  General framework classes for useful functionality)
    Pathfinding.as
    Collision.as
    Debug.as
    Math.as
    RenderUtils.as
  - mvc (This is the PureMVC application structure)
    - Main.as <- entry point
    - AppFacade.as
    - controller
      - startup
        InitCoreCommand.as
        InitDataCommand.as
        InitGameCommand.as
        LaunchGame.as
        StartupCommand.as
    - model
      - game
        GameProxy.as
      - world
        - vo (I have VOs for objects that tend to get passed across application boundaries)
          - entities
              EntityVO.as
              PlayerVO.as
              EnemyVO.as
        EntityProxy.as
        WorldProxy.as
      - util (Theses are utility classes that related to functionality not appropriate for MVC)
        EntityCollision.as
        EntityVisibility.as
    - view
        - components
          uiView.as
        UIMediator.as
        WorldMediator.as

Does this look ok to you?  I really want to nail this down, so when I explain the new structure to our other programmers, they know where to put old and new code.

When I've finished all of this, I might expose it to everyone as a full game implementation, in order to help the community.

Cheers,
Shane
4  Announcements and General Discussion / Architecture / Mediator structure on: August 30, 2011, 07:28:16
Hi,

Ok, getting to the end of my first week with PureMVC, and I have run into another question around architecture.  This time, my question is around Mediators for logic

In my previous, non-PureMVC, projects (games), I would create a task (my Controller layer) which would be long living, receiving all sorts of  'tick' messages and such.  That task, upon creation, would create a set of views (View layer) to display my content with it being the ViewDelegate, then sit there handling all sorts of messages until it was done.  At which point, it would kill itself, or be killed by another task/manager somewhere else.

For example, imagine a simplified 'GameTask'.  It is created after the player has left the front-end and is starting the actual game.

GameTask:
- onCreate:
  - Load assets (Model layer)
  - Create GameHUD View.
  - Create GameCanvas View.

- onTick
  - Update physics, player control, etc...

- onRender()
  - Render directly into the Game View.

- onDestroy:
  - Kill Game View
  - Kill HUD View
  - Kill assets

Ok, pretty standard stuff.

Now, when porting this to PureMVC, I'm trying to work out what goes where.  Because there is no such thing as a long running task/process (PureMVC Commands are transient), I'm not sure exactly where to put the game logic.  I could just pull it all out of PureMVC and have it running alongside, but that feels like it completely defeats the purpose of using PureMVC to begin with.

So because Notifications in PureMVC are sent through the View layer (i.e only Mediators can receive Notifications), I decided to make a State class that derives Mediator.  These states are sort of like my 'tasks'.  They can register, send and receive Notifications.  Still feels wrong though... I'm essentially putting logic in the View layer.

I then have a GameState (which 'isa' Mediator).  This is like my GameTask: long living, can access the Model layer via Proxies, can send/receive Notifications/Commands to do various things, can be registered and de/unregistered, and generally be the main man.

Here is cut down example of what I mean:
:
public class GameStateMediator extends State implements ITick
{
override public function onRegister():void
{
facade.registerMediator(new GameHUDMediator);
facade.registerMediator(new GameCanvasMediator);
// Register any Commands I need to talk to the rest of the system.
// Register itself with my game library to receive ticks.
}

override public function onRemove():void
{
facade.removeMediator(GameCanvasMediator.NAME);
facade.removeMediator(GameHUDMediator.NAME);
// Deregister any Commands.
// Deregister itself from my game library.
}

public function onTick():void
{
// Update physics, player control, etc...
// Anything that might be interesting to rest of the system, like the HUD, will cause a sendNotification(). e.g. COMMAND_PLAYER_HEALTH_UPDATED.
}

override public function handleNotification(n:INotification):void
{
// Respond to any other parts of the system sending Notifications.
}
}

public class GameHUDMediator extends Mediator implements IViewDelegate
{
override public function onRegister():void
{
// Create my custom library views, with 'this' as a delegate.
}

override public function onRemove():void
{
// Destroy my custom library views.
}

// From IViewDelegate
public function onViewRender(v:View):void
{
var gsp:GameStateProxy = facade.retrieveProxy(GameStateProxy.NAME) as GameStateProxy;
// render anything anything the view needs from data retrieved from the GameStateProxy.
}
}


Now, this all works, and seems ok, however I've got a niggling feeling the GameState could be a Proxy object, so all logic sits in the Model layer.  Also, should Mediators be registering other Mediators? Surely that's a job for a Command, but I want a persistent Command, not a transient one.

But even that feels odd, because it feels weird to say that any logic like gameplay, should reside in the Controller layer.

I'd love to hear what other people are doing here.

Cheers,
Shane
5  Announcements and General Discussion / Architecture / Purpose of VOs on: August 25, 2011, 05:52:48
Hi,

I've only used PureMVC for a couple of days, but I really like how it's constructed.  I'm mainly from a C++ background, so there are a couple of questions I have around Proxy objects and Value Objects (VOs) that I hope aren't painfully obvious to AS3 people.

Firstly, I'm not sure I fully understand the purpose of VOs.  I thought the whole idea behind Proxies was to hide the actual data representation, exposing necessary data via getter/setters.  The way I'm seeing them used is sort of an exposed key/value pair hanging off the proxy.  Are they meant to be sort of read-only objects, with the write interface being the proxy?  Or are they read/write?  If they're read AND write, this breaks encapsulation, so I'm confused.  Or are these types of VOs meant to be very simple, with pretty much non-existent Proxy objects?

Secondly, in researching PureMVC architecture, I'm seeing a lot of people have a VO full of static variables for singleton-type classes.  For example, it seems common to have an ApplicationVO where programmers access its data from anywhere using ApplicationVO.someThing.  I've even seen ApplicationVO classes with functions, that return data.  For example, I've seen one class that looks like this:

:
class ApplicationVO
{
  public static var FILESYSTEM_ROOT="some_directory/";
  public static var BASE_IMAGE_FILENAME="img_";

  public static function getPath(filename:String):String {
    return FILESYSTEM_ROOT+BASE_IMAGE_FILENAME+filename;
  }
}

I'm not sure if I'm missing the point, but shouldn't all of this be in the Proxy?

I'm seeing similar patterns in Mediators; i.e. static functions in mediators, or singleton mediators (BlahMediator.getInstance()).  Isn't this again killing loose coupling?

If the answer to all of this is simple, it's convenient, or it's because of performance, then I get it.  I'm from a console video game programming background so I understand tighter coupling for the sake of performance.  Still, why have both static Proxies AND VOs?  Why not just have a static Proxy which exposes the VO, like so:

:
class MyVO {
  public var blah:int = 0;
}

class MyProxy extends Proxy {
  private var _myVO:MyVO;
  private static var _instance:MyProxy;

  public function MyProxy() {
    _myVO = new MyVO;
    _instance = this;
  }
  public static function get instance():MyProxy {
    return _instance;
  }
  // at most expose the VO via a static in the proxy
  public static function get vo():MyVO
  {
    return _instance._myVO;
  }
}

This is how I've decided to implement singleton-type proxy objects.  Is this the right way to go, or am I missing something?

I've got more questions, but this is a good start ;)

Cheers,
Shane
Pages: [1]