Skip to content

Commit 67c79bf

Browse files
committed
puremvc-haxe-demo-hello-openfl
1 parent 5448e8a commit 67c79bf

File tree

11 files changed

+660
-0
lines changed

11 files changed

+660
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
* PureMVC Haxe Demo - Hello OpenFL - Copyright © 2022 Bowler Hat LLC
2+
* PureMVC AS3 / Flash Demo - HelloFlash - Copyright © 2008, Cliff Hall
3+
* PureMVC - Copyright(c) 2007-2008 Futurescale, Inc.
4+
All rights reserved.
5+
6+
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7+
8+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10+
* Neither the name of Futurescale, Inc., PureMVC.org, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11+
12+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# PureMVC Haxe Hello OpenFL
2+
3+
This example app demonstrates how to use [PureMVC](http://puremvc.org/) within an [OpenFL](https://openfl.org/) project. A lonely little blue box appears, moving in a grey room. Interact with it.
4+
5+
Based on [PureMVC ActionScript 3 Demo: HelloFlash (Flash)](https://github.com/PureMVC/puremvc-as3-demo-flash-helloflash)
6+
7+
## Interaction
8+
9+
A lonely little blue box appears, moving in a grey room. Interact with it.
10+
11+
- When it hits a wall it changes direction and shrinks.
12+
- If you grab it and drag it around, diffrently colored boxes trail out going the opposite of the direction you drag.
13+
- The colors are from a short palette of about 5 colors and they cycle.
14+
- If you roll your mouse-wheel all the boxes scale up or down in size depending on the direction you scroll it. (Mac users use the two-finger downswipe to scale up and two-finger upswipe to scale down)
15+
- When the boxes are all tiny, its hard to grab them, so you might scale them all up.
16+
- Catch one and hold on to it. Allow the others to decay in size a bit by bouncing off the walls. Then drag around to emit some, let them decay, etc.
17+
- Scale them up until they all look like a jigging mass of Jello™. Then scroll farther, most wrap around and become small, but some stay large. Let them decay.
18+
19+
## Techniques Illustrated
20+
21+
- Starting the application via the ApplicationFacade
22+
- Sending a Notification to trigger a Startup Command
23+
- Initializing the Model and View from a Command
24+
- Dynamically created View Components and Mediators with unique instance names
25+
- View components communicating with their Mediators
26+
- Mediators communicating with a Proxy
27+
- Use of a Proxy to hold Model data
28+
- Mediators communicating with other Mediators via Notification
29+
30+
## Live demo
31+
32+
A build of the [_puremvc-haxe-demo-hello-openfl_ sample](https://feathersui.com/samples/haxe-openfl/puremvc/puremvc-haxe-demo-hello-openfl/) is hosted on the Feathers UI website, and it may be viewed in any modern web browser.
33+
34+
## Run locally
35+
36+
This project includes an [_project.xml_](https://lime.software/docs/project-files/xml-format/) file that configures all options for [OpenFL](https://openfl.org/). This file makes it easy to build from the command line, and many IDEs can parse this file to configure a Haxe project to use OpenFL.
37+
38+
### Prerequisites
39+
40+
- [Install Haxe 4.0.0 or newer](https://haxe.org/download/)
41+
- Install OpenFL from Haxelib
42+
```sh
43+
haxelib install openfl
44+
haxelib run openfl setup
45+
```
46+
47+
### Command Line
48+
49+
Run the [**openfl**](https://www.openfl.org/learn/haxelib/docs/tools/) tool in your terminal:
50+
51+
```sh
52+
haxelib run openfl test html5
53+
```
54+
55+
In addition to `html5`, other supported targets include `windows`, `mac`, `linux`, `android`, and `ios`. See [Lime Command Line Tools: Basic Commands](https://lime.software/docs/command-line-tools/basic-commands/) for complete details about the available commands.
Lines changed: 9 additions & 0 deletions
Loading
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<project>
3+
<meta title="Hello OpenFL" package="com.feathersui.samples.puremvc.HelloOpenFL" version="1.0.0" company="Bowler Hat LLC"/>
4+
<meta title="PureMVC Haxe Hello OpenFL Demo — Feathers UI Samples" if="html5"/>
5+
<app main="HelloOpenFL" file="HelloOpenFL"/>
6+
7+
<window allow-high-dpi="true"/>
8+
<window fps="60"/>
9+
<window fps="0" if="html5"/>
10+
11+
<source path="src"/>
12+
13+
<haxelib name="openfl"/>
14+
<haxelib name="puremvc-standard"/>
15+
16+
<icon path="assets/icons/feathersui-icon.svg"/>
17+
</project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
PureMVC Haxe Demo - Hello OpenFL
3+
Copyright (c) 2022 Bowler Hat LLC
4+
PureMVC AS3 / Flash Demo - HelloFlash
5+
By Cliff Hall <clifford.hall@puremvc.org>
6+
Copyright(c) 2007-08, Some rights reserved.
7+
*/
8+
9+
import openfl.display.Sprite;
10+
import org.puremvc.haxe.demos.openfl.helloopenfl.ApplicationFacade;
11+
12+
class HelloOpenFL extends Sprite {
13+
public function new() {
14+
super();
15+
ApplicationFacade.getInstance().startup(this.stage);
16+
}
17+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
PureMVC Haxe Demo - Hello OpenFL
3+
Copyright (c) 2022 Bowler Hat LLC
4+
PureMVC AS3 / Flash Demo - HelloFlash
5+
By Cliff Hall <clifford.hall@puremvc.org>
6+
Copyright(c) 2007-08, Some rights reserved.
7+
*/
8+
9+
package org.puremvc.haxe.demos.openfl.helloopenfl;
10+
11+
import openfl.display.Stage;
12+
import org.puremvc.haxe.demos.openfl.helloopenfl.controller.StartupCommand;
13+
import org.puremvc.haxe.patterns.facade.Facade;
14+
15+
/**
16+
A concrete `Facade` for the `HelloOpenFL` application.
17+
18+
The main job of the `ApplicationFacade` is to act as a single
19+
place for mediators, proxies and commands to access and communicate
20+
with each other without having to interact with the Model, View, and
21+
Controller classes directly. All this capability it inherits from
22+
the PureMVC Facade class.
23+
24+
This concrete Facade subclass is also a central place to define
25+
notification constants which will be shared among commands, proxies and
26+
mediators, as well as initializing the controller with Command to
27+
Notification mappings.
28+
**/
29+
class ApplicationFacade extends Facade {
30+
// Notification name constants
31+
public static final STARTUP = "startup";
32+
public static final STAGE_ADD_SPRITE = "stageAddSprite";
33+
public static final SPRITE_SCALE = "spriteScale";
34+
public static final SPRITE_DROP = "spriteDrop";
35+
36+
public function new() {
37+
super();
38+
}
39+
40+
/**
41+
Singleton ApplicationFacade Factory Method
42+
**/
43+
public static function getInstance():ApplicationFacade {
44+
if (Facade.instance == null) {
45+
Facade.instance = new ApplicationFacade();
46+
}
47+
return cast(Facade.instance, ApplicationFacade);
48+
}
49+
50+
/**
51+
Register Commands with the Controller
52+
**/
53+
override private function initializeController():Void {
54+
super.initializeController();
55+
registerCommand(STARTUP, StartupCommand);
56+
}
57+
58+
/**
59+
Start the application
60+
**/
61+
public function startup(stage:Stage):Void {
62+
sendNotification(STARTUP, stage);
63+
}
64+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
PureMVC Haxe Demo - Hello OpenFL
3+
Copyright (c) 2022 Bowler Hat LLC
4+
PureMVC AS3 / Flash Demo - HelloFlash
5+
By Cliff Hall <clifford.hall@puremvc.org>
6+
Copyright(c) 2007-08, Some rights reserved.
7+
*/
8+
9+
package org.puremvc.haxe.demos.openfl.helloopenfl.controller;
10+
11+
import openfl.display.Stage;
12+
import org.puremvc.haxe.demos.openfl.helloopenfl.model.SpriteDataProxy;
13+
import org.puremvc.haxe.demos.openfl.helloopenfl.view.StageMediator;
14+
import org.puremvc.haxe.interfaces.ICommand;
15+
import org.puremvc.haxe.interfaces.INotification;
16+
import org.puremvc.haxe.patterns.command.SimpleCommand;
17+
18+
/**
19+
A command executed when the application starts.
20+
*/
21+
class StartupCommand extends SimpleCommand implements ICommand {
22+
/**
23+
Register the Proxies and Mediators.
24+
25+
Get the View Components for the Mediators from the app,
26+
which passed a reference to itself on the notification.
27+
**/
28+
override public function execute(note:INotification):Void {
29+
facade.registerProxy(new SpriteDataProxy());
30+
var stage = cast(note.getBody(), Stage);
31+
facade.registerMediator(new StageMediator(stage));
32+
sendNotification(ApplicationFacade.STAGE_ADD_SPRITE);
33+
}
34+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
PureMVC Haxe Demo - Hello OpenFL
3+
Copyright (c) 2022 Bowler Hat LLC
4+
PureMVC AS3 / Flash Demo - HelloFlash
5+
By Cliff Hall <clifford.hall@puremvc.org>
6+
Copyright(c) 2007-08, Some rights reserved.
7+
*/
8+
9+
package org.puremvc.haxe.demos.openfl.helloopenfl.model;
10+
11+
import org.puremvc.haxe.patterns.proxy.Proxy;
12+
13+
class SpriteDataProxy extends Proxy {
14+
public static final NAME = "SpriteDataProxy"; // Proxy name
15+
16+
public function new() {
17+
super(NAME, 0);
18+
palette = [blue, red, yellow, green, cyan];
19+
}
20+
21+
private var palette:Array<UInt>;
22+
private var red:UInt = 0xFF0000;
23+
private var green:UInt = 0x00FF00;
24+
private var blue:UInt = 0x0000FF;
25+
private var yellow:UInt = 0xFFFF00;
26+
private var cyan:UInt = 0x00FFFF;
27+
28+
public function nextSpriteColor(startColor:UInt):UInt {
29+
// identify color index
30+
var index = 0;
31+
for (j in 0...palette.length) {
32+
index = j;
33+
if (startColor == palette[index])
34+
break;
35+
}
36+
37+
// select the next color in the palette
38+
index = (index == palette.length - 1) ? 0 : index + 1;
39+
// return startColor;
40+
return palette[index];
41+
}
42+
43+
/**
44+
* Get the next Sprite ID
45+
*/
46+
public var nextSpriteID(get, never):String;
47+
48+
private function get_nextSpriteID():String {
49+
return "sprite" + spriteCount++;
50+
}
51+
52+
/**
53+
* Get the number of sprites
54+
*/
55+
public var spriteCount(get, set):Int;
56+
57+
private function get_spriteCount():Int {
58+
return (data : Int);
59+
}
60+
61+
private function set_spriteCount(count:Int):Int {
62+
data = count;
63+
return data;
64+
}
65+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
PureMVC Haxe Demo - Hello OpenFL
3+
Copyright (c) 2022 Bowler Hat LLC
4+
PureMVC AS3 / Flash Demo - HelloFlash
5+
By Cliff Hall <clifford.hall@puremvc.org>
6+
Copyright(c) 2007-08, Some rights reserved.
7+
*/
8+
9+
package org.puremvc.haxe.demos.openfl.helloopenfl.view;
10+
11+
import openfl.events.Event;
12+
import org.puremvc.haxe.demos.openfl.helloopenfl.ApplicationFacade;
13+
import org.puremvc.haxe.demos.openfl.helloopenfl.model.SpriteDataProxy;
14+
import org.puremvc.haxe.demos.openfl.helloopenfl.view.components.HelloSprite;
15+
import org.puremvc.haxe.interfaces.IMediator;
16+
import org.puremvc.haxe.interfaces.INotification;
17+
import org.puremvc.haxe.patterns.mediator.Mediator;
18+
19+
/**
20+
A Mediator for interacting with the HelloSprite.
21+
**/
22+
class HelloSpriteMediator extends Mediator implements IMediator {
23+
/**
24+
Constructor.
25+
**/
26+
public function new(viewComponent:HelloSprite) {
27+
// pass the viewComponent to the superclass where
28+
// it will be stored in the inherited viewComponent property
29+
//
30+
// *** Note that the name of the mediator is the same as the
31+
// *** id of the HelloSprite it stewards. It does not use a
32+
// *** fixed 'NAME' constant as most single-use mediators do
33+
super(viewComponent.id, viewComponent);
34+
35+
// Retrieve reference to frequently consulted Proxies
36+
spriteDataProxy = cast(facade.retrieveProxy(SpriteDataProxy.NAME), SpriteDataProxy);
37+
38+
// Listen for events from the view component
39+
helloSprite.addEventListener(HelloSprite.SPRITE_DIVIDE, onSpriteDivide);
40+
}
41+
42+
/**
43+
List all notifications this Mediator is interested in.
44+
45+
Automatically called by the framework when the mediator
46+
is registered with the view.
47+
48+
@return Array the list of Notification names
49+
**/
50+
override public function listNotificationInterests():Array<String> {
51+
return [ApplicationFacade.SPRITE_SCALE, ApplicationFacade.SPRITE_DROP];
52+
}
53+
54+
/**
55+
Handle all notifications this Mediator is interested in.
56+
57+
Called by the framework when a notification is sent that
58+
this mediator expressed an interest in when registered
59+
(see `listNotificationInterests`).
60+
61+
@param INotification a notification
62+
**/
63+
override public function handleNotification(note:INotification):Void {
64+
switch (note.getName()) {
65+
case ApplicationFacade.SPRITE_DROP:
66+
helloSprite.dropSprite();
67+
68+
case ApplicationFacade.SPRITE_SCALE:
69+
var delta = (note.getBody() : Int);
70+
helloSprite.scaleSprite(delta);
71+
}
72+
}
73+
74+
/**
75+
Sprite divide.
76+
77+
User is dragging the sprite, send a notification to create a new sprite
78+
and pass the state the new sprite should inherit.
79+
**/
80+
private function onSpriteDivide(event:Event):Void {
81+
helloSprite.color = spriteDataProxy.nextSpriteColor(helloSprite.color);
82+
sendNotification(ApplicationFacade.STAGE_ADD_SPRITE, helloSprite.newSpriteState);
83+
}
84+
85+
/**
86+
Cast the viewComponent to its actual type.
87+
88+
This is a useful idiom for mediators. The
89+
PureMVC Mediator class defines a viewComponent
90+
property of type Object.
91+
92+
Here, we cast the generic viewComponent to
93+
its actual type in a protected mode. This
94+
retains encapsulation, while allowing the instance
95+
(and subclassed instance) access to a
96+
strongly typed reference with a meaningful
97+
name.
98+
99+
@return app the viewComponent cast to HelloSprite
100+
**/
101+
private var helloSprite(get, never):HelloSprite;
102+
103+
private function get_helloSprite():HelloSprite {
104+
return cast(viewComponent, HelloSprite);
105+
}
106+
107+
private var spriteDataProxy:SpriteDataProxy;
108+
}

0 commit comments

Comments
 (0)