Использование шаблонов T4 с VS2010 Express и XNA - PullRequest
1 голос
/ 11 мая 2011

Я использую VS2010 express для создания игры, созданной с . Я пытаюсь использовать шаблоны (для создания строго типизированных классов местоположений контента, таким образом, используя Level1Location = Content.Levels.Level1 вместо Level1Location = @"Content\Levels\Level1".

Я читал, что шаблоны T4 не настроены должным образом в экспресс-версиях, но если я создаю файл с расширением .tt, он должен работать. Однако, когда я создаю файл .tt в моей библиотеке классов XNA, я получаю следующее предупреждение (и без кода):

The custom tool 'TextTemplatingFileGenerator' failed. Could not load file or assembly 'Microsoft.VisualStudio.ServicesProxy, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

Я искал и искал и не могу найти ничего полезного. Кто-нибудь сталкивался с этой проблемой раньше? Кто-нибудь знает, есть ли решение?

Я также попытался изменить пользовательский инструмент на TextTemplatingFilePreprocessor, как и предлагалось, однако я получаю ту же ошибку.

РЕДАКТИРОВАТЬ: Я обнаружил, что проблема в том, что он находится в проекте / библиотеке XNA. Он отлично работает в обычном классе, так что моя задача - добавить проект в решение только для шаблона. Вопрос все еще открыт, можете ли вы заставить его работать в проекте XNA?

1 Ответ

3 голосов
/ 19 мая 2011

Хотя я опубликовал этот ответ, я все еще ищу более простой способ сделать это (т. Е. Файл tt в самом проекте XNA)

На случай, если кто-нибудь найдетна этой странице вот моя работа:

Создайте новый (не XNA) проект библиотеки классов.

Добавьте текстовый файл, переименованный с расширением .tt.

Введите свой код T4 (см. Ниже).

В своем проекте XNA добавьте существующий элемент, перейдите к созданному файлу .cs и добавьте в качестве ссылки.

Затем, чтобы мы всегдаполучите обновленный файл cs, щелкните правой кнопкой мыши проект XNA и выберите зависимости проекта, а затем отметьте свой проект библиотеки классов, содержащий файл .tt.

Используя приведенный ниже код шаблона, вы можете делать такие вещи, как Content.Load (Content.MyGameContent.Graphics.Textures.AwesomeTexture);Вы также можете получить имена папок в виде строк с помощью Content.MyGameContent.Graphics.Textures, например, благодаря прикольному неявному оператору преобразования строк.

<#@ template language="c#" hostspecific="true" #>
<#@ assembly name="EnvDTE100" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name="System" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="EnvDTE100" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
namespace Content
{
<#
var serviceProvider = this.Host as IServiceProvider;
var dte = serviceProvider.GetService(typeof(DTE)) as DTE;

foreach (Project Proj in dte.Solution.Projects)
{
    bool IsContentProj = false;
    foreach(Property Prop in Proj.Properties)
    {
        if(Prop.Name == "Microsoft.Xna.GameStudio.ContentProject.ContentRootDirectoryExtender.ContentRootDirectory")
        {
            IsContentProj = true;
        }
    }
    if (IsContentProj)
    {
#>
    public static class <#=Proj.Name #>
    {
<#
        foreach(ProjectItem PI in Proj.ProjectItems)
        {
GenerateProjectItemClass(PI, true, "        ");
        }
#>
    }
<#
    }
}
#>
}
<#+
    void GenerateProjectItemClass(ProjectItem Item, bool Static, string Indent)
    {
        const string FolderItemKind = "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}";
        const string FileItemKind = "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}";
        string ClassName = Path.GetDirectoryName(Item.FileNames[0]).Substring(Path.GetDirectoryName(Item.FileNames[0]).LastIndexOf(Path.DirectorySeparatorChar) + 1);
        int ContentRootLength = Path.GetDirectoryName(Item.ContainingProject.FileName).Length;

        string RelativeLocation = Path.ChangeExtension(Path.GetFullPath(Item.FileNames[0]).Substring(ContentRootLength + 1), null);

        switch(Item.Kind)
        {
            case FolderItemKind:
#>
<#=Indent#>public class <#=ClassName #>Class
<#=Indent#>{
<#=Indent#>    private const string Location = @"<#= RelativeLocation #>";
<#=Indent#>    public static implicit operator string(<#=ClassName #>Class MyClass)
<#=Indent#>    {
<#=Indent#>        return Location;
<#=Indent#>    }
<#+
            foreach(ProjectItem ChildItem in Item.ProjectItems)
                GenerateProjectItemClass(ChildItem, false, Indent + "    ");
#>
<#=Indent#>}
<#=Indent#>
<#=Indent#>public <#= Static ? "static " : " " #><#=ClassName#>Class <#=ClassName#> = new <#=ClassName#>Class();
<#=Indent#>
<#+
            break;
            case FileItemKind:
#>
<#=Indent#>public <#= Static ? "static " : " " #>string <#= Path.GetFileNameWithoutExtension(Item.FileNames[0]) #> = @"<#=RelativeLocation #>";
<#+
            break;
        }
    }
#>
...