tecscde 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rubocop.yml +125 -0
- data/.rubocop_todo.yml +188 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +6 -0
- data/LICENSE +46 -0
- data/LICENSE.ja +32 -0
- data/README.ja.md +200 -0
- data/README.md +35 -0
- data/Rakefile +27 -0
- data/bin/tecscde +64 -0
- data/glade/tecscde-cell-property.glade +205 -0
- data/glade/tecscde-celltype-property.glade +172 -0
- data/glade/tecscde-celltype.glade +414 -0
- data/glade/tecscde-export.glade +161 -0
- data/glade/test-cell-plugin.rb +51 -0
- data/glade/test-cell-property.rb +35 -0
- data/glade/test-export.rb +35 -0
- data/glade/test-palette.rb +26 -0
- data/lib/tcflow.rb +148 -0
- data/lib/tecscde.rb +65 -0
- data/lib/tecscde/NewCell.png +0 -0
- data/lib/tecscde/SelectArrow.png +0 -0
- data/lib/tecscde/attr_tree_view.rb +253 -0
- data/lib/tecscde/cell_plugin_dialog.glade +294 -0
- data/lib/tecscde/cell_plugin_dialog.rb +89 -0
- data/lib/tecscde/celltype_tree_view.rb +105 -0
- data/lib/tecscde/change_set_control.rb +35 -0
- data/lib/tecscde/change_set_control/change_set.rb +32 -0
- data/lib/tecscde/change_set_control/change_set_manager.rb +62 -0
- data/lib/tecscde/command.rb +35 -0
- data/lib/tecscde/control.rb +491 -0
- data/lib/tecscde/highlighted_objects.rb +180 -0
- data/lib/tecscde/logger.rb +74 -0
- data/lib/tecscde/main_view_and_model.rb +80 -0
- data/lib/tecscde/palette.glade +553 -0
- data/lib/tecscde/palette.rb +174 -0
- data/lib/tecscde/preferences.glade +117 -0
- data/lib/tecscde/preferences.rb +44 -0
- data/lib/tecscde/tecs_model.rb +1137 -0
- data/lib/tecscde/tecs_model/hbar.rb +68 -0
- data/lib/tecscde/tecs_model/tm_c_port.rb +122 -0
- data/lib/tecscde/tecs_model/tm_c_port_array.rb +98 -0
- data/lib/tecscde/tecs_model/tm_cell.rb +496 -0
- data/lib/tecscde/tecs_model/tm_e_port.rb +126 -0
- data/lib/tecscde/tecs_model/tm_e_port_array.rb +78 -0
- data/lib/tecscde/tecs_model/tm_join.rb +293 -0
- data/lib/tecscde/tecs_model/tm_join_bar.rb +146 -0
- data/lib/tecscde/tecs_model/tm_port.rb +238 -0
- data/lib/tecscde/tecs_model/tm_port_array.rb +246 -0
- data/lib/tecscde/tecs_model/tm_region.rb +107 -0
- data/lib/tecscde/tecs_model/tm_uneditable.rb +68 -0
- data/lib/tecscde/tecs_model/vbar.rb +68 -0
- data/lib/tecscde/templates/_cell_info.cde.erb +15 -0
- data/lib/tecscde/templates/_join_info.cde.erb +28 -0
- data/lib/tecscde/templates/main.cde.erb +49 -0
- data/lib/tecscde/tm_object.rb +91 -0
- data/lib/tecscde/version.rb +4 -0
- data/lib/tecscde/view.rb +58 -0
- data/lib/tecscde/view/cairo_matrix.rb +90 -0
- data/lib/tecscde/view/canvas.rb +59 -0
- data/lib/tecscde/view/constants.rb +114 -0
- data/lib/tecscde/view/main_view.rb +1245 -0
- data/lib/tecsflow.rb +475 -0
- data/lib/tecsflow/C_parser.tab.rb +2471 -0
- data/lib/tecsflow/C_parser.y.rb +1087 -0
- data/lib/tecsflow/classes.rb +421 -0
- data/lib/tecsgen.rb +581 -0
- data/lib/tecsgen/core/C_parser.tab.rb +2477 -0
- data/lib/tecsgen/core/C_parser.y +1032 -0
- data/lib/tecsgen/core/bnf-deb.tab.rb +5193 -0
- data/lib/tecsgen/core/bnf.tab.rb +5193 -0
- data/lib/tecsgen/core/bnf.y +2211 -0
- data/lib/tecsgen/core/componentobj.rb +7901 -0
- data/lib/tecsgen/core/ctypes.rb +226 -0
- data/lib/tecsgen/core/expression.rb +1031 -0
- data/lib/tecsgen/core/gen_xml.rb +374 -0
- data/lib/tecsgen/core/generate.rb +5206 -0
- data/lib/tecsgen/core/location.rb +116 -0
- data/lib/tecsgen/core/messages.rb +101 -0
- data/lib/tecsgen/core/optimize.rb +456 -0
- data/lib/tecsgen/core/plugin.rb +332 -0
- data/lib/tecsgen/core/pluginModule.rb +165 -0
- data/lib/tecsgen/core/syntaxobj.rb +1234 -0
- data/lib/tecsgen/core/tecs_lang.rb +306 -0
- data/lib/tecsgen/core/tecsgen.rb +453 -0
- data/lib/tecsgen/core/tecsinfo.rb +860 -0
- data/lib/tecsgen/core/tool_info.rb +258 -0
- data/lib/tecsgen/core/types.rb +1632 -0
- data/lib/tecsgen/core/unjoin_plugin.rb +218 -0
- data/lib/tecsgen/core/value.rb +650 -0
- data/lib/tecsgen/messages/messages_console_en_US.rb +1171 -0
- data/lib/tecsgen/messages/messages_console_ja_JP.rb +1171 -0
- data/lib/tecsgen/messages/messages_file_en_US.rb +334 -0
- data/lib/tecsgen/messages/messages_file_ja_JP.rb +163 -0
- data/lib/tecsgen/plugin/ATK1AlarmPlugin.rb +196 -0
- data/lib/tecsgen/plugin/ATK1DelayTaskPlugin.rb +106 -0
- data/lib/tecsgen/plugin/ATK1EventPlugin.rb +147 -0
- data/lib/tecsgen/plugin/ATK1ISRPlugin.rb +174 -0
- data/lib/tecsgen/plugin/ATK1KernelPlugin.rb +287 -0
- data/lib/tecsgen/plugin/ATK1ResourcePlugin.rb +124 -0
- data/lib/tecsgen/plugin/ATK1TaskPlugin.rb +220 -0
- data/lib/tecsgen/plugin/C2TECSBridgePlugin.rb +210 -0
- data/lib/tecsgen/plugin/CellPlugin.rb +61 -0
- data/lib/tecsgen/plugin/CelltypePlugin.rb +72 -0
- data/lib/tecsgen/plugin/CompositePlugin.rb +66 -0
- data/lib/tecsgen/plugin/DomainPlugin.rb +89 -0
- data/lib/tecsgen/plugin/HRP2AlarmHandlerPlugin.rb +76 -0
- data/lib/tecsgen/plugin/HRP2Cache.rb +1 -0
- data/lib/tecsgen/plugin/HRP2CyclicHandlerPlugin.rb +75 -0
- data/lib/tecsgen/plugin/HRP2DataqueuePlugin.rb +68 -0
- data/lib/tecsgen/plugin/HRP2EventflagPlugin.rb +68 -0
- data/lib/tecsgen/plugin/HRP2FixedSizeMemoryPoolPlugin.rb +68 -0
- data/lib/tecsgen/plugin/HRP2HandlerPlugin.rb +117 -0
- data/lib/tecsgen/plugin/HRP2KernelObjectPlugin.rb +372 -0
- data/lib/tecsgen/plugin/HRP2ObjectPlugin.rb +94 -0
- data/lib/tecsgen/plugin/HRP2Plugin.rb +140 -0
- data/lib/tecsgen/plugin/HRP2PostHook.rb +111 -0
- data/lib/tecsgen/plugin/HRP2PriorityDataqueuePlugin.rb +66 -0
- data/lib/tecsgen/plugin/HRP2RPCPlugin.rb +319 -0
- data/lib/tecsgen/plugin/HRP2SVCPlugin.rb +473 -0
- data/lib/tecsgen/plugin/HRP2SemaphorePlugin.rb +67 -0
- data/lib/tecsgen/plugin/HRP2TaskPlugin.rb +200 -0
- data/lib/tecsgen/plugin/HRPHandlerPlugin.rb +125 -0
- data/lib/tecsgen/plugin/HRPKernelObjectManager.rb +72 -0
- data/lib/tecsgen/plugin/HRPKernelObjectPlugin.rb +333 -0
- data/lib/tecsgen/plugin/HRPObjectPlugin.rb +93 -0
- data/lib/tecsgen/plugin/HRPPlugin.rb +356 -0
- data/lib/tecsgen/plugin/HRPRPCPlugin.rb +407 -0
- data/lib/tecsgen/plugin/HRPSVCPlugin.rb +859 -0
- data/lib/tecsgen/plugin/HRPTaskPlugin.rb +107 -0
- data/lib/tecsgen/plugin/Mruby2CBridgePlugin.rb +86 -0
- data/lib/tecsgen/plugin/MrubyBridgeCellPlugin.rb +264 -0
- data/lib/tecsgen/plugin/MrubyBridgeCelltypePlugin.rb +293 -0
- data/lib/tecsgen/plugin/MrubyBridgeCompositePlugin.rb +49 -0
- data/lib/tecsgen/plugin/MrubyBridgePlugin.rb +67 -0
- data/lib/tecsgen/plugin/MrubyBridgeSignaturePlugin.rb +1307 -0
- data/lib/tecsgen/plugin/MrubyInfoBridgePlugin.rb +14 -0
- data/lib/tecsgen/plugin/MrubyInfoBridgeSignaturePlugin.rb +994 -0
- data/lib/tecsgen/plugin/MultiPlugin.rb +57 -0
- data/lib/tecsgen/plugin/NotifierPlugin.rb +1217 -0
- data/lib/tecsgen/plugin/OpaqueMarshalerPlugin.rb +81 -0
- data/lib/tecsgen/plugin/OpaqueRPCPlugin.rb +323 -0
- data/lib/tecsgen/plugin/RPCPlugin.rb +266 -0
- data/lib/tecsgen/plugin/RepeatCellPlugin.rb +166 -0
- data/lib/tecsgen/plugin/RepeatJoinPlugin.rb +130 -0
- data/lib/tecsgen/plugin/SharedOpaqueRPCPlugin.rb +357 -0
- data/lib/tecsgen/plugin/SharedRPCPlugin.rb +329 -0
- data/lib/tecsgen/plugin/SignaturePlugin.rb +77 -0
- data/lib/tecsgen/plugin/TECS2CBridgePlugin.rb +178 -0
- data/lib/tecsgen/plugin/TECSInfoPlugin.rb +280 -0
- data/lib/tecsgen/plugin/ThroughPlugin.rb +333 -0
- data/lib/tecsgen/plugin/TracePlugin.rb +484 -0
- data/lib/tecsgen/plugin/lib/GenHRP2Marshaler.rb +761 -0
- data/lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb +1107 -0
- data/lib/tecsgen/plugin/lib/GenParamCopy.rb +365 -0
- data/lib/tecsgen/plugin/lib/GenTransparentMarshaler.rb +683 -0
- data/lib/tecsgen/plugin/lib/MrubyBridgeCelltypePluginModule.rb +283 -0
- data/lib/tecsgen/plugin/lib/MrubyBridgeSignaturePluginModule.rb +277 -0
- data/lib/tecsgen/version.rb +6 -0
- data/samples/FigureSamples/active/active.cde +104 -0
- data/samples/FigureSamples/active/active.cdl +20 -0
- data/samples/FigureSamples/active/active.pdf +0 -0
- data/samples/FigureSamples/active/active.png +0 -0
- data/samples/FigureSamples/active/gen/tmp_C_src.c +36 -0
- data/samples/FigureSamples/active/gen/tmp_cygwin_tecs.h +1908 -0
- data/samples/FigureSamples/active/gen/tmp_plugin_post_code.cdl +0 -0
- data/samples/FigureSamples/allocator/allocator-internal.png +0 -0
- data/samples/FigureSamples/allocator/allocator.cde +171 -0
- data/samples/FigureSamples/allocator/allocator.cdl +58 -0
- data/samples/FigureSamples/allocator/allocator.png +0 -0
- data/samples/FigureSamples/basic/Makefile +87 -0
- data/samples/FigureSamples/basic/SimpleSample-trace.cdl +50 -0
- data/samples/FigureSamples/basic/SimpleSample.cde +91 -0
- data/samples/FigureSamples/basic/SimpleSample.cdl +47 -0
- data/samples/FigureSamples/basic/basic.cde +93 -0
- data/samples/FigureSamples/basic/basic.cdl +46 -0
- data/samples/FigureSamples/basic/basic.png +0 -0
- data/samples/FigureSamples/callback/callback.cde +130 -0
- data/samples/FigureSamples/callback/callback.cdl +29 -0
- data/samples/FigureSamples/callback/callback.png +0 -0
- data/samples/FigureSamples/carray/carray.cde +144 -0
- data/samples/FigureSamples/carray/carray.cdl +38 -0
- data/samples/FigureSamples/carray/carray.png +0 -0
- data/samples/FigureSamples/cearray/cearray.cde +314 -0
- data/samples/FigureSamples/cearray/cearray.cdl +60 -0
- data/samples/FigureSamples/cearray/cearray.png +0 -0
- data/samples/FigureSamples/composite/composite-internal.png +0 -0
- data/samples/FigureSamples/composite/composite.cde +216 -0
- data/samples/FigureSamples/composite/composite.cdl +95 -0
- data/samples/FigureSamples/composite/composite.png +0 -0
- data/samples/FigureSamples/earray/earray.cde +142 -0
- data/samples/FigureSamples/earray/earray.cdl +38 -0
- data/samples/FigureSamples/earray/earray.png +0 -0
- data/samples/FigureSamples/join/Makefile +87 -0
- data/samples/FigureSamples/join/join.cde +132 -0
- data/samples/FigureSamples/join/join.cdl +40 -0
- data/samples/FigureSamples/join/join.png +0 -0
- data/samples/FigureSamples/relay/Makefile +99 -0
- data/samples/FigureSamples/relay/relay-internal.png +0 -0
- data/samples/FigureSamples/relay/relay.cde +284 -0
- data/samples/FigureSamples/relay/relay.cdl +52 -0
- data/samples/FigureSamples/relay/relay.png +0 -0
- data/samples/FigureSamples/rpc/Makefile +123 -0
- data/samples/FigureSamples/rpc/rpc-expand.png +0 -0
- data/samples/FigureSamples/rpc/rpc.cde +245 -0
- data/samples/FigureSamples/rpc/rpc.png +0 -0
- data/samples/FigureSamples/rpc/rpc_sample.cdl +53 -0
- data/samples/SimpleSample/Makefile +25 -0
- data/samples/SimpleSample/SimpleSample/Makefile +86 -0
- data/samples/SimpleSample/SimpleSample/Makefile-trace +91 -0
- data/samples/SimpleSample/SimpleSample/README.txt +106 -0
- data/samples/SimpleSample/SimpleSample/SimpleSample-trace.cdl +50 -0
- data/samples/SimpleSample/SimpleSample/SimpleSample.cdl +45 -0
- data/samples/SimpleSample/SimpleSample/src/tSample.c +77 -0
- data/samples/SimpleSample/SimpleSample/src/tSimple.c +48 -0
- data/samples/SimpleSample/SimpleSample/src/tecs-types.h +27 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/Makefile +51 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/Makefile-trace +91 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/README.txt +106 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/SimpleSample-trace.cdl +80 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/SimpleSample.cdl +77 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/rSample/Makefile +112 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/rSimple/Makefile +109 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tSample.c +80 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tSimple.c +47 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tTaskMain.c +66 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tecs-types.h +27 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/Makefile +125 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/Makefile-trace +130 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/SimpleSample-trace.cdl +54 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/SimpleSample.cdl +53 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/src/tSample.c +80 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/src/tSimple.c +54 -0
- data/tecscde.gemspec +41 -0
- metadata +353 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#
|
|
2
|
+
# TECSCDE - TECS Component Diagram Editor
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2014-2015 by TOPPERS Project
|
|
5
|
+
#
|
|
6
|
+
# The above copyright holders grant permission gratis to use,
|
|
7
|
+
# duplicate, modify, or redistribute (hereafter called use) this
|
|
8
|
+
# software (including the one made by modifying this software),
|
|
9
|
+
# provided that the following four conditions (1) through (4) are
|
|
10
|
+
# satisfied.
|
|
11
|
+
#
|
|
12
|
+
# (1) When this software is used in the form of source code, the above
|
|
13
|
+
# copyright notice, this use conditions, and the disclaimer shown
|
|
14
|
+
# below must be retained in the source code without modification.
|
|
15
|
+
#
|
|
16
|
+
# (2) When this software is redistributed in the forms usable for the
|
|
17
|
+
# development of other software, such as in library form, the above
|
|
18
|
+
# copyright notice, this use conditions, and the disclaimer shown
|
|
19
|
+
# below must be shown without modification in the document provided
|
|
20
|
+
# with the redistributed software, such as the user manual.
|
|
21
|
+
#
|
|
22
|
+
# (3) When this software is redistributed in the forms unusable for the
|
|
23
|
+
# development of other software, such as the case when the software
|
|
24
|
+
# is embedded in a piece of equipment, either of the following two
|
|
25
|
+
# conditions must be satisfied:
|
|
26
|
+
#
|
|
27
|
+
# (a) The above copyright notice, this use conditions, and the
|
|
28
|
+
# disclaimer shown below must be shown without modification in
|
|
29
|
+
# the document provided with the redistributed software, such as
|
|
30
|
+
# the user manual.
|
|
31
|
+
#
|
|
32
|
+
# (b) How the software is to be redistributed must be reported to the
|
|
33
|
+
# TOPPERS Project according to the procedure described
|
|
34
|
+
# separately.
|
|
35
|
+
#
|
|
36
|
+
# (4) The above copyright holders and the TOPPERS Project are exempt
|
|
37
|
+
# from responsibility for any type of damage directly or indirectly
|
|
38
|
+
# caused from the use of this software and are indemnified by any
|
|
39
|
+
# users or end users of this software from any and all causes of
|
|
40
|
+
# action whatsoever.
|
|
41
|
+
#
|
|
42
|
+
# THIS SOFTWARE IS PROVIDED "AS IS." THE ABOVE COPYRIGHT HOLDERS AND
|
|
43
|
+
# THE TOPPERS PROJECT DISCLAIM ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
44
|
+
# INCLUDING, BUT NOT LIMITED TO, ITS APPLICABILITY TO A PARTICULAR
|
|
45
|
+
# PURPOSE. IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS AND THE
|
|
46
|
+
# TOPPERS PROJECT BE LIABLE FOR ANY TYPE OF DAMAGE DIRECTLY OR
|
|
47
|
+
# INDIRECTLY CAUSED FROM THE USE OF THIS SOFTWARE.
|
|
48
|
+
#
|
|
49
|
+
# $Id: palette.rb 2640 2017-06-03 11:27:12Z okuma-top $
|
|
50
|
+
#
|
|
51
|
+
|
|
52
|
+
require "tecscde/attr_tree_view"
|
|
53
|
+
require "tecscde/celltype_tree_view"
|
|
54
|
+
require "tecscde/preferences"
|
|
55
|
+
|
|
56
|
+
module TECSCDE
|
|
57
|
+
class Palette
|
|
58
|
+
# control::TECSCDE::Control
|
|
59
|
+
def initialize(control)
|
|
60
|
+
@control = control
|
|
61
|
+
setup
|
|
62
|
+
@window.show_all
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def setup
|
|
66
|
+
@builder = Gtk::Builder.new
|
|
67
|
+
@builder.add_from_file(File.join(__dir__, "palette.glade"))
|
|
68
|
+
|
|
69
|
+
#----- window -----#
|
|
70
|
+
@window = @builder["window_palette"]
|
|
71
|
+
@window.realize
|
|
72
|
+
# @window.type = ( Gtk::Window::TOPLEVEL )
|
|
73
|
+
@window.window.set_functions(Gdk::Window::FUNC_RESIZE | Gdk::Window::FUNC_MOVE)
|
|
74
|
+
|
|
75
|
+
setup_menubar
|
|
76
|
+
|
|
77
|
+
#----- pointer BUTTON -----#
|
|
78
|
+
@button_pointer = @builder["togglebutton_pointer"]
|
|
79
|
+
@button_pointer.signal_connect("clicked") do
|
|
80
|
+
@control.on_pointer
|
|
81
|
+
# @button_pointer.active = true
|
|
82
|
+
@button_new_cell.active = false
|
|
83
|
+
false
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#----- new cell BUTTON -----#
|
|
87
|
+
@button_new_cell = @builder["togglebutton_new_cell"]
|
|
88
|
+
@button_new_cell.signal_connect("clicked") do
|
|
89
|
+
@control.on_new_cell
|
|
90
|
+
# @button_new_cell.active = true
|
|
91
|
+
@button_pointer.active = false
|
|
92
|
+
false
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#----- undo BUTTON -----#
|
|
96
|
+
@button_undo = @builder["button_undo"]
|
|
97
|
+
@button_undo.signal_connect("clicked") { @control.on_undo }
|
|
98
|
+
|
|
99
|
+
#----- redo BUTTON -----#
|
|
100
|
+
@button_redo = @builder["button_redo"]
|
|
101
|
+
@button_redo.signal_connect("clicked") { @control.on_redo }
|
|
102
|
+
# currently redo doesn't work well
|
|
103
|
+
@button_redo.set_sensitive(false)
|
|
104
|
+
|
|
105
|
+
#----- celltype TREEVIEW -----#
|
|
106
|
+
@tree_view_celltype = @builder["treeview_celltype"]
|
|
107
|
+
@celltype_tree_view = CelltypeTreeView.new(@tree_view_celltype)
|
|
108
|
+
|
|
109
|
+
#----- -----#
|
|
110
|
+
@frame_cell = @builder["frame_cell"]
|
|
111
|
+
|
|
112
|
+
#----- cell name ENTRY -----#
|
|
113
|
+
@entry_cell_name = @builder["entry_cell_name"]
|
|
114
|
+
@entry_cell_name.signal_connect("activate") do |entry|
|
|
115
|
+
@control.on_cell_name_entry_active(entry)
|
|
116
|
+
false
|
|
117
|
+
end
|
|
118
|
+
@entry_cell_name.signal_connect("focus-out-event") do |entry, _event|
|
|
119
|
+
@control.on_cell_name_entry_focus_out(entry)
|
|
120
|
+
false
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
@entry_cell_region = @builder["entry_cell_region"]
|
|
124
|
+
@entry_cell_region.signal_connect("activate") do |entry|
|
|
125
|
+
@control.on_cell_region_entry_active(entry)
|
|
126
|
+
false
|
|
127
|
+
end
|
|
128
|
+
@entry_cell_region.signal_connect("focus-out-event") do |entry, _event|
|
|
129
|
+
@control.on_cell_region_entry_focus_out(entry)
|
|
130
|
+
false
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
@treeview_cell_attribute = @builder["treeview_cell_attribute"]
|
|
134
|
+
@attr_tree_view = AttrTreeView.new(@treeview_cell_attribute)
|
|
135
|
+
|
|
136
|
+
@control.set_attr_operation_widgets(@window, @celltype_tree_view, @attr_tree_view, @entry_cell_name, @entry_cell_region, @frame_cell)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def setup_menubar
|
|
140
|
+
@builder["menuitem-save"].signal_connect("activate") do
|
|
141
|
+
@control.on_save
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
@builder["menuitem-export"].signal_connect("activate") do
|
|
145
|
+
@control.on_export
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
@builder["menuitem-preferences"].signal_connect("activate") do
|
|
149
|
+
preferences = TECSCDE::Preferences.new(@control)
|
|
150
|
+
preferences.run
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
@builder["menuitem-quit"].signal_connect("activate") do
|
|
154
|
+
@control.on_quit
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
@builder["menuitem-undo"].signal_connect("activate") do
|
|
158
|
+
@control.on_undo
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
@builder["menuitem-redo"].signal_connect("activate") do
|
|
162
|
+
@control.on_redo
|
|
163
|
+
end
|
|
164
|
+
# currently redo doesn't work well
|
|
165
|
+
@builder["menuitem-redo"].sensitive = false
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def set_view(view)
|
|
169
|
+
@window.set_transient_for(view.get_window)
|
|
170
|
+
@window.window.set_group(view.get_window.window)
|
|
171
|
+
@window.window.raise
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<interface>
|
|
3
|
+
<requires lib="gtk+" version="2.24"/>
|
|
4
|
+
<!-- interface-naming-policy project-wide -->
|
|
5
|
+
<object class="GtkDialog" id="preferences">
|
|
6
|
+
<property name="can_focus">False</property>
|
|
7
|
+
<property name="border_width">5</property>
|
|
8
|
+
<property name="type_hint">dialog</property>
|
|
9
|
+
<child internal-child="vbox">
|
|
10
|
+
<object class="GtkVBox" id="dialog-vbox1">
|
|
11
|
+
<property name="visible">True</property>
|
|
12
|
+
<property name="can_focus">False</property>
|
|
13
|
+
<property name="spacing">2</property>
|
|
14
|
+
<child internal-child="action_area">
|
|
15
|
+
<object class="GtkHButtonBox" id="dialog-action_area1">
|
|
16
|
+
<property name="visible">True</property>
|
|
17
|
+
<property name="can_focus">False</property>
|
|
18
|
+
<property name="layout_style">end</property>
|
|
19
|
+
<child>
|
|
20
|
+
<object class="GtkButton" id="button-cancel">
|
|
21
|
+
<property name="label">gtk-cancel</property>
|
|
22
|
+
<property name="visible">True</property>
|
|
23
|
+
<property name="can_focus">True</property>
|
|
24
|
+
<property name="receives_default">True</property>
|
|
25
|
+
<property name="use_action_appearance">False</property>
|
|
26
|
+
<property name="use_underline">True</property>
|
|
27
|
+
<property name="use_stock">True</property>
|
|
28
|
+
</object>
|
|
29
|
+
<packing>
|
|
30
|
+
<property name="expand">False</property>
|
|
31
|
+
<property name="fill">False</property>
|
|
32
|
+
<property name="position">0</property>
|
|
33
|
+
</packing>
|
|
34
|
+
</child>
|
|
35
|
+
<child>
|
|
36
|
+
<object class="GtkButton" id="button-apply">
|
|
37
|
+
<property name="label">gtk-apply</property>
|
|
38
|
+
<property name="visible">True</property>
|
|
39
|
+
<property name="can_focus">True</property>
|
|
40
|
+
<property name="receives_default">True</property>
|
|
41
|
+
<property name="use_action_appearance">False</property>
|
|
42
|
+
<property name="use_stock">True</property>
|
|
43
|
+
</object>
|
|
44
|
+
<packing>
|
|
45
|
+
<property name="expand">False</property>
|
|
46
|
+
<property name="fill">False</property>
|
|
47
|
+
<property name="position">1</property>
|
|
48
|
+
</packing>
|
|
49
|
+
</child>
|
|
50
|
+
</object>
|
|
51
|
+
<packing>
|
|
52
|
+
<property name="expand">True</property>
|
|
53
|
+
<property name="fill">True</property>
|
|
54
|
+
<property name="position">0</property>
|
|
55
|
+
</packing>
|
|
56
|
+
</child>
|
|
57
|
+
<child>
|
|
58
|
+
<object class="GtkVBox" id="vbox1">
|
|
59
|
+
<property name="visible">True</property>
|
|
60
|
+
<property name="can_focus">False</property>
|
|
61
|
+
<child>
|
|
62
|
+
<object class="GtkHBox" id="hbox1">
|
|
63
|
+
<property name="visible">True</property>
|
|
64
|
+
<property name="can_focus">False</property>
|
|
65
|
+
<child>
|
|
66
|
+
<object class="GtkLabel" id="paper-size-label">
|
|
67
|
+
<property name="visible">True</property>
|
|
68
|
+
<property name="can_focus">False</property>
|
|
69
|
+
<property name="label" translatable="yes">Paper size</property>
|
|
70
|
+
</object>
|
|
71
|
+
<packing>
|
|
72
|
+
<property name="expand">True</property>
|
|
73
|
+
<property name="fill">True</property>
|
|
74
|
+
<property name="position">0</property>
|
|
75
|
+
</packing>
|
|
76
|
+
</child>
|
|
77
|
+
<child>
|
|
78
|
+
<object class="GtkComboBoxText" id="paper-size">
|
|
79
|
+
<property name="visible">True</property>
|
|
80
|
+
<property name="can_focus">False</property>
|
|
81
|
+
<items>
|
|
82
|
+
<item>A4L</item>
|
|
83
|
+
<item>A3L</item>
|
|
84
|
+
<item>A2L</item>
|
|
85
|
+
</items>
|
|
86
|
+
</object>
|
|
87
|
+
<packing>
|
|
88
|
+
<property name="expand">True</property>
|
|
89
|
+
<property name="fill">True</property>
|
|
90
|
+
<property name="position">1</property>
|
|
91
|
+
</packing>
|
|
92
|
+
</child>
|
|
93
|
+
</object>
|
|
94
|
+
<packing>
|
|
95
|
+
<property name="expand">True</property>
|
|
96
|
+
<property name="fill">True</property>
|
|
97
|
+
<property name="position">0</property>
|
|
98
|
+
</packing>
|
|
99
|
+
</child>
|
|
100
|
+
<child>
|
|
101
|
+
<placeholder/>
|
|
102
|
+
</child>
|
|
103
|
+
</object>
|
|
104
|
+
<packing>
|
|
105
|
+
<property name="expand">True</property>
|
|
106
|
+
<property name="fill">True</property>
|
|
107
|
+
<property name="position">1</property>
|
|
108
|
+
</packing>
|
|
109
|
+
</child>
|
|
110
|
+
</object>
|
|
111
|
+
</child>
|
|
112
|
+
<action-widgets>
|
|
113
|
+
<action-widget response="-6">button-cancel</action-widget>
|
|
114
|
+
<action-widget response="-10">button-apply</action-widget>
|
|
115
|
+
</action-widgets>
|
|
116
|
+
</object>
|
|
117
|
+
</interface>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require "gtk2"
|
|
2
|
+
require "tecscde/tecs_model"
|
|
3
|
+
|
|
4
|
+
module TECSCDE
|
|
5
|
+
class Preferences
|
|
6
|
+
|
|
7
|
+
attr_accessor :selected_paper
|
|
8
|
+
|
|
9
|
+
def initialize(control)
|
|
10
|
+
@control = control
|
|
11
|
+
@builder = Gtk::Builder.new
|
|
12
|
+
@builder.add_from_file(File.join(__dir__, "preferences.glade"))
|
|
13
|
+
@selected_paper = nil
|
|
14
|
+
@changed = false
|
|
15
|
+
setup
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def setup
|
|
19
|
+
setup_combo_box
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def setup_combo_box
|
|
23
|
+
combo = @builder["paper-size"]
|
|
24
|
+
combo.signal_connect("changed") do
|
|
25
|
+
@selected_paper = combo.active_text
|
|
26
|
+
@changed = true
|
|
27
|
+
end
|
|
28
|
+
combo.active = @control.preferences[:paper].index
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def run
|
|
32
|
+
dialog = @builder["preferences"]
|
|
33
|
+
response = dialog.run
|
|
34
|
+
if response == Gtk::ResponseType::APPLY
|
|
35
|
+
apply
|
|
36
|
+
end
|
|
37
|
+
dialog.destroy
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def apply
|
|
41
|
+
@control.change_preferences(paper: @selected_paper)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,1137 @@
|
|
|
1
|
+
#
|
|
2
|
+
# TECSCDE - TECS Component Diagram Editor
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2014-2019 by TOPPERS Project
|
|
5
|
+
#
|
|
6
|
+
# The above copyright holders grant permission gratis to use,
|
|
7
|
+
# duplicate, modify, or redistribute (hereafter called use) this
|
|
8
|
+
# software (including the one made by modifying this software),
|
|
9
|
+
# provided that the following four conditions (1) through (4) are
|
|
10
|
+
# satisfied.
|
|
11
|
+
#
|
|
12
|
+
# (1) When this software is used in the form of source code, the above
|
|
13
|
+
# copyright notice, this use conditions, and the disclaimer shown
|
|
14
|
+
# below must be retained in the source code without modification.
|
|
15
|
+
#
|
|
16
|
+
# (2) When this software is redistributed in the forms usable for the
|
|
17
|
+
# development of other software, such as in library form, the above
|
|
18
|
+
# copyright notice, this use conditions, and the disclaimer shown
|
|
19
|
+
# below must be shown without modification in the document provided
|
|
20
|
+
# with the redistributed software, such as the user manual.
|
|
21
|
+
#
|
|
22
|
+
# (3) When this software is redistributed in the forms unusable for the
|
|
23
|
+
# development of other software, such as the case when the software
|
|
24
|
+
# is embedded in a piece of equipment, either of the following two
|
|
25
|
+
# conditions must be satisfied:
|
|
26
|
+
#
|
|
27
|
+
# (a) The above copyright notice, this use conditions, and the
|
|
28
|
+
# disclaimer shown below must be shown without modification in
|
|
29
|
+
# the document provided with the redistributed software, such as
|
|
30
|
+
# the user manual.
|
|
31
|
+
#
|
|
32
|
+
# (b) How the software is to be redistributed must be reported to the
|
|
33
|
+
# TOPPERS Project according to the procedure described
|
|
34
|
+
# separately.
|
|
35
|
+
#
|
|
36
|
+
# (4) The above copyright holders and the TOPPERS Project are exempt
|
|
37
|
+
# from responsibility for any type of damage directly or indirectly
|
|
38
|
+
# caused from the use of this software and are indemnified by any
|
|
39
|
+
# users or end users of this software from any and all causes of
|
|
40
|
+
# action whatsoever.
|
|
41
|
+
#
|
|
42
|
+
# THIS SOFTWARE IS PROVIDED "AS IS." THE ABOVE COPYRIGHT HOLDERS AND
|
|
43
|
+
# THE TOPPERS PROJECT DISCLAIM ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
44
|
+
# INCLUDING, BUT NOT LIMITED TO, ITS APPLICABILITY TO A PARTICULAR
|
|
45
|
+
# PURPOSE. IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS AND THE
|
|
46
|
+
# TOPPERS PROJECT BE LIABLE FOR ANY TYPE OF DAMAGE DIRECTLY OR
|
|
47
|
+
# INDIRECTLY CAUSED FROM THE USE OF THIS SOFTWARE.
|
|
48
|
+
#
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# methods marked *** can be called externally.
|
|
52
|
+
# don't call unmarked methods other than TECSModel.
|
|
53
|
+
#
|
|
54
|
+
|
|
55
|
+
require "erb"
|
|
56
|
+
require "json"
|
|
57
|
+
|
|
58
|
+
require "tecscde/view/constants"
|
|
59
|
+
require "tecscde/tm_object"
|
|
60
|
+
require "tecscde/change_set_control"
|
|
61
|
+
|
|
62
|
+
module TECSCDE
|
|
63
|
+
class TECSModel < TmObject
|
|
64
|
+
include TECSCDE::ChangeSetControl
|
|
65
|
+
include TECSCDE::View::Constants
|
|
66
|
+
|
|
67
|
+
# tool_info schema for tecscde
|
|
68
|
+
TECSCDE_SCHEMA = {
|
|
69
|
+
tecscde: {
|
|
70
|
+
cell_list: [:cell_location], # array
|
|
71
|
+
join_list: [:join_location] # array
|
|
72
|
+
},
|
|
73
|
+
__tecscde: {
|
|
74
|
+
paper: :paper # paper
|
|
75
|
+
},
|
|
76
|
+
paper: {
|
|
77
|
+
type: "paper", # fixed string (type name)
|
|
78
|
+
size: :string, # "A4", "A3", "A2"
|
|
79
|
+
orientation: :string, # "LANDSCAPE", "PORTRAIT"
|
|
80
|
+
},
|
|
81
|
+
cell_location: {
|
|
82
|
+
type: "cell_location", # fixed string (type name)
|
|
83
|
+
region: :string, # "rRegion::rReg"
|
|
84
|
+
name: :string, # "CellName"
|
|
85
|
+
location: [:number], # [ x, y, w, h ]
|
|
86
|
+
port_location: [:port_location] # array
|
|
87
|
+
},
|
|
88
|
+
port_location: {
|
|
89
|
+
type: "port_location", # fixed string (type name)
|
|
90
|
+
port_name: :string,
|
|
91
|
+
edge: :string, # "EDGE_TOP" | "EDGE_BOTTOM" | "EDGE_LEFT" | "EDGE_RIGHT"
|
|
92
|
+
offset: :number # real number (mm) (>=0)
|
|
93
|
+
},
|
|
94
|
+
__port_location: { # port_location optional
|
|
95
|
+
subscript: :integer
|
|
96
|
+
},
|
|
97
|
+
join_location: {
|
|
98
|
+
type: "join_location", # fixed string (type name)
|
|
99
|
+
call_region: :string, # "rRegionParent::rRegionChild",
|
|
100
|
+
call_cell: :string, # "CellName",
|
|
101
|
+
call_port: :string, # "cPort",
|
|
102
|
+
entry_region: :string, # "rERegionParent::rERegionChild",
|
|
103
|
+
entry_cell: :string, # "ECellName",
|
|
104
|
+
entry_port: :string, # "ePort",
|
|
105
|
+
bar_list: [:HBar, :VBar] # mixed (HBar&VBar) array type
|
|
106
|
+
},
|
|
107
|
+
__join_location: { # join_location optional
|
|
108
|
+
call_port_subscript: :integer, # >= 0
|
|
109
|
+
entry_port_subscript: :integer, # >= 0
|
|
110
|
+
},
|
|
111
|
+
HBar: {
|
|
112
|
+
type: "HBar", # fixed string (type name)
|
|
113
|
+
position: :number, # real number (mm), location in X-axis
|
|
114
|
+
},
|
|
115
|
+
VBar: {
|
|
116
|
+
type: "VBar", # fixed string (type name)
|
|
117
|
+
position: :number, # real number (mm), location in Y-axis
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# edges for join (connected by Bars from TmCPort to TmEPort)
|
|
122
|
+
EDGE_TOP = 0b00
|
|
123
|
+
EDGE_BOTTOM = 0b01
|
|
124
|
+
EDGE_LEFT = 0b10
|
|
125
|
+
EDGE_RIGHT = 0b11
|
|
126
|
+
|
|
127
|
+
# gap is length between parallel bars.
|
|
128
|
+
CPGAP = 10 # (mm)
|
|
129
|
+
EPGAP = 10 # (mm)
|
|
130
|
+
GAP = 5 # (mm)
|
|
131
|
+
ALIGN = 1.0 # (mm) # grid size
|
|
132
|
+
|
|
133
|
+
# acceptable error of position information in .cde file
|
|
134
|
+
MAX_ERROR_IN_NOR = 0.5
|
|
135
|
+
MAX_ERROR_IN_TAN = 2
|
|
136
|
+
|
|
137
|
+
# minmal distance to next port (minimal interval)
|
|
138
|
+
DIST_PORT = 4 # (mm)
|
|
139
|
+
|
|
140
|
+
# Paper Size w/o margin (10 mm each side)
|
|
141
|
+
PaperSpec = Struct.new(:index, :size, :key, :orientation, :name, :height, :width) do
|
|
142
|
+
def cairo_paper_class
|
|
143
|
+
Cairo::Paper.const_get(@name)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
PAPERS = {
|
|
147
|
+
A4L: PaperSpec.new(0, "A4", :A4L, "LANDSCAPE", "A4_LANDSCAPE", 190, 277),
|
|
148
|
+
A3L: PaperSpec.new(1, "A3", :A3L, "LANDSCAPE", "A3_LANDSCAPE", 277, 400),
|
|
149
|
+
A2L: PaperSpec.new(2, "A2", :A2L, "LANDSCAPE", "A2_LANDSCAPE", 400, 574),
|
|
150
|
+
}
|
|
151
|
+
# name must be found in Cairo::Paper.constants
|
|
152
|
+
|
|
153
|
+
NEAR_DIST = 2 # (mm)
|
|
154
|
+
|
|
155
|
+
IDENTIFIER_RE = /[A-Za-z_][0-9A-Za-z_]*/
|
|
156
|
+
|
|
157
|
+
attr_reader :file_editing, :paper
|
|
158
|
+
|
|
159
|
+
# @paper::PaperSpec : See PaperSpec
|
|
160
|
+
# @cell_list::[TmCell]
|
|
161
|
+
# @cell_hash::{ Symbole(namespace_path) => TmCell }
|
|
162
|
+
# @join_list::[TmJoin]
|
|
163
|
+
# @view::TView
|
|
164
|
+
# @root_region::TmRegion
|
|
165
|
+
# @file_editing::String
|
|
166
|
+
|
|
167
|
+
def initialize(tecsgen)
|
|
168
|
+
@cell_list = []
|
|
169
|
+
@cell_hash = {}
|
|
170
|
+
@join_list = []
|
|
171
|
+
@tecsgen = tecsgen
|
|
172
|
+
@paper = PAPERS[:A3L]
|
|
173
|
+
|
|
174
|
+
# __tool_info__( "tecsgen" )
|
|
175
|
+
@direct_import = []
|
|
176
|
+
@import_path_opt = []
|
|
177
|
+
@define = []
|
|
178
|
+
@cpp = ""
|
|
179
|
+
@file_editing = "untitled"
|
|
180
|
+
@owner = nil
|
|
181
|
+
init_change_set
|
|
182
|
+
|
|
183
|
+
create_root_region
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
#=== TECSModel#new_cell ***
|
|
187
|
+
# namespace_path::String : namespace path string of celltype
|
|
188
|
+
def new_cell(xm, ym, celltype_name, ct_namespace_path, tecsgen_cell = nil)
|
|
189
|
+
ct_nsp = NamespacePath.analyze(ct_namespace_path)
|
|
190
|
+
ct_nsp.append!(celltype_name.to_sym)
|
|
191
|
+
ct = Namespace.find(ct_nsp)
|
|
192
|
+
if ct.nil?
|
|
193
|
+
TECSCDE.logger.error("TM9999 celltype #{ct_nsp}: not found for cell #{@name}")
|
|
194
|
+
return
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
if tecsgen_cell
|
|
198
|
+
region = get_region_from_tecsgen_region(tecsgen_cell.get_region)
|
|
199
|
+
else
|
|
200
|
+
region = get_region_by_location(xm, ym)
|
|
201
|
+
end
|
|
202
|
+
new_cell2(xm, ym, ct, region, tecsgen_cell)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# celltype::Celltype : in tecsgen (should be changed to TmCelltype)
|
|
206
|
+
# region:TmRegion :
|
|
207
|
+
# tecsgen_cell:Cell : in tecsgen
|
|
208
|
+
def new_cell2(xm, ym, celltype, region, tecsgen_cell)
|
|
209
|
+
modified do
|
|
210
|
+
name = celltype.get_name.to_s.gsub(/t(.*)/, '\\1').to_sym
|
|
211
|
+
if @cell_hash[name]
|
|
212
|
+
count = 0
|
|
213
|
+
while @cell_hash[(name.to_s + count.to_s).to_sym]
|
|
214
|
+
count += 1
|
|
215
|
+
end
|
|
216
|
+
name = (name.to_s + count.to_s).to_sym
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
cell = TmCell.new(name, celltype, xm, ym, region, tecsgen_cell)
|
|
220
|
+
@cell_list << cell
|
|
221
|
+
@cell_hash[name] = cell
|
|
222
|
+
|
|
223
|
+
w, h = @view.get_text_extent(name, CELL_NAME, ALIGN_CENTER, TEXT_HORIZONTAL)
|
|
224
|
+
w2, h = @view.get_text_extent(celltype.get_name, CELL_NAME, ALIGN_CENTER, TEXT_HORIZONTAL)
|
|
225
|
+
w += 2
|
|
226
|
+
w = w2 if w2 > w
|
|
227
|
+
w = 20 if w < 20
|
|
228
|
+
h = 13 if h < 13
|
|
229
|
+
cell.set_geometry(xm, ym, w, h)
|
|
230
|
+
|
|
231
|
+
return cell
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
#=== TECSModel#delete_cell
|
|
236
|
+
# don't call externally, use TmCell#delete instead
|
|
237
|
+
def delete_cell(cell)
|
|
238
|
+
modified do
|
|
239
|
+
@cell_list.delete(cell)
|
|
240
|
+
@cell_hash.delete(cell.get_name) # mikan region
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
#=== TECSModel#rename_cell
|
|
245
|
+
# old_name::Symbol
|
|
246
|
+
# cell:: TmCell
|
|
247
|
+
# don't call externally, use TmCell#change_name instead
|
|
248
|
+
def rename_cell(cell, new_name)
|
|
249
|
+
modified do
|
|
250
|
+
raise "cell name not Symbol" unless new_name.is_a?(Symbol)
|
|
251
|
+
if cell.get_name == new_name
|
|
252
|
+
return true
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
unless IDENTIFIER_RE =~ new_name
|
|
256
|
+
TECSCDE.message_box("'#{new_name}' has unsuitable character for identifier", nil)
|
|
257
|
+
return false
|
|
258
|
+
end
|
|
259
|
+
if @cell_hash[new_name]
|
|
260
|
+
TECSCDE.message_box("'#{new_name}' already exists", nil)
|
|
261
|
+
return false
|
|
262
|
+
end
|
|
263
|
+
@cell_hash.delete(cell.get_name)
|
|
264
|
+
@cell_hash[new_name] = cell
|
|
265
|
+
return true
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
#=== TECSModel#new_join ***
|
|
270
|
+
def new_join(cport, eport)
|
|
271
|
+
modified do
|
|
272
|
+
join = TmJoin.new(cport, eport, self)
|
|
273
|
+
@join_list << join
|
|
274
|
+
return join
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
#=== TECSModel#delete_join
|
|
279
|
+
# don't call externally. call TmJoin#delete instead
|
|
280
|
+
def delete_join(join)
|
|
281
|
+
modified do
|
|
282
|
+
@join_list.delete(join)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
#=== TECSModel.normal direction of edge
|
|
287
|
+
# RETURN:: 1: if direction is positive, -1: negative
|
|
288
|
+
def self.get_sign_of_normal(edge_side)
|
|
289
|
+
(edge_side & 0b01) != 0 ? 1 : -1
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
#=== TECSModel.vertical?
|
|
293
|
+
# RETURN:: true if vertical, false if horizontal
|
|
294
|
+
def self.vertical?(edge_side)
|
|
295
|
+
((edge_side & 0b10) != 0) ? true : false
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def self.horizontal?(edge_side)
|
|
299
|
+
!vertical?(edge_side)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
#=== TECSModel.parallel?
|
|
303
|
+
# RETURN:: true if parallel, false if right anble
|
|
304
|
+
def self.parallel?(edge_side1, edge_side2)
|
|
305
|
+
# p "edge val", edge_side1, edge_side2, edge_side1 ^ edge_side2
|
|
306
|
+
(edge_side1 ^ edge_side2) < 0b10
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
#=== TECSModel.opposite?
|
|
310
|
+
# this function can be applicable only when edge_side1, edge_side2 are parallel
|
|
311
|
+
def self.opposite?(edge_side1, edge_side2)
|
|
312
|
+
(((edge_side1 ^ edge_side2) & 0b01) != 0) ? true : false
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
#=== TECSModel.round_length_val
|
|
316
|
+
def self.round_length_val(val)
|
|
317
|
+
round_unit = TECSModel.get_alignment
|
|
318
|
+
# round_unit = 0.25
|
|
319
|
+
# (val / round_unit).round * round_unit
|
|
320
|
+
(val / round_unit).round * round_unit
|
|
321
|
+
# val
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
#=== TECSModel#get_cell_list ***
|
|
325
|
+
def get_cell_list
|
|
326
|
+
@cell_list
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
#=== TECSModel#get_join_list ***
|
|
330
|
+
def get_join_list
|
|
331
|
+
@join_list
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def paper=(name)
|
|
335
|
+
@paper = PAPERS[name]
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
#=== TECSModel#set_view ***
|
|
339
|
+
def set_view(view)
|
|
340
|
+
@view = view
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
#=== TECSModel#get_celltype_list ***
|
|
344
|
+
def get_celltype_list
|
|
345
|
+
return unless @tecsgen
|
|
346
|
+
@tecsgen.get_celltype_list
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
#=== TECSModel#get_region_from_tecsgen_region
|
|
350
|
+
def get_region_from_tecsgen_region(tecsgen_region)
|
|
351
|
+
nsp = tecsgen_region.get_namespace_path
|
|
352
|
+
get_region_from_namespace_path(nsp)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
#=== TECSModel#get_region_from_namespace_path
|
|
356
|
+
def get_region_from_namespace_path(nsp)
|
|
357
|
+
path_array = nsp.get_path
|
|
358
|
+
region = @root_region
|
|
359
|
+
i = 0
|
|
360
|
+
while i < path_array.length
|
|
361
|
+
region = region.get_region(path_array[i])
|
|
362
|
+
i += 1
|
|
363
|
+
end
|
|
364
|
+
region
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
#=== TECSModel#get_region_by_location
|
|
368
|
+
def get_region_by_location(x, y)
|
|
369
|
+
@root_region # mikan
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
#=== TECSModel#create_root_region
|
|
373
|
+
def create_root_region
|
|
374
|
+
nsp = NamespacePath.new("::", true)
|
|
375
|
+
@root_region = TmRegion.new(nsp, self)
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
#=== TECSModel.get_alignment
|
|
379
|
+
# return::String : file name editing
|
|
380
|
+
def self.get_alignment
|
|
381
|
+
ALIGN
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def clip_x(x)
|
|
385
|
+
max = @paper.width - 2
|
|
386
|
+
if x < 2
|
|
387
|
+
x = 2
|
|
388
|
+
elsif x > max
|
|
389
|
+
x = max
|
|
390
|
+
end
|
|
391
|
+
x
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
def clip_y(y)
|
|
395
|
+
max = @paper.height - 2
|
|
396
|
+
if y < 2
|
|
397
|
+
y = 2
|
|
398
|
+
elsif y > max
|
|
399
|
+
y = max
|
|
400
|
+
end
|
|
401
|
+
y
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
#=== TECSModel.clone_for_undo
|
|
405
|
+
def clone_for_undo
|
|
406
|
+
bu = clone
|
|
407
|
+
bu.copy_from(self)
|
|
408
|
+
bu
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
#=== TECSModel.setup_clone
|
|
412
|
+
def copy_from(model)
|
|
413
|
+
model.instance_variables.each do |iv|
|
|
414
|
+
val = model.instance_variable_get(iv)
|
|
415
|
+
instance_variable_set(iv, val)
|
|
416
|
+
end
|
|
417
|
+
@cell_list = model.instance_variable_get(:@cell_list).dup
|
|
418
|
+
@cell_hash = model.instance_variable_get(:@cell_hash).dup
|
|
419
|
+
@join_list = model.instance_variable_get(:@join_list).dup
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def model
|
|
423
|
+
self
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
#=== TECSModel#add_cell_list_from_tecsgen
|
|
427
|
+
def add_cell_list_from_tecsgen
|
|
428
|
+
#----- set @file_editing -----#
|
|
429
|
+
argv = TECSGEN.get_argv
|
|
430
|
+
if argv.empty?
|
|
431
|
+
@file_editing = ""
|
|
432
|
+
else
|
|
433
|
+
last_arg = argv[-1]
|
|
434
|
+
if last_arg =~ /\.cde\Z/
|
|
435
|
+
@file_editing = last_arg
|
|
436
|
+
else
|
|
437
|
+
if last_arg =~ /\.cdl\Z/
|
|
438
|
+
@file_editing = last_arg.gsub(/\.cdl\Z/, ".cde")
|
|
439
|
+
else
|
|
440
|
+
@file_editing = last_arg + ".cde"
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
print "file_editing: #{@file_editing}\n"
|
|
446
|
+
|
|
447
|
+
tecsgen_cell_list = @tecsgen.get_cell_list
|
|
448
|
+
tecsgen_cell_list2 = []
|
|
449
|
+
x = 10
|
|
450
|
+
y = 10
|
|
451
|
+
# x = @paper[ :width ] - 60
|
|
452
|
+
# y = @paper[ :height ] -30
|
|
453
|
+
|
|
454
|
+
cell_list = {} # ::Cell => TmCell
|
|
455
|
+
return unless tecsgen_cell_list
|
|
456
|
+
TECSCDE.logger.info("=== create cell ===")
|
|
457
|
+
tecsgen_cell_list.each do |cell|
|
|
458
|
+
# p cell.get_owner.get_namespace
|
|
459
|
+
# p cell.get_owner.get_namespace_path
|
|
460
|
+
if @cell_hash[cell.get_name] # duplicate cell in cdl file
|
|
461
|
+
next
|
|
462
|
+
end
|
|
463
|
+
if cell.get_celltype.nil? # celltype not found error in cdl (tecsgen)
|
|
464
|
+
TECSCDE.logger.info("add_cell: celltype not found: #{cell.get_name} #{cell.get_owner.get_namespace_path}")
|
|
465
|
+
next
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
TECSCDE.logger.info("add_cell #{cell.get_name} #{cell.get_owner.get_namespace_path} #{cell.get_locale}")
|
|
469
|
+
new_cell_ = create_cell_from_tecsgen(cell, x, y)
|
|
470
|
+
tecsgen_cell_list2 << cell
|
|
471
|
+
cell_list[cell] = new_cell_
|
|
472
|
+
|
|
473
|
+
new_cell_.set_editable(cell.get_locale)
|
|
474
|
+
|
|
475
|
+
x += 55
|
|
476
|
+
if x >= @paper[:width] - 30
|
|
477
|
+
x = 10
|
|
478
|
+
y += 30
|
|
479
|
+
if y >= @paper[:height] - 15
|
|
480
|
+
y = 10
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
# x -= 55
|
|
484
|
+
# if x <= 10
|
|
485
|
+
# x = @paper[ :width ] - 60
|
|
486
|
+
# y -= 30
|
|
487
|
+
# if y <= 50
|
|
488
|
+
# y = @paper[ :height ] -30
|
|
489
|
+
# end
|
|
490
|
+
# end
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
set_location_from_tecsgen_old
|
|
494
|
+
#------ validate and set location info from __tool_info( "tecscde" ) ------#
|
|
495
|
+
# begin
|
|
496
|
+
if validate || $b_force_apply_tool_info
|
|
497
|
+
TECSCDE.logger.info("=== set_paper ===")
|
|
498
|
+
set_paper_from_tecsgen
|
|
499
|
+
|
|
500
|
+
TECSCDE.logger.info("=== set_cell_location ===")
|
|
501
|
+
set_cell_location_from_tecsgen
|
|
502
|
+
else
|
|
503
|
+
TECSCDE.logger.error("validate error in __tool_info__( \"tecscde\" )")
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
TECSCDE.logger.info("=== create join ===")
|
|
507
|
+
tecsgen_cell_list2.each do |cell|
|
|
508
|
+
cell.get_join_list.get_items.each do |join|
|
|
509
|
+
if join.get_array_member2.nil?
|
|
510
|
+
create_join_from_tecsgen(cell, join, cell_list)
|
|
511
|
+
else
|
|
512
|
+
join.get_array_member2.each do |j|
|
|
513
|
+
if j
|
|
514
|
+
create_join_from_tecsgen(cell, j, cell_list)
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
if validate || $b_force_apply_tool_info
|
|
522
|
+
TECSCDE.logger.info("=== set_join_location ===")
|
|
523
|
+
set_join_location_from_tecsgen
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
#=== TECSModel#create_cell_from_tecsgen
|
|
528
|
+
def create_cell_from_tecsgen(cell, x, y)
|
|
529
|
+
new_cell_ = new_cell(x, y, cell.get_celltype.get_name, cell.get_celltype.get_owner.get_namespace_path.to_s, cell)
|
|
530
|
+
new_name = cell.get_name # automatically given name
|
|
531
|
+
new_cell_.change_name(new_name)
|
|
532
|
+
|
|
533
|
+
# decide cell box size from text width
|
|
534
|
+
w, h = @view.get_text_extent(new_name, CELL_NAME, ALIGN_CENTER, TEXT_HORIZONTAL)
|
|
535
|
+
w2, h = @view.get_text_extent(cell.get_celltype.get_name, CELLTYPE_NAME, ALIGN_CENTER, TEXT_HORIZONTAL)
|
|
536
|
+
w = w2 if w2 > w
|
|
537
|
+
w += 2
|
|
538
|
+
h += 2
|
|
539
|
+
w = 25 if w < 25
|
|
540
|
+
h = 15 if h < 15
|
|
541
|
+
new_cell_.set_geometry(x, y, w, h)
|
|
542
|
+
new_cell_
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
#=== TECSModel#create_join_from_tecsgen
|
|
546
|
+
def create_join_from_tecsgen(cell, join, cell_list)
|
|
547
|
+
# p join.get_name
|
|
548
|
+
object = cell.get_celltype.find(join.get_name)
|
|
549
|
+
# p "OBJECT CLASS #{object.class}"
|
|
550
|
+
if object.instance_of?(::Port)
|
|
551
|
+
return unless object.get_port_type == :CALL
|
|
552
|
+
return if object.is_require?
|
|
553
|
+
lhs_cell = cell_list[cell]
|
|
554
|
+
cport = lhs_cell.get_cport_for_new_join(join.get_name, join.get_subscript)
|
|
555
|
+
if cport.nil?
|
|
556
|
+
TECSCDE.logger.error("#{@name}.#{join.get_name} not found")
|
|
557
|
+
return
|
|
558
|
+
end
|
|
559
|
+
rhs_cell = cell_list[join.get_cell]
|
|
560
|
+
if rhs_cell.nil? # not joined in cdl (tecsgen)
|
|
561
|
+
return
|
|
562
|
+
end
|
|
563
|
+
# eport = rhs_cell.eports[ join.get_port_name ]
|
|
564
|
+
eport = rhs_cell.get_eport_for_new_join(join.get_port_name, join.get_rhs_subscript1)
|
|
565
|
+
# p "new_join #{lhs_cell.get_name}.#{cport.get_name} => #{rhs_cell.get_name}.#{eport.get_name}"
|
|
566
|
+
new_join_ = new_join(cport, eport)
|
|
567
|
+
new_join_.set_editable(join.get_locale)
|
|
568
|
+
else
|
|
569
|
+
cell_list[cell].set_attr(join.get_name, join.get_rhs.to_CDL_str)
|
|
570
|
+
end
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
def set_paper_from_tecsgen
|
|
574
|
+
info = TOOL_INFO.get_tool_info(:tecscde)
|
|
575
|
+
return if info.nil? || info[:paper].nil?
|
|
576
|
+
|
|
577
|
+
#----- paper -----#
|
|
578
|
+
paper_info = info[:paper]
|
|
579
|
+
return unless paper_info
|
|
580
|
+
size = paper_info[:size]
|
|
581
|
+
orientation = paper_info[:orientation]
|
|
582
|
+
paper = nil
|
|
583
|
+
PAPERS.each do |_name, spec|
|
|
584
|
+
if spec.size == size && spec.orientation == orientation
|
|
585
|
+
TECSCDE.logger.info("paper found #{spec.name}")
|
|
586
|
+
paper = spec
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
@paper = paper if paper
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
def set_cell_location_from_tecsgen
|
|
593
|
+
info = TOOL_INFO.get_tool_info(:tecscde)
|
|
594
|
+
if info.nil? || info[:cell_list].nil?
|
|
595
|
+
return
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
#----- cell location -----#
|
|
599
|
+
info[:cell_list].each do |cell_location|
|
|
600
|
+
# region = cell_location[ :region ].to_sym
|
|
601
|
+
name = cell_location[:name].to_sym
|
|
602
|
+
loc = cell_location[:location]
|
|
603
|
+
if loc.length != 4
|
|
604
|
+
TECSCDE.logger.error("#{name}: cell_location.location: array length is not inconsistent, #{loc.length} for 4")
|
|
605
|
+
next
|
|
606
|
+
end
|
|
607
|
+
cell = @cell_hash[name]
|
|
608
|
+
if cell
|
|
609
|
+
# p "apply location: #{cell.get_name}"
|
|
610
|
+
cell.set_geometry(*loc)
|
|
611
|
+
|
|
612
|
+
#------ port location -----#
|
|
613
|
+
cell_location[:port_location].each do |port_location|
|
|
614
|
+
# mikan offset not set yet
|
|
615
|
+
port_name = port_location[:port_name].to_sym
|
|
616
|
+
edge = get_edge_side_val(port_location[:edge])
|
|
617
|
+
offset = port_location[:offset]
|
|
618
|
+
subscript = port_location[:subscript]
|
|
619
|
+
port = cell.cports[port_name]
|
|
620
|
+
if port.nil?
|
|
621
|
+
port = cell.eports[port_name]
|
|
622
|
+
end
|
|
623
|
+
if port.nil?
|
|
624
|
+
TECSCDE.logger.info("port '#{port_name}' not found")
|
|
625
|
+
next
|
|
626
|
+
end
|
|
627
|
+
if subscript
|
|
628
|
+
unless port.array?
|
|
629
|
+
TECSCDE.logger.info("port '#{port_name}' : 'subscript' specified but not array")
|
|
630
|
+
next
|
|
631
|
+
end
|
|
632
|
+
if subscript < 0
|
|
633
|
+
TECSCDE.logger.info("port '#{port_name}' : 'subscript' negative valude specified")
|
|
634
|
+
next
|
|
635
|
+
end
|
|
636
|
+
port = port.ports[subscript] # array
|
|
637
|
+
if port.nil?
|
|
638
|
+
TECSCDE.logger.info("port '#{port_name}' : 'subscript=#{subscript}' out of range")
|
|
639
|
+
next
|
|
640
|
+
end
|
|
641
|
+
else
|
|
642
|
+
if port.array?
|
|
643
|
+
TECSCDE.logger.info("port '#{port_name}' : array but no 'subscript' specified")
|
|
644
|
+
next
|
|
645
|
+
end
|
|
646
|
+
end
|
|
647
|
+
port.set_position(edge, offset)
|
|
648
|
+
end
|
|
649
|
+
else
|
|
650
|
+
@cell_hash.each do |a, _b|
|
|
651
|
+
TECSCDE.logger.info(a)
|
|
652
|
+
end
|
|
653
|
+
TECSCDE.logger.info("not apply location: #{name}")
|
|
654
|
+
next
|
|
655
|
+
end
|
|
656
|
+
end
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
def set_join_location_from_tecsgen
|
|
660
|
+
info = TOOL_INFO.get_tool_info(:tecscde)
|
|
661
|
+
if info.nil?
|
|
662
|
+
return
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
#----- join location -----#
|
|
666
|
+
info[:join_list].each do |jl|
|
|
667
|
+
# jl[ :call_region ]
|
|
668
|
+
cp_cell_nspath = jl[:call_cell].to_sym
|
|
669
|
+
cp_name = jl[:call_port].to_sym
|
|
670
|
+
cp_subscript = jl[:call_port_subscript]
|
|
671
|
+
# jl[ :entry_region ]
|
|
672
|
+
ep_cell_nspath = jl[:entry_cell].to_sym
|
|
673
|
+
ep_name = jl[:entry_port].to_sym
|
|
674
|
+
ep_subscript = jl[:entry_port_subscript]
|
|
675
|
+
|
|
676
|
+
bl = jl[:bar_list]
|
|
677
|
+
bar_list = []
|
|
678
|
+
bl.each do |bar|
|
|
679
|
+
bar_list << [bar[:type], bar[:position]]
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
# cp_cell_nspath, cp_name, ep_cell_nspath, ep_name, bar_list = jl.get_location
|
|
683
|
+
# p "set_location_from_tecsgen, #{cp_cell_nspath}, #{cp_name}, #{ep_cell_nspath}, #{ep_name}, #{bar_list}"
|
|
684
|
+
cp_cell = @cell_hash[cp_cell_nspath]
|
|
685
|
+
ep_cell = @cell_hash[ep_cell_nspath]
|
|
686
|
+
# check existance of cells
|
|
687
|
+
next if cp_cell.nil?
|
|
688
|
+
next if ep_cell.nil?
|
|
689
|
+
cport = cp_cell.cports[cp_name]
|
|
690
|
+
if cport.is_a?(TmCPortArray)
|
|
691
|
+
if cp_subscript.nil?
|
|
692
|
+
TECSCDE.logger.error("TM9999 location information ignored #{cp_name} is array but not specified subscript")
|
|
693
|
+
next
|
|
694
|
+
end
|
|
695
|
+
cport = cport.get_member(cp_subscript)
|
|
696
|
+
else
|
|
697
|
+
if cp_subscript
|
|
698
|
+
TECSCDE.logger.error("TM9999 #{cp_name} is not array but specified subscript")
|
|
699
|
+
end
|
|
700
|
+
end
|
|
701
|
+
eport = ep_cell.eports[ep_name]
|
|
702
|
+
if eport.is_a?(TmEPortArray)
|
|
703
|
+
if ep_subscript.nil?
|
|
704
|
+
TECSCDE.logger.error("TM9999 location information ignored #{ep_name} is array but not specified subscript")
|
|
705
|
+
next
|
|
706
|
+
end
|
|
707
|
+
eport = eport.get_member(ep_subscript)
|
|
708
|
+
else
|
|
709
|
+
if ep_subscript
|
|
710
|
+
TECSCDE.logger.error("TM9999 #{ep_name} is not array but specified subscript")
|
|
711
|
+
end
|
|
712
|
+
end
|
|
713
|
+
# p "1 #{cp_name} #{cp_subscript} #{ep_name} #{ep_subscript} #{cport} #{eport}"
|
|
714
|
+
|
|
715
|
+
# check existance of cport & eport and direction of bar & edge (must be in right angle)
|
|
716
|
+
# mikan necessary more than 2 bars
|
|
717
|
+
next if cport.nil?
|
|
718
|
+
next if eport.nil?
|
|
719
|
+
next unless eport.include?(cport.get_join(cp_subscript))
|
|
720
|
+
next unless bar_list.length >= 2
|
|
721
|
+
# p "2"
|
|
722
|
+
bar_type = bar_list[0][0].to_sym
|
|
723
|
+
next if TECSModel.vertical?(cport.get_edge_side) && bar_type == :VBar
|
|
724
|
+
next if TECSModel.horizontal?(cport.get_edge_side) && bar_type == :HBar
|
|
725
|
+
# p "3"
|
|
726
|
+
len = bar_list.length
|
|
727
|
+
|
|
728
|
+
normal_pos = bar_list[len - 1][1]
|
|
729
|
+
tan_pos = bar_list[len - 2][1]
|
|
730
|
+
# p "normal_pos=#{normal_pos}, eport_normal=#{eport.get_position_in_normal_dir}"
|
|
731
|
+
# p "tan_pos=#{tan_pos}, eport_tan=#{eport.get_position_in_tangential_dir}"
|
|
732
|
+
# check if normal_pos & tan_pos can be evaluated and the position of bars goal
|
|
733
|
+
if !normal_pos.nil? && !tan_pos.nil? &&
|
|
734
|
+
((normal_pos - eport.get_position_in_normal_dir).abs <= MAX_ERROR_IN_NOR) &&
|
|
735
|
+
((tan_pos - eport.get_position_in_tangential_dir).abs <= MAX_ERROR_IN_TAN)
|
|
736
|
+
# p "4"
|
|
737
|
+
bars = []
|
|
738
|
+
bar_list.each do |bar_info|
|
|
739
|
+
# bar_list: array of [ IDENTIFER, position ] => bars ( array of HBar or VBar )
|
|
740
|
+
pos = bar_info[1]
|
|
741
|
+
if !pos.nil? && bar_info[0].to_sym == :HBar
|
|
742
|
+
bar = HBar.new(pos, cport.get_join)
|
|
743
|
+
bars << bar
|
|
744
|
+
elsif !pos.nil? && bar_info[0].to_sym == :VBar
|
|
745
|
+
bar = VBar.new(pos, cport.get_join)
|
|
746
|
+
bars << bar
|
|
747
|
+
else
|
|
748
|
+
bars = []
|
|
749
|
+
break
|
|
750
|
+
end
|
|
751
|
+
end
|
|
752
|
+
# mikan length more than 2
|
|
753
|
+
len = bars.length
|
|
754
|
+
if len >= 0.1
|
|
755
|
+
bars[len - 1].set_position(eport.get_position_in_normal_dir)
|
|
756
|
+
bars[len - 2].set_position(eport.get_position_in_tangential_dir)
|
|
757
|
+
# p "bar changed for #{cp_cell_nspath}.#{cport.get_name}"
|
|
758
|
+
cport.get_join.change_bars(bars)
|
|
759
|
+
end
|
|
760
|
+
end
|
|
761
|
+
end
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
#=== TECSModel#validate
|
|
765
|
+
# validate JSON format data in __tool_info__( "tecscde" )
|
|
766
|
+
def validate
|
|
767
|
+
validator = TOOL_INFO::VALIDATOR.new(:tecscde, TECSCDE_SCHEMA)
|
|
768
|
+
validator.validate
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
#=== save data ***
|
|
772
|
+
def save(filename)
|
|
773
|
+
File.open(filename, "w") do |file|
|
|
774
|
+
file.write(render)
|
|
775
|
+
end
|
|
776
|
+
rescue => ex
|
|
777
|
+
TECSCDE.message_box("fail to save #{filename}\n#{ex}", :OK)
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
def render
|
|
781
|
+
erb = ERB.new(File.read(File.join(__dir__, "templates", "main.cde.erb")), nil, "-")
|
|
782
|
+
erb.result(binding)
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
def render_partial(file, indent_width: 8, **kw)
|
|
786
|
+
erb = ERB.new(File.read(File.join(__dir__, "templates", file)), nil, "-")
|
|
787
|
+
b = binding
|
|
788
|
+
kw.each do |name, value|
|
|
789
|
+
b.local_variable_set(name, value)
|
|
790
|
+
end
|
|
791
|
+
lines = erb.result(b).lines
|
|
792
|
+
string = lines.first.dup
|
|
793
|
+
lines[1..-1].each do |line|
|
|
794
|
+
string << " " * indent_width
|
|
795
|
+
string << line
|
|
796
|
+
end
|
|
797
|
+
string
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
def base_directories
|
|
801
|
+
dirs = $base_dir.select do |dir, necessary|
|
|
802
|
+
necessary
|
|
803
|
+
end
|
|
804
|
+
dirs.keys
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
def define_macros
|
|
808
|
+
$define
|
|
809
|
+
end
|
|
810
|
+
|
|
811
|
+
def import_paths
|
|
812
|
+
tecspath = $tecspath.gsub(/\\/, '\\\\\\\\')
|
|
813
|
+
$import_path.reject do |path|
|
|
814
|
+
path =~ Regexp.new("\\A#{tecspath}")
|
|
815
|
+
end
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
def direct_imports
|
|
819
|
+
imports = Import.get_list
|
|
820
|
+
return [] if imports.empty?
|
|
821
|
+
imports = imports.select do |_path, import|
|
|
822
|
+
(import.is_imported? == false) && (import.get_cdl_name != @file_editing)
|
|
823
|
+
end
|
|
824
|
+
imports.values.map(&:get_cdl_name)
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
def tecsgen
|
|
828
|
+
{
|
|
829
|
+
tecscde_version: TECSCDE::VERSION,
|
|
830
|
+
cde_format_version: TECSCDE::FORMAT_VERSION,
|
|
831
|
+
save_date: DateTime.now,
|
|
832
|
+
base_dir: base_directories,
|
|
833
|
+
define_macro: define_macros,
|
|
834
|
+
import_path: import_paths,
|
|
835
|
+
direct_import: direct_imports
|
|
836
|
+
}
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
def generate_cports_lines(cports, indet_width = 4)
|
|
840
|
+
lines = []
|
|
841
|
+
cports.each do |_name, cport|
|
|
842
|
+
if cport.array?
|
|
843
|
+
cport.ports.each do |call_port|
|
|
844
|
+
join = call_port.get_join
|
|
845
|
+
next unless join
|
|
846
|
+
entry_port = join. eport
|
|
847
|
+
subscript = if entry_port.get_subscript
|
|
848
|
+
"[ #{entry_port.get_subscript} ]"
|
|
849
|
+
else
|
|
850
|
+
""
|
|
851
|
+
end
|
|
852
|
+
lines << "#{call_port.get_name}[ #{call_port.get_subscript} ] = #{entry_port.get_cell.get_name}.#{entry_port.get_name}#{subscript};"
|
|
853
|
+
end
|
|
854
|
+
else
|
|
855
|
+
join = cport.get_join
|
|
856
|
+
next unless join
|
|
857
|
+
entry_port = join.eport
|
|
858
|
+
subscript = if entry_port.get_subscript
|
|
859
|
+
"[ #{entry_port.get_subscript} ]"
|
|
860
|
+
else
|
|
861
|
+
""
|
|
862
|
+
end
|
|
863
|
+
lines << "#{cport.get_name} = #{entry_port.get_cell.get_name}.#{entry_port.get_name}#{subscript};"
|
|
864
|
+
end
|
|
865
|
+
end
|
|
866
|
+
lines
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
def port_location(ports)
|
|
870
|
+
ports.map do |port|
|
|
871
|
+
if port.array?
|
|
872
|
+
port.ports.map do |child|
|
|
873
|
+
{
|
|
874
|
+
type: "port_location",
|
|
875
|
+
port_name: port.get_name,
|
|
876
|
+
subscript: port.get_subscript,
|
|
877
|
+
edge: port.get_edge_side_name,
|
|
878
|
+
offset: port.offset
|
|
879
|
+
}
|
|
880
|
+
end
|
|
881
|
+
else
|
|
882
|
+
{
|
|
883
|
+
type: "port_location",
|
|
884
|
+
port_name: port.get_name,
|
|
885
|
+
edge: port.get_edge_side_name,
|
|
886
|
+
offset: port.offset
|
|
887
|
+
}
|
|
888
|
+
end
|
|
889
|
+
end
|
|
890
|
+
end
|
|
891
|
+
|
|
892
|
+
#----- old syntax for location information -----#
|
|
893
|
+
# load code is still used for old data.
|
|
894
|
+
|
|
895
|
+
#=== TECSModel#set_location_from_tecsgen
|
|
896
|
+
# get location information from cde file and apply it to TmCell & TmJoin
|
|
897
|
+
def set_location_from_tecsgen_old
|
|
898
|
+
# set cell location
|
|
899
|
+
@tecsgen.get_cell_location_list.each do |cl|
|
|
900
|
+
cell_nspath, x, y, w, h, port_location_list = cl.get_location
|
|
901
|
+
# p "set_location_from_tecsgen", cell_nspath, x, y, w, h, port_location_list
|
|
902
|
+
cell = @cell_hash[cell_nspath.to_s.to_sym]
|
|
903
|
+
# p "apply location: #{cell&.get_name}"
|
|
904
|
+
cell&.set_geometry(x, y, w, h)
|
|
905
|
+
end
|
|
906
|
+
|
|
907
|
+
# set join location
|
|
908
|
+
@tecsgen.get_join_location_list.each do |jl|
|
|
909
|
+
cp_cell_nspath, cp_name, ep_cell_nspath, ep_name, bar_list = jl.get_location
|
|
910
|
+
cp_subscript = nil # kari
|
|
911
|
+
ep_subscript = nil
|
|
912
|
+
# p "set_location_from_tecsgen, #{cp_cell_nspath}, #{cp_name}, #{ep_cell_nspath}, #{ep_name}, #{bar_list}"
|
|
913
|
+
cp_cell = @cell_hash[cp_cell_nspath.to_s.to_sym]
|
|
914
|
+
ep_cell = @cell_hash[ep_cell_nspath.to_s.to_sym]
|
|
915
|
+
# check existance of cells
|
|
916
|
+
next if cp_cell.nil? || ep_cell.nil?
|
|
917
|
+
cport = cp_cell.cports[cp_name.to_sym]
|
|
918
|
+
eport = ep_cell.eports[ep_name.to_sym]
|
|
919
|
+
# p "1 #{cp_name} #{ep_name} #{cport} #{eport}"
|
|
920
|
+
|
|
921
|
+
# check existance of cport & eport and direction of bar & edge (must be in right angle)
|
|
922
|
+
# mikan necessary more than 2 bars
|
|
923
|
+
next if cport.nil? || eport.nil?
|
|
924
|
+
next unless eport.include?(cport.get_join(cp_subscript))
|
|
925
|
+
next unless bar_list.length >= 2
|
|
926
|
+
# p "2"
|
|
927
|
+
bar_type = bar_list[0][0]
|
|
928
|
+
next if TECSModel.vertical?(cport.get_edge_side) && bar_type == :VBar
|
|
929
|
+
next if TECSModel.horizontal?(cport.get_edge_side) && bar_type == :HBar
|
|
930
|
+
# p "3"
|
|
931
|
+
len = bar_list.length
|
|
932
|
+
# bar_list: [ [:HBar, pos]
|
|
933
|
+
normal_pos = bar_list[len - 1][1].eval_const(nil)
|
|
934
|
+
tan_pos = bar_list[len - 2][1].eval_const(nil)
|
|
935
|
+
# p "normal_pos=#{normal_pos}, eport_normal=#{eport.get_position_in_normal_dir}"
|
|
936
|
+
# p "tan_pos=#{tan_pos}, eport_tan=#{eport.get_position_in_tangential_dir}"
|
|
937
|
+
# check if normal_pos & tan_pos can be evaluated and the position of bars goal
|
|
938
|
+
if !normal_pos.nil? && !tan_pos.nil? &&
|
|
939
|
+
((normal_pos - eport.get_position_in_normal_dir).abs <= MAX_ERROR_IN_NOR) &&
|
|
940
|
+
((tan_pos - eport.get_position_in_tangential_dir).abs <= MAX_ERROR_IN_TAN)
|
|
941
|
+
# p "4"
|
|
942
|
+
bars = []
|
|
943
|
+
bar_list.each do |bar_info|
|
|
944
|
+
# bar_list: array of [ IDENTIFER, position ] => bars ( array of HBar or VBar )
|
|
945
|
+
pos = bar_info[1].eval_const(nil)
|
|
946
|
+
if !pos.nil? && bar_info[0] == :HBar
|
|
947
|
+
bar = HBar.new(pos, cport.get_join)
|
|
948
|
+
bars << bar
|
|
949
|
+
elsif !pos.nil? && bar_info[0] == :VBar
|
|
950
|
+
bar = VBar.new(pos, cport.get_join)
|
|
951
|
+
bars << bar
|
|
952
|
+
else
|
|
953
|
+
bars = []
|
|
954
|
+
break
|
|
955
|
+
end
|
|
956
|
+
end
|
|
957
|
+
# mikan length more than 2
|
|
958
|
+
len = bars.length
|
|
959
|
+
if len >= 2
|
|
960
|
+
bars[len - 1].set_position(eport.get_position_in_normal_dir)
|
|
961
|
+
bars[len - 2].set_position(eport.get_position_in_tangential_dir)
|
|
962
|
+
# p "bar changed for #{cp_cell_nspath}.#{cport.get_name}"
|
|
963
|
+
cport.get_join.change_bars(bars)
|
|
964
|
+
end
|
|
965
|
+
end
|
|
966
|
+
end
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
#=== TECSModel#get_edge_side_val
|
|
970
|
+
def get_edge_side_val(edge_side_name)
|
|
971
|
+
case edge_side_name
|
|
972
|
+
when "EDGE_TOP"
|
|
973
|
+
EDGE_TOP
|
|
974
|
+
when "EDGE_BOTTOM"
|
|
975
|
+
EDGE_BOTTOM
|
|
976
|
+
when "EDGE_LEFT"
|
|
977
|
+
EDGE_LEFT
|
|
978
|
+
when "EDGE_RIGHT"
|
|
979
|
+
EDGE_RIGHT
|
|
980
|
+
else
|
|
981
|
+
0 # same as EDGE_TOP
|
|
982
|
+
end
|
|
983
|
+
end
|
|
984
|
+
end
|
|
985
|
+
end
|
|
986
|
+
|
|
987
|
+
require "tecscde/tecs_model/tm_c_port"
|
|
988
|
+
require "tecscde/tecs_model/tm_c_port_array"
|
|
989
|
+
require "tecscde/tecs_model/tm_cell"
|
|
990
|
+
require "tecscde/tecs_model/tm_e_port"
|
|
991
|
+
require "tecscde/tecs_model/tm_e_port_array"
|
|
992
|
+
require "tecscde/tecs_model/tm_join"
|
|
993
|
+
require "tecscde/tecs_model/tm_join_bar"
|
|
994
|
+
require "tecscde/tecs_model/tm_port"
|
|
995
|
+
require "tecscde/tecs_model/tm_port_array"
|
|
996
|
+
require "tecscde/tecs_model/tm_region"
|
|
997
|
+
require "tecscde/tecs_model/tm_uneditable"
|
|
998
|
+
require "tecscde/tecs_model/hbar"
|
|
999
|
+
require "tecscde/tecs_model/vbar"
|
|
1000
|
+
|
|
1001
|
+
#
|
|
1002
|
+
# Software Design Memo
|
|
1003
|
+
#
|
|
1004
|
+
# pattern of lines between cells
|
|
1005
|
+
#
|
|
1006
|
+
# (a) parallel opposite side generic
|
|
1007
|
+
# (b) parallel opposite side abbreviated
|
|
1008
|
+
# (c) right angle generic
|
|
1009
|
+
# (d) right angle abbreviated
|
|
1010
|
+
# (e) parallel same side generic
|
|
1011
|
+
# (f) parallel same side abbreviated
|
|
1012
|
+
#
|
|
1013
|
+
# applying abbrviated patterns, there is conditions.
|
|
1014
|
+
#
|
|
1015
|
+
# +-------------+
|
|
1016
|
+
# | (f)|---------------------------1+
|
|
1017
|
+
# | (d)|-------------------1+ |
|
|
1018
|
+
# | (e)|----1+ | |
|
|
1019
|
+
# | (c)|---1+| | |
|
|
1020
|
+
# | (a)|--1+|| | |
|
|
1021
|
+
# | (b)|-1+||| | |
|
|
1022
|
+
# | (c)'|-+|||| | |
|
|
1023
|
+
# +-------------+ ||||| | |
|
|
1024
|
+
# ||||+2-------------------3+|
|
|
1025
|
+
# |||+2---------3+ | ||
|
|
1026
|
+
# ||+2---3+ | | ||
|
|
1027
|
+
# || | +-------------+ ||
|
|
1028
|
+
# || 4 | V V | 4|
|
|
1029
|
+
# || +-|> <|-+|
|
|
1030
|
+
# |+2-------|> <|-2+
|
|
1031
|
+
# | | ^ |
|
|
1032
|
+
# | +-------------+
|
|
1033
|
+
# | |
|
|
1034
|
+
# +--------------+
|
|
1035
|
+
#
|
|
1036
|
+
# edge_side
|
|
1037
|
+
# horizontal
|
|
1038
|
+
# EDGE_TOP = 0b00
|
|
1039
|
+
# EDGE_BOTTOM = 0b01
|
|
1040
|
+
# vertical
|
|
1041
|
+
# EDGE_LEFT = 0b10
|
|
1042
|
+
# EDGE_RIGHT = 0b11
|
|
1043
|
+
#
|
|
1044
|
+
#
|
|
1045
|
+
# bit0: 1 if normal direction is positive, 0 negative
|
|
1046
|
+
# bit1: 1 if vertical, 0 if horizontal
|
|
1047
|
+
#
|
|
1048
|
+
# TECSModel class method
|
|
1049
|
+
# get_sign_of_normal( edge_side ) = (edge_side & 0b01) ? 1 : -1
|
|
1050
|
+
# vertical?( edge_side ) = (edge_side & 0b10) ? true : false
|
|
1051
|
+
# parallel?( edge_side1, edge_side2 ) = ( edge_side1 ^ edge_side2 ) < 0b10
|
|
1052
|
+
# opposite?( edge_side1, edge_side2 ) = ( ( edge_side1 ^ edge_side2 ) & 0b01 ) ? true : false
|
|
1053
|
+
# this function can be applicable only when edge_side1, edge_side2 are parallel
|
|
1054
|
+
#
|
|
1055
|
+
# TmCell#get_edge_position_in_normal_dir( edge_side )
|
|
1056
|
+
# case edge_side
|
|
1057
|
+
# when EDGE_TOP y
|
|
1058
|
+
# when EDGE_BOTTOM y+height
|
|
1059
|
+
# when EDGE_LEFT x
|
|
1060
|
+
# when EDGE_RIGHT x+width
|
|
1061
|
+
#
|
|
1062
|
+
# #=== (1) (6) bar from call port. this indicate A position.
|
|
1063
|
+
# TmCPort#get_normal_bar_of_edge
|
|
1064
|
+
# pos = @cell.get_edge_position_in_normal_dir( @edge_side ) + GAP * TECSModel.get_sign_of_normal( @edge_side )
|
|
1065
|
+
# TECSModel.vertical?( @edge_side ) ? HBar.new( pos ) : VBar.new( pos )
|
|
1066
|
+
#
|
|
1067
|
+
# TmCPort#tangential_position
|
|
1068
|
+
# ( TECSModel.vertical? @edge_side ) ? @cell.get_y + @offs : @cell.get_x + @offs
|
|
1069
|
+
#
|
|
1070
|
+
# TmJoin#create_bars
|
|
1071
|
+
# if TECSModel.parallel?( @edge_side, dest_port.get_edge_side )
|
|
1072
|
+
# if TECSModel.opposite?( @edge_side, dest_port.get_edge_side )
|
|
1073
|
+
# create_bars_a
|
|
1074
|
+
# else
|
|
1075
|
+
# create_bars_e
|
|
1076
|
+
# else
|
|
1077
|
+
# create_bars_c
|
|
1078
|
+
#
|
|
1079
|
+
# TmJoin#create_bars_a
|
|
1080
|
+
# @bars = []
|
|
1081
|
+
#
|
|
1082
|
+
# @bars[0] = @cport.get_normal_bar_of_edge
|
|
1083
|
+
#
|
|
1084
|
+
# posa = @cport.get_position_in_tangential_dir
|
|
1085
|
+
# e1, e2 = @eport.get_cell.get_right_angle_edges_position( @cport.get_edge_side )
|
|
1086
|
+
# pos2 = ( posa - e1 ).abs > ( posa - e2 ).abs ? e2 : e1
|
|
1087
|
+
# @bars[2] = (bar[1].instance_of? HBar) ? VBar.new( pos2 ) : HBar.new( pos2 )
|
|
1088
|
+
#
|
|
1089
|
+
# pos3 = @eport.get_position_in_normal_dir + GAP * @eport.get_sign_of_normal
|
|
1090
|
+
# @bars[2] = (@bars[1].instance_of? HBar) ? VBar.new( pos3 ) : HBar.new( pos3 )
|
|
1091
|
+
#
|
|
1092
|
+
# pos4 = @eport.get_position_in_normal_dir + GAP * @eport.get_sign_of_normal
|
|
1093
|
+
# @bars[3] = (@bars[2].instance_of? HBar) ? VBar.new( pos4 ) : HBar.new( pos4 )
|
|
1094
|
+
#
|
|
1095
|
+
# pos5 = @eport.get_position_in_tangential_dir
|
|
1096
|
+
# @bars[4] = (@bars[3].instance_of? HBar) ? VBar.new( pos5 ) : HBar.new( pos5 )
|
|
1097
|
+
#
|
|
1098
|
+
# pos6 = @eport.get_position_in_normal_dir
|
|
1099
|
+
# @bars[5] = (@bars[4].instance_of? HBar) ? VBar.new( pos6 ) : HBar.new( pos6 )
|
|
1100
|
+
#
|
|
1101
|
+
# TmJoin#create_bars_c
|
|
1102
|
+
# @bars = []
|
|
1103
|
+
#
|
|
1104
|
+
# @bars[0] = @cport.get_normal_bar_of_edge
|
|
1105
|
+
#
|
|
1106
|
+
# pos1 = @eport.get_position_in_normal_dir + GAP * @eport.get_sign_of_normal
|
|
1107
|
+
# @bars[1] = (bar[0].instance_of? HBar) ? VBar.new( pos1 ) : HBar.new( pos1 )
|
|
1108
|
+
#
|
|
1109
|
+
# pos2 = @eport.get_position_in_tangential_dir
|
|
1110
|
+
# @bars[2] = (bar[1].instance_of? HBar) ? VBar.new( pos2 ) : HBar.new( pos2 )
|
|
1111
|
+
#
|
|
1112
|
+
# pos3 = @eport.get_position_in_normal_dir
|
|
1113
|
+
# @bars[3] = (bar[2].instance_of? HBar) ? VBar.new( pos3 ) : HBar.new( pos3 )
|
|
1114
|
+
#
|
|
1115
|
+
# TmJoin#create_bars_e
|
|
1116
|
+
# @bars = []
|
|
1117
|
+
#
|
|
1118
|
+
# @bars[0] = @cport.get_normal_bar_of_edge
|
|
1119
|
+
#
|
|
1120
|
+
# pos1 = @eport.get_position_in_normal_dir + GAP * @eport.get_sign_of_normal
|
|
1121
|
+
# @bars[1] = (bar[0].instance_of? HBar) ? VBar.new( pos1 ) : HBar.new( pos1 )
|
|
1122
|
+
#
|
|
1123
|
+
# posa = @cport.get_position_in_tangential_dir
|
|
1124
|
+
# e1, e2 = @eport.get_cell.get_right_angle_edges_position( @cport.get_edge_side )
|
|
1125
|
+
# pos2 = ( posa - e1 ).abs > ( posa - e2 ).abs ? e2 : e1
|
|
1126
|
+
# @bars[2] = (bar[1].instance_of? HBar) ? VBar.new( pos2 ) : HBar.new( pos2 )
|
|
1127
|
+
#
|
|
1128
|
+
# pos3 = @eport.get_position_in_normal_dir + GAP * @eport.get_sign_of_normal
|
|
1129
|
+
# @bars[3] = (bar[2].instance_of? HBar) ? VBar.new( pos3 ) : HBar.new( pos3 )
|
|
1130
|
+
#
|
|
1131
|
+
# pos4 = @eport.get_position_in_normal_dir
|
|
1132
|
+
# @bars[4] = (bar[3].instance_of? HBar) ? VBar.new( pos4 ) : HBar.new( pos4 )
|
|
1133
|
+
#
|
|
1134
|
+
#
|
|
1135
|
+
#
|
|
1136
|
+
#----- JSON schema (likely) -----#
|
|
1137
|
+
#
|