Compare commits

...

105 Commits

Author SHA1 Message Date
ccc8d80ac2 add help plugin and handler, eclipse help does not start 2021-11-16 18:24:30 +01:00
1af3171b2e cleanup imports 2021-11-16 14:15:33 +01:00
03fd9e154b Merge branch 'master' into develop 2021-11-16 14:13:22 +01:00
3572f683e3 add zoom levels 2021-11-16 14:12:10 +01:00
524ffb189c fix MT race condition 2021-11-16 14:11:30 +01:00
7fac6c8f74 Merge branch 'release/2.14.1' into develop 2021-11-16 11:32:41 +01:00
037c645075 Merge branch 'release/2.14.1' 2021-11-16 11:32:41 +01:00
2f9bd29dc8 update version numbers 2021-11-16 11:32:34 +01:00
92662c546a fix zoom level calculation 2021-11-16 11:28:32 +01:00
efa6544623 cleanup 2021-11-16 11:27:58 +01:00
52cf9daeec unify time printing (#69) 2021-11-16 09:37:50 +01:00
4a315722b1 add help browser window instead of dialog 2021-11-16 09:33:09 +01:00
a52efd1a12 Merge branch 'master' into develop 2021-11-15 22:25:12 +01:00
535df30ada Merge branch 'release/2.14.0' into develop 2021-11-15 21:38:51 +01:00
bad34dd1d1 Merge branch 'release/2.14.0' 2021-11-15 21:38:51 +01:00
5ac7f05f57 Merge branch 'master' of https://git.minres.com/VP-Tools/SCViewer 2021-11-15 21:37:51 +01:00
8353b59a27 update version numbers for release
This release fixes the following tickets:
* #62: Instead of or in addition to the Restore Default Zoom button, add
Full Zoom Out button.
* #64: Load multiple trace files and enable the possibility to view
signals from different files in a single window.
* partial #66: key shortcuts for actions like zoom in/out, go to
next/prev event etc
* #70: add full zoom and zoom between markers (once we had markers)
* #75: marker is often hiding events underneath for highlighting and
getting transaction details
* #82: Implement help for keyboard shortcuts
2021-11-15 21:29:08 +01:00
2c6ca6c376 update version number to 2.14 2021-11-15 21:25:05 +01:00
f4b03cb0e6 extend zoom handling (#70) and hide tx property panes (#58) 2021-11-15 21:23:13 +01:00
c7858997c0 update README.md 2021-11-15 15:18:56 +01:00
bd99ab3992 corrected parent path im poms 2021-11-15 15:14:04 +01:00
66f365d38d externalize string in HelpDialog class 2021-11-15 15:14:04 +01:00
59987f262d update key bindings 2021-11-15 15:14:04 +01:00
452a28362e fix help link 2021-11-15 15:14:04 +01:00
d6805f383b add help dialog 2021-11-15 15:14:04 +01:00
076611eec7 allow multiple loading of same format 2021-11-15 15:14:04 +01:00
e0fa55e2c0 corrected parent path im poms 2021-11-15 14:32:55 +01:00
9ea1994228 update key bindings 2021-11-15 14:16:46 +01:00
36f628c365 add help dialog 2021-11-15 13:07:58 +01:00
ff87e72510 allow multiple loading of same format 2021-11-15 10:52:59 +01:00
aef1e29a53 Merge branch 'release/2.13.2' into develop 2021-07-11 14:22:41 +02:00
1ebf9ba382 update version numbers 2021-07-11 13:47:48 +02:00
929408d08c fix missing gzip txlog file filter in file dialog 2021-07-11 13:47:27 +02:00
f57fb93525 fix reload issues 2021-07-11 13:46:35 +02:00
788065e456 Merge branch 'release/2.13.1' 2021-03-25 21:09:49 +00:00
22b46e0525 fix fit zoom level calculation 2021-03-25 21:07:05 +00:00
b75018239a Merge branch 'master' into develop
Conflicts:
	features/com.minres.scviewer.database.feature/pom.xml
	features/com.minres.scviewer.e4.feature/pom.xml
	features/com.minres.scviewer.e4.platform.feature/pom.xml
	features/com.minres.scviewer.feature/pom.xml
	features/com.minres.scviewer.ui.feature/pom.xml
	plugins/com.minres.scviewer.database.sqlite/pom.xml
	plugins/com.minres.scviewer.database.text/pom.xml
	plugins/com.minres.scviewer.database.ui.swt/pom.xml
	plugins/com.minres.scviewer.database.vcd/pom.xml
	plugins/com.minres.scviewer.database/pom.xml
	plugins/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF
	plugins/com.minres.scviewer.e4.application/pom.xml
	plugins/com.minres.scviewer.ui/pom.xml
	pom.xml
	products/com.minres.scviewer.e4.product/pom.xml
	products/com.minres.scviewer.e4.product/scviewer.product
	releng/com.minres.scviewer.target/pom.xml
	releng/com.minres.scviewer.updateSite/pom.xml
	tests/com.minres.scviewer.database.test/pom.xml
2021-03-25 20:46:30 +00:00
598bb8eec7 Merge remote-tracking branch 'origin/master' 2021-03-25 20:33:25 +00:00
869265fc13 add gzip files to file dialog filter 2021-03-25 20:27:55 +00:00
5ad813527a fix CLI handling 2021-03-25 20:27:55 +00:00
73f8d3d50a fix full name display of generators 2021-03-25 20:27:55 +00:00
da1701195d update version numbers 2021-03-25 20:27:55 +00:00
9b6334509e update version numbers 2021-03-25 20:27:54 +00:00
ac4acc34a4 fix warning and left-overs 2021-03-25 20:27:54 +00:00
b6963f38d6 move interface to primitive types 2021-03-25 20:27:54 +00:00
182a036ade some more refactoring 2021-03-25 20:27:53 +00:00
97f2182290 adapt painter 2021-03-25 20:27:53 +00:00
1986a8c9c3 add explicit event list 2021-03-25 20:27:53 +00:00
6905d96329 add TreeMap facade 2021-03-25 20:27:52 +00:00
818f786b1d add dispose check in case view is closed while loading db 2021-03-25 20:27:52 +00:00
2948c1bd33 update version numbers 2021-03-25 20:22:15 +00:00
78faab404c apply UI fixes
* wrong arrow target of transaction
* wrong zomm factor calculation for zoom fit
* streams and waveforms not visible if at root level
2021-03-25 20:18:50 +00:00
64b10970a8 add gzip files to file dialog filter 2021-03-02 21:55:52 +01:00
6ab8fd232e fix CLI handling 2021-03-02 21:55:52 +01:00
f337a94112 fix full name display of generators 2021-03-02 21:55:52 +01:00
0135631a3e update version numbers 2021-03-02 21:55:52 +01:00
d0e1e8801f update version numbers 2021-03-02 21:55:52 +01:00
d1b3a91979 fix warning and left-overs 2021-03-02 21:55:52 +01:00
45c1396e0e move interface to primitive types 2021-03-02 21:55:51 +01:00
b7301733f0 some more refactoring 2021-03-02 21:55:51 +01:00
5df91dbaa8 adapt painter 2021-03-02 21:55:51 +01:00
68918689e7 add explicit event list 2021-03-02 21:55:51 +01:00
c41dd646da add TreeMap facade 2021-03-02 21:55:51 +01:00
a077389b83 add dispose check in case view is closed while loading db 2021-03-02 21:55:51 +01:00
caa37375c0 add gzip files to file dialog filter 2021-03-02 21:42:54 +01:00
3daea8ab43 fix CLI handling 2021-03-02 19:32:21 +01:00
c5d77af0d0 fix full name display of generators 2021-03-02 19:32:09 +01:00
7f7fdf09f4 update version numbers 2021-02-27 19:13:28 +00:00
7aba6a2ecb update version numbers 2021-02-27 19:13:17 +00:00
012395b933 Merge branch 'feature/eclipse_collections' into develop 2021-02-27 18:47:31 +00:00
787e3accc0 fix warning and left-overs 2021-02-27 14:00:29 +00:00
b778940c83 move interface to primitive types 2021-02-27 13:59:00 +00:00
71297c4e5a some more refactoring 2021-02-27 13:47:37 +00:00
1d2395e00d adapt painter 2021-02-27 13:33:15 +00:00
b69e1886b9 add explicit event list 2021-02-27 13:27:51 +00:00
d65803a4b7 add TreeMap facade 2021-02-26 11:57:54 +00:00
0e49a68e09 add dispose check in case view is closed while loading db 2021-02-24 08:46:19 +00:00
7af5593fd4 Merge branch 'release/2.12.2' into develop 2021-02-24 07:05:00 +00:00
25545dac51 Merge branch 'release/2.12.2' 2021-02-24 07:04:59 +00:00
df77af64ca update version numbers 2021-02-24 07:04:47 +00:00
e264ab2cbe fix name display in waveform view (#6) 2021-02-24 06:56:28 +00:00
8c17ed4146 Merge branch 'release/2.12.1' into develop 2021-02-18 08:19:17 +00:00
4ee2e8bc68 Merge branch 'release/2.12.1' 2021-02-18 08:19:16 +00:00
bdcba613d5 fix version numbers 2021-02-18 08:18:47 +00:00
049de0ddaf add VM arguments for Java > 9 2021-02-18 08:14:12 +00:00
6be3f378d4 renmove deprecated newInstance call 2021-02-18 06:32:14 +00:00
6d8aa33fc9 update language level 2021-02-18 06:26:42 +00:00
b37ba9f2f1 Merge branch 'master' into develop 2021-02-17 21:15:33 +00:00
799f083a74 fix hierarchy display 2021-02-17 21:14:28 +00:00
156abe63cd fix display bug 2021-02-17 20:27:58 +00:00
d38016a03f fix display bug 2021-02-17 20:24:25 +00:00
5604c3ee5e Merge branch 'release/2.12.0' 2021-01-15 16:50:33 +01:00
5adeae15a9 change name of generated product artifacts 2021-01-15 15:52:28 +01:00
bca94ceb9d fix stream row calculation 2021-01-15 15:51:59 +01:00
a42f086339 set max heap to 2GB by default 2021-01-14 23:56:04 +01:00
888edf32be remove ITxGenerator interface 2021-01-14 23:55:47 +01:00
ee5536f1b5 update version numbers 2021-01-14 23:51:18 +01:00
59859e5d90 cache some more infos for stream 2021-01-14 23:36:29 +01:00
5bae086712 fix (Sonarlint) warnings 2021-01-14 23:36:07 +01:00
16de83616a adapt ui to database API 2021-01-14 23:14:22 +01:00
6530362b89 refactor tests 2021-01-14 23:14:05 +01:00
0372e03abb minor database API change 2021-01-14 23:13:11 +01:00
26e8ea8a51 change design browser icons 2021-01-14 21:57:27 +01:00
efd042dd22 fix duplicate version numbers 2021-01-12 20:28:51 +01:00
d06642d51f Merge branch 'release/2.11.2' into develop 2021-01-12 20:25:46 +01:00
164 changed files with 2808 additions and 1235 deletions

3
.gitignore vendored
View File

@ -8,4 +8,5 @@ SCViewer.xcf
SCViewer_1.png
copyrightLog.txt
/workspace
?*.launch
?*.launch
/.settings/

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.minres.scviewer.parent</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -1,4 +0,0 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -18,14 +18,37 @@ The viewer has the following features
- sqlite based
- visualization of transaction relations
To build the plugins the Eclipse SDK or PDE can be used. In both cases the Groovy
eclipse plugin (http://groovy.codehaus.org/Eclipse+Plugin or Market) has to be
installed.
To build the plugins the Eclipse SDK or PDE can be used.
TODO
====
- add more tests
- move to feature based product to allow automatic updates
- improve graphics
- catch-up e3 plugin to functionality of e4 product
- add calculated traces
Key Shortcuts
=============
Legend:
* Left Mouse Button: LMB
* Middle Mouse Button: MMB
* Mouse Scroll wheel: MScrl
* Context any means Name List, Value List or Waveform
| Input | Modifier | Context | Action |
|-----------|----------|----------|-----------------------------------|
| LMB klick | | any | select |
| LMB klick | Shift | Waveform | move selected marker to position |
| LMB klick | Control | Waveform | move cursor to position |
| LMB drag | | Waveform | zoom to range |
| MMB klick | | Waveform | move selected marker to position |
| MScrl | | any | scroll window up/down |
| MScrl | Shift | any | scroll window left/right |
| Key left | | Waveform | scroll window to the left (slow) |
| Key right | | Waveform | scroll window to the right (slow) |
| Key left | Shift | Waveform | scroll window to the left (fast) |
| Key right | Shift | Waveform | scroll window to the right (fast) |
| Key up | | Waveform | move selection up |
| Key down | | Waveform | move selection down |
| Key up | Control | Waveform | move selected track up |
| Key down | Control | Waveform | move selected track down |
| Key + | Control | Waveform | zoom in |
| Key - | Control | Waveform | zoom out |
| Key Pos1 | | Waveform | jump to selected marker |
| Key End | | Waveform | jump to cursor |
| Key Del | | any | delete selected entries |

View File

@ -27,12 +27,12 @@ http://www.eclipse.org/legal/epl-v10.html
</url>
<requires>
<import plugin="org.codehaus.groovy" version="2.5.8" match="greaterOrEqual"/>
<import plugin="org.eclipse.osgi.services" version="3.4.0" match="greaterOrEqual"/>
<import plugin="com.google.guava" version="15.0.0" match="greaterOrEqual"/>
<import plugin="org.eclipse.osgi"/>
<import plugin="com.minres.scviewer.database" version="1.0.0" match="greaterOrEqual"/>
<import plugin="org.eclipse.core.runtime"/>
<import feature="org.eclipse.collections.feature" version="10.4.0.v20200820-2049"/>
</requires>
<plugin

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>3.0.0-SNAPSHOT</version>
</project>

View File

@ -64,4 +64,11 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.minres.scviewer.help"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>
</project>

View File

@ -29,6 +29,10 @@
id="org.eclipse.emf.common"
version="0.0.0"/>
<includes
id="org.eclipse.collections.feature"
version="0.0.0"/>
<requires>
<import plugin="org.eclipse.core.expressions" version="3.2.0" match="compatible"/>
<import plugin="org.eclipse.core.filesystem" version="1.3.0" match="compatible"/>

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>1.0.0-SNAPSHOT</version>
</project>

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>
</project>

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>
</project>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="lib" path="sqlite-jdbc-3.8.7.jar"/>

View File

@ -1,8 +1,10 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -4,7 +4,7 @@ Bundle-Name: SQLite transaction database
Bundle-SymbolicName: com.minres.scviewer.database.sqlite
Bundle-Version: 1.1.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0"
Bundle-ClassPath: .,sqlite-jdbc-3.8.7.jar
Service-Component: OSGI-INF/component.xml

View File

@ -4,8 +4,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
<dependencies>

View File

@ -14,12 +14,13 @@ import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.EventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.RelationTypeFactory;
@ -35,18 +36,18 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
private Integer maxConcurrency;
private TreeMap<Long, IEvent[]> events;
private IEventList events;
private List<RelationType> usedRelationsList;
public AbstractTxStream(IDatabase database, String name, long streamId) {
protected AbstractTxStream(IDatabase database, String name, long streamId) {
super(name);
this.database=database;
this.streamId=streamId;
}
@Override
public int getWidth() {
public int getRowCount() {
if(maxConcurrency==null){
StringBuilder sb = new StringBuilder();
sb.append("SELECT MAX(concurrencyLevel) as concurrencyLevel FROM ScvTx where stream=");
@ -71,9 +72,9 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
}
@Override
public NavigableMap<Long, IEvent[]> getEvents(){
public IEventList getEvents(){
if(events==null){
events=new TreeMap<>();
events=new EventList();
for(Entry<Integer, ITx> entry:getTransactions().entrySet()){
putEvent(new TxEvent(EventKind.BEGIN, entry.getValue()));
putEvent(new TxEvent(EventKind.END, entry.getValue()));
@ -83,22 +84,13 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
}
private void putEvent(TxEvent ev){
Long time = ev.getTime();
if(events.containsKey(time)) {
IEvent[] oldV = events.get(time);
IEvent[] newV = new IEvent[oldV.length+1];
System.arraycopy(oldV, 0, newV, 0, oldV.length);
newV[oldV.length]=ev;
events.put(time, newV);
} else {
events.put(time, new IEvent[] {ev});
}
events.put(ev.getTime(), ev);
}
protected abstract Map<Integer, ITx> getTransactions();
@Override
public IEvent[] getEventsAtTime(Long time) {
public IEvent[] getEventsAtTime(long time) {
return getEvents().get(time);
}
@ -113,12 +105,12 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
}
@Override
public IEvent[] getEventsBeforeTime(Long time) {
Entry<Long, IEvent[]> e = events.floorEntry(time);
public IEvent[] getEventsBeforeTime(long time) {
EventEntry e = events.floorEntry(time);
if(e==null)
return new IEvent[]{};
else
return events.floorEntry(time).getValue();
return events.floorEntry(time).events;
}
@Override
@ -126,4 +118,11 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
return WaveformType.TRANSACTION;
}
/**
* Calculate concurrency.
*/
public void calculateConcurrency() {
}
}

View File

@ -48,7 +48,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
@Override
public Long getMaxTime() {
public long getMaxTime() {
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
database, "time = (SELECT MAX(time) FROM ScvTxEvent)");
try {
@ -56,7 +56,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
if(!event.isEmpty())
return event.get(0).getTime()*scvSimProps.getTime_resolution();
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
return 0L;
@ -73,7 +73,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
streams.add(stream);
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
return streams;
}
@ -99,7 +99,6 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
@Override
public void load(IWaveformDb db, File file) throws InputFormatException {
dispose();
database=new SQLiteDatabase(file.getAbsolutePath(), db);
database.setData("TIMERESOLUTION", 1L);
SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<>(ScvSimProps.class, database);
@ -110,7 +109,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
}
pcs.firePropertyChange(IWaveformDbLoader.LOADING_FINISHED, null, null);
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
throw new InputFormatException(e.toString());
}
}

View File

@ -28,7 +28,6 @@ import com.minres.scviewer.database.sqlite.tables.ScvTxEvent;
import com.minres.scviewer.database.sqlite.tables.ScvTxRelation;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxAttribute;
import com.minres.scviewer.database.tx.ITxGenerator;
import com.minres.scviewer.database.tx.ITxRelation;
public class Tx implements ITx {
@ -38,8 +37,8 @@ public class Tx implements ITx {
private TxGenerator trGenerator;
private ScvTx scvTx;
private List<ITxAttribute> attributes;
private Long begin;
private Long end;
private long begin=-1;
private long end=-1;
private List<ITxRelation> incoming;
private List<ITxRelation> outgoing;
@ -51,7 +50,7 @@ public class Tx implements ITx {
}
@Override
public Long getId() {
public long getId() {
return (long) scvTx.getId();
}
@ -61,18 +60,17 @@ public class Tx implements ITx {
}
@Override
public ITxGenerator getGenerator() {
public IWaveform getGenerator() {
return trGenerator;
}
@Override
public int getConcurrencyIndex() {
int getConcurrencyIndex() {
return scvTx.getConcurrencyLevel();
}
@Override
public Long getBeginTime() {
if(begin==null){
public long getBeginTime() {
if(begin<0){
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.BEGIN.ordinal());
try {
@ -80,15 +78,15 @@ public class Tx implements ITx {
begin= scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION");
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return begin;
}
@Override
public Long getEndTime() {
if(end==null){
public long getEndTime() {
if(end<0){
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.END.ordinal());
try {
@ -96,7 +94,7 @@ public class Tx implements ITx {
end = scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION");
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return end;
@ -114,7 +112,7 @@ public class Tx implements ITx {
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return attributes;
@ -131,7 +129,7 @@ public class Tx implements ITx {
incoming.add(createRelation(scvRelation, false));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return incoming;
@ -148,7 +146,7 @@ public class Tx implements ITx {
outgoing.add(createRelation(scvRelation, true));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
}
}
return outgoing;
@ -171,7 +169,7 @@ public class Tx implements ITx {
else
return new TxRelation(trStream.getRelationType(rel.getName()), that, this);
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
@ -180,11 +178,11 @@ public class Tx implements ITx {
@Override
public int compareTo(ITx o) {
int res = this.getBeginTime().compareTo(o.getBeginTime());
int res = Long.compare(this.getBeginTime(), o.getBeginTime());
if(res!=0)
return res;
else
return this.getId().compareTo(o.getId());
return Long.compare(this.getId(), o.getId());
}
@Override

View File

@ -28,7 +28,7 @@ public class TxEvent implements ITxEvent {
}
@Override
public Long getTime() {
public long getTime() {
return type==EventKind.BEGIN?tx.getBeginTime():tx.getEndTime();
}
@ -56,4 +56,10 @@ public class TxEvent implements ITxEvent {
public WaveformType getType() {
return WaveformType.TRANSACTION;
}
@Override
public int getRowIndex() {
return ((Tx)tx).getConcurrencyIndex();
}
}

View File

@ -22,9 +22,8 @@ import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
import com.minres.scviewer.database.sqlite.tables.ScvGenerator;
import com.minres.scviewer.database.sqlite.tables.ScvTx;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxGenerator;
public class TxGenerator extends AbstractTxStream implements ITxGenerator {
public class TxGenerator extends AbstractTxStream {
private TxStream stream;
@ -40,15 +39,10 @@ public class TxGenerator extends AbstractTxStream implements ITxGenerator {
}
@Override
public Long getId() {
public long getId() {
return (long) scvGenerator.getId();
}
@Override
public IWaveform getStream() {
return stream;
}
@Override
public String getName() {
return scvGenerator.getName();
@ -56,7 +50,7 @@ public class TxGenerator extends AbstractTxStream implements ITxGenerator {
@Override
public boolean isSame(IWaveform other) {
return(other instanceof TxGenerator && this.getId().equals(other.getId()));
return(other instanceof TxGenerator && this.getId() == other.getId());
}
@Override
@ -75,7 +69,7 @@ public class TxGenerator extends AbstractTxStream implements ITxGenerator {
transactions.put(scvTx.getId(), new Tx(database, (TxStream) stream, this, scvTx));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
}

View File

@ -26,7 +26,6 @@ import com.minres.scviewer.database.sqlite.tables.ScvGenerator;
import com.minres.scviewer.database.sqlite.tables.ScvStream;
import com.minres.scviewer.database.sqlite.tables.ScvTx;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxGenerator;
public class TxStream extends AbstractTxStream {
@ -50,11 +49,11 @@ public class TxStream extends AbstractTxStream {
}
@Override
public Long getId() {
public long getId() {
return (long) scvStream.getId();
}
public List<ITxGenerator> getGenerators() {
public List<IWaveform> getGenerators() {
if(generators==null){
SQLiteDatabaseSelectHandler<ScvGenerator> handler = new SQLiteDatabaseSelectHandler<>(
ScvGenerator.class, database, "stream="+scvStream.getId());
@ -64,7 +63,7 @@ public class TxStream extends AbstractTxStream {
generators.put(scvGenerator.getId(), new TxGenerator(database, this, scvGenerator));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
}
@ -82,7 +81,7 @@ public class TxStream extends AbstractTxStream {
transactions.put(scvTx.getId(), new Tx(database, this, generators.get(scvTx.getGenerator()), scvTx));
}
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
| InvocationTargetException | SQLException | IntrospectionException e) {
| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) {
e.printStackTrace();
}
}
@ -90,13 +89,13 @@ public class TxStream extends AbstractTxStream {
}
@Override
public IEvent[] getEventsAtTime(Long time) {
public IEvent[] getEventsAtTime(long time) {
return getEvents().get(time);
}
@Override
public boolean isSame(IWaveform other) {
return(other instanceof TxStream && this.getId().equals(other.getId()));
return(other instanceof TxStream && this.getId() == other.getId());
}
@Override

View File

@ -75,10 +75,11 @@ public class SQLiteDatabaseSelectHandler<T> extends AbstractDatabaseHandler<T> {
* @throws IllegalAccessException
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public synchronized List<T> selectObjects() throws SQLException,
InstantiationException, IllegalAccessException,
IntrospectionException, InvocationTargetException {
IntrospectionException, InvocationTargetException, IllegalArgumentException, NoSuchMethodException, SecurityException {
Connection connection = null;
Statement statement = null;
@ -113,17 +114,18 @@ public class SQLiteDatabaseSelectHandler<T> extends AbstractDatabaseHandler<T> {
* @throws IllegalAccessException
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
private List<T> createObjects(ResultSet resultSet)
throws SQLException, InstantiationException,
IllegalAccessException, IntrospectionException,
InvocationTargetException {
InvocationTargetException, IllegalArgumentException, NoSuchMethodException, SecurityException {
List<T> list = new ArrayList<>();
while (resultSet.next()) {
T instance = type.newInstance();
T instance = type.getDeclaredConstructor().newInstance();
for (Field field : type.getDeclaredFields()) {

View File

@ -1,17 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry exported="true" kind="lib" path="lib/mapdb-3.0.7.jar" sourcepath="lib/mapdb-3.0.7-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="lib" path="lib/kotlin-stdlib-1.2.42.jar"/>
<classpathentry exported="true" kind="lib" path="lib/lz4-1.3.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/elsa-3.0.0-M5.jar"/>

View File

@ -1,9 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Textual transaction database
Bundle-SymbolicName: com.minres.scviewer.database.text
Bundle-Version: 3.0.0.qualifier
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: com.minres.scviewer.database,
org.eclipse.osgi.services;bundle-version="3.4.0",

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoader">
<implementation class="com.minres.scviewer.database.text.TextDbLoader"/>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoaderFactory">
<implementation class="com.minres.scviewer.database.text.TextDbLoaderFactory"/>
<service>
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
<provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/>
</service>
</scr:component>

View File

@ -2,12 +2,12 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.database.text</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>

View File

@ -12,16 +12,16 @@
package com.minres.scviewer.database.text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.HashMap;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventList;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.WaveformType;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxEvent;
/**
@ -29,6 +29,8 @@ import com.minres.scviewer.database.tx.ITxEvent;
*/
abstract class AbstractTxStream extends HierNode implements IWaveform {
private final String fullName;
/** The id. */
private Long id;
@ -36,10 +38,10 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
protected TextDbLoader loader;
/** The events. */
TreeMap<Long, IEvent[]> events = new TreeMap<>();
IEventList events = new EventList();
/** The concurrency calculated. */
boolean concurrencyCalculated = false;
/** The max concurrency. */
private int rowCount = -1;
/**
* Instantiates a new abstract tx stream.
@ -48,26 +50,29 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @param id the id
* @param name the name
*/
public AbstractTxStream(TextDbLoader loader, Long id, String name) {
protected AbstractTxStream(TextDbLoader loader, Long id, String name) {
super(name);
fullName=name;
this.loader = loader;
this.id = id;
}
/**
* Gets the full hierarchical name.
*
* @return the full name
*/
@Override
public String getFullName() {
return fullName;
}
/**
* Adds the event.
*
* @param evt the evt
*/
public void addEvent(ITxEvent evt) {
if (!events.containsKey(evt.getTime()))
events.put(evt.getTime(), new IEvent[] { evt });
else {
IEvent[] evts = events.get(evt.getTime());
IEvent[] newEvts = Arrays.copyOf(evts, evts.length + 1);
newEvts[evts.length] = evt;
events.put(evt.getTime(), newEvts);
}
events.put(evt.getTime(), evt);
}
/**
@ -76,9 +81,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @return the events
*/
@Override
public NavigableMap<Long, IEvent[]> getEvents() {
if (!concurrencyCalculated)
calculateConcurrency();
public IEventList getEvents() {
return events;
}
@ -89,9 +92,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @return the events at time
*/
@Override
public IEvent[] getEventsAtTime(Long time) {
if (!concurrencyCalculated)
calculateConcurrency();
public IEvent[] getEventsAtTime(long time) {
return events.get(time);
}
@ -102,14 +103,12 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @return the events before time
*/
@Override
public IEvent[] getEventsBeforeTime(Long time) {
if (!concurrencyCalculated)
calculateConcurrency();
Entry<Long, IEvent[]> e = events.floorEntry(time);
public IEvent[] getEventsBeforeTime(long time) {
EventEntry e = events.floorEntry(time);
if (e == null)
return new IEvent[] {};
else
return events.floorEntry(time).getValue();
return events.floorEntry(time).events;
}
/**
@ -128,32 +127,63 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
* @return the id
*/
@Override
public Long getId() {
public long getId() {
return id;
}
/**
* Gets the width.
*
* @return the width
*/
@Override
public int getRowCount() {
if (rowCount<0)
calculateConcurrency();
return rowCount;
}
/**
* Calculate concurrency.
*/
synchronized void calculateConcurrency() {
if (concurrencyCalculated)
void calculateConcurrency() {
if (rowCount>=0)
return;
ArrayList<Long> rowendtime = new ArrayList<>();
events.entrySet().stream().forEach(entry -> {
IEvent[] values = entry.getValue();
Arrays.asList(values).stream().filter(e -> e.getKind() == EventKind.BEGIN).forEach(evt -> {
Tx tx = (Tx) ((TxEvent) evt).getTransaction();
ArrayList<Long> rowEndTime = new ArrayList<>();
HashMap<Long, Integer> rowByTxId = new HashMap<>();
for(EventEntry entry: events) {
for(IEvent evt:entry.events) {
TxEvent txEvt = (TxEvent) evt;
ITx tx = txEvt.getTransaction();
int rowIdx = 0;
for (; rowIdx < rowendtime.size() && rowendtime.get(rowIdx) > tx.getBeginTime(); rowIdx++)
;
if (rowendtime.size() <= rowIdx)
rowendtime.add(tx.getEndTime());
else
rowendtime.set(rowIdx, tx.getEndTime());
tx.setConcurrencyIndex(rowIdx);
});
});
concurrencyCalculated = true;
switch(evt.getKind()) {
case END:
Long txId = txEvt.getTransaction().getId();
txEvt.setConcurrencyIndex(rowByTxId.get(txId));
rowByTxId.remove(txId);
break;
case SINGLE:
for (; rowIdx < rowEndTime.size() && rowEndTime.get(rowIdx)>tx.getBeginTime(); rowIdx++);
if (rowEndTime.size() <= rowIdx)
rowEndTime.add(tx.getEndTime());
else
rowEndTime.set(rowIdx, tx.getEndTime());
((TxEvent) evt).setConcurrencyIndex(rowIdx);
break;
case BEGIN:
for (; rowIdx < rowEndTime.size() && rowEndTime.get(rowIdx)>tx.getBeginTime(); rowIdx++);
if (rowEndTime.size() <= rowIdx)
rowEndTime.add(tx.getEndTime());
else
rowEndTime.set(rowIdx, tx.getEndTime());
((TxEvent) evt).setConcurrencyIndex(rowIdx);
rowByTxId.put(tx.getId(), rowIdx);
break;
}
}
}
rowCount=rowEndTime.size()>0?rowEndTime.size():1;
getChildNodes().parallelStream().forEach(c -> ((TxGenerator)c).calculateConcurrency());
}
}

View File

@ -28,14 +28,13 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import org.eclipse.collections.impl.map.mutable.UnifiedMap;
import org.mapdb.DB;
import org.mapdb.DB.HashMapMaker;
import org.mapdb.DB.TreeMapSink;
import org.mapdb.DBMaker;
import org.mapdb.HTreeMap;
import org.mapdb.Serializer;
@ -106,18 +105,59 @@ public class TextDbLoader implements IWaveformDbLoader {
/** The Constant x. */
static final byte[] x = "scv_tr_stream".getBytes();
/**
* Adds the property change listener.
*
* @param l the l
*/
@Override
public void addPropertyChangeListener(PropertyChangeListener l) {
pcs.addPropertyChangeListener(l);
}
/**
* Removes the property change listener.
*
* @param l the l
*/
@Override
public void removePropertyChangeListener(PropertyChangeListener l) {
pcs.removePropertyChangeListener(l);
}
/**
* Gets the max time.
*
* @return the max time
*/
@Override
public Long getMaxTime() {
public long getMaxTime() {
return maxTime;
}
/**
* Gets the transaction.
*
* @param txId the tx id
* @return the transaction
*/
public ITx getTransaction(long txId) {
if (txCache.containsKey(txId))
return txCache.get(txId);
if(transactions.containsKey(txId)) {
Tx tx = new Tx(this, transactions.get(txId));
txCache.put(txId, tx);
return tx;
} else {
throw new IllegalArgumentException();
}
}
public ScvTx getScvTx(long id) {
return transactions.get(id);
if(transactions.containsKey(id))
return transactions.get(id);
else
throw new IllegalArgumentException();
}
/**
@ -127,7 +167,18 @@ public class TextDbLoader implements IWaveformDbLoader {
*/
@Override
public Collection<IWaveform> getAllWaves() {
return new ArrayList<>(txStreams.values());
ArrayList<IWaveform> ret = new ArrayList<>(txStreams.values());
ret.addAll(txGenerators.values());
return ret;
}
/**
* Gets the all relation types.
*
* @return the all relation types
*/
public Collection<RelationType> getAllRelationTypes() {
return relationTypes.values();
}
/**
@ -156,6 +207,22 @@ public class TextDbLoader implements IWaveformDbLoader {
return false;
}
/**
* Checks if is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
private static boolean isGzipped(File f) {
try (InputStream is = new FileInputStream(f)) {
byte[] signature = new byte[2];
int nread = is.read(signature); // read the gzip signature
return nread == 2 && signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b;
} catch (IOException e) {
return false;
}
}
/**
* Load.
*
@ -188,28 +255,14 @@ public class TextDbLoader implements IWaveformDbLoader {
TextDbParser parser = new TextDbParser(this);
try {
// parser.txSink = mapDb.treeMap("transactions", Serializer.LONG, Serializer.JAVA).createFromSink();
parser.txSink = mapDb.hashMap("transactions", Serializer.LONG, Serializer.JAVA).create();
parser.parseInput(gzipped ? new GZIPInputStream(new FileInputStream(file)) : new FileInputStream(file));
// transactions = parser.txSink.create();
transactions = parser.txSink;
} catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
} catch (Exception e) {
throw new InputFormatException(e.toString());
}
for (TxStream stream : txStreams.values()) {
Thread t = new Thread() {
@Override
public void run() {
try {
stream.calculateConcurrency();
} catch (Exception e) {
/* don't let exceptions bubble up */ }
}
};
threads.add(t);
t.start();
}
txStreams.values().parallelStream().forEach(TxStream::calculateConcurrency);
}
/**
@ -231,31 +284,6 @@ public class TextDbLoader implements IWaveformDbLoader {
}
}
/**
* Checks if is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
private static boolean isGzipped(File f) {
try (InputStream is = new FileInputStream(f)) {
byte[] signature = new byte[2];
int nread = is.read(signature); // read the gzip signature
return nread == 2 && signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b;
} catch (IOException e) {
return false;
}
}
/**
* Gets the all relation types.
*
* @return the all relation types
*/
public Collection<RelationType> getAllRelationTypes() {
return relationTypes.values();
}
/**
* The Class TextDbParser.
*/
@ -321,6 +349,11 @@ public class TextDbLoader implements IWaveformDbLoader {
}
if (curLine != null)
parseLine(curLine, nextLine);
for(Entry<Long, ScvTx> e: transactionById.entrySet()) {
ScvTx scvTx = e.getValue();
scvTx.endTime=loader.maxTime;
txSink.put(e.getKey(), scvTx);
}
}
/**
@ -368,8 +401,6 @@ public class TextDbLoader implements IWaveformDbLoader {
ScvTx scvTx = new ScvTx(id, gen.stream.getId(), genId,
Long.parseLong(tokens[3]) * stringToScale(tokens[4]));
loader.maxTime = loader.maxTime > scvTx.beginTime ? loader.maxTime : scvTx.beginTime;
TxStream stream = loader.txStreams.get(gen.stream.getId());
stream.setConcurrency(stream.getConcurrency() + 1);
if (nextLine != null && nextLine.charAt(0) == 'a') {
int idx = 0;
while (nextLine != null && nextLine.charAt(0) == 'a') {
@ -391,18 +422,14 @@ public class TextDbLoader implements IWaveformDbLoader {
TxGenerator gen = loader.txGenerators.get(scvTx.generatorId);
TxStream stream = loader.txStreams.get(gen.stream.getId());
if (scvTx.beginTime == scvTx.endTime) {
TxEvent evt = new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime);
stream.addEvent(evt);
gen.addEvent(evt);
stream.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
gen.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
} else {
TxEvent begEvt = new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime);
stream.addEvent(begEvt);
gen.addEvent(begEvt);
TxEvent endEvt = new TxEvent(loader, EventKind.END, id, scvTx.endTime);
stream.addEvent(endEvt);
gen.addEvent(endEvt);
stream.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
gen.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
stream.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
gen.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
}
stream.setConcurrency(stream.getConcurrency() - 1);
if (nextLine != null && nextLine.charAt(0) == 'a') {
int idx = 0;
while (nextLine != null && nextLine.charAt(0) == 'a') {
@ -521,38 +548,4 @@ public class TextDbLoader implements IWaveformDbLoader {
}
/**
* Gets the transaction.
*
* @param txId the tx id
* @return the transaction
*/
public ITx getTransaction(long txId) {
if (txCache.containsKey(txId))
return txCache.get(txId);
Tx tx = new Tx(this, txId);
txCache.put(txId, tx);
return tx;
}
/**
* Adds the property change listener.
*
* @param l the l
*/
@Override
public void addPropertyChangeListener(PropertyChangeListener l) {
pcs.addPropertyChangeListener(l);
}
/**
* Removes the property change listener.
*
* @param l the l
*/
@Override
public void removePropertyChangeListener(PropertyChangeListener l) {
pcs.removePropertyChangeListener(l);
}
}

View File

@ -0,0 +1,77 @@
/*******************************************************************************
* Copyright (c) 2012 IT Just working.
* Copyright (c) 2020 MINRES Technologies GmbH
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IT Just working - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
/**
* The Class TextDbLoader.
*/
public class TextDbLoaderFactory implements IWaveformDbLoaderFactory {
/** The Constant x. */
static final byte[] x = "scv_tr_stream".getBytes();
/**
* Checks if f is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
private static boolean isGzipped(File f) {
try (InputStream is = new FileInputStream(f)) {
byte[] signature = new byte[2];
int nread = is.read(signature); // read the gzip signature
return nread == 2 && signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b;
} catch (IOException e) {
return false;
}
}
/**
* Can load.
*
* @param inputFile the input file
* @return true, if successful
*/
@Override
public boolean canLoad(File inputFile) {
if (!inputFile.isDirectory() && inputFile.exists()) {
boolean gzipped = isGzipped(inputFile);
try(InputStream stream = gzipped ? new GZIPInputStream(new FileInputStream(inputFile)) : new FileInputStream(inputFile)){
byte[] buffer = new byte[x.length];
int readCnt = stream.read(buffer, 0, x.length);
if (readCnt == x.length) {
for (int i = 0; i < x.length; i++)
if (buffer[i] != x[i])
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
return false;
}
@Override
public IWaveformDbLoader getLoader() {
return new TextDbLoader();
}
}

View File

@ -19,7 +19,6 @@ import java.util.stream.Collectors;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxAttribute;
import com.minres.scviewer.database.tx.ITxGenerator;
import com.minres.scviewer.database.tx.ITxRelation;
/**
@ -29,9 +28,15 @@ class Tx implements ITx {
/** The loader. */
private final TextDbLoader loader;
private ScvTx scvTx =null;
/** The id. */
private long id;
private final long id;
private final long generatorId;
private final long streamId;
/** The begin time. */
long beginTime = -1;
@ -39,9 +44,6 @@ class Tx implements ITx {
/** The end time. */
long endTime = -1;
/** The concurrency index. */
private int concurrencyIndex;
/**
* Instantiates a new tx.
*
@ -51,6 +53,10 @@ class Tx implements ITx {
public Tx(TextDbLoader loader, ScvTx scvTx) {
this.loader = loader;
id = scvTx.id;
generatorId=scvTx.generatorId;
streamId=scvTx.streamId;
beginTime=scvTx.beginTime;
endTime=scvTx.endTime;
}
/**
@ -59,9 +65,11 @@ class Tx implements ITx {
* @param loader the loader
* @param txId the tx id
*/
public Tx(TextDbLoader loader, long txId) {
public Tx(TextDbLoader loader, long id, long generatorId, long streamId) {
this.loader = loader;
id = txId;
this.id = id;
this.generatorId=generatorId;
this.streamId = streamId;
}
/**
@ -94,11 +102,11 @@ class Tx implements ITx {
*/
@Override
public int compareTo(ITx o) {
int res = getBeginTime().compareTo(o.getBeginTime());
int res = Long.compare(getBeginTime(), o.getBeginTime());
if (res != 0)
return res;
else
return getId().compareTo(o.getId());
return Long.compare(getId(), o.getId());
}
/**
@ -113,7 +121,7 @@ class Tx implements ITx {
return true;
if (obj == null || getClass() != obj.getClass())
return false;
return this.loader.getScvTx(id).equals(((Tx) obj).loader.getScvTx(id));
return this.getScvTx().equals(((Tx) obj).getScvTx());
}
/**
@ -123,7 +131,7 @@ class Tx implements ITx {
*/
@Override
public int hashCode() {
return loader.getScvTx(id).hashCode();
return getScvTx().hashCode();
}
/**
@ -142,8 +150,8 @@ class Tx implements ITx {
* @return the id
*/
@Override
public Long getId() {
return loader.getScvTx(id).id;
public long getId() {
return getScvTx().id;
}
/**
@ -153,7 +161,7 @@ class Tx implements ITx {
*/
@Override
public IWaveform getStream() {
return loader.txStreams.get(loader.getScvTx(id).streamId);
return loader.txStreams.get(streamId);
}
/**
@ -162,8 +170,8 @@ class Tx implements ITx {
* @return the generator
*/
@Override
public ITxGenerator getGenerator() {
return loader.txGenerators.get(loader.getScvTx(id).generatorId);
public IWaveform getGenerator() {
return loader.txGenerators.get(generatorId);
}
/**
@ -172,9 +180,12 @@ class Tx implements ITx {
* @return the begin time
*/
@Override
public Long getBeginTime() {
if (beginTime < 0)
beginTime = loader.getScvTx(id).beginTime;
public long getBeginTime() {
if (beginTime < 0) {
ScvTx tx = scvTx==null?loader.getScvTx(id):getScvTx();
beginTime = tx.beginTime;
endTime = tx.endTime;
}
return beginTime;
}
@ -184,9 +195,12 @@ class Tx implements ITx {
* @return the end time
*/
@Override
public Long getEndTime() {
if (endTime < 0)
endTime = loader.getScvTx(id).endTime;
public long getEndTime() {
if (endTime < 0) {
ScvTx tx = scvTx==null?loader.getScvTx(id):getScvTx();
beginTime = tx.beginTime;
endTime = tx.endTime;
}
return endTime;
}
@ -196,26 +210,7 @@ class Tx implements ITx {
* @param time the new end time
*/
void setEndTime(Long time) {
loader.getScvTx(id).endTime = time;
}
/**
* Gets the concurrency index.
*
* @return the concurrency index
*/
@Override
public int getConcurrencyIndex() {
return concurrencyIndex;
}
/**
* Sets the concurrency index.
*
* @param idx the new concurrency index
*/
void setConcurrencyIndex(int idx) {
concurrencyIndex = idx;
getScvTx().endTime = time;
}
/**
@ -225,7 +220,12 @@ class Tx implements ITx {
*/
@Override
public List<ITxAttribute> getAttributes() {
return loader.getScvTx(id).attributes;
return getScvTx().attributes;
}
private ScvTx getScvTx() {
if(scvTx==null)
scvTx=loader.getScvTx(id);
return scvTx;
}
}

View File

@ -32,6 +32,7 @@ class TxEvent implements ITxEvent {
/** The time. */
final long time;
private int concurrencyIdx=-1;
/**
* Instantiates a new tx event.
*
@ -94,7 +95,7 @@ class TxEvent implements ITxEvent {
* @return the time
*/
@Override
public Long getTime() {
public long getTime() {
return time;
}
@ -107,4 +108,13 @@ class TxEvent implements ITxEvent {
public ITx getTransaction() {
return loader.getTransaction(transaction);
}
@Override
public int getRowIndex() {
return concurrencyIdx;
}
public void setConcurrencyIndex(int idx) {
concurrencyIdx=idx;
}
}

View File

@ -15,12 +15,11 @@ import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.tx.ITxGenerator;
/**
* The Class TxGenerator.
*/
class TxGenerator extends AbstractTxStream implements ITxGenerator {
class TxGenerator extends AbstractTxStream {
/** The stream. */
TxStream stream;
@ -45,16 +44,6 @@ class TxGenerator extends AbstractTxStream implements ITxGenerator {
stream.addChild(this);
}
/**
* Gets the stream.
*
* @return the stream
*/
@Override
public IWaveform getStream() {
return stream;
}
/**
* Checks if is same.
*
@ -63,7 +52,7 @@ class TxGenerator extends AbstractTxStream implements ITxGenerator {
*/
@Override
public boolean isSame(IWaveform other) {
return (other instanceof TxGenerator && this.getId().equals(other.getId()));
return (other instanceof TxGenerator && this.getId()==other.getId());
}
/**
@ -93,14 +82,15 @@ class TxGenerator extends AbstractTxStream implements ITxGenerator {
public String getKind() {
return stream.getKind();
}
/**
* Gets the width.
* Gets the full hierarchical name.
*
* @return the width
* @return the full name
*/
@Override
public int getWidth() {
return stream.getWidth();
public String getFullName() {
return ((AbstractTxStream)parent).getFullName()+"."+name;
}
}

View File

@ -42,7 +42,7 @@ class TxStream extends AbstractTxStream {
*/
@Override
public boolean isSame(IWaveform other) {
return (other instanceof TxStream && this.getId().equals(other.getId()));
return (other instanceof TxStream && this.getId() == other.getId());
}
/**
@ -55,40 +55,4 @@ class TxStream extends AbstractTxStream {
return kind;
}
/** The max concurrency. */
private int maxConcurrency = 0;
/** The concurrency. */
private int concurrency = 0;
/**
* Sets the concurrency.
*
* @param concurrency the new concurrency
*/
void setConcurrency(int concurrency) {
this.concurrency = concurrency;
if (concurrency > maxConcurrency)
maxConcurrency = concurrency;
}
/**
* Gets the concurrency.
*
* @return the concurrency
*/
int getConcurrency() {
return this.concurrency;
}
/**
* Gets the width.
*
* @return the width
*/
@Override
public int getWidth() {
return maxConcurrency;
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>

View File

@ -9,8 +9,8 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@ -21,6 +21,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
@ -66,6 +67,7 @@ org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=igno
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
@ -98,5 +100,5 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SWT database widget
Bundle-SymbolicName: com.minres.scviewer.database.ui.swt
Bundle-Version: 3.0.0.qualifier
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.swt;bundle-version="3.103.1",
com.minres.scviewer.database;bundle-version="1.0.0",
com.google.guava;bundle-version="15.0.0",

View File

@ -5,8 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<version>3.0.0-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
</project>

View File

@ -27,10 +27,14 @@ import com.minres.scviewer.database.tx.ITx;
public interface IWaveformView extends PropertyChangeListener, ISelectionProvider{
String CURSOR_PROPERTY = "cursor_time";
static final String CURSOR_PROPERTY = "cursor_time";
String MARKER_PROPERTY = "marker_time";
static final String MARKER_PROPERTY = "marker_time";
static final int CURSOR_POS = 0;
static final int MARKER_POS = 1;
public static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");
public void addSelectionChangedListener(ISelectionChangedListener listener);
@ -113,6 +117,8 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide
public void scrollHorizontal(int percent);
public void scrollTo(int pos);
public void addDisposeListener( DisposeListener listener );
public void deleteSelectedTracks();

View File

@ -1,14 +1,36 @@
package com.minres.scviewer.database.ui.swt;
import java.text.DecimalFormat;
public class Constants {
public static final String[] UNIT_STRING={"fs", "ps", "ns", "us", "ms"};//, "s"};
public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300};
public static final long[] UNIT_MULTIPLIER={1, 1000, 1000*1000, 1000*1000*1000, 1000*1000*1000*1000, 1000*1000*1000*1000*1000 };
//public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300};
public static final long[] SCALE_MULTIPLIER={1, 2, 5, 10, 20, 50, 100, 200, 500};
public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER";
public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER";
public static final DecimalFormat TIME_FORMAT_FS = new DecimalFormat("#");
public static final DecimalFormat TIME_FORMAT_PS = new DecimalFormat("#");
public static final DecimalFormat TIME_FORMAT_NS = new DecimalFormat("#.0##");
public static final DecimalFormat TIME_FORMAT_US = new DecimalFormat("#.0#####");
public static final DecimalFormat TIME_FORMAT_MS = new DecimalFormat("#.0#####");
public static DecimalFormat getTimeFormatForLevel(int level) {
switch(level/SCALE_MULTIPLIER.length) {
case 0: return TIME_FORMAT_FS;
case 1: return TIME_FORMAT_PS;
case 2: return TIME_FORMAT_NS;
case 3: return TIME_FORMAT_US;
case 4: return TIME_FORMAT_MS;
default:
return TIME_FORMAT_FS;
}
}
private Constants() {}
}

View File

@ -10,9 +10,11 @@
*******************************************************************************/
package com.minres.scviewer.database.ui.swt.internal;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
@ -21,8 +23,11 @@ import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxEvent;
import com.minres.scviewer.database.tx.ITxRelation;
import com.minres.scviewer.database.ui.WaveformColors;
@ -32,7 +37,7 @@ public class ArrowPainter implements IPainter {
private int yCtrlOffset = 30;
private WaveformCanvas waveCanvas;
private final WaveformCanvas waveCanvas;
private ITx tx;
@ -48,8 +53,6 @@ public class ArrowPainter implements IPainter {
long scaleFactor;
boolean deferUpdate;
public ArrowPainter(WaveformCanvas waveCanvas, RelationType relationType) {
this.waveCanvas = waveCanvas;
highlightType=relationType;
@ -78,36 +81,47 @@ public class ArrowPainter implements IPainter {
}
}
protected void calculateGeometries() {
deferUpdate = false;
private int getConcurrencyIndex(ITx tx) {
IEvent[] eventList = tx.getStream().getEventsBeforeTime(tx.getBeginTime());
Optional<Integer> res = Arrays.stream(eventList).map(e -> ((ITxEvent)e).getRowIndex()).findFirst();
return res.isPresent()? res.get():0;
}
protected boolean calculateGeometries() {
iRect.clear();
oRect.clear();
IWaveformPainter painter = waveCanvas.wave2painterMap.get(tx.getStream());
if(painter == null)
painter = waveCanvas.wave2painterMap.get(tx.getGenerator());
if (painter == null) { // stream has been added but painter not yet
// created
deferUpdate = true;
return;
return true;
}
int laneHeight = painter.getHeight() / tx.getStream().getWidth();
int laneHeight = painter.getHeight() / tx.getStream().getRowCount();
txRectangle = new Rectangle((int) (tx.getBeginTime() / scaleFactor),
waveCanvas.rulerHeight + painter.getVerticalOffset() + laneHeight * tx.getConcurrencyIndex(),
waveCanvas.rulerHeight + painter.getVerticalOffset() + laneHeight * getConcurrencyIndex(tx),
(int) ((tx.getEndTime() - tx.getBeginTime()) / scaleFactor), laneHeight);
deriveGeom(tx.getIncomingRelations(), iRect, false);
deriveGeom(tx.getOutgoingRelations(), oRect, true);
return false;
}
protected void deriveGeom(Collection<ITxRelation> relations, List<LinkEntry> res, boolean useTarget) {
for (ITxRelation iTxRelation : relations) {
ITx otherTx = useTarget ? iTxRelation.getTarget() : iTxRelation.getSource();
if (waveCanvas.wave2painterMap.containsKey(otherTx.getStream())) {
IWaveformPainter painter = waveCanvas.wave2painterMap.get(otherTx.getStream());
int height = waveCanvas.styleProvider.getTrackHeight();
Rectangle bb = new Rectangle(
(int) (otherTx.getBeginTime() / scaleFactor),
waveCanvas.rulerHeight + painter.getVerticalOffset() + height * otherTx.getConcurrencyIndex(),
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor),
height);
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
for(IWaveform iWaveform: new IWaveform[]{otherTx.getStream(), otherTx.getGenerator()}) {
if (waveCanvas.wave2painterMap.containsKey(iWaveform)) {
IWaveformPainter painter = waveCanvas.wave2painterMap.get(iWaveform);
if(painter!=null) {
int height = waveCanvas.styleProvider.getTrackHeight();
Rectangle bb = new Rectangle(
(int) (otherTx.getBeginTime() / scaleFactor),
waveCanvas.rulerHeight + painter.getVerticalOffset() + height * getConcurrencyIndex(otherTx),
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor),
height);
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
}
}
}
}
}
@ -119,11 +133,9 @@ public class ArrowPainter implements IPainter {
Color highliteColor = waveCanvas.styleProvider.getColor(WaveformColors.REL_ARROW_HIGHLITE);
if(tx==null) return;
if (!deferUpdate) {
scaleFactor = waveCanvas.getScaleFactor();
calculateGeometries();
}
if(deferUpdate) return;
scaleFactor = waveCanvas.getScaleFactor();
if(calculateGeometries())
return;
int correctionValue = (int)(selectionOffset);
Rectangle correctedTargetRectangle = new Rectangle(txRectangle.x+correctionValue, txRectangle.y, txRectangle.width, txRectangle.height);
for (LinkEntry entry : iRect) {

View File

@ -15,6 +15,7 @@ import org.eclipse.swt.graphics.Rectangle;
import com.minres.scviewer.database.ui.ICursor;
import com.minres.scviewer.database.ui.WaveformColors;
import com.minres.scviewer.database.ui.swt.Constants;
public class CursorPainter implements IPainter, ICursor {
@ -84,7 +85,7 @@ public class CursorPainter implements IPainter, ICursor {
proj.setBackground(drawColor);
proj.setForeground(textColor);
double dTime=time;
proj.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top);
proj.drawText(Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top);
}
}
}

View File

@ -10,22 +10,20 @@
*******************************************************************************/
package com.minres.scviewer.database.ui.swt.internal;
import java.text.DecimalFormat;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.wb.swt.SWTResourceManager;
import com.minres.scviewer.database.ui.swt.Constants;
public class RulerPainter implements IPainter {
protected WaveformCanvas waveCanvas;
protected final WaveformCanvas waveCanvas;
static final int RULER_TICK_MINOR = 10;
static final int RULER_TICK_MAJOR = 100;
static final DecimalFormat df = new DecimalFormat("#.00####");
public RulerPainter(WaveformCanvas waveCanvas) {
this.waveCanvas=waveCanvas;
}
@ -40,7 +38,7 @@ public class RulerPainter implements IPainter {
if(headerBgColor.isDisposed())
headerBgColor=SWTResourceManager.getColor(255,255,255);
String unit=waveCanvas.getUnitStr();
int unitMultiplier=waveCanvas.getUnitMultiplier();
long unitMultiplier=waveCanvas.getUnitMultiplier();
long scaleFactor=waveCanvas.getScaleFactor();
long startPos=area.x*scaleFactor;
@ -52,7 +50,7 @@ public class RulerPainter implements IPainter {
int minorTickY = waveCanvas.rulerHeight-5;
int majorTickY = waveCanvas.rulerHeight-15;
int textY=waveCanvas.rulerHeight-20;
int textY=waveCanvas.rulerHeight-30;
int baselineY=waveCanvas.rulerHeight - 1;
int bottom=waveCanvas.rulerHeight - 2;
@ -66,13 +64,22 @@ public class RulerPainter implements IPainter {
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, baselineY));
gc.setForeground(headerFgColor);
gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom);
boolean allMarker=true;
for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) {
if ((tick % rulerTickMajor) == 0) {
String text = Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(tick/scaleFactor*unitMultiplier);
if(text.length()>8) allMarker=false;
}
}
boolean drawText = true;
for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) {
int x0Pos = (int) (pos/scaleFactor);
long x0Val = tick/scaleFactor;
if ((tick % rulerTickMajor) == 0) {
gc.drawText(df.format(x0Val*unitMultiplier)+unit, x0Pos, area.y+textY);
if(allMarker || drawText)
gc.drawText(Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(x0Val*unitMultiplier)+unit, x0Pos, area.y+textY);
gc.drawLine(x0Pos, area.y+majorTickY, x0Pos,area.y+ bottom);
drawText=!drawText;
} else {
gc.drawLine(x0Pos, area.y+minorTickY, x0Pos, area.y+bottom);
}

View File

@ -12,8 +12,6 @@ package com.minres.scviewer.database.ui.swt.internal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.NavigableMap;
import javax.swing.JPanel;
@ -26,7 +24,9 @@ import org.eclipse.swt.graphics.Rectangle;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.DoubleVal;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.ui.TrackEntry;
import com.minres.scviewer.database.ui.WaveformColors;
@ -37,16 +37,16 @@ public class SignalPainter extends TrackPainter {
IEvent value;
boolean fromMap;
public SignalChange(Entry<Long, IEvent[]> entry) {
time = entry.getKey();
value = entry.getValue()[0];
public SignalChange(EventEntry entry) {
time = entry.timestamp;
value = entry.events[0];
fromMap = true;
}
public void set(Entry<Long, IEvent[]> entry, Long actTime) {
public void set(EventEntry entry, Long actTime) {
if (entry != null) {
time = entry.getKey();
value = entry.getValue()[0];
time = entry.timestamp;
value = entry.events[0];
fromMap = true;
} else {
time = actTime;
@ -100,21 +100,16 @@ public class SignalPainter extends TrackPainter {
long beginTime = beginPos*scaleFactor;
long endTime = beginTime + area.width*scaleFactor;
Entry<Long, IEvent[]> first = signal.getEvents().floorEntry(beginTime);
Entry<Long, IEvent[]> last = signal.getEvents().floorEntry(endTime);
if (first == null) {
if (last == null)
return;
EventEntry first = signal.getEvents().floorEntry(beginTime);
if (first == null)
first = signal.getEvents().firstEntry();
} else if (last == null) {
last = signal.getEvents().lastEntry();
}
beginTime = first.timestamp;
proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE));
proj.setLineStyle(SWT.LINE_SOLID);
proj.setLineWidth(1);
NavigableMap<Long, IEvent[]> entries = signal.getEvents().subMap(first.getKey(), false, last.getKey(), true);
SignalChange left = new SignalChange(first);
SignalChange right = new SignalChange(entries.size() > 0 ? entries.firstEntry() : first);
IEventList entries = signal.getEvents().subMap(beginTime, true, endTime);
SignalChange left = new SignalChange(entries.firstEntry());
SignalChange right = new SignalChange(entries.size() > 1 ? entries.higherEntry(left.time) : entries.firstEntry());
maxPosX = area.x + area.width;
yOffsetT = this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y;
yOffsetM = this.waveCanvas.styleProvider.getTrackHeight() / 2 + area.y;
@ -153,15 +148,15 @@ public class SignalPainter extends TrackPainter {
if (xSigChangeEndPos == xSigChangeBeginPos) {
multiple = true;
long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScaleFactor();
Entry<Long, IEvent[]> entry = entries.floorEntry(eTime);
if(entry!=null && entry.getKey()> right.time)
EventEntry entry = entries.floorEntry(eTime);
if(entry!=null && entry.timestamp> right.time)
right.set(entry, endTime);
xSigChangeEndPos = getXPosEnd(eTime);
}
} while (left.time < endTime);
}
private SignalStencil getStencil(GC gc, SignalChange left, NavigableMap<Long, IEvent[]> entries) {
private SignalStencil getStencil(GC gc, SignalChange left, IEventList entries) {
IEvent val = left.value;
if(val instanceof BitVector) {
BitVector bv = (BitVector) val;
@ -253,15 +248,15 @@ public class SignalPainter extends TrackPainter {
private long maxVal;
private long minVal;
double yRange = (yOffsetB-yOffsetT);
public MultiBitStencilAnalog(NavigableMap<Long, IEvent[]> entries, Object left, boolean continous, boolean signed) {
public MultiBitStencilAnalog(IEventList entries, Object left, boolean continous, boolean signed) {
this.continous=continous;
this.signed=signed;
Collection<IEvent[]> values = entries.values();
Collection<EventEntry> ievents = entries.entrySet();
minVal=signed?((BitVector)left).toSignedValue():((BitVector)left).toUnsignedValue();
if(!values.isEmpty()) {
if(!ievents.isEmpty()) {
maxVal=minVal;
for (IEvent[] tp : entries.values())
for(IEvent e: tp) {
for (EventEntry tp : ievents)
for(IEvent e: tp.events) {
long v = signed?((BitVector)e).toSignedValue():((BitVector)e).toUnsignedValue();
maxVal=Math.max(maxVal, v);
minVal=Math.min(minVal, v);
@ -358,15 +353,15 @@ public class SignalPainter extends TrackPainter {
boolean continous=true;
public RealStencil(NavigableMap<Long, IEvent[]> entries, Object left, boolean continous) {
public RealStencil(IEventList entries, Object left, boolean continous) {
this.continous=continous;
Collection<IEvent[]> values = entries.values();
Collection<EventEntry> values = entries.entrySet();
minVal=(Double) left;
range=2.0;
if(!values.isEmpty()) {
double maxVal=minVal;
for (IEvent[] val : entries.values())
for(IEvent e:val) {
for (EventEntry val : values)
for(IEvent e:val.events) {
double v = ((DoubleVal)e).value;
if(Double.isNaN(maxVal))
maxVal=v;

View File

@ -10,18 +10,17 @@
*******************************************************************************/
package com.minres.scviewer.database.ui.swt.internal;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeSet;
import java.util.TreeMap;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxEvent;
@ -37,19 +36,27 @@ public class StreamPainter extends TrackPainter{
private IWaveform stream;
private int txBase;
private int txHeight;
private TreeSet<ITx> seenTx;
// TODO: remove TreeMap usage
private TreeMap<ITx, ITxEvent> seenTx;
public StreamPainter(WaveformCanvas waveCanvas, boolean even, TrackEntry trackEntry) {
super(trackEntry, even);
this.waveCanvas = waveCanvas;
this.stream=trackEntry.waveform;
this.seenTx=new TreeSet<>();
this.seenTx=new TreeMap<>();
}
@SuppressWarnings("unchecked")
public void paintArea(Projection proj, Rectangle area) {
if(stream.getEvents().size()==0) return;
int trackHeight=trackEntry.height/stream.getWidth();
int trackHeight=trackEntry.height/stream.getRowCount();
if(stream.getEvents().size()==0) {
proj.setFillRule(SWT.FILL_EVEN_ODD);
proj.setLineStyle(SWT.LINE_SOLID);
proj.setLineWidth(1);
proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE));
for( int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight)
proj.drawLine(area.x, y1, area.x+area.width, y1);
return;
}
txBase=trackHeight/5;
txHeight=trackHeight*3/5;
if(trackEntry.selected) {
@ -65,10 +72,11 @@ public class StreamPainter extends TrackPainter{
long beginTime = beginPos*scaleFactor;
long endTime = beginTime + area.width*scaleFactor;
Entry<Long, ?> firstTx=stream.getEvents().floorEntry(beginTime);
Entry<Long, ?> lastTx=stream.getEvents().ceilingEntry(endTime);
if(firstTx==null) firstTx = stream.getEvents().firstEntry();
if(lastTx==null) lastTx=stream.getEvents().lastEntry();
IEventList events = stream.getEvents();
EventEntry firstTx = events.floorEntry(beginTime);
EventEntry lastTx = events.ceilingEntry(endTime);
if(firstTx==null) firstTx = events.firstEntry();
if(lastTx==null) lastTx = events.lastEntry();
proj.setFillRule(SWT.FILL_EVEN_ODD);
proj.setLineStyle(SWT.LINE_SOLID);
proj.setLineWidth(1);
@ -77,46 +85,50 @@ public class StreamPainter extends TrackPainter{
for( int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight)
proj.drawLine(area.x, y1, area.x+area.width, y1);
if(firstTx==lastTx) {
for(ITxEvent txEvent:(Collection<? extends ITxEvent>)firstTx.getValue())
drawTx(proj, area, txEvent.getTransaction(), false);
for(IEvent txEvent: firstTx.events)
drawTx(proj, area, ((ITxEvent)txEvent).getTransaction(), ((ITxEvent)txEvent).getRowIndex(), false);
}else{
seenTx.clear();
NavigableMap<Long, IEvent[]> entries = stream.getEvents().subMap(firstTx.getKey(), true, lastTx.getKey(), true);
boolean highlighed=false;
ITxEvent highlighed=null;
proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE));
long selectedId=waveCanvas.currentSelection!=null? waveCanvas.currentSelection.getId():-1;
for(Entry<Long, IEvent[]> entry: entries.entrySet())
for(IEvent evt:entry.getValue()){
ITx tx = ((ITxEvent) evt).getTransaction();
highlighed|=selectedId==tx.getId();
for(EventEntry entry: events.subMap(firstTx.timestamp, true, lastTx.timestamp))
for(IEvent e:entry.events){
ITxEvent evt = (ITxEvent) e;
ITx tx = evt.getTransaction();
if(selectedId==tx.getId())
highlighed=evt;
switch(evt.getKind()) {
case BEGIN:
seenTx.add(tx);
seenTx.put(tx, evt);
break;
case END:
drawTx(proj, area, tx, evt.getRowIndex(), false);
seenTx.remove(tx);
break;
case SINGLE:
drawTx(proj, area, tx, false);
drawTx(proj, area, tx, evt.getRowIndex(), false);
break;
}
}
for(ITx tx:seenTx){
drawTx(proj, area, tx, false);
}
if(highlighed){
seenTx.entrySet().stream().forEach(e -> {
drawTx(proj, area, e.getKey(), e.getValue().getRowIndex(), false);
});
if(highlighed!=null){
proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE_HIGHLITE));
drawTx(proj, area, waveCanvas.currentSelection, true);
drawTx(proj, area, highlighed.getTransaction(), highlighed.getRowIndex(), true);
}
}
}
protected void drawTx(Projection proj, Rectangle area, ITx tx, boolean highlighted ) {
protected void drawTx(Projection proj, Rectangle area, ITx tx, int concurrencyIndex, boolean highlighted ) {
// compute colors
Color[] transColor = waveCanvas.styleProvider.computeColor( tx.getGenerator().getName());
proj.setBackground(transColor[highlighted?1:0]);
int offset = tx.getConcurrencyIndex()*this.waveCanvas.styleProvider.getTrackHeight();
int offset = concurrencyIndex*this.waveCanvas.styleProvider.getTrackHeight();
Rectangle bb = new Rectangle(
(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()), area.y+offset+txBase,
(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScaleFactor()), txHeight);
@ -143,12 +155,12 @@ public class StreamPainter extends TrackPainter{
public ITx getClicked(Point point) {
int lane=point.y/waveCanvas.styleProvider.getTrackHeight();
Entry<Long, IEvent[]> firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor());
EventEntry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor());
if(firstTx!=null){
do {
ITx tx = getTxFromEntry(lane, point.x, firstTx);
ITx tx = getTxFromEntry(lane, point.x, firstTx.events);
if(tx!=null) return tx;
firstTx=stream.getEvents().lowerEntry(firstTx.getKey());
firstTx=stream.getEvents().lowerEntry(firstTx.timestamp);
}while(firstTx!=null);
}
return null;
@ -162,27 +174,21 @@ public class StreamPainter extends TrackPainter{
this.stream = stream;
}
protected ITx getTxFromEntry(int lane, int offset, Entry<Long, IEvent[]> firstTx) {
protected ITx getTxFromEntry(int lane, int offset, IEvent[] firstTx) {
long timePoint=offset*waveCanvas.getScaleFactor();
for(IEvent evt:firstTx.getValue()){
if(evt instanceof ITxEvent) {
ITx tx=((ITxEvent)evt).getTransaction();
if((evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE)&&
tx.getConcurrencyIndex()==lane && tx.getBeginTime()<=timePoint && tx.getEndTime()>=timePoint){
return ((ITxEvent)evt).getTransaction();
}
}
}
// now with some fuzziness
timePoint=(offset-5)*waveCanvas.getScaleFactor();
long timePointLow=(offset-5)*waveCanvas.getScaleFactor();
long timePointHigh=(offset+5)*waveCanvas.getScaleFactor();
for(IEvent evt:firstTx.getValue()){
if(evt instanceof ITxEvent) {
ITx tx=((ITxEvent)evt).getTransaction();
if((evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE) &&
tx.getConcurrencyIndex()==lane && tx.getBeginTime()<=timePointHigh && tx.getEndTime()>=timePoint){
return ((ITxEvent)evt).getTransaction();
}
for(IEvent e:firstTx){
if(e instanceof ITxEvent) {
ITxEvent evt = (ITxEvent) e;
ITx tx=evt.getTransaction();
if(
(evt.getKind()==EventKind.SINGLE && evt.getTime()==timePoint) ||
(evt.getKind()==EventKind.SINGLE && evt.getTime()>timePointLow && evt.getTime()<timePointHigh) ||
(evt.getKind()==EventKind.BEGIN && evt.getRowIndex()==lane && evt.getTime()<=timePoint && tx.getEndTime()>=timePoint)
){
return tx;
}
}
}
return null;

View File

@ -11,10 +11,12 @@
package com.minres.scviewer.database.ui.swt.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
@ -32,9 +34,12 @@ import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.ScrollBar;
import com.google.common.collect.Lists;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxEvent;
import com.minres.scviewer.database.ui.IWaveformStyleProvider;
import com.minres.scviewer.database.ui.IWaveformView;
import com.minres.scviewer.database.ui.TrackEntry;
@ -165,7 +170,7 @@ public class WaveformCanvas extends Canvas {
}
public int getMaxZoomLevel(){
return Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length-1;
return Constants.SCALE_MULTIPLIER.length*Constants.UNIT_STRING.length-1;
}
public void setZoomLevel(int level) {
@ -174,12 +179,21 @@ public class WaveformCanvas extends Canvas {
}
public void setZoomLevel(int level, long centerTime) {
if(level<0) {
if(level<-1) {
long cTime = getCursorPainters().get(0).getTime();
long time_diff = centerTime>cTime?centerTime-cTime:cTime-centerTime;
level = findFitZoomLevel(time_diff);
centerTime = (centerTime>cTime?cTime:centerTime)+time_diff/2;
} else
level = findFitZoomLevel(maxTime);
if(level<0) level = 0;
}
//FIXME: keep center if zoom-out and cursor is not in view
long oldScaleFactor=scaleFactor;
if(level<0) level = 0;
if(level<Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length){
this.scaleFactor = (long) Math.pow(10, level/2d);
if(level%2==1) this.scaleFactor*=3;
if(level<Constants.SCALE_MULTIPLIER.length*Constants.UNIT_STRING.length){
int scale = level%Constants.SCALE_MULTIPLIER.length;
int unit = level/Constants.SCALE_MULTIPLIER.length;
this.scaleFactor = Constants.UNIT_MULTIPLIER[unit]*Constants.SCALE_MULTIPLIER[scale];
ITx tx = arrowPainter.getTx();
arrowPainter.setTx(null);
/*
@ -188,8 +202,9 @@ public class WaveformCanvas extends Canvas {
* xcn = tc/newScaleFactor
* t0n = (xcn-xoffs)*scaleFactor
*/
long xc=centerTime/oldScaleFactor; // cursor total x-offset
long xoffs=xc+origin.x; // cursor offset relative to left border
Rectangle clientArea = getClientArea();
long clientAreaWidth = clientArea.width;
long xoffs = clientAreaWidth/2;
long xcn=centerTime/scaleFactor; // new total x-offset
long originX=xcn-xoffs;
if(originX>0) {
@ -204,22 +219,39 @@ public class WaveformCanvas extends Canvas {
}
}
private int findFitZoomLevel(long duration) {
//get area actually capable of displaying data, i.e. area of the receiver which is capable of displaying data
Rectangle clientArea = getClientArea();
long clientAreaWidth = clientArea.width;
//try to find existing zoomlevel where scaleFactor*clientAreaWidth >= maxTime, if one is found set it as new zoomlevel
for(int unitIdx=0; unitIdx<Constants.UNIT_STRING.length; unitIdx++) {
long magnitudeMultiplier = Constants.UNIT_MULTIPLIER[unitIdx];
for (int scaleIdx=0; scaleIdx<Constants.SCALE_MULTIPLIER.length; scaleIdx++){
long scaleFactor = magnitudeMultiplier * Constants.SCALE_MULTIPLIER[scaleIdx];
long range = scaleFactor*clientAreaWidth;
if( range >= duration)
return unitIdx*Constants.SCALE_MULTIPLIER.length+scaleIdx;
}
}
return -1;
}
public long getScaleFactor() {
return scaleFactor;
}
public long getScaleFactorPow10() {
int scale = level/Constants.UNIT_MULTIPLIER.length;
int scale = level/Constants.SCALE_MULTIPLIER.length;
double res = Math.pow(1000, scale);
return (long) res;
}
public String getUnitStr(){
return Constants.UNIT_STRING[level/Constants.UNIT_MULTIPLIER.length];
return Constants.UNIT_STRING[level/Constants.SCALE_MULTIPLIER.length];
}
public int getUnitMultiplier(){
return Constants.UNIT_MULTIPLIER[level%Constants.UNIT_MULTIPLIER.length];
public long getUnitMultiplier(){
return Constants.SCALE_MULTIPLIER[level%Constants.SCALE_MULTIPLIER.length];
}
public long getTimeForOffset(int xOffset){
@ -424,13 +456,17 @@ public class WaveformCanvas extends Canvas {
}
for (IWaveformPainter painter : wave2painterMap.values()) {
if (painter instanceof StreamPainter && ((StreamPainter) painter).getStream() == tx.getStream()) {
int top = painter.getVerticalOffset() + styleProvider.getTrackHeight() * tx.getConcurrencyIndex();
int bottom = top + styleProvider.getTrackHeight();
if (top < -origin.y) {
setOrigin(origin.x, -(top-styleProvider.getTrackHeight()));
} else if (bottom > (size.y - origin.y)) {
setOrigin(origin.x, size.y - bottom);
}
EventEntry entry = tx.getStream().getEvents().floorEntry(tx.getBeginTime());
Optional<IEvent> res = Arrays.stream(entry.events).filter(e -> ((ITxEvent)e).getTransaction().equals(tx)).findFirst();
if(res.isPresent()) {
int top = painter.getVerticalOffset() + styleProvider.getTrackHeight() * ((ITxEvent)res.get()).getRowIndex();
int bottom = top + styleProvider.getTrackHeight();
if (top < -origin.y) {
setOrigin(origin.x, -(top-styleProvider.getTrackHeight()));
} else if (bottom > (size.y - origin.y)) {
setOrigin(origin.x, size.y - bottom);
}
}
}
}
}
@ -467,6 +503,12 @@ public class WaveformCanvas extends Canvas {
}
}
public void centerAt(long time) {
int scaledTime = (int) (time / scaleFactor);
int newX = -scaledTime+getWidth()/2;
setOrigin(newX>0?0:newX, origin.y);
}
public int getRulerHeight() {
return rulerHeight;
}

View File

@ -13,7 +13,6 @@ package com.minres.scviewer.database.ui.swt.internal;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -21,7 +20,6 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.TreeMap;
@ -77,8 +75,10 @@ import org.eclipse.wb.swt.SWTResourceManager;
import com.google.common.collect.Lists;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.DoubleVal;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventKind;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.WaveformType;
@ -98,8 +98,6 @@ public class WaveformView implements IWaveformView {
private PropertyChangeSupport pcs;
static final DecimalFormat df = new DecimalFormat("#0.00####");
private ITx currentTxSelection;
private ArrayList<TrackEntry> currentWaveformSelection = new ArrayList<>();
@ -124,6 +122,12 @@ public class WaveformView implements IWaveformView {
protected ObservableList<TrackEntry> streams;
private boolean waveformsContainTx=false;
public boolean isWaveformsContainTx() {
return waveformsContainTx;
}
int selectedMarker = 0;
private int tracksVerticalHeight;
@ -163,7 +167,7 @@ public class WaveformView implements IWaveformView {
setSelection(new StructuredSelection(res), (e.stateMask & SWT.CTRL) != 0, false);
} else
setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0,
false);
false);
} else {
setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, false);
}
@ -196,88 +200,93 @@ public class WaveformView implements IWaveformView {
down = false;
if (start == null)
return;
if ((e.stateMask & SWT.MODIFIER_MASK & ~SWT.SHIFT) != 0)
return; // don't react on modifier except shift
if (e.button == 1 && Math.abs(e.x - start.x) > 3) {
asyncUpdate(e.widget);
long startTime = waveformCanvas.getTimeForOffset(start.x);
long endTime = waveformCanvas.getTimeForOffset(end.x);
long targetTimeRange = endTime - startTime;
long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime();
if (targetTimeRange == 0)
return;
long relation = currentTimeRange / targetTimeRange;
long i = 1;
int level = 0;
do {
if (relation < 0) {
if (-relation < i) {
break;
}
level--;
if (-relation < i * 3) {
break;
}
level--;
} else {
if (relation < i) {
break;
}
level++;
if (relation < i * 3) {
break;
}
level++;
}
i = i * 10;
} while (i < 10000);
if (i < 10000) {
int curLevel = waveformCanvas.getZoomLevel();
waveformCanvas.setZoomLevel(curLevel - level, (startTime + endTime) / 2);
}
} else if (e.button == 1 && ((e.stateMask & SWT.SHIFT) == 0)) {
// set cursor (button 1 and no shift)
if (Math.abs(e.x - start.x) < 3 && Math.abs(e.y - start.y) < 3) {
// first set cursor time
setCursorTime(snapOffsetToEvent(start));
// then set selection and reveal
setSelection(new StructuredSelection(initialSelected));
if ((e.stateMask & SWT.MODIFIER_MASK & ~(SWT.SHIFT | SWT.CTRL)) != 0)
return; // don't react on modifier except shift and control
boolean isCtrl = (e.stateMask & SWT.CTRL)!=0;
boolean isShift = (e.stateMask & SWT.SHIFT)!=0;
if (e.button == 1) {
if (Math.abs(e.x - start.x) > 3) { // was drag event
asyncUpdate(e.widget);
long startTime = waveformCanvas.getTimeForOffset(start.x);
long endTime = waveformCanvas.getTimeForOffset(end.x);
long targetTimeRange = endTime - startTime;
long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime();
if (targetTimeRange == 0)
return;
long relation = currentTimeRange / targetTimeRange;
long i = 1;
int level = 0;
do {
if (relation < 0) {
if (-relation < i) {
break;
}
level--;
if (-relation < i * 3) {
break;
}
level--;
} else {
if (relation < i) {
break;
}
level++;
if (relation < i * 3) {
break;
}
level++;
}
i = i * 10;
} while (i < 10000);
if (i < 10000) {
int curLevel = waveformCanvas.getZoomLevel();
waveformCanvas.setZoomLevel(curLevel - level, (startTime + endTime) / 2);
}
} else if( isShift) { // set marker (button 1 and shift)
setMarkerTime(snapOffsetToEvent(start), selectedMarker);
} else if(isCtrl) { // set cursor (button 1 and ctrl)
setCursorTime(snapOffsetToEvent(start));
} else { // set cursor (button 1 only)
if (Math.abs(e.y - start.y) < 3) {
// first set cursor time
setCursorTime(snapOffsetToEvent(start));
// then set selection and reveal
setSelection(new StructuredSelection(initialSelected));
}
}
} else if (e.button == 2 || (e.button == 1 && (e.stateMask & SWT.SHIFT) != 0)) {
// set marker (button 1 and shift)
} else if (e.button == 2) { // set marker (button 2)
setMarkerTime(snapOffsetToEvent(start), selectedMarker);
asyncUpdate(e.widget);
}
asyncUpdate(e.widget);
}
protected long snapOffsetToEvent(Point p) {
long time = waveformCanvas.getTimeForOffset(p.x);
long scaling = 5 * waveformCanvas.getScaleFactor();
for (Object o : waveformCanvas.getElementsAt(p)) {
Entry<Long, IEvent[]> floorEntry = null;
Entry<Long, IEvent[]> ceilEntry = null;
EventEntry floorEntry = null;
EventEntry ceilEntry = null;
if (o instanceof TrackEntry) {
TrackEntry entry = (TrackEntry) o;
NavigableMap<Long, IEvent[]> map = entry.waveform.getEvents();
IEventList map = entry.waveform.getEvents();
floorEntry = map.floorEntry(time);
ceilEntry = map.ceilingEntry(time);
} else if (o instanceof ITx) {
NavigableMap<Long, IEvent[]> map = ((ITx) o).getStream().getEvents();
IEventList map = ((ITx) o).getStream().getEvents();
floorEntry = map.floorEntry(time);
ceilEntry = map.ceilingEntry(time);
}
if (floorEntry != null && time - floorEntry.getKey() > scaling)
if (floorEntry != null && time - floorEntry.timestamp > scaling)
floorEntry = null;
if (ceilEntry != null && ceilEntry.getKey() - time > scaling)
if (ceilEntry != null && ceilEntry.timestamp - time > scaling)
ceilEntry = null;
if (ceilEntry == null && floorEntry != null) {
time = floorEntry.getKey();
time = floorEntry.timestamp;
} else if (ceilEntry != null && floorEntry == null) {
time = ceilEntry.getKey();
time = ceilEntry.timestamp;
} else if (ceilEntry != null && floorEntry != null) {
time = time - floorEntry.getKey() < ceilEntry.getKey() - time ? floorEntry.getKey()
: ceilEntry.getKey();
time = time - floorEntry.timestamp < ceilEntry.timestamp - time ? floorEntry.timestamp
: ceilEntry.timestamp;
}
}
return time;
@ -286,8 +295,8 @@ public class WaveformView implements IWaveformView {
@Override
public void handleEvent(Event e) {
switch (e.type) {
case SWT.MouseWheel:
break;
// case SWT.MouseWheel:
// break;
case SWT.MouseDown:
start = new Point(e.x, e.y);
end = new Point(e.x, e.y);
@ -509,13 +518,15 @@ public class WaveformView implements IWaveformView {
boolean even = true;
TextLayout tl = new TextLayout(waveformCanvas.getDisplay());
tl.setFont(styleProvider.getNameFont());
waveformsContainTx=false;
for (TrackEntry streamEntry : streams) {
streamEntry.height = styleProvider.getTrackHeight();
streamEntry.vOffset = tracksVerticalHeight;
if (streamEntry.waveform.getType() == WaveformType.TRANSACTION) {
streamEntry.currentValue = "";
streamEntry.height *= streamEntry.waveform.getWidth();
streamEntry.height *= streamEntry.waveform.getRowCount();
painter = new StreamPainter(waveformCanvas, even, streamEntry);
waveformsContainTx=true;
} else if (streamEntry.waveform.getType() == WaveformType.SIGNAL) {
streamEntry.currentValue = "---";
painter = new SignalPainter(waveformCanvas, even, streamEntry);
@ -579,20 +590,21 @@ public class WaveformView implements IWaveformView {
entry.currentValue = Double.toString(val);
}
} else if (entry.waveform.getType() == WaveformType.TRANSACTION) {
ITx[] resultsList = new ITx[entry.waveform.getWidth()];
Entry<Long, IEvent[]> firstTx = entry.waveform.getEvents().floorEntry(time);
ITx[] resultsList = new ITx[entry.waveform.getRowCount()];
EventEntry firstTx = entry.waveform.getEvents().floorEntry(time);
if (firstTx != null) {
do {
for (IEvent evt : firstTx.getValue()) {
if (evt instanceof ITxEvent) {
ITx tx = ((ITxEvent) evt).getTransaction();
for (IEvent e : firstTx.events) {
if (e instanceof ITxEvent) {
ITxEvent evt = ((ITxEvent) e);
ITx tx = evt.getTransaction();
if ((evt.getKind() == EventKind.BEGIN || evt.getKind() == EventKind.SINGLE)
&& tx.getBeginTime() <= time && tx.getEndTime() >= time
&& resultsList[tx.getConcurrencyIndex()] == null)
resultsList[tx.getConcurrencyIndex()] = ((ITxEvent) evt).getTransaction();
&& resultsList[evt.getRowIndex()] == null)
resultsList[evt.getRowIndex()] = evt.getTransaction();
}
}
firstTx = entry.waveform.getEvents().lowerEntry(firstTx.getKey());
firstTx = entry.waveform.getEvents().lowerEntry(firstTx.timestamp);
} while (firstTx != null && !isArrayFull(resultsList));
boolean separator = false;
StringBuilder sb = new StringBuilder();
@ -754,7 +766,7 @@ public class WaveformView implements IWaveformView {
ITx txSel = (ITx) selList.get(0);
TrackEntry trackEntry = selList.size() == 2 && selList.get(1) instanceof TrackEntry
? (TrackEntry) selList.get(1)
: null;
: null;
if (trackEntry == null) {
trackEntry = getEntryFor(txSel);
if (trackEntry == null && addIfNeeded) {
@ -853,11 +865,11 @@ public class WaveformView implements IWaveformView {
}
}
if (transaction == null) {
Entry<Long, IEvent[]> entry = selectedWaveform.waveform.getEvents()
EventEntry entry = selectedWaveform.waveform.getEvents()
.higherEntry(currentTxSelection.getBeginTime());
if (entry != null)
do {
for (IEvent evt : entry.getValue()) {
for (IEvent evt : entry.events) {
if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN
|| evt.getKind() == EventKind.SINGLE)) {
transaction = ((ITxEvent) evt).getTransaction();
@ -865,7 +877,7 @@ public class WaveformView implements IWaveformView {
}
}
if (transaction == null)
entry = selectedWaveform.waveform.getEvents().higherEntry(entry.getKey());
entry = selectedWaveform.waveform.getEvents().higherEntry(entry.timestamp);
} while (entry != null && transaction == null);
}
} else if (direction == GotoDirection.PREV) {
@ -882,11 +894,11 @@ public class WaveformView implements IWaveformView {
}
}
if (transaction == null) {
Entry<Long, IEvent[]> entry = selectedWaveform.waveform.getEvents()
EventEntry entry = selectedWaveform.waveform.getEvents()
.lowerEntry(currentTxSelection.getBeginTime());
if (entry != null)
do {
for (IEvent evt : Lists.reverse(Arrays.asList(entry.getValue()))) {
for (IEvent evt : Lists.reverse(Arrays.asList(entry.events))) {
if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN
|| evt.getKind() == EventKind.SINGLE)) {
transaction = ((ITxEvent) evt).getTransaction();
@ -894,7 +906,7 @@ public class WaveformView implements IWaveformView {
}
}
if (transaction == null)
entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.getKey());
entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.timestamp);
} while (entry != null && transaction == null);
}
}
@ -928,7 +940,7 @@ public class WaveformView implements IWaveformView {
return candidates.get(0);
default:
ArrayList<ITxRelation> visibleCandidates = candidates.stream().filter(this::streamsVisible)
.collect(Collectors.toCollection(ArrayList::new));
.collect(Collectors.toCollection(ArrayList::new));
if (visibleCandidates.isEmpty()) {
return new RelSelectionDialog(waveformCanvas.getShell(), candidates, target).open();
} else if (visibleCandidates.size() == 1) {
@ -957,14 +969,14 @@ public class WaveformView implements IWaveformView {
return;
TrackEntry sel = currentWaveformSelection.get(0);
long time = getCursorTime();
NavigableMap<Long, ?> map = null;
IEventList map = null;
if (sel.waveform.getType() == WaveformType.TRANSACTION || sel.waveform.getType() == WaveformType.SIGNAL) {
map = sel.waveform.getEvents();
}
if (map != null) {
Entry<Long, ?> entry = direction == GotoDirection.PREV ? map.lowerEntry(time) : map.higherEntry(time);
EventEntry entry = direction == GotoDirection.PREV ? map.lowerEntry(time) : map.higherEntry(time);
if (entry != null) {
time = entry.getKey();
time = entry.timestamp;
setCursorTime(time);
waveformCanvas.reveal(time);
waveformCanvas.redraw();
@ -1036,7 +1048,7 @@ public class WaveformView implements IWaveformView {
TrackEntry trackEntry = trackVerticalOffset.get(firstKey);
IWaveform w = trackEntry.waveform;
if (w.getType() == WaveformType.TRANSACTION)
subArea.height *= w.getWidth();
subArea.height *= w.getRowCount();
drawTextFormat(gc, subArea, firstKey, w.getFullName(), trackEntry.selected);
} else {
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
@ -1044,7 +1056,7 @@ public class WaveformView implements IWaveformView {
IWaveform w = entry.getValue().waveform;
subArea.height = styleProvider.getTrackHeight();
if (w.getType() == WaveformType.TRANSACTION)
subArea.height *= w.getWidth();
subArea.height *= w.getRowCount();
drawTextFormat(gc, subArea, entry.getKey(), w.getFullName(), entry.getValue().selected);
}
}
@ -1065,7 +1077,7 @@ public class WaveformView implements IWaveformView {
TrackEntry trackEntry = trackVerticalOffset.get(firstKey);
IWaveform w = trackEntry.waveform;
if (w.getType() == WaveformType.TRANSACTION)
subArea.height *= w.getWidth();
subArea.height *= w.getRowCount();
drawValue(gc, subArea, firstKey, trackEntry.currentValue, trackEntry.selected);
} else {
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
@ -1073,7 +1085,7 @@ public class WaveformView implements IWaveformView {
IWaveform w = entry.getValue().waveform;
subArea.height = styleProvider.getTrackHeight();
if (w.getType() == WaveformType.TRANSACTION)
subArea.height *= w.getWidth();
subArea.height *= w.getRowCount();
drawValue(gc, subArea, entry.getKey(), entry.getValue().currentValue,
entry.getValue().selected);
}
@ -1140,8 +1152,12 @@ public class WaveformView implements IWaveformView {
*/
@Override
public void setZoomLevel(int scale) {
waveformCanvas.setZoomLevel(scale);
waveformCanvas.reveal(getCursorTime());
if(scale<-1) {
waveformCanvas.setZoomLevel(scale, getMarkerTime(selectedMarker));
} else {
waveformCanvas.setZoomLevel(scale);
waveformCanvas.reveal(getCursorTime());
}
}
/*
@ -1228,7 +1244,7 @@ public class WaveformView implements IWaveformView {
if (event.y < tracksVerticalHeight) {
event.doit = true;
LocalSelectionTransfer.getTransfer()
.setSelection(new StructuredSelection(currentWaveformSelection));
.setSelection(new StructuredSelection(currentWaveformSelection));
}
}
@ -1458,7 +1474,7 @@ public class WaveformView implements IWaveformView {
StringBuilder sb = new StringBuilder();
double dTime = time;
double scaledTime = dTime / waveformCanvas.getScaleFactorPow10();
return sb.append(df.format(scaledTime)).append(waveformCanvas.getUnitStr()).toString();
return sb.append(Constants.getTimeFormatForLevel(waveformCanvas.getZoomLevel()).format(scaledTime)).append(waveformCanvas.getUnitStr()).toString();
}
/*
@ -1468,11 +1484,11 @@ public class WaveformView implements IWaveformView {
*/
@Override
public String[] getZoomLevels() {
String[] res = new String[Constants.UNIT_MULTIPLIER.length * Constants.UNIT_STRING.length];
String[] res = new String[Constants.SCALE_MULTIPLIER.length * Constants.UNIT_STRING.length];
int index = 0;
for (String unit : Constants.UNIT_STRING) {
for (int factor : Constants.UNIT_MULTIPLIER) {
res[index++] = Integer.toString(factor) + unit;
for (long factor : Constants.SCALE_MULTIPLIER) {
res[index++] = Long.toString(factor) + unit;
}
}
return res;
@ -1502,6 +1518,22 @@ public class WaveformView implements IWaveformView {
waveformCanvas.redraw();
}
@Override
public void scrollTo(int pos) {
long time = 0;
switch(pos) {
case IWaveformView.CURSOR_POS:
time = getCursorTime();
break;
case IWaveformView.MARKER_POS:
time = getMarkerTime(selectedMarker);
break;
default:
break;
}
waveformCanvas.centerAt(time);
}
public void asyncUpdate(Widget widget) {
widget.getDisplay().asyncExec(() -> {
waveformCanvas.redraw();
@ -1531,5 +1563,4 @@ public class WaveformView implements IWaveformView {
getStreamList().add(idx, e);
return e;
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>

View File

@ -1,8 +1,10 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: VCD signal database
Bundle-SymbolicName: com.minres.scviewer.database.vcd
Bundle-Version: 2.2.0.qualifier
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.eclipse.osgi.services;bundle-version="3.4.0",
com.google.guava;bundle-version="15.0.0"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="VCDDbLoader">
<implementation class="com.minres.scviewer.database.vcd.VCDDbLoader"/>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="VCDDbLoaderFactory">
<implementation class="com.minres.scviewer.database.vcd.VCDDbLoaderFactory"/>
<service>
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
<provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/>
</service>
</scr:component>

View File

@ -1,12 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.database.vcd</artifactId>
<version>2.2.0-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
</project>

View File

@ -20,15 +20,13 @@ import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.Vector;
import java.util.zip.GZIPInputStream;
import com.google.common.collect.Iterables;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.DoubleVal;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader;
@ -115,19 +113,20 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
moduleStack=null;
throw new InputFormatException(e.toString());
}
if(!res) throw new InputFormatException("Could not parse VCD file");
if(!res)
throw new InputFormatException("Could not parse VCD file");
// calculate max time of this database
for(IWaveform waveform:signals) {
NavigableMap<Long, IEvent[]> events =waveform.getEvents();
IEventList events =waveform.getEvents();
if(!events.isEmpty())
maxTime= Math.max(maxTime, events.lastKey());
}
// extend signals to have a last value set at max time
for(IWaveform s:signals){
if(s instanceof VCDSignal<?>) {
TreeMap<Long,?> events = (TreeMap<Long, ?>) ((VCDSignal<?>)s).getEvents();
IEventList events = ((VCDSignal<?>)s).getEvents();
if(events.size()>0 && events.lastKey()<maxTime){
Object val = events.lastEntry().getValue();
Object val = events.lastEntry().events[0];
if(val instanceof BitVector) {
((VCDSignal<BitVector>)s).addSignalChange(maxTime, (BitVector) val);
} else if(val instanceof DoubleVal)
@ -147,7 +146,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
* @see com.minres.scviewer.database.ITrDb#getMaxTime()
*/
@Override
public Long getMaxTime() {
public long getMaxTime() {
return maxTime;
}
@ -165,7 +164,8 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
@Override
public void enterModule(String tokenString) {
if(moduleStack.isEmpty()) {
if("SystemC".compareTo(tokenString)!=0) moduleStack.push(tokenString);
if("SystemC".compareTo(tokenString)!=0)
moduleStack.push(tokenString);
} else
moduleStack.push(moduleStack.peek()+"."+tokenString);
@ -204,7 +204,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
@Override
public int getNetWidth(int intValue) {
VCDSignal<?> signal = (VCDSignal<?>) signals.get(intValue);
return signal.getWidth();
return signal.getRowCount();
}
/* (non-Javadoc)

View File

@ -0,0 +1,77 @@
/*******************************************************************************
* Copyright (c) 2015-2021 MINRES Technologies GmbH and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* MINRES Technologies GmbH - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.vcd;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
/**
* The Class VCDDb.
*/
public class VCDDbLoaderFactory implements IWaveformDbLoaderFactory {
/**
* Checks if is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
private static boolean isGzipped(File f) {
try (InputStream is = new FileInputStream(f)) {
byte [] signature = new byte[2];
int nread = is.read( signature ); //read the gzip signature
return nread == 2 && signature[ 0 ] == (byte) 0x1f && signature[ 1 ] == (byte) 0x8b;
}
catch (IOException e) {
return false;
}
}
/**
* Can load.
*
* @param inputFile the input file
* @return true, if successful
*/
@Override
public boolean canLoad(File inputFile) {
if(!inputFile.isDirectory() || inputFile.exists()) {
String name = inputFile.getName();
if(!(name.endsWith(".vcd") ||
name.endsWith(".vcdz") ||
name.endsWith(".vcdgz") ||
name.endsWith(".vcd.gz")) )
return false;
boolean gzipped = isGzipped(inputFile);
try(InputStream stream = gzipped ? new GZIPInputStream(new FileInputStream(inputFile)) : new FileInputStream(inputFile)){
byte[] buffer = new byte[8];
if (stream.read(buffer, 0, buffer.length) == buffer.length) {
return buffer[0]=='$';
}
} catch (Exception e) {
return false;
}
}
return false;
}
@Override
public IWaveformDbLoader getLoader() {
return new VCDDbLoader();
}
}

View File

@ -10,12 +10,11 @@
*******************************************************************************/
package com.minres.scviewer.database.vcd;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import com.minres.scviewer.database.EventEntry;
import com.minres.scviewer.database.EventList;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.WaveformType;
@ -27,7 +26,7 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
private final int width;
private NavigableMap<Long, IEvent[]> values;
private IEventList values;
public VCDSignal(String name) {
this(0, name, 1);
@ -42,7 +41,7 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
fullName=name;
this.id=id;
this.width=width;
this.values=new TreeMap<>();
this.values=new EventList();
}
public VCDSignal(VCDSignal<T> o, int id, String name) {
@ -63,44 +62,36 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
}
@Override
public Long getId() {
public long getId() {
return id;
}
public void addSignalChange(Long time, T value){
if(values.containsKey(time)) {
IEvent[] oldV = values.get(time);
IEvent[] newV = new IEvent[oldV.length+1];
System.arraycopy(oldV, 0, newV, 0, oldV.length);
newV[oldV.length]=value;
values.put(time, newV);
} else {
values.put(time, new IEvent[] {value});
}
values.put(time, value);
}
@Override
public NavigableMap<Long, IEvent[]> getEvents() {
public IEventList getEvents() {
return values;
}
@Override
public IEvent[] getEventsAtTime(Long time) {
public IEvent[] getEventsAtTime(long time) {
return values.get(time);
}
@Override
public IEvent[] getEventsBeforeTime(Long time) {
Entry<Long, IEvent[]> e = values.floorEntry(time);
public IEvent[] getEventsBeforeTime(long time) {
EventEntry e = values.floorEntry(time);
if(e==null)
return new IEvent[] {};
else
return values.floorEntry(time).getValue();
return values.floorEntry(time).events;
}
@Override
public boolean isSame(IWaveform other) {
return( other instanceof VCDSignal<?> && this.getId().equals(other.getId()));
return( other instanceof VCDSignal<?> && this.getId() == other.getId());
}
@Override
@ -109,7 +100,7 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform {
}
@Override
public int getWidth() {
public int getRowCount() {
return width;
}

View File

@ -1,7 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -1,9 +1,16 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Waveform database
Bundle-SymbolicName: com.minres.scviewer.database
Bundle-Version: 3.0.0.qualifier
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-11
Export-Package: com.minres.scviewer.database,
com.minres.scviewer.database.tx
Bundle-ActivationPolicy: lazy

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="com.minres.scviewer.database.loader">
<implementation class="com.minres.scviewer.database.internal.WaveformDb"/>
<reference bind="bind" cardinality="1..n" interface="com.minres.scviewer.database.IWaveformDbLoader" name="IWaveformDbLoader" policy="dynamic" unbind="unbind"/>
<reference bind="bind" cardinality="1..n" interface="com.minres.scviewer.database.IWaveformDbLoaderFactory" name="IWaveformDbLoaderFactory" policy="dynamic" unbind="unbind"/>
</scr:component>

View File

@ -4,9 +4,9 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
<version>3.0.0-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
</project>

View File

@ -0,0 +1,41 @@
package com.minres.scviewer.database;
import java.util.Arrays;
public class EventEntry implements Comparable<EventEntry>{
public long timestamp; // unsigned
public IEvent[] events = null;
public EventEntry(long timestamp) {
this.timestamp = timestamp;
}
public EventEntry(long timestamp, IEvent[] events) {
this.timestamp = timestamp;
this.events = events;
}
@Override
public int compareTo(EventEntry o) {
return Long.compareUnsigned(timestamp, o.timestamp);
}
@Override
public String toString() {
return String.format("e.%d@%d", events.length,timestamp);
}
public void append(IEvent value) {
if(events.length==0)
events = new IEvent[] {value};
else {
int idx = events.length;
events = Arrays.copyOf(events, idx+1);
events[idx]=value;
}
}
}

View File

@ -0,0 +1,195 @@
package com.minres.scviewer.database;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class EventList implements IEventList {
ArrayList<EventEntry> store = new ArrayList<>();
int start = 0;
int end = store.size();
boolean unmodifiable = false;
public class Iterator implements java.util.Iterator<EventEntry> {
EventList list;
private int pos;
public Iterator(EventList list) {
this.list=list;
this.pos=-1;
}
@Override
public boolean hasNext() {
return pos<(list.end-1);
}
@Override
public EventEntry next() {
if(hasNext()) {
pos++;
return list.store.get(pos);
} else
return null;
}
@Override
public void remove() {
list.store.remove(pos);
}
}
public EventList() {
}
private EventList(ArrayList<EventEntry> store , int start, int end) {
this.store=store;
this.start=start;
this.end=end;
this.unmodifiable=true;
}
@Override
public IEventList subMap(long from, boolean includeFrom, long to) {
//the index of the first element greater than the key, or list.size()
int beginIndex = Collections.binarySearch(store, new EventEntry(from));
int startIndex = beginIndex < 0? -(beginIndex + 1): beginIndex;
int endIndex = Collections.binarySearch(store, new EventEntry(to));
endIndex = endIndex < 0? -(endIndex + 1): endIndex+1;
if(beginIndex>0 && !includeFrom)
return new EventList(store, startIndex+1, endIndex);
else
return new EventList(store, startIndex, endIndex);
}
@Override
public int size() {
return end-start;
}
@Override
public boolean containsKey(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
return index>=0 && index>=start && index<end;
}
@Override
public IEvent[] get(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
if(index<0) return null;
return index>=start && index<end? store.get(index).events: null;
}
@Override
public void put(long key, IEvent value) {
if(unmodifiable) throw new UnsupportedOperationException();
if(store.size()==0 || store.get(store.size()-1).timestamp < key) {
store.add(new EventEntry(key, new IEvent[] {value}));
} else {
int index = Collections.binarySearch(store, new EventEntry(key));
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0) {
EventEntry e = new EventEntry(key, new IEvent[] {value});
index = -(index + 1);
store.add(index, e);
} else {
// Insertion index is index of existing element, to add new element behind it increase index
store.get(index).append(value);
}
}
end=store.size();
}
@Override
public Collection<EventEntry> entrySet() {
if(start != 0 || end != store.size())
return Collections.unmodifiableList(store.subList(start, end));
else
return Collections.unmodifiableList(store);
}
@Override
public boolean isEmpty() {
return start==end || store.isEmpty();
}
@Override
public long firstKey() {
return store.get(start).timestamp;
}
@Override
public long lastKey() {
return store.get(end-1).timestamp;
}
// Navigable map functions
@Override
public EventEntry firstEntry() {
return store.get(start);
}
@Override
public EventEntry lastEntry() {
return store.get(end-1);
}
@Override
public EventEntry floorEntry(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
if(index==-1) return null;
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0) {
index = -(index + 2);
}
if(index>=end)
return store.get(end-1);
return index<start? null: store.get(index);
}
@Override
public EventEntry ceilingEntry(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0)
index = -(index + 1);
if(index<start)
return store.get(start);
return index>=end? null: store.get(index);
}
@Override
public EventEntry lowerEntry(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0)
index = -(index + 1);
index--;
if(index>=end)
return store.get(end-1);
return index>=end || index<start ?null:store.get(index);
}
@Override
public EventEntry higherEntry(long key) {
int index = Collections.binarySearch(store, new EventEntry(key));
// < 0 if element is not in the list, see Collections.binarySearch
if (index < 0)
index = -(index + 1);
else
index++;
if(index<start)
return store.get(start);
return index>=end || index<start ?null:store.get(index);
}
@Override
public java.util.Iterator<EventEntry> iterator() {
return new Iterator(this);
}
}

View File

@ -80,7 +80,7 @@ public class HierNode implements IHierNode {
}
/**
* Gets the full name.
* Gets the full hierarchical name.
*
* @return the full name
*/

View File

@ -0,0 +1,84 @@
package com.minres.scviewer.database;
import java.util.Collection;
public interface IEventList extends Iterable<EventEntry> {
int size();
Collection<EventEntry> entrySet();
boolean containsKey(long key);
IEvent[] get(long key);
void put(long key, IEvent value);
long firstKey();
long lastKey();
boolean isEmpty();
/**
* Returns a key-value mapping associated with the greatest key less
* than or equal to the given key, or null if there is no such key.
*
* @param key
* @return
*/
EventEntry floorEntry(long key);
/**
* Returns a key-value mapping associated with the least key greater
* than or equal to the given key, or null if there is no such key.
*
* @param key
* @return
*/
EventEntry ceilingEntry(long key);
/**
* Returns a key-value mapping associated with the least key in this map,
* or null if the map is empty.
*
* @return
*/
EventEntry firstEntry();
/**
* Returns a key-value mapping associated with the least key in this map,
* or null if the map is empty.
*
* @return
*/
EventEntry lastEntry();
/**
* Returns a key-value mapping associated with the least key strictly greater
* than the given key, or null if there is no such key.
*
* @param key
* @return
*/
EventEntry higherEntry(long key);
/**
* Returns a key-value mapping associated with the greatest key strictly less
* than the given key, or null if there is no such key.
*
* @param key
* @return
*/
EventEntry lowerEntry(long key);
/**
* Returns a view of the portion of this map whose keys range from
* {@code fromKey} to {@code toKey}. If {@code fromKey} and
* {@code toKey} are equal, the returned map is empty unless
* {@code fromInclusive} is true. The
* returned map is backed by this map, so changes in the returned map are
* reflected in this map, and vice-versa. The returned map supports all
* optional map operations that this map supports.
*
* @param fromKey low endpoint of the keys in the returned map
* @param fromInclusive {@code true} if the low endpoint
* is to be included in the returned view
* @param toKey high endpoint of the keys in the returned map (inclusive)
*/
IEventList subMap(long key, boolean b, long key2);
}

View File

@ -10,8 +10,8 @@
*******************************************************************************/
package com.minres.scviewer.database;
import java.util.NavigableMap;
// TODO: Auto-generated Javadoc
/**
* The Interface IWaveform.
*
@ -24,7 +24,7 @@ public interface IWaveform extends IHierNode {
*
* @return the id
*/
public Long getId();
public long getId();
/**
* Checks if is same.
@ -39,7 +39,7 @@ public interface IWaveform extends IHierNode {
*
* @return the events
*/
public NavigableMap<Long, IEvent[]> getEvents();
public IEventList getEvents();
/**
* Gets the events at time.
@ -47,7 +47,7 @@ public interface IWaveform extends IHierNode {
* @param time the time
* @return the events at time
*/
public IEvent[] getEventsAtTime(Long time);
public IEvent[] getEventsAtTime(long time);
/**
* Gets the events before time.
@ -55,7 +55,7 @@ public interface IWaveform extends IHierNode {
* @param time the time
* @return the events before time
*/
public IEvent[] getEventsBeforeTime(Long time);
public IEvent[] getEventsBeforeTime(long time);
/**
* Gets the type.
@ -76,6 +76,6 @@ public interface IWaveform extends IHierNode {
*
* @return the width
*/
public int getWidth();
public int getRowCount();
}

View File

@ -23,7 +23,7 @@ public interface IWaveformDb extends IHierNode {
*
* @return the max time
*/
public Long getMaxTime();
public long getMaxTime();
/**
* Gets the stream by name.
@ -62,9 +62,4 @@ public interface IWaveformDb extends IHierNode {
*/
public boolean isLoaded();
/**
* Clear.
*/
public void clear();
}

View File

@ -69,7 +69,7 @@ public interface IWaveformDbLoader {
*
* @return the max time
*/
public Long getMaxTime();
public long getMaxTime();
/**
* Gets the all waves.

View File

@ -8,20 +8,26 @@
* Contributors:
* MINRES Technologies GmbH - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.tx;
package com.minres.scviewer.database;
import com.minres.scviewer.database.IWaveform;
import java.io.File;
/**
* The Interface ITxGenerator.
* A factory for creating IWaveformDb objects.
*/
public interface ITxGenerator extends IWaveform {
public interface IWaveformDbLoaderFactory {
/**
* Gets the stream.
* Check if the loader produced by this factory can load the given file.
*
* @return the stream
* @param inputFile the input file
* @return true, if successful
*/
public IWaveform getStream();
public boolean canLoad(File inputFile);
/**
* Gets the database.
*
* @return the database
*/
IWaveformDbLoader getLoader();
}

View File

@ -15,16 +15,17 @@ import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.IHierNode;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
import com.minres.scviewer.database.RelationType;
/**
@ -33,7 +34,7 @@ import com.minres.scviewer.database.RelationType;
public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeListener {
/** The loaders. */
private static List<IWaveformDbLoader> loaders = new LinkedList<>();
private static List<IWaveformDbLoaderFactory> loaderFactories = new LinkedList<>();
/** The loaded. */
private boolean loaded;
@ -45,15 +46,15 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
private Map<String, IWaveform> waveforms;
/** The max time. */
private Long maxTime;
private long maxTime = -1;
/**
* Bind.
*
* @param loader the loader
*/
public synchronized void bind(IWaveformDbLoader loader) {
loaders.add(loader);
public synchronized void bind(IWaveformDbLoaderFactory loader) {
loaderFactories.add(loader);
}
/**
@ -61,8 +62,8 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
*
* @param loader the loader
*/
public synchronized void unbind(IWaveformDbLoader loader) {
loaders.remove(loader);
public synchronized void unbind(IWaveformDbLoaderFactory loader) {
loaderFactories.remove(loader);
}
/**
@ -70,8 +71,8 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
*
* @return the loaders
*/
public static List<IWaveformDbLoader> getLoaders() {
return Collections.unmodifiableList(loaders);
public static List<IWaveformDbLoaderFactory> getLoaders() {
return Collections.unmodifiableList(loaderFactories);
}
/**
@ -79,7 +80,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
*/
public WaveformDb() {
super();
waveforms = new HashMap<>();
waveforms = new ConcurrentHashMap<>();
relationTypes = new ArrayList<>();
maxTime = 0L;
}
@ -90,7 +91,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
* @return the max time
*/
@Override
public Long getMaxTime() {
public long getMaxTime() {
return maxTime;
}
@ -123,31 +124,32 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
*/
@Override
public boolean load(File inp) {
for (IWaveformDbLoader loader : loaders) {
if (loader.canLoad(inp)) {
boolean retval = true;
for (IWaveformDbLoaderFactory loaderFactory : loaderFactories) {
if (loaderFactory.canLoad(inp)) {
IWaveformDbLoader loader = loaderFactory.getLoader();
loader.addPropertyChangeListener(this);
try {
loader.addPropertyChangeListener(this);
loader.load(this, inp);
loader.removePropertyChangeListener(this);
for (IWaveform w : loader.getAllWaves()) {
waveforms.put(w.getFullName(), w);
}
if (loader.getMaxTime() > maxTime) {
maxTime = loader.getMaxTime();
}
if (name == null)
name = getFileBasename(inp.getName());
buildHierarchyNodes();
relationTypes.addAll(loader.getAllRelationTypes());
pcs.firePropertyChange(IHierNode.LOADING_FINISHED, null, null);
loaded = true;
return true;
} catch (Exception e) {
return false;
retval=false;
}
loader.removePropertyChangeListener(this);
for (IWaveform w : loader.getAllWaves()) {
waveforms.put(w.getFullName(), w);
}
if (loader.getMaxTime() > maxTime) {
maxTime = loader.getMaxTime();
}
if (name == null)
name = getFileBasename(inp.getName());
buildHierarchyNodes();
relationTypes.addAll(loader.getAllRelationTypes());
}
}
return false;
pcs.firePropertyChange(IHierNode.LOADING_FINISHED, null, null);
loaded = true;
return retval;
}
/**
@ -165,16 +167,6 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
return ext;
}
/**
* Clear.
*/
@Override
public void clear() {
waveforms.clear();
childNodes.clear();
loaded = false;
}
/**
* Checks if is loaded.
*
@ -189,6 +181,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
if (IWaveformDbLoader.SIGNAL_ADDED.equals(evt.getPropertyName())
|| IWaveformDbLoader.STREAM_ADDED.equals(evt.getPropertyName())) {
IWaveform waveform = (IWaveform) evt.getNewValue();
waveforms.put(waveform.getFullName(), waveform);
putInHierarchy(waveform);
pcs.firePropertyChange(IHierNode.WAVEFORMS, null, waveforms);
pcs.firePropertyChange(IHierNode.CHILDS, null, childNodes);
@ -200,7 +193,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
/**
* Builds the hierarchy nodes.
*/
private void buildHierarchyNodes() {
private synchronized void buildHierarchyNodes() {
boolean needsSorting = false;
for (IWaveform stream : getAllWaves()) {
if (stream.getParent() == null) {
@ -226,14 +219,13 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL
break;
}
}
if (childNode != null) {
if (childNode == null) {
HierNode newNode = new HierNode(name, node);
node.addChild(newNode);
node = newNode;
} else {
node = childNode;
break;
}
HierNode newNode = new HierNode(name, node);
node.addChild(newNode);
node = newNode;
}
node.addChild(waveform);
waveform.setParent(node);

View File

@ -25,7 +25,7 @@ public interface ITx extends Comparable<ITx> {
*
* @return the id
*/
public Long getId();
public long getId();
/**
* Gets the stream.
@ -39,28 +39,21 @@ public interface ITx extends Comparable<ITx> {
*
* @return the generator
*/
public ITxGenerator getGenerator();
public IWaveform getGenerator();
/**
* Gets the begin time.
*
* @return the begin time
*/
public Long getBeginTime();
public long getBeginTime();
/**
* Gets the end time.
*
* @return the end time
*/
public Long getEndTime();
/**
* Gets the concurrency index.
*
* @return the concurrency index
*/
public int getConcurrencyIndex();
public long getEndTime();
/**
* Gets the attributes.

View File

@ -22,7 +22,7 @@ public interface ITxEvent extends IEvent {
*
* @return the time
*/
public Long getTime();
public long getTime();
/**
* Gets the transaction.
@ -30,4 +30,12 @@ public interface ITxEvent extends IEvent {
* @return the transaction
*/
public ITx getTransaction();
/**
* Gets the concurrency index.
*
* @return the concurrency index
*/
public int getRowIndex();
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>

View File

@ -1,13 +1,15 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:ui="http://www.eclipse.org/ui/2010/UIModel/application/ui" xmi:id="_95PfsHNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ide.application" bindingContexts="_95PfuXNmEeWBq8z1Dv39LA">
<children xsi:type="basic:TrimmedWindow" xmi:id="_95PfsXNmEeWBq8z1Dv39LA" label="SC Viewer" bindingContexts="_95PfunNmEeWBq8z1Dv39LA" width="1280" height="700">
<children xsi:type="basic:TrimmedWindow" xmi:id="_95PfsXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.trimmedwindow.main" label="SC Viewer" bindingContexts="_95PfunNmEeWBq8z1Dv39LA" width="1280" height="700">
<children xsi:type="advanced:PerspectiveStack" xmi:id="_95QGxnNmEeWBq8z1Dv39LA">
<children xsi:type="advanced:Perspective" xmi:id="_95QGx3NmEeWBq8z1Dv39LA">
<children xsi:type="basic:PartStack" xmi:id="_95QGyXNmEeWBq8z1Dv39LA" elementId="org.eclipse.editorss" containerData="7500">
@ -9,6 +9,7 @@
</children>
</children>
<children xsi:type="basic:Part" xmi:id="__VNlAIytEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.dialog.aboutscviewer" toBeRendered="false" visible="false" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.AboutDialog" label="About SCViewer" bindingContexts="_95Pfu3NmEeWBq8z1Dv39LA"/>
<children xsi:type="basic:Part" xmi:id="_hXh-kEYFEeyPM8G0E2EYww" elementId="com.minres.scviewer.e4.application.dialog.onlinehelp" toBeRendered="false" visible="false" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.HelpDialog" label="SCViewer Online Help" bindingContexts="_95Pfu3NmEeWBq8z1Dv39LA" closeable="true"/>
<mainMenu xmi:id="_95PfyXNmEeWBq8z1Dv39LA" elementId="menu:org.eclipse.ui.main.menu">
<children xsi:type="menu:Menu" xmi:id="_95QGwHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.menu.file" label="File">
<children xsi:type="menu:HandledMenuItem" xmi:id="_igsK0BkREeudD5MqrWoETQ" elementId="" label="Open Database" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/folder_database.png" mnemonics="M1+O" command="_95PfwHNmEeWBq8z1Dv39LA"/>
@ -55,7 +56,8 @@
</children>
<children xsi:type="menu:Menu" xmi:id="_95QGxHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.menu.help" label="Help">
<children xsi:type="menu:HandledMenuItem" xmi:id="_UQRi0B07EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handledmenuitem.checkforupdate" visible="false" label="Check for Update" enabled="false" command="_-9ED4B06EeuiP60JNw0iiA"/>
<children xsi:type="menu:HandledMenuItem" xmi:id="_95QGxXNmEeWBq8z1Dv39LA" label="About" command="_95PfxnNmEeWBq8z1Dv39LA"/>
<children xsi:type="menu:HandledMenuItem" xmi:id="_95QGxXNmEeWBq8z1Dv39LA" label="Online Help" command="_lqjIYEYEEeyPM8G0E2EYww"/>
<children xsi:type="menu:HandledMenuItem" xmi:id="_4xtmgEYEEeyPM8G0E2EYww" label="About" command="_95PfxnNmEeWBq8z1Dv39LA"/>
</children>
</mainMenu>
<trimBars xmi:id="_95QGy3NmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.main.toolbar">
@ -100,19 +102,25 @@
</children>
</children>
<children xsi:type="menu:ToolBar" xmi:id="_oQdMUHcqEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbar.1">
<children xsi:type="menu:HandledToolItem" xmi:id="_5DrGQHf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfit" label="Zoom out" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magnifier.png" tooltip="Restore default zoom level" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_5DrGQXf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.14" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="fit"/>
<children xsi:type="menu:HandledToolItem" xmi:id="_LFGfsEZEEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfull" label="Zoom full" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_full.png" tooltip="Zoom full range" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_LFGfsUZEEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.parameter.full" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="full"/>
</children>
<children xsi:type="menu:HandledToolItem" xmi:id="_5DrGQHf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfit" label="Zoom fit" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_fit.png" tooltip="Zoom between cursor and marker" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_5DrGQXf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.fit" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="fit"/>
</children>
<children xsi:type="menu:ToolBarSeparator" xmi:id="_p1AvUHcqEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbarseparator.1"/>
<children xsi:type="menu:HandledToolItem" xmi:id="_XMQPAHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomin" label="Zoom in" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magnifier_zoom_in.png" tooltip="Zoom in by a factor of 3" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_fi5w4HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.15" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/>
<parameters xmi:id="_fi5w4HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.in" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/>
</children>
<children xsi:type="menu:HandledToolItem" xmi:id="_XqTc8HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomout" label="Zoom out" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magifier_zoom_out.png" tooltip="Zoom out by a factor of 3" command="_693GoHcqEeWwZ-9vrAR2UQ">
<parameters xmi:id="_d7OBYHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.14" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/>
<parameters xmi:id="_d7OBYHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.out" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/>
</children>
</children>
<children xsi:type="menu:ToolBar" xmi:id="_fwn8wGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.toolbar.2">
<children xsi:type="menu:HandledToolItem" xmi:id="_j-XIgGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handledtoolitem.hover" label="Hover" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/lightbulb.png" tooltip="Enable hover window in waveform" selected="true" type="Check" command="_uyeyYGtTEeqmlpoaaMHoiw">
<children xsi:type="menu:HandledToolItem" xmi:id="_j-XIgGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handledtoolitem.txdetails" label="TX Details" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/application_side_expand.png" tooltip="Show tx details parts" selected="true" type="Check" command="_Fj1gQEYoEeyKK_icsY7Xjg">
<tags>EnableTxDetails</tags>
</children>
<children xsi:type="menu:HandledToolItem" xmi:id="_33tugEYnEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handledtoolitem.hover" label="Hover" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/lightbulb.png" tooltip="Enable hover window in waveform" selected="true" type="Check" command="_uyeyYGtTEeqmlpoaaMHoiw">
<tags>EnableHover</tags>
</children>
</children>
@ -126,6 +134,9 @@
</children>
</trimBars>
</children>
<children xsi:type="basic:Window" xmi:id="_Gm0qAEamEeyPDuc8x6Ggxw" elementId="com.minres.scviewer.e4.application.window.help" toBeRendered="false" selectedElement="_M5eT0EamEeyPDuc8x6Ggxw" label="SC Viewer Help" width="800" height="600">
<children xsi:type="basic:Part" xmi:id="_M5eT0EamEeyPDuc8x6Ggxw" elementId="com.minres.scviewer.e4.application.part.container" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.help.HelpBrowser"/>
</children>
<handlers xmi:id="_95PfvXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.quitCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.QuitHandler" command="_95PfvHNmEeWBq8z1Dv39LA"/>
<handlers xmi:id="_95PfwXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.openCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.OpenHandler" command="_95PfwHNmEeWBq8z1Dv39LA"/>
<handlers xmi:id="_95PfxHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.saveCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SaveHandler" command="_95Pfw3NmEeWBq8z1Dv39LA"/>
@ -135,10 +146,12 @@
<handlers xmi:id="_UUnX8IoNEeWxJ_wPkM6yGQ" elementId="com.minres.scviewer.e4.application.handler.set_them" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ThemeSetHandler" command="_KlGlsIoNEeWxJ_wPkM6yGQ"/>
<handlers xmi:id="_V4EscIuGEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.handler.setreleationtype" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SetRelationTypeHandler" command="_E9lUgIt2EeWid7xO48ZBXw"/>
<handlers xmi:id="__99WoJebEeW09eyIbHsdvg" elementId="com.minres.scviewer.e4.application.handler.loadStoreSettings" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.LoadStoreSettingsHandler" command="_7-AIMJebEeW09eyIbHsdvg"/>
<handlers xmi:id="_x4pSEGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handler.0" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableHover" command="_uyeyYGtTEeqmlpoaaMHoiw"/>
<handlers xmi:id="_x4pSEGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handler.enablehover" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableHover" command="_uyeyYGtTEeqmlpoaaMHoiw"/>
<handlers xmi:id="_h3jU8BkWEeudD5MqrWoETQ" elementId="com.minres.scviewer.e4.application.handler.reloadCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ReloadHandler" command="_srACsBkREeudD5MqrWoETQ"/>
<handlers xmi:id="_gn_boBlEEeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handler.txSearch" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SearchHandler" command="_XDxTYBlEEeuiP60JNw0iiA"/>
<handlers xmi:id="_CCEtAB07EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handler.update" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.UpdateHandler" command="_-9ED4B06EeuiP60JNw0iiA"/>
<handlers xmi:id="_ru2NIEYEEeyPM8G0E2EYww" elementId="com.minres.scviewer.e4.application.handler.helpCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.HelpHandler" command="_lqjIYEYEEeyPM8G0E2EYww"/>
<handlers xmi:id="_TwU0IEYoEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handler.enabletxdetails" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableTxDetails" command="_Fj1gQEYoEeyKK_icsY7Xjg"/>
<bindingTables xmi:id="_95PfvnNmEeWBq8z1Dv39LA" bindingContext="_95PfuXNmEeWBq8z1Dv39LA">
<bindings xmi:id="_95Pfv3NmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.keybinding.quit" keySequence="M1+Q" command="_95PfvHNmEeWBq8z1Dv39LA">
<tags>type:user</tags>
@ -280,6 +293,8 @@
<commands xmi:id="_srACsBkREeudD5MqrWoETQ" elementId="com.minres.scviewer.e4.application.reload" commandName="Reload Command"/>
<commands xmi:id="_XDxTYBlEEeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.txSearch" commandName="Search Command"/>
<commands xmi:id="_-9ED4B06EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.command.update" commandName="Update"/>
<commands xmi:id="_lqjIYEYEEeyPM8G0E2EYww" elementId="org.eclipse.ui.help.helpAction" commandName="Help Command"/>
<commands xmi:id="_Fj1gQEYoEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.command.enabletxdetails" commandName="Enable Tx Details" description="Show tx details parts"/>
<addons xmi:id="_95PfsnNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
<addons xmi:id="_95Pfs3NmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
<addons xmi:id="_95PftHNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>

View File

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: com.minres.scviewer.e4.application;singleton:=true
Bundle-Version: 2.11.2.qualifier
Bundle-Version: 2.14.1
Bundle-Vendor: %Bundle-Vendor
Require-Bundle: javax.inject;bundle-version="1.0.0",
org.eclipse.core.runtime;bundle-version="3.11.1",
@ -35,8 +35,10 @@ Require-Bundle: javax.inject;bundle-version="1.0.0",
org.eclipse.equinox.p2.core;bundle-version="2.6.300",
org.eclipse.equinox.p2.engine;bundle-version="2.6.600",
org.eclipse.equinox.p2.operations;bundle-version="2.5.700",
org.eclipse.equinox.p2.metadata.repository;bundle-version="1.3.400"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
org.eclipse.equinox.p2.metadata.repository;bundle-version="1.3.400",
org.eclipse.help.base;bundle-version="4.2.900"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Import-Package: com.minres.scviewer.database,
javax.annotation;version="1.0.0";resolution:=optional,
javax.inject;version="1.0.0"
Automatic-Module-Name: com.minres.scviewer.e4.application

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -3,12 +3,11 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.e4.application</artifactId>
<version>2.11.2-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.11.2-SNAPSHOT</version>
<relativePath>../..</relativePath>
<version>2.14.1</version>
<relativePath>../../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
</project>
</project>

View File

@ -61,6 +61,8 @@ public class E4LifeCycle {
final Options opt = new Options(args, 0, Integer.MAX_VALUE);
opt.getSet()
.addOption("clearPersistedState", Multiplicity.ZERO_OR_ONE)
.addOption("launcher.defaultAction", Separator.BLANK, Multiplicity.ZERO_OR_ONE)
.addOption("launcher.openFile", Multiplicity.ZERO_OR_ONE)
.addOption("c", Separator.BLANK, Multiplicity.ZERO_OR_ONE);
if (!opt.check(Options.DEFAULT_SET, true, false)) {
logger.error(opt.getCheckErrors());

View File

@ -24,6 +24,7 @@ public class Messages extends NLS {
public static String SCViewerPreferencesPage_0;
public static String SCViewerPreferencesPage_1;
public static String SCViewerPreferencesPage_2;
public static String SCViewerPreferencesPage_3;
public static String StatusBarControl_1;
public static String StatusBarControl_2;
public static String StatusBarControl_3;
@ -82,6 +83,16 @@ public class Messages extends NLS {
public static String cursor;
public static String cursor_drag;
public static String cursor_text;
public static String HelpBrowser_7;
public static String HelpBrowser_8;
public static String HelpDialog_0;
public static String HelpDialog_1;
public static String HelpDialog_2;
public static String HelpDialog_3;
public static String HelpDialog_4;
public static String HelpDialog_5;
public static String HelpDialog_6;
public static String HelpDialog_7;
public static String marker;
public static String marker_text;
public static String rel_arrow;

View File

@ -40,7 +40,7 @@ public class WaveformPopupMenuContribution {
if(elem instanceof TrackEntry) {
TrackEntry e = (TrackEntry) elem;
if(e.waveform.getType() == WaveformType.SIGNAL) {
Object o = e.waveform.getEvents().firstEntry().getValue()[0];
Object o = e.waveform.getEvents().firstEntry().events[0];
if(checkForDouble && o instanceof DoubleVal)
return true;
else if(o instanceof BitVector && ((BitVector)o).getWidth()>1)

View File

@ -0,0 +1,57 @@
package com.minres.scviewer.e4.application.handlers;
import java.util.LinkedList;
import java.util.List;
import javax.inject.Inject;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.di.extensions.Preference;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.osgi.service.prefs.BackingStoreException;
import com.minres.scviewer.e4.application.preferences.PreferenceConstants;
@SuppressWarnings("restriction")
public class EnableTxDetails {
static final String TAG_NAME = "EnableTxDetails"; //$NON-NLS-1$
static final String ICON_DISABLED = "platform:/plugin/com.minres.scviewer.e4.application/icons/application_side_expand.png"; //$NON-NLS-1$
static final String ICON_ENABLED = "platform:/plugin/com.minres.scviewer.e4.application/icons/application_side_contract.png"; //$NON-NLS-1$
static final String TOOLTIP_DISABLED = "Show tx details parts";
static final String TOOLTIP_ENABLED = "Hide tx details parts";
@Inject
MApplication application;
@Inject
EPartService partService;
@Inject
@Optional
public void reactOnShowHoverChange(EModelService modelService, @Preference(value = PreferenceConstants.SHOW_TX_DETAILS) Boolean show) {
List<String> tags = new LinkedList<>();
tags.add(TAG_NAME);
List<MHandledItem> elements = modelService.findElements(application, null, MHandledItem.class, tags );
for( MHandledItem hi : elements ){
hi.setSelected(show);
hi.setIconURI(show?ICON_ENABLED:ICON_DISABLED);
hi.setTooltip(show?TOOLTIP_ENABLED:TOOLTIP_DISABLED);
}
}
@Execute
public void execute(MHandledItem handledItem, @Preference(nodePath = PreferenceConstants.PREFERENCES_SCOPE) IEclipsePreferences prefs ) {
try {
prefs.putBoolean(PreferenceConstants.SHOW_TX_DETAILS, handledItem.isSelected());
prefs.flush();
} catch (BackingStoreException e) {}
}
}

View File

@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright (c) 2015-2021 MINRES Technologies GmbH and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* MINRES Technologies GmbH - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.e4.application.handlers;
import java.io.File;
import java.net.URL;
import java.nio.file.Paths;
import org.eclipse.core.runtime.Platform;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
import org.eclipse.help.HelpSystem;
import org.eclipse.help.IHelp;
import org.eclipse.help.standalone.Help;
import org.eclipse.osgi.service.datalocation.Location;
public class HelpHandler {
static final String DIALOG_ID="com.minres.scviewer.e4.application.dialog.onlinehelp"; //$NON-NLS-1$
static final String WINDOW_ID="com.minres.scviewer.e4.application.window.help"; //$NON-NLS-1$
@Execute
public void execute(MApplication app, /*MWindow window,*/ EModelService ms /*@Named("mdialog01.dialog.0") MDialog dialog*/) {
// MPart mel = (MPart) ms.find(DIALOG_ID, app); //$NON-NLS-1$
// mel.setToBeRendered(true);
// mel.setToBeRendered(false);
try {
File installDir = Paths.get(Platform.getInstallLocation().getURL().toURI()).toFile();
File instanceDir = Paths.get(Platform.getInstanceLocation().getURL().toURI()).toFile();
Help helpSystem = new Help(new String[] {"-eclipseHome", installDir.getAbsolutePath(), "-data", instanceDir.getAbsolutePath()});
helpSystem.start();
helpSystem.displayHelp("/com.minres.scviewer.help/toc.xml");
} catch (Exception e) {
MUIElement w = ms.find(WINDOW_ID, app);
if(w!=null) w.setToBeRendered(true);
}
}
}

View File

@ -42,6 +42,8 @@ public class ZoomHandler {
waveformViewerPart.setZoomLevel(zoomLevel+1);
else if("fit".equalsIgnoreCase(level)) //$NON-NLS-1$
waveformViewerPart.setZoomFit();
else if("full".equalsIgnoreCase(level)) //$NON-NLS-1$
waveformViewerPart.setZoomFull();
}
}

View File

@ -482,6 +482,7 @@ public class HeapStatus extends Composite {
});
}
};
t.setDaemon(true);
t.start();
}

View File

@ -9,7 +9,7 @@ DesignBrowser_8=Insert before
LoadingWaveformDb_0=Database loading...
LoadStoreSettingsHandler_2=*.scview
LoadStoreSettingsHandler_3=SCViewer.scview
OpenHandler_0=*.vcd;*.txdb;*.txlog;*.fbrdb
OpenHandler_0=*.vcd;*.vcd.gz;*.txlog;*.txlog.gz;*.txdb;*.fbrdb
QuitHandler_0=Confirmation
QuitHandler_1=Do you want to exit?
RelationTypeToolControl_0=------------
@ -18,6 +18,7 @@ ResourceManager_0=Wrong decorate corner
SCViewerPreferencesPage_0=Check for changed database
SCViewerPreferencesPage_1=Show hover window in waveform
SCViewerPreferencesPage_2=Waveform track height
SCViewerPreferencesPage_3=Show tx details in waveform
StatusBarControl_1=Currently running:
StatusBarControl_2=\nLast task:
StatusBarControl_3=Currently running:
@ -76,6 +77,16 @@ signal_nan=Signal NaN Value
cursor=Cursor
cursor_drag=dragged Cursor
cursor_text=Cursor Text
HelpBrowser_7=Error initializing help browser
HelpBrowser_8=An error occurred while initializing the help browser:
HelpDialog_0=Back
HelpDialog_1=Forward
HelpDialog_2=Stop
HelpDialog_3=Refresh
HelpDialog_4=Go
HelpDialog_5=Address
HelpDialog_6=https://git.minres.com/VP-Tools/SCViewer/src/branch/master/README.md\#key-shortcuts
HelpDialog_7=Could not instantiate Browser:
marker=Marker
marker_text=Marker TExt
rel_arrow=Relation arrow

View File

@ -131,7 +131,9 @@ public class AboutDialog extends Dialog {
if (style != null && style.underline && style.underlineStyle == SWT.UNDERLINE_LINK) {
Desktop.getDesktop().browse(new java.net.URI(style.data.toString()));
}
} catch (IOException | URISyntaxException | IllegalArgumentException e) {}
} catch (IOException | URISyntaxException | IllegalArgumentException e) {
} catch (UnsupportedOperationException e) {
}
});
styleRange.start = 0;

View File

@ -133,10 +133,11 @@ public class DesignBrowser {
treeViewer.refresh();
});
} else if(IHierNode.LOADING_FINISHED.equals(evt.getPropertyName())) {
treeViewer.getTree().getDisplay().asyncExec(() -> {
treeViewer.update(waveformViewerPart.getDatabase(), null);
DesignBrowser.this.updateButtons();
});
if(!treeViewer.getControl().isDisposed())
treeViewer.getTree().getDisplay().asyncExec(() -> {
treeViewer.update(waveformViewerPart.getDatabase(), null);
DesignBrowser.this.updateButtons();
});
}
};
@ -206,7 +207,7 @@ public class DesignBrowser {
updateButtons();
}
});
treeViewer.setLabelProvider(new TxDbLabelProvider());
treeViewer.setLabelProvider(new TxDbLabelProvider(true));
treeViewer.addFilter(treeAttributeFilter);
treeViewer.setUseHashlookup(true);
treeViewer.setAutoExpandLevel(2);
@ -252,7 +253,7 @@ public class DesignBrowser {
updateButtons();
}
});
txTableViewer.setLabelProvider(new TxDbLabelProvider());
txTableViewer.setLabelProvider(new TxDbLabelProvider(false));
txTableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
txTableViewer.addFilter(tableAttributeFilter);
txTableViewer.addDoubleClickListener(event -> {
@ -596,6 +597,7 @@ public class DesignBrowser {
* Apply.
*/
public void apply() {
if(treeViewer.getControl().isDisposed()) return;
treeViewer.setExpandedElements(expandedElements);
treeViewer.setSelection(treeSelection, true);
txTableViewer.setSelection(tableSelection, true);

View File

@ -3,6 +3,7 @@ package com.minres.scviewer.e4.application.parts;
import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.PathMatcher;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -229,6 +230,14 @@ public class FileBrowserDialog extends TrayDialog {
colSize.getColumn().setText("Size");
colSize.getColumn().addSelectionListener(getSelectionAdapter(colSize.getColumn(), 1));
TableViewerColumn colDate = new TableViewerColumn(tableViewer, SWT.RIGHT);
colDate.setLabelProvider(new FileTableLabelProvider() {
@Override public String getText(Object element) { return DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM).format(((File) element).lastModified()); }
});
colDate.getColumn().setWidth(200);
colDate.getColumn().setText("Modification Date");
colDate.getColumn().addSelectionListener(getSelectionAdapter(colDate.getColumn(), 2));
TableViewerColumn colEmpty = new TableViewerColumn(tableViewer, SWT.CENTER);
colEmpty.setLabelProvider(new FileTableLabelProvider() {
@Override public String getText(Object element) { return ""; }
@ -264,7 +273,7 @@ public class FileBrowserDialog extends TrayDialog {
tableViewer.setInput(selectedDir.listFiles());
}
});
sashForm.setWeights(new int[]{3, 3});
sashForm.setWeights(new int[]{2, 3});
return area;
}
@ -337,7 +346,11 @@ public class FileBrowserDialog extends TrayDialog {
if(f instanceof File) {
if(matchers.isEmpty()) return true;
for (PathMatcher m : matchers) {
try {
if(m.matches(((File)f).toPath())) return true;
} catch (Exception e) {
return false;
}
}
}
return false;
@ -441,6 +454,9 @@ public class FileBrowserDialog extends TrayDialog {
case 1:
rc = Long.valueOf(p1.length()).compareTo(p2.length());
break;
case 2:
rc = Long.valueOf(p1.lastModified()).compareTo(p2.lastModified());
break;
default:
rc = 0;
}

View File

@ -0,0 +1,177 @@
package com.minres.scviewer.e4.application.parts;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import com.minres.scviewer.e4.application.Messages;
public class HelpDialog extends Dialog {
/**
* Create the dialog.
*
* @param parentShell the parent shell
*/
@Inject
public HelpDialog(Shell parentShell) {
super(parentShell);
setShellStyle(getShellStyle() | SWT.MODELESS | SWT.MAX | SWT.BORDER | SWT.TITLE);
setBlockOnOpen(false);
}
@Override
protected boolean isResizable() {
return true;
}
@Override
protected Point getInitialSize() {
return new Point(800, 600);
}
/**
* Create contents of the dialog.
*
* @param parent the parent
* @return the control
*/
@Override
protected Control createDialogArea(Composite parent) {
Composite container = (Composite) super.createDialogArea(parent);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
container.setLayout(gridLayout);
ToolBar toolbar = new ToolBar(container, SWT.NONE);
ToolItem itemBack = new ToolItem(toolbar, SWT.PUSH);
itemBack.setText(Messages.HelpDialog_0);
ToolItem itemForward = new ToolItem(toolbar, SWT.PUSH);
itemForward.setText(Messages.HelpDialog_1);
ToolItem itemStop = new ToolItem(toolbar, SWT.PUSH);
itemStop.setText(Messages.HelpDialog_2);
ToolItem itemRefresh = new ToolItem(toolbar, SWT.PUSH);
itemRefresh.setText(Messages.HelpDialog_3);
ToolItem itemGo = new ToolItem(toolbar, SWT.PUSH);
itemGo.setText(Messages.HelpDialog_4);
GridData data = new GridData();
data.horizontalSpan = 3;
toolbar.setLayoutData(data);
Label labelAddress = new Label(container, SWT.NONE);
labelAddress.setText(Messages.HelpDialog_5);
final Text location = new Text(container, SWT.BORDER);
data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.horizontalSpan = 2;
data.grabExcessHorizontalSpace = true;
location.setLayoutData(data);
final Browser browser;
try {
browser = new Browser(container, SWT.NONE);
data = new GridData();
// data.widthHint = 800;
// data.heightHint =600;
data.horizontalAlignment = GridData.FILL;
data.verticalAlignment = GridData.FILL;
data.horizontalSpan = 3;
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
browser.setLayoutData(data);
final Label status = new Label(container, SWT.NONE);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
status.setLayoutData(data);
final ProgressBar progressBar = new ProgressBar(container, SWT.NONE);
data = new GridData();
data.horizontalAlignment = GridData.END;
progressBar.setLayoutData(data);
/* event handling */
Listener listener = event -> {
ToolItem item = (ToolItem) event.widget;
String string = item.getText();
if (string.equals(Messages.HelpDialog_0))
browser.back();
else if (string.equals(Messages.HelpDialog_1))
browser.forward();
else if (string.equals(Messages.HelpDialog_2))
browser.stop();
else if (string.equals(Messages.HelpDialog_3))
browser.refresh();
else if (string.equals(Messages.HelpDialog_4))
browser.setUrl(location.getText());
};
browser.addProgressListener(new ProgressListener() {
@Override
public void changed(ProgressEvent event) {
if (event.total == 0) return;
int ratio = event.current * 100 / event.total;
progressBar.setSelection(ratio);
}
@Override
public void completed(ProgressEvent event) {
progressBar.setSelection(0);
}
});
browser.addStatusTextListener(event -> status.setText(event.text));
browser.addLocationListener(LocationListener.changedAdapter(event -> {
if (event.top) location.setText(event.location);
}
));
itemBack.addListener(SWT.Selection, listener);
itemForward.addListener(SWT.Selection, listener);
itemStop.addListener(SWT.Selection, listener);
itemRefresh.addListener(SWT.Selection, listener);
itemGo.addListener(SWT.Selection, listener);
location.addListener(SWT.DefaultSelection, e -> browser.setUrl(location.getText()));
browser.setUrl(Messages.HelpDialog_6);
} catch (SWTError e) {
System.out.println(Messages.HelpDialog_7 + e.getMessage());
}
return container;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
*/
@Override
protected void createButtonsForButtonBar(Composite parent) {
// create OK button
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.CLOSE_LABEL, true);
}
/**
* Open the dialog.
* @return the result
*/
@PostConstruct
@Override
public int open() {
return super.open();
}
}

Some files were not shown because too many files have changed in this diff Show More