Skip to content

Гайд по доработке движка ​

Разработка ведется в фичаветках, которые потом вливаются в ствол. Специальных веток, наподобие git-flow мы не используем, оказалось, что для нас слишком много формализма и слишком мало пользы.

Стволов у нас несколько, потому что одновременно поддерживается несколько версий:

  • Очередная версия, которая активно разрабатывается (ветка develop)
  • Ветка разработки 1.x, в части багфиксов (lts)
  • Ветки фиксации релизов (release/*) - после вливания в одну из этих веток CI начнет публикацию релиза на сайт
    • release/latest - последний релиз стабильной версии
    • release/preview - релиз ознакомительной версии.
    • release/lts - релиз LTS версии, поддерживаемой в части багфиксов (lts)

Версия 1.x ​

Версия 1.x на данный момент самая распространенная и считается стабильной. Разработка новых фич в ней не ведется. Основана на .NET 4.8, на линуксе требует Mono

Версия 2.0 ​

Разрабатываемая мажорная версия, является официальной заменой версии 1. Основана на актуальных версиях .NET, кроссплатформенная, собирается под windows, linus, MacOS ARM и x86

Добавление класса ​

Вам нужно добавить обычный новый класс C#, дать ему какое-то имя %ВашеИмя% и унаследовать его от класса AutoContext<%ВашеИмя%>. Кроме того, класс нужно пометить атрибутом ContextClassAttribute.

csharp

using System;
using System.IO;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Contexts;

namespace ScriptEngine.Machine.Library
{
	[ContextClass("ЧтениеТекста", "TextReader")]
	class TextReadImpl : AutoContext<TextReadImpl>, IDisposable
	{
		StreamReader _reader;

		[ContextMethod("Открыть", "Open")]
		public void Open(string path, string encoding = null)
		{
			if (encoding == null)
			{
				_reader = Environment.FileOpener.OpenReader(path);
			}
			else
			{
				var enc = Encoding.GetEncoding(encoding);
				_reader = Environment.FileOpener.OpenReader(path, enc);
			}
		}
    }
}

В примере приведен фрагмент класса TextReadImpl, который в языке виден, как ЧтениеТекста. Класс унаследован от AutoContext<TextReadImpl> и помечен атрибутом ContextClassAttribute.

В принципе, этих простых действий достаточно, чтобы ваш класс появился в языке.

Конструкторы класса ​

В приведенном примере класс не имеет конструктора. Экземпляр такого класса нельзя создать через оператор Новый, однако его можно вернуть, как результат какого-либо метода.

Чтобы экземпляры класс могли создаваться через оператор Новый, нашему классу нужно задать конструкторы. Конструктор реализуется в виде статического метода класса, помеченного атрибутом ScriptConstructorAttribute и возвращающего IRuntimeContextInstance.

csharp

    [ScriptConstructor(Name="По имени файла и кодировке")]
    public static IRuntimeContextInstance Constructor(IValue path, IValue encoding)
    {
        var reader = new TextReadImpl();
        reader.Open(path.AsString(), encoding.AsString());
        return reader;
    }

Методы класса ​

Методы класса - это обычные методы-члены класса C#, которые помечены атрибутом ContextMethodAttribute.

Типы параметров автоматически транслируются из типов языка 1С в типы языка C#

csharp

    [ContextMethod("Открыть", "Open")]
	public void Open(string path, string encoding = null)
	{
		if (encoding == null)
		{
			_reader = Environment.FileOpener.OpenReader(path);
		}
		else
		{
			var enc = Encoding.GetEncoding(encoding);
			_reader = Environment.FileOpener.OpenReader(path, enc);
		}
	}

Обратите внимание, параметры заявлены, как string. OneScript самостоятельно транслирует типы значений, передаваемых из скрипта в методы C# и выбрасывает исключения, если типы несовместимы.

Выходные параметры методов ​

Если метод имеет выходной параметр (возвращает значение в параметре), то этот параметр должен иметь тип IVariable и быть помечен атрибутом ByRefAttribute. Т.е. это должно выглядеть примерно так:

csharp

[ContextMethod("Свойство", "Property")]
public bool HasProperty(string name, [ByRef] IVariable value = null)
{
    value.Value = ValueFactory.Create("Это строковое значение, передаваемое в скрипт");
}

Второй параметр value является необязательным и в нем можно вернуть значение обратно в скрипт.

Свойства классов ​

Свойство класса - это обычное свойство класса C#, помеченное атрибутом ContextPropertyAttribute.

csharp
[ContextProperty("Имя","Name")]
public string Name
{
    get
    {
        return "some name";
    }
}

Доступность чтения и записи свойства регулируется двумя способами:

  • Обычная видимость get/set элементов свойства
  • Параметры CanRead/CanWrite атрибута ContextPropertyAttribute

В приведенном примере свойство не содержит части set, поэтому оно будет доступно в скриптах только, как свойство "Для чтения". Если добавить туда часть set, то свойство будет доступно для записи.

OneScript самостоятельно регистрирует в системе доступность свойств и автоматически транслирует типы значений языка 1С в типы C# и обратно.

Итоги ​

Чтобы добавить свой класс в язык, вам нужно:

  1. Создать обычный класс C#
  2. Пометить его атрибутом ContextClass
  3. Унаследовать его от AutoContext<ИмяВашегоКласса>
  4. Пометить нужные свойства класса атрибутом ContextProperty
  5. Пометить нужные методы класса атрибутом ContextMethod
  6. Создать статический метод для конструктора и пометить его атрибутом ScriptConstructor
  7. Все, ваш класс теперь можно использовать в сценариях.

All trademarks, logos, and brand names are the property of their respective owners. Use of these names, trademarks, and brands does not imply endorsement.