Внедрение системы CVAR - PullRequest
       19

Внедрение системы CVAR

8 голосов
/ 04 марта 2011

Я хотел бы реализовать то, что я знаю как Систему CVAR, я не совсем уверен в том, какое официальное название у нее (если есть).

По сути, это система, используемая в некоторых программах ивидеоигры, где пользователь может снять консоль и ввести команду, например, «переменная 500», чтобы установить эту переменную равной 500. Примеры этого можно найти в любой игре Half-Life, играх Doom и Quake и многих других,Общая идея, по-видимому, заключается в том, чтобы скрыть базовую архитектуру, но при этом разрешить защищенный доступ, например, можно просмотреть значение, скажем, силы тяжести, но не изменить Это.Некоторые из этих значений также могут быть функциями, например, пользователь может ввести «создать» для создания типа врага в своем местоположении или в другом указанном местоположении.

Просмотр Half-Life 2 SDKи из того, что я помню в GoldSrc SDK, кажется, что они, по крайней мере, реализовали «пометки» своего рода, когда определенные команды будут работать только при определенных условиях, например, если задано другое значение или если у пользователя есть некоторый уровень разрешений,

Первоначально я думал о том, чтобы создать словарь или объект, подобный этому, и использовать его для привязки строковых значений к делегатам функций, а также для поддержания своего рода «уровня защиты», чтобы ограничить использованиеопределенные команды.Однако это кажется довольно громоздким, так как я считаю, что мне нужно было бы пройти и добавить новую запись вручную для каждого значения или функции, которую я хотел реализовать.Я также не знаю, даст ли это мне нужный мне уровень управления.

В идеале я бы хотел, чтобы класс системы CVAR, а также функция Register, которая могла бы его приниматьскажем, делегат переменной / функции, строка для доступа к ней и любой уровень защиты, который мне нужен.Таким образом, я могу добавлять то, что мне нужно, так как я их вижу, так что все по-прежнему находится в связанных классах и файлах.

Я просто ищу некоторые идеи здесь, поэтому мои вопросы:

  • Кто-нибудь когда-либо делал что-то подобное раньше, и если да, то как?
  • Будет ли моя реализация работать?(Теоретически, если нет, можете ли вы придумать лучший способ?)
  • Если кто-то более осведомлен о том, как это делает одно из упомянутых ранее названий, можете ли вы остановиться на этом немного подробнее?Кажется, трудно найти документацию по ним.

Я на самом деле не ищу конкретный код, просто больше структурирования дизайна.И это не обязательно должно быть «коммерчески» или работать как другой, мне просто нужно что-то, чтобы заставить меня работать.

Ответы [ 3 ]

2 голосов
/ 04 марта 2011

Ты думал о чем-то подобном?

class CVAR
{
   [ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
   private float gravity = 0.1f;

   [ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
   private float friction = 0.1f;

   [ProtectionLevel(CVARFlags.ReadOnly)]
   private string serverVersion = "x.x.x";

   public void SetCVARValue(string commandLine) {
       string cvarName = GetCvarName(commandLine); // parse the cmd line and get the cvar name from there
       object cvarValue = GetCvarValue(commandLine); // parse the value from the string

       FieldInfo field = typeof(CVAR).GetField(cvarName);
       object[] attributes = field.GetCustomAttributes(typeof(ProtectionLevel), false);

       if(attributes.Length > 0) {
           ProtectionLevelAttribute attr = (ProtectionLevelAttribute)attributes[0];

           if(attr.CheckConditions(World.Instance)) {
               field.SetValue(this, cvarValue);
           } else {
               // error report
           }
       }
   }
}
1 голос
/ 04 марта 2011

Вы можете написать синтаксический анализатор, который будет искать такие команды, как

/object_property value
/object_method arg1 arg2

Словарь, как вы и предлагали, может отображать эти строки в свойствах и функциях.Создание словаря может быть выполнено динамически, используя рефлексию, просматривая подходящие объекты, беря их открытые методы и методы доступа и генерируя для них строку.

Затем словарь можно отобразить в классе для удобства и ошибок.проверяя.

Для методов значения словаря могут быть делегатами, которые принимают 0..n аргументов, для свойств / полей вам нужно будет иметь возможность некоторой привязки данных между вашими фактическими полями и значением словаря,UNLESS, ваши объекты сами ссылаются на словари для своих значений, в этом случае значения только живут на месте.

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

[Flags]
public enum CVarAccessibilities
{
     Settable,
     Gettable
}

public class CVar<T>
{
     public CVarAccessibilities Accessibility { get; set; }
     T val;
     public T Value { 
        get { return val; }
        set
        {
             if (!Accessibility.HasFlag(CVarAccessibilities.Settable))
                  return; // just don't set it, maybe print some warning
             val = value;
        }
     }
}

public static class CVarRegistry
{
     static Dictionary<string, Object> CVars;

     static CVarRegistry { /* use reflections to initialize the dictionary */ }

     public static T GetValue<T>(Type owner, string paramName)
     {
          CVar cvar;
          if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
                 throw new MyCustomException();
          return (T)cvar.Value;
     }

     public static void SetValue<T>(Type owner, string paramName, T value)
     {
          CVar cvar;
          if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
                 throw new MyCustomException();
          cvar.Value = value;
     }
}



public class MyObject
{
    public static int MyRegisteredValue
    {
        get { return Global.CVarRegistry.GetValue<int>(typeof(MyObject), "MyRegisteredValue");  }
        set { Global.CVarRegistry.SetValue(typeof(MyObject), "MyRegisteredValue"); }
    }
 }

Надеюсь, что поможет!

1 голос
/ 04 марта 2011

Это более часто называют переменными 'tweak'.

Хорошее обсуждение здесь: https://gamedev.stackexchange.com/questions/3631/tweaking-and-settings-runtime-variable-modification-and-persistence

...