Merge branch 'master' of git://github.com/chrisforbes/OpenRA
This commit is contained in:
@@ -46,5 +46,10 @@ namespace OpenRa
|
||||
if( i.Value is T )
|
||||
yield return (T)i.Value;
|
||||
}
|
||||
|
||||
public IEnumerator<object> GetEnumerator()
|
||||
{
|
||||
return WithInterface<object>().GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,16 @@ namespace OpenRa.Game
|
||||
{
|
||||
class Actor
|
||||
{
|
||||
[Sync]
|
||||
public readonly TypeDictionary traits = new TypeDictionary();
|
||||
public readonly UnitInfo Info;
|
||||
|
||||
public readonly uint ActorID;
|
||||
[Sync]
|
||||
public int2 Location;
|
||||
[Sync]
|
||||
public Player Owner;
|
||||
[Sync]
|
||||
public int Health;
|
||||
IActivity currentActivity;
|
||||
|
||||
@@ -101,7 +105,7 @@ namespace OpenRa.Game
|
||||
if (underCursor != null && !underCursor.Info.Selectable)
|
||||
underCursor = null;
|
||||
|
||||
return traits.WithInterface<IOrder>()
|
||||
return traits.WithInterface<IIssueOrder>()
|
||||
.Select( x => x.IssueOrder( this, xy, mi, underCursor ) )
|
||||
.FirstOrDefault( x => x != null );
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ namespace OpenRa.Game
|
||||
{
|
||||
readonly Renderer renderer;
|
||||
readonly LineRenderer lineRenderer;
|
||||
readonly Sheet specialBin;
|
||||
readonly SpriteRenderer chromeRenderer;
|
||||
readonly Sprite specialBinSprite;
|
||||
readonly Sheet chromeTexture;
|
||||
readonly SpriteRenderer rgbaRenderer;
|
||||
readonly Sprite[] specialBinSprites;
|
||||
readonly Sprite moneyBinSprite;
|
||||
readonly Sprite tooltipSprite;
|
||||
readonly Sprite powerIndicatorSprite;
|
||||
@@ -39,7 +39,7 @@ namespace OpenRa.Game
|
||||
readonly Sprite optionsBottomRight;
|
||||
readonly Sprite optionsBackground;
|
||||
|
||||
readonly SpriteRenderer buildPaletteRenderer;
|
||||
readonly SpriteRenderer shpRenderer;
|
||||
readonly Animation cantBuild;
|
||||
readonly Animation ready;
|
||||
readonly Animation clock;
|
||||
@@ -47,6 +47,7 @@ namespace OpenRa.Game
|
||||
readonly List<Pair<Rectangle, Action<bool>>> buttons = new List<Pair<Rectangle, Action<bool>>>();
|
||||
readonly List<Sprite> digitSprites;
|
||||
readonly Dictionary<string, Sprite[]> tabSprites;
|
||||
readonly Dictionary<string, Sprite> spsprites;
|
||||
readonly Sprite[] shimSprites;
|
||||
readonly Sprite blank;
|
||||
|
||||
@@ -55,23 +56,34 @@ namespace OpenRa.Game
|
||||
bool hadRadar = false;
|
||||
bool optionsPressed = false;
|
||||
const int MinRows = 4;
|
||||
|
||||
string currentTab = "Building";
|
||||
static string[] groups = new string[] { "Building", "Defense", "Infantry", "Vehicle", "Plane", "Ship" };
|
||||
readonly Dictionary<string, Sprite> sprites;
|
||||
|
||||
const int NumClockFrames = 54;
|
||||
|
||||
public Chrome(Renderer r)
|
||||
{
|
||||
// Positioning of chrome elements
|
||||
// Build palette
|
||||
paletteColumns = 4;
|
||||
paletteOrigin = new int2(Game.viewport.Width - paletteColumns * 64 - 9 - 20, 240 - 9);
|
||||
paletteOrigin = new int2(Game.viewport.Width - paletteColumns * 64 - 9 - 20, 282);
|
||||
|
||||
this.renderer = r;
|
||||
specialBin = new Sheet(renderer, "specialbin.png");
|
||||
chromeRenderer = new SpriteRenderer(renderer, true, renderer.RgbaSpriteShader);
|
||||
chromeTexture = new Sheet(renderer, "specialbin.png");
|
||||
rgbaRenderer = new SpriteRenderer(renderer, true, renderer.RgbaSpriteShader);
|
||||
lineRenderer = new LineRenderer(renderer);
|
||||
buildPaletteRenderer = new SpriteRenderer(renderer, true);
|
||||
shpRenderer = new SpriteRenderer(renderer, true);
|
||||
|
||||
specialBinSprite = new Sprite(specialBin, new Rectangle(0, 0, 32, 192), TextureChannel.Alpha);
|
||||
moneyBinSprite = new Sprite(specialBin, new Rectangle(512 - 320, 0, 320, 32), TextureChannel.Alpha);
|
||||
tooltipSprite = new Sprite(specialBin, new Rectangle(0, 288, 272, 136), TextureChannel.Alpha);
|
||||
specialBinSprites = new []
|
||||
{
|
||||
new Sprite(chromeTexture, new Rectangle(0, 0, 32, 51), TextureChannel.Alpha),
|
||||
new Sprite(chromeTexture, new Rectangle(0, 51, 32, 51 /*144*/), TextureChannel.Alpha),
|
||||
new Sprite(chromeTexture, new Rectangle(0, 192-39, 32, 39 ), TextureChannel.Alpha),
|
||||
};
|
||||
moneyBinSprite = new Sprite(chromeTexture, new Rectangle(512 - 320, 0, 320, 32), TextureChannel.Alpha);
|
||||
tooltipSprite = new Sprite(chromeTexture, new Rectangle(0, 288, 272, 136), TextureChannel.Alpha);
|
||||
|
||||
var powerIndicator = new Animation("power");
|
||||
powerIndicator.PlayRepeating("power-level-indicator");
|
||||
@@ -116,10 +128,15 @@ namespace OpenRa.Game
|
||||
u => u,
|
||||
u => SpriteSheetBuilder.LoadAllSprites(Rules.UnitInfo[u].Icon ?? (u + "icon"))[0]);
|
||||
|
||||
spsprites = Rules.SupportPowerInfo
|
||||
.ToDictionary(
|
||||
u => u.Key,
|
||||
u => SpriteSheetBuilder.LoadAllSprites(u.Value.Image)[0]);
|
||||
|
||||
tabSprites = groups.Select(
|
||||
(g, i) => Pair.New(g,
|
||||
OpenRa.Game.Graphics.Util.MakeArray(3,
|
||||
n => new Sprite(specialBin,
|
||||
n => new Sprite(chromeTexture,
|
||||
new Rectangle(512 - (n + 1) * 27, 64 + i * 40, 27, 40),
|
||||
TextureChannel.Alpha))))
|
||||
.ToDictionary(a => a.First, a => a.Second);
|
||||
@@ -128,15 +145,15 @@ namespace OpenRa.Game
|
||||
cantBuild.PlayFetchIndex("idle", () => 0);
|
||||
|
||||
digitSprites = Graphics.Util.MakeArray(10, a => a)
|
||||
.Select(n => new Sprite(specialBin, new Rectangle(32 + 13 * n, 0, 13, 17), TextureChannel.Alpha)).ToList();
|
||||
.Select(n => new Sprite(chromeTexture, new Rectangle(32 + 13 * n, 0, 13, 17), TextureChannel.Alpha)).ToList();
|
||||
|
||||
shimSprites = new[]
|
||||
{
|
||||
new Sprite( specialBin, new Rectangle( 0, 192, 9, 10 ), TextureChannel.Alpha ),
|
||||
new Sprite( specialBin, new Rectangle( 0, 202, 9, 10 ), TextureChannel.Alpha ),
|
||||
new Sprite( specialBin, new Rectangle( 0, 216, 9, 48 ), TextureChannel.Alpha ),
|
||||
new Sprite( specialBin, new Rectangle( 11, 192, 64, 10 ), TextureChannel.Alpha ),
|
||||
new Sprite( specialBin, new Rectangle( 11, 202, 64, 10 ), TextureChannel.Alpha ),
|
||||
new Sprite( chromeTexture, new Rectangle( 0, 192, 9, 10 ), TextureChannel.Alpha ),
|
||||
new Sprite( chromeTexture, new Rectangle( 0, 202, 9, 10 ), TextureChannel.Alpha ),
|
||||
new Sprite( chromeTexture, new Rectangle( 0, 216, 9, 48 ), TextureChannel.Alpha ),
|
||||
new Sprite( chromeTexture, new Rectangle( 11, 192, 64, 10 ), TextureChannel.Alpha ),
|
||||
new Sprite( chromeTexture, new Rectangle( 11, 202, 64, 10 ), TextureChannel.Alpha ),
|
||||
};
|
||||
|
||||
ready = new Animation("pips");
|
||||
@@ -163,15 +180,15 @@ namespace OpenRa.Game
|
||||
|
||||
DrawMinimap();
|
||||
|
||||
chromeRenderer.DrawSprite(specialBinSprite, float2.Zero, PaletteType.Chrome);
|
||||
chromeRenderer.DrawSprite(moneyBinSprite, new float2(Game.viewport.Width - 320, 0), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(moneyBinSprite, new float2(Game.viewport.Width - 320, 0), PaletteType.Chrome);
|
||||
|
||||
DrawMoney();
|
||||
DrawPower();
|
||||
chromeRenderer.Flush();
|
||||
rgbaRenderer.Flush();
|
||||
DrawButtons();
|
||||
|
||||
int paletteHeight = DrawBuildPalette(currentTab);
|
||||
DrawSupportPowers();
|
||||
DrawBuildTabs(paletteHeight);
|
||||
DrawChat();
|
||||
DrawOptionsMenu();
|
||||
@@ -186,9 +203,10 @@ namespace OpenRa.Game
|
||||
if (hasRadar != hadRadar)
|
||||
Sound.Play((hasRadar) ? "radaron2.aud" : "radardn1.aud");
|
||||
hadRadar = hasRadar;
|
||||
|
||||
var isJammed = false; // todo: MRJ can do this
|
||||
|
||||
if (hasRadar)
|
||||
Game.minimap.Draw(new float2(Game.viewport.Width - 256, 8));
|
||||
Game.minimap.Draw(new float2(Game.viewport.Width - 247, 10), hasRadar, isJammed);
|
||||
}
|
||||
|
||||
void AddButton(Rectangle r, Action<bool> b) { buttons.Add(Pair.New(r, b)); }
|
||||
@@ -220,24 +238,20 @@ namespace OpenRa.Game
|
||||
|
||||
// Don't let tabs overlap the bevel
|
||||
if (y > paletteOrigin.Y + paletteHeight - tabHeight - 9 && y < paletteOrigin.Y + paletteHeight)
|
||||
{
|
||||
y += tabHeight;
|
||||
}
|
||||
|
||||
// Stick tabs to the edge of the screen
|
||||
if (y > paletteOrigin.Y + paletteHeight)
|
||||
{
|
||||
x = Game.viewport.Width - tabWidth;
|
||||
}
|
||||
|
||||
chromeRenderer.DrawSprite(q.Value[index], new float2(x, y), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(q.Value[index], new float2(x, y), PaletteType.Chrome);
|
||||
|
||||
buttons.Add(Pair.New(new Rectangle(x, y, tabWidth, tabHeight),
|
||||
(Action<bool>)(isLmb => currentTab = groupName)));
|
||||
y += tabHeight;
|
||||
}
|
||||
|
||||
chromeRenderer.Flush();
|
||||
rgbaRenderer.Flush();
|
||||
}
|
||||
|
||||
void CheckDeadTab( string groupName )
|
||||
@@ -259,7 +273,7 @@ namespace OpenRa.Game
|
||||
var x = Game.viewport.Width - 155;
|
||||
foreach (var d in moneyDigits.Reverse())
|
||||
{
|
||||
chromeRenderer.DrawSprite(digitSprites[d - '0'], new float2(x, 6), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(digitSprites[d - '0'], new float2(x, 6), PaletteType.Chrome);
|
||||
x -= 14;
|
||||
}
|
||||
}
|
||||
@@ -270,11 +284,11 @@ namespace OpenRa.Game
|
||||
void DrawPower()
|
||||
{
|
||||
//draw background
|
||||
float2 powerOrigin = Game.viewport.Location+new float2(Game.viewport.Width - 20, 240 - 9);
|
||||
float2 powerOrigin = Game.viewport.Location + new float2(Game.viewport.Width - 20, paletteOrigin.Y);
|
||||
|
||||
buildPaletteRenderer.DrawSprite(powerLevelTopSprite, powerOrigin, PaletteType.Chrome);
|
||||
buildPaletteRenderer.DrawSprite(powerLevelBottomSprite, powerOrigin + new float2(0, powerLevelTopSprite.size.Y), PaletteType.Chrome);
|
||||
buildPaletteRenderer.Flush();
|
||||
shpRenderer.DrawSprite(powerLevelTopSprite, powerOrigin, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(powerLevelBottomSprite, powerOrigin + new float2(0, powerLevelTopSprite.size.Y), PaletteType.Chrome);
|
||||
shpRenderer.Flush();
|
||||
float2 top = powerOrigin + new float2(0, 15);
|
||||
float2 bottom = powerOrigin + new float2(0, powerLevelTopSprite.size.Y + powerLevelBottomSprite.size.Y) - new float2(0, 50);
|
||||
|
||||
@@ -306,43 +320,12 @@ namespace OpenRa.Game
|
||||
//draw indicator
|
||||
float2 drainedPosition = new float2(bottom.X + 2, lastPowerDrainedPos.Value + Game.viewport.Location.Y);
|
||||
|
||||
buildPaletteRenderer.DrawSprite(powerIndicatorSprite, drainedPosition, PaletteType.Chrome);
|
||||
buildPaletteRenderer.Flush();
|
||||
shpRenderer.DrawSprite(powerIndicatorSprite, drainedPosition, PaletteType.Chrome);
|
||||
shpRenderer.Flush();
|
||||
}
|
||||
|
||||
void DrawButtons()
|
||||
{
|
||||
// Chronoshift
|
||||
Rectangle chronoshiftRect = new Rectangle(6, 14, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height);
|
||||
var chronoshiftDrawPos = Game.viewport.Location + new float2(chronoshiftRect.Location);
|
||||
|
||||
var hasChronosphere = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains<Chronosphere>());
|
||||
|
||||
if (!hasChronosphere)
|
||||
repairButton.ReplaceAnim("disabled");
|
||||
else
|
||||
{
|
||||
//repairButton.ReplaceAnim(Game.controller.orderGenerator is RepairOrderGenerator ? "pressed" : "normal");
|
||||
AddButton(chronoshiftRect, isLmb => HandleChronosphereButton());
|
||||
}
|
||||
buildPaletteRenderer.DrawSprite(repairButton.Image, chronoshiftDrawPos, PaletteType.Chrome);
|
||||
|
||||
// Iron Curtain
|
||||
Rectangle curtainRect = new Rectangle(6, 14+50, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height);
|
||||
var curtainDrawPos = Game.viewport.Location + new float2(curtainRect.Location);
|
||||
|
||||
var hasCurtain = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains<IronCurtain>());
|
||||
|
||||
if (!hasCurtain)
|
||||
repairButton.ReplaceAnim("disabled");
|
||||
else
|
||||
{
|
||||
//repairButton.ReplaceAnim(Game.controller.orderGenerator is RepairOrderGenerator ? "pressed" : "normal");
|
||||
AddButton(curtainRect, isLmb => HandleIronCurtainButton());
|
||||
}
|
||||
buildPaletteRenderer.DrawSprite(repairButton.Image, curtainDrawPos, PaletteType.Chrome);
|
||||
|
||||
|
||||
// Repair
|
||||
Rectangle repairRect = new Rectangle(Game.viewport.Width - 120, 5, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height);
|
||||
var repairDrawPos = Game.viewport.Location + new float2(repairRect.Location);
|
||||
@@ -356,7 +339,7 @@ namespace OpenRa.Game
|
||||
repairButton.ReplaceAnim(Game.controller.orderGenerator is RepairOrderGenerator ? "pressed" : "normal");
|
||||
AddButton(repairRect, isLmb => Game.controller.ToggleInputMode<RepairOrderGenerator>());
|
||||
}
|
||||
buildPaletteRenderer.DrawSprite(repairButton.Image, repairDrawPos, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(repairButton.Image, repairDrawPos, PaletteType.Chrome);
|
||||
|
||||
// Sell
|
||||
Rectangle sellRect = new Rectangle(Game.viewport.Width - 80, 5,
|
||||
@@ -367,8 +350,8 @@ namespace OpenRa.Game
|
||||
sellButton.ReplaceAnim(Game.controller.orderGenerator is SellOrderGenerator ? "pressed" : "normal");
|
||||
|
||||
AddButton(sellRect, isLmb => Game.controller.ToggleInputMode<SellOrderGenerator>());
|
||||
buildPaletteRenderer.DrawSprite(sellButton.Image, sellDrawPos, PaletteType.Chrome);
|
||||
buildPaletteRenderer.Flush();
|
||||
shpRenderer.DrawSprite(sellButton.Image, sellDrawPos, PaletteType.Chrome);
|
||||
shpRenderer.Flush();
|
||||
|
||||
if (Game.Settings.PowerDownBuildings)
|
||||
{
|
||||
@@ -381,12 +364,12 @@ namespace OpenRa.Game
|
||||
pwrdownButton.ReplaceAnim(Game.controller.orderGenerator is PowerDownOrderGenerator ? "pressed" : "normal");
|
||||
|
||||
AddButton(pwrdownRect, isLmb => Game.controller.ToggleInputMode<PowerDownOrderGenerator>());
|
||||
buildPaletteRenderer.DrawSprite(pwrdownButton.Image, pwrdownDrawPos, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(pwrdownButton.Image, pwrdownDrawPos, PaletteType.Chrome);
|
||||
}
|
||||
buildPaletteRenderer.Flush();
|
||||
shpRenderer.Flush();
|
||||
|
||||
//Options
|
||||
Rectangle optionsRect = new Rectangle(0 + 40,0, optionsButton.Image.bounds.Width,
|
||||
Rectangle optionsRect = new Rectangle(0,0, optionsButton.Image.bounds.Width,
|
||||
optionsButton.Image.bounds.Height);
|
||||
|
||||
var optionsDrawPos = Game.viewport.Location + new float2(optionsRect.Location);
|
||||
@@ -394,8 +377,8 @@ namespace OpenRa.Game
|
||||
optionsButton.ReplaceAnim(optionsPressed ? "left-pressed" : "left-normal");
|
||||
|
||||
AddButton(optionsRect, isLmb => optionsPressed = !optionsPressed);
|
||||
buildPaletteRenderer.DrawSprite(optionsButton.Image, optionsDrawPos, PaletteType.Chrome);
|
||||
buildPaletteRenderer.Flush();
|
||||
shpRenderer.DrawSprite(optionsButton.Image, optionsDrawPos, PaletteType.Chrome);
|
||||
shpRenderer.Flush();
|
||||
|
||||
renderer.DrawText("Options", new int2(80, -2) , Color.White);
|
||||
}
|
||||
@@ -413,37 +396,25 @@ namespace OpenRa.Game
|
||||
var backgroundDrawPos = menuDrawPos + new float2( (width - optionsBackground.bounds.Width)/2, (height - optionsBackground.bounds.Height)/2);
|
||||
|
||||
//draw background
|
||||
buildPaletteRenderer.DrawSprite(optionsBackground, backgroundDrawPos, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsBackground, backgroundDrawPos, PaletteType.Chrome);
|
||||
|
||||
//draw borders
|
||||
buildPaletteRenderer.DrawSprite(optionsTopLeft, menuDrawPos, PaletteType.Chrome);
|
||||
buildPaletteRenderer.DrawSprite(optionsLeft, menuDrawPos + new float2(0, optionsTopLeft.bounds.Height), PaletteType.Chrome);
|
||||
buildPaletteRenderer.DrawSprite(optionsBottomLeft, menuDrawPos + new float2(0, optionsTopLeft.bounds.Height + optionsLeft.bounds.Height), PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsTopLeft, menuDrawPos, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsLeft, menuDrawPos + new float2(0, optionsTopLeft.bounds.Height), PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsBottomLeft, menuDrawPos + new float2(0, optionsTopLeft.bounds.Height + optionsLeft.bounds.Height), PaletteType.Chrome);
|
||||
|
||||
buildPaletteRenderer.DrawSprite(optionsTop, menuDrawPos + new float2(optionsTopLeft.bounds.Width, 0), PaletteType.Chrome);
|
||||
buildPaletteRenderer.DrawSprite(optionsTopRight, menuDrawPos + new float2(optionsTopLeft.bounds.Width + optionsTop.bounds.Width, 0), PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsTop, menuDrawPos + new float2(optionsTopLeft.bounds.Width, 0), PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsTopRight, menuDrawPos + new float2(optionsTopLeft.bounds.Width + optionsTop.bounds.Width, 0), PaletteType.Chrome);
|
||||
|
||||
buildPaletteRenderer.DrawSprite(optionsBottom, menuDrawPos + new float2(optionsTopLeft.bounds.Width, optionsTopLeft.bounds.Height + optionsLeft.bounds.Height +adjust), PaletteType.Chrome);
|
||||
buildPaletteRenderer.DrawSprite(optionsBottomRight, menuDrawPos + new float2(optionsBottomLeft.bounds.Width + optionsBottom.bounds.Width, optionsTopLeft.bounds.Height + optionsLeft.bounds.Height), PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsBottom, menuDrawPos + new float2(optionsTopLeft.bounds.Width, optionsTopLeft.bounds.Height + optionsLeft.bounds.Height +adjust), PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsBottomRight, menuDrawPos + new float2(optionsBottomLeft.bounds.Width + optionsBottom.bounds.Width, optionsTopLeft.bounds.Height + optionsLeft.bounds.Height), PaletteType.Chrome);
|
||||
|
||||
buildPaletteRenderer.DrawSprite(optionsRight, menuDrawPos + new float2(optionsTopLeft.bounds.Width + optionsTop.bounds.Width + adjust + 1, optionsTopRight.bounds.Height), PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(optionsRight, menuDrawPos + new float2(optionsTopLeft.bounds.Width + optionsTop.bounds.Width + adjust + 1, optionsTopRight.bounds.Height), PaletteType.Chrome);
|
||||
|
||||
buildPaletteRenderer.Flush();
|
||||
shpRenderer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
void HandleChronosphereButton()
|
||||
{
|
||||
if (Game.controller.ToggleInputMode<ChronosphereSelectOrderGenerator>())
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
|
||||
void HandleIronCurtainButton()
|
||||
{
|
||||
if (Game.controller.ToggleInputMode<IronCurtainOrderGenerator>())
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
|
||||
|
||||
void DrawChat()
|
||||
{
|
||||
var chatpos = new int2(400, Game.viewport.Height - 20);
|
||||
@@ -464,22 +435,6 @@ namespace OpenRa.Game
|
||||
renderer.DrawText(line.b, p, line.a);
|
||||
renderer.DrawText(line.c, p + new int2(size.X + 10, 0), Color.White);
|
||||
}
|
||||
|
||||
string currentTab = "Building";
|
||||
static string[] groups = new string[] { "Building", "Defense", "Infantry", "Vehicle", "Plane", "Ship" };
|
||||
Dictionary<string, Sprite> sprites;
|
||||
|
||||
const int NumClockFrames = 54;
|
||||
Func<int> ClockAnimFrame(string group)
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var queue = Game.LocalPlayer.PlayerActor.traits.Get<Traits.ProductionQueue>();
|
||||
var producing = queue.CurrentItem( group );
|
||||
if (producing == null) return 0;
|
||||
return (producing.TotalTime - producing.RemainingTime) * NumClockFrames / producing.TotalTime;
|
||||
};
|
||||
}
|
||||
|
||||
// Return an int telling us the y coordinate at the bottom of the palette
|
||||
int DrawBuildPalette(string queueName)
|
||||
@@ -511,7 +466,7 @@ namespace OpenRa.Game
|
||||
var drawPos = Game.viewport.Location + new float2(rect.Location);
|
||||
var isBuildingSomething = queue.CurrentItem(queueName) != null;
|
||||
|
||||
buildPaletteRenderer.DrawSprite(sprites[item], drawPos, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(sprites[item], drawPos, PaletteType.Chrome);
|
||||
|
||||
var firstOfThis = queue.AllItems(queueName).FirstOrDefault(a => a.Item == item);
|
||||
|
||||
@@ -527,7 +482,7 @@ namespace OpenRa.Game
|
||||
* NumClockFrames / firstOfThis.TotalTime);
|
||||
clock.Tick();
|
||||
|
||||
buildPaletteRenderer.DrawSprite(clock.Image, drawPos, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(clock.Image, drawPos, PaletteType.Chrome);
|
||||
|
||||
if (firstOfThis.Done)
|
||||
{
|
||||
@@ -567,28 +522,28 @@ namespace OpenRa.Game
|
||||
{
|
||||
var rect = new Rectangle(origin.X + x * 64, origin.Y + 48 * y, 64, 48);
|
||||
var drawPos = Game.viewport.Location + new float2(rect.Location);
|
||||
buildPaletteRenderer.DrawSprite(blank, drawPos, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(blank, drawPos, PaletteType.Chrome);
|
||||
AddButton(rect, _ => { });
|
||||
if (++x == columns) { x = 0; y++; }
|
||||
}
|
||||
|
||||
foreach (var ob in overlayBits)
|
||||
buildPaletteRenderer.DrawSprite(ob.First, ob.Second, PaletteType.Chrome);
|
||||
shpRenderer.DrawSprite(ob.First, ob.Second, PaletteType.Chrome);
|
||||
|
||||
buildPaletteRenderer.Flush();
|
||||
shpRenderer.Flush();
|
||||
|
||||
for (var j = 0; j < y; j++)
|
||||
chromeRenderer.DrawSprite(shimSprites[2], new float2(origin.X - 9, origin.Y + 48 * j), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(shimSprites[2], new float2(origin.X - 9, origin.Y + 48 * j), PaletteType.Chrome);
|
||||
|
||||
chromeRenderer.DrawSprite(shimSprites[0], new float2(origin.X - 9, origin.Y - 9), PaletteType.Chrome);
|
||||
chromeRenderer.DrawSprite(shimSprites[1], new float2(origin.X - 9, origin.Y - 1 + 48 * y), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(shimSprites[0], new float2(origin.X - 9, origin.Y - 9), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(shimSprites[1], new float2(origin.X - 9, origin.Y - 1 + 48 * y), PaletteType.Chrome);
|
||||
|
||||
for (var i = 0; i < columns; i++)
|
||||
{
|
||||
chromeRenderer.DrawSprite(shimSprites[3], new float2(origin.X + 64 * i, origin.Y - 9), PaletteType.Chrome);
|
||||
chromeRenderer.DrawSprite(shimSprites[4], new float2(origin.X + 64 * i, origin.Y - 1 + 48 * y), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(shimSprites[3], new float2(origin.X + 64 * i, origin.Y - 9), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(shimSprites[4], new float2(origin.X + 64 * i, origin.Y - 1 + 48 * y), PaletteType.Chrome);
|
||||
}
|
||||
chromeRenderer.Flush();
|
||||
rgbaRenderer.Flush();
|
||||
|
||||
if (tooltipItem != null)
|
||||
DrawProductionTooltip(tooltipItem, new int2(Game.viewport.Width, origin.Y + y * 48 + 9)/*tooltipPos*/);
|
||||
@@ -682,8 +637,8 @@ namespace OpenRa.Game
|
||||
void DrawProductionTooltip(string unit, int2 pos)
|
||||
{
|
||||
var p = pos.ToFloat2() - new float2(tooltipSprite.size.X, 0);
|
||||
chromeRenderer.DrawSprite(tooltipSprite, p, PaletteType.Chrome);
|
||||
chromeRenderer.Flush();
|
||||
rgbaRenderer.DrawSprite(tooltipSprite, p, PaletteType.Chrome);
|
||||
rgbaRenderer.Flush();
|
||||
|
||||
var info = Rules.UnitInfo[unit];
|
||||
|
||||
@@ -717,5 +672,100 @@ namespace OpenRa.Game
|
||||
renderer.DrawText(info.LongDesc.Replace( "\\n", "\n" ), p.ToInt2(), Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSupportPowers()
|
||||
{
|
||||
var numPowers = Game.LocalPlayer.SupportPowers.Values
|
||||
.Where(a => a.IsAvailable).Count();
|
||||
|
||||
if (numPowers == 0) return;
|
||||
|
||||
rgbaRenderer.DrawSprite(specialBinSprites[0], new float2(0,14), PaletteType.Chrome);
|
||||
for (var i = 1; i < numPowers; i++)
|
||||
rgbaRenderer.DrawSprite(specialBinSprites[1], new float2(0, 14 + i * 51), PaletteType.Chrome);
|
||||
rgbaRenderer.DrawSprite(specialBinSprites[2], new float2(0, 14 + numPowers * 51), PaletteType.Chrome);
|
||||
|
||||
rgbaRenderer.Flush();
|
||||
|
||||
var y = 24;
|
||||
|
||||
string tooltipItem = null;
|
||||
int2 tooltipPos = int2.Zero;
|
||||
|
||||
foreach (var sp in Game.LocalPlayer.SupportPowers)
|
||||
{
|
||||
var image = spsprites[sp.Key];
|
||||
if (sp.Value.IsAvailable)
|
||||
{
|
||||
var drawPos = Game.viewport.Location + new float2(5, y);
|
||||
shpRenderer.DrawSprite(image, drawPos, PaletteType.Chrome);
|
||||
|
||||
clock.PlayFetchIndex("idle",
|
||||
() => (sp.Value.TotalTime - sp.Value.RemainingTime)
|
||||
* NumClockFrames / sp.Value.TotalTime);
|
||||
clock.Tick();
|
||||
|
||||
shpRenderer.DrawSprite(clock.Image, drawPos, PaletteType.Chrome);
|
||||
|
||||
var rect = new Rectangle(5, y, 64, 48);
|
||||
if (sp.Value.IsDone)
|
||||
{
|
||||
ready.Play("ready");
|
||||
shpRenderer.DrawSprite(ready.Image,
|
||||
drawPos + new float2((64 - ready.Image.size.X) / 2, 2),
|
||||
PaletteType.Chrome);
|
||||
|
||||
AddButton(rect, HandleSupportPower( sp.Value ));
|
||||
}
|
||||
|
||||
if (rect.Contains(lastMousePos.ToPoint()))
|
||||
{
|
||||
tooltipItem = sp.Key;
|
||||
tooltipPos = drawPos.ToInt2() + new int2(72, 0) - Game.viewport.Location.ToInt2();
|
||||
}
|
||||
|
||||
y += 51;
|
||||
}
|
||||
}
|
||||
|
||||
shpRenderer.Flush();
|
||||
|
||||
if (tooltipItem != null)
|
||||
DrawSupportPowerTooltip(tooltipItem, tooltipPos);
|
||||
}
|
||||
|
||||
Action<bool> HandleSupportPower(SupportPower sp)
|
||||
{
|
||||
return b => { if (b) sp.Activate(); };
|
||||
}
|
||||
|
||||
string FormatTime(int ticks)
|
||||
{
|
||||
var seconds = ticks / 25;
|
||||
var minutes = seconds / 60;
|
||||
|
||||
return "{0:D2}:{1:D2}".F(minutes, seconds % 60);
|
||||
}
|
||||
|
||||
void DrawSupportPowerTooltip(string sp, int2 pos)
|
||||
{
|
||||
rgbaRenderer.DrawSprite(tooltipSprite, pos, PaletteType.Chrome);
|
||||
rgbaRenderer.Flush();
|
||||
|
||||
var info = Rules.SupportPowerInfo[sp];
|
||||
|
||||
pos += new int2(5, 5);
|
||||
|
||||
renderer.DrawText2(info.Description, pos, Color.White);
|
||||
|
||||
var timer = "Charge Time: {0}".F(FormatTime(Game.LocalPlayer.SupportPowers[sp].RemainingTime));
|
||||
DrawRightAligned(timer, pos + new int2((int)tooltipSprite.size.X - 10, 0), Color.White);
|
||||
|
||||
if (info.LongDesc != null)
|
||||
{
|
||||
pos += new int2(0, 25);
|
||||
renderer.DrawText(info.LongDesc.Replace("\\n", "\n"), pos, Color.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,14 +147,24 @@ namespace OpenRa.Game
|
||||
|
||||
public Cursor ChooseCursor()
|
||||
{
|
||||
var mi = new MouseInput
|
||||
{
|
||||
Location = (Game.CellSize * MousePosition - Game.viewport.Location).ToInt2(),
|
||||
Button = MouseButton.Right,
|
||||
Modifiers = GetModifierKeys(),
|
||||
};
|
||||
int sync = Game.world.SyncHash();
|
||||
|
||||
return orderGenerator.GetCursor(MousePosition.ToInt2(), mi);
|
||||
try
|
||||
{
|
||||
var mi = new MouseInput
|
||||
{
|
||||
Location = ( Game.CellSize * MousePosition - Game.viewport.Location ).ToInt2(),
|
||||
Button = MouseButton.Right,
|
||||
Modifiers = GetModifierKeys(),
|
||||
};
|
||||
|
||||
return orderGenerator.GetCursor( MousePosition.ToInt2(), mi );
|
||||
}
|
||||
finally
|
||||
{
|
||||
if( sync != Game.world.SyncHash() )
|
||||
throw new InvalidOperationException( "Desync in Controller.ChooseCursor" );
|
||||
}
|
||||
}
|
||||
|
||||
Cache<int, List<Actor>> controlGroups = new Cache<int, List<Actor>>(_ => new List<Actor>());
|
||||
|
||||
0
OpenRa.Game/Effects/Bullet.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Bullet.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Corpse.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Corpse.cs
Normal file → Executable file
0
OpenRa.Game/Effects/DelayedAction.cs
Normal file → Executable file
0
OpenRa.Game/Effects/DelayedAction.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Explosion.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Explosion.cs
Normal file → Executable file
0
OpenRa.Game/Effects/FlashTarget.cs
Normal file → Executable file
0
OpenRa.Game/Effects/FlashTarget.cs
Normal file → Executable file
33
OpenRa.Game/Effects/GpsSatellite.cs
Executable file
33
OpenRa.Game/Effects/GpsSatellite.cs
Executable file
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using OpenRa.Game.Graphics;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game.Effects
|
||||
{
|
||||
class GpsSatellite : IEffect
|
||||
{
|
||||
readonly float heightPerTick = 10;
|
||||
float2 offset;
|
||||
Animation anim = new Animation("sputnik");
|
||||
|
||||
public GpsSatellite(float2 offset)
|
||||
{
|
||||
this.offset = offset;
|
||||
anim.PlayRepeating("idle");
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
anim.Tick();
|
||||
offset.Y -= heightPerTick;
|
||||
|
||||
if (offset.Y < 0)
|
||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
yield return new Renderable(anim.Image,offset, PaletteType.Gold);
|
||||
}
|
||||
}
|
||||
}
|
||||
0
OpenRa.Game/Effects/IEffect.cs
Normal file → Executable file
0
OpenRa.Game/Effects/IEffect.cs
Normal file → Executable file
0
OpenRa.Game/Effects/InvulnEffect.cs
Normal file → Executable file
0
OpenRa.Game/Effects/InvulnEffect.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Missile.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Missile.cs
Normal file → Executable file
0
OpenRa.Game/Effects/MoveFlash.cs
Normal file → Executable file
0
OpenRa.Game/Effects/MoveFlash.cs
Normal file → Executable file
20
OpenRa.Game/Effects/PowerDownIndicator.cs
Normal file → Executable file
20
OpenRa.Game/Effects/PowerDownIndicator.cs
Normal file → Executable file
@@ -9,7 +9,10 @@ namespace OpenRa.Game.Effects
|
||||
Actor a;
|
||||
Building b;
|
||||
Animation anim = new Animation("powerdown");
|
||||
|
||||
bool removeNextFrame = false;
|
||||
bool indicatorState = true;
|
||||
int stateTicks = 0;
|
||||
|
||||
public PowerDownIndicator(Actor a)
|
||||
{
|
||||
this.a = a;
|
||||
@@ -19,8 +22,19 @@ namespace OpenRa.Game.Effects
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
if (!b.Disabled || a.IsDead)
|
||||
if (removeNextFrame == true)
|
||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||
|
||||
// Fix off-by one frame bug with undisabling causing low-power
|
||||
if (!b.Disabled || a.IsDead)
|
||||
removeNextFrame = true;
|
||||
|
||||
// Flash power icon
|
||||
if (++stateTicks == 15)
|
||||
{
|
||||
stateTicks = 0;
|
||||
indicatorState = !indicatorState;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
@@ -28,7 +42,7 @@ namespace OpenRa.Game.Effects
|
||||
foreach (var r in a.Render())
|
||||
yield return r.WithPalette(PaletteType.Disabled);
|
||||
|
||||
if (b.ManuallyDisabled)
|
||||
if (b.ManuallyDisabled && indicatorState)
|
||||
yield return new Renderable(anim.Image,
|
||||
a.CenterLocation - .5f * anim.Image.size, PaletteType.Chrome);
|
||||
}
|
||||
|
||||
0
OpenRa.Game/Effects/RepairIndicator.cs
Normal file → Executable file
0
OpenRa.Game/Effects/RepairIndicator.cs
Normal file → Executable file
37
OpenRa.Game/Effects/SatelliteLaunch.cs
Executable file
37
OpenRa.Game/Effects/SatelliteLaunch.cs
Executable file
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using OpenRa.Game.Graphics;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game.Effects
|
||||
{
|
||||
class SatelliteLaunch : IEffect
|
||||
{
|
||||
int frame = 0;
|
||||
Actor a;
|
||||
Animation doors = new Animation("atek");
|
||||
float2 doorOffset = new float2(-4,0);
|
||||
|
||||
public SatelliteLaunch(Actor a)
|
||||
{
|
||||
this.a = a;
|
||||
doors.PlayThen("active",
|
||||
() => Game.world.AddFrameEndTask(w => w.Remove(this)));
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
doors.Tick();
|
||||
|
||||
if (++frame == 19)
|
||||
{
|
||||
Game.world.AddFrameEndTask(w => w.Add(new GpsSatellite(a.CenterLocation - .5f * doors.Image.size + doorOffset)));
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> Render()
|
||||
{
|
||||
yield return new Renderable(doors.Image,
|
||||
a.CenterLocation - .5f * doors.Image.size + doorOffset, PaletteType.Gold);
|
||||
}
|
||||
}
|
||||
}
|
||||
0
OpenRa.Game/Effects/Smoke.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Smoke.cs
Normal file → Executable file
@@ -1,169 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="OpenRa.Game.Game">
|
||||
<Position X="9.5" Y="9.25" Width="2.25" />
|
||||
<Members>
|
||||
<Method Name="FindUnits" Hidden="true" />
|
||||
<Field Name="lastTime" Hidden="true" />
|
||||
<Method Name="LoadMapActors" Hidden="true" />
|
||||
<Field Name="localPlayerIndex" Hidden="true" />
|
||||
<Field Name="oreFrequency" Hidden="true" />
|
||||
<Field Name="oreTicks" Hidden="true" />
|
||||
</Members>
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAaAkDQAABJAAQEEBEECEgAQQUBAAAAAIYAKBCAAwiA=</HashCode>
|
||||
<FileName>Game.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="world" />
|
||||
<Field Name="viewport" />
|
||||
<Field Name="controller" />
|
||||
<Field Name="PathFinder" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Controller">
|
||||
<Position X="6.5" Y="10.75" Width="1.75" />
|
||||
<Members>
|
||||
<Method Name="ApplyOrders" Hidden="true" />
|
||||
<Method Name="CombineSelection" Hidden="true" />
|
||||
<Field Name="controlGroups" Hidden="true" />
|
||||
<Method Name="CursorForOrderString" Hidden="true" />
|
||||
<Field Name="dragEnd" Hidden="true" />
|
||||
<Field Name="dragStart" Hidden="true" />
|
||||
<Field Name="GetModifierKeys" Hidden="true" />
|
||||
<Field Name="recentOrders" Hidden="true" />
|
||||
</Members>
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAACoAAAAAAAAAAQDEgQAABAAABAAAAAAKAACCAA=</HashCode>
|
||||
<FileName>Controller.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="orderGenerator" />
|
||||
</ShowAsAssociation>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.Viewport">
|
||||
<Position X="13.5" Y="10.25" Width="1.75" />
|
||||
<Members>
|
||||
<Field Name="cursorFrame" Hidden="true" />
|
||||
<Field Name="cursorRenderer" Hidden="true" />
|
||||
<Field Name="dragRegion" Hidden="true" />
|
||||
<Field Name="mousePos" Hidden="true" />
|
||||
<Field Name="renderer" Hidden="true" />
|
||||
<Field Name="screenSize" Hidden="true" />
|
||||
<Field Name="scrollPosition" Hidden="true" />
|
||||
</Members>
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAIAAAAABAAACABCAAYAEEAAAABAAAAAAAAgAEEIwBE=</HashCode>
|
||||
<FileName>Graphics\Viewport.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.World">
|
||||
<Position X="4.75" Y="17.25" Width="2" />
|
||||
<Members>
|
||||
<Field Name="actors" Hidden="true" />
|
||||
<Field Name="effects" Hidden="true" />
|
||||
<Field Name="frameEndActions" Hidden="true" />
|
||||
<Field Name="nextAID" Hidden="true" />
|
||||
</Members>
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAIAACABAAABgAAAAYQABAAEAAAAAAAAAAAAAAAAQBA=</HashCode>
|
||||
<FileName>World.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsCollectionAssociation>
|
||||
<Property Name="Actors" />
|
||||
</ShowAsCollectionAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Actor">
|
||||
<Position X="9.5" Y="16.75" Width="1.75" />
|
||||
<Members>
|
||||
<Field Name="currentActivity" Hidden="true" />
|
||||
</Members>
|
||||
<TypeIdentifier>
|
||||
<HashCode>AgEACACAAAAAAAAAAQIAEIAkAQQAAAAAABAgAEAAQgA=</HashCode>
|
||||
<FileName>Actor.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="Owner" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.GameRules.UnitInfo" Collapsed="true">
|
||||
<Position X="11" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ACIAAAKAAJAgwiAAgAAAgFQAJAhQAHAAGCACAADIRAA=</HashCode>
|
||||
<FileName>GameRules\UnitInfo.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Player">
|
||||
<Position X="11.75" Y="16.75" Width="2.25" />
|
||||
<Members>
|
||||
<Field Name="displayCashDeltaPerFrame" Hidden="true" />
|
||||
<Method Name="GiveAdvice" Hidden="true" />
|
||||
<Method Name="UpdatePower" Hidden="true" />
|
||||
</Members>
|
||||
<TypeIdentifier>
|
||||
<HashCode>QEEEAAQAAAIAQQAACAMAACCAAAAAAA0gCAEAAQABQAA=</HashCode>
|
||||
<FileName>Player.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.GameRules.MobileInfo" Collapsed="true">
|
||||
<Position X="9.75" Y="3.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAQAAAAAAAAAAAABAQAAAAAAAAAAAAAAAAg=</HashCode>
|
||||
<FileName>GameRules\UnitInfo.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.GameRules.BuildingInfo" Collapsed="true">
|
||||
<Position X="13.25" Y="3.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAJQAAAIAAAAgAAACAAAABIAAAICAAABAAAAQAAAAgA=</HashCode>
|
||||
<FileName>GameRules\UnitInfo.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.GameRules.InfantryInfo" Collapsed="true">
|
||||
<Position X="8.75" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAEEAAAAABIAAAAAAAAAAAAAAAACAAAQA=</HashCode>
|
||||
<FileName>GameRules\UnitInfo.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.GameRules.VehicleInfo" Collapsed="true">
|
||||
<Position X="11" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAEAAAAAAAAAAAAAEAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>GameRules\UnitInfo.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.GameRules.ActorInfo" Collapsed="true">
|
||||
<Position X="11" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>GameRules\ActorInfo.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.PathFinder">
|
||||
<Position X="9.25" Y="6.25" Width="1.75" />
|
||||
<Members>
|
||||
<Method Name="AvoidUnitsNear" Hidden="true" />
|
||||
<Method Name="CheckSanePath" Hidden="true" />
|
||||
<Method Name="CheckSanePath2" Hidden="true" />
|
||||
<Method Name="FindBidiPath" Hidden="true" />
|
||||
<Method Name="IsBlocked" Hidden="true" />
|
||||
<Method Name="MakeBidiPath" Hidden="true" />
|
||||
<Method Name="MakePath" Hidden="true" />
|
||||
<Field Name="passableCost" Hidden="true" />
|
||||
</Members>
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAgAACAAAICAAgAEoAAMAAAAAAAAgA=</HashCode>
|
||||
<FileName>PathFinder.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Interface Name="OpenRa.Game.IOrderGenerator">
|
||||
<Position X="3.5" Y="12" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAQAA=</HashCode>
|
||||
<FileName>IOrderGenerator.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Interface>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
@@ -84,11 +84,12 @@ namespace OpenRa.Game
|
||||
|
||||
Rules.Map.InitOreDensity();
|
||||
worldRenderer = new WorldRenderer(renderer);
|
||||
minimap = new Minimap(renderer);
|
||||
|
||||
SequenceProvider.Initialize(usingAftermath);
|
||||
viewport = new Viewport(clientSize, Rules.Map.Offset, Rules.Map.Offset + Rules.Map.Size, renderer);
|
||||
|
||||
minimap = new Minimap(renderer);
|
||||
|
||||
BuildingInfluence = new BuildingInfluenceMap();
|
||||
UnitInfluence = new UnitInfluenceMap();
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ using System.Text;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.Graphics;
|
||||
using IjwFramework.Types;
|
||||
using System.Collections;
|
||||
|
||||
namespace OpenRa.Game.GameRules
|
||||
{
|
||||
class InfoLoader<T>
|
||||
class InfoLoader<T> : IEnumerable<KeyValuePair<string, T>>
|
||||
{
|
||||
readonly Dictionary<string, T> infos = new Dictionary<string, T>();
|
||||
|
||||
@@ -28,9 +29,7 @@ namespace OpenRa.Game.GameRules
|
||||
get { return infos[name.ToLowerInvariant()]; }
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
|
||||
{
|
||||
return infos.GetEnumerator();
|
||||
}
|
||||
public IEnumerator<KeyValuePair<string, T>> GetEnumerator() { return infos.GetEnumerator(); }
|
||||
IEnumerator IEnumerable.GetEnumerator() { return infos.GetEnumerator(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace OpenRa.Game.GameRules
|
||||
{
|
||||
public class SupportPowerInfo
|
||||
{
|
||||
public readonly bool Powered = true;
|
||||
public readonly bool OneShot = false;
|
||||
public readonly int ChargeTime = 0;
|
||||
public readonly float ChargeTime = 0;
|
||||
public readonly string Image;
|
||||
public readonly string Description = "";
|
||||
public readonly string LongDesc = "";
|
||||
public readonly string[] Prerequisite = { };
|
||||
public readonly int TechLevel = -1;
|
||||
public readonly bool GivenAuto = true;
|
||||
public readonly string Impl = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenRa.Game.GameRules
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> BuildableItems( Player player, params string[] categories )
|
||||
{
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="OpenRa.Game.Graphics.Animation">
|
||||
<Position X="15.75" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQCgACAAAAAAAAAAAAAAAAAAAAEABAEgAAAAQQIQAA=</HashCode>
|
||||
<FileName>Graphics\Animation.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsCollectionAssociation>
|
||||
<Property Name="Images" />
|
||||
</ShowAsCollectionAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.Viewport">
|
||||
<Position X="4.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAQAABAAAgAAAAIYAAEAAAABCAAAAAABgAAAAgAE=</HashCode>
|
||||
<FileName>Graphics\Viewport.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="renderer" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.HardwarePalette">
|
||||
<Position X="9.75" Y="10" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAQAAAAA=</HashCode>
|
||||
<FileName>Graphics\HardwarePalette.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.Region" Collapsed="true">
|
||||
<Position X="18.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AIQAAAAAAAAAggAABAIAIAQCAAAAAGAAAAAAAAAQAAA=</HashCode>
|
||||
<FileName>Graphics\Region.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.Renderer">
|
||||
<Position X="4.25" Y="5.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>QACAEAAGAAAAAgMAAAAAAAAAAAAAAAAAAAAAAEAAAAA=</HashCode>
|
||||
<FileName>Graphics\Renderer.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.Sheet">
|
||||
<Position X="9.75" Y="6" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAACAgAAACAgAAAAIAAAAAgAAAAIAAAAggAA=</HashCode>
|
||||
<FileName>Graphics\Sheet.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="renderer" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.SheetBuilder">
|
||||
<Position X="1.25" Y="6" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AQIACAAAAAAAIQAAAAAAAAAAgAAAAIAAAEAAAAACgAA=</HashCode>
|
||||
<FileName>Graphics\SheetBuilder.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="renderer" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.Sprite">
|
||||
<Position X="12.75" Y="6.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAQAAIAAAAIAAAAAAAAAAAAABAAACAAAEAgA=</HashCode>
|
||||
<FileName>Graphics\Sprite.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="sheet" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.SpriteRenderer">
|
||||
<Position X="6.75" Y="5.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAQQAAAAECAAAAAAAAAAAAAABAQABAAAAAAAACIwAQ=</HashCode>
|
||||
<FileName>Graphics\SpriteRenderer.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="currentSheet" />
|
||||
<Field Name="renderer" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.SpriteSheetBuilder">
|
||||
<Position X="12.75" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAACAAAA=</HashCode>
|
||||
<FileName>Graphics\SpriteSheetBuilder.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsCollectionAssociation>
|
||||
<Field Name="sprites" />
|
||||
</ShowAsCollectionAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.TerrainRenderer">
|
||||
<Position X="7" Y="2.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AACQEAAAAAAAAgAAAAAACAAAABgAAAAAAAAAAAAAgAA=</HashCode>
|
||||
<FileName>Graphics\TerrainRenderer.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Field Name="renderer" />
|
||||
<Field Name="terrainSheet" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="OpenRa.Game.Graphics.UnitSheetBuilder">
|
||||
<Position X="15.75" Y="6" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAgAAAAAAAAAAAAAAAAQAAAAAAAQAAAACAAAA=</HashCode>
|
||||
<FileName>Graphics\UnitSheetBuilder.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsCollectionAssociation>
|
||||
<Field Name="sprites" />
|
||||
</ShowAsCollectionAssociation>
|
||||
</Class>
|
||||
<Struct Name="OpenRa.Game.Graphics.Vertex" Collapsed="true">
|
||||
<Position X="18.25" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAgAAACAAFJgAQAAAAA=</HashCode>
|
||||
<FileName>Graphics\Vertex.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Enum Name="OpenRa.Game.Graphics.TextureChannel" Collapsed="true">
|
||||
<Position X="18.25" Y="3" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAgAAAAAAAAAAAAAAABAAAAAAABAAAAA=</HashCode>
|
||||
<FileName>Graphics\Sprite.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
@@ -2,32 +2,47 @@
|
||||
using System.Linq;
|
||||
using OpenRa.Game.Traits;
|
||||
using OpenRa.FileFormats;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace OpenRa.Game.Graphics
|
||||
{
|
||||
class Minimap
|
||||
{
|
||||
Sheet sheet;
|
||||
SpriteRenderer spriteRenderer;
|
||||
SpriteRenderer rgbaRenderer;
|
||||
SpriteRenderer shpRenderer;
|
||||
Sprite sprite;
|
||||
Bitmap terrain, oreLayer;
|
||||
Animation radarAnim, alliesAnim, sovietAnim;
|
||||
|
||||
public void Tick() { }
|
||||
|
||||
public Minimap(Renderer r)
|
||||
{
|
||||
sheet = new Sheet(r, new Size(128, 128));
|
||||
spriteRenderer = new SpriteRenderer(r, true, r.RgbaSpriteShader);
|
||||
shpRenderer = new SpriteRenderer(r, true);
|
||||
rgbaRenderer = new SpriteRenderer(r, true, r.RgbaSpriteShader);
|
||||
sprite = new Sprite(sheet, new Rectangle(0, 0, 128, 128), TextureChannel.Alpha);
|
||||
|
||||
sovietAnim = new Animation("ussrradr");
|
||||
sovietAnim.PlayRepeating("idle");
|
||||
alliesAnim = new Animation("natoradr");
|
||||
alliesAnim.PlayRepeating("idle");
|
||||
radarAnim = Game.LocalPlayer.Race == Race.Allies ? alliesAnim : sovietAnim;
|
||||
}
|
||||
|
||||
// todo: extract these from the palette
|
||||
Color[] terrainTypeColors;
|
||||
|
||||
public void InvalidateOre() { oreLayer = null; }
|
||||
|
||||
public void Update()
|
||||
{
|
||||
radarAnim = Game.LocalPlayer.Race == Race.Allies ? alliesAnim : sovietAnim;
|
||||
radarAnim.Tick();
|
||||
|
||||
if (!Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains<ProvidesRadar>()))
|
||||
return;
|
||||
|
||||
if (terrainTypeColors == null)
|
||||
{
|
||||
var pal = new Palette(FileSystem.Open(Rules.Map.Theater + ".pal"));
|
||||
@@ -65,25 +80,59 @@ namespace OpenRa.Game.Graphics
|
||||
}
|
||||
|
||||
var bitmap = new Bitmap(oreLayer);
|
||||
|
||||
for( var y = 0; y < 128; y++ )
|
||||
for (var x = 0; x < 128; x++)
|
||||
var bitmapData = bitmap.LockBits(new Rectangle( 0,0,bitmap.Width, bitmap.Height ),
|
||||
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
|
||||
unsafe
|
||||
{
|
||||
int* c = (int *)bitmapData.Scan0;
|
||||
|
||||
for (var y = 0; y < 128; y++)
|
||||
for (var x = 0; x < 128; x++)
|
||||
{
|
||||
var b = Game.BuildingInfluence.GetBuildingAt(new int2(x, y));
|
||||
if (b != null)
|
||||
*(c + (y * bitmapData.Stride >> 2) + x) =
|
||||
(b.Owner != null ? Chat.paletteColors[(int)b.Owner.Palette] : terrainTypeColors[4]).ToArgb();
|
||||
}
|
||||
|
||||
foreach (var a in Game.world.Actors.Where(a => a.traits.Contains<Unit>()))
|
||||
*(c + (a.Location.Y * bitmapData.Stride >> 2) + a.Location.X) = Chat.paletteColors[(int)a.Owner.Palette].ToArgb();
|
||||
|
||||
unchecked
|
||||
{
|
||||
var b = Game.BuildingInfluence.GetBuildingAt(new int2(x, y));
|
||||
if (b != null)
|
||||
bitmap.SetPixel(x, y, b.Owner != null ? Chat.paletteColors[(int)b.Owner.Palette] : terrainTypeColors[4]);
|
||||
for (var y = 0; y < 128; y++)
|
||||
for (var x = 0; x < 128; x++)
|
||||
if (!Game.LocalPlayer.Shroud.IsExplored(new int2(x, y)))
|
||||
*(c + (y * bitmapData.Stride >> 2) + x) = (int)0xff000000;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var a in Game.world.Actors.Where(a => a.traits.Contains<Unit>()))
|
||||
bitmap.SetPixel(a.Location.X, a.Location.Y, Chat.paletteColors[(int)a.Owner.Palette]);
|
||||
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
sheet.Texture.SetData(bitmap);
|
||||
}
|
||||
|
||||
public void Draw(float2 pos)
|
||||
public void Draw(float2 pos, bool hasRadar, bool isJammed)
|
||||
{
|
||||
spriteRenderer.DrawSprite(sprite, pos, PaletteType.Chrome, new float2(256,256));
|
||||
spriteRenderer.Flush();
|
||||
if (hasRadar && radarAnim.CurrentSequence.Name == "idle")
|
||||
radarAnim.PlayThen("open", () => radarAnim.PlayRepeating("active"));
|
||||
if (hasRadar && radarAnim.CurrentSequence.Name == "no-power")
|
||||
radarAnim.PlayBackwardsThen("close", () => radarAnim.PlayRepeating("active"));
|
||||
if (!hasRadar && radarAnim.CurrentSequence.Name == "active")
|
||||
radarAnim.PlayThen("close", () => radarAnim.PlayRepeating("no-power"));
|
||||
if (isJammed && radarAnim.CurrentSequence.Name == "active")
|
||||
radarAnim.PlayRepeating("jammed");
|
||||
if (!isJammed && radarAnim.CurrentSequence.Name == "jammed")
|
||||
radarAnim.PlayRepeating("active");
|
||||
|
||||
shpRenderer.DrawSprite(radarAnim.Image, pos + Game.viewport.Location - new float2( 290-256,0), PaletteType.Chrome, new float2(290, 272));
|
||||
shpRenderer.Flush();
|
||||
|
||||
if (radarAnim.CurrentSequence.Name == "active")
|
||||
{
|
||||
rgbaRenderer.DrawSprite(sprite, pos - new float2((290-256)/2, -5), PaletteType.Chrome, new float2(256, 256));
|
||||
rgbaRenderer.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,8 @@ namespace OpenRa.Game
|
||||
|
||||
void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e)
|
||||
{
|
||||
int sync = Game.world.SyncHash();
|
||||
|
||||
Game.viewport.DispatchMouseInput(
|
||||
new MouseInput
|
||||
{
|
||||
@@ -103,6 +105,9 @@ namespace OpenRa.Game
|
||||
Location = new int2(e.Location),
|
||||
Modifiers = (Modifiers)(int)ModifierKeys,
|
||||
});
|
||||
|
||||
if( sync != Game.world.SyncHash() )
|
||||
throw new InvalidOperationException( "Desync in DispatchMouseInput" );
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
@@ -136,6 +141,8 @@ namespace OpenRa.Game
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
|
||||
int sync = Game.world.SyncHash();
|
||||
|
||||
/* hack hack hack */
|
||||
if (e.KeyCode == Keys.F8 && !Game.orderManager.GameStarted)
|
||||
{
|
||||
@@ -156,16 +163,24 @@ namespace OpenRa.Game
|
||||
if (!Game.chat.isChatting)
|
||||
if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
|
||||
Game.controller.DoControlGroup( (int)e.KeyCode - (int)Keys.D0, (Modifiers)(int)e.Modifiers );
|
||||
|
||||
if( sync != Game.world.SyncHash() )
|
||||
throw new InvalidOperationException( "Desync in OnKeyDown" );
|
||||
}
|
||||
|
||||
protected override void OnKeyPress(KeyPressEventArgs e)
|
||||
{
|
||||
base.OnKeyPress(e);
|
||||
|
||||
int sync = Game.world.SyncHash();
|
||||
|
||||
if (e.KeyChar == '\r')
|
||||
Game.chat.Toggle();
|
||||
else if (Game.chat.isChatting)
|
||||
Game.chat.TypeChar(e.KeyChar);
|
||||
|
||||
if( sync != Game.world.SyncHash() )
|
||||
throw new InvalidOperationException( "Desync in OnKeyPress" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,10 +83,12 @@
|
||||
<Compile Include="Effects\Corpse.cs" />
|
||||
<Compile Include="Effects\DelayedAction.cs" />
|
||||
<Compile Include="Effects\FlashTarget.cs" />
|
||||
<Compile Include="Effects\GpsSatellite.cs" />
|
||||
<Compile Include="Effects\InvulnEffect.cs" />
|
||||
<Compile Include="Effects\MoveFlash.cs" />
|
||||
<Compile Include="Effects\PowerDownIndicator.cs" />
|
||||
<Compile Include="Effects\RepairIndicator.cs" />
|
||||
<Compile Include="Effects\SatelliteLaunch.cs" />
|
||||
<Compile Include="Effects\Smoke.cs" />
|
||||
<Compile Include="Effects\TeslaZap.cs" />
|
||||
<Compile Include="Exts.cs" />
|
||||
@@ -119,8 +121,15 @@
|
||||
<Compile Include="Shroud.cs" />
|
||||
<Compile Include="Smudge.cs" />
|
||||
<Compile Include="Sound.cs" />
|
||||
<Compile Include="SupportPower.cs" />
|
||||
<Compile Include="SupportPowers\ChronospherePower.cs" />
|
||||
<Compile Include="SupportPowers\GpsSatellite.cs" />
|
||||
<Compile Include="SupportPowers\IronCurtainPower.cs" />
|
||||
<Compile Include="SupportPowers\ISupportPowerImpl.cs" />
|
||||
<Compile Include="SupportPowers\NullPower.cs" />
|
||||
<Compile Include="Support\Stopwatch.cs" />
|
||||
<Compile Include="Support\PerfHistory.cs" />
|
||||
<Compile Include="Sync.cs" />
|
||||
<Compile Include="Traits\AcceptsOre.cs" />
|
||||
<Compile Include="Traits\Activities\Attack.cs" />
|
||||
<Compile Include="Traits\Activities\CaptureBuilding.cs" />
|
||||
@@ -162,6 +171,7 @@
|
||||
<Compile Include="Traits\Activities\Repair.cs" />
|
||||
<Compile Include="Traits\Activities\ReturnToBase.cs" />
|
||||
<Compile Include="Traits\Activities\Sell.cs" />
|
||||
<Compile Include="Traits\Activities\Steal.cs" />
|
||||
<Compile Include="Traits\Activities\Teleport.cs" />
|
||||
<Compile Include="BuildingInfluenceMap.cs" />
|
||||
<Compile Include="Orders\IOrderGenerator.cs" />
|
||||
@@ -216,6 +226,7 @@
|
||||
<Compile Include="Traits\Explodes.cs" />
|
||||
<Compile Include="Traits\ChronoshiftDeploy.cs" />
|
||||
<Compile Include="Traits\Fake.cs" />
|
||||
<Compile Include="Traits\GpsLaunchSite.cs" />
|
||||
<Compile Include="Traits\Harvester.cs" />
|
||||
<Compile Include="Traits\Helicopter.cs" />
|
||||
<Compile Include="Traits\InvisibleToOthers.cs" />
|
||||
@@ -255,6 +266,7 @@
|
||||
<Compile Include="Traits\StoresOre.cs" />
|
||||
<Compile Include="Traits\Submarine.cs" />
|
||||
<Compile Include="Traits\TakeCover.cs" />
|
||||
<Compile Include="Traits\Thief.cs" />
|
||||
<Compile Include="Traits\TraitsInterfaces.cs" />
|
||||
<Compile Include="Traits\Tree.cs" />
|
||||
<Compile Include="Traits\Turreted.cs" />
|
||||
@@ -299,10 +311,6 @@
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Game Code.cd" />
|
||||
<None Include="Graphics\Graphics.cd" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using OpenRa.Game.Traits;
|
||||
using OpenRa.Game.SupportPowers;
|
||||
|
||||
namespace OpenRa.Game.Orders
|
||||
{
|
||||
class ChronoshiftDestinationOrderGenerator : IOrderGenerator
|
||||
{
|
||||
public readonly Actor self;
|
||||
SupportPower power;
|
||||
|
||||
public ChronoshiftDestinationOrderGenerator(Actor self)
|
||||
public ChronoshiftDestinationOrderGenerator(Actor self, SupportPower power)
|
||||
{
|
||||
this.self = self;
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(int2 xy, MouseInput mi)
|
||||
@@ -23,8 +25,8 @@ namespace OpenRa.Game.Orders
|
||||
Game.controller.CancelInputMode();
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return new Order("Chronoshift", self, null, xy, null);
|
||||
yield return new Order("Chronoshift", self, null, xy,
|
||||
power != null ? power.Name : null);
|
||||
}
|
||||
|
||||
public void Tick() {}
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.Traits;
|
||||
using OpenRa.Game.SupportPowers;
|
||||
|
||||
namespace OpenRa.Game.Orders
|
||||
{
|
||||
class ChronosphereSelectOrderGenerator : IOrderGenerator
|
||||
{
|
||||
SupportPower power;
|
||||
public ChronosphereSelectOrderGenerator(SupportPower power)
|
||||
{
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(int2 xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right)
|
||||
@@ -30,9 +36,7 @@ namespace OpenRa.Game.Orders
|
||||
var unit = underCursor != null ? underCursor.Info as UnitInfo : null;
|
||||
|
||||
if (unit != null)
|
||||
{
|
||||
yield return new Order("ChronosphereSelect", underCursor, null, int2.Zero, null);
|
||||
}
|
||||
yield return new Order("ChronosphereSelect", underCursor, null, int2.Zero, power.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.Traits;
|
||||
using OpenRa.Game.SupportPowers;
|
||||
|
||||
namespace OpenRa.Game.Orders
|
||||
{
|
||||
class IronCurtainOrderGenerator : IOrderGenerator
|
||||
{
|
||||
SupportPower power;
|
||||
public IronCurtainOrderGenerator(SupportPower power)
|
||||
{
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(int2 xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right)
|
||||
@@ -30,9 +36,7 @@ namespace OpenRa.Game.Orders
|
||||
var unit = underCursor != null ? underCursor.Info as UnitInfo : null;
|
||||
|
||||
if (unit != null)
|
||||
{
|
||||
yield return new Order("IronCurtain", underCursor, null, int2.Zero, null);
|
||||
}
|
||||
yield return new Order("IronCurtain", underCursor, null, int2.Zero, power.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.SupportPowers;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
@@ -12,7 +13,7 @@ namespace OpenRa.Game
|
||||
public readonly int2 TargetLocation;
|
||||
public readonly string TargetString;
|
||||
public bool IsImmediate;
|
||||
|
||||
|
||||
public Actor Subject { get { return ActorFromUInt(SubjectId); } }
|
||||
public Actor TargetActor { get { return ActorFromUInt(TargetActorId); } }
|
||||
public Player Player { get { return Subject.Owner; } }
|
||||
@@ -20,8 +21,8 @@ namespace OpenRa.Game
|
||||
public Order(string orderString, Actor subject,
|
||||
Actor targetActor, int2 targetLocation, string targetString)
|
||||
: this( orderString, UIntFromActor( subject ),
|
||||
UIntFromActor( targetActor ), targetLocation, targetString ) {}
|
||||
|
||||
UIntFromActor( targetActor ), targetLocation, targetString) {}
|
||||
|
||||
Order(string orderString, uint subjectId,
|
||||
uint targetActorId, int2 targetLocation, string targetString)
|
||||
{
|
||||
|
||||
@@ -86,6 +86,7 @@ namespace OpenRa.Game.Orders
|
||||
case "Infiltrate": return Cursor.Enter;
|
||||
case "Capture": return Cursor.Capture;
|
||||
case "Harvest": return Cursor.AttackMove;
|
||||
case "Steal" : return Cursor.Enter;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace OpenRa.Game.Orders
|
||||
|
||||
default:
|
||||
{
|
||||
foreach (var t in order.Subject.traits.WithInterface<IOrder>())
|
||||
foreach (var t in order.Subject.traits.WithInterface<IResolveOrder>())
|
||||
t.ResolveOrder(order.Subject, order);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace OpenRa.Game
|
||||
public bool IsReady;
|
||||
|
||||
public Shroud Shroud = new Shroud();
|
||||
public Dictionary<string, SupportPower> SupportPowers;
|
||||
|
||||
public Player( Actor playerActor, int index, PaletteType palette, string playerName, Race race, string internalName )
|
||||
{
|
||||
@@ -37,6 +38,10 @@ namespace OpenRa.Game
|
||||
this.InternalName = internalName;
|
||||
this.PlayerName = playerName;
|
||||
this.Race = race;
|
||||
|
||||
SupportPowers = Rules.SupportPowerInfo.ToDictionary(
|
||||
spi => spi.Key,
|
||||
spi => new SupportPower(spi.Key, spi.Value, this));
|
||||
}
|
||||
|
||||
void UpdatePower()
|
||||
@@ -126,6 +131,9 @@ namespace OpenRa.Game
|
||||
UpdatePower();
|
||||
UpdateOreCapacity();
|
||||
|
||||
foreach (var sp in SupportPowers.Values)
|
||||
sp.Tick();
|
||||
|
||||
if (this == Game.LocalPlayer)
|
||||
{
|
||||
var totalMoney = Cash + Ore;
|
||||
|
||||
@@ -13,10 +13,21 @@ namespace OpenRa.Game
|
||||
Sprite[] shadowBits = SpriteSheetBuilder.LoadAllSprites("shadow");
|
||||
Sprite[,] sprites = new Sprite[128, 128];
|
||||
bool dirty;
|
||||
|
||||
public bool IsExplored(int2 xy)
|
||||
bool hasGPS = false;
|
||||
|
||||
public bool HasGPS
|
||||
{
|
||||
return explored[ xy.X, xy.Y ];
|
||||
get { return hasGPS; }
|
||||
set { hasGPS = value; dirty = true;}
|
||||
}
|
||||
|
||||
public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); }
|
||||
public bool IsExplored(int x, int y)
|
||||
{
|
||||
if (hasGPS)
|
||||
return true;
|
||||
|
||||
return explored[ x, y ];
|
||||
}
|
||||
|
||||
public void Explore(Actor a)
|
||||
@@ -27,48 +38,47 @@ namespace OpenRa.Game
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
static readonly byte[] ShroudTiles =
|
||||
{
|
||||
0xf,0xf,0xf,0xf,
|
||||
0xf,0xf,0xf,0xf,
|
||||
0xf,0xf,0xf,0xf,
|
||||
0xf,0xf,0xf,0xf,
|
||||
0,7,13,0,
|
||||
14,6,12,4,
|
||||
11,3,9,1,
|
||||
0,2,8,0,
|
||||
};
|
||||
|
||||
static readonly byte[] ExtraShroudTiles =
|
||||
{
|
||||
46, 41, 42, 38,
|
||||
43, 45, 39, 35,
|
||||
40, 37, 44, 34,
|
||||
36, 33, 32, 47,
|
||||
};
|
||||
|
||||
Sprite ChooseShroud(int i, int j)
|
||||
{
|
||||
// bits are for exploredness: left, right, up, down, self
|
||||
var n = new[] {
|
||||
0xf,0xf,0xf,0xf,
|
||||
0xf,0x0f,0x0f,0xf,
|
||||
0xf,0x0f,0x0f,0xf,
|
||||
0xf,0xf,0xf,0xf,
|
||||
0,7,13,0,
|
||||
14,6,12,4,
|
||||
11,3,9,1,
|
||||
0,2,8,0,
|
||||
};
|
||||
|
||||
var v = 0;
|
||||
if (explored[i - 1, j]) v |= 1;
|
||||
if (explored[i + 1, j]) v |= 2;
|
||||
if (explored[i, j - 1]) v |= 4;
|
||||
if (explored[i, j + 1]) v |= 8;
|
||||
if (explored[i, j]) v |= 16;
|
||||
if (IsExplored(i - 1, j)) v |= 1;
|
||||
if (IsExplored(i + 1, j)) v |= 2;
|
||||
if (IsExplored(i, j - 1)) v |= 4;
|
||||
if (IsExplored(i, j + 1)) v |= 8;
|
||||
if (IsExplored(i, j)) v |= 16;
|
||||
|
||||
var x = n[v];
|
||||
var x = ShroudTiles[v];
|
||||
if (x != 0)
|
||||
return shadowBits[x];
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
// bits are for exploredness: TL, TR, BR, BL
|
||||
var m = new[] {
|
||||
46, 41, 42, 38,
|
||||
43, 45, 39, 35,
|
||||
40, 37, 44, 34,
|
||||
36, 33, 32, 47,
|
||||
};
|
||||
|
||||
var u = 0;
|
||||
if (explored[i - 1, j - 1]) u |= 1;
|
||||
if (explored[i + 1, j - 1]) u |= 2;
|
||||
if (explored[i + 1, j + 1]) u |= 4;
|
||||
if (explored[i - 1, j + 1]) u |= 8;
|
||||
return shadowBits[m[u]];
|
||||
}
|
||||
|
||||
return shadowBits[x];
|
||||
// bits are for exploredness: TL, TR, BR, BL
|
||||
var u = 0;
|
||||
if (IsExplored(i - 1, j - 1)) u |= 1;
|
||||
if (IsExplored(i + 1, j - 1)) u |= 2;
|
||||
if (IsExplored(i + 1, j + 1)) u |= 4;
|
||||
if (IsExplored(i - 1, j + 1)) u |= 8;
|
||||
return shadowBits[ExtraShroudTiles[u]];
|
||||
}
|
||||
|
||||
public void Draw(SpriteRenderer r)
|
||||
|
||||
104
OpenRa.Game/SupportPower.cs
Normal file
104
OpenRa.Game/SupportPower.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.SupportPowers;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
// todo: fix this to route Activate through the orders system (otherwise desync in netplay)
|
||||
|
||||
class SupportPower
|
||||
{
|
||||
public readonly SupportPowerInfo Info;
|
||||
public readonly Player Owner;
|
||||
public readonly ISupportPowerImpl Impl;
|
||||
public readonly string Name;
|
||||
|
||||
static ISupportPowerImpl ConstructPowerImpl(string implName)
|
||||
{
|
||||
var type = typeof(ISupportPowerImpl).Assembly.GetType(
|
||||
typeof(ISupportPowerImpl).Namespace + "." + implName, true, false);
|
||||
var ctor = type.GetConstructor(Type.EmptyTypes);
|
||||
return (ISupportPowerImpl)ctor.Invoke(new object[] { });
|
||||
}
|
||||
|
||||
public SupportPower(string name, SupportPowerInfo info, Player owner)
|
||||
{
|
||||
Name = name;
|
||||
Info = info;
|
||||
Owner = owner;
|
||||
RemainingTime = TotalTime = (int)(info.ChargeTime * 60 * 25);
|
||||
Impl = ConstructPowerImpl(info.Impl);
|
||||
}
|
||||
|
||||
public bool IsUsed;
|
||||
public bool IsAvailable { get; private set; }
|
||||
public bool IsDone { get { return RemainingTime == 0; } }
|
||||
public int RemainingTime { get; private set; }
|
||||
public int TotalTime { get; private set; }
|
||||
bool notifiedReady = false;
|
||||
bool notifiedCharging = false;
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
if (Info.OneShot && IsUsed)
|
||||
return;
|
||||
|
||||
if (Info.GivenAuto)
|
||||
{
|
||||
var buildings = Rules.TechTree.GatherBuildings(Owner);
|
||||
var effectivePrereq = Info.Prerequisite
|
||||
.Select( a => a.ToLowerInvariant() )
|
||||
.Where( a => Rules.UnitInfo[a].Owner
|
||||
.Any( r => r == Owner.Race ));
|
||||
|
||||
IsAvailable = Info.TechLevel > -1
|
||||
&& effectivePrereq.Any()
|
||||
&& effectivePrereq.All(a => buildings[a].Count > 0);
|
||||
}
|
||||
|
||||
if (IsAvailable && (!Info.Powered || Owner.GetPowerState() == PowerState.Normal))
|
||||
{
|
||||
if (RemainingTime > 0) --RemainingTime;
|
||||
if (!notifiedCharging)
|
||||
{
|
||||
Impl.IsChargingNotification(this);
|
||||
notifiedCharging = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (RemainingTime == 0
|
||||
&& Impl != null
|
||||
&& !notifiedReady)
|
||||
{
|
||||
Impl.IsReadyNotification(this);
|
||||
notifiedReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
if (Impl != null)
|
||||
Impl.Activate(this);
|
||||
}
|
||||
|
||||
public void FinishActivate()
|
||||
{
|
||||
if (Info.OneShot)
|
||||
{
|
||||
IsUsed = true;
|
||||
IsAvailable = false;
|
||||
}
|
||||
RemainingTime = TotalTime;
|
||||
notifiedReady = false;
|
||||
notifiedCharging = false;
|
||||
}
|
||||
|
||||
public void Give(bool requireCharge) // called by crate/spy/etc code
|
||||
{
|
||||
IsAvailable = true;
|
||||
IsUsed = false;
|
||||
RemainingTime = requireCharge ? TotalTime : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
OpenRa.Game/SupportPowers/ChronospherePower.cs
Normal file
39
OpenRa.Game/SupportPowers/ChronospherePower.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using OpenRa.Game.Orders;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game.SupportPowers
|
||||
{
|
||||
class ChronospherePower : ISupportPowerImpl
|
||||
{
|
||||
public void IsReadyNotification(SupportPower p) { Sound.Play("chrordy1.aud"); }
|
||||
public void IsChargingNotification(SupportPower p) { Sound.Play("chrochr1.aud"); }
|
||||
|
||||
public void OnFireNotification(Actor target, int2 xy)
|
||||
{
|
||||
p.FinishActivate();
|
||||
Game.controller.CancelInputMode();
|
||||
|
||||
Sound.Play("chrono2.aud");
|
||||
|
||||
foreach (var a in Game.world.Actors.Where(a => a.traits.Contains<ChronoshiftPaletteEffect>()))
|
||||
a.traits.Get<ChronoshiftPaletteEffect>().DoChronoshift();
|
||||
|
||||
// Play chronosphere active anim
|
||||
var chronosphere = Game.world.Actors.Where(a => a.Owner == p.Owner && a.traits.Contains<Chronosphere>()).FirstOrDefault();
|
||||
|
||||
if (chronosphere != null)
|
||||
chronosphere.traits.Get<RenderBuilding>().PlayCustomAnim(chronosphere, "active");
|
||||
}
|
||||
SupportPower p;
|
||||
public void Activate(SupportPower p)
|
||||
{
|
||||
this.p = p;
|
||||
Game.controller.orderGenerator = new ChronosphereSelectOrderGenerator(p);
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
}
|
||||
}
|
||||
32
OpenRa.Game/SupportPowers/GpsSatellite.cs
Normal file
32
OpenRa.Game/SupportPowers/GpsSatellite.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Linq;
|
||||
using OpenRa.Game.Effects;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game.SupportPowers
|
||||
{
|
||||
class GpsSatellite : ISupportPowerImpl
|
||||
{
|
||||
const int revealDelay = 15 * 25;
|
||||
|
||||
public void OnFireNotification(Actor a, int2 xy) { }
|
||||
public void IsChargingNotification(SupportPower p) { }
|
||||
public void IsReadyNotification(SupportPower p)
|
||||
{
|
||||
var launchSite = Game.world.Actors
|
||||
.FirstOrDefault(a => a.Owner == p.Owner && a.traits.Contains<GpsLaunchSite>());
|
||||
|
||||
if (launchSite == null)
|
||||
return;
|
||||
|
||||
Game.world.AddFrameEndTask(w =>
|
||||
{
|
||||
w.Add(new SatelliteLaunch(launchSite));
|
||||
w.Add(new DelayedAction(revealDelay, () => p.Owner.Shroud.HasGPS = true));
|
||||
});
|
||||
|
||||
p.FinishActivate();
|
||||
}
|
||||
|
||||
public void Activate(SupportPower p) {}
|
||||
}
|
||||
}
|
||||
15
OpenRa.Game/SupportPowers/ISupportPowerImpl.cs
Normal file
15
OpenRa.Game/SupportPowers/ISupportPowerImpl.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.Game.SupportPowers
|
||||
{
|
||||
interface ISupportPowerImpl
|
||||
{
|
||||
void Activate(SupportPower p);
|
||||
void OnFireNotification(Actor target, int2 xy);
|
||||
void IsChargingNotification(SupportPower p);
|
||||
void IsReadyNotification(SupportPower p);
|
||||
}
|
||||
}
|
||||
43
OpenRa.Game/SupportPowers/IronCurtainPower.cs
Normal file
43
OpenRa.Game/SupportPowers/IronCurtainPower.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.Orders;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game.SupportPowers
|
||||
{
|
||||
class IronCurtainPower : ISupportPowerImpl
|
||||
{
|
||||
public void IsReadyNotification(SupportPower p)
|
||||
{
|
||||
Sound.Play("ironrdy1.aud");
|
||||
}
|
||||
|
||||
public void IsChargingNotification(SupportPower p)
|
||||
{
|
||||
Sound.Play("ironchg1.aud");
|
||||
}
|
||||
|
||||
public void OnFireNotification(Actor target, int2 xy)
|
||||
{
|
||||
p.FinishActivate();
|
||||
Game.controller.CancelInputMode();
|
||||
Sound.Play("ironcur9.aud");
|
||||
|
||||
// Play active anim
|
||||
var ironCurtain = Game.world.Actors
|
||||
.Where(a => a.Owner == p.Owner && a.traits.Contains<IronCurtain>())
|
||||
.FirstOrDefault();
|
||||
if (ironCurtain != null)
|
||||
ironCurtain.traits.Get<RenderBuilding>().PlayCustomAnim(ironCurtain, "active");
|
||||
}
|
||||
SupportPower p;
|
||||
public void Activate(SupportPower p)
|
||||
{
|
||||
this.p = p;
|
||||
// Pick a building to use
|
||||
Game.controller.orderGenerator = new IronCurtainOrderGenerator(p);
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
}
|
||||
}
|
||||
19
OpenRa.Game/SupportPowers/NullPower.cs
Normal file
19
OpenRa.Game/SupportPowers/NullPower.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.Game.SupportPowers
|
||||
{
|
||||
class NullPower : ISupportPowerImpl
|
||||
{
|
||||
public void OnFireNotification(Actor a, int2 xy) { }
|
||||
public void IsReadyNotification(SupportPower p) { }
|
||||
public void IsChargingNotification(SupportPower p) { }
|
||||
public void Activate(SupportPower p)
|
||||
{
|
||||
// if this was a real power, i'd do something here!
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
107
OpenRa.Game/Sync.cs
Executable file
107
OpenRa.Game/Sync.cs
Executable file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using IjwFramework.Collections;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
class SyncAttribute : Attribute { }
|
||||
|
||||
static class Sync
|
||||
{
|
||||
static Cache<Type, Func<object, int>> hashFuncCache = new Cache<Type, Func<object, int>>( t => GenerateHashFunc( t ) );
|
||||
|
||||
public static int CalculateSyncHash( object obj )
|
||||
{
|
||||
return hashFuncCache[ obj.GetType() ]( obj );
|
||||
}
|
||||
|
||||
public static Func<object,int> GenerateHashFunc( Type t )
|
||||
{
|
||||
var d = new DynamicMethod( "hash_{0}".F( t.Name ), typeof( int ), new Type[] { typeof( object ) }, t );
|
||||
var il = d.GetILGenerator();
|
||||
var this_ = il.DeclareLocal( t ).LocalIndex;
|
||||
il.Emit( OpCodes.Ldarg_0 );
|
||||
il.Emit( OpCodes.Castclass, t );
|
||||
il.Emit( OpCodes.Stloc, this_ );
|
||||
il.Emit( OpCodes.Ldc_I4_0 );
|
||||
|
||||
const BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
foreach( var field in t.GetFields( bf ).Where( x => x.GetCustomAttributes( typeof( SyncAttribute ), true ).Length != 0 ) )
|
||||
{
|
||||
il.Emit( OpCodes.Ldloc, this_ );
|
||||
il.Emit( OpCodes.Ldfld, field );
|
||||
|
||||
if( field.FieldType == typeof( int ) )
|
||||
{
|
||||
il.Emit( OpCodes.Xor );
|
||||
}
|
||||
else if( field.FieldType == typeof( bool ) )
|
||||
{
|
||||
var l = il.DefineLabel();
|
||||
il.Emit( OpCodes.Ldc_I4, 0xaaa );
|
||||
il.Emit( OpCodes.Brtrue, l );
|
||||
il.Emit( OpCodes.Pop );
|
||||
il.Emit( OpCodes.Ldc_I4, 0x555 );
|
||||
il.MarkLabel( l );
|
||||
il.Emit( OpCodes.Xor );
|
||||
}
|
||||
else if( field.FieldType == typeof( int2 ) )
|
||||
{
|
||||
il.EmitCall( OpCodes.Call, ( (Func<int2, int>)hash_int2 ).Method, null );
|
||||
il.Emit( OpCodes.Xor );
|
||||
}
|
||||
else if( field.FieldType == typeof( TypeDictionary ) )
|
||||
{
|
||||
il.EmitCall( OpCodes.Call, ( (Func<TypeDictionary, int>)hash_tdict ).Method, null );
|
||||
il.Emit( OpCodes.Xor );
|
||||
}
|
||||
else if( field.FieldType == typeof( Actor ) )
|
||||
{
|
||||
il.EmitCall( OpCodes.Call, ( (Func<Actor, int>)hash_actor ).Method, null );
|
||||
il.Emit( OpCodes.Xor );
|
||||
}
|
||||
else if( field.FieldType == typeof( Player ) )
|
||||
{
|
||||
il.EmitCall( OpCodes.Call, ( (Func<Player, int>)hash_player ).Method, null );
|
||||
il.Emit( OpCodes.Xor );
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException( "SyncAttribute on unhashable field" );
|
||||
}
|
||||
|
||||
il.Emit( OpCodes.Ret );
|
||||
return (Func<object,int>)d.CreateDelegate( typeof( Func<object,int> ) );
|
||||
}
|
||||
|
||||
internal static int hash_int2( int2 i2 )
|
||||
{
|
||||
return ( ( i2.X * 5 ) ^ ( i2.Y * 3 ) ) / 4;
|
||||
}
|
||||
|
||||
internal static int hash_tdict( TypeDictionary d )
|
||||
{
|
||||
int ret = 0;
|
||||
foreach( var o in d )
|
||||
ret += CalculateSyncHash( o );
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal static int hash_actor( Actor a )
|
||||
{
|
||||
if( a != null )
|
||||
return (int)( a.ActorID << 16 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal static int hash_player( Player p )
|
||||
{
|
||||
if( p != null )
|
||||
return p.Index * 0x567;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
OpenRa.Game/Traits/Activities/Steal.cs
Normal file
29
OpenRa.Game/Traits/Activities/Steal.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.Game.Traits.Activities
|
||||
{
|
||||
class Steal : IActivity
|
||||
{
|
||||
Actor target;
|
||||
|
||||
public Steal(Actor target) { this.target = target; }
|
||||
|
||||
public IActivity NextActivity { get; set; }
|
||||
|
||||
public IActivity Tick(Actor self)
|
||||
{
|
||||
if (target == null || target.IsDead) return NextActivity;
|
||||
if (target.Owner == self.Owner) return NextActivity;
|
||||
|
||||
foreach (var t in target.traits.WithInterface<IAcceptThief>())
|
||||
t.OnSteal(target, self);
|
||||
|
||||
return NextActivity;
|
||||
}
|
||||
|
||||
public void Cancel(Actor self) { target = null; NextActivity = null; }
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,14 @@ using OpenRa.Game.Effects;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class AttackBase : IOrder, ITick
|
||||
class AttackBase : IIssueOrder, IResolveOrder, ITick
|
||||
{
|
||||
public Actor target;
|
||||
[Sync] public Actor target;
|
||||
|
||||
// time (in frames) until each weapon can fire again.
|
||||
[Sync]
|
||||
protected int primaryFireDelay = 0;
|
||||
[Sync]
|
||||
protected int secondaryFireDelay = 0;
|
||||
|
||||
int primaryBurst;
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace OpenRa.Game.Traits
|
||||
public AttackFrontal(Actor self, int facingTolerance)
|
||||
: base(self) { FacingTolerance = facingTolerance; }
|
||||
|
||||
int FacingTolerance;
|
||||
readonly int FacingTolerance;
|
||||
|
||||
public override void Tick(Actor self)
|
||||
{
|
||||
|
||||
@@ -9,11 +9,13 @@ using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Building : INotifyDamage, IOrder, ITick
|
||||
class Building : INotifyDamage, IResolveOrder, ITick
|
||||
{
|
||||
readonly Actor self;
|
||||
public readonly BuildingInfo unitInfo;
|
||||
[Sync]
|
||||
bool isRepairing = false;
|
||||
[Sync]
|
||||
bool manuallyDisabled = false;
|
||||
public bool ManuallyDisabled { get { return manuallyDisabled; } }
|
||||
public bool Disabled { get { return (manuallyDisabled || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); } }
|
||||
@@ -44,11 +46,6 @@ namespace OpenRa.Game.Traits
|
||||
Sound.Play("kaboom22.aud");
|
||||
}
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
return null; // sell/repair orders are issued through Chrome, not here.
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "Sell")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class C4Demolition : IOrder
|
||||
class C4Demolition : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public C4Demolition(Actor self) { }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Cargo : IPips, IOrder
|
||||
class Cargo : IPips, IIssueOrder, IResolveOrder
|
||||
{
|
||||
List<Actor> cargo = new List<Actor>();
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ using OpenRa.Game.Orders;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ChronoshiftDeploy : IOrder, ISpeedModifier, ITick, IPips
|
||||
class ChronoshiftDeploy : IIssueOrder, IResolveOrder, ISpeedModifier, ITick, IPips
|
||||
{
|
||||
// Recharge logic
|
||||
[Sync]
|
||||
int chargeTick = 0; // How long until we can chronoshift again?
|
||||
int chargeLength = (int)(Rules.Aftermath.ChronoTankDuration * 60 * 25); // How long between shifts?
|
||||
readonly int chargeLength = (int)(Rules.Aftermath.ChronoTankDuration * 60 * 25); // How long between shifts?
|
||||
|
||||
public ChronoshiftDeploy(Actor self) { }
|
||||
|
||||
@@ -38,7 +39,7 @@ namespace OpenRa.Game.Traits
|
||||
if (order.OrderString == "ChronoshiftSelf" && movement.CanEnterCell(order.TargetLocation))
|
||||
{
|
||||
// Cannot chronoshift into unexplored location
|
||||
if (!Game.LocalPlayer.Shroud.IsExplored(order.TargetLocation))
|
||||
if (!self.Owner.Shroud.IsExplored(order.TargetLocation))
|
||||
return;
|
||||
|
||||
Game.controller.CancelInputMode();
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
using OpenRa.Game.Orders;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Chronoshiftable : IOrder, ISpeedModifier, ITick
|
||||
class Chronoshiftable : IResolveOrder, ISpeedModifier, ITick
|
||||
{
|
||||
// Return-to-sender logic
|
||||
[Sync]
|
||||
int2 chronoshiftOrigin;
|
||||
[Sync]
|
||||
int chronoshiftReturnTicks = 0;
|
||||
|
||||
|
||||
public Chronoshiftable(Actor self) { }
|
||||
|
||||
public void Tick(Actor self)
|
||||
@@ -31,55 +32,42 @@ namespace OpenRa.Game.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
return null; // Chronoshift order is issued through Chrome.
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "ChronosphereSelect")
|
||||
{
|
||||
Game.controller.orderGenerator = new ChronoshiftDestinationOrderGenerator(self);
|
||||
var power = self.Owner.SupportPowers[order.TargetString];
|
||||
Game.controller.orderGenerator = new ChronoshiftDestinationOrderGenerator(self, power);
|
||||
}
|
||||
|
||||
var movement = self.traits.WithInterface<IMovement>().FirstOrDefault();
|
||||
if (order.OrderString == "Chronoshift" && movement.CanEnterCell(order.TargetLocation))
|
||||
{
|
||||
// Cannot chronoshift into unexplored location
|
||||
if (!Game.LocalPlayer.Shroud.IsExplored(order.TargetLocation))
|
||||
if (!self.Owner.Shroud.IsExplored(order.TargetLocation))
|
||||
return;
|
||||
|
||||
|
||||
// Set up return-to-sender info
|
||||
chronoshiftOrigin = self.Location;
|
||||
chronoshiftReturnTicks = (int)(Rules.General.ChronoDuration * 60 * 25);
|
||||
|
||||
var chronosphere = Game.world.Actors.Where(a => a.Owner == order.Subject.Owner && a.traits.Contains<Chronosphere>()).FirstOrDefault();
|
||||
|
||||
// Kill cargo
|
||||
if (Rules.General.ChronoKillCargo && self.traits.Contains<Cargo>())
|
||||
{
|
||||
var cargo = self.traits.Get<Cargo>();
|
||||
while (!cargo.IsEmpty(self))
|
||||
{
|
||||
if (chronosphere != null)
|
||||
chronosphere.Owner.Kills++;
|
||||
order.Player.Kills++;
|
||||
cargo.Unload(self);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the teleport
|
||||
Game.controller.CancelInputMode();
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new Activities.Teleport(order.TargetLocation));
|
||||
Sound.Play("chrono2.aud");
|
||||
|
||||
foreach (var a in Game.world.Actors.Where(a => a.traits.Contains<ChronoshiftPaletteEffect>()))
|
||||
a.traits.Get<ChronoshiftPaletteEffect>().DoChronoshift();
|
||||
|
||||
// Play chronosphere active anim
|
||||
if (chronosphere != null)
|
||||
chronosphere.traits.Get<RenderBuilding>().PlayCustomAnim(chronosphere, "active");
|
||||
var power = self.Owner.SupportPowers[order.TargetString].Impl;
|
||||
power.OnFireNotification(self, self.Location);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Cloak : IRenderModifier, INotifyAttack, ITick
|
||||
{
|
||||
[Sync]
|
||||
int remainingUncloakTime = 2; /* setup for initial cloak */
|
||||
|
||||
public Cloak(Actor self) {}
|
||||
|
||||
@@ -3,7 +3,7 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ConstructionYard : IOrder, IMovement
|
||||
class ConstructionYard : IIssueOrder, IResolveOrder, IMovement
|
||||
{
|
||||
readonly Actor self;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using OpenRa.Game.Orders;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class DemoTruck : Chronoshiftable, IOrder, INotifyDamage
|
||||
class DemoTruck : Chronoshiftable, IResolveOrder, INotifyDamage
|
||||
{
|
||||
readonly Actor self;
|
||||
public DemoTruck(Actor self)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class EngineerCapture : IOrder
|
||||
class EngineerCapture : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public const int EngineerDamage = 300; // todo: push into rules, as a weapon
|
||||
|
||||
|
||||
6
OpenRa.Game/Traits/GpsLaunchSite.cs
Normal file
6
OpenRa.Game/Traits/GpsLaunchSite.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
using OpenRa.Game.Effects;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class GpsLaunchSite { public GpsLaunchSite(Actor self) { } }
|
||||
}
|
||||
@@ -3,9 +3,11 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Harvester : IOrder, IPips
|
||||
class Harvester : IIssueOrder, IResolveOrder, IPips
|
||||
{
|
||||
[Sync]
|
||||
public int oreCarried = 0; /* sum of these must not exceed capacity */
|
||||
[Sync]
|
||||
public int gemsCarried = 0;
|
||||
|
||||
public bool IsFull { get { return oreCarried + gemsCarried == Rules.General.BailCount; } }
|
||||
|
||||
@@ -4,7 +4,7 @@ using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Helicopter : IOrder, IMovement
|
||||
class Helicopter : IIssueOrder, IResolveOrder, IMovement
|
||||
{
|
||||
public IDisposable reservation;
|
||||
public Helicopter(Actor self) {}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
using OpenRa.Game.Traits;
|
||||
using OpenRa.Game.Orders;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRa.Game.Effects;
|
||||
using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class IronCurtainable: IOrder, IDamageModifier, ITick
|
||||
class IronCurtainable : IResolveOrder, IDamageModifier, ITick
|
||||
{
|
||||
[Sync]
|
||||
int RemainingTicks = 0;
|
||||
|
||||
public IronCurtainable(Actor self) { }
|
||||
@@ -23,24 +19,15 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
return (RemainingTicks > 0) ? 0.0f : 1.0f;
|
||||
}
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
return null; // Chronoshift order is issued through Chrome.
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "IronCurtain")
|
||||
{
|
||||
Game.controller.CancelInputMode();
|
||||
var power = self.Owner.SupportPowers[order.TargetString].Impl;
|
||||
power.OnFireNotification(self, self.Location);
|
||||
Game.world.AddFrameEndTask(w => w.Add(new InvulnEffect(self)));
|
||||
RemainingTicks = (int)(Rules.General.IronCurtain * 60 * 25);
|
||||
Sound.Play("ironcur9.aud");
|
||||
// Play active anim
|
||||
var ironCurtain = Game.world.Actors.Where(a => a.Owner == order.Subject.Owner && a.traits.Contains<IronCurtain>()).FirstOrDefault();
|
||||
if (ironCurtain != null)
|
||||
ironCurtain.traits.Get<RenderBuilding>().PlayCustomAnim(ironCurtain, "active");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
class LimitedAmmo : INotifyAttack, IPips
|
||||
{
|
||||
[Sync]
|
||||
int ammo;
|
||||
Actor self;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class McvDeploy : IOrder
|
||||
class McvDeploy : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public McvDeploy(Actor self) { }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Text;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Minelayer : IOrder
|
||||
class Minelayer : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public Minelayer(Actor self) { }
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Mobile : IOrder, IOccupySpace, IMovement
|
||||
class Mobile : IIssueOrder, IResolveOrder, IOccupySpace, IMovement
|
||||
{
|
||||
readonly Actor self;
|
||||
|
||||
[Sync]
|
||||
int2 __fromCell;
|
||||
public int2 fromCell
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Passenger : IOrder
|
||||
class Passenger : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public Passenger(Actor self) { }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Plane : IOrder, IMovement
|
||||
class Plane : IIssueOrder, IResolveOrder, IMovement
|
||||
{
|
||||
public IDisposable reservation;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Production : IOrder, IProducer, ITags
|
||||
class Production : IIssueOrder, IResolveOrder, IProducer, ITags
|
||||
{
|
||||
bool isPrimary = false;
|
||||
public bool IsPrimary { get { return isPrimary; } }
|
||||
@@ -66,9 +66,7 @@ namespace OpenRa.Game.Traits
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "Deploy")
|
||||
{
|
||||
SetPrimaryProducer(self, !isPrimary);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPrimaryProducer(Actor self, bool state)
|
||||
|
||||
@@ -6,7 +6,7 @@ using IjwFramework.Collections;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class ProductionQueue : IOrder, ITick
|
||||
class ProductionQueue : IResolveOrder, ITick
|
||||
{
|
||||
Actor self;
|
||||
|
||||
@@ -22,12 +22,6 @@ namespace OpenRa.Game.Traits
|
||||
(p.Value)[0].Tick( self.Owner );
|
||||
}
|
||||
|
||||
public Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor )
|
||||
{
|
||||
// production isn't done by clicks in the world; the chrome handles it.
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ResolveOrder( Actor self, Order order )
|
||||
{
|
||||
switch( order.OrderString )
|
||||
@@ -80,6 +74,7 @@ namespace OpenRa.Game.Traits
|
||||
}
|
||||
|
||||
// Key: Production category.
|
||||
// TODO: sync this
|
||||
readonly Cache<string, List<ProductionItem>> production
|
||||
= new Cache<string, List<ProductionItem>>( _ => new List<ProductionItem>() );
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ using OpenRa.Game.Orders;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class RallyPoint : IRender, IOrder, ITick
|
||||
class RallyPoint : IRender, IIssueOrder, IResolveOrder, ITick
|
||||
{
|
||||
[Sync]
|
||||
public int2 rallyPoint;
|
||||
public Animation anim;
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ namespace OpenRa.Game.Traits
|
||||
class RenderWarFactory : IRender, INotifyBuildComplete, INotifyDamage, ITick, INotifyProduction
|
||||
{
|
||||
public Animation roof;
|
||||
[Sync]
|
||||
bool doneBuilding;
|
||||
[Sync]
|
||||
bool isOpen;
|
||||
public readonly Actor self;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Repairable : IOrder
|
||||
class Repairable : IIssueOrder, IResolveOrder
|
||||
{
|
||||
IDisposable reservation;
|
||||
public Repairable(Actor self) { }
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System;
|
||||
using OpenRa.Game.GameRules;
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class StoresOre : IPips
|
||||
class StoresOre : IPips, IAcceptThief
|
||||
{
|
||||
public const int MaxStealAmount = 100; //todo: How is cash stolen determined?
|
||||
|
||||
readonly Actor self;
|
||||
|
||||
public StoresOre(Actor self)
|
||||
@@ -11,6 +14,21 @@ namespace OpenRa.Game.Traits
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public void OnSteal(Actor self, Actor thief)
|
||||
{
|
||||
// Steal half the ore the building holds
|
||||
var toSteal = (self.Info as BuildingInfo).Storage/2;
|
||||
self.Owner.TakeCash(toSteal);
|
||||
thief.Owner.GiveCash(toSteal);
|
||||
|
||||
if (Game.LocalPlayer == thief.Owner)
|
||||
Sound.Play("credit1.aud");
|
||||
|
||||
// the thief is sacrificed.
|
||||
thief.Health = 0;
|
||||
Game.world.AddFrameEndTask(w => w.Remove(thief));
|
||||
}
|
||||
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
{
|
||||
for (int i = 0; i < self.Info.OrePips; i++)
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Submarine : IRenderModifier, INotifyAttack, ITick, INotifyDamage
|
||||
{
|
||||
[Sync]
|
||||
int remainingSurfaceTime = 2; /* setup for initial dive */
|
||||
|
||||
public Submarine(Actor self) { }
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace OpenRa.Game.Traits
|
||||
const float proneDamage = .5f;
|
||||
const float proneSpeed = .5f;
|
||||
|
||||
[Sync]
|
||||
int remainingProneTime = 0;
|
||||
|
||||
public bool IsProne { get { return remainingProneTime > 0; } }
|
||||
|
||||
29
OpenRa.Game/Traits/Thief.cs
Normal file
29
OpenRa.Game/Traits/Thief.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using OpenRa.Game.Traits.Activities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Thief : IIssueOrder, IResolveOrder
|
||||
{
|
||||
public Thief(Actor self) { }
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button != MouseButton.Right) return null;
|
||||
if (underCursor == null) return null;
|
||||
if (!underCursor.traits.WithInterface<IAcceptThief>().Any()) return null;
|
||||
|
||||
return new Order("Steal", self, underCursor, int2.Zero, null);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "Steal")
|
||||
{
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new Move(order.TargetActor, 1));
|
||||
self.QueueActivity(new Steal(order.TargetActor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,18 +10,18 @@ namespace OpenRa.Game.Traits
|
||||
// depends on the order of pips in WorldRenderer.cs!
|
||||
enum PipType { Transparent, Green, Yellow, Red, Gray };
|
||||
enum TagType { None, Fake, Primary };
|
||||
|
||||
|
||||
interface ITick { void Tick(Actor self); }
|
||||
interface IRender { IEnumerable<Renderable> Render(Actor self); }
|
||||
interface IIssueOrder { Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor ); }
|
||||
interface IResolveOrder { void ResolveOrder( Actor self, Order order ); }
|
||||
|
||||
interface INotifySold { void Sold(Actor self); }
|
||||
interface INotifyDamage { void Damaged(Actor self, AttackInfo e); }
|
||||
interface INotifyBuildComplete { void BuildingComplete (Actor self); }
|
||||
interface INotifyProduction { void UnitProduced(Actor self, Actor other); }
|
||||
interface IOrder
|
||||
{
|
||||
Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor );
|
||||
void ResolveOrder( Actor self, Order order );
|
||||
}
|
||||
interface IAcceptThief { void OnSteal(Actor self, Actor thief); }
|
||||
|
||||
interface IProducer
|
||||
{
|
||||
bool Produce( Actor self, UnitInfo producee );
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Turreted : ITick
|
||||
{
|
||||
[Sync]
|
||||
public int turretFacing = 0;
|
||||
public int? desiredFacing;
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Unit : INotifyDamage
|
||||
{
|
||||
[Sync]
|
||||
public int Facing;
|
||||
[Sync]
|
||||
public int Altitude;
|
||||
|
||||
public Unit( Actor self ) { }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRa.Game.Effects;
|
||||
using OpenRa.Game.Support;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
@@ -12,15 +13,15 @@ namespace OpenRa.Game
|
||||
|
||||
public void Add(Actor a)
|
||||
{
|
||||
a.IsInWorld = true;
|
||||
actors.Add(a);
|
||||
a.IsInWorld = true;
|
||||
actors.Add(a);
|
||||
ActorAdded(a);
|
||||
}
|
||||
|
||||
public void Remove(Actor a)
|
||||
{
|
||||
a.IsInWorld = false;
|
||||
actors.Remove(a);
|
||||
a.IsInWorld = false;
|
||||
actors.Remove(a);
|
||||
ActorRemoved(a);
|
||||
}
|
||||
|
||||
@@ -52,5 +53,17 @@ namespace OpenRa.Game
|
||||
{
|
||||
return nextAID++;
|
||||
}
|
||||
|
||||
public int SyncHash()
|
||||
{
|
||||
using (new PerfSample("synchash"))
|
||||
{
|
||||
int ret = 0;
|
||||
foreach (var a in Actors)
|
||||
ret += (int)a.ActorID * Sync.CalculateSyncHash(a);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using OpenRa.FileFormats;
|
||||
using System.Xml;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using OpenRa.FileFormats;
|
||||
|
||||
namespace SequenceEditor
|
||||
{
|
||||
|
||||
17
ra.yaml
Normal file
17
ra.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Red Alert rules
|
||||
#
|
||||
|
||||
Vehicles:
|
||||
V2RL:
|
||||
Buildable: { Description="V2 Rocket", Prerequisites=[weap,dome], TechLevel=4, Cost=700,
|
||||
LongDesc="Long-range rocket artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft" }
|
||||
Unit: { HP=150, Armor=light, Crewed=yes, Voice=VehicleVoice }
|
||||
Mobile: { Sight=5, ROT=5, Speed=7, UMT=Track }
|
||||
AttackBase: { Primary=SCUD, Ammo=1 }
|
||||
RenderUnitReload: {}
|
||||
AutoTarget: {}
|
||||
Repairable: {}
|
||||
Chronoshiftable: {}
|
||||
Passenger: {}
|
||||
IronCurtainable: {}
|
||||
@@ -1228,7 +1228,7 @@ ROT=30
|
||||
|
||||
; big missile silo
|
||||
[MSLO]
|
||||
Prerequisite=stek
|
||||
Prerequisite=stek,atek
|
||||
Primary=none
|
||||
Strength=400
|
||||
Armor=heavy
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
<sequence name="idle" start="0" />
|
||||
<sequence name="damaged-idle" start="1" />
|
||||
<sequence name="make" start="0" length="*" src="atekmake" />
|
||||
<sequence name="active" start="0" length="*" src="sputdoor" />
|
||||
</unit>
|
||||
<!-- soviet tech center -->
|
||||
<unit name="stek">
|
||||
@@ -201,9 +202,9 @@
|
||||
</unit>
|
||||
<!-- iron curtain -->
|
||||
<unit name="iron">
|
||||
<sequence name="idle" start="0" length="1" />
|
||||
<sequence name="active" start="0" length="11" />
|
||||
<sequence name="damaged-idle" start="11" length="1" />
|
||||
<sequence name="idle" start="0" length="1" />
|
||||
<sequence name="active" start="0" length="11" />
|
||||
<sequence name="damaged-idle" start="11" length="1" />
|
||||
<sequence name="damaged-active" start="11" length="11" />
|
||||
<sequence name="make" start="0" length="*" src="ironmake" />
|
||||
</unit>
|
||||
@@ -1030,10 +1031,30 @@
|
||||
<sequence name="left-normal" start="0" length="1" />
|
||||
<sequence name="left-pressed" start="1" length="1" />
|
||||
</unit>
|
||||
<unit name="sputnik">
|
||||
<sequence name="idle" start="0" length="4" />
|
||||
</unit>
|
||||
<unit name="dd-crnr">
|
||||
<sequence name="idle" start="0" length="4" />
|
||||
<sequence name="top-left" start="0" length="1" />
|
||||
<sequence name="top-right" start="1" length="1" />
|
||||
<sequence name="bottom-left" start="2" length="1" />
|
||||
<sequence name="bottom-right" start="3" length="1" />
|
||||
</unit>
|
||||
<unit name="ussrradr">
|
||||
<sequence name="idle" start="0" length="1" />
|
||||
<sequence name="open" start="1" length="20" />
|
||||
<sequence name="jammed" start="21" length="4" />
|
||||
<sequence name="close" start="25" length="16" />
|
||||
<sequence name="no-power" start="41" length="1" />
|
||||
<sequence name="active" start="42" length="1" />
|
||||
</unit>
|
||||
<unit name="natoradr">
|
||||
<sequence name="idle" start="0" length="1" />
|
||||
<sequence name="open" start="1" length="20" />
|
||||
<sequence name="active" start="42" length="1" />
|
||||
<sequence name="jammed" start="21" length="4" />
|
||||
<sequence name="close" start="25" length="16" />
|
||||
<sequence name="no-power" start="41" length="1" />
|
||||
</unit>
|
||||
</sequences>
|
||||
55
thirdparty/yaml/AssemblyInfo.cs
vendored
Normal file
55
thirdparty/yaml/AssemblyInfo.cs
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
//
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
[assembly: AssemblyTitle("Yaml Parser")]
|
||||
[assembly: AssemblyDescription("Yaml .NET library")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("UHasselt students")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("Christophe Lambrechts and Jonathan Slenders")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
154
thirdparty/yaml/Binary.cs
vendored
Normal file
154
thirdparty/yaml/Binary.cs
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// A Yaml Boolean node
|
||||
/// tag:yaml.org,2002:binary
|
||||
/// </summary>
|
||||
public class Binary : Scalar
|
||||
{
|
||||
private byte [] content;
|
||||
|
||||
/// <summary> Binary constructor from byte array </summary>
|
||||
/// <remarks> This constructor only sets the reference, no new memory is allocated </remarks>
|
||||
public Binary (byte[] val) :
|
||||
base ("tag:yaml.org,2002:binary", NodeType.Binary)
|
||||
{
|
||||
content = val;
|
||||
}
|
||||
|
||||
/// <summary> Parse a binary node </summary>
|
||||
public Binary (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:binary", NodeType.Binary)
|
||||
{
|
||||
try
|
||||
{
|
||||
content = Parse (stream);
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
throw new ParseException (stream, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Binary content </summary>
|
||||
/// <remarks> There is no new memory allocated in the 'set'. </remarks>
|
||||
public byte [] Content
|
||||
{
|
||||
get { return content; }
|
||||
set { content = value; }
|
||||
}
|
||||
|
||||
/// <summary> Parses a binairy node. </summary>
|
||||
/// <remarks>
|
||||
/// This is not an efficient method. First the stream is placed
|
||||
/// in a string. And after that the string is converted in a byte[].
|
||||
/// If there is a fault in the binairy string then that will only be detected
|
||||
/// after reading the whole stream and after coneverting.
|
||||
/// </remarks>
|
||||
public static new byte [] Parse (ParseStream stream)
|
||||
{
|
||||
bool quoted = false;
|
||||
bool block = false;
|
||||
System.Text.StringBuilder input = new System.Text.StringBuilder();
|
||||
|
||||
if (stream.EOF)
|
||||
throw new ParseException (stream, "Empty node");
|
||||
|
||||
// Detect block scalar
|
||||
stream.SkipSpaces ();
|
||||
if (stream.Char == '|')
|
||||
{
|
||||
block = true;
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
}
|
||||
|
||||
while ( ! stream.EOF)
|
||||
{
|
||||
// Detect quotes
|
||||
if (stream.Char == '\"')
|
||||
if (quoted)
|
||||
break; //End of stream
|
||||
else
|
||||
quoted = true; //Start of quoted stream
|
||||
// Detect and ignore newline char's
|
||||
else if (!(stream.Char == '\n' && block))
|
||||
input.Append( stream.Char );
|
||||
|
||||
stream.Next ();
|
||||
}
|
||||
|
||||
//Console.WriteLine("convert [" + input.ToString() + "]");
|
||||
|
||||
return System.Convert.FromBase64String (input.ToString ());
|
||||
}
|
||||
|
||||
/// <summary> To String </summary>
|
||||
/// <remarks> The hexadecimal notation, 20 bytes for each line </remarks>
|
||||
public override string ToString ()
|
||||
{
|
||||
System.Text.StringBuilder output = new System.Text.StringBuilder ();
|
||||
|
||||
output.Append ("[BINARY]\n\t");
|
||||
for (uint i = 0; i < content.Length; i++)
|
||||
{
|
||||
if ((i%16) == 0)
|
||||
output.Append( "\n\t" );
|
||||
output.AppendFormat ("{0:X2} ", content[i]);
|
||||
}
|
||||
output.Append ("\n[/BINARY]");
|
||||
|
||||
return output.ToString ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the base64 content to YAML
|
||||
/// </summary>
|
||||
/// <remarks> The lines are splitted in blocks of 20 bytes </remarks>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
stream.Append("!!binary |" + "\n" );
|
||||
|
||||
string bin = System.Convert.ToBase64String(content);
|
||||
|
||||
while (bin.Length > 75)
|
||||
{
|
||||
stream.Append(" " + bin.Substring(0, 75) + "\n");
|
||||
bin = bin.Substring(75);
|
||||
}
|
||||
stream.Append(" " + bin );
|
||||
|
||||
// Old coden, everything on one line
|
||||
// stream.Append ("!!binary \"" + System.Convert.ToBase64String (content) + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
132
thirdparty/yaml/Boolean.cs
vendored
Normal file
132
thirdparty/yaml/Boolean.cs
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for storing a Yaml Boolean node
|
||||
/// tag:yaml.org,2002:bool
|
||||
/// </summary>
|
||||
public class Boolean : Scalar
|
||||
{
|
||||
private bool content;
|
||||
|
||||
/// <summary> New boolean </summary>
|
||||
public Boolean (bool val) :
|
||||
base ("tag:yaml.org,2002:bool", NodeType.Boolean)
|
||||
{
|
||||
content = val;
|
||||
}
|
||||
|
||||
/// <summary> Parse boolean </summary>
|
||||
public Boolean (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:bool", NodeType.Boolean)
|
||||
{
|
||||
// Read the first 8 chars
|
||||
char [] chars = new char [8];
|
||||
|
||||
int length = 0;
|
||||
for (int i = 0; i < chars.Length && ! stream.EOF; i ++)
|
||||
{
|
||||
chars [i] = stream.Char;
|
||||
length ++;
|
||||
stream.Next (true);
|
||||
}
|
||||
|
||||
// Compare
|
||||
if (length == 1)
|
||||
{
|
||||
if (chars[0] == 'Y' || chars[0] == 'y')
|
||||
{ content = true; return; }
|
||||
|
||||
if (chars[0] == 'N' || chars[0] == 'n')
|
||||
{ content = false; return; }
|
||||
}
|
||||
if (length == 2)
|
||||
{
|
||||
string s = "" + chars [0] + chars [1];
|
||||
|
||||
if (s == "ON" || s == "On" || s == "on")
|
||||
{ content = true; return; }
|
||||
|
||||
if (s == "NO" || s == "No" || s == "no")
|
||||
{ content = false; return; }
|
||||
}
|
||||
if (length == 3)
|
||||
{
|
||||
string s = "" + chars [0] + chars [1] + chars [2];
|
||||
|
||||
if (s == "YES" || s == "Yes" || s == "yes")
|
||||
{ content = true; return; }
|
||||
|
||||
if (s == "OFF" || s == "Off" || s == "off")
|
||||
{ content = false; return; }
|
||||
}
|
||||
if (length == 4)
|
||||
{
|
||||
string s = "" + chars [0] + chars [1] + chars [2] + chars [3];
|
||||
|
||||
if (s == "TRUE" || s == "True" || s == "true")
|
||||
{ content = true; return; }
|
||||
}
|
||||
if (length == 5)
|
||||
{
|
||||
string s = "" + chars [0] + chars [1] + chars [2] + chars [3] + chars[4];
|
||||
|
||||
if (s == "FALSE" || s == "False" || s == "false")
|
||||
{ content = false; return; }
|
||||
}
|
||||
|
||||
// No boolean
|
||||
throw new Exception ("No valid boolean");
|
||||
}
|
||||
|
||||
/// <summary> Node content </summary>
|
||||
public bool Content
|
||||
{
|
||||
get { return content; }
|
||||
set { content = value; }
|
||||
}
|
||||
|
||||
/// <summary> To String </summary>
|
||||
public override string ToString ()
|
||||
{
|
||||
return "[BOOLEAN]" + content.ToString () + "[/BOOLEAN]";
|
||||
}
|
||||
|
||||
/// <summary> Write to YAML </summary>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
if (Content)
|
||||
stream.Append ("y");
|
||||
else
|
||||
stream.Append ("n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
504
thirdparty/yaml/COPYING
vendored
Normal file
504
thirdparty/yaml/COPYING
vendored
Normal file
@@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
295
thirdparty/yaml/Float.cs
vendored
Normal file
295
thirdparty/yaml/Float.cs
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for storing a Yaml Float node
|
||||
/// tag:yaml.org,2002:float
|
||||
/// </summary>
|
||||
public class Float : Scalar
|
||||
{
|
||||
private double content;
|
||||
|
||||
/// <summary> New float </summary>
|
||||
public Float (float val) : base ("tag:yaml.org,2002:float", NodeType.Float)
|
||||
{
|
||||
content = val;
|
||||
}
|
||||
|
||||
/// <summary> Parse float </summary>
|
||||
public Float (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:float", NodeType.Float)
|
||||
{
|
||||
// NaN
|
||||
if (stream.Char == '.')
|
||||
{
|
||||
stream.Next (true);
|
||||
ParseNaN (stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
// By default positief
|
||||
int sign = 1;
|
||||
|
||||
// Negative sign
|
||||
if (stream.Char == '-')
|
||||
{
|
||||
sign = -1;
|
||||
stream.Next (true);
|
||||
}
|
||||
// Positive sign
|
||||
else if (stream.Char == '+')
|
||||
stream.Next (true);
|
||||
|
||||
// Test for inf, Inf and INF
|
||||
if ( ! stream.EOF && stream.Char == '.')
|
||||
{
|
||||
stream.Next (true);
|
||||
ParseInf (stream, sign);
|
||||
}
|
||||
// Parse the numbers
|
||||
else if (!stream.EOF)
|
||||
ParseNumber (stream, sign);
|
||||
|
||||
else
|
||||
throw new ParseException (stream,
|
||||
"No valid float, no data behind the sign");
|
||||
}
|
||||
}
|
||||
|
||||
#region Parse special formats (NaN and Inf)
|
||||
/// <summary>
|
||||
/// Test for the value's nan, NaN and NAN in the stream. If
|
||||
/// found then it is placed inside the content.
|
||||
/// There is no more data excepted behind it
|
||||
/// </summary>
|
||||
private void ParseNaN (ParseStream stream)
|
||||
{
|
||||
// Read the first 8 chars
|
||||
char [] chars = new char [8];
|
||||
|
||||
int length = 0;
|
||||
for (int i = 0; i < chars.Length && ! stream.EOF; i ++)
|
||||
{
|
||||
chars [i] = stream.Char;
|
||||
length ++;
|
||||
stream.Next (true);
|
||||
}
|
||||
|
||||
// Compare
|
||||
if (length == 3)
|
||||
{
|
||||
string s = "" + chars [0] + chars [1] + chars [2];
|
||||
|
||||
if (s == "NAN" || s == "NaN" || s == "nan")
|
||||
{
|
||||
content = double.NaN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ParseException (stream, "No valid NaN");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for the value's inf, Inf and INF in the stream. If
|
||||
/// found then it 'merged' with the sign and placed in the content.
|
||||
/// There is no more data excepted behind it.
|
||||
/// </summary>
|
||||
private void ParseInf (ParseStream stream, int sign)
|
||||
{
|
||||
// Read the first 8 chars
|
||||
char [] chars = new char [8];
|
||||
|
||||
int length = 0;
|
||||
for (int i = 0; i < chars.Length && ! stream.EOF; i ++)
|
||||
{
|
||||
chars [i] = stream.Char;
|
||||
length ++;
|
||||
stream.Next (true);
|
||||
}
|
||||
|
||||
// Compare
|
||||
if (length == 3)
|
||||
{
|
||||
string s = "" + chars [0] + chars [1] + chars [2];
|
||||
|
||||
if (s == "INF" || s == "Inf" || s == "inf")
|
||||
{
|
||||
if (sign < 0)
|
||||
content = double.NegativeInfinity;
|
||||
else
|
||||
content = double.PositiveInfinity;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ParseException (stream, "No valid infinity");
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// If it is not Infinity or NaN, then parse as a number
|
||||
/// </summary>
|
||||
private void ParseNumber (ParseStream stream, int sign)
|
||||
{
|
||||
bool base60 = false; // Base 60 with ':'
|
||||
bool afterDecimal = false; // Before or after the decimal point
|
||||
|
||||
double factor = 0.1;
|
||||
double part; // If base60 different parts, else output value
|
||||
|
||||
// Set sign
|
||||
content = sign >= 0 ? 1 : -1;
|
||||
|
||||
// First char must 0-9
|
||||
if (stream.Char >= '0' && stream.Char <= '9')
|
||||
{
|
||||
part = (uint) (stream.Char - '0');
|
||||
stream.Next (true);
|
||||
}
|
||||
else
|
||||
throw new ParseException (stream,
|
||||
"No valid float: Invalid first character of float: " + stream.Char);
|
||||
|
||||
while (! stream.EOF)
|
||||
{
|
||||
// Decimal
|
||||
if (stream.Char >= '0' && stream.Char <= '9')
|
||||
if (afterDecimal)
|
||||
{
|
||||
part += (uint) (stream.Char - '0') * factor;
|
||||
factor *= 0.1;
|
||||
}
|
||||
else
|
||||
part = (part * 10) + (uint) (stream.Char - '0');
|
||||
|
||||
// Base60 detected
|
||||
else if (stream.Char == ':')
|
||||
{
|
||||
if ( ! base60) // First time
|
||||
{
|
||||
content *= part; // Multiply to get sign
|
||||
part = 0;
|
||||
base60 = true; // We are now sure base 60
|
||||
}
|
||||
else
|
||||
{
|
||||
if (part > 59)
|
||||
throw new ParseException (stream,
|
||||
"Part of base 60 can't be larger then 59");
|
||||
content = (60 * content) + part;
|
||||
part = 0;
|
||||
}
|
||||
}
|
||||
// If first '.', then after decimal, else it is ignored if not in Base60
|
||||
else if ( (!base60 || (base60 && !afterDecimal)) && stream.Char == '.' )
|
||||
afterDecimal = true;
|
||||
|
||||
// Determine scientific notation
|
||||
else if ( (stream.Char == 'E' || stream.Char == 'e') && ! base60 )
|
||||
{
|
||||
stream.Next (true);
|
||||
content *= Math.Pow (10, ParseScient (stream));
|
||||
}
|
||||
// Ignore underscores if before the decimal point, special case if base 60
|
||||
else if ((!afterDecimal || (afterDecimal && base60)) && stream.Char != '_')
|
||||
throw new ParseException (stream, "Unknown char");
|
||||
|
||||
stream.Next (true);
|
||||
}
|
||||
|
||||
// Add last part of base to content
|
||||
if (base60)
|
||||
content = (60 * content) + part;
|
||||
else
|
||||
content *= part; // Multiply to get sign
|
||||
}
|
||||
|
||||
/// <summary> Parses the exponential part of the float </summary>
|
||||
private static long ParseScient (ParseStream stream)
|
||||
{
|
||||
ulong output = 0;
|
||||
short sign;
|
||||
|
||||
if (stream.Char == '-')
|
||||
sign = -1;
|
||||
else if (stream.Char == '+')
|
||||
sign = 1;
|
||||
else
|
||||
throw new ParseException (stream,
|
||||
"Excepted + or - for the exponential part");
|
||||
|
||||
stream.Next (true);
|
||||
|
||||
while (! stream.EOF)
|
||||
{
|
||||
if (stream.Char >= '0' && stream.Char <= '9')
|
||||
output = (10 * output) + (uint) stream.Char - '0';
|
||||
else
|
||||
throw new ParseException (stream,
|
||||
"Unexepted char in exponential part: >" +
|
||||
stream.Char + "<");
|
||||
|
||||
stream.Next (true);
|
||||
}
|
||||
|
||||
return sign * (long) output;
|
||||
}
|
||||
|
||||
/// <summary> Content </summary>
|
||||
public double Content
|
||||
{
|
||||
get { return content; }
|
||||
set { content = value; }
|
||||
}
|
||||
|
||||
/// <summary> To string </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return "[FLOAT]" + content + "[/FLOAT]";
|
||||
}
|
||||
|
||||
/// <summary> Write to a YAML node </summary>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
if (content.Equals( double.NaN ))
|
||||
stream.Append ("!!float .NaN");
|
||||
|
||||
else if (content.Equals( double.NegativeInfinity ))
|
||||
stream.Append ("!!float -.Inf");
|
||||
|
||||
else if (content.Equals( double.PositiveInfinity ))
|
||||
stream.Append ("!!float +.Inf");
|
||||
|
||||
else stream.Append ("!!float " + content);
|
||||
}
|
||||
}
|
||||
}
|
||||
266
thirdparty/yaml/Integer.cs
vendored
Normal file
266
thirdparty/yaml/Integer.cs
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for storing a Yaml Integer node
|
||||
/// uri: tag:yaml.org,2002:int
|
||||
/// </summary>
|
||||
public class Integer : Scalar
|
||||
{
|
||||
private long content;
|
||||
|
||||
/// <summary> New Integer </summary>
|
||||
public Integer (long val) :
|
||||
base ("tag:yaml.org,2002:int", NodeType.Integer)
|
||||
{
|
||||
content = val;
|
||||
}
|
||||
|
||||
/// <summary> Content </summary>
|
||||
public long Content
|
||||
{
|
||||
get { return content; }
|
||||
set { content = value; }
|
||||
}
|
||||
|
||||
/// <summary> Parse an integer </summary>
|
||||
public Integer (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:int", NodeType.Integer)
|
||||
{
|
||||
short sign = 1; // Positive sign by default
|
||||
|
||||
// Negative sign
|
||||
if (stream.Char == '-')
|
||||
{
|
||||
sign = -1;
|
||||
stream.Next ();
|
||||
}
|
||||
// Positive sign
|
||||
else if (stream.Char == '+')
|
||||
stream.Next ();
|
||||
|
||||
try
|
||||
{
|
||||
// Determine base
|
||||
if (stream.Char == '0')
|
||||
{
|
||||
stream.Next ();
|
||||
|
||||
// Base 2
|
||||
if (stream.Char == 'b')
|
||||
{
|
||||
stream.Next ();
|
||||
content = ParseBase (stream, 2, sign);
|
||||
return;
|
||||
}
|
||||
// Base 16
|
||||
else if (stream.Char == 'x')
|
||||
{
|
||||
stream.Next ();
|
||||
content = Parse16 (stream, sign);
|
||||
return;
|
||||
}
|
||||
// Base 8
|
||||
else
|
||||
{
|
||||
content = ParseBase (stream, 8, sign);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Other base
|
||||
stream.BuildLookaheadBuffer ();
|
||||
|
||||
// First, try to parse with base 10
|
||||
try
|
||||
{
|
||||
content = ParseBase (stream, 10, sign);
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
return;
|
||||
}
|
||||
catch { }
|
||||
|
||||
// If not parseable with base 10, then try base 60
|
||||
stream.RewindLookaheadBuffer ();
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
|
||||
content = Parse60 (stream, sign);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ParseException (stream, ex.ToString ());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Hexadecimal string </summary>
|
||||
private static long Parse16 (ParseStream stream, short sign)
|
||||
{
|
||||
uint output = 0;
|
||||
|
||||
while (! stream.EOF)
|
||||
{
|
||||
// 0 .. 9
|
||||
if (stream.Char >= '0' && stream.Char <= '9')
|
||||
{
|
||||
output = (output * 16) + (uint) (stream.Char - '0');
|
||||
OverflowTest (output, sign);
|
||||
}
|
||||
// a .. f
|
||||
else if (stream.Char >= 'a' && stream.Char <= 'f')
|
||||
{
|
||||
output = (output * 16) + (uint) (stream.Char - 'a') + 10;
|
||||
OverflowTest (output, sign);
|
||||
}
|
||||
// A .. F
|
||||
else if (stream.Char >= 'A' && stream.Char <= 'F')
|
||||
{
|
||||
output = (output * 16) + (uint) (stream.Char - 'A') + 10;
|
||||
OverflowTest(output, sign);
|
||||
}
|
||||
// Ignore underscores, other chars are not allowed
|
||||
else if (stream.Char != '_')
|
||||
throw new Exception ("Unknown char in base 16");
|
||||
|
||||
stream.Next ();
|
||||
}
|
||||
|
||||
return (long) (sign * output);
|
||||
}
|
||||
|
||||
/// <summary> Parses a string with a given base (maximum 10) </summary>
|
||||
/// <remarks>
|
||||
/// This is not completly correct. For base10 the first char may not be a '_'
|
||||
/// The other bases allow this...
|
||||
/// </remarks>
|
||||
private static long ParseBase (ParseStream stream, uint basis, short sign)
|
||||
{
|
||||
// Base must be <= 10
|
||||
if (basis > 10)
|
||||
throw new Exception ("Base to large. Maximum 10");
|
||||
|
||||
ulong output = 0;
|
||||
char max = (char) ((basis - 1) + (int) '0');
|
||||
|
||||
// Parse
|
||||
while (! stream.EOF)
|
||||
{
|
||||
// Decimal
|
||||
if (stream.Char >= '0' && stream.Char <= max)
|
||||
{
|
||||
output = (output * basis) + (uint) (stream.Char - '0');
|
||||
OverflowTest (output, sign);
|
||||
}
|
||||
// Ignore underscores, but other chars are not allowed
|
||||
// see remarks
|
||||
else if (stream.Char != '_')
|
||||
throw new Exception ("Unknown char in base " + basis);
|
||||
|
||||
stream.Next ();
|
||||
}
|
||||
return sign * (long) output;
|
||||
}
|
||||
|
||||
/// <summary> Parses a string with base 60, without sign </summary>
|
||||
private static long Parse60 (ParseStream stream, short sign)
|
||||
{
|
||||
ulong output = 0;
|
||||
|
||||
// Parse
|
||||
ulong part = 0;
|
||||
bool firstPart = true; // Only the first part can be larger then 59
|
||||
|
||||
while (! stream.EOF)
|
||||
{
|
||||
// Decimal
|
||||
if (stream.Char >= '0' && stream.Char <= '9')
|
||||
part = (part * 10) + (uint) (stream.Char - '0');
|
||||
|
||||
// New part
|
||||
else if (stream.Char == ':')
|
||||
{
|
||||
// Only the first part can be largen then 60
|
||||
if ( ! firstPart)
|
||||
if (part >= 60)
|
||||
throw new
|
||||
Exception ("Part of base 60 scalar is too large (max. 59)");
|
||||
else
|
||||
firstPart = false;
|
||||
|
||||
output = (output * 60) + part;
|
||||
OverflowTest(output, sign);
|
||||
part = 0;
|
||||
}
|
||||
|
||||
// Ignore underscores, other chars are not allowed
|
||||
else if (stream.Char != '_')
|
||||
throw new Exception ("Unknown char in base 16");
|
||||
|
||||
stream.Next ();
|
||||
}
|
||||
|
||||
// Add last part to the output
|
||||
if (!firstPart)
|
||||
if (part >= 60)
|
||||
throw new Exception (
|
||||
"Part of base 60 scalar is too large (max. 59)");
|
||||
else
|
||||
firstPart = false;
|
||||
|
||||
output = (output * 60) + part;
|
||||
OverflowTest (output, sign);
|
||||
|
||||
return sign * (long) output;
|
||||
}
|
||||
|
||||
/// <summary> Test that the unsigned int fits in a signed int </summary>
|
||||
/// <param name="number"> Value to test </param>
|
||||
/// <param name="sign"> Sign of the int where it must fit in </param>
|
||||
private static void OverflowTest (ulong number, short sign)
|
||||
{
|
||||
// NOTE: Negatif numbers can be one larger
|
||||
if ((sign >= 0 && number > System.Int64.MaxValue) ||
|
||||
(sign < 0 && number > (ulong) System.Int64.MaxValue + 1) )
|
||||
|
||||
throw new Exception ("YAML overflow exception");
|
||||
}
|
||||
|
||||
/// <summary> To String </summary>
|
||||
public override string ToString ()
|
||||
{
|
||||
return "[INTEGER]" + content.ToString () + "[/INTEGER]";
|
||||
}
|
||||
|
||||
/// <summary> Write to YAML </summary>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
stream.Append (content.ToString ());
|
||||
}
|
||||
}
|
||||
}
|
||||
292
thirdparty/yaml/Mapping.cs
vendored
Normal file
292
thirdparty/yaml/Mapping.cs
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
// TODO Access to nodes via the [] overload
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Yaml Mapping
|
||||
/// </summary>
|
||||
public class Mapping : Node
|
||||
{
|
||||
private ArrayList childNodes = new ArrayList ();
|
||||
|
||||
/// <summary> New empty mapping </summary>
|
||||
public Mapping () : base ("tag:yaml.org,2002:map", NodeType.Mapping) { }
|
||||
|
||||
/// <summary> New mapping from a mappingnode array </summary>
|
||||
public Mapping (MappingNode [] nodes) :
|
||||
base ("tag:yaml.org,2002:map", NodeType.Mapping)
|
||||
{
|
||||
foreach (MappingNode node in nodes)
|
||||
childNodes.Add (node);
|
||||
}
|
||||
|
||||
/// <summary> Parse a mapping </summary>
|
||||
public Mapping (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:map", NodeType.Mapping)
|
||||
{
|
||||
// Mapping with eplicit key, (implicit mappings are threaded
|
||||
// in Node.cs)
|
||||
if (stream.Char == '?')
|
||||
{
|
||||
// Parse recursively
|
||||
do {
|
||||
Node key, val;
|
||||
|
||||
// Skip over '?'
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
|
||||
// Parse recursively. The false param avoids
|
||||
// looking recursively for implicit mappings.
|
||||
stream.StopAt (new char [] {':'});
|
||||
stream.Indent ();
|
||||
key = Parse (stream, false);
|
||||
stream.UnIndent ();
|
||||
stream.DontStop ();
|
||||
|
||||
// Parse recursively. The false param avoids
|
||||
// looking for implit nodes
|
||||
if (stream.Char == ':')
|
||||
{
|
||||
// Skip over ':'
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
|
||||
// Parse recursively
|
||||
stream.Indent ();
|
||||
val = Parse (stream);
|
||||
stream.UnIndent ();
|
||||
}
|
||||
else
|
||||
val = new Null ();
|
||||
|
||||
AddMappingNode (key, val);
|
||||
|
||||
// Skip possible newline
|
||||
// NOTE: this can't be done by the drop-newline
|
||||
// method since this is not the end of a block
|
||||
if (stream.Char == '\n')
|
||||
stream.Next ();
|
||||
}
|
||||
while ( ! stream.EOF && stream.Char == '?');
|
||||
}
|
||||
// Inline mapping
|
||||
else if (stream.Char == '{')
|
||||
{
|
||||
// Override the parent's stop chars, never stop
|
||||
stream.StopAt (new char [] { });
|
||||
|
||||
// Skip '{'
|
||||
stream.Next ();
|
||||
|
||||
do {
|
||||
Node key, val;
|
||||
|
||||
// Skip '?'
|
||||
// (NOTE: it's not obligated to use this '?',
|
||||
// especially because this is an inline mapping)
|
||||
if (stream.Char == '?')
|
||||
{
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
}
|
||||
|
||||
// Parse recursively the key
|
||||
stream.StopAt (new char [] {':', ',', '}'});
|
||||
stream.Indent ();
|
||||
key = Parse (stream, false);
|
||||
stream.UnIndent ();
|
||||
stream.DontStop ();
|
||||
|
||||
// Value
|
||||
if (stream.Char == ':')
|
||||
{
|
||||
// Skip colon
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
|
||||
// Parse recursively the value
|
||||
stream.StopAt (new char [] {'}', ','});
|
||||
stream.Indent ();
|
||||
val = Parse (stream, false);
|
||||
stream.UnIndent ();
|
||||
stream.DontStop ();
|
||||
}
|
||||
else
|
||||
val = new Null ();
|
||||
|
||||
AddMappingNode (key, val);
|
||||
|
||||
// Skip comma (key sepatator)
|
||||
if (stream.Char != '}' && stream.Char != ',')
|
||||
{
|
||||
stream.DontStop ();
|
||||
throw new ParseException (stream, "Comma expected in inline sequence");
|
||||
}
|
||||
|
||||
if (stream.Char == ',')
|
||||
{
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
}
|
||||
}
|
||||
while ( ! stream.EOF && stream.Char != '}' );
|
||||
|
||||
// Re-accept the parent's stop chars
|
||||
stream.DontStop ();
|
||||
|
||||
// Skip '}'
|
||||
if (stream.Char == '}')
|
||||
stream.Next ();
|
||||
else
|
||||
throw new ParseException (stream, "Inline mapping not closed");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Add a node to this mapping </summary>
|
||||
public void AddMappingNode (Node key, Node val)
|
||||
{
|
||||
childNodes.Add (new MappingNode (key, val));
|
||||
}
|
||||
|
||||
/// <summary> Add a node to this mapping </summary>
|
||||
public void AddMappingNode (MappingNode node)
|
||||
{
|
||||
if (node != null)
|
||||
childNodes.Add (node);
|
||||
else
|
||||
childNodes.Add (new MappingNode (null, null));
|
||||
}
|
||||
|
||||
/// <summary> Number of mappings </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return childNodes.Count; }
|
||||
}
|
||||
|
||||
/// <summary> To String </summary>
|
||||
public override string ToString ()
|
||||
{
|
||||
string result = "";
|
||||
foreach (MappingNode node in childNodes)
|
||||
result += node.ToString ();
|
||||
|
||||
return "[MAPPING]" + result + "[/MAPPING]";
|
||||
}
|
||||
|
||||
/// <summary> Node info </summary>
|
||||
public override Node Info ()
|
||||
{
|
||||
Mapping mapping = new Mapping ();
|
||||
mapping.AddMappingNode (new String ("kind"), new String ("mapping"));
|
||||
mapping.AddMappingNode (new String ("type_id"), new String (URI));
|
||||
|
||||
Mapping childs = new Mapping ();
|
||||
int i = 0;
|
||||
foreach (MappingNode child in childNodes)
|
||||
{
|
||||
Sequence keyvaluepair = new Sequence ();
|
||||
keyvaluepair.AddNode (child.Key.Info () );
|
||||
keyvaluepair.AddNode (child.Value.Info ());
|
||||
|
||||
childs.AddMappingNode (new String ("key_" + i), keyvaluepair);
|
||||
i ++;
|
||||
}
|
||||
|
||||
mapping.AddMappingNode (new String ("value"), childs);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/// <summary> Write to YAML </summary>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
foreach (MappingNode node in childNodes)
|
||||
{
|
||||
stream.Append ("? ");
|
||||
|
||||
stream.Indent ();
|
||||
Yaml.Node key = node.Key;
|
||||
key.Write (stream);
|
||||
stream.UnIndent ();
|
||||
|
||||
stream.Append (": ");
|
||||
|
||||
stream.Indent ();
|
||||
node.Value.Write (stream);
|
||||
stream.UnIndent ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Node pair (key, value) of a mapping
|
||||
/// </summary>
|
||||
public class MappingNode
|
||||
{
|
||||
private Node key;
|
||||
private Node val;
|
||||
|
||||
/// <summary> Create a new mappingnode </summary>
|
||||
public MappingNode (Node key, Node val)
|
||||
{
|
||||
if (key == null) key = new Null ();
|
||||
if (val == null) val = new Null ();
|
||||
|
||||
this.key = key;
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
/// <summary> Key property </summary>
|
||||
public Node Key
|
||||
{
|
||||
get { return key; }
|
||||
set { key = (value == null ? new Null () : value); }
|
||||
}
|
||||
|
||||
/// <summary> Value property </summary>
|
||||
public Node Value
|
||||
{
|
||||
get { return val; }
|
||||
set { val = (value == null ? new Null () : value); }
|
||||
}
|
||||
|
||||
/// <summary> To String </summary>
|
||||
public override string ToString ()
|
||||
{
|
||||
return
|
||||
"[KEY]" + key.ToString () + "[/KEY]" +
|
||||
"[VAL]" + val.ToString () + "[/VAL]";
|
||||
}
|
||||
}
|
||||
}
|
||||
469
thirdparty/yaml/Node.cs
vendored
Normal file
469
thirdparty/yaml/Node.cs
vendored
Normal file
@@ -0,0 +1,469 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
#define UNSTABLE
|
||||
#define SUPPORT_EXPLICIT_TYPES
|
||||
#define SUPPORT_IMPLICIT_MAPPINGS
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Kind of node, used to determine the type of node.
|
||||
/// </summary>
|
||||
public enum NodeType
|
||||
{
|
||||
/// <summary>A Yaml mapping - collection type</summary>
|
||||
Mapping,
|
||||
/// <summary>A Yaml sequence - collection type</summary>
|
||||
Sequence,
|
||||
|
||||
/// <summary>A Yaml binary scalar </summary>
|
||||
Binary,
|
||||
/// <summary>A Yaml boolean scalar </summary>
|
||||
Boolean,
|
||||
/// <summary>A Yaml float scalar </summary>
|
||||
Float,
|
||||
/// <summary>A Yaml integer scalar </summary>
|
||||
Integer,
|
||||
/// <summary>A Yaml null scalar </summary>
|
||||
Null,
|
||||
/// <summary>A Yaml string scalar </summary>
|
||||
String,
|
||||
/// <summary>A Yaml timestamp scalar </summary>
|
||||
Timestamp
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Node in the Yaml tree
|
||||
/// </summary>
|
||||
|
||||
public abstract class Node
|
||||
{
|
||||
/// <summary> The uri given by http://yaml.org/type/ </summary>
|
||||
protected readonly string uri;
|
||||
|
||||
/// <summary> Determines wich node we are talking about </summary>
|
||||
protected NodeType nodetype;
|
||||
|
||||
/// <summary> Node Constructor </summary>
|
||||
/// <param name="uri"> URI of the node </param>
|
||||
/// <param name="nodetype"> The type of node that we want to store </param>
|
||||
public Node (string uri, NodeType nodetype)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.nodetype = nodetype;
|
||||
}
|
||||
|
||||
/// <summary> Parse a Yaml string and return a Yaml tree </summary>
|
||||
public static Node Parse (string lines)
|
||||
{
|
||||
StringReader reader = new StringReader (lines);
|
||||
Node node = Parse (new ParseStream (reader));
|
||||
reader.Close ();
|
||||
return node;
|
||||
}
|
||||
|
||||
/// <summary> Parse a Yaml string from a textreader and return a Yaml tree </summary>
|
||||
public static Node Parse (TextReader textreader)
|
||||
{
|
||||
return Parse (new ParseStream (textreader));
|
||||
}
|
||||
|
||||
/// <summary> Return a Yaml string </summary>
|
||||
public string Write ()
|
||||
{
|
||||
StringWriter stringWriter = new StringWriter ();
|
||||
WriteStream writeStream = new WriteStream (stringWriter);
|
||||
|
||||
Write (writeStream);
|
||||
|
||||
stringWriter.Close ();
|
||||
return stringWriter.ToString ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Yaml string from a textfile and return a Yaml tree
|
||||
/// </summary>
|
||||
public static Node FromFile (string filename)
|
||||
{
|
||||
// Open YAML file
|
||||
StreamReader reader = File.OpenText (filename);
|
||||
ParseStream parsestream = new ParseStream (reader);
|
||||
|
||||
// Parse
|
||||
Node node = Parse (parsestream);
|
||||
|
||||
// Close YAML file
|
||||
reader.Close ();
|
||||
return node;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a YAML tree to a file using UTF-8 encoding
|
||||
/// </summary>
|
||||
public void ToFile (string filename)
|
||||
{
|
||||
ToFile (filename, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a YAML tree to a file
|
||||
/// </summary>
|
||||
public void ToFile (string filename, Encoding enc)
|
||||
{
|
||||
// Open YAML file
|
||||
StreamWriter writer = new StreamWriter (filename, false, enc);
|
||||
WriteStream writestream = new WriteStream (writer);
|
||||
|
||||
// Write
|
||||
Write (writestream);
|
||||
|
||||
// Close YAML file
|
||||
writer.Close ();
|
||||
}
|
||||
|
||||
/// <summary> Parse function </summary>
|
||||
protected static Node Parse (ParseStream stream) { return Parse (stream, true); }
|
||||
|
||||
/// <summary> Internal parse method </summary>
|
||||
/// <param name="parseImplicitMappings">
|
||||
/// Avoids ethernal loops while parsing implicit mappings. Implicit mappings are
|
||||
/// not rocognized by a leading character. So while trying to parse the key of
|
||||
/// something we think that could be a mapping, we're sure that if it is a mapping,
|
||||
/// the key of this implicit mapping is not a mapping itself.
|
||||
///
|
||||
/// NOTE: Implicit mapping still belong to unstable code and require the UNSTABLE and
|
||||
/// IMPLICIT_MAPPINGS preprocessor flags.
|
||||
/// </param>
|
||||
/// <param name="stream"></param>
|
||||
protected static Node Parse (ParseStream stream, bool parseImplicitMappings)
|
||||
{
|
||||
// ----------------
|
||||
// Skip Whitespace
|
||||
// ----------------
|
||||
if (! stream.EOF)
|
||||
{
|
||||
// Move the firstindentation pointer after the whitespaces of this line
|
||||
stream.SkipSpaces ();
|
||||
while (stream.Char == '\n' && ! stream.EOF)
|
||||
{
|
||||
// Skip newline and next whitespaces
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------
|
||||
// No remaining chars (Null/empty stream)
|
||||
// -----------------
|
||||
if (stream.EOF)
|
||||
return new Null ();
|
||||
|
||||
// -----------------
|
||||
// Explicit type
|
||||
// -----------------
|
||||
|
||||
#if SUPPORT_EXPLICIT_TYPES
|
||||
stream.BuildLookaheadBuffer ();
|
||||
|
||||
char a = '\0', b = '\0';
|
||||
|
||||
a = stream.Char; stream.Next ();
|
||||
b = stream.Char; stream.Next ();
|
||||
|
||||
// Starting with !!
|
||||
if (a == '!' && b == '!' && ! stream.EOF)
|
||||
{
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
|
||||
// Read the tagname
|
||||
string tag = "";
|
||||
|
||||
while (stream.Char != ' ' && stream.Char != '\n' && ! stream.EOF)
|
||||
{
|
||||
tag += stream.Char;
|
||||
stream.Next ();
|
||||
}
|
||||
|
||||
// Skip Whitespace
|
||||
if (! stream.EOF)
|
||||
{
|
||||
stream.SkipSpaces ();
|
||||
while (stream.Char == '\n' && ! stream.EOF)
|
||||
{
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
}
|
||||
}
|
||||
|
||||
// Parse
|
||||
Node n;
|
||||
switch (tag)
|
||||
{
|
||||
// Mappings and sequences
|
||||
// NOTE:
|
||||
// - sets are mappings without values
|
||||
// - Ordered maps are ordered sequence of key: value
|
||||
// pairs without duplicates.
|
||||
// - Pairs are ordered sequence of key: value pairs
|
||||
// allowing duplicates.
|
||||
|
||||
// TODO: Create new datatypes for omap and pairs
|
||||
// derived from sequence with a extra duplicate
|
||||
// checking.
|
||||
|
||||
case "seq": n = new Sequence (stream); break;
|
||||
case "map": n = new Mapping (stream); break;
|
||||
case "set": n = new Mapping (stream); break;
|
||||
case "omap": n = new Sequence (stream); break;
|
||||
case "pairs": n = new Sequence (stream); break;
|
||||
|
||||
// Scalars
|
||||
//
|
||||
// TODO: do we have to move this to Scalar.cs
|
||||
// in order to get the following working:
|
||||
//
|
||||
// !!str "...": "..."
|
||||
// !!str "...": "..."
|
||||
|
||||
case "timestamp": n = new Timestamp (stream); break;
|
||||
case "binary": n = new Binary (stream); break;
|
||||
case "null": n = new Null (stream); break;
|
||||
case "float": n = new Float (stream); break;
|
||||
case "int": n = new Integer (stream); break;
|
||||
case "bool": n = new Boolean (stream); break;
|
||||
case "str": n = new String (stream); break;
|
||||
|
||||
// Unknown data type
|
||||
default:
|
||||
throw new Exception ("Incorrect tag '!!" + tag + "'");
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.RewindLookaheadBuffer ();
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
}
|
||||
#endif
|
||||
// -----------------
|
||||
// Sequence
|
||||
// -----------------
|
||||
|
||||
if (stream.Char == '-' || stream.Char == '[')
|
||||
return new Sequence (stream);
|
||||
|
||||
// -----------------
|
||||
// Mapping
|
||||
// -----------------
|
||||
|
||||
if (stream.Char == '?' || stream.Char == '{')
|
||||
return new Mapping (stream);
|
||||
|
||||
// -----------------
|
||||
// Try implicit mapping
|
||||
// -----------------
|
||||
|
||||
// This are mappings which are not preceded by a question
|
||||
// mark. The keys have to be scalars.
|
||||
|
||||
#if (UNSTABLE && SUPPORT_IMPLICIT_MAPPINGS)
|
||||
|
||||
// NOTE: This code can't be included in Mapping.cs
|
||||
// because of the way we are using to rewind the buffer.
|
||||
|
||||
Node key, val;
|
||||
|
||||
if (parseImplicitMappings)
|
||||
{
|
||||
// First Key/value pair
|
||||
|
||||
stream.BuildLookaheadBuffer ();
|
||||
|
||||
stream.StopAt (new char [] {':'});
|
||||
|
||||
// Keys of implicit mappings can't be sequences, or other mappings
|
||||
// just look for scalars
|
||||
key = Scalar.Parse (stream, false);
|
||||
stream.DontStop ();
|
||||
|
||||
Console.WriteLine ("key: " + key);
|
||||
|
||||
// Followed by a colon, so this is a real mapping
|
||||
if (stream.Char == ':')
|
||||
{
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
|
||||
Mapping mapping = new Mapping ();
|
||||
|
||||
// Skip colon and spaces
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
|
||||
// Parse the value
|
||||
Console.Write ("using buffer: " + stream.UsingBuffer ());
|
||||
stream.Indent ();
|
||||
Console.Write ("using buffer: " + stream.UsingBuffer ());
|
||||
// val = Parse (stream, false);
|
||||
Console.Write ("<<");
|
||||
while (!stream.EOF) {Console.Write (stream.Char);stream.Next (true);}
|
||||
Console.Write (">>");
|
||||
|
||||
val = new String (stream);
|
||||
|
||||
|
||||
Console.Write ("using buffer: " + stream.UsingBuffer ());
|
||||
stream.UnIndent ();
|
||||
Console.Write ("using buffer: " + stream.UsingBuffer ());
|
||||
|
||||
Console.Write ("<<");
|
||||
while (!stream.EOF) {Console.Write (stream.Char);stream.Next (true);}
|
||||
Console.Write (">>");
|
||||
|
||||
|
||||
|
||||
|
||||
Console.WriteLine ("val: " + val);
|
||||
mapping.AddMappingNode (key, val);
|
||||
|
||||
// Skip possible newline
|
||||
// NOTE: this can't be done by the drop-newline
|
||||
// method since this is not the end of a block
|
||||
while (stream.Char == '\n')
|
||||
stream.Next (true);
|
||||
|
||||
// Other key/value pairs
|
||||
while (! stream.EOF)
|
||||
{
|
||||
stream.StopAt (new char [] {':'} );
|
||||
stream.Indent ();
|
||||
key = Scalar.Parse (stream);
|
||||
stream.UnIndent ();
|
||||
stream.DontStop ();
|
||||
|
||||
Console.WriteLine ("key 2: " + key);
|
||||
if (stream.Char == ':')
|
||||
{
|
||||
// Skip colon and spaces
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
|
||||
// Parse the value
|
||||
stream.Indent ();
|
||||
val = Parse (stream);
|
||||
stream.UnIndent ();
|
||||
|
||||
Console.WriteLine ("val 2: " + val);
|
||||
mapping.AddMappingNode (key, val);
|
||||
}
|
||||
else // TODO: Is this an error?
|
||||
{
|
||||
// NOTE: We can't recover from this error,
|
||||
// the last buffer has been destroyed, so
|
||||
// rewinding is impossible.
|
||||
throw new ParseException (stream,
|
||||
"Implicit mapping without value node");
|
||||
}
|
||||
|
||||
// Skip possible newline
|
||||
while (stream.Char == '\n')
|
||||
stream.Next ();
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
stream.RewindLookaheadBuffer ();
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
}
|
||||
|
||||
#endif
|
||||
// -----------------
|
||||
// No known data structure, assume this is a scalar
|
||||
// -----------------
|
||||
|
||||
Scalar scalar = Scalar.Parse (stream);
|
||||
|
||||
// Skip trash
|
||||
while (! stream.EOF)
|
||||
stream.Next ();
|
||||
|
||||
|
||||
return scalar;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URI of this node, according to the YAML documentation.
|
||||
/// </summary>
|
||||
public string URI
|
||||
{
|
||||
get { return uri; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kind of node: mapping, sequence, string, ...
|
||||
/// </summary>
|
||||
public NodeType Type
|
||||
{
|
||||
get { return nodetype; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a Yaml tree back to a file or stream
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// should not be called from outside the parser. This method
|
||||
/// is only public from inside the Sequence and Mapping Write
|
||||
/// methods.
|
||||
/// </remarks>
|
||||
/// <param name="stream">Were the output data go's</param>
|
||||
protected internal virtual void Write (WriteStream stream) {}
|
||||
|
||||
/// <summary>
|
||||
/// The ToString method here, and in all the classses
|
||||
/// derived from this class, is used mainly for debugging
|
||||
/// purpose. ToString returns a xml-like textual representation
|
||||
/// of the objects. It's very useful to see how a Yaml document
|
||||
/// has been parsed because of the disambiguous representation
|
||||
/// of this notation.
|
||||
/// </summary>
|
||||
public override abstract string ToString ();
|
||||
|
||||
/// <summary>
|
||||
/// Node info returns a YAML node and is also mostly used
|
||||
/// for debugging the parser. This could be used for
|
||||
/// traversing the meta-info of another YAML tree
|
||||
/// </summary>
|
||||
public abstract Node Info ();
|
||||
}
|
||||
}
|
||||
100
thirdparty/yaml/Null.cs
vendored
Normal file
100
thirdparty/yaml/Null.cs
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for storing a Yaml Null node
|
||||
/// tag:yaml.org,2002:null
|
||||
/// </summary>
|
||||
public class Null : Scalar
|
||||
{
|
||||
/// <summary> Null Constructor </summary>
|
||||
public Null () : base ("tag:yaml.org,2002:null", NodeType.Null) { }
|
||||
|
||||
/// <summary> Parse a null node </summary>
|
||||
public Null (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:null", NodeType.Null)
|
||||
{
|
||||
// An empty string is a valid null node
|
||||
if (stream.EOF)
|
||||
return;
|
||||
|
||||
else
|
||||
{
|
||||
// Read the first 4 chars
|
||||
char [] chars = new char [8];
|
||||
int length = 0;
|
||||
for (int i = 0; i < chars.Length && ! stream.EOF; i ++)
|
||||
{
|
||||
chars [i] = stream.Char;
|
||||
length ++;
|
||||
stream.Next ();
|
||||
}
|
||||
|
||||
// Compare
|
||||
if (length == 1)
|
||||
{
|
||||
string s = "" + chars [0];
|
||||
|
||||
// Canonical notation
|
||||
if (s == "~")
|
||||
return;
|
||||
}
|
||||
if (length == 4)
|
||||
{
|
||||
string s = "" + chars [0] + chars [1] + chars [2] + chars [3];
|
||||
|
||||
// null, Null, NULL
|
||||
if (s == "NULL" || s == "Null" || s == "null")
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ParseException (stream, "Not NULL");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Content property </summary>
|
||||
public object Content
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
/// <summary> To String </summary>
|
||||
public override string ToString ()
|
||||
{
|
||||
return "[NULL]~[/NULL]";
|
||||
}
|
||||
|
||||
/// <summary> Write to YAML </summary>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
stream.Append ("~");
|
||||
}
|
||||
}
|
||||
}
|
||||
63
thirdparty/yaml/ParseException.cs
vendored
Normal file
63
thirdparty/yaml/ParseException.cs
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// ParseException, could be thrown while parsing a YAML stream
|
||||
/// </summary>
|
||||
public class ParseException : Exception
|
||||
{
|
||||
// Line of the Yaml stream/file where the fault occures
|
||||
private readonly int linenr;
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
/// <param name="stream"> The parse stream (contains the line number where it went wrong) </param>
|
||||
/// <param name="message"> Info about the exception </param>
|
||||
public ParseException (ParseStream stream, string message) :
|
||||
base ("Parse error near line " + stream.CurrentLine + ": " + message)
|
||||
{
|
||||
this.linenr = stream.CurrentLine;
|
||||
}
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
/// <param name="stream"> The parse stream (contains the line number where it went wrong) </param>
|
||||
/// <param name="child"> The exception that is for example throwed again </param>
|
||||
public ParseException (ParseStream stream, Exception child) :
|
||||
base ( "Parse error near line " + stream.CurrentLine, child )
|
||||
{
|
||||
this.linenr = stream.CurrentLine;
|
||||
}
|
||||
|
||||
/// <summary> The line where the error occured </summary>
|
||||
public int LineNumber
|
||||
{
|
||||
get { return linenr; }
|
||||
}
|
||||
}
|
||||
}
|
||||
899
thirdparty/yaml/ParseStream.cs
vendored
Normal file
899
thirdparty/yaml/ParseStream.cs
vendored
Normal file
@@ -0,0 +1,899 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// The Preprocessor class
|
||||
/// Given a character stream, this class will
|
||||
/// walk through that stream.
|
||||
/// NOTE: Comments are not longer skipped at this level,
|
||||
/// but now in the last level instead. (because of
|
||||
/// problems with comments within the buffer)
|
||||
/// NOTE: Null characters are skipped, read nulls should
|
||||
/// be escaped. \0
|
||||
/// </summary>
|
||||
public class Preprocessor
|
||||
{
|
||||
private TextReader stream;
|
||||
private int currentline = 1; // Line numbers start with one
|
||||
private bool literal = false; // Parse literal/verbatim
|
||||
|
||||
/// <summary> Constuctor </summary>
|
||||
public Preprocessor (TextReader stream)
|
||||
{
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
/// <summary> Jump to the next character </summary>
|
||||
public void Next ()
|
||||
{
|
||||
// Transition to the next line?
|
||||
if (Char == '\n')
|
||||
currentline ++;
|
||||
|
||||
// Not yet passed the end of file
|
||||
if (! EOF)
|
||||
{
|
||||
// Next
|
||||
stream.Read ();
|
||||
|
||||
// Skip null chars
|
||||
while (stream.Peek () == '\0')
|
||||
stream.Read ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Start parsing literal </summary>
|
||||
public void StartLiteral ()
|
||||
{
|
||||
literal = true;
|
||||
}
|
||||
|
||||
/// <summary> Stop parsing literal </summary>
|
||||
public void StopLiteral ()
|
||||
{
|
||||
if (literal)
|
||||
literal = false;
|
||||
else
|
||||
throw new Exception ("Called StopLiteral without " +
|
||||
"calling StartLiteral before");
|
||||
}
|
||||
|
||||
/// <summary> Literal parsing </summary>
|
||||
public bool Literal
|
||||
{
|
||||
get { return literal; }
|
||||
// No set method, setting must by using the {Start,Stop}Literal
|
||||
// methods. They provide mory symmetry in the parser.
|
||||
}
|
||||
|
||||
/// <summary> The current character </summary>
|
||||
public char Char
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EOF)
|
||||
return '\0';
|
||||
else
|
||||
return (char) stream.Peek ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> End of file/stream </summary>
|
||||
public bool EOF
|
||||
{
|
||||
get { return stream.Peek () == -1; }
|
||||
}
|
||||
|
||||
/// <summary> Returns the current line number </summary>
|
||||
public int CurrentLine
|
||||
{
|
||||
get { return currentline; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The indentation processor,
|
||||
/// This class divides the stream from the preprocessor
|
||||
/// in substreams, according to the current level
|
||||
/// of indentation.
|
||||
/// </summary>
|
||||
public class IndentationProcessor : Preprocessor
|
||||
{
|
||||
// While trying to readahead over whitespaces,
|
||||
// This is how many whitespaces were skipped that weren't yet read
|
||||
private int whitespaces = 0;
|
||||
private int whitespacesSkipped = 0;
|
||||
|
||||
// Reached the end
|
||||
private bool endofstream = false;
|
||||
|
||||
// Current level of indentation
|
||||
private int indentationLevel = 0;
|
||||
private bool indentationRequest = false;
|
||||
private Stack indentationStack = new Stack ();
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
public IndentationProcessor (TextReader stream) : base (stream) { }
|
||||
|
||||
/// <summary>
|
||||
/// Request an indentation. When we meet a \n and the following
|
||||
/// line is more indented then the current indentationlever, then
|
||||
/// save this request
|
||||
/// </summary>
|
||||
public void Indent ()
|
||||
{
|
||||
if (Literal)
|
||||
throw new Exception ("Cannot (un)indent while literal parsing " +
|
||||
"has been enabled");
|
||||
else
|
||||
{
|
||||
// Handle double requests
|
||||
if (indentationRequest)
|
||||
indentationStack.Push ((object) indentationLevel);
|
||||
|
||||
// Remember
|
||||
indentationRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Cancel the last indentation </summary>
|
||||
public void UnIndent ()
|
||||
{
|
||||
if (Literal)
|
||||
throw new Exception ("Cannot (un)indent while literal parsing " +
|
||||
"has been enabled");
|
||||
else
|
||||
{
|
||||
// Cancel the indentation request
|
||||
if (indentationRequest)
|
||||
{
|
||||
indentationRequest = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Unpop the last indentation
|
||||
if (indentationStack.Count > 0)
|
||||
indentationLevel = (int) indentationStack.Pop ();
|
||||
|
||||
// When not indented
|
||||
else
|
||||
throw new Exception ("Unable to unindent a not indented parse stream");
|
||||
|
||||
// Parent stream not yet finished
|
||||
// Skipped whitespaces in the childstream (at that time assumed to be
|
||||
// indentation) can become content.
|
||||
if (endofstream && indentationLevel <= whitespaces)
|
||||
{
|
||||
endofstream = false;
|
||||
if (whitespaces == this.indentationLevel)
|
||||
whitespaces = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Go to the next parsable char in the stream </summary>
|
||||
public new void Next ()
|
||||
{
|
||||
if (endofstream)
|
||||
return;
|
||||
|
||||
// Are there still whitespaces to skip
|
||||
if (whitespaces > 0)
|
||||
{
|
||||
// All whitespaces were skipped
|
||||
if (whitespaces == whitespacesSkipped + this.indentationLevel)
|
||||
whitespaces = 0;
|
||||
|
||||
// Else, skip one
|
||||
else
|
||||
{
|
||||
whitespacesSkipped ++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// All whitespaces have been skipped
|
||||
if (whitespaces == 0 && ! base.EOF)
|
||||
{
|
||||
// When a char is positioned at a newline '\n',
|
||||
// then skip 'indentation' chars and continue.
|
||||
// When there are less spaces available, then we are
|
||||
// at the end of the (sub)stream
|
||||
if (! base.EOF && base.Char == '\n' && ! Literal)
|
||||
{
|
||||
// Skip over newline
|
||||
base.Next ();
|
||||
|
||||
// Skip indentation (and count the spaces)
|
||||
int i = 0;
|
||||
while (! base.EOF && base.Char == ' ' && i < this.indentationLevel)
|
||||
{
|
||||
i ++;
|
||||
base.Next ();
|
||||
}
|
||||
|
||||
// Not enough indented?
|
||||
if (i < this.indentationLevel)
|
||||
{
|
||||
// Remember the number of whitespaces, and
|
||||
// continue at the moment that the indentationlevel
|
||||
// drops below this number of whitespaces
|
||||
whitespaces = i;
|
||||
whitespacesSkipped = 0;
|
||||
endofstream = true;
|
||||
return;
|
||||
}
|
||||
// Indentation request
|
||||
else if (indentationRequest)
|
||||
{
|
||||
while (! base.EOF && base.Char == ' ')
|
||||
{
|
||||
i ++;
|
||||
base.Next ();
|
||||
}
|
||||
|
||||
// Remember current indentation
|
||||
indentationStack.Push ((object) indentationLevel);
|
||||
indentationRequest = false;
|
||||
|
||||
// Number of spaces before this line is equal to the
|
||||
// current level of indentation, so the
|
||||
// indentation request cannot be fulfilled
|
||||
if (indentationLevel == i)
|
||||
{
|
||||
whitespaces = i;
|
||||
whitespacesSkipped = 0;
|
||||
endofstream = true;
|
||||
return;
|
||||
}
|
||||
else // i > indentationLevel
|
||||
indentationLevel = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
// Next char
|
||||
base.Next ();
|
||||
}
|
||||
else
|
||||
endofstream = true;
|
||||
}
|
||||
|
||||
/// <summary> Reads the current char from the stream </summary>
|
||||
public new char Char
|
||||
{
|
||||
get
|
||||
{
|
||||
// In case of spaces
|
||||
if (whitespaces > 0)
|
||||
return ' ';
|
||||
|
||||
// \0 at the end of the stream
|
||||
else if (base.EOF || endofstream)
|
||||
return '\0';
|
||||
|
||||
// Return the char
|
||||
else
|
||||
return base.Char;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> End of File/Stream </summary>
|
||||
public new bool EOF
|
||||
{
|
||||
get { return endofstream || base.EOF; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Third stream processor, this class adds a buffer with a maximum
|
||||
/// size of 1024 chars. The buffer cannot encapsulate multiple lines
|
||||
/// because that could do strange things while rewinding/indenting
|
||||
/// </summary>
|
||||
|
||||
public class BufferStream : IndentationProcessor
|
||||
{
|
||||
LookaheadBuffer buffer = new LookaheadBuffer ();
|
||||
|
||||
// When the buffer is used, this is true
|
||||
private bool useLookaheadBuffer = false;
|
||||
|
||||
// In use, but requested to destroy. The buffer will keep to exists
|
||||
// (only in this layer) and shall be destroyed when we move out of
|
||||
// the buffer
|
||||
private bool destroyRequest = false;
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
public BufferStream (TextReader stream) : base (stream) { }
|
||||
|
||||
/// <summary> Build lookahead buffer </summary>
|
||||
public void BuildLookaheadBuffer ()
|
||||
{
|
||||
if (Literal)
|
||||
throw new Exception ("Cannot build a buffer while " +
|
||||
"literal parsing is enabled");
|
||||
else
|
||||
{
|
||||
// When the buffer is already in use
|
||||
if (useLookaheadBuffer && ! destroyRequest)
|
||||
throw new Exception ("Buffer already exist, cannot rebuild " +
|
||||
"the buffer at this level");
|
||||
|
||||
// Cancel the destroy request
|
||||
if (destroyRequest)
|
||||
destroyRequest = false;
|
||||
|
||||
// Or start a new buffer
|
||||
else
|
||||
{
|
||||
buffer.Clear ();
|
||||
buffer.Append (Char);
|
||||
}
|
||||
|
||||
useLookaheadBuffer = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Move to the next character in the parse stream. </summary>
|
||||
public new void Next ()
|
||||
{
|
||||
// End of file (This check is not really necessary because base.next
|
||||
// would skip this anyway)
|
||||
if (EOF) return;
|
||||
|
||||
// When it's not allowed to leave the buffer
|
||||
if (useLookaheadBuffer && ! destroyRequest && ! NextInBuffer () )
|
||||
return;
|
||||
|
||||
// When using the lookahead buffer
|
||||
if (useLookaheadBuffer)
|
||||
{
|
||||
// Requested to destroy
|
||||
if (destroyRequest)
|
||||
{
|
||||
// But not yet reached the end of the buffer
|
||||
if (buffer.Position < buffer.LastPosition)
|
||||
{
|
||||
buffer.Position ++;
|
||||
buffer.ForgetThePast ();
|
||||
}
|
||||
// Reached the end
|
||||
else
|
||||
{
|
||||
buffer.Clear ();
|
||||
useLookaheadBuffer = false;
|
||||
destroyRequest = false;
|
||||
|
||||
base.Next ();
|
||||
}
|
||||
}
|
||||
// Continue in the buffer
|
||||
else
|
||||
{
|
||||
// We've been here before
|
||||
if (buffer.Position < buffer.LastPosition)
|
||||
buffer.Position ++;
|
||||
|
||||
// This is new to the buffer, but there is place
|
||||
// to remember new chars
|
||||
else if (
|
||||
buffer.Position == buffer.LastPosition &&
|
||||
! buffer.Full)
|
||||
{
|
||||
// Save the next char in the buffer
|
||||
base.Next();
|
||||
buffer.Append (base.Char);
|
||||
}
|
||||
// Otherwise, the buffer is full
|
||||
else
|
||||
throw new Exception ("buffer overflow");
|
||||
}
|
||||
}
|
||||
// Not using the buffer
|
||||
else
|
||||
base.Next();
|
||||
}
|
||||
|
||||
/// <summary> Returns true when using a buffer </summary>
|
||||
public bool UsingBuffer ()
|
||||
{
|
||||
return useLookaheadBuffer && ! destroyRequest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true when the next char will still be in the buffer
|
||||
/// (after calling next)
|
||||
/// </summary>
|
||||
private bool NextInBuffer ()
|
||||
{
|
||||
return
|
||||
// Using the buffer
|
||||
useLookaheadBuffer &&
|
||||
|
||||
// Next char has been read before
|
||||
(buffer.Position < buffer.LastPosition ||
|
||||
|
||||
// Or the next char will also be in the buffer
|
||||
(Char != '\n' && ! base.EOF &&
|
||||
|
||||
// There is still unused space
|
||||
! buffer.Full));
|
||||
}
|
||||
|
||||
/// <summary> Destroys the current lookaheadbuffer, if there is one </summary>
|
||||
public void DestroyLookaheadBuffer ()
|
||||
{
|
||||
if (useLookaheadBuffer && ! destroyRequest)
|
||||
{
|
||||
buffer.ForgetThePast ();
|
||||
destroyRequest = true;
|
||||
}
|
||||
else
|
||||
throw new Exception ("Called destroy buffer before building the buffer");
|
||||
}
|
||||
|
||||
/// <summary> Rewind the buffer </summary>
|
||||
public void RewindLookaheadBuffer ()
|
||||
{
|
||||
if (! useLookaheadBuffer || destroyRequest)
|
||||
throw new Exception ("Cannot rewind the buffer. No buffer in use");
|
||||
|
||||
else
|
||||
buffer.Rewind ();
|
||||
}
|
||||
|
||||
/// <summary> The current character </summary>
|
||||
public new char Char
|
||||
{
|
||||
get
|
||||
{
|
||||
// When using a buffer
|
||||
if (useLookaheadBuffer)
|
||||
return buffer.Char;
|
||||
|
||||
else
|
||||
return base.Char;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> End of stream/file </summary>
|
||||
public new bool EOF
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
// When it's not allowed to run out of the buffer
|
||||
(useLookaheadBuffer && ! destroyRequest && ! NextInBuffer () ) ||
|
||||
|
||||
// Not using the buffer, but the end of stream has been reached
|
||||
(! useLookaheadBuffer && base.EOF);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Current position in the lookahead buffer </summary>
|
||||
protected int LookaheadPosition
|
||||
{
|
||||
get
|
||||
{
|
||||
if (useLookaheadBuffer)
|
||||
return buffer.Position;
|
||||
|
||||
else
|
||||
throw new Exception ("Not using a lookahead buffer");
|
||||
}
|
||||
set
|
||||
{
|
||||
if (useLookaheadBuffer)
|
||||
{
|
||||
if (value >= 0 && value <= buffer.LastPosition)
|
||||
buffer.Position = value;
|
||||
|
||||
else
|
||||
throw new Exception ("Lookahead position not between 0 " +
|
||||
"and the buffer size");
|
||||
}
|
||||
else
|
||||
throw new Exception ("Not using a lookahead buffer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Parsestream with multilever buffer </summary>
|
||||
public class MultiBufferStream : BufferStream
|
||||
{
|
||||
private Stack bufferStack = new Stack (); // Top is current buffer start
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
public MultiBufferStream (TextReader stream) : base (stream) { }
|
||||
|
||||
/// <summary> Destroy the current buffer </summary>
|
||||
public new void BuildLookaheadBuffer ()
|
||||
{
|
||||
if (Literal)
|
||||
throw new Exception ("Cannot build a buffer while " +
|
||||
"literal parsing is enabled");
|
||||
else
|
||||
{
|
||||
// Already using a buffer
|
||||
if (base.UsingBuffer ())
|
||||
// Remember the current position
|
||||
bufferStack.Push ((object) base.LookaheadPosition);
|
||||
|
||||
// Otherwise, create a new buffer
|
||||
else
|
||||
{
|
||||
// Remember the current position (= 0)
|
||||
bufferStack .Push ((object) 0);
|
||||
|
||||
base.BuildLookaheadBuffer ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Destroy the current buffer </summary>
|
||||
public new void DestroyLookaheadBuffer ()
|
||||
{
|
||||
// Clear the buffer info when we runned out of the buffer,
|
||||
if ( ! base.UsingBuffer () )
|
||||
bufferStack.Clear ();
|
||||
|
||||
else
|
||||
{
|
||||
// Unpop the buffers start index
|
||||
bufferStack.Pop ();
|
||||
|
||||
// Destroy it when the last buffer is gone
|
||||
if (bufferStack.Count == 0)
|
||||
base.DestroyLookaheadBuffer ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Rewind the current buffer </summary>
|
||||
public new void RewindLookaheadBuffer ()
|
||||
{
|
||||
if (base.UsingBuffer () )
|
||||
base.LookaheadPosition = (int) bufferStack.Peek ();
|
||||
else
|
||||
throw new Exception ("Rewinding not possible. Not using a " +
|
||||
"lookahead buffer.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drop the comments
|
||||
/// (This is disabled when literal parsing is enabled)
|
||||
/// </summary>
|
||||
public class DropComments : MultiBufferStream
|
||||
{
|
||||
/// <summary> Constructor </summary>
|
||||
public DropComments (TextReader stream) : base (stream) { }
|
||||
|
||||
/// <summary> Move to the next character in the parse stream. </summary>
|
||||
public new void Next ()
|
||||
{
|
||||
base.Next ();
|
||||
|
||||
// Skip comments
|
||||
if (base.Char == '#' && ! Literal)
|
||||
while (! base.EOF && base.Char != '\n')
|
||||
base.Next ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This layer removes the trailing newline at the end of each (sub)stream
|
||||
/// </summary>
|
||||
public class DropTrailingNewline : DropComments
|
||||
{
|
||||
// One char buffer
|
||||
private bool newline = false;
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
public DropTrailingNewline (TextReader stream) : base (stream) { }
|
||||
|
||||
/// <summary> The current character </summary>
|
||||
public new char Char
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EOF)
|
||||
return '\0';
|
||||
else if (newline)
|
||||
return '\n';
|
||||
else
|
||||
return base.Char;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> End of File/Stream </summary>
|
||||
public new bool EOF
|
||||
{
|
||||
get { return ! newline && base.EOF; }
|
||||
}
|
||||
|
||||
/// <summary> Skip space characters </summary>
|
||||
public int SkipSpaces ()
|
||||
{
|
||||
int count = 0;
|
||||
while (Char == ' ')
|
||||
{
|
||||
Next ();
|
||||
count ++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary> Move to the next character in the parse stream. </summary>
|
||||
public new void Next ()
|
||||
{
|
||||
Next (false);
|
||||
}
|
||||
|
||||
/// <summary> Move to the next character in the parse stream. </summary>
|
||||
/// <param name="dropLastNewLine"> Forget the last newline </param>
|
||||
public void Next (bool dropLastNewLine)
|
||||
{
|
||||
if (newline)
|
||||
newline = false;
|
||||
else
|
||||
{
|
||||
base.Next ();
|
||||
|
||||
if (dropLastNewLine && ! base.EOF && Char == '\n')
|
||||
{
|
||||
base.Next ();
|
||||
|
||||
if (base.EOF)
|
||||
newline = false;
|
||||
else
|
||||
newline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Stops parsing at specific characters, useful for parsing inline
|
||||
/// structures like (for instance):
|
||||
///
|
||||
/// [aaa, bbb, ccc, {ddd: eee, "fff": ggg}]
|
||||
/// </summary>
|
||||
public class ParseStream : DropTrailingNewline
|
||||
{
|
||||
private Stack stopstack = new Stack ();
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
public ParseStream (TextReader stream) : base (stream) { }
|
||||
|
||||
/// <summary> Set the characters where we should stop. </summary>
|
||||
public void StopAt (char [] characters)
|
||||
{
|
||||
stopstack.Push (characters);
|
||||
}
|
||||
|
||||
/// <summary> Unset the characters where we should stop. </summary>
|
||||
public void DontStop ()
|
||||
{
|
||||
if (stopstack.Count > 0)
|
||||
stopstack.Pop ();
|
||||
else
|
||||
throw new Exception ("Called DontStop without " +
|
||||
"calling StopAt before");
|
||||
}
|
||||
|
||||
/// <summary> True when we have to stop here </summary>
|
||||
private bool StopNow
|
||||
{
|
||||
get {
|
||||
if (stopstack.Count > 0)
|
||||
foreach (char c in (char []) stopstack.Peek ())
|
||||
if (c == base.Char)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Start parsing literal </summary>
|
||||
public new void StartLiteral ()
|
||||
{
|
||||
base.StartLiteral ();
|
||||
|
||||
// Parsing literal disables stopping
|
||||
StopAt (new Char [] { });
|
||||
}
|
||||
|
||||
/// <summary> Stop parsing literal </summary>
|
||||
public new void StopLiteral ()
|
||||
{
|
||||
base.StopLiteral ();
|
||||
|
||||
DontStop ();
|
||||
}
|
||||
/// <summary> Move to the next character in the parse stream. </summary>
|
||||
public new void Next ()
|
||||
{
|
||||
Next (false);
|
||||
}
|
||||
|
||||
/// <summary> Move to the next character in the parse stream. </summary>
|
||||
public new void Next (bool dropLastNewLine)
|
||||
{
|
||||
if ( ! StopNow )
|
||||
base.Next (dropLastNewLine);
|
||||
}
|
||||
|
||||
/// <summary> The current character </summary>
|
||||
public new char Char
|
||||
{
|
||||
get
|
||||
{
|
||||
if (StopNow)
|
||||
return '\0';
|
||||
|
||||
else
|
||||
return base.Char;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> End of stream/file </summary>
|
||||
public new bool EOF
|
||||
{
|
||||
get { return StopNow || base.EOF; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The lookahead buffer, used by the buffer layer in the parser
|
||||
/// </summary>
|
||||
class LookaheadBuffer
|
||||
{
|
||||
// The buffer array
|
||||
private char [] buffer = new char [1024];
|
||||
|
||||
private int size = 0; // 0 = Nothing in the buffer
|
||||
private int position = -1; // Current position
|
||||
private int rotation = 0; // Start of circular buffer
|
||||
|
||||
/// <summary> Character at the current position </summary>
|
||||
public char Char
|
||||
{
|
||||
get
|
||||
{
|
||||
if (size > 0)
|
||||
return buffer [(position + rotation) % buffer.Length];
|
||||
|
||||
else
|
||||
throw new Exception ("Trying to read from an emty buffer");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> The current position </summary>
|
||||
public int Position
|
||||
{
|
||||
get { return position; }
|
||||
|
||||
set
|
||||
{
|
||||
if (value >= 0 && value < size)
|
||||
position = value;
|
||||
else
|
||||
throw new Exception ("Buffer position should be " +
|
||||
"between zero and 'size' ");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> The last possible postition which could be set </summary>
|
||||
public int LastPosition
|
||||
{
|
||||
get { return size - 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The last possible position which could be set if
|
||||
/// the buffer where full
|
||||
/// </summary>
|
||||
public int MaxPosition
|
||||
{
|
||||
get { return buffer.Length - 1; }
|
||||
}
|
||||
|
||||
/// <summary> True when the buffer is full </summary>
|
||||
public bool Full
|
||||
{
|
||||
get { return size == buffer.Length; }
|
||||
}
|
||||
|
||||
/// <summary> Current buffer size </summary>
|
||||
public int Size
|
||||
{
|
||||
get { return size; }
|
||||
}
|
||||
|
||||
/// <summary> Append a character to the buffer </summary>
|
||||
public void Append (char c)
|
||||
{
|
||||
// Appending is only possible when the current position is the
|
||||
// last in the buffer
|
||||
if (position < LastPosition)
|
||||
throw new Exception ("Appending to buffer only possible " +
|
||||
"when the position is the last");
|
||||
|
||||
// Buffer overflow
|
||||
if (size == buffer.Length)
|
||||
throw new Exception ("Buffer full");
|
||||
|
||||
// Append
|
||||
position ++;
|
||||
size ++;
|
||||
buffer [(position + rotation) % buffer.Length] = c;
|
||||
}
|
||||
|
||||
/// <summary> Rewind the buffer </summary>
|
||||
public void Rewind ()
|
||||
{
|
||||
position = 0;
|
||||
}
|
||||
|
||||
/// <summary> Reset (clear) the buffer </summary>
|
||||
public void Clear ()
|
||||
{
|
||||
position = -1;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
/// <summary> Move to the next character </summary>
|
||||
public void Next ()
|
||||
{
|
||||
if (Position < Size)
|
||||
Position ++;
|
||||
|
||||
else throw new Exception ("Cannot move past the buffer");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove characters from the buffer before the current character
|
||||
/// </summary>
|
||||
public void ForgetThePast ()
|
||||
{
|
||||
// Size becomes smaller, characters before the position should be dropped
|
||||
size -= position;
|
||||
|
||||
// The current position becomes the new startposition
|
||||
rotation = (rotation + position + buffer.Length) % buffer.Length;
|
||||
|
||||
// The current position in the new buffer becomes zero
|
||||
position = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
137
thirdparty/yaml/Scalar.cs
vendored
Normal file
137
thirdparty/yaml/Scalar.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
#define SUPPORT_NULL_NODES
|
||||
#define SUPPORT_INTEGER_NODES
|
||||
#define SUPPORT_FLOAT_NODES
|
||||
#define SUPPORT_BOOLEAN_NODES
|
||||
#define SUPPORT_TIMESTAMP_NODES
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// All Yaml scalars are derived from this class
|
||||
/// </summary>
|
||||
public abstract class Scalar : Node
|
||||
{
|
||||
/// <summary> Constructor </summary>
|
||||
public Scalar (string uri, NodeType nodetype) : base (uri, nodetype) { }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parses a scalar
|
||||
/// <list type="bullet">
|
||||
/// <item>Integer</item>
|
||||
/// <item>String</item>
|
||||
/// <item>Boolean</item>
|
||||
/// <item>Null</item>
|
||||
/// <item>Timestamp</item>
|
||||
/// <item>Float</item>
|
||||
/// <item>Binary</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Binary is only parsed behind an explicit !!binary tag (in Node.cs)
|
||||
/// </remarks>
|
||||
public static new Scalar Parse (ParseStream stream)
|
||||
{
|
||||
// -----------------
|
||||
// Parse scalars
|
||||
// -----------------
|
||||
|
||||
stream.BuildLookaheadBuffer ();
|
||||
|
||||
// Try Null
|
||||
#if SUPPORT_NULL_NODES
|
||||
try
|
||||
{
|
||||
Scalar s = new Null (stream);
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
return s;
|
||||
} catch { }
|
||||
#endif
|
||||
// Try boolean
|
||||
#if SUPPORT_BOOLEAN_NODES
|
||||
stream.RewindLookaheadBuffer ();
|
||||
try
|
||||
{
|
||||
Scalar scalar = new Boolean (stream);
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
return scalar;
|
||||
}
|
||||
catch { }
|
||||
#endif
|
||||
// Try integer
|
||||
#if SUPPORT_INTEGER_NODES
|
||||
stream.RewindLookaheadBuffer ();
|
||||
try
|
||||
{
|
||||
Scalar scalar = new Integer (stream);
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
return scalar;
|
||||
} catch { }
|
||||
#endif
|
||||
// Try Float
|
||||
#if SUPPORT_FLOAT_NODES
|
||||
stream.RewindLookaheadBuffer ();
|
||||
try
|
||||
{
|
||||
Scalar scalar = new Float (stream);
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
return scalar;
|
||||
}
|
||||
catch { }
|
||||
#endif
|
||||
// Try timestamp
|
||||
#if SUPPORT_TIMESTAMP_NODES
|
||||
stream.RewindLookaheadBuffer ();
|
||||
try {
|
||||
Scalar scalar = new Timestamp (stream);
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
return scalar;
|
||||
} catch { }
|
||||
#endif
|
||||
// Other scalars are strings
|
||||
stream.RewindLookaheadBuffer ();
|
||||
stream.DestroyLookaheadBuffer ();
|
||||
|
||||
return new String (stream);
|
||||
}
|
||||
|
||||
/// <summary> Node info </summary>
|
||||
// TODO, move to each induvidual child
|
||||
public override Node Info ()
|
||||
{
|
||||
Mapping mapping = new Mapping ();
|
||||
mapping.AddMappingNode (new String ("kind"), new String ("scalar"));
|
||||
mapping.AddMappingNode (new String ("type_id"), new String (URI));
|
||||
mapping.AddMappingNode (new String ("value"), this);
|
||||
return mapping;
|
||||
}
|
||||
}
|
||||
}
|
||||
197
thirdparty/yaml/Sequence.cs
vendored
Normal file
197
thirdparty/yaml/Sequence.cs
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Yaml Sequence
|
||||
/// </summary>
|
||||
public class Sequence : Node
|
||||
{
|
||||
private ArrayList childNodes = new ArrayList ();
|
||||
|
||||
/// <summary> New, empty sequence </summary>
|
||||
public Sequence ( ) : base ("tag:yaml.org,2002:seq", NodeType.Sequence) { }
|
||||
|
||||
/// <summary> New sequence from a node array </summary>
|
||||
public Sequence (Node [] nodes) :
|
||||
base ("tag:yaml.org,2002:seq", NodeType.Sequence)
|
||||
{
|
||||
foreach (Node node in nodes)
|
||||
childNodes.Add (node);
|
||||
}
|
||||
|
||||
/// <summary> Parse a sequence </summary>
|
||||
public Sequence (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:seq", NodeType.Sequence)
|
||||
{
|
||||
// Is this really a sequence?
|
||||
if (stream.Char == '-')
|
||||
{
|
||||
// Parse recursively
|
||||
do {
|
||||
// Override the parent's stop chars, never stop
|
||||
stream.StopAt (new char [] { } );
|
||||
|
||||
// Skip over '-'
|
||||
stream.Next ();
|
||||
|
||||
// Parse recursively
|
||||
stream.Indent ();
|
||||
AddNode (Parse (stream));
|
||||
stream.UnIndent ();
|
||||
|
||||
// Re-accept the parent's stop chars
|
||||
stream.DontStop ();
|
||||
}
|
||||
while ( ! stream.EOF && stream.Char == '-' );
|
||||
}
|
||||
// Or inline Sequence
|
||||
else if (stream.Char == '[')
|
||||
{
|
||||
// Override the parent's stop chars, never stop
|
||||
stream.StopAt (new char [] { });
|
||||
|
||||
// Skip '['
|
||||
stream.Next ();
|
||||
|
||||
do {
|
||||
stream.StopAt (new char [] {']', ','});
|
||||
stream.Indent ();
|
||||
AddNode (Parse (stream, false));
|
||||
stream.UnIndent ();
|
||||
stream.DontStop ();
|
||||
|
||||
// Skip ','
|
||||
if (stream.Char != ']' && stream.Char != ',')
|
||||
{
|
||||
stream.DontStop ();
|
||||
throw new ParseException (stream, "Comma expected in inline sequence");
|
||||
}
|
||||
|
||||
if (stream.Char == ',')
|
||||
{
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
}
|
||||
}
|
||||
while ( ! stream.EOF && stream.Char != ']');
|
||||
|
||||
// Re-accept the parent's stop chars
|
||||
stream.DontStop ();
|
||||
|
||||
// Skip ']'
|
||||
if (stream.Char == ']')
|
||||
stream.Next (true);
|
||||
else
|
||||
throw new ParseException (stream, "Inline sequence not closed");
|
||||
|
||||
}
|
||||
// Throw an exception when not
|
||||
else
|
||||
throw new Exception ("This is not a sequence");
|
||||
}
|
||||
|
||||
/// <summary> Add a node to this sequence </summary>
|
||||
public void AddNode (Node node)
|
||||
{
|
||||
if (node != null)
|
||||
childNodes.Add (node);
|
||||
else
|
||||
childNodes.Add (new Null ());
|
||||
}
|
||||
|
||||
/// <summary> Get a node </summary>
|
||||
public Node this [int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index > 0 && index < childNodes.Count)
|
||||
return (Node) childNodes [index];
|
||||
|
||||
else
|
||||
throw new IndexOutOfRangeException ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> The node array </summary>
|
||||
public Node [] Nodes
|
||||
{
|
||||
get
|
||||
{
|
||||
Node [] nodes = new Node [childNodes.Count];
|
||||
|
||||
for (int i = 0; i < childNodes.Count; i ++)
|
||||
nodes [i] = (Node) childNodes [i];
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Textual destription of this node </summary>
|
||||
public override string ToString ()
|
||||
{
|
||||
string result = "";
|
||||
foreach (Node node in childNodes)
|
||||
result += node.ToString ();
|
||||
|
||||
return "[SEQUENCE]" + result + "[/SEQUENCE]";
|
||||
}
|
||||
|
||||
/// <summary> Node info </summary>
|
||||
public override Node Info ()
|
||||
{
|
||||
Mapping mapping = new Mapping ();
|
||||
mapping.AddMappingNode (new String ("kind"), new String ("sequence"));
|
||||
mapping.AddMappingNode (new String ("type_id"), new String (URI));
|
||||
|
||||
Sequence childs = new Sequence ();
|
||||
|
||||
foreach (Node child in childNodes)
|
||||
childs.AddNode (child.Info ());
|
||||
|
||||
mapping.AddMappingNode (new String ("value"), childs);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/// <summary> Write back to a stream </summary>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
foreach (Node node in childNodes)
|
||||
{
|
||||
stream.Append ("- ");
|
||||
|
||||
stream.Indent ();
|
||||
node.Write (stream);
|
||||
stream.UnIndent ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
449
thirdparty/yaml/String.cs
vendored
Normal file
449
thirdparty/yaml/String.cs
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
// Unicode support:
|
||||
// http://www.yoda.arachsys.com/csharp/unicode.html
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Yaml String node
|
||||
/// </summary>
|
||||
public class String : Scalar
|
||||
{
|
||||
private string content;
|
||||
private bool block = false;
|
||||
private bool folded = false;
|
||||
|
||||
/// <summary> New string constructor </summary>
|
||||
public String (string val) :
|
||||
base ("tag:yaml.org,2002:str", NodeType.String)
|
||||
{
|
||||
content = val;
|
||||
}
|
||||
|
||||
/// <summary> Parse a string </summary>
|
||||
public String (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:str", NodeType.String)
|
||||
{
|
||||
// set flags for folded or block scalar
|
||||
if (stream.Char == '>') // TODO: '+' and '-' chomp chars
|
||||
folded = true;
|
||||
|
||||
else if (stream.Char == '|')
|
||||
block = true;
|
||||
|
||||
if (block || folded)
|
||||
{
|
||||
stream.Next ();
|
||||
stream.SkipSpaces ();
|
||||
}
|
||||
|
||||
// -----------------
|
||||
// Folded Scalar
|
||||
// -----------------
|
||||
if (folded)
|
||||
{
|
||||
System.Text.StringBuilder builder = new System.Text.StringBuilder ();
|
||||
|
||||
// First line (the \n after the first line is always ignored,
|
||||
// not replaced with a whitespace)
|
||||
while (! stream.EOF && stream.Char != '\n')
|
||||
{
|
||||
builder.Append (stream.Char);
|
||||
stream.Next ();
|
||||
}
|
||||
|
||||
// Skip the first newline
|
||||
stream.Next ();
|
||||
|
||||
// Next lines (newlines will be replaced by spaces in folded scalars)
|
||||
while (! stream.EOF)
|
||||
{
|
||||
if (stream.Char == '\n')
|
||||
builder.Append (' ');
|
||||
else
|
||||
builder.Append (stream.Char);
|
||||
|
||||
stream.Next (true);
|
||||
}
|
||||
content = builder.ToString ();
|
||||
}
|
||||
|
||||
// -----------------
|
||||
// Block Scalar (verbatim block without folding)
|
||||
// -----------------
|
||||
else if (block)
|
||||
{
|
||||
/*
|
||||
Console.Write(">>");
|
||||
while (! stream.EOF)
|
||||
{
|
||||
Console.Write (stream.Char);
|
||||
stream.Next();
|
||||
}
|
||||
Console.Write("<<");
|
||||
// */
|
||||
|
||||
System.Text.StringBuilder builder = new System.Text.StringBuilder ();
|
||||
while (! stream.EOF)
|
||||
{
|
||||
builder.Append (stream.Char);
|
||||
stream.Next (true);
|
||||
}
|
||||
content = builder.ToString ();
|
||||
}
|
||||
|
||||
// String between double quotes
|
||||
if (stream.Char == '\"')
|
||||
content = ParseDoubleQuoted (stream);
|
||||
|
||||
// Single quoted string
|
||||
else if (stream.Char == '\'')
|
||||
content = ParseSingleQuoted (stream);
|
||||
|
||||
// String without quotes
|
||||
else
|
||||
content = ParseUnQuoted (stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a String surrounded with single quotes
|
||||
/// </summary>
|
||||
private string ParseSingleQuoted (ParseStream stream)
|
||||
{
|
||||
System.Text.StringBuilder builder = new System.Text.StringBuilder ();
|
||||
|
||||
// Start literal parsing
|
||||
stream.StartLiteral ();
|
||||
|
||||
// Skip '''
|
||||
stream.Next (true);
|
||||
|
||||
while (! stream.EOF)
|
||||
{
|
||||
if (stream.Char == '\'')
|
||||
{
|
||||
stream.Next ();
|
||||
|
||||
// Escaped single quote
|
||||
if (stream.Char == '\'')
|
||||
builder.Append (stream.Char);
|
||||
|
||||
// End of string
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
builder.Append (stream.Char);
|
||||
|
||||
stream.Next ();
|
||||
|
||||
// Skip \'
|
||||
if (stream.EOF)
|
||||
{
|
||||
stream.StopLiteral ();
|
||||
throw new ParseException (stream,
|
||||
"Single quoted string not closed");
|
||||
}
|
||||
}
|
||||
|
||||
// Stop literal parsing
|
||||
stream.StopLiteral ();
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a String surrounded with double quotes
|
||||
/// </summary>
|
||||
private string ParseDoubleQuoted(ParseStream stream)
|
||||
{
|
||||
System.Text.StringBuilder builder = new System.Text.StringBuilder ();
|
||||
|
||||
// Skip '"'
|
||||
stream.Next ();
|
||||
|
||||
// Stop at "
|
||||
stream.StopAt (new char [] {'\"'} );
|
||||
|
||||
while (! stream.EOF)
|
||||
{
|
||||
if (stream.Char == '\n')
|
||||
{
|
||||
builder.Append (' ');
|
||||
stream.Next ();
|
||||
}
|
||||
else
|
||||
builder.Append (NextUnescapedChar (stream));
|
||||
}
|
||||
|
||||
// Don't stop at "
|
||||
stream.DontStop ();
|
||||
|
||||
// Skip '"'
|
||||
if (stream.Char != '\"')
|
||||
throw new ParseException (stream,
|
||||
"Double quoted string not closed");
|
||||
else
|
||||
stream.Next (true);
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a String surrounded without nothing
|
||||
/// </summary>
|
||||
private string ParseUnQuoted(ParseStream stream)
|
||||
{
|
||||
System.Text.StringBuilder builder = new System.Text.StringBuilder ();
|
||||
|
||||
while (! stream.EOF)
|
||||
builder.Append (NextUnescapedChar (stream));
|
||||
|
||||
// Trimming left
|
||||
int count = 0;
|
||||
while (count < builder.Length &&
|
||||
(builder [count] == ' ' || builder [count] == '\t'))
|
||||
count ++;
|
||||
|
||||
if (count >= 0)
|
||||
builder.Remove (0, count);
|
||||
|
||||
// Trimming right
|
||||
count = 0;
|
||||
while (count < builder.Length &&
|
||||
(builder [builder.Length - count - 1] == ' ' ||
|
||||
builder [builder.Length - count - 1] == '\t'))
|
||||
count ++;
|
||||
|
||||
if (count >= 0)
|
||||
builder.Remove (builder.Length - count, count);
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a character from the stream, unescapes it,
|
||||
/// and moves to the next character.
|
||||
/// </summary>
|
||||
private char NextUnescapedChar (ParseStream stream)
|
||||
{
|
||||
char c = stream.Char;
|
||||
|
||||
// If escaped
|
||||
if (c == '\\')
|
||||
{
|
||||
// Never stop, every special character
|
||||
// looses its meaning behind a backslash.
|
||||
stream.StopAt (new Char [] { });
|
||||
|
||||
stream.Next (true);
|
||||
c = stream.Char;
|
||||
|
||||
// ASCII null
|
||||
if (c == '0') c = '\0';
|
||||
|
||||
// ASCII bell
|
||||
else if (c == 'a') c = (char) 0x7;
|
||||
|
||||
// ASCII backspace
|
||||
else if (c == 'b') c = (char) 0x8;
|
||||
|
||||
// ASCII horizontal tab
|
||||
else if (c == 't') c = (char) 0x9;
|
||||
|
||||
// ASCII newline
|
||||
else if (c == 'n') c = (char) 0xA;
|
||||
|
||||
// ASCII vertical tab
|
||||
else if (c == 'v') c = (char) 0xB;
|
||||
|
||||
// ASCII form feed
|
||||
else if (c == 'f') c = (char) 0xC;
|
||||
|
||||
// ASCII carriage return
|
||||
else if (c == 'r') c = (char) 0xD;
|
||||
|
||||
// ASCII escape
|
||||
else if (c == 'e') c = (char) 0x1D;
|
||||
|
||||
// Unicode next line
|
||||
else if (c == 'N') c = (char) 0x85;
|
||||
|
||||
// Unicode non breaking space
|
||||
else if (c == '_') c = (char) 0xA0;
|
||||
|
||||
// TODO larger unicode characters
|
||||
|
||||
// Unicode line separator
|
||||
// else if (c == 'L') c = (char) 0x20282028;
|
||||
|
||||
// 8 bit hexadecimal
|
||||
else if (c == 'x')
|
||||
{
|
||||
int c_int = (char) 0;
|
||||
|
||||
for (int i = 0; i < 2; i ++)
|
||||
{
|
||||
c_int *= 16;
|
||||
|
||||
stream.Next ();
|
||||
char d = stream.Char;
|
||||
|
||||
if (d >= '0' && d <= '9')
|
||||
c_int += d - '0';
|
||||
|
||||
else if (d >= 'a' && d <= 'f')
|
||||
c_int += d - 'a';
|
||||
|
||||
else if (d >= 'A' && d <= 'F')
|
||||
c_int += d - 'A';
|
||||
else
|
||||
{
|
||||
stream.DontStop ();
|
||||
throw new ParseException (stream,
|
||||
"Invalid escape sequence");
|
||||
}
|
||||
}
|
||||
c = (char) c_int;
|
||||
}
|
||||
|
||||
stream.Next (true);
|
||||
|
||||
// Restore last stop settings
|
||||
stream.DontStop ();
|
||||
}
|
||||
else
|
||||
stream.Next (true);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/// <summary> Content property </summary>
|
||||
public string Content
|
||||
{
|
||||
get { return content; }
|
||||
set { content = value; }
|
||||
}
|
||||
|
||||
/// <summary> To String </summary>
|
||||
public override string ToString ()
|
||||
{
|
||||
return "[STRING]" + content + "[/STRING]";
|
||||
}
|
||||
|
||||
/// <summary> Write </summary>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
// TODO, not required, but writing to block or folded scalars
|
||||
// generates a little more neat code.
|
||||
|
||||
// Analyze string
|
||||
bool multiline = false;
|
||||
bool mustbequoted = false;
|
||||
|
||||
for (int i = 0; i < content.Length; i ++)
|
||||
{
|
||||
char c = content [i];
|
||||
|
||||
if (c == '\n')
|
||||
multiline = true;
|
||||
|
||||
// We quote everything except strings like /[a-zA-Z]*/
|
||||
// However there are more strings which don't require
|
||||
// quotes.
|
||||
if ( ! ( c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'))
|
||||
mustbequoted = true;
|
||||
}
|
||||
|
||||
// Double quoted strings
|
||||
if (mustbequoted)
|
||||
{
|
||||
stream.Append ("\"");
|
||||
|
||||
for (int i = 0; i < content.Length; i ++)
|
||||
{
|
||||
char c = content [i];
|
||||
|
||||
// Backslash
|
||||
if (c == '\\') stream.Append ("\\" + "\\");
|
||||
|
||||
// Double quote
|
||||
else if (c == '\"') stream.Append ("\\" + "\"");
|
||||
|
||||
// Single quote
|
||||
else if (c == '\'') stream.Append ("\\" + "\'");
|
||||
|
||||
// ASCII null
|
||||
else if (c == '\0') stream.Append ("\\0");
|
||||
|
||||
// ASCII bell
|
||||
else if (c == (char) 0x7) stream.Append ("\\a");
|
||||
|
||||
// ASCII backspace
|
||||
else if (c == (char) 0x8) stream.Append ("\\b");
|
||||
|
||||
// ASCII horizontal tab
|
||||
else if (c == (char) 0x9) stream.Append ("\\t");
|
||||
|
||||
// ASCII newline
|
||||
else if (c == (char) 0xA) stream.Append ("\\n");
|
||||
|
||||
// ASCII vertical tab
|
||||
else if (c == (char) 0xB) stream.Append ("\\v");
|
||||
|
||||
// ASCII form feed
|
||||
else if (c == (char) 0xC) stream.Append ("\\f");
|
||||
|
||||
// ASCII carriage return
|
||||
else if (c == (char) 0xD) stream.Append ("\\r");
|
||||
|
||||
// ASCII escape
|
||||
else if (c == (char) 0x1D) stream.Append ("\\e");
|
||||
|
||||
// Unicode next line
|
||||
else if (c == (char) 0x85) stream.Append ("\\N");
|
||||
|
||||
// Unicode non breaking space
|
||||
else if (c == (char) 0xA0) stream.Append ("\\_");
|
||||
|
||||
// TODO larger unicode characters
|
||||
|
||||
else
|
||||
stream.Append ("" + c);
|
||||
}
|
||||
stream.Append ("\"");
|
||||
}
|
||||
|
||||
// Simple non-quoted strings
|
||||
else
|
||||
stream.Append (content);
|
||||
}
|
||||
}
|
||||
}
|
||||
356
thirdparty/yaml/Timestamp.cs
vendored
Normal file
356
thirdparty/yaml/Timestamp.cs
vendored
Normal file
@@ -0,0 +1,356 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Yaml Timestamp node
|
||||
/// uri: tag:yaml.org,2002:timestamp
|
||||
/// </summary>
|
||||
public class Timestamp : Scalar
|
||||
{
|
||||
private System.DateTime content;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the offset from the UTC time in hours
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We use this extra variable for compatibility with Mono
|
||||
/// and .NET 1.0. .NET 2.0 has an extra property for
|
||||
/// System.Datetime for the timezone.
|
||||
/// </remarks>
|
||||
private double timezone = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Basic constructor that takes a given datetime
|
||||
/// </summary>
|
||||
/// <param name="datetime">A .NET 1.0 datetime</param>
|
||||
public Timestamp (DateTime datetime) :
|
||||
base ("tag:yaml.org,2002:timestamp", NodeType.Timestamp)
|
||||
{
|
||||
this.content = datetime;
|
||||
this.timezone = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Basic constructor, that also gives the posibility to set a timezone
|
||||
/// </summary>
|
||||
/// <param name="datetime">A .NET 1.0 datetime</param>
|
||||
/// <param name="timezone">The offset, in hours,r to UTC that determine the timezone </param>
|
||||
public Timestamp (DateTime datetime, double timezone) :
|
||||
base ("tag:yaml.org,2002:timestamp", NodeType.Timestamp)
|
||||
{
|
||||
this.content = datetime;
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
/// <summary> Content property </summary>
|
||||
public System.DateTime Content
|
||||
{
|
||||
get { return content; }
|
||||
set { content = value; }
|
||||
}
|
||||
|
||||
/// <summary> Timezone, an offset in hours </summary>
|
||||
public double Timezone
|
||||
{
|
||||
get { return timezone; }
|
||||
set { timezone = value; }
|
||||
}
|
||||
|
||||
/// <summary> To String </summary>
|
||||
public override string ToString ()
|
||||
{
|
||||
return "[TIMESTAMP]" + YamlString () + "[/TIMESTAMP]";
|
||||
}
|
||||
|
||||
/// <summary> Parse a DateTime </summary>
|
||||
public Timestamp (ParseStream stream) :
|
||||
base ("tag:yaml.org,2002:timestamp", NodeType.Timestamp)
|
||||
{
|
||||
int year = 0;
|
||||
int month = 0;
|
||||
int day = 0;
|
||||
int hour = 0;
|
||||
int minutes = 0;
|
||||
int seconds = 0;
|
||||
int ms = 0;
|
||||
|
||||
try
|
||||
{
|
||||
// Parse year
|
||||
year = ParseNumber (stream, 4);
|
||||
SkipChar (stream, '-');
|
||||
|
||||
// Parse month
|
||||
month = ParseNumber (stream, 2);
|
||||
SkipChar (stream, '-');
|
||||
|
||||
// Parse day
|
||||
day = ParseNumber (stream, 2);
|
||||
|
||||
// Additional, the time
|
||||
if ( ! stream.EOF)
|
||||
ParseTime (stream, out hour, out minutes, out seconds);
|
||||
|
||||
// Additional, milliseconds
|
||||
if ( ! stream.EOF)
|
||||
ms = ParseMilliSeconds (stream);
|
||||
|
||||
// Additional, the timezone
|
||||
if ( ! stream.EOF)
|
||||
timezone = ParseTimezone (stream);
|
||||
|
||||
// If there is more, then a format exception
|
||||
if ( ! stream.EOF)
|
||||
throw new Exception ("More data then excepted");
|
||||
|
||||
content = new DateTime (year, month, day, hour, minutes, seconds, ms);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ParseException (stream, ex.ToString ());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the time (hours, minutes, seconds)
|
||||
/// </summary>
|
||||
private void ParseTime (ParseStream stream,
|
||||
out int hour, out int minutes, out int seconds)
|
||||
{
|
||||
if (stream.Char == 't' || stream.Char == 'T')
|
||||
stream.Next (true);
|
||||
else
|
||||
SkipWhitespace (stream);
|
||||
|
||||
// Parse hour
|
||||
// Note: A hour can be represented by one or two digits.
|
||||
string hulp = "";
|
||||
while (stream.Char >= '0' && stream.Char <= '9' &&
|
||||
! stream.EOF && hulp.Length <= 2)
|
||||
{
|
||||
hulp += stream.Char;
|
||||
stream.Next (true);
|
||||
}
|
||||
hour = Int32.Parse (hulp);
|
||||
|
||||
SkipChar (stream, ':');
|
||||
|
||||
// Parse minutes
|
||||
minutes = ParseNumber (stream, 2);
|
||||
SkipChar (stream, ':');
|
||||
|
||||
// Parse seconds
|
||||
seconds = ParseNumber (stream, 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the milliseconds
|
||||
/// </summary>
|
||||
private int ParseMilliSeconds (ParseStream stream)
|
||||
{
|
||||
int ms = 0;
|
||||
|
||||
// Look for fraction
|
||||
if (stream.Char == '.')
|
||||
{
|
||||
stream.Next (true);
|
||||
|
||||
// Parse fraction, can consists of an
|
||||
// unlimited sequence of numbers, we only
|
||||
// look to the first three (max 1000)
|
||||
int count = 0;
|
||||
|
||||
while (stream.Char >= '0' && stream.Char <= '9' &&
|
||||
count < 3 && ! stream.EOF)
|
||||
{
|
||||
ms *= 10;
|
||||
ms += stream.Char - '0';
|
||||
|
||||
stream.Next (true);
|
||||
count ++;
|
||||
}
|
||||
|
||||
if (count == 1) ms *= 100;
|
||||
if (count == 2) ms *= 10;
|
||||
if (count == 3) ms *= 1;
|
||||
|
||||
// Ignore the rest
|
||||
while (stream.Char >= '0' && stream.Char <= '9' &&
|
||||
! stream.EOF)
|
||||
stream.Next (true);
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the time zone
|
||||
/// </summary>
|
||||
private double ParseTimezone (ParseStream stream)
|
||||
{
|
||||
double timezone = 0;
|
||||
|
||||
SkipWhitespace (stream);
|
||||
|
||||
// Timezone = UTC, use by default 0
|
||||
if (stream.Char == 'Z')
|
||||
stream.Next (true);
|
||||
else
|
||||
{
|
||||
// Find the sign of the offset
|
||||
int sign = 0;
|
||||
|
||||
if (stream.Char == '-')
|
||||
sign = -1;
|
||||
|
||||
else if (stream.Char == '+')
|
||||
sign = +1;
|
||||
|
||||
else
|
||||
throw new Exception ("Invalid time zone: " +
|
||||
"unexpected character");
|
||||
|
||||
// Read next char and test for more chars
|
||||
stream.Next (true);
|
||||
if (stream.EOF)
|
||||
throw new Exception ("Invalid time zone");
|
||||
|
||||
// Parse hour offset
|
||||
// Note: A hour can be represented by one or two digits.
|
||||
string hulp = "";
|
||||
while (stream.Char >= '0' &&
|
||||
stream.Char <= '9' &&
|
||||
!stream.EOF && hulp.Length <= 2)
|
||||
{
|
||||
hulp += (stream.Char);
|
||||
stream.Next (true);
|
||||
}
|
||||
timezone = sign * Double.Parse (hulp);
|
||||
|
||||
// Parse the minutes of the timezone
|
||||
// when there is still more to parse
|
||||
if ( ! stream.EOF)
|
||||
{
|
||||
SkipChar (stream, ':');
|
||||
int temp = ParseNumber (stream, 2);
|
||||
|
||||
timezone += (temp / 60.0);
|
||||
}
|
||||
}
|
||||
|
||||
return timezone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an integer
|
||||
/// </summary>
|
||||
/// <param name="length">
|
||||
/// The number of characters that the integer is expected to be.
|
||||
/// </param>
|
||||
/// <param name="stream"> The stream that will be parsed </param>
|
||||
private int ParseNumber (ParseStream stream, int length)
|
||||
{
|
||||
System.Text.StringBuilder hulp = new System.Text.StringBuilder ();
|
||||
|
||||
int i;
|
||||
for (i = 0; i < length && !stream.EOF; i++)
|
||||
{
|
||||
hulp.Append (stream.Char);
|
||||
stream.Next (true);
|
||||
}
|
||||
if (i == length)
|
||||
return Int32.Parse (hulp.ToString ());
|
||||
else
|
||||
throw new Exception ("Can't parse number");
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skips a specified char, and throws an exception when
|
||||
/// another char was found.
|
||||
/// </summary>
|
||||
private void SkipChar (ParseStream stream, char toSkip)
|
||||
{
|
||||
if (stream.Char == toSkip)
|
||||
stream.Next (true);
|
||||
else
|
||||
throw new Exception ("Unexpected character");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skips the spaces * and tabs * in the current stream
|
||||
/// </summary>
|
||||
private void SkipWhitespace (ParseStream stream)
|
||||
{
|
||||
while ((stream.Char == ' ' || stream.Char == '\t') && ! stream.EOF)
|
||||
stream.Next (true);
|
||||
}
|
||||
|
||||
/// <summary> Yaml notation for this datetime </summary>
|
||||
private string YamlString ()
|
||||
{
|
||||
string date = content.ToString ("yyyy-MM-ddTHH:mm:ss");
|
||||
int ms = content.Millisecond;
|
||||
if (ms != 0)
|
||||
{
|
||||
string hulp = "" + (ms / 1000.0);
|
||||
hulp = hulp.Substring(2); // Cut of the '0,', first 2 digits
|
||||
|
||||
date += "." + hulp;
|
||||
}
|
||||
string zone = "";
|
||||
|
||||
if (timezone != 0)
|
||||
{
|
||||
int timezoneHour = (int) Math.Floor (timezone);
|
||||
int timezoneMinutes = (int) (60 * (timezone - timezoneHour));
|
||||
|
||||
// if positif offset add '+', a '-' is default added
|
||||
if (timezone > 0)
|
||||
zone = "+";
|
||||
|
||||
zone += timezoneHour.ToString ();
|
||||
if (timezoneMinutes != 0)
|
||||
zone += ":" + timezoneMinutes;
|
||||
}
|
||||
else
|
||||
zone = "Z"; // UTC timezone as default and if offset == 0
|
||||
|
||||
return date + zone;
|
||||
}
|
||||
|
||||
/// <summary> Write to YAML </summary>
|
||||
protected internal override void Write (WriteStream stream)
|
||||
{
|
||||
stream.Append (YamlString ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
121
thirdparty/yaml/WriteStream.cs
vendored
Normal file
121
thirdparty/yaml/WriteStream.cs
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
// ====================================================================================================
|
||||
// YAML Parser for the .NET Framework
|
||||
// ====================================================================================================
|
||||
//
|
||||
// Copyright (c) 2006
|
||||
// Christophe Lambrechts
|
||||
// Jonathan Slenders
|
||||
//
|
||||
// ====================================================================================================
|
||||
// This file is part of the .NET YAML Parser.
|
||||
//
|
||||
// This .NET YAML parser is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The .NET YAML parser is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Foobar; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System.Reflection;
|
||||
// ====================================================================================================
|
||||
|
||||
#define ENABLE_COMPRESSION
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace Yaml
|
||||
{
|
||||
/// <summary>
|
||||
/// Help class for writing a Yaml tree to a string
|
||||
/// </summary>
|
||||
public class WriteStream
|
||||
{
|
||||
private TextWriter stream;
|
||||
private int indentation = 0;
|
||||
private bool lastcharisnewline = false;
|
||||
|
||||
private static string indentationChars = " ";
|
||||
|
||||
/// <summary> Constructor </summary>
|
||||
public WriteStream (TextWriter stream)
|
||||
{
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
/// <summary> Append a string </summary>
|
||||
public void Append (string s)
|
||||
{
|
||||
// Just add the text to the output stream when
|
||||
// there is no indentation
|
||||
if (indentation == 0)
|
||||
stream.Write (s);
|
||||
|
||||
// Otherwise process each individual char
|
||||
else
|
||||
for (int i = 0; i < s.Length; i ++)
|
||||
{
|
||||
// Indent after a newline
|
||||
if (lastcharisnewline)
|
||||
{
|
||||
WriteIndentation ();
|
||||
lastcharisnewline = false;
|
||||
}
|
||||
|
||||
// Add char
|
||||
stream.Write (s [i]);
|
||||
|
||||
// Remember newlines
|
||||
if (s [i] == '\n')
|
||||
lastcharisnewline = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Indentation </summary>
|
||||
public void Indent ()
|
||||
{
|
||||
// Increase indentation level
|
||||
indentation ++;
|
||||
|
||||
// Add a newline
|
||||
#if ENABLE_COMPRESSION
|
||||
lastcharisnewline = false;
|
||||
#else
|
||||
stream.Write ("\n");
|
||||
lastcharisnewline = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary> Write the indentation to the output stream </summary>
|
||||
private void WriteIndentation ()
|
||||
{
|
||||
for (int i = 0; i < indentation; i ++)
|
||||
stream.Write (indentationChars);
|
||||
}
|
||||
|
||||
/// <summary> Unindent </summary>
|
||||
public void UnIndent ()
|
||||
{
|
||||
if (indentation > 0)
|
||||
{
|
||||
// Decrease indentation level
|
||||
indentation --;
|
||||
|
||||
// Add a newline
|
||||
if (! lastcharisnewline)
|
||||
stream.Write ("\n");
|
||||
lastcharisnewline = true;
|
||||
}
|
||||
else
|
||||
throw new Exception ("Cannot unindent a not indented writestream.");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
188
thirdparty/yaml/Yaml.csproj
vendored
Normal file
188
thirdparty/yaml/Yaml.csproj
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{D4424F4D-7939-4247-98F5-6A7F6DEBA7C9}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>
|
||||
</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>Yaml</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Yaml</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>0.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>.\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Binary.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Boolean.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Float.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Integer.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Mapping.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Node.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Null.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ParseException.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ParseStream.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Scalar.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Sequence.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="String.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Timestamp.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="WriteStream.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
19
thirdparty/yaml/Yaml.sln
vendored
Normal file
19
thirdparty/yaml/Yaml.sln
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yaml", "Yaml.csproj", "{D4424F4D-7939-4247-98F5-6A7F6DEBA7C9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D4424F4D-7939-4247-98F5-6A7F6DEBA7C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D4424F4D-7939-4247-98F5-6A7F6DEBA7C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D4424F4D-7939-4247-98F5-6A7F6DEBA7C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D4424F4D-7939-4247-98F5-6A7F6DEBA7C9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
24
thirdparty/yaml/test.yaml
vendored
Normal file
24
thirdparty/yaml/test.yaml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
? boolean: y
|
||||
? float: 8.6e2
|
||||
? integer: 174832
|
||||
? null: ~
|
||||
? inline sequence: [item1, item2]
|
||||
? inline mappings: {key: value, key2: value2}
|
||||
? sequence:
|
||||
- item 1
|
||||
- item 2
|
||||
? tricky situations:
|
||||
- ? block scalar: |
|
||||
regel 1
|
||||
regel 2
|
||||
- ? folded scalar: >
|
||||
regel 1
|
||||
nog steeds regel 1
|
||||
- ? double quoted: "met veel escapes aa\"bb\n\'cc"
|
||||
- ? met tags:
|
||||
- !!int 2
|
||||
- !!string 2
|
||||
- !!float 2
|
||||
- { key: value, key 3: "{a: b}", key 2: a }
|
||||
- ? [aaa]: bbb
|
||||
- ? single quotes: 'regel 1 regel 2'
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user