Как переместить код в данные, став более подходом, управляемым данными? - PullRequest
0 голосов
/ 29 апреля 2020

Для справки, смотрите статью: https://gameprogrammingpatterns.com/bytecode.html#data -% 3E-код

Здравствуйте, я сейчас смотрю много повторений в моем игровом коде в C# ,

как, например:

public void SomeAction() {
    DoSomething();
    DoSomething();
    DoAnotherThing();
}

Мне удалось преобразовать этот код в подход, основанный на данных, используя шаблон команды:

public List<Command> commands;

public void DoAction() {
    foreach (cmd in commands) {
        cmd.Execute();
    }
}

Я понял, что данные управляемый подход красиво разработан, и это правильный подход для меня. Но потом я наткнулся на это:

private float[] data;

public IEnumerable<float> ExampleQuery() {
    return data
        .Select(x => x + 2)
        .Where(x => x < 50)
        .Select(x => x * 3)
        .Select(x => x * 10)
        .Select(x => x > 999 ? 999 : x);
}

как конвертировать в это:

private float[] data;
public List<Rules> rules;

public IEnumerable<float> Query() {
    // should I foreach here?
}

Как видите, этот должен быть управляемым данными, так что если я хочу сделать больше правил для запроса данных, мне не нужно перекомпилировать, и я могу просто добавить больше правил в список.

Из ссылки:

Мы хотим, чтобы их было легко изменить, легко перезагрузить и физически отделить от остальной части исполняемого файла. Я не знаю о вас, но для меня это звучит очень похоже на данные . Если мы можем определить наше поведение в отдельных файлах данных, которые игровой движок загружает и каким-то образом «выполняет», мы можем достичь всех наших целей. Нам просто нужно выяснить, что означает «выполнить» для данных.

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

* Любая хорошая справочная статья также очень поможет.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020

Просто используйте список функций, таких как:

List<( Func<float,bool> where, Func<float,float> select )> rules;

public IEnumerable<float> Query ( IEnumerable<float> original ) {
    IEnumerable<float> result = original;
    foreach ( var i in rules ) {
        result = result.Where( i.where ).Select( i.select );
    }
    return result;
}

rules.AddRange( new[] {
    ( (x => true), (x => x + 2) ),
    ( (x => x < 50), (x => x) ),
    ( (x => true), (x => x * 3) ),
    ( (x => true), (x => x * 10) ),
    ( (x => true), (x => ( x > 999 ) ? 999 : x) )
} );

или даже лучше:

List<Func<IEnumerable<float>,IEnumerable<float>>> rules;

public IEnumerable Query ( IEnumerable<float> original ) {
    foreach ( var i in rules ) original = i.Invoke( original );
    return original;
}

rules.AddRange( new[] {
    ( x => x.Select( y => y + 2 ) ),
    ( x => x.Where( y => y < 50 ) ),
    ( x => x.Select( y => y * 3 ) ),
    ( x => x.Select( y => y * 10 ) ),
    ( x => x.Select( y => ( y > 999 ) ? 999 : y ) ),
} );
0 голосов
/ 29 апреля 2020

Вы можете сделать:

public List<Rules> rules;
var floats = data.Select(x => x + 2)
        .Where(x => x < 50)
        .Select(x => x * 3)
        .Select(x => x * 10)
        .Select(x => x > 999 ? 999 : x);

public List<Rules> ExampleQuery()
{
 foreach(var d in floats)
 {
  rules.Add(d);
 }
  return rules;
}
...