Framework: Profile

В комментариях зашла речь о том, как организовывать и работать с глобальными данными, которые должны быть доступны из любого места программы в любой момент времени её эксплуатации. Или это мне только показалось, не важно.
Класс, о котором я расскажу позволяет не только передавать данные между стейтами «не на прямую», но и организовывает сохранение игры. Класс утилитный, как практически все классы пакета elmortem.core.

Profile

elmortem.core.Profile
Класс представляет собой хранилище переменных, которые можно свободно добавлять и изменять из любого места программы, а затем сохранить в SharedObject с заданным именем. Так же можно проверить наличие сохранённых переменных по имени сохранения.
package elmortem.core {
  import flash.net.SharedObject;
  import elmortem.utils.Data;
  
  public class Profile {
    static private var name:String = "";
    static private var vars:Object = {};
    
    // задаём значение переменной
    static public function setVar(name:String, value:*):void {
      trace("setVar: "+name+" = "+value);
      var v:* = Data.clone(value);
      try {
        vars[name] = v;
      } catch(e:Error) {
        vars[name] = value;
      }
    }
    // получаем значение переменной
    static public function getVar(name:String):* {
      return Data.clone(vars[name]);
    }
    // очищаем загруженные переменные
    static public function clearVars():void {
      vars = { };
      name = "";
    }
    // сохраняем переменные по имени
    static public function saveVars(name:String):void {
      Profile.name = name;
      var so:SharedObject = SharedObject.getLocal(name);
      so.setProperty("vars", Data.clone(vars));
      so.flush();
    }
    // загружаем переменные по имени
    static public function loadVars(name:String):void {
      Profile.name = name;
      var so:SharedObject = SharedObject.getLocal(name);
      vars = so.data.vars;
      if (!vars) vars = { };
    }
    // удаляем сохранённые переменные по имени
    static public function clearSavesVars(name:String, is_local:Boolean = false):void {
      var so:SharedObject = SharedObject.getLocal(name);
      so.clear();
      if (is_local && Profile.name == name) vars = { };
    }
    // проверяем наличие сохранений по имени
    static public function isSavedVars(name:String):Boolean {
      try {
        var so:SharedObject = SharedObject.getLocal(name);
      } catch (e:Error) {
        trace(e.message);
        return false;
      }
      return (so && so.data && so.data.vars);
    }
  }
}

Пример работы с классом.
// Document Class
public class Main extends Sprite {
  static public var stateManager:StateManager;

  public function Main():void {
    if (stage) init();
    else addEventListener(Event.ADDED_TO_STAGE, init);
  }
  private function init(e:Event = null):void {
    removeEventListener(Event.ADDED_TO_STAGE, init);
    Profile.loadVars("mysave");
    stateManager = new StateManager({clip:this});
    stateManager.show(new Gameplay());
  }
}
// Gameplay State
public class Gameplay extends State {
  private var map:int;
  public function Gameplay(attrIn:Object = null) {
    super(attrIn);
  }
  override protected function init():void {
    map = int(Profile.getVar("map"));
    trace(map);
    stage.addEventListener(MouseEvent.CLICK, onClick);
  }
  override public function free():void {
    removeEventListener(MouseEvent.CLICK, onClick);
    super.free();
  }
  private function onClick(e:MouseEvent):void {
    Profile.setVar("map", ++map);
    Profile.saveVars("mysave");
    Main.stateManager.show(new Gameplay());
  }
}

Комментарии (10)

0
0
Хотел вставить тег «ката» получился пустой комментарий
0
Извиняюсь, забыл совсем…
Было бы неплохо, если бы при публикации статьи без ката выдавалось предупреждение. Всё равно у нас тут большинство статей длинные, кат почти везде актуален.
0
Если делать класс не как утилитный, то можно ведь легко реализовать несколько профилей и их переключение
0
Так и так можно переключение реализовать и несколько профилей. Есть же saveVars и loadVars. Я вот себе даже не представляю ситуации, когда нужно одновременно работать с несколькими профилями.
0
По мне, так лучше использовать классы для хранения данных — меньше вероятность опечататься в названии переменой или ошибиться с типом, и к тому же можно работать со структурами данных.
0
Подробнее?
0
не
map = int(Profile.getVar("map"));

а
map = Profile.map;

:)
0
Да, именно это и имелось ввиду.
0
Ну так ничто не мешает. Просто мне так удобнее. Я вообще не представляю, как моно перепутать тип…
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.