设为首页 加入收藏

TOP

【Spine】Spine Runtime for Delphi移植笔记(五) - spine.core.atlas(一)
2017-10-10 12:04:46 】 浏览:7815
Tags:Spine Runtime for Delphi 移植 笔记 spine.core.atlas
////////////////////////////////////////////////////////////////////////////////
//Generic delphi runtime v3.6 for Spine animation tool                        //
//Runtime port by cjk (hzi1980@163.com)                                       //
////////////////////////////////////////////////////////////////////////////////

unit spine.core.atlas;

interface

uses
  System.Classes, System.SysUtils, System.Generics.Collections, System.TypInfo,
  System.Math, spine.types, spine.classes;

type
  TSpineAtlas = class(IAtlas)
  private type
    TupleStringArray = array [0..3] of string;
  private
    FPages: TObjectList<TAtlasPage>;
    FRegions: TObjectDictionary<string, TAtlasRegion>;
    FTextureLoader: ITextureLoader;
    procedure Load(const AStream: TStream);
  public
    constructor Create(const AStream: TStream; const ATextureLoader: ITextureLoader);
    destructor Destroy; override;
  end;

implementation

{ TSpineAtlas }

constructor TSpineAtlas.Create(const AStream: TStream;
  const ATextureLoader: ITextureLoader);
begin
  inherited Create;
  FPages:= TObjectList<TAtlasPage>.Create;
  FRegions:= TObjectDictionary<string,TAtlasRegion>.Create([doOwnsValues]);
  FTextureLoader:= ATextureLoader;
  Load(AStream);
end;

destructor TSpineAtlas.Destroy;
begin
  FPages.Free;
  FRegions.Free;
  inherited;
end;

procedure TSpineAtlas.Load(const AStream: TStream);
var
  EndOf: Boolean;

  function ReadLn(): string;
  var
    b, b1: Byte;
  begin
    Result:= '';
    if AStream.Position = AStream.Size then
    begin
      EndOf:= True;
      Exit;
    end;
    //
    while AStream.Position < AStream.Size do
    begin
      {$Hints off}
      AStream.Read(b, 1);
      {$Hints on}
      if (b <> $D) and (b <> $A) then
        Result:= Result + AnsiChar(Chr(b))
      else
        Break;
    end;
    //
    if AStream.Position < AStream.Size then
      {$Hints off}
      AStream.Read(b1, 1)
      {$Hints on}
    else Exit;
    //
    while ((b1 = $D) or (b1 = $A)) and (b1 <> b) and (AStream.Position < AStream.Size) do
      AStream.Read(b1, 1);
    //
    if AStream.Position < AStream.Size then
      AStream.Position:= AStream.Position - 1;
  end;

  function ReadTuple(out ATuple: TupleStringArray): Integer;
  var
    ln: string;
    colon, i, lastMatch, comma: Integer;
  begin
    ln:= Trim(ReadLn);
    colon:= ln.IndexOf(':');
    if colon = -1 then raise Exception.CreateFmt('Invalid line:%s',[ln]);
    lastMatch:= colon + 1;
    for i:= 0 to 2 do
    begin
      comma:= ln.IndexOf(',', lastMatch);
      if comma = -1 then break;
      ATuple[i]:= ln.Substring(lastMatch, comma - lastMatch).Trim;
      lastMatch:= comma + 1;
    end;
    ATuple[i]:= ln.Substring(lastMatch).Trim;
    result:= i + 1;
  end;

  function ReadValue: string;
  var
    ln: string;
    colon, i, lastMatch, comma: Integer;
  begin
    ln:= Trim(ReadLn);
    colon:= ln.IndexOf(':');
    if colon = -1 then raise Exception.CreateFmt('Invalid line:%s',[ln]);
        result:= ln.Substring(colon + 1).Trim;
  end;
  
var
  Page: TAtlasPage;
  Region: TAtlasRegion;
  Line, Direction: string;
  Tuple: TupleStringArray;
  i: Integer;  
begin
  EndOf:= False;
  Page:= nil;
  Region:= nil;
  while not EndOf do
  begin
    Line:= Trim(ReadLn);
    if Length(Line) > 0 then
    begin
      if Page = nil then
      begin
        Page:= TAtlasPage.Create;
        Page.Name:= Line;
        //
        if ReadTuple(Tuple) = 2 then
        begin
          Page.Width := Tuple[0].ToInteger;
                    Page.Height:= Tuple[1].ToInteger;
                    ReadTuple(Tuple);
                end;
        Page.Format:= TPageFormat(GetEnumValue(TypeInfo(TPageFormat), 'pf'+Tuple[0]));
        //
        ReadTuple(Tupl
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇DELPHI SOKET 编程--使用TServerS.. 下一篇Delphi的Socket编程步骤

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目