NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

custom_graph.py (29284B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\nodegraph\client\custom_graph.py
      2 from __future__ import print_function
      3 import datetime
      4 import blue
      5 import logging
      6 import uuid
      7 import yaml
      8 from carbonui import uiconst
      9 from copy import deepcopy
     10 from nodegraph.common.atomdata import get_atom_data, get_atom_input_parameter_dict, get_event_atoms, get_action_atoms, get_condition_atoms, get_getter_atoms
     11 from nodegraph.common.nodedata import get_node_type, get_node_input_parameter_dict, get_node_types, get_node_graph_data
     12 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     13 from utillib import KeyVal
     14 try:
     15     import nodegraph.tools as tools
     16 except ImportError:
     17     tools = None
     18 
     19 logger = logging.getLogger(__name__)
     20 
     21 def get_custom_node_graphs():
     22     return settings.user.ui.Get('custom_node_graphs', {})
     23 
     24 
     25 def get_custom_node_graph(node_graph_id, as_object = False):
     26     nodes_data = deepcopy(get_custom_node_graphs().get(node_graph_id, None))
     27     if as_object and nodes_data:
     28         for node_id in nodes_data:
     29             nodes_data[node_id] = KeyVal(nodes_data[node_id])
     30             for parameter_id in nodes_data[node_id].nodeParameters:
     31                 value = nodes_data[node_id].nodeParameters[parameter_id].get('value', None)
     32                 connection = nodes_data[node_id].nodeParameters[parameter_id].get('connection', None)
     33                 if connection:
     34                     connection = KeyVal(connection)
     35                 nodes_data[node_id].nodeParameters[parameter_id] = KeyVal(value=value, connection=connection)
     36 
     37             if 'atom_id' in nodes_data[node_id].nodeParameters:
     38                 if 'atomParameters' not in nodes_data[node_id]:
     39                     nodes_data[node_id]['atomParameters'] = {}
     40                 for parameter_id in nodes_data[node_id].atomParameters:
     41                     value = nodes_data[node_id].atomParameters[parameter_id].get('value', None)
     42                     connection = nodes_data[node_id].atomParameters[parameter_id].get('connection', None)
     43                     if connection:
     44                         connection = KeyVal(connection)
     45                     nodes_data[node_id].atomParameters[parameter_id] = KeyVal(value=value, connection=connection)
     46 
     47     return nodes_data
     48 
     49 
     50 def get_custom_node_graph_authored_id(node_graph_id):
     51     try:
     52         return int(node_graph_id.split('_')[1])
     53     except:
     54         return None
     55 
     56 
     57 def save_custom_node_graphs(data):
     58     settings.user.ui.Set('custom_node_graphs', data)
     59     sm.GetService('settings').SaveSettings(async=False)
     60 
     61 
     62 def create_new_custom_node_graph(node_graph_id = None, nodes_data = None):
     63     new_node_graph_id = 'custom_{}'.format(node_graph_id or datetime.datetime.now().isoformat())
     64     custom_node_graphs = get_custom_node_graphs()
     65     if new_node_graph_id in custom_node_graphs:
     66         return new_node_graph_id
     67     custom_node_graphs[new_node_graph_id] = nodes_data or {}
     68     save_custom_node_graphs(custom_node_graphs)
     69     return new_node_graph_id
     70 
     71 
     72 def delete_all_custom_node_graphs():
     73     save_custom_node_graphs({})
     74 
     75 
     76 def delete_custom_node_graph(node_graph_id, show_prompt = True):
     77     if show_prompt:
     78         response = prompt_player_fsd_dialog('CustomQuestion', {'header': 'Delete',
     79          'question': 'Are you sure you want to delete the node graph?'}, buttons=uiconst.YESNO)
     80         if response != uiconst.ID_YES:
     81             return
     82     custom_node_graphs = get_custom_node_graphs()
     83     if node_graph_id not in custom_node_graphs:
     84         print("Custom node graph doesn't exists", node_graph_id)
     85         return
     86     custom_node_graphs.pop(node_graph_id, None)
     87     save_custom_node_graphs(custom_node_graphs)
     88 
     89 
     90 def copy_graph_to_clipboard(node_graph_id, node_ids = None):
     91     data = get_custom_node_graph(node_graph_id)
     92     if node_ids:
     93         data = {node_id:node_data for node_id, node_data in data.iteritems() if node_id in node_ids}
     94     blue.pyos.SetClipboardData(yaml.safe_dump(convert_to_fsd_nodes(data), default_flow_style=False, allow_unicode=True, indent=4))
     95 
     96 
     97 def save_all_custom_fsd_graphs():
     98     graphs = get_custom_node_graphs()
     99     for graph_id, nodes_data in graphs.iteritems():
    100         authored_id = get_custom_node_graph_authored_id(graph_id)
    101         if not authored_id:
    102             continue
    103         save_fsd_node_graph(authored_id, nodes_data)
    104 
    105 
    106 def save_fsd_node_graph(node_graph_id, nodes_data):
    107     data = tools.load_node_graph_yaml(node_graph_id)
    108     data['nodes'] = convert_to_fsd_nodes(nodes_data)
    109     tools.save_node_graph_yaml(node_graph_id, data)
    110 
    111 
    112 def convert_to_fsd_nodes(dict_nodes):
    113     fsd_nodes = {}
    114     for node_id in dict_nodes:
    115         fsd_nodes[node_id] = dict_nodes[node_id]
    116         if 'comment' in fsd_nodes[node_id] and not fsd_nodes[node_id]['comment']:
    117             del fsd_nodes[node_id]['comment']
    118         if 'atom_id' in fsd_nodes[node_id]['nodeParameters'] and 'atomParameters' in fsd_nodes[node_id]:
    119             atom_type_parameters = get_atom_input_parameter_dict(fsd_nodes[node_id]['nodeParameters']['atom_id']['value'])
    120             for parameter_id in fsd_nodes[node_id]['atomParameters'].keys():
    121                 if parameter_id not in atom_type_parameters:
    122                     logger.error('Invalid atom parameter %s in node %s - removing', parameter_id, node_id)
    123                     del fsd_nodes[node_id]['atomParameters'][parameter_id]
    124                     continue
    125                 parameter = atom_type_parameters[parameter_id]
    126                 parameter_data = fsd_nodes[node_id]['atomParameters'][parameter_id]
    127                 if 'connection' in parameter_data:
    128                     value = {'connection': parameter_data['connection']}
    129                 else:
    130                     value = parameter_data['value']
    131                     if parameter.parameterType == 'boolType':
    132                         value = bool(value)
    133                     elif parameter.parameterType == 'boolListType':
    134                         value = [ bool(i) for i in value ]
    135                     value = {'value': {'unionType': parameter.parameterType,
    136                                'unionValue': value}}
    137                 fsd_nodes[node_id]['atomParameters'][parameter_id] = value
    138 
    139             if not fsd_nodes[node_id]['atomParameters']:
    140                 del fsd_nodes[node_id]['atomParameters']
    141         node_type_parameters = get_node_input_parameter_dict(fsd_nodes[node_id]['nodeType'])
    142         for parameter_id in fsd_nodes[node_id]['nodeParameters'].keys():
    143             if parameter_id not in node_type_parameters:
    144                 logger.error('Invalid node parameter %s in node %s - removing', parameter_id, node_id)
    145                 del fsd_nodes[node_id]['nodeParameters'][parameter_id]
    146                 continue
    147             parameter = node_type_parameters[parameter_id]
    148             parameter_data = fsd_nodes[node_id]['nodeParameters'][parameter_id]
    149             if 'connection' in parameter_data:
    150                 value = {'connection': parameter_data['connection']}
    151             else:
    152                 value = parameter_data['value']
    153                 if parameter.parameterType == 'boolType':
    154                     value = bool(value)
    155                 elif parameter.parameterType == 'boolListType':
    156                     value = [ bool(i) for i in value ]
    157                 value = {'value': {'unionType': parameter.parameterType,
    158                            'unionValue': value}}
    159             fsd_nodes[node_id]['nodeParameters'][parameter_id] = value
    160 
    161     return fsd_nodes
    162 
    163 
    164 def get_yaml_nodes_as_dict(node_graph_id):
    165     nodes_data = tools.load_node_graph_yaml(node_graph_id)['nodes']
    166     if not nodes_data:
    167         return {}
    168     result = nodes_data
    169     for node_id, node in nodes_data.iteritems():
    170         result[node_id] = {'nodeType': node['nodeType'],
    171          'nodeParameters': node['nodeParameters'],
    172          'atomParameters': node.get('atomParameters', {}),
    173          'connections': node['connections'],
    174          'position': node['position'],
    175          'comment': node.get('comment', None)}
    176         node_type = get_node_type(node['nodeType'])
    177         for parameter in node_type.parameters.inputs:
    178             if parameter.parameterKey not in result[node_id]['nodeParameters']:
    179                 continue
    180             param = result[node_id]['nodeParameters'][parameter.parameterKey]
    181             if 'connection' in param:
    182                 result[node_id]['nodeParameters'][parameter.parameterKey]['connection'] = param['connection']
    183             elif 'value' in param:
    184                 result[node_id]['nodeParameters'][parameter.parameterKey]['value'] = param['value']['unionValue']
    185             else:
    186                 result[node_id]['nodeParameters'][parameter.parameterKey]['value'] = param
    187 
    188         if 'atom_id' in result[node_id]['nodeParameters']:
    189             atom_id = result[node_id]['nodeParameters']['atom_id']
    190             if not isinstance(atom_id, int):
    191                 atom_id = atom_id['value']
    192             atom_type = get_atom_data(atom_id)
    193             for parameter in atom_type.parameters.inputs:
    194                 if parameter.parameterKey not in result[node_id]['atomParameters']:
    195                     continue
    196                 param = result[node_id]['atomParameters'][parameter.parameterKey]
    197                 if 'connection' in param:
    198                     result[node_id]['atomParameters'][parameter.parameterKey]['connection'] = param['connection']
    199                 elif 'value' in param:
    200                     result[node_id]['atomParameters'][parameter.parameterKey]['value'] = param['value']['unionValue']
    201                 else:
    202                     result[node_id]['atomParameters'][parameter.parameterKey]['value'] = param
    203 
    204     return result
    205 
    206 
    207 def get_built_nodes_as_dict(node_graph_id):
    208     nodes_data = get_node_graph_data(node_graph_id).nodes
    209     if not nodes_data:
    210         return {}
    211     result = {}
    212     for node_id, node in nodes_data.iteritems():
    213         result[node_id] = KeyVal(nodeType=node.nodeType, nodeParameters=dict(node.nodeParameters), connections={}, position=list(node.position), comment=node.comment)
    214         node_type = get_node_type(node.nodeType)
    215         for parameter in node_type.parameters.inputs:
    216             if parameter.parameterKey not in result[node_id]['nodeParameters']:
    217                 continue
    218             param = result[node_id]['nodeParameters'][parameter.parameterKey]
    219             if getattr(param, 'connection', None):
    220                 connection = getattr(param, 'connection')
    221                 update_parameter_connection(result[node_id], parameter.parameterKey, connection.node, connection.parameter)
    222             elif getattr(param, 'value', None) is not None:
    223                 update_parameter(result[node_id], parameter.parameterKey, getattr(param, 'value'))
    224             else:
    225                 update_parameter(result[node_id], parameter.parameterKey, param)
    226 
    227         if 'atom_id' in result[node_id]['nodeParameters']:
    228             result[node_id]['atomParameters'] = dict(node.atomParameters or {})
    229             atom_id = result[node_id]['nodeParameters']['atom_id']
    230             if not isinstance(atom_id, int):
    231                 atom_id = atom_id['value']
    232             atom_type = get_atom_data(atom_id)
    233             for parameter in atom_type.parameters.inputs:
    234                 if parameter.parameterKey not in result[node_id]['atomParameters']:
    235                     continue
    236                 param = result[node_id]['atomParameters'][parameter.parameterKey]
    237                 if getattr(param, 'connection', None):
    238                     connection = getattr(param, 'connection')
    239                     update_parameter_connection(result[node_id], parameter.parameterKey, connection.node, connection.parameter)
    240                 elif getattr(param, 'value', None) is not None:
    241                     update_parameter(result[node_id], parameter.parameterKey, getattr(param, 'value'))
    242                 else:
    243                     update_parameter(result[node_id], parameter.parameterKey, param)
    244 
    245         for connection_id in node.connections:
    246             result[node_id]['connections'][connection_id] = list(node.connections[connection_id])
    247 
    248     result = convert_to_dict_nodes(result)
    249     return result
    250 
    251 
    252 def convert_to_dict_nodes(nodes_data):
    253     result = {}
    254     for node_id in nodes_data:
    255         result[node_id] = nodes_data[node_id].__dict__
    256         for parameter_id, parameter in nodes_data[node_id]['nodeParameters'].items():
    257             data = {}
    258             if parameter.connection:
    259                 data['connection'] = parameter.connection.__dict__
    260             else:
    261                 data['value'] = parameter.value
    262             result[node_id]['nodeParameters'][parameter_id] = data
    263 
    264         for parameter_id, parameter in nodes_data[node_id].get('atomParameters', {}).items():
    265             data = {}
    266             if parameter.connection:
    267                 data['connection'] = parameter.connection.__dict__
    268             else:
    269                 data['value'] = parameter.value
    270             result[node_id]['atomParameters'][parameter_id] = data
    271 
    272     return result
    273 
    274 
    275 def convert_from_clipboard(nodes_data, position):
    276     import sys
    277     result = {}
    278     new_id_map = {}
    279     min_x = sys.maxint
    280     min_y = sys.maxint
    281     for node_id, node_data in nodes_data.iteritems():
    282         new_node_id = str(uuid.uuid4())
    283         new_id_map[node_id] = new_node_id
    284         result[new_node_id] = KeyVal(node_data)
    285         min_x = min(min_x, result[new_node_id]['position'][0])
    286         min_y = min(min_y, result[new_node_id]['position'][1])
    287 
    288     for node_id, node_data in result.iteritems():
    289         if 'comment' not in node_data:
    290             node_data['comment'] = ''
    291         node_data['position'] = (result[node_id]['position'][0] - min_x + position[0], result[node_id]['position'][1] - min_y + position[1])
    292         new_connections = {}
    293         for connection_id in node_data['connections']:
    294             new_connections[connection_id] = []
    295             for connected_node_id in node_data['connections'][connection_id]:
    296                 if connected_node_id not in nodes_data:
    297                     continue
    298                 new_connections[connection_id].append(new_id_map[connected_node_id])
    299 
    300         node_data['connections'] = new_connections
    301         for parameter_id, parameter in node_data['nodeParameters'].items():
    302             if 'value' in parameter:
    303                 node_data['nodeParameters'][parameter_id] = KeyVal(value=parameter['value']['unionValue'], connection=None)
    304             elif parameter['connection']['node'] in nodes_data:
    305                 node_data['nodeParameters'][parameter_id] = KeyVal(value=None, connection=KeyVal(node=new_id_map[parameter['connection']['node']], parameter=parameter['connection']['parameter']))
    306             else:
    307                 node_data['nodeParameters'].pop(parameter_id, None)
    308 
    309         for parameter_id, parameter in node_data.get('atomParameters', {}).items():
    310             if 'value' in parameter:
    311                 node_data['atomParameters'][parameter_id] = KeyVal(value=parameter['value']['unionValue'], connection=None)
    312             elif parameter['connection']['node'] in nodes_data:
    313                 node_data['atomParameters'][parameter_id] = KeyVal(value=None, connection=KeyVal(node=new_id_map[parameter['connection']['node']], parameter=parameter['connection']['parameter']))
    314             else:
    315                 node_data['atomParameters'].pop(parameter_id, None)
    316 
    317     return result
    318 
    319 
    320 def customize_all_fsd_graphs(fix = False):
    321     from nodegraph.common.nodedata import get_node_graphs
    322     custom_graphs = get_custom_node_graphs()
    323     fsd_graphs = get_node_graphs()
    324     for node_graph_id in fsd_graphs:
    325         custom_id = 'custom_{}'.format(node_graph_id)
    326         if custom_id in custom_graphs:
    327             continue
    328         nodes_data = get_yaml_nodes_as_dict(node_graph_id)
    329         if fix:
    330             nodes_data = fix_custom_graph(node_graph_id, nodes_data)
    331         create_new_custom_node_graph(node_graph_id, nodes_data)
    332 
    333 
    334 def customize_fsd_graph(node_graph_id, fix = False):
    335     nodes_data = get_yaml_nodes_as_dict(node_graph_id)
    336     if fix:
    337         nodes_data = fix_custom_graph(node_graph_id, nodes_data)
    338     return create_new_custom_node_graph(node_graph_id, nodes_data)
    339 
    340 
    341 def fix_custom_graphs():
    342     graphs = get_custom_node_graphs()
    343     for graph_id in graphs:
    344         graphs[graph_id] = fix_custom_graph(graph_id, graphs[graph_id])
    345 
    346 
    347 def fix_custom_graph(node_graph_id, nodes_data):
    348     fixed_graph_nodes = {}
    349     with_output_variables = set()
    350     node_id_map = {}
    351 
    352     def get_new_node_id(node_id):
    353         if node_id not in node_id_map:
    354             if not isinstance(node_id, str):
    355                 node_id_map[node_id] = str(uuid.uuid4())
    356             else:
    357                 node_id_map[node_id] = node_id
    358         return node_id_map[node_id]
    359 
    360     for node_id in nodes_data:
    361         node = nodes_data[node_id]
    362         if node['nodeType'] == 29:
    363             continue
    364         fixed_node = {'nodeType': node['nodeType'],
    365          'position': node['position'],
    366          'connections': {},
    367          'nodeParameters': node['nodeParameters'],
    368          'comment': node.get('comment', '')}
    369         if 'atomParameters' in node:
    370             fixed_node['atomParameters'] = node['atomParameters']
    371         comment = node.get('notes', node.get('comment', ''))
    372         if comment:
    373             fixed_node['comment'] = comment
    374         for parameter_id in fixed_node['nodeParameters']:
    375             try:
    376                 if not isinstance(fixed_node['nodeParameters'][parameter_id], basestring) and ('value' in fixed_node['nodeParameters'][parameter_id] or 'connection' in fixed_node['nodeParameters'][parameter_id]):
    377                     continue
    378             except:
    379                 pass
    380 
    381             fixed_node['nodeParameters'][parameter_id] = {'value': fixed_node['nodeParameters'][parameter_id]}
    382 
    383         if 'atomParameters' in fixed_node:
    384             for parameter_id in fixed_node['atomParameters']:
    385                 try:
    386                     if not isinstance(fixed_node['atomParameters'][parameter_id], basestring) and ('value' in fixed_node['atomParameters'][parameter_id] or 'connection' in fixed_node['atomParameters'][parameter_id]):
    387                         continue
    388                 except:
    389                     pass
    390 
    391                 fixed_node['atomParameters'][parameter_id] = {'value': fixed_node['atomParameters'][parameter_id]}
    392 
    393         for connection_id in node['connections']:
    394             if connection_id == 'variables':
    395                 if node['connections'].get(connection_id, []):
    396                     with_output_variables.add(node_id)
    397             else:
    398                 fixed_node['connections'][connection_id] = [ get_new_node_id(connected_node_id) for connected_node_id in node['connections'].get(connection_id, []) ]
    399 
    400         fixed_graph_nodes[get_new_node_id(node_id)] = fixed_node
    401 
    402     for node_id in with_output_variables:
    403         node = nodes_data[node_id]
    404         new_node_id = get_new_node_id(node_id)
    405         for connected_node_id in node['connections']['variables']:
    406             connected_node = nodes_data[connected_node_id]
    407             if connected_node['nodeType'] == 29:
    408                 for map_id in connected_node['connections']['variables']:
    409                     map_node = fixed_graph_nodes[get_new_node_id(map_id)]
    410                     parameter_id = connected_node['nodeParameters']['output_key']
    411                     connection_parameter_id = connected_node['nodeParameters']['input_key']
    412                     if map_node['nodeType'] == 19:
    413                         parameter_id = 'blackboard_value'
    414                     if node['nodeType'] == 18:
    415                         connection_parameter_id = 'blackboard_value'
    416                     update_parameter_connection(map_node, parameter_id, new_node_id, connection_parameter_id)
    417 
    418             elif connected_node['nodeType'] == 19:
    419                 if connected_node['nodeParameters'].get('input_key', ''):
    420                     map_node = fixed_graph_nodes[get_new_node_id(connected_node_id)]
    421                     update_parameter_connection(map_node, 'blackboard_value', new_node_id, connected_node['nodeParameters']['input_key']['value'])
    422                     connected_node['nodeParameters'].pop('input_key', None)
    423             elif node['nodeType'] != 18:
    424                 print('*********** warning', node_graph_id, node_id, connected_node_id)
    425             if node['nodeType'] == 18:
    426                 output_key = node['nodeParameters'].get('output_key', None)
    427                 if not output_key:
    428                     continue
    429                 for connected_node_id in node['connections']['variables']:
    430                     if nodes_data[connected_node_id]['nodeType'] == 29:
    431                         continue
    432                     try:
    433                         map_node = fixed_graph_nodes[get_new_node_id(connected_node_id)]
    434                         update_parameter_connection(map_node, output_key['value'], new_node_id, 'blackboard_value')
    435                     except:
    436                         print('NOT FIXED???', node_graph_id, node_id, connected_node_id)
    437 
    438         if node['nodeType'] == 18:
    439             node['nodeParameters'].pop('output_key', None)
    440 
    441     for node_id in fixed_graph_nodes:
    442         if fixed_graph_nodes[node_id]['nodeType'] == 19:
    443             fixed_graph_nodes[node_id]['nodeParameters'].pop('input_key', None)
    444         elif fixed_graph_nodes[node_id]['nodeType'] == 18:
    445             fixed_graph_nodes[node_id]['nodeParameters'].pop('output_key', None)
    446 
    447     return fixed_graph_nodes
    448 
    449 
    450 def update_parameter(node_data, parameter_id, value):
    451     parameter, parameter_group = _get_parameter_and_group(node_data, parameter_id)
    452     if not parameter:
    453         return
    454     default_value = parameter.defaultValue
    455     if value is None:
    456         if default_value is None:
    457             node_data[parameter_group].pop(parameter_id, None)
    458             return
    459         value = default_value
    460     if default_value is None and value is not None:
    461         if parameter.parameterType.endswith('ListType'):
    462             default_value = []
    463         else:
    464             default_value = type(value)()
    465     if value == default_value:
    466         node_data[parameter_group].pop(parameter_id, None)
    467         return
    468     if parameter.parameterType == 'boolType':
    469         value = bool(value)
    470     elif parameter.parameterType == 'boolListType':
    471         value = [ bool(i) for i in value ]
    472     elif parameter.parameterType.endswith('ListType') or parameter.parameterType == 'vector3Type':
    473         value = list(value)
    474     if parameter_group not in node_data:
    475         node_data[parameter_group] = {}
    476     node_data[parameter_group][parameter_id] = KeyVal(value=value, connection=None)
    477 
    478 
    479 def update_parameter_connection(node_data, parameter_id, connection_node_id, connection_parameter_id):
    480     parameter, parameter_group = _get_parameter_and_group(node_data, parameter_id)
    481     if not parameter:
    482         return
    483     if connection_node_id and connection_parameter_id:
    484         if parameter_group not in node_data:
    485             node_data[parameter_group] = {}
    486         node_data[parameter_group][parameter_id] = KeyVal(value=None, connection=KeyVal(node=connection_node_id, parameter=connection_parameter_id))
    487     elif parameter_group in node_data:
    488         node_data[parameter_group].pop(parameter_id, None)
    489 
    490 
    491 def _get_parameter_and_group(node_data, parameter_id):
    492     parameter = None
    493     parameter_group = None
    494     node_type_parameters = get_node_input_parameter_dict(node_data['nodeType'])
    495     if parameter_id in node_type_parameters:
    496         parameter = node_type_parameters[parameter_id]
    497         parameter_group = 'nodeParameters'
    498     else:
    499         atom_parameter = node_data['nodeParameters'].get('atom_id', None)
    500         if atom_parameter:
    501             atom_type_parameters = get_atom_input_parameter_dict(atom_parameter['value'])
    502             if parameter_id in atom_type_parameters:
    503                 parameter = atom_type_parameters[parameter_id]
    504                 parameter_group = 'atomParameters'
    505     return (parameter, parameter_group)
    506 
    507 
    508 def _get_atom_id_from_old(atom_id):
    509     from nodegraph.client.actions import get_atom_action_class
    510     from nodegraph.client.conditions import get_atom_condition_class
    511     from nodegraph.client.events import get_atom_event_class
    512     atom_class = get_atom_action_class(atom_id)
    513     if atom_class:
    514         return atom_class.atom_id
    515     atom_class = get_atom_condition_class(atom_id)
    516     if atom_class:
    517         return atom_class.atom_id
    518     atom_class = get_atom_event_class(atom_id)
    519     if atom_class:
    520         return atom_class.atom_id
    521     return atom_id
    522 
    523 
    524 def get_new_node_data(node_type_id, position, atom_type_id = None):
    525     from nodegraph.client.actions import get_atom_action_class
    526     node_data = KeyVal(nodeType=node_type_id, position=position, nodeParameters={}, comment=None)
    527     node_type = get_node_type(node_type_id)
    528     node_data['connections'] = {connection_id:[] for connection_id in node_type.ports.outPorts}
    529     if atom_type_id:
    530         action_class = get_atom_action_class(atom_type_id)
    531         if action_class is not None:
    532             track_action = getattr(action_class, 'track_action', False)
    533             node_data['nodeParameters']['track_action'] = KeyVal(value=track_action, connection=None)
    534         node_data['nodeParameters']['atom_id'] = KeyVal(value=atom_type_id, connection=None)
    535         node_data['atomParameters'] = {}
    536     return node_data
    537 
    538 
    539 def multiply_spacing(x = 1, y = 1):
    540     graphs = get_custom_node_graphs()
    541     for graph_id, nodes_data in graphs.iteritems():
    542         for node_id in nodes_data:
    543             position = nodes_data[node_id]['position']
    544             nodes_data[node_id]['position'] = [position[0] * x, position[1] * y]
    545 
    546     save_custom_node_graphs(graphs)
    547 
    548 
    549 def create_graph_with_all_client_nodes():
    550     create_graph_with_all_nodes('client')
    551 
    552 
    553 def create_graph_with_all_server_nodes():
    554     create_graph_with_all_nodes('server')
    555 
    556 
    557 def create_graph_with_all_nodes(filter_tag):
    558     new_graph = {}
    559     action_node_type = 4
    560     event_node_type = 5
    561     validation_node_type = 9
    562     getter_atom_node_type = 30
    563     node_types = {node_type_id for node_type_id in get_node_types() if node_type_id not in (action_node_type,
    564      event_node_type,
    565      validation_node_type,
    566      getter_atom_node_type)}
    567     node_id = 0
    568     x = 0
    569     y = 0
    570     for node_type_id in node_types:
    571         new_graph[node_id] = get_new_node_data(node_type_id, [x, y])
    572         y += 4
    573         node_id += 1
    574 
    575     x = 4
    576     y = 0
    577     for atom_id, atom in get_action_atoms().iteritems():
    578         if filter_tag not in atom.tags:
    579             continue
    580         new_graph[node_id] = get_new_node_data(action_node_type, [x, y], atom_id)
    581         y += 4
    582         node_id += 1
    583 
    584     x = 8
    585     y = 0
    586     for atom_id, atom in get_event_atoms().iteritems():
    587         if filter_tag not in atom.tags:
    588             continue
    589         new_graph[node_id] = get_new_node_data(event_node_type, [x, y], atom_id)
    590         y += 4
    591         node_id += 1
    592 
    593     x = 12
    594     y = 0
    595     for atom_id, atom in get_condition_atoms().iteritems():
    596         if filter_tag not in atom.tags:
    597             continue
    598         new_graph[node_id] = get_new_node_data(validation_node_type, [x, y], atom_id)
    599         y += 4
    600         node_id += 1
    601 
    602     x = 16
    603     y = 0
    604     for atom_id, atom in get_getter_atoms().iteritems():
    605         if filter_tag not in atom.tags:
    606             continue
    607         new_graph[node_id] = get_new_node_data(getter_atom_node_type, [x, y], atom_id)
    608         y += 4
    609         node_id += 1
    610 
    611     create_new_custom_node_graph('all_{}_nodes'.format(filter_tag), new_graph)
    612 
    613 
    614 def start_all_custom_graphs():
    615     from nodegraph.client.graph import ClientNodeGraph
    616     from utillib import KeyVal
    617     graphs = get_custom_node_graphs()
    618     for node_graph_id in graphs:
    619         print('Starting', node_graph_id)
    620         node_graph = ClientNodeGraph(graph_id=node_graph_id, graph_data=KeyVal(name=node_graph_id, description='', nodes=get_custom_node_graph(node_graph_id, as_object=True)))
    621         sm.GetService('node_graph')._active_graphs[node_graph.instance_id] = node_graph
    622         node_graph.start_node_graph()
    623 
    624 
    625 def start_all_fsd_graphs(client_graphs = True, server_graphs = True):
    626     from nodegraph.common.nodedata import get_node_graphs
    627     for node_graph_id, node_graph in get_node_graphs().iteritems():
    628         if 'server' in node_graph.tags:
    629             if server_graphs:
    630                 print('Starting server graph', node_graph_id, node_graph.name)
    631                 sm.GetService('node_graph').qa_start_node_graph(node_graph_id)
    632         elif client_graphs:
    633             print('Starting client graph', node_graph_id, node_graph.name)
    634             sm.GetService('node_graph').start_node_graph(node_graph_id)
    635 
    636 
    637 def open_all_custom_graphs(wait_time = 0.5):
    638     from nodegraph.client.ui.window import NodeGraphEditorWindow
    639     import uthread2
    640     for node_graph_id in get_custom_node_graphs():
    641         print('Opening', node_graph_id)
    642         NodeGraphEditorWindow.Open(node_graph_id=node_graph_id)
    643         uthread2.sleep(wait_time)
    644 
    645 
    646 def open_all_fsd_graphs(wait_time = 0.5):
    647     from nodegraph.client.ui.window import NodeGraphEditorWindow
    648     from nodegraph.common.nodedata import get_node_graphs
    649     import uthread2
    650     for node_graph_id in get_node_graphs():
    651         print('Opening', node_graph_id)
    652         NodeGraphEditorWindow.Open(node_graph_id=node_graph_id)
    653         uthread2.sleep(wait_time)