Skip to content

Commit

Permalink
Add ability to write arbitrary HTML in WebPlayer.
Browse files Browse the repository at this point in the history
git-svn-id: https://quest.svn.codeplex.com/svn/trunk@5579 4a90e977-6436-4932-9605-20e10c2b6fb3
  • Loading branch information
alexwarren committed Feb 13, 2011
1 parent c65d479 commit 02e534c
Show file tree
Hide file tree
Showing 13 changed files with 260 additions and 10 deletions.
1 change: 1 addition & 0 deletions IASL/IASL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public interface IPlayer
string GetNewGameFile(string originalFilename, string extensions);
void PlaySound(string filename, bool synchronous, bool looped);
void StopSound();
void WriteHTML(string html);
}

public enum HyperlinkType
Expand Down
5 changes: 5 additions & 0 deletions LegacyASLTests/TestPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,10 @@ public void StopSound()
{
throw new NotImplementedException();
}

public void WriteHTML(string html)
{
throw new NotImplementedException();
}
}
}
3 changes: 3 additions & 0 deletions Player/Player.vb
Original file line number Diff line number Diff line change
Expand Up @@ -969,4 +969,7 @@ Public Class Player
m_destroyed = True
End Sub

Public Sub WriteHTML(html As String) Implements IPlayer.WriteHTML
Throw New NotImplementedException()
End Sub
End Class
8 changes: 8 additions & 0 deletions Quest 5.0.sln
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebPlayer", "WebPlayer\WebP
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LegacyASLTests", "LegacyASLTests\LegacyASLTests.csproj", "{9D7478AE-52D8-41B6-8E5C-D3F483919993}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorldModelTests", "WorldModelTests\WorldModelTests.csproj", "{EF616C5D-B02E-4BF2-9AB5-81E6F479C342}"
EndProject
Global
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = Quest 5.0.vsmdi
Expand Down Expand Up @@ -127,6 +129,12 @@ Global
{9D7478AE-52D8-41B6-8E5C-D3F483919993}.Release|Any CPU.Build.0 = Release|Any CPU
{9D7478AE-52D8-41B6-8E5C-D3F483919993}.ReleaseSetup|Any CPU.ActiveCfg = Release|Any CPU
{9D7478AE-52D8-41B6-8E5C-D3F483919993}.ReleaseSetup|Any CPU.Build.0 = Release|Any CPU
{EF616C5D-B02E-4BF2-9AB5-81E6F479C342}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF616C5D-B02E-4BF2-9AB5-81E6F479C342}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF616C5D-B02E-4BF2-9AB5-81E6F479C342}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF616C5D-B02E-4BF2-9AB5-81E6F479C342}.Release|Any CPU.Build.0 = Release|Any CPU
{EF616C5D-B02E-4BF2-9AB5-81E6F479C342}.ReleaseSetup|Any CPU.ActiveCfg = Release|Any CPU
{EF616C5D-B02E-4BF2-9AB5-81E6F479C342}.ReleaseSetup|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
8 changes: 8 additions & 0 deletions WebPlayer/PlayerHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ void RunScript(string data)
parameters.Add(new StringParameter(args[i].Trim()));
}

// Clear text buffer before running custom JavaScript, otherwise text written
// before now may appear after inserted HTML.
m_buffer.OutputText(ClearBuffer());
m_buffer.AddJavaScriptToBuffer(args[0], parameters.ToArray());
}

Expand Down Expand Up @@ -454,5 +457,10 @@ public IEnumerable<string> SetUpExternalScripts()

return result;
}

