Skip to content

Commit

Permalink
[12] Added support for more properties and types. Not quite up to par…
Browse files Browse the repository at this point in the history
… yet for loading .tweak files, but getting very close!
  • Loading branch information
wilson212 committed Feb 17, 2016
1 parent 24a3c5c commit 0e7d903
Show file tree
Hide file tree
Showing 35 changed files with 1,514 additions and 271 deletions.
6 changes: 6 additions & 0 deletions BF2ScriptingEngine/BF2ScriptingEngine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,13 @@
<Compile Include="Scripting\Components\SimpleDeviationComp.cs" />
<Compile Include="Scripting\Components\SingleFireComp.cs" />
<Compile Include="Scripting\Components\ToggleCameraComp.cs" />
<Compile Include="Scripting\Components\WarningHud.cs" />
<Compile Include="Scripting\Components\WeaponBasedRecoilComp.cs" />
<Compile Include="Scripting\Components\Abstract\ZoomComp.cs" />
<Compile Include="Scripting\ConFileStringEntry.cs" />
<Compile Include="Scripting\Enumerations\ControlsCategory.cs" />
<Compile Include="Scripting\Enumerations\PhysicsType.cs" />
<Compile Include="Scripting\Enumerations\VehicleCategory.cs" />
<Compile Include="Scripting\GeometryTemplates\StaticMesh.cs" />
<Compile Include="Scripting\Interfaces\ICastable.cs" />
<Compile Include="Scripting\ObjectTemplates\AnimatedBundle.cs" />
Expand All @@ -72,6 +77,7 @@
<Compile Include="Scripting\ObjectTemplates\LandingGear.cs" />
<Compile Include="Scripting\ObjectTemplates\Parachute.cs" />
<Compile Include="Scripting\ObjectTemplates\RotationalBundle.cs" />
<Compile Include="Scripting\ObjectTemplates\Sound.cs" />
<Compile Include="Scripting\ObjectTemplates\Spring.cs" />
<Compile Include="Scripting\ObjectTemplates\SupplyObject.cs" />
<Compile Include="Scripting\ObjectTemplates\UAVVehicle.cs" />
Expand Down
21 changes: 21 additions & 0 deletions BF2ScriptingEngine/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Expand Down Expand Up @@ -89,5 +90,25 @@ public static string[] SplitWithQuotes(this string text, char[] splitChars, bool
.SelectMany(element => element)
.ToArray();
}

/// <summary>
/// Returns true if string is numeric and not empty or null or whitespace.
/// Determines if string is numeric by parsing as Double
/// </summary>
/// <param name="str"></param>
/// <param name="style">
/// Optional style - defaults to NumberStyles.Number
/// (leading and trailing whitespace, leading and trailing sign,
/// decimal point and thousands separator)
/// </param>
/// <param name="culture">Optional CultureInfo - defaults to InvariantCulture</param>
/// <returns></returns>
public static bool IsNumeric(this string str, NumberStyles style = NumberStyles.Number,
CultureInfo culture = null)
{
double num;
if (culture == null) culture = CultureInfo.InvariantCulture;
return Double.TryParse(str, style, culture, out num) && !String.IsNullOrWhiteSpace(str);
}
}
}
6 changes: 5 additions & 1 deletion BF2ScriptingEngine/ReferenceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ static ReferenceManager()
// Create Object Template
current = new ReferenceType("ObjectTemplate", typeof(ObjectTemplate));
current.Mappings.Add("create", ObjectTemplate.Create);
current.Mappings.Add("activeSafe", ObjectTemplate.Create);
AddType(current);

// Create Weapon Template
current = new ReferenceType("weaponTemplate", typeof(WeaponTemplate));
current.Mappings.Add("create", WeaponTemplate.Create);
current.Mappings.Add("activeSafe", WeaponTemplate.Create);
AddType(current);

// Create Ai Template
Expand All @@ -47,6 +49,7 @@ static ReferenceManager()
// Create Kit Template
current = new ReferenceType("GeometryTemplate", typeof(GeometryTemplate));
current.Mappings.Add("create", GeometryTemplate.Create);
current.Mappings.Add("activeSafe", GeometryTemplate.Create);
AddType(current);

// Create Kit Template
Expand Down Expand Up @@ -108,7 +111,8 @@ public static ReferenceType GetReferenceType(Type objType)
{
foreach (KeyValuePair<string, ReferenceType> item in Registry)
{
if (item.Value.Type.IsAssignableFrom(objType))
Type check = item.Value.Type;
if (check == objType || check.IsAssignableFrom(objType))
return item.Value;
}

Expand Down
52 changes: 45 additions & 7 deletions BF2ScriptingEngine/Scope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ public class Scope
/// </summary>
public MissingObjectHandling MissingObjectHandling { get; set; } = MissingObjectHandling.CreateNew;

/// <summary>
/// Gets or Sets whether this Scope is required to pass created objects
/// up to the parent <see cref="Scope"/> if one is defined
/// </summary>
/// <remarks>
/// The ScopeType will be respected, if this Scope is Detached, then a clone
/// copy of the object will be givin to the parent scope
/// </remarks>
public bool RegisterObjects { get; set; } = false;

/// <summary>
/// Keeps a list of all active objects, for each template type
/// </summary>
Expand Down Expand Up @@ -127,7 +137,7 @@ public Scope(Scope parentScope, ScopeType type)
public void Execute(string input, ConFile file = null)
{
// === Create Token
Token token = Tokenizer.Tokenize(input, ScriptEngine.TokenExpressions);
Token token = Tokenizer.Tokenize(input);
token.File = file;

// === Execute on Scope
Expand Down Expand Up @@ -158,6 +168,15 @@ public void AddObject(ConFileObject obj, bool setActive = true)
if (setActive)
SetActiveObject(obj);

// Register object?
if (ParentScope != null && RegisterObjects)
{
if (ScopeType == ScopeType.Attached)
ParentScope.AddObject(obj, setActive);
else
ParentScope.AddObject(obj.Clone(), setActive);
}

// Add object
Objects.Add(key, obj);
}
Expand Down Expand Up @@ -193,6 +212,15 @@ internal void AddObject(ConFileObject obj, Token token)
{
// Add object
Objects.Add(key, obj);

// Register object?
if (ParentScope != null && RegisterObjects)
{
if (ScopeType == ScopeType.Attached)
ParentScope.AddObject(obj, token);
else
ParentScope.AddObject(obj.Clone(), token);
}
}

// Set object as active
Expand Down Expand Up @@ -290,13 +318,22 @@ public ConFileObject GetActiveObject(ReferenceType type)
internal ConFileObject GetObject(Token token)
{
// Pull info
TokenArgs tokenArgs = token.TokenArgs;
string name = token.TokenArgs.Arguments.Last();
try
{
TokenArgs tokenArgs = token.TokenArgs;
string name = token.TokenArgs.Arguments.Last();

// Create our Objects key
var type = tokenArgs.ReferenceType;
var key = new Tuple<string, ReferenceType>(name, type);
return GetObject(key, token);
// Create our Objects key
var type = tokenArgs.ReferenceType;
var key = new Tuple<string, ReferenceType>(name, type);
return GetObject(key, token);
}
catch
{
throw;
}


}

/// <summary>
Expand Down Expand Up @@ -335,6 +372,7 @@ internal ConFileObject GetObject(Tuple<string, ReferenceType> key, Token token)
else
{
// === Deep Clone === //
Objects[key] = ParentScope.GetObject(key, token).Clone();
}
break;
default:
Expand Down
72 changes: 1 addition & 71 deletions BF2ScriptingEngine/ScriptEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,76 +17,6 @@ namespace BF2ScriptingEngine
/// <seealso cref="http://bf2tech.org/index.php/ConGrammar"/>
public static class ScriptEngine
{
/// <summary>
/// An array of all the expressions needed to tokenize the contents
/// of a Con file.
/// </summary>
/// <remarks>
/// Order is important here, as we itterate through these expressions, lines
/// that match an expression are removed from our source. As we get to the bottom
/// of this array, the source will get smaller and smaller as we match our expressions.
/// </remarks>
internal static KeyValuePair<TokenType, string>[] TokenExpressions = new[]
{
// === Parse comments first, as somethings like objects and properties can be commented out === //

// Multiline Rem Comment on a single line
new KeyValuePair<TokenType, string>(TokenType.RemComment,
@"^beginRem(?<value>.*?)endRem$"
),

// Multiline Rem Comment START
new KeyValuePair<TokenType, string>(TokenType.BeginRem,
@"^beginRem(?<value>.*?)$"
),

// Multiline Rem Comment END
new KeyValuePair<TokenType, string>(TokenType.EndRem,
@"^(?<value>.*)endRem$"
),

// Single line Rem Comment
new KeyValuePair<TokenType, string>(TokenType.RemComment,
@"^rem([\s|\t]+)(?<value>.*)?$"
),

// === Objects === //

new KeyValuePair<TokenType, string>(TokenType.ActiveSwitch,
@"^(?<reference>[a-z]+)\.active(?<type>[a-z_]*)([\s|\t]+)(?<value>.*)?$"
),

// Object property value, HAS TO FOLLOW everything else with a similar expression
// due to the ungreediness of this regular expression
new KeyValuePair<TokenType, string>(TokenType.ObjectProperty,
@"^(?<reference>[a-z]+)\.(?<property>[a-z_\.]+)([\s|\t]+)(?<value>.*)?$"
),

// === Vars Conditionals === //

// If statements
new KeyValuePair<TokenType, string>(TokenType.IfStart, @"^if(?<value>.*)?$"),

// End If
new KeyValuePair<TokenType, string>(TokenType.EndIf, @"^(?<value>.*)endIf$"),

// Variable
new KeyValuePair<TokenType, string>(TokenType.Variable, @"^(?:var[\s\t]+)(?<name>[a-z0-9_]+)[\s\t]*(?:=[\s\t]*)?(?<value>.*?)?$"),
new KeyValuePair<TokenType, string>(TokenType.Variable, @"^(?<name>[a-z0-9_]+)[\s\t]*(?:=[\s\t]*)(?<value>.*?)$"),

// Constant
new KeyValuePair<TokenType, string>(TokenType.Constant, @"^(?:const[\s\t]+)(?<name>[a-z0-9_]+)[\s\t]*(?:=[\s\t]*)(?<value>.*?)$"),

// Include command
new KeyValuePair<TokenType, string>(TokenType.Include, @"^include(?<value>.*)?$"),

// Run command
new KeyValuePair<TokenType, string>(TokenType.Run, @"^run(?<value>.*)?$"),

// Finally, match everything else
new KeyValuePair<TokenType, string>(TokenType.None, @"^(?<value>.*?)$")
};

/// <summary>
/// Gets a list of characters used to split a confile line into arguments
/// </summary>
Expand Down Expand Up @@ -249,7 +179,7 @@ internal static async Task ParseFileLines(
// ============
// First we convert our confile lines into parsed tokens
// ============
Token[] fileTokens = Tokenizer.Tokenize(workingFile, ref fileContents, TokenExpressions);
Token[] fileTokens = Tokenizer.Tokenize(workingFile, ref fileContents);
TokenArgs tokenArgs;
Scope currentScope = workingFile.Scope;

Expand Down
Loading

0 comments on commit 0e7d903

Please sign in to comment.