extends Node var id_array: Array # Массив id целей var treats : Dictionary # Словарь целей var msg_counter : int = 0 # Счётчик отправленных пакетов var g_table: GridContainer const TableCellType1 = preload('res://ячейка-1.tscn') const TableCellType2 = preload('res://кнопка-3.tscn') const TableCellType3 = preload('res://кнопка-4.tscn') const TableCellType4 = preload('res://заголовок.tscn') const TableCellType5 = preload('res://ячейка-2.tscn') const TableCellType6 = preload('res://кнопка-5.tscn') const TableHeader = preload('res://table/header.tscn') # Индекс колонки: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const TABLE_HEADERS = ['ID Цели', 'Курc.град', 'Частота', 'Ш. диап.', 'Ампл.', 'T обновл.', 'Мод.', 'Реж. см. F', 'Ск. пер.', 'Протокол', 'Ст. дол.', 'Ст. шир.', 'Cт. выс.', 'Тек. дол.', 'Тек. шир.', 'Тек. выс.', ] const TABLE_HEADER_TYPES = [ TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader] const TABLE_HEADER_ALIGNMENTS = [ HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER] const TABLE_ROW_TYPES = [ TableCellType1, TableCellType5, TableCellType5, TableCellType5, TableCellType5, TableCellType5, TableCellType6, TableCellType6, TableCellType5, TableCellType6, TableCellType5, TableCellType5, TableCellType5, TableCellType5, TableCellType5, TableCellType5] const TABLE_ROW_ALIGNMENTS = [ HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER] const TABLE_COLUMN_SIZES = [ 82, 82, 82, 82, 82, 90, 150, 150, 80, 150, 82, 82, 82, 82, 82, 82] const COLUMN_ID = 0 # Идентификатор цели const COLUMN_AOA = 1 # Курсовой угол на источник сигнала, градусы const COLUMN_FREQ = 2 # Частота несущей или центральная частота, МГц const COLUMN_WIDTH = 3 # Ширина занимаемого диапазона частот, МГц const COLUMN_POW = 4 # Уровень принимаемого сигнала, дБ const COLUMN_TICK = 5 # Относительное время обнаружения сигнала, мс. const COLUMN_TMOD = 6 # Вид модуляции const COLUMN_FREQM = 7 # Режим смены частоты. const COLUMN_BAUD = 8 # Скорость передачи данных, бит/с const COLUMN_PROTO = 9 # Тип протокола источника сигнала. const COLUMN_SLON = 10 # Координаты старта, долгота в градусах const COLUMN_SLAT = 11 # Координаты старта, широта в градусах const COLUMN_SALT = 12 # Координаты старта, высота от уровня моря, метры const COLUMN_LAT = 13 # Текущие координаты, долгота в градусах const COLUMN_LON = 14 # Текущие координаты, широта в градусах const COLUMN_ALT = 15 # Текущая высота, метры # Индексы колонок, которым можно задавать выравнивание текста const TABLE_ALLIGNED_COLUMNS = [ COLUMN_ID, COLUMN_AOA, COLUMN_FREQ, COLUMN_WIDTH, COLUMN_POW, COLUMN_TICK, COLUMN_BAUD, COLUMN_SLON, COLUMN_SLAT, COLUMN_SALT, COLUMN_LAT, COLUMN_LON, COLUMN_ALT ] # Индексы колонок, в которых можно вводит текст const TABLE_ENTRY_COLUMNS = [ COLUMN_AOA, COLUMN_FREQ, COLUMN_WIDTH, COLUMN_POW, COLUMN_TICK, COLUMN_BAUD, COLUMN_SLON, COLUMN_SLAT, COLUMN_SALT, COLUMN_LAT, COLUMN_LON, COLUMN_ALT ] # Типы модуляции const MODE_TYPES = ['<неопр.>', 'am', 'ook', 'ask', 'fm', 'qpsk', 'oqpsk', 'pi4qpsk', 'qam16', 'qam32', 'qam64', 'qam128', 'qam256', 'qam512', 'fsk', 'cpfsk', 'psk','ofdm'] # Режим смены частоты const FREQM = ['<неопр.>', 'fhss', 'lfm', 'const'] # Протоколы радиомодема const M_PROTO = ['<неопр.>', '3dlink', 'skyhopperpro', 'picardiooem', 'solo7', 'j11', 'mavlink', 'ltm', 'hc12', 'df1', ] # Номера колонок const COLUMN_OPT = [[COLUMN_TMOD, MODE_TYPES], [COLUMN_FREQM, FREQM], [COLUMN_PROTO, M_PROTO]] const COLUMN_OPT_BTN = [COLUMN_TMOD, COLUMN_FREQM, COLUMN_PROTO] const ID_ARRAY_LEN = 100 # Размер пула номеров целей # Цель class Threat: # параметры цели, второе значение, разрешение отправки. var row: Dictionary = { 'id':[0,true], 'aoa':[10.0,true], 'freq':[2480.0,true], 'width':[20.0,true], 'power':[20.0,true], 'tick':[10,true], 'tmod':['<неопр.>',false], 'freqm':['<неопр.>',false], 'baud':[0.0,false], 'proto':['<неопр.>',false], 'slon':[0.0,false], 'slat':[0.0,false], 'salt':[0.0,false], 'lat':[0.0,false], 'lon':[0.0,false], 'alt':[0.0,false], } var row_id: int func _init(th_id : int, row_i: int): row.id[0] = th_id row_id = row_i func get_data(): var data_to_send : Dictionary for key in row.keys(): var value = row[key] var data = value[0] var need_send = value[1] if need_send: data_to_send[key] = data return data_to_send func update_rows(): var new_rows: Array = [] new_rows.append(_check_value(row.id)) new_rows.append(_check_value(row.aoa)) new_rows.append(_check_value(row.freq)) new_rows.append(_check_value(row.width)) new_rows.append(_check_value(row.power)) new_rows.append(_check_value(row.tick)) new_rows.append(_check_value(row.tmod)) new_rows.append(_check_value(row.freqm)) new_rows.append(_check_value(row.baud)) new_rows.append(_check_value(row.proto)) new_rows.append(_check_value(row.slon)) new_rows.append(_check_value(row.slat)) new_rows.append(_check_value(row.salt)) new_rows.append(_check_value(row.lat)) new_rows.append(_check_value(row.lon)) new_rows.append(_check_value(row.alt)) return new_rows func _check_value(val): if val[1]: return '%s' % val[0] else: return '' func set_aoa(val): var value = float(val) value = Tools.check_low_high(value, 0, 360) value = Tools.check_len(val, value) row.aoa[0] = value row.aoa[1] = Tools.check_empty(value) return value func set_freq(val): var value = float(val) value = Tools.check_negative(value) value = Tools.check_len(val, value) row.freq[0] = value row.freq[1] = Tools.check_empty(value) return value func set_width(val): var value = float(val) value = Tools.check_negative(value) value = Tools.check_len(val, value) row.width[0] = value row.width[1] = Tools.check_empty(value) return value func set_power(val): var value = float(val) value = Tools.check_negative(value) value = Tools.check_len(val, value) row.power[0] = value row.power[1] = Tools.check_empty(value) return value func set_tick(val): var value = int(val) value = Tools.check_low_high(value, 0, 60000) value = Tools.check_len(val, value) row.tick[0] = value row.tick[1] = Tools.check_empty(value) return value func set_baud(val): var value = float(val) value = Tools.check_negative(value) value = Tools.check_len(val, value) row.baud[0] = value row.baud[1] = Tools.check_empty(value) return value func set_slon(val): var value = float(val) value = Tools.check_low_high(value, -90, 90) value = Tools.check_len(val, value) row.slon[0] = value row.slon[1] = Tools.check_empty(value) return value func set_slat(val): var value = float(val) value = Tools.check_low_high(value, -180, 180) value = Tools.check_len(val, value) row.slat[0] = value row.slat[1] = Tools.check_empty(value) return value func set_salt(val): var value = float(val) value = Tools.check_len(val, value) row.salt[0] = value row.salt[1] = Tools.check_empty(value) return value func set_lon(val): var value = float(val) value = Tools.check_low_high(value, -90, 90) value = Tools.check_len(val, value) row.lon[0] = value row.lon[1] = Tools.check_empty(value) return value func set_lat(val): var value = float(val) value = Tools.check_low_high(value, -180, 180) value = Tools.check_len(val, value) row.lat[0] = value row.lat[1] = Tools.check_empty(value) return value func set_alt_pressed(val): var value = float(val) value = Tools.check_len(val, value) row.alt[0] = value row.alt[1] = Tools.check_empty(value) return value func set_tmod(val): var value = str(val) row.tmod[0] = value row.tmod[1] = false if value == '<неопр.>' else true return value func set_freqm(val): var value = str(val) row.freqm[0] = value row.freqm[1] = false if value == '<неопр.>' else true return value func set_proto(val): var value = str(val) row.proto[0] = value row.proto[1] = false if value == '<неопр.>' else true return value func init_treats(table, btn_add, btn_del, btn_save): # Инициализация вкладки с целями for i in range(ID_ARRAY_LEN): # Заполняет массив ID целей id_array.append(i+1) table.set_header(TABLE_HEADER_TYPES) table.set_header_text(TABLE_HEADERS) load_treats(table) init_table(table, TABLE_COLUMN_SIZES) g_table = table table.set_columns_min_size(TABLE_COLUMN_SIZES) table.connect('row_pressed', Callable(self, 'on_row_pressed').bind(table)) table.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, []) table.connect_columns(self, 'item_selected', 'on_item_selected', COLUMN_OPT_BTN, []) btn_add.connect('button_up', Callable(self, 'on_btn_add').bind(table)) btn_del.connect('button_up', Callable(self, 'on_btn_del').bind(table)) btn_save.connect('button_up', Callable(self, 'on_btn_save')) func load_treats(table): var file = FileAccess.open('res://save.json', FileAccess.READ) var read = file.get_as_text() file.close() var json_conv: = JSON.new() if Error.OK == json_conv.parse(read): var json_data = json_conv.get_data() for item in json_data: if item.has('id'): var id = item['id'] id_array.erase(int(id)) var threat : = Threat.new(id, table.get_rows_count()) treats['%d' % id] = threat for key in item: threat.row[key] = [item[key], true] var row = threat.update_rows() table.add_row(TABLE_ROW_TYPES) table.set_row_text(table.get_rows_count()-1, row) table.set_node_user_data(0, table.get_rows_count()-1, threat) init_opt_btns(table.get_rows_count()-1, table, threat) table.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, []) table.connect_columns(self, 'item_selected', 'on_item_selected', COLUMN_OPT_BTN, []) func on_btn_save(): var file = FileAccess.open('res://save.json', FileAccess.WRITE) var data_to_json : Array for key in treats: var treat = treats[key] var data = treat.get_data() data_to_json.append(data) var json = JSON.new().stringify(data_to_json) file.store_string(json) file.close() func init_table(table: Table, sizes: Array): for i_row in table.get_rows_count(): pass func init_opt_btns(row : int, table, threat): for item in COLUMN_OPT: var i: int = 0 var i_col = item[0] var opt_arr = item[1] var cell = table.get_node2(i_col, row) for opt in opt_arr: cell.add_item(opt) if i_col == COLUMN_TMOD: var mode = threat.row['tmod'][0] i = MODE_TYPES.find(mode) if i_col == COLUMN_FREQM: var freqm = threat.row['freqm'][0] i = FREQM.find(freqm) if i_col == COLUMN_PROTO: var proto = threat.row['proto'][0] i = M_PROTO.find(proto) cell.select(i) func on_item_selected(item_num, node): var optbtn_text = node[0].text var indexis = g_table.get_key_indexes(node[0].name) var row_i = indexis[1] var col_i = indexis[0] var cell = g_table.get_node2(0,row_i) var value = set_value(optbtn_text, cell.text, col_i) func on_edit_entry(text : String, entry): var indexis = g_table.get_key_indexes(entry[0].name) var row_i = indexis[1] var col_i = indexis[0] var cell = g_table.get_node2(0,row_i) var value = set_value(text, cell.text, col_i) entry[0].text = str(value) func set_value(val : String, treat_id : String, column : int): var treat = treats[treat_id] match column: COLUMN_AOA: return treat.set_aoa(val) COLUMN_FREQ: return treat.set_freq(val) COLUMN_WIDTH: return treat.set_width(val) COLUMN_POW: return treat.set_power(val) COLUMN_TICK: return treat.set_tick(val) COLUMN_TMOD: return treat.set_tmod(val) COLUMN_FREQM: return treat.set_freqm(val) COLUMN_BAUD: return treat.set_baud(val) COLUMN_PROTO: return treat.set_proto(val) COLUMN_SLON: return treat.set_slon(val) COLUMN_SLAT: return treat.set_slat(val) COLUMN_SALT: return treat.set_salt(val) COLUMN_LAT: return treat.set_lon(val) COLUMN_LON: return treat.set_lat(val) COLUMN_ALT: return treat.set_alt_pressed(val) func on_row_pressed(i_row: int, table): table.clear_rows_selected() table.set_row_selected(i_row, true) func on_btn_add(table): var id = pop_id() var threat : = Threat.new(id, table.get_rows_count()) treats['%d' % id] = threat var row = threat.update_rows() table.add_row(TABLE_ROW_TYPES) table.set_row_text(table.get_rows_count()-1, row) table.set_node_user_data(0, table.get_rows_count()-1, threat) init_opt_btns(table.get_rows_count()-1, table, threat) table.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, []) table.connect_columns(self, 'item_selected', 'on_item_selected', COLUMN_OPT_BTN, []) func on_btn_del(table): var row_i = [] table.get_selected_rows(row_i) if len(row_i) > 0: var cell = table.get_node2(0, row_i[0]) treats.erase(cell.text) table.remove_row(row_i[0]) for i in table.get_rows_count(): var treat = table.get_node_user_data(0, i) treat.row_id = i func pop_id(): var id = 0 if len(id_array): id = id_array[0] id_array.remove_at(0) return id func push_id(id : int): id_array.append(id) func get_threats_data(): var data_to_json : Dictionary data_to_json['ts'] = 5 msg_counter += 1 data_to_json['ss'] = msg_counter data_to_json['msvk'] = [] data_to_json['mis'] = [] for key in treats: var treat = treats[key] set_ticks(treat) var data = treat.get_data() data_to_json['mis'].append(data) var json = JSON.new().stringify(data_to_json) var pac = json.to_utf8_buffer() return pac func set_ticks(treat): var tick = Time.get_ticks_msec() var cell = g_table.get_node2(COLUMN_TICK, treat.row_id) cell.text = str(treat.set_tick(str(tick%60000)))