public void WriteHTML(string html)
{
m_textBuffer += html;
}
}
}
4 changes: 2 additions & 2 deletions WorldModel/WorldModel/GameLoader/ElementLoaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ public override string AppliesTo
public override object Load(XmlReader reader, ref Element current)
{
string file = GameLoader.GetTemplateAttribute(reader, "ref");
string path = WorldModel.GetExternalPath(System.IO.Path.GetDirectoryName(WorldModel.Filename), file);
string path = WorldModel.GetExternalPath(file);
XmlReader newReader = XmlReader.Create(path);
newReader.Read();
if (newReader.Name != "library")
Expand Down Expand Up @@ -819,7 +819,7 @@ public override object Load(XmlReader reader, ref Element current)
{
Element jsRef = WorldModel.GetElementFactory(ElementType.Javascript).Create();
string file = GameLoader.GetTemplateAttribute(reader, "src");
string path = WorldModel.GetExternalPath(System.IO.Path.GetDirectoryName(WorldModel.Filename), file);
string path = WorldModel.GetExternalPath(file);
jsRef.Fields[FieldDefinitions.Src] = path;

return jsRef;
Expand Down
75 changes: 75 additions & 0 deletions WorldModel/WorldModel/Scripts/InsertScript.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AxeSoftware.Quest.Functions;

namespace AxeSoftware.Quest.Scripts
{
public class InsertScriptConstructor : ScriptConstructorBase
{
#region ScriptConstructorBase Members

public override string Keyword
{
get { return "insert"; }
}

protected override IScript CreateInt(List<string> parameters)
{
return new InsertScript(WorldModel, new Expression<string>(parameters[0], WorldModel));
}

protected override int[] ExpectedParameters
{
get { return new int[] { 1 }; }
}
#endregion
}

public class InsertScript : ScriptBase
{
private WorldModel m_worldModel;
private IFunction<string> m_filename;

public InsertScript(WorldModel worldModel, IFunction<string> filename)
{
m_worldModel = worldModel;
m_filename = filename;
}

#region IScript Members

public override void Execute(Context c)
{
string filename = m_filename.Execute(c);
string path = m_worldModel.GetExternalPath(filename);
m_worldModel.PlayerUI.WriteHTML(System.IO.File.ReadAllText(path));
}

#endregion

public override string Save()
{
return SaveScript("msg", m_filename.Save());
}

public override string GetParameter(int index)
{
return m_filename.Save();
}

public override void SetParameterInternal(int index, string value)
{
m_filename = new Expression<string>(value, m_worldModel);
}

public override string Keyword
{
get
{
return "insert";
}
}
}
}
28 changes: 22 additions & 6 deletions WorldModel/WorldModel/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,28 @@ public static void ResolveVariableName(string name, out string obj, out string v
/// <returns></returns>
public static string ConvertDottedPropertiesToVariable(string expression)
{
// TO DO: This needs to ignore the pattern if it's inside quotes.
// Again as for the solution to stripping out comments in ScriptFactory.cs, solution is
// probably to see if we have a match for this regex, but then go through the expression
// one character at a time, set flag when within quote characters, and replace . with _
// as appropriate.
return s_convertVariables.Replace(expression, "$1_$2");
// We ignore dots which appear within quotes by splitting the string
// at the position of quote marks, and then alternating whether we replace or not.
string[] sections = expression.Split('\"');
string result = string.Empty;

bool insideQuote = false;
for (int i = 0; i <= sections.Length - 1; i++)
{
string section = sections[i];
if (!insideQuote)
{
result += s_convertVariables.Replace(section, "$1_$2");
}
else
{
result += section;
}
if (i < sections.Length - 1) result += "\"";
insideQuote = !insideQuote;
}

return result;
}

public static List<string> SplitIntoLines(string text)
Expand Down
14 changes: 12 additions & 2 deletions WorldModel/WorldModel/WorldModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ internal string Interface
get { return m_elements.GetSingle(ElementType.Interface).Fields[FieldDefinitions.Interface]; }
set
{
string HTMLfile = GetExternalPath(System.IO.Path.GetDirectoryName(m_filename), value);
string HTMLfile = GetExternalPath(value);

Element i;
if (m_elements.Count(ElementType.Interface) == 0)
Expand Down Expand Up @@ -767,7 +767,12 @@ public static string ConvertTypeToTypeName(Type type)
throw new ArgumentOutOfRangeException(string.Format("Unrecognised type '{0}'", type.ToString()));
}

public string GetExternalPath(string current, string file)
public string GetExternalPath(string file)
{
return GetExternalPath(System.IO.Path.GetDirectoryName(Filename), file);
}

private string GetExternalPath(string current, string file)
{
string path;

Expand Down Expand Up @@ -835,5 +840,10 @@ void LogException(Exception ex)
{
if (LogError != null) LogError(ex.Message + Environment.NewLine + ex.StackTrace);
}

internal IPlayer PlayerUI
{
get { return m_playerUI; }
}
}
}
1 change: 1 addition & 0 deletions WorldModel/WorldModel/WorldModel.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
<Compile Include="Scripts\FinishScript.cs" />
<Compile Include="Scripts\ForEachScript.cs" />
<Compile Include="Scripts\ForScript.cs" />
<Compile Include="Scripts\InsertScript.cs" />
<Compile Include="Scripts\ListAddScript.cs" />
<Compile Include="Scripts\PopulateScript.cs" />
<Compile Include="ScriptFactory.cs" />
Expand Down
35 changes: 35 additions & 0 deletions WorldModelTests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// 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("WorldModelTests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WorldModelTests")]
[assembly: AssemblyCopyright("Copyright © 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("339bd264-6f79-4553-a638-0e108f7a9fb1")]

// 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 Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
23 changes: 23 additions & 0 deletions WorldModelTests/UtilityTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using AxeSoftware.Quest;

namespace WorldModelTests
{
[TestClass]
public class UtilityTests
{
[TestMethod]
public void TestConvertDottedProperties()
{
Assert.AreEqual("obj_prop", Utility.ConvertDottedPropertiesToVariable("obj.prop"));
Assert.AreEqual("obj1_prop obj2_prop", Utility.ConvertDottedPropertiesToVariable("obj1.prop obj2.prop"));
Assert.AreEqual("(\"myfile.html\")", Utility.ConvertDottedPropertiesToVariable("(\"myfile.html\")"));
Assert.AreEqual("\"myfile.html\"", Utility.ConvertDottedPropertiesToVariable("\"myfile.html\""));
Assert.AreEqual("obj1_prop \"test.html\" obj2_prop", Utility.ConvertDottedPropertiesToVariable("obj1.prop \"test.html\" obj2.prop"));
}
}
}
65 changes: 65 additions & 0 deletions WorldModelTests/WorldModelTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EF616C5D-B02E-4BF2-9AB5-81E6F479C342}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WorldModelTests</RootNamespace>
<AssemblyName>WorldModelTests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
<Visible>False</Visible>
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UtilityTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WorldModel\WorldModel\WorldModel.csproj">
<Project>{F8CA1A78-02F7-405B-B223-3EFBEFBD8A88}</Project>
<Name>WorldModel</Name>
</ProjectReference>
</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.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

0 comments on commit 02e534c

Please sign in to comment.