first implementation of Cairngorm

This commit is contained in:
2025-11-17 14:29:12 +01:00
parent 99f8c52d50
commit 5e869c96a5
10 changed files with 498 additions and 3 deletions
+27 -3
View File
@@ -1,3 +1,9 @@
import control.AppController;
import business.Services;
import model.AppModelLocator;
import com.adobe.cairngorm.control.CairngormEventDispatcher;
import control.LoadRidersEvent;
import feathers.events.FeathersEvent;
import feathers.layout.VerticalAlign;
import components.NekoRectangle;
import feathers.controls.Application;
@@ -12,12 +18,19 @@ import openfl.Assets;
import openfl.text.Font;
class LPTCManager2026 extends Application {
private var mainPanel:Panel;
private var model = AppModelLocator.getInstance();
private var services = new Services();
private var appController = new AppController();
//private var mainPanel:Panel;
// private var nav:StackNavigator;
public function new() {
super();
addEventListener(FeathersEvent.CREATION_COMPLETE, onCreationComplete);
}
override private function initialize():Void {
@@ -26,7 +39,7 @@ class LPTCManager2026 extends Application {
stage.displayState = NORMAL;
stage.scaleMode = NO_SCALE;
mainPanel = new Panel();
/*mainPanel = new Panel();
mainPanel.autoSizeMode = STAGE;
mainPanel.backgroundSkin = new NekoRectangle(Constants.MAIN_COLOR3);
@@ -70,10 +83,21 @@ class LPTCManager2026 extends Application {
mainPanel.footer = footer;
addChild(mainPanel);
addChild(mainPanel);*/
// nav = new StackNavigator();
trace(this, "--> initialize()");
}
private function loadRiders():Void {
trace(this + " --> loadRiders()");
var cgEvent:LoadRidersEvent = new LoadRidersEvent();
CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
}
private function onCreationComplete(event:FeathersEvent):Void {
trace(this + " --> onCreationComplete()");
loadRiders();
}
}
+24
View File
@@ -0,0 +1,24 @@
package business;
import com.adobe.cairngorm.business.ServiceLocator;
import feathers.rpc.IResponder;
import feathers.rpc.http.HTTPService;
class LoadRidersDelegate {
private var command:IResponder;
private var service:HTTPService;
public function new(command:IResponder) {
// constructor will store a reference to the service we're going to call
service = ServiceLocator.getInstance().getHTTPService('loadRidersService');
// and store a reference to the command that created this delegate
this.command = command;
}
public function loadRidersService():Void {
// call the service
var token = service.send();
// notify this command when the service call completes
token.addResponder(command);
}
}
+15
View File
@@ -0,0 +1,15 @@
package business;
import com.adobe.cairngorm.business.ServiceLocator;
import feathers.rpc.http.HTTPService;
class Services extends ServiceLocator {
public var loadRidersService:HTTPService;
public function new() {
super();
loadRidersService = new HTTPService();
loadRidersService.url = "data/riders.json";
loadRidersService.resultFormat = HTTPService.RESULT_FORMAT_JSON;
}
}
+54
View File
@@ -0,0 +1,54 @@
package command;
import openfl.Vector;
import vo.Rider;
import feathers.data.ArrayCollection;
import openfl.Lib;
import haxe.DynamicAccess;
import business.LoadRidersDelegate;
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import feathers.rpc.IResponder;
import feathers.rpc.events.ResultEvent;
import haxe.Json;
import model.AppModelLocator;
class LoadRidersCommand implements ICommand implements IResponder {
private var model = AppModelLocator.getInstance();
public function execute(cgEvent:CairngormEvent):Void {
// create a worker who will go get some data and pass it a reference to this command so the delegate knows where to return the data
var delegate = new LoadRidersDelegate(this);
// make the delegate do some work
delegate.loadRidersService();
trace(this + "execute()");
}
// this is called when the delegate receives a result from the service
public function result(rpcEvent:Dynamic):Void {
// populate the riders DP in the model locator with the JSON results from the service call
var riders:Array<Rider> = cast(rpcEvent, ResultEvent).result;
model.ridersListDP = new ArrayCollection(riders);
trace("ridersListDP.length --> " + model.ridersListDP.length);
/*var data:DynamicAccess<Dynamic> = Json.parse(cast(rpcEvent, ResultEvent).result);
*/
/*var data:DynamicAccess<Dynamic> = Json.parse(e.target.data);
for (key => value in data){
ConfigValues.data[key] = value;
} */
}
// this is called when the delegate receives a fault from the service
public function fault(rpcEvent:Dynamic):Void {
// store an error message in the model locator
// labels, alerts, etc can bind to this to notify the user of errors
model.errorStatus = "Fault occured in LoadEmployeesCommand.";
}
}
+13
View File
@@ -0,0 +1,13 @@
package control;
import command.LoadRidersCommand;
import com.adobe.cairngorm.control.FrontController;
class AppController extends FrontController {
public static final LOAD_RIDERS_EVENT = "loadRidersEvent";
public function new() {
super();
addCommand(AppController.LOAD_RIDERS_EVENT, LoadRidersCommand);
}
}
+9
View File
@@ -0,0 +1,9 @@
package control;
import com.adobe.cairngorm.control.CairngormEvent;
class LoadRidersEvent extends CairngormEvent {
public function new() {
super(AppController.LOAD_RIDERS_EVENT);
}
}
+76
View File
@@ -0,0 +1,76 @@
package model;
import vo.Rider;
import feathers.data.ArrayCollection;
import openfl.errors.Error;
import openfl.events.Event;
import com.adobe.cairngorm.model.IModelLocator;
import openfl.events.EventDispatcher;
class AppModelLocator extends EventDispatcher implements IModelLocator {
// events constants
public static final VIEWING_CHANGE = "viewingChange";
public static final RIDERS_LIST_DP_CHANGE = "ridersListDPChange";
// this instance stores a static reference to itself
private static var model:AppModelLocator;
// available values for the main viewstack defined as constants to help uncover errors at compile time instead of run time
public static final ADMIN_LOGIN = 0;
public static final RIDERS_LIST = 1;
public static final RIDER_DETAIL = 2;
// viewstack starts out on the admin login screen
public var viewing(default, set):Int = ADMIN_LOGIN;
private function set_viewing(value:Int):Int {
viewing = value;
dispatchEvent(new Event(VIEWING_CHANGE));
return viewing;
}
// rider object contains uid/passwd
// its value gets set at login and cleared at logout but nothing binds to it or uses it
// retained since it was used in the original Adobe CafeTownsend example app
/*public var user(default, set):User;
private function set_user(value:User):User {
user = value;
dispatchEvent(new Event(USER_CHANGE));
return user;
}*/
// contains the main riders list which is populated on startup
// mx:application's creationComplete event is mutated into a cairngorm event
// that calls the httpservice for the data
public var ridersListDP(default, set):ArrayCollection<Rider>;
private function set_ridersListDP(value:ArrayCollection<Rider>):ArrayCollection<Rider> {
ridersListDP = value;
dispatchEvent(new Event(RIDERS_LIST_DP_CHANGE));
return ridersListDP;
}
// variable to store error messages from the httpservice
// nothinng currently binds to it, but an Alert or the login box could to show startup errors
public var errorStatus:String;
// singleton: constructor only allows one model locator
public function new() {
super();
if (AppModelLocator.model != null) {
throw new Error("Only one ModelLocator instance should be instantiated");
}
}
// singleton: always returns the one existing static instance to itself
public static function getInstance():AppModelLocator {
if (model == null)
model = new AppModelLocator();
return model;
}
}
+64
View File
@@ -0,0 +1,64 @@
package vo;
class Rider {
private static var currentIndex = 1000;
public var id:Int;
public var name:String;
public var firstName:String;
public var age:Int;
public var lastLessonDate:Int;
public var level:Int;
public var credit:Int;
public var address:String;
public var notes:String;
public var ffeLicence:Bool;
public var ffeLicenceValidityYear:Int;
public var ffeLicenceNumber:String;
public var legalGuardianName:String;
public var legalGuardianFirstName:String;
public var legalGuardianRole:String;
public var legalGuardianPhoneNumber:Int;
public var legalGuardianEmail:String;
public function new(pId:Int = 0,
pName:String = "",
pFirstName:String = "",
pAge:Int = 0,
pLastLessonDate:Int,
pLevel:Int = 0,
pCredit:Int = 0,
pAddress:String = "",
pNotes:String = "",
pffeLicence:Bool = false,
pffeLicenceValidityYear:Int = 0,
pffeLicenceNumber:String = "",
pLegalGuardianName:String = "",
pLegalGuardianFirstName:String = "",
pLegalGuardianRole:String = "",
pLegalGuardianPhoneNumber:Int = 0,
pLegalGuardianEmail:String = "") {
id = (pId == 0) ? currentIndex++ : pId;
name = pName;
firstName = pFirstName;
age = pAge;
lastLessonDate = pLastLessonDate;
level = pLevel;
credit = pCredit;
address = pAddress;
notes = pNotes;
ffeLicence = pffeLicence;
ffeLicenceValidityYear = pffeLicenceValidityYear;
ffeLicenceNumber = pffeLicenceNumber;
legalGuardianName = pLegalGuardianName;
legalGuardianFirstName = pLegalGuardianFirstName;
legalGuardianRole = pLegalGuardianRole;
legalGuardianPhoneNumber = pLegalGuardianPhoneNumber;
legalGuardianEmail = pLegalGuardianEmail;
//startdate = (startdate == null) ? Date.now() : startdate;
}
}