Created
February 8, 2014 08:48
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
' Gambas class file | |
' GroupUniversalValues | |
' Класс содержащий дополнительные свойства для юнита или части юнита | |
' Содержит пачку дополнительных свойств | |
' Как работать с данным классом | |
' Нужно сначала запросить номер искомого элемента по имени или ID | |
' После проверить не равно ли оно -1 что означает отсутствие этого свойства у объекта | |
' И если всё в порядке то обратиться к массиву Values и извлечь оттуда элемент по нужному номеру | |
Public NameValue As New String[] ' имя параметра | |
Public IDValue As New Integer[] ' числовое значение совпадающее с именем параметра | |
' каждый параметр должен должен обладать своим ID, а так же NameValue и IDValue должны быть синхронизированны | |
Public Values As New Variant[] ' Всё таки я решил хранить значения в типе Variant | |
'4 + 4 + 8 = 16 байт на одно свойство | |
Public Count As Integer ' колличество свойств | |
Public Function FindName(Name As String) As Integer | |
'Возвращает номер значения в массиве по имени, ищет его | |
Dim a As Integer ' счётчик цикла | |
Dim e As Boolean ' флаг досрочного выхода | |
Dim x As Integer ' возвращаемое значение | |
Dim m As Integer | |
m = NameValue.Max | |
x = -1 ' свойство не найдено | |
If Count > 0 Then | |
For a = 0 To m | |
If NameValue[a] = Name Then | |
'нужное имя найдено | |
x = a ' присвоение значения возвращаемой переменной | |
e = True ' запланировать досрочный выход | |
End If | |
If e = True Then Break ' совершить досрочный выход | |
Next | |
End If | |
Return x ' возвратить значение | |
End | |
Public Function FindID(ID As Integer) As Integer | |
'Возвращает номер значения в массиве по ID, ищет его | |
'Поиск по ID быстрее | |
Dim a As Integer ' счётчик цикла | |
Dim e As Boolean ' флаг досрочного выхода | |
Dim x As Integer ' возвращаемое значение | |
Dim m As Integer | |
m = IDValue.Max | |
x = -1 ' свойство не найдено | |
If Count > 0 Then | |
For a = 0 To m | |
If IDValue[a] = ID Then | |
'нужное имя найдено | |
x = a ' присвоение значения возвращаемой переменной | |
e = True ' запланировать досрочный выход | |
End If | |
If e = True Then Break ' совершить досрочный выход | |
Next | |
End If | |
Return x ' возвратить значение | |
End | |
Public Function FindRangeID(MinID As Integer, MaxID As Integer) As Integer | |
' Функция ищет ID в заданном диапазоне. И возвращает индекс первого найденого значения | |
Dim a As Integer ' счётчик цикла | |
Dim e As Boolean ' флаг досрочного выхода | |
Dim x As Integer ' возвращаемое значение | |
Dim m As Integer | |
m = IDValue.Max | |
x = -1 ' свойство не найдено | |
If Count > 0 Then | |
For a = 0 To m | |
If IDValue[a] >= MinID Then | |
'значение больше или равно минимальному | |
If IDValue[a] <= MaxID Then | |
'Значение меньше или равно максимальному | |
x = a ' присвоение значения возвращаемой переменной | |
e = True ' запланировать досрочный выход | |
Endif | |
Endif | |
If e = True Then Break ' совершить досрочный выход | |
Next | |
End If | |
Return x ' возвратить значение | |
End | |
Public Function FindRangeArrayID(MinID As Integer, MaxID As Integer) As Integer[] | |
' Функция ищет ID в заданном диапазоне. И возвращает индексы всех найденых значений | |
Dim a As Integer ' счётчик цикла | |
Dim e As Boolean ' флаг досрочного выхода | |
Dim x As New Integer[] ' возвращаемые значения. Если не будет найдено ни одного, то присвоить нулевому элементу массива значение -1 | |
Dim m As Integer | |
m = IDValue.Max | |
If Count > 0 Then | |
For a = 0 To m | |
If IDValue[a] >= MinID Then | |
'значение больше или равно минимальному | |
If IDValue[a] <= MaxID Then | |
'Значение меньше или равно максимальному | |
x.Add(a) ' Добавление результата в массив | |
'e = True ' запланировать досрочный выход | |
'Планировать выход не надо, так как следует просмотреть все значения в массиве | |
Endif | |
Endif | |
'If e = True Then Break ' совершить досрочный выход | |
Next | |
End If | |
If x.Count = 0 Then | |
'Результата нет | |
x.Add(-1, 0) ' свойство не найдено | |
Endif | |
Return x ' возвратить значение | |
End | |
'Функция добавления значения | |
Public Function AddValueName(Name As String, Value As Variant, Optional ID As Integer = 0) As Integer | |
'добавляет значение по имени, возвращает тот же результат что и FindName, а именно номер значения в массиве Values[] | |
'не проверяет есть ли значение уже в массиве | |
Values.Add(Value) | |
NameValue.Add(Name) | |
IDValue.Add(ID) | |
Count = Count + 1 ' увеличение счётчика | |
Return Count ' возвратить номер добавленного элемента | |
End | |
Public Function AddValueID(ID As Integer, Value As Variant, Optional Name As String = "") As Integer | |
'добавляет значение по ID, возвращает тот же результат что и FindID, а именно номер значения в массиве Values[] | |
'не проверяет есть ли значение уже в массиве | |
Values.Add(Value) | |
NameValue.Add("") | |
IDValue.Add(ID) | |
Count = Count + 1 ' увеличение счётчика | |
Return Count ' возвратить номер добавленного элемента | |
End | |
'Функции редактирования/добавления значения | |
Public Function EditValueName(Name As String, Value As Variant, Optional ID As Integer = 0) As Integer | |
'Изменяет значение по имени или добавляет его если оно отсутствует | |
Dim a As Integer | |
Dim c As Integer | |
Dim v As Integer | |
v = FindName(Name) ' следует оптимизировать методом китайского кода | |
If v = -1 Then | |
'значение не найдено | |
c = AddValueName(Name, Value, ID) ' создать нужное значение | |
Endif | |
If v > -1 Then | |
'значение найдено | |
Values[v] = Value ' присвоить значение | |
c = v | |
Endif | |
Return c ' возвратить номер присвоенного значения | |
End | |
Public Function EditValueID(ID As Integer, Value As Variant, Optional Name As String = "") As Integer | |
'Изменяет значение по ID или добавляет его если оно отсутствует | |
Dim a As Integer | |
Dim c As Integer | |
Dim v As Integer | |
v = FindID(ID) ' следует оптимизировать методом китайского кода | |
If v = -1 Then | |
'значение не найдено | |
c = AddValueID(ID, Value, Name) ' создать нужное значение | |
Endif | |
If v > -1 Then | |
'значение найдено | |
Values[v] = Value ' присвоить значение | |
c = v | |
Endif | |
Return c ' возвратить номер присвоенного значения | |
End | |
Public Sub _new() | |
'при создании объекта необходимо записать балластное свойство | |
Dim v As Variant | |
Values.Add(v, 0) | |
NameValue.Add("", 0) | |
IDValue.Add(0, 0) | |
Count = 0 ' установка счётчика в 0 | |
End | |
' Функции возвращающие нужные значения сразу. Будут оптимизированы методом китайского кода | |
Public Function GetValueName(Name As String, Optional DefaultValue As Variant = Null) As Variant | |
Dim rv As Variant | |
Dim nv As Integer | |
nv = FindName(Name) | |
If nv <> -1 Then | |
rv = Values[nv] | |
Endif | |
Return rv | |
End | |
Public Function GetValueID(ID As Integer, Optional DefaultValue As Variant = Null) As Variant | |
Dim rv As Variant | |
Dim nv As Integer | |
rv = DefaultValue | |
nv = FindID(ID) | |
If nv <> -1 Then | |
rv = Values[nv] | |
Endif | |
Return rv | |
End | |
Public Function SaveClass() As String[] | |
'Функция возвращает массив строк содержащий все значения сохранённые в классе | |
Dim Srm As New String[] ' массив для результата | |
Dim r As String ' результат 1 строка | |
Dim a As Integer ' счётчик цикла | |
Dim m As Integer ' мксимальное значение цикла | |
Dim TypeGameObjectDataClass As Integer ' тип переменной | |
Dim t As New GameObjectDataClass ' пустая переменная для определения типа | |
'переменные для сохранения вложенных значений GameObjectDataClass | |
Dim godcStrings As New String[] 'массив для временного хранения строк | |
Dim godcA As Integer ' счётчик цикла для перебора массива | |
Dim godcM As Integer ' конец счётчика | |
Dim godcLink As GameObjectDataClass ' переменная ссылка для ускорения опраций с объектом | |
TypeGameObjectDataClass = TypeOf(t) ' тип контейнера для сложных свойств-объектов с более чем одним параметров | |
m = Values.Max | |
Srm.Add("begin universal-values") | |
For a = 0 To m | |
'перебор всех значений | |
Srm.Add("name=" & NameValue[a]) | |
Srm.Add("id=" & Str(IDValue[a])) | |
If TypeOf(Values[a]) = gb.Integer Then | |
'значение integer | |
Srm.Add("value-integer=" & Str(Values[a])) | |
Endif | |
If TypeOf(Values[a]) = gb.Single Then | |
'значение Single | |
Srm.Add("value-single=" & Str(Values[a])) | |
Endif | |
If TypeOf(Values[a]) = gb.Float Then | |
'значение float | |
Srm.Add("value-float=" & Str(Values[a])) | |
Endif | |
If TypeOf(Values[a]) = gb.String Then | |
'значение строка | |
Srm.Add("value-string=" & Values[a]) | |
Endif | |
If TypeOf(Values[a]) = TypeGameObjectDataClass Then | |
'комплексное значение GameObjectDataClass | |
'здесь надо будет сохранено куча строк | |
Srm.Add("value-godc=") ' GameObjectDataClass | |
godcStrings.Clear ' очистка массива | |
godcLink = Null ' обнудение переменной ссылки | |
godcLink = Values[a] ' присвоение ссылки, в дальнейшем использовать для операций эту ссылку | |
godcStrings = godcLink.SaveClass() ' сохранение класса в массив | |
' а теперь надо перебрать массив и сохранить его строки в массиве Srm этого класса | |
godcM = godcStrings.Max ' узнать индекс последнего элемента в массиве | |
For godcA = 0 To godcM | |
'собственно перебор | |
Srm.Add(godcStrings[godcA]) ' добавить в Srm массив значение из возвращённого массива | |
Next | |
Endif | |
Srm.Add("next value") | |
Next | |
Srm.Add("end universal-values") | |
Return Srm | |
End | |
Public Sub LoadClass(DataArray As String[]) | |
' Функция загружает в класс необходимые значения | |
' Она будет сложнее чем GameObjectDataClass ибо ей нужно фильтровать много типов значений | |
' Надо бы придумать формат | |
' | |
' Формат: | |
' name=Ox | |
' id=150 | |
' value-integer=10 | |
' next value | |
' name=axe | |
' id=1 | |
' value-godc | |
' begin game-object-data | |
' данные GameObjectDataClass | |
' end game-object-data | |
' end universal-values | |
Dim a As Integer 'счётчик цикла | |
Dim m As Integer 'ограничитель цикла | |
Dim Name As String ' имя | |
Dim ID As Integer ' ID | |
Dim sdata As New ClassStringData ' класс для операций разложения строк | |
Dim OP As String | |
Dim Value As String ' переменные для кэширования значений операций разложения строки | |
Dim r As Integer ' временная переменная | |
Dim DataValue As Variant ' значение | |
Dim ValueInteger As Integer | |
Dim ValueSingle As Single | |
Dim ValueFloat As Float | |
Dim ValueString As String | |
Dim ValueGODC As GameObjectDataClass ' значения конкретных типов. Создание и инициализация объекта проходит внутри тела процедуры | |
Dim Srm As New String[] ' текстовый массив для вложенных сложных типов | |
Count = 0 | |
NameValue.Clear | |
IDValue.Clear | |
Values.Clear ' очистка объекта от старых данных | |
'_new ' нициализация объекта заново и создание балластного значения под индексом 0 | |
' Это вызов не нужен так как приводит при каждой загрузке/сохранении к дублированию элемента 0 | |
' поэтому следует заранее установить счётчик в отметку -1 | |
Count = -1 ' В данном случае расчёт идёт на то что сначала элементы добавляються в массив, а потом увеличивается на 1 | |
' счётчик Count То есть при доблении 1го элемента, он будет иметь индекс 0 . Это то самое балластное значение в массиве | |
' Не следует использовать кэшированные значения индексов после перезагрузки классов. | |
' Это нужно потому что в дальнейшем внутреняя нумерация может быть изменена | |
m = DataArray.Max ' установление ограничителя цикла | |
For a = 0 To m | |
'перебор строк | |
OP = sdata.GetOpS(DataArray[a]) | |
Value = sdata.GetValueS(DataArray[a]) ' разложение строки на оператор и параметр | |
If OP = "name" Then | |
'присвоение имени | |
Name = Value | |
Endif | |
If OP = "id" Then | |
'присвоение ID | |
ID = Val(Value) | |
Endif | |
If OP = "value-integer" Then | |
'целое число | |
ValueInteger = Val(Value) ' присвоение и преобразование в нужный тип средствами runtime среды | |
DataValue = ValueInteger ' присовение преобразованного значения переменной variant | |
Endif | |
If OP = "value-single" Then | |
'дробное число | |
ValueSingle = Val(Value) ' присвоение и преобразование в нужный тип средствами runtime среды | |
DataValue = ValueSingle ' присовение преобразованного значения переменной variant | |
Endif | |
If OP = "value-float" Then | |
'float | |
ValueFloat = Val(Value) ' присвоение и преобразование в нужный тип средствами runtime среды | |
DataValue = ValueFloat ' присовение преобразованного значения переменной variant | |
Endif | |
If OP = "value-string" Then | |
'строка | |
ValueString = Value ' присвоение и преобразование в нужный тип средствами runtime среды | |
DataValue = ValueString ' присовение преобразованного значения переменной variant | |
Endif | |
If OP = "value-godc" Then | |
' вложенный сложный объект | |
' Тут то придёться подумать как правильно это написать | |
ValueGODC = New GameObjectDataClass ' создание нового сложного объекта | |
Srm.Clear | |
Do | |
'цикл перебора строк | |
a = a + 1 ' увеличение счётчика вышестоящего цикла FOR | |
OP = sdata.GetOpS(DataArray[a]) ' вычленение оператора | |
Srm.Add(DataArray[a]) ' копирование строки во временный массив | |
Loop Until OP = "end game-object-data" ' окончание описания сложного объекта | |
' Строки относящиеся к вложенному объекту скопированны в массив Srm | |
' Счётчик (a) тоже скорректирован что бы не просматривать строки относящиеся к вложенному объекту ещё раз | |
ValueGODC.LoadClass(Srm) ' обработка строк вложенным сложным объектом и загрузка в него данных | |
DataValue = ValueGODC ' присвоение ссылки переменной типа Variant, промежуточной | |
ValueGODC = Null ' очистка первичной ссылки на загруженный сложный объект | |
Endif | |
If OP = "next value" Then | |
'следующее значение, присвоить | |
r = AddValueID(ID, DataValue, Name) ' здесь мы добавляем новое значение и кэшируем его позицию в списке для быстрого использования | |
' использеться функция AddValueID которая не проверяет есть ли уже объект в массиве | |
DataValue = Null ' обнуление используемых переменных | |
ID = 0 | |
Name = "" | |
Endif | |
Next | |
End |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment