Compare commits
129 Commits
Author | SHA1 | Date | |
---|---|---|---|
6bf642d2af | |||
15c24f0925 | |||
4d4a6579c6 | |||
b648dccfd8 | |||
f9425834a3 | |||
e0d00e6402 | |||
b1b7517759 | |||
a5b9c28007 | |||
b5e408595b | |||
f15930682e | |||
f8765518bc | |||
73e952faea | |||
111383bcba | |||
244f005ae6 | |||
701733e69d | |||
6b4a9c1e14 | |||
3abbc3e0e2 | |||
2a7b713ef2 | |||
593571ce10 | |||
979261432a | |||
e25f56a8a9 | |||
e8788e6ce0 | |||
8a8691a889 | |||
de15b84bef | |||
b78d8bea45 | |||
a49842a119 | |||
dbe5d603ed | |||
cde1835c74 | |||
b332eca891 | |||
75efd69b77 | |||
960610bab2 | |||
98029f8c7a | |||
9c09cf5f40 | |||
113d65cfc4 | |||
22e7bb04f0 | |||
d8c5b7d9c3 | |||
2e7ae5309f | |||
f81e830e93 | |||
47a285bf6d | |||
c080773878 | |||
bcf4e1a274 | |||
93fd192782 | |||
e687eef42c | |||
2a709113fe | |||
8d7acdb9cb | |||
77684d828c | |||
9f902057ba | |||
42660c7a2e | |||
97a806f9d9 | |||
60185fbaee | |||
5411a405d4 | |||
694dad1cf5 | |||
5fb9a7dcdf | |||
3faa7205ae | |||
3cbe5d56d9 | |||
5745ab4f2c | |||
4a17108ccc | |||
408138c27c | |||
3211db8743 | |||
0c81988d8c | |||
0107c423a3 | |||
5d41816eb6 | |||
e41b7e25ed | |||
dba8b2731d | |||
048fa93b53 | |||
6cc5597c25 | |||
694423be3b | |||
0634b9cfd5 | |||
c4b16338a8 | |||
bda2a84532 | |||
9d4c951e7f | |||
8a89b21d34 | |||
e02df858fa | |||
0fbe22e2e0 | |||
021c2bceff | |||
9862c14040 | |||
23131e7527 | |||
0833bca1bd | |||
1cf00ec882 | |||
6c0bbd5f1f | |||
f13b091664 | |||
dff41eceb2 | |||
d267e64907 | |||
792dcd55f3 | |||
2b33ea0c85 | |||
f69a6f2e89 | |||
0f133a3df6 | |||
549c522bf7 | |||
2f11d8ed7b | |||
7dd0a24df6 | |||
a052fe2324 | |||
4fc24453ae | |||
b468fba441 | |||
f80021059e | |||
7c0822b4d2 | |||
cdde384ed3 | |||
fce1bdb1e7 | |||
b68a7d3259 | |||
44b13c105d | |||
ed0558afdf | |||
d0be3b0ca2 | |||
a052c6aa3b | |||
8a30ba8dea | |||
0a7972c54d | |||
b1890eb5e1 | |||
1aaf5c837e | |||
c8a213e985 | |||
5f82700290 | |||
40a0137dfd | |||
4ec9a928b9 | |||
c82c41bbf0 | |||
79c49e6f1d | |||
96d628d322 | |||
b4d81d96b8 | |||
08fdc18290 | |||
5c784af74f | |||
ff4cb91aed | |||
31ed3e4858 | |||
0007ab9322 | |||
f723a770c7 | |||
af1b3d00dc | |||
316647031a | |||
929cf21ff8 | |||
6ff48cac7a | |||
b083094cc8 | |||
8180a0e5d7 | |||
5a39bab52e | |||
02ba74ae16 | |||
c02f8a6520 |
5
.gitignore
vendored
5
.gitignore
vendored
@ -3,3 +3,8 @@
|
||||
/.recommenders/
|
||||
/RemoteSystemsTempFiles/
|
||||
/*.zip
|
||||
SCViewer initiator_target.launch
|
||||
SCViewer.xcf
|
||||
SCViewer_1.png
|
||||
*.launch
|
||||
copyrightLog.txt
|
||||
|
203
LICENSE
Normal file
203
LICENSE
Normal file
@ -0,0 +1,203 @@
|
||||
Eclipse Public License - v 1.0
|
||||
|
||||
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
|
||||
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
|
||||
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
|
||||
|
||||
1. DEFINITIONS
|
||||
|
||||
"Contribution" means:
|
||||
|
||||
a) in the case of the initial Contributor, the initial code and documentation
|
||||
distributed under this Agreement, and
|
||||
b) in the case of each subsequent Contributor:
|
||||
i) changes to the Program, and
|
||||
ii) additions to the Program;
|
||||
|
||||
where such changes and/or additions to the Program originate from and are
|
||||
distributed by that particular Contributor. A Contribution 'originates'
|
||||
from a Contributor if it was added to the Program by such Contributor
|
||||
itself or anyone acting on such Contributor's behalf. Contributions do not
|
||||
include additions to the Program which: (i) are separate modules of
|
||||
software distributed in conjunction with the Program under their own
|
||||
license agreement, and (ii) are not derivative works of the Program.
|
||||
|
||||
"Contributor" means any person or entity that distributes the Program.
|
||||
|
||||
"Licensed Patents" mean patent claims licensable by a Contributor which are
|
||||
necessarily infringed by the use or sale of its Contribution alone or when
|
||||
combined with the Program.
|
||||
|
||||
"Program" means the Contributions distributed in accordance with this
|
||||
Agreement.
|
||||
|
||||
"Recipient" means anyone who receives the Program under this Agreement,
|
||||
including all Contributors.
|
||||
|
||||
2. GRANT OF RIGHTS
|
||||
a) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide, royalty-free copyright license to
|
||||
reproduce, prepare derivative works of, publicly display, publicly
|
||||
perform, distribute and sublicense the Contribution of such Contributor,
|
||||
if any, and such derivative works, in source code and object code form.
|
||||
b) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide, royalty-free patent license under
|
||||
Licensed Patents to make, use, sell, offer to sell, import and otherwise
|
||||
transfer the Contribution of such Contributor, if any, in source code and
|
||||
object code form. This patent license shall apply to the combination of
|
||||
the Contribution and the Program if, at the time the Contribution is
|
||||
added by the Contributor, such addition of the Contribution causes such
|
||||
combination to be covered by the Licensed Patents. The patent license
|
||||
shall not apply to any other combinations which include the Contribution.
|
||||
No hardware per se is licensed hereunder.
|
||||
c) Recipient understands that although each Contributor grants the licenses
|
||||
to its Contributions set forth herein, no assurances are provided by any
|
||||
Contributor that the Program does not infringe the patent or other
|
||||
intellectual property rights of any other entity. Each Contributor
|
||||
disclaims any liability to Recipient for claims brought by any other
|
||||
entity based on infringement of intellectual property rights or
|
||||
otherwise. As a condition to exercising the rights and licenses granted
|
||||
hereunder, each Recipient hereby assumes sole responsibility to secure
|
||||
any other intellectual property rights needed, if any. For example, if a
|
||||
third party patent license is required to allow Recipient to distribute
|
||||
the Program, it is Recipient's responsibility to acquire that license
|
||||
before distributing the Program.
|
||||
d) Each Contributor represents that to its knowledge it has sufficient
|
||||
copyright rights in its Contribution, if any, to grant the copyright
|
||||
license set forth in this Agreement.
|
||||
|
||||
3. REQUIREMENTS
|
||||
|
||||
A Contributor may choose to distribute the Program in object code form under
|
||||
its own license agreement, provided that:
|
||||
|
||||
a) it complies with the terms and conditions of this Agreement; and
|
||||
b) its license agreement:
|
||||
i) effectively disclaims on behalf of all Contributors all warranties
|
||||
and conditions, express and implied, including warranties or
|
||||
conditions of title and non-infringement, and implied warranties or
|
||||
conditions of merchantability and fitness for a particular purpose;
|
||||
ii) effectively excludes on behalf of all Contributors all liability for
|
||||
damages, including direct, indirect, special, incidental and
|
||||
consequential damages, such as lost profits;
|
||||
iii) states that any provisions which differ from this Agreement are
|
||||
offered by that Contributor alone and not by any other party; and
|
||||
iv) states that source code for the Program is available from such
|
||||
Contributor, and informs licensees how to obtain it in a reasonable
|
||||
manner on or through a medium customarily used for software exchange.
|
||||
|
||||
When the Program is made available in source code form:
|
||||
|
||||
a) it must be made available under this Agreement; and
|
||||
b) a copy of this Agreement must be included with each copy of the Program.
|
||||
Contributors may not remove or alter any copyright notices contained
|
||||
within the Program.
|
||||
|
||||
Each Contributor must identify itself as the originator of its Contribution,
|
||||
if
|
||||
any, in a manner that reasonably allows subsequent Recipients to identify the
|
||||
originator of the Contribution.
|
||||
|
||||
4. COMMERCIAL DISTRIBUTION
|
||||
|
||||
Commercial distributors of software may accept certain responsibilities with
|
||||
respect to end users, business partners and the like. While this license is
|
||||
intended to facilitate the commercial use of the Program, the Contributor who
|
||||
includes the Program in a commercial product offering should do so in a manner
|
||||
which does not create potential liability for other Contributors. Therefore,
|
||||
if a Contributor includes the Program in a commercial product offering, such
|
||||
Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
|
||||
every other Contributor ("Indemnified Contributor") against any losses,
|
||||
damages and costs (collectively "Losses") arising from claims, lawsuits and
|
||||
other legal actions brought by a third party against the Indemnified
|
||||
Contributor to the extent caused by the acts or omissions of such Commercial
|
||||
Contributor in connection with its distribution of the Program in a commercial
|
||||
product offering. The obligations in this section do not apply to any claims
|
||||
or Losses relating to any actual or alleged intellectual property
|
||||
infringement. In order to qualify, an Indemnified Contributor must:
|
||||
a) promptly notify the Commercial Contributor in writing of such claim, and
|
||||
b) allow the Commercial Contributor to control, and cooperate with the
|
||||
Commercial Contributor in, the defense and any related settlement
|
||||
negotiations. The Indemnified Contributor may participate in any such claim at
|
||||
its own expense.
|
||||
|
||||
For example, a Contributor might include the Program in a commercial product
|
||||
offering, Product X. That Contributor is then a Commercial Contributor. If
|
||||
that Commercial Contributor then makes performance claims, or offers
|
||||
warranties related to Product X, those performance claims and warranties are
|
||||
such Commercial Contributor's responsibility alone. Under this section, the
|
||||
Commercial Contributor would have to defend claims against the other
|
||||
Contributors related to those performance claims and warranties, and if a
|
||||
court requires any other Contributor to pay any damages as a result, the
|
||||
Commercial Contributor must pay those damages.
|
||||
|
||||
5. NO WARRANTY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
|
||||
IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
|
||||
Recipient is solely responsible for determining the appropriateness of using
|
||||
and distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement , including but not limited to the
|
||||
risks and costs of program errors, compliance with applicable laws, damage to
|
||||
or loss of data, programs or equipment, and unavailability or interruption of
|
||||
operations.
|
||||
|
||||
6. DISCLAIMER OF LIABILITY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
|
||||
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
|
||||
LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
|
||||
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGES.
|
||||
|
||||
7. GENERAL
|
||||
|
||||
If any provision of this Agreement is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of the
|
||||
remainder of the terms of this Agreement, and without further action by the
|
||||
parties hereto, such provision shall be reformed to the minimum extent
|
||||
necessary to make such provision valid and enforceable.
|
||||
|
||||
If Recipient institutes patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
|
||||
(excluding combinations of the Program with other software or hardware)
|
||||
infringes such Recipient's patent(s), then such Recipient's rights granted
|
||||
under Section 2(b) shall terminate as of the date such litigation is filed.
|
||||
|
||||
All Recipient's rights under this Agreement shall terminate if it fails to
|
||||
comply with any of the material terms or conditions of this Agreement and does
|
||||
not cure such failure in a reasonable period of time after becoming aware of
|
||||
such noncompliance. If all Recipient's rights under this Agreement terminate,
|
||||
Recipient agrees to cease use and distribution of the Program as soon as
|
||||
reasonably practicable. However, Recipient's obligations under this Agreement
|
||||
and any licenses granted by Recipient relating to the Program shall continue
|
||||
and survive.
|
||||
|
||||
Everyone is permitted to copy and distribute copies of this Agreement, but in
|
||||
order to avoid inconsistency the Agreement is copyrighted and may only be
|
||||
modified in the following manner. The Agreement Steward reserves the right to
|
||||
publish new versions (including revisions) of this Agreement from time to
|
||||
time. No one other than the Agreement Steward has the right to modify this
|
||||
Agreement. The Eclipse Foundation is the initial Agreement Steward. The
|
||||
Eclipse Foundation may assign the responsibility to serve as the Agreement
|
||||
Steward to a suitable separate entity. Each new version of the Agreement will
|
||||
be given a distinguishing version number. The Program (including
|
||||
Contributions) may always be distributed subject to the version of the
|
||||
Agreement under which it was received. In addition, after a new version of the
|
||||
Agreement is published, Contributor may elect to distribute the Program
|
||||
(including its Contributions) under the new version. Except as expressly
|
||||
stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
|
||||
licenses to the intellectual property of any Contributor under this Agreement,
|
||||
whether expressly, by implication, estoppel or otherwise. All rights in the
|
||||
Program not expressly granted under this Agreement are reserved.
|
||||
|
||||
This Agreement is governed by the laws of the State of New York and the
|
||||
intellectual property laws of the United States of America. No party to this
|
||||
Agreement will bring a legal action under this Agreement more than one year
|
||||
after the cause of action arose. Each party waives its rights to a jury trial in
|
||||
any resulting litigation.
|
38
README.md
38
README.md
@ -6,34 +6,26 @@ created by the SystemC VCD trace implementation and the SystemC Verification Lib
|
||||
For further description of the SCV please refer to
|
||||
http://www.accellera.org/activities/committees/systemc-verification.
|
||||
|
||||
The viewer is in early alpha stage and not yet ready for production use!
|
||||
> If you encounter issue when running on Linux please try running as `SWT_GTK3=0 scviewer` as there exist issues wiht GTK3.
|
||||
|
||||
The viewer has the following features
|
||||
- support of VCD files (compressed and uncompressed)
|
||||
- real numbers
|
||||
- showing vectors and real numbers as analog (step-wise & continuous)
|
||||
- various value representations of bit vectors
|
||||
- support of SCV transaction recordings in various formats
|
||||
- text log files (compressed and uncompressed)
|
||||
- sqlite based
|
||||
- visualization of transaction relations
|
||||
|
||||
The plugins are structured as follows:
|
||||
- com.minres.scviewer.database
|
||||
the interface defining the API to access the database and the implementation for VCD
|
||||
- com.minres.scviewer.database.text
|
||||
an implementation of the API to read the text files generated by the SCV
|
||||
sc_tr_text database
|
||||
- com.minres.scviewer.database.sqlite
|
||||
an implementation of the API to read the files generated by implementation in the
|
||||
sc_tr_sqlite project using a SQLite based database
|
||||
- com.minres.scviewer.database.test
|
||||
a some JUnit tests of the 3 back ends
|
||||
- com.minres.scviewer.ui
|
||||
the viewer it self to diplay the transactions and associated views like the
|
||||
outline of the DB and the properties of the transaction
|
||||
- com.minres.scviewer.feature
|
||||
the feature combining the plugins above into a somhow usable form
|
||||
- scv_tr_sqlite
|
||||
a C++ project containing the SQLite based SCV database implementation. A simple
|
||||
example (scv_tr_recording_example.cpp) for testig purposes is provided.
|
||||
|
||||
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.
|
||||
|
||||
TODO
|
||||
====
|
||||
- refactor the graphical viewer (again)
|
||||
- add more tests
|
||||
- additional analysis means
|
||||
- move to feature based product to allow automatic updates
|
||||
- improve graphics
|
||||
- catch-up e3 plugin to functionality of e4 product
|
||||
- add calculated traces
|
||||
|
9
com.minres.scviewer.database.leveldb/.classpath
Normal file
9
com.minres.scviewer.database.leveldb/.classpath
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry exported="true" kind="lib" path="json-20180813.jar" sourcepath="json-20180813-sources.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="leveldb-0.11-SNAPSHOT-uber.jar" sourcepath="leveldb-0.11-SNAPSHOT-sources.jar"/>
|
||||
<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.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
4
com.minres.scviewer.database.leveldb/.gitignore
vendored
Normal file
4
com.minres.scviewer.database.leveldb/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/json-20180813-sources.jar
|
||||
/leveldb-0.11-SNAPSHOT-sources.jar
|
||||
/bin/
|
||||
/target/
|
33
com.minres.scviewer.database.leveldb/.project
Normal file
33
com.minres.scviewer.database.leveldb/.project
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.minres.scviewer.database.leveldb</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ds.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -0,0 +1,7 @@
|
||||
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.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
@ -0,0 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
pluginProject.equinox=false
|
||||
pluginProject.extensions=false
|
||||
resolve.requirebundle=false
|
@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
enabled=true
|
||||
path=OSGI-INF
|
||||
validationErrorLevel=error
|
||||
validationErrorLevel.missingImplicitUnbindMethod=error
|
18
com.minres.scviewer.database.leveldb/META-INF/MANIFEST.MF
Normal file
18
com.minres.scviewer.database.leveldb/META-INF/MANIFEST.MF
Normal file
@ -0,0 +1,18 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Leveldb
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.leveldb
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Import-Package: org.osgi.framework;version="1.3.0"
|
||||
Automatic-Module-Name: com.minres.scviewer.database.leveldb
|
||||
Service-Component: OSGI-INF/*.xml
|
||||
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||
org.eclipse.equinox.util;bundle-version="1.0.500",
|
||||
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
||||
org.eclipse.osgi.services;bundle-version="3.4.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: leveldb-0.11-SNAPSHOT-uber.jar,
|
||||
.,
|
||||
json-20180813.jar
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="LevelDbLoader">
|
||||
<implementation class="com.minres.scviewer.database.leveldb.LevelDBLoader"/>
|
||||
<service>
|
||||
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
|
||||
</service>
|
||||
</scr:component>
|
7
com.minres.scviewer.database.leveldb/build.properties
Normal file
7
com.minres.scviewer.database.leveldb/build.properties
Normal file
@ -0,0 +1,7 @@
|
||||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
OSGI-INF/,\
|
||||
leveldb-0.11-SNAPSHOT-uber.jar,\
|
||||
json-20180813.jar
|
BIN
com.minres.scviewer.database.leveldb/json-20180813-sources.jar
Normal file
BIN
com.minres.scviewer.database.leveldb/json-20180813-sources.jar
Normal file
Binary file not shown.
BIN
com.minres.scviewer.database.leveldb/json-20180813.jar
Normal file
BIN
com.minres.scviewer.database.leveldb/json-20180813.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
13
com.minres.scviewer.database.leveldb/pom.xml
Normal file
13
com.minres.scviewer.database.leveldb/pom.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<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.leveldb</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<relativePath>../com.minres.scviewer.parent</relativePath>
|
||||
</parent>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
@ -0,0 +1,87 @@
|
||||
package com.minres.scviewer.database.leveldb;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.iq80.leveldb.Options;
|
||||
import org.iq80.leveldb.impl.SeekingIterator;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
|
||||
public class LevelDBLoader implements IWaveformDbLoader {
|
||||
|
||||
static byte[] toByteArray(String value) {
|
||||
return value.getBytes(UTF_8);
|
||||
}
|
||||
|
||||
private TxDBWrapper levelDb;
|
||||
private IWaveformDb db;
|
||||
private Long maxTime=null;
|
||||
private List<RelationType> usedRelationsList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public boolean load(IWaveformDb db, File inp) throws Exception {
|
||||
try {
|
||||
this.db=db;
|
||||
levelDb = new TxDBWrapper(new Options(), inp);
|
||||
JSONObject configVal = new JSONObject(levelDb.get("__config"));
|
||||
if(!configVal.isEmpty())
|
||||
levelDb.setTimeResolution(configVal.getLong("resolution"));
|
||||
} catch(Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getMaxTime() {
|
||||
if(maxTime==null) {
|
||||
SeekingIterator<String, String> it = levelDb.iterator();
|
||||
it.seek("st~");
|
||||
Entry<String, String> val = null;
|
||||
while(it.hasNext()) {
|
||||
Entry<String, String> v = it.next();
|
||||
if(!v.getKey().startsWith("st~")) continue;
|
||||
val=v;
|
||||
}
|
||||
if(val==null)
|
||||
maxTime = 0L;
|
||||
else {
|
||||
String[] token = val.getKey().split("~");
|
||||
maxTime = Long.parseLong(token[2], 16)*levelDb.getTimeResolution();
|
||||
}
|
||||
}
|
||||
return maxTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IWaveform> getAllWaves() {
|
||||
List<IWaveform> streams=new ArrayList<IWaveform>();
|
||||
SeekingIterator<String, String> it = levelDb.iterator();
|
||||
it.seek("s~");
|
||||
while(it.hasNext()) {
|
||||
Entry<String, String> val = it.next();
|
||||
if(!val.getKey().startsWith("s~")) break;
|
||||
TxStream stream = new TxStream(levelDb, db, new JSONObject(val.getValue()));
|
||||
stream.setRelationTypeList(usedRelationsList);
|
||||
streams.add(stream);
|
||||
}
|
||||
return streams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<RelationType> getAllRelationTypes() {
|
||||
// return Collections.emptyList();
|
||||
return usedRelationsList;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.minres.scviewer.database.leveldb;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.iq80.leveldb.shaded.guava.collect.Maps.immutableEntry;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.iq80.leveldb.DBIterator;
|
||||
import org.iq80.leveldb.impl.SeekingIterator;
|
||||
|
||||
class StringDbIterator implements SeekingIterator<String, String> {
|
||||
private final DBIterator iterator;
|
||||
|
||||
StringDbIterator(DBIterator iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seekToFirst() {
|
||||
iterator.seekToFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(String targetKey) {
|
||||
iterator.seek(targetKey.getBytes(UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entry<String, String> peek() {
|
||||
return adapt(iterator.peekNext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entry<String, String> next() {
|
||||
return adapt(iterator.next());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private Entry<String, String> adapt(Entry<byte[], byte[]> next) {
|
||||
return immutableEntry(new String(next.getKey(), UTF_8), new String(next.getValue(), UTF_8));
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.leveldb;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.iq80.leveldb.impl.SeekingIterator;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.minres.scviewer.database.ITx;
|
||||
import com.minres.scviewer.database.ITxAttribute;
|
||||
import com.minres.scviewer.database.ITxEvent;
|
||||
import com.minres.scviewer.database.ITxGenerator;
|
||||
import com.minres.scviewer.database.ITxRelation;
|
||||
import com.minres.scviewer.database.ITxStream;
|
||||
|
||||
public class Tx implements ITx {
|
||||
|
||||
private TxDBWrapper levelDb;
|
||||
private TxStream trStream;
|
||||
private TxGenerator trGenerator;
|
||||
private long id;
|
||||
private long start_time=0;
|
||||
private long end_time=0;
|
||||
private int concurency_index;
|
||||
private boolean initialized=false;
|
||||
private List<ITxAttribute> attributes;
|
||||
private List<ITxRelation> incoming, outgoing;
|
||||
|
||||
public Tx(TxDBWrapper levelDb, TxStream trStream, TxGenerator trGenerator, long id) {
|
||||
this.levelDb=levelDb;
|
||||
this.trStream=trStream;
|
||||
this.trGenerator=trGenerator;
|
||||
this.id=id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITxStream<ITxEvent> getStream() {
|
||||
return trStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITxGenerator getGenerator() {
|
||||
return trGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConcurrencyIndex() {
|
||||
if(!initialized) loadFromDb();
|
||||
return concurency_index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getBeginTime() {
|
||||
if(!initialized) loadFromDb();
|
||||
return start_time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getEndTime() {
|
||||
loadFromDb();
|
||||
return end_time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ITxAttribute> getAttributes() {
|
||||
if(attributes==null) {
|
||||
loadFromDb();
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ITxRelation> getIncomingRelations() {
|
||||
if(incoming==null) {
|
||||
incoming = new ArrayList<ITxRelation>();
|
||||
SeekingIterator<String, String> it = levelDb.iterator();
|
||||
String key = "ri~"+String.format("%016x", id);
|
||||
it.seek(key);
|
||||
while(it.hasNext()) {
|
||||
String val = it.next().getKey();
|
||||
if(!val.startsWith(key)) break;;
|
||||
String[] token = val.split("~");
|
||||
long otherId = Long.parseLong(token[2], 16);
|
||||
incoming.add(createRelation(otherId, token[3], false));
|
||||
}
|
||||
|
||||
}
|
||||
return incoming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ITxRelation> getOutgoingRelations() {
|
||||
if(outgoing==null) {
|
||||
outgoing = new ArrayList<ITxRelation>();
|
||||
SeekingIterator<String, String> it = levelDb.iterator();
|
||||
String key="ro~"+String.format("%016x", id);
|
||||
it.seek(key);
|
||||
while(it.hasNext()) {
|
||||
String val = it.next().getKey();
|
||||
if(!val.startsWith(key)) break;
|
||||
String[] token = val.split("~");
|
||||
long otherId = Long.parseLong(token[2], 16);
|
||||
outgoing.add(createRelation(otherId, token[3], true));
|
||||
}
|
||||
|
||||
}
|
||||
return outgoing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ITx o) {
|
||||
int res = this.getBeginTime().compareTo(o.getBeginTime());
|
||||
if(res!=0)
|
||||
return res;
|
||||
else
|
||||
return this.getId().compareTo(o.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "tx#"+getId()+"["+getBeginTime()/1000000+"ns - "+getEndTime()/1000000+"ns]";
|
||||
}
|
||||
|
||||
private void loadFromDb() throws JSONException {
|
||||
JSONObject dbVal = new JSONObject(levelDb.get("x~"+ String.format("%016x", id)));
|
||||
start_time=dbVal.getLong("START_TIME") * levelDb.getTimeResolution();
|
||||
end_time=dbVal.getLong("END_TIME") * levelDb.getTimeResolution();
|
||||
concurency_index=dbVal.getInt("conc");
|
||||
attributes=new ArrayList<>();
|
||||
JSONArray arr = dbVal.getJSONArray("attr");
|
||||
arr.forEach(entry -> {
|
||||
TxAttribute attr = new TxAttribute(this, (JSONObject) entry);
|
||||
attributes.add(attr);
|
||||
});
|
||||
initialized=true;
|
||||
}
|
||||
|
||||
private ITxRelation createRelation(long otherId, String name, boolean outgoing) {
|
||||
try {
|
||||
JSONObject otherTxVal = new JSONObject(levelDb.get("x~"+ String.format("%016x", otherId)));
|
||||
if(otherTxVal.isEmpty()) return null;
|
||||
JSONObject otherStreamVal = new JSONObject(levelDb.get("s~"+ String.format("%016x", otherTxVal.getLong("s"))));
|
||||
if(otherStreamVal.isEmpty()) return null;
|
||||
TxStream tgtStream = (TxStream) trStream.getDb().getStreamByName(otherStreamVal.getString("name"));
|
||||
Tx that = (Tx) tgtStream.getTransactions().get(otherId);
|
||||
return outgoing?
|
||||
new TxRelation(trStream.getRelationType(name), this, that):
|
||||
new TxRelation(trStream.getRelationType(name), that, this);
|
||||
} catch (SecurityException | IllegalArgumentException | JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.leveldb;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.minres.scviewer.database.AssociationType;
|
||||
import com.minres.scviewer.database.DataType;
|
||||
import com.minres.scviewer.database.ITxAttribute;
|
||||
|
||||
public class TxAttribute implements ITxAttribute{
|
||||
|
||||
private String name;
|
||||
|
||||
private DataType dataType;
|
||||
|
||||
private AssociationType associationType;
|
||||
|
||||
private Object value;
|
||||
|
||||
public TxAttribute(Tx trTransaction, JSONObject attribute) {
|
||||
this.name=attribute.getString("name");
|
||||
this.dataType=DataType.values()[attribute.getInt("type")];
|
||||
this.associationType=AssociationType.values()[attribute.getInt("assoc")];
|
||||
this.value=attribute.get("value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssociationType getType() {
|
||||
return associationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.minres.scviewer.database.leveldb;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.iq80.leveldb.Options;
|
||||
import org.iq80.leveldb.Range;
|
||||
import org.iq80.leveldb.ReadOptions;
|
||||
import org.iq80.leveldb.Snapshot;
|
||||
import org.iq80.leveldb.impl.DbImpl;
|
||||
import org.iq80.leveldb.impl.SeekingIterator;
|
||||
|
||||
class TxDBWrapper {
|
||||
private final Options options;
|
||||
private final ReadOptions ro = new ReadOptions();
|
||||
private final File databaseDir;
|
||||
private DbImpl db;
|
||||
private long timeResolution=1L;;
|
||||
|
||||
TxDBWrapper(Options options, File databaseDir) throws IOException {
|
||||
this.options = options.verifyChecksums(true).createIfMissing(false).errorIfExists(false).cacheSize(64*1024*1024);
|
||||
this.databaseDir = databaseDir;
|
||||
this.db = new DbImpl(options, databaseDir);
|
||||
ro.snapshot(db.getSnapshot());
|
||||
}
|
||||
|
||||
public String get(String key) {
|
||||
byte[] slice = db.get(LevelDBLoader.toByteArray(key));
|
||||
if (slice == null) {
|
||||
return null;
|
||||
}
|
||||
return new String(slice, UTF_8);
|
||||
}
|
||||
|
||||
public String get(String key, Snapshot snapshot) {
|
||||
byte[] slice = db.get(LevelDBLoader.toByteArray(key), ro);
|
||||
return slice == null? null : new String(slice, UTF_8);
|
||||
}
|
||||
|
||||
public void put(String key, String value) {
|
||||
db.put(LevelDBLoader.toByteArray(key), LevelDBLoader.toByteArray(value));
|
||||
}
|
||||
|
||||
public void delete(String key) {
|
||||
db.delete(LevelDBLoader.toByteArray(key));
|
||||
}
|
||||
|
||||
public SeekingIterator<String, String> iterator() {
|
||||
return new StringDbIterator(db.iterator());
|
||||
}
|
||||
|
||||
public Snapshot getSnapshot() {
|
||||
return db.getSnapshot();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
ro.snapshot().close();
|
||||
db.close();
|
||||
} catch (IOException e) {} // ignore any error
|
||||
}
|
||||
|
||||
public long size(String start, String limit) {
|
||||
return db.getApproximateSizes(new Range(LevelDBLoader.toByteArray(start), LevelDBLoader.toByteArray(limit)));
|
||||
}
|
||||
|
||||
public long getMaxNextLevelOverlappingBytes() {
|
||||
return db.getMaxNextLevelOverlappingBytes();
|
||||
}
|
||||
|
||||
public void reopen() throws IOException {
|
||||
reopen(options);
|
||||
}
|
||||
|
||||
public void reopen(Options options) throws IOException {
|
||||
this.close();
|
||||
db = new DbImpl(options.verifyChecksums(true).createIfMissing(false).errorIfExists(false), databaseDir);
|
||||
ro.snapshot(db.getSnapshot());
|
||||
}
|
||||
|
||||
public long getTimeResolution() {
|
||||
return timeResolution;
|
||||
}
|
||||
|
||||
public void setTimeResolution(long resolution) {
|
||||
this.timeResolution = resolution;
|
||||
}
|
||||
}
|
@ -8,39 +8,50 @@
|
||||
* Contributors:
|
||||
* MINRES Technologies GmbH - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database;
|
||||
package com.minres.scviewer.database.leveldb;
|
||||
|
||||
public class SignalChange implements IWaveformEvent {
|
||||
|
||||
Long time;
|
||||
|
||||
|
||||
public SignalChange() {
|
||||
time=0L;
|
||||
}
|
||||
import com.minres.scviewer.database.ITx;
|
||||
import com.minres.scviewer.database.ITxEvent;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
|
||||
public SignalChange(Long time) {
|
||||
public class TxEvent implements ITxEvent {
|
||||
|
||||
private final Type type;
|
||||
private ITx tx;
|
||||
|
||||
public TxEvent(Type type, ITx tx) {
|
||||
super();
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(IWaveformEvent o) {
|
||||
return time.compareTo(o.getTime());
|
||||
this.type = type;
|
||||
this.tx = tx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Long time) {
|
||||
this.time = time;
|
||||
return type==Type.BEGIN?tx.getBeginTime():tx.getEndTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWaveformEvent duplicate() throws CloneNotSupportedException {
|
||||
return (IWaveformEvent) this.clone();
|
||||
return new TxEvent(type, tx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(IWaveformEvent o) {
|
||||
return getTime().compareTo(o.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITx getTransaction() {
|
||||
return tx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type.toString()+"@"+getTime()+" of tx #"+tx.getId();
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.leveldb;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.minres.scviewer.database.ITx;
|
||||
import com.minres.scviewer.database.ITxEvent;
|
||||
import com.minres.scviewer.database.ITxGenerator;
|
||||
import com.minres.scviewer.database.ITxStream;
|
||||
|
||||
public class TxGenerator implements ITxGenerator {
|
||||
|
||||
private ITxStream<ITxEvent> stream;
|
||||
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public TxGenerator(ITxStream<ITxEvent> stream, JSONObject object) {
|
||||
this.stream=stream;
|
||||
this.id=object.getLong("id");
|
||||
this.name=object.getString("name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITxStream<ITxEvent> getStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ITx> getTransactions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.leveldb;
|
||||
|
||||
import com.minres.scviewer.database.ITxRelation;
|
||||
import com.minres.scviewer.database.ITx;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
|
||||
public class TxRelation implements ITxRelation {
|
||||
|
||||
RelationType relationType;
|
||||
Tx source, target;
|
||||
|
||||
public TxRelation(RelationType relationType, Tx source, Tx target) {
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
this.relationType = relationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelationType getRelationType() {
|
||||
return relationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITx getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITx getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,178 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.leveldb;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.iq80.leveldb.impl.SeekingIterator;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Vector;
|
||||
|
||||
import com.minres.scviewer.database.HierNode;
|
||||
import com.minres.scviewer.database.ITx;
|
||||
import com.minres.scviewer.database.ITxEvent;
|
||||
import com.minres.scviewer.database.ITxGenerator;
|
||||
import com.minres.scviewer.database.ITxStream;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
|
||||
public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
||||
|
||||
private TxDBWrapper levelDb;
|
||||
|
||||
private String fullName;
|
||||
|
||||
private String kind;
|
||||
|
||||
private IWaveformDb db;
|
||||
|
||||
private long id;
|
||||
|
||||
private TreeMap<Long, TxGenerator> generators;
|
||||
|
||||
private TreeMap<Long, ITx> transactions;
|
||||
|
||||
private Integer maxConcurrency;
|
||||
|
||||
private TreeMap<Long, List<ITxEvent>> events;
|
||||
|
||||
private List<RelationType> usedRelationsList;
|
||||
|
||||
public TxStream(TxDBWrapper database, IWaveformDb waveformDb, JSONObject object) {
|
||||
super(object.get("name").toString());
|
||||
this.levelDb=database;
|
||||
this.db=waveformDb;
|
||||
this.fullName=object.getString("name");
|
||||
this.kind=object.getString("kind");
|
||||
this.id = object.getLong("id");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWaveformDb getDb() {
|
||||
return db;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ITxGenerator> getGenerators() {
|
||||
if(generators==null){
|
||||
generators=new TreeMap<Long, TxGenerator>();
|
||||
SeekingIterator<String, String> it = levelDb.iterator();
|
||||
String key="sg~"+String.format("%016x", id);
|
||||
it.seek(key);
|
||||
while(it.hasNext()) {
|
||||
Entry<String, String> val = it.next();
|
||||
if(!val.getKey().startsWith(key)) break;
|
||||
JSONObject jVal = new JSONObject(val.getValue());
|
||||
generators.put(jVal.getLong("id"), new TxGenerator(this, jVal));
|
||||
}
|
||||
}
|
||||
return new ArrayList<ITxGenerator>(generators.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxConcurrency() {
|
||||
if(maxConcurrency==null){
|
||||
getTransactions();
|
||||
}
|
||||
return maxConcurrency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableMap<Long, List<ITxEvent>> getEvents(){
|
||||
if(events==null){
|
||||
events=new TreeMap<Long, List<ITxEvent>>();
|
||||
for(Entry<Long, ITx> entry:getTransactions().entrySet()){
|
||||
ITx tx = entry.getValue();
|
||||
putEvent(new TxEvent(TxEvent.Type.BEGIN, tx));
|
||||
putEvent(new TxEvent(TxEvent.Type.END, tx));
|
||||
}
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
private void putEvent(TxEvent ev){
|
||||
Long time = ev.getTime();
|
||||
if(!events.containsKey(time)){
|
||||
Vector<ITxEvent> vector=new Vector<ITxEvent>();
|
||||
vector.add(ev);
|
||||
events.put(time, vector);
|
||||
} else {
|
||||
events.get(time).add(ev);
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<Long, ITx> getTransactions() {
|
||||
if(transactions==null){
|
||||
if(generators==null) getGenerators();
|
||||
transactions = new TreeMap<Long, ITx>();
|
||||
maxConcurrency=0;
|
||||
SeekingIterator<String, String> it = levelDb.iterator();
|
||||
String key = "sgx~"+String.format("%016x", id);
|
||||
it.seek(key);
|
||||
while(it.hasNext()) {
|
||||
Entry<String, String> val = it.next();
|
||||
if(!val.getKey().startsWith(key)) break;
|
||||
String[] token = val.getKey().split("~");
|
||||
long gid = Long.parseLong(token[2], 16); // gen id
|
||||
long id = Long.parseLong(token[3], 16); // tx id
|
||||
ITx tx = new Tx(levelDb, this, generators.get(gid), id);
|
||||
transactions.put(id, tx);
|
||||
maxConcurrency= Math.max(maxConcurrency, tx.getConcurrencyIndex());
|
||||
}
|
||||
maxConcurrency++;
|
||||
}
|
||||
return transactions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ITxEvent> getWaveformEventsAtTime(Long time) {
|
||||
return getEvents().get(time);
|
||||
}
|
||||
|
||||
public void setRelationTypeList(List<RelationType> usedRelationsList){
|
||||
this.usedRelationsList=usedRelationsList;
|
||||
}
|
||||
|
||||
public RelationType getRelationType(String name) {
|
||||
RelationType relType=RelationType.create(name);
|
||||
if(!usedRelationsList.contains(relType)) usedRelationsList.add(relType);
|
||||
return relType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean equals(IWaveform other) {
|
||||
return(other instanceof TxStream && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
}
|
@ -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.7"/>
|
||||
<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.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry exported="true" kind="lib" path="sqlite-jdbc-3.8.7.jar"/>
|
||||
|
@ -1,2 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
@ -1,7 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
@ -4,7 +4,7 @@ Bundle-Name: SQLite transaction database
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.sqlite
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||
org.eclipse.equinox.util;bundle-version="1.0.500",
|
||||
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
||||
@ -15,3 +15,4 @@ Bundle-ActivationPolicy: lazy
|
||||
Embed-Dependency: sqlite-jdbc
|
||||
Embedded-Artifacts: sqlite-jdbc-3.8.7.jar;g="org.xerial";
|
||||
a="sqlite-jdbc";v="3.8.7"
|
||||
Automatic-Module-Name: com.minres.scviewer.database.sqlite
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<relativePath>../com.minres.scviewer.parent</relativePath>
|
||||
</parent>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
@ -15,4 +15,5 @@
|
||||
<version>3.8.7</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</project>
|
@ -13,6 +13,7 @@ package com.minres.scviewer.database.sqlite;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
@ -22,7 +23,6 @@ import java.util.List;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
||||
import com.minres.scviewer.database.sqlite.db.SQLiteDatabase;
|
||||
@ -60,9 +60,9 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
|
||||
public List<IWaveform> getAllWaves() {
|
||||
SQLiteDatabaseSelectHandler<ScvStream> handler = new SQLiteDatabaseSelectHandler<ScvStream>(ScvStream.class, database);
|
||||
List<IWaveform<? extends IWaveformEvent>> streams=new ArrayList<IWaveform<? extends IWaveformEvent>>();
|
||||
List<IWaveform> streams=new ArrayList<IWaveform>();
|
||||
try {
|
||||
for(ScvStream scvStream:handler.selectObjects()){
|
||||
TxStream stream = new TxStream(database, db, scvStream);
|
||||
@ -81,14 +81,17 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
||||
@Override
|
||||
public boolean load(IWaveformDb db, File file) throws Exception {
|
||||
this.db=db;
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[x.length];
|
||||
int read = fis.read(buffer, 0, x.length);
|
||||
fis.close();
|
||||
if (read == x.length)
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i]) return false;
|
||||
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[x.length];
|
||||
int read = fis.read(buffer, 0, x.length);
|
||||
fis.close();
|
||||
if (read == x.length)
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i]) return false;
|
||||
} catch(FileNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
database=new SQLiteDatabase(file.getAbsolutePath());
|
||||
database.setData("TIMERESOLUTION", 1L);
|
||||
SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<ScvSimProps>(ScvSimProps.class, database);
|
||||
|
@ -29,7 +29,6 @@ import com.minres.scviewer.database.ITxGenerator;
|
||||
import com.minres.scviewer.database.ITxStream;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
||||
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
|
||||
@ -117,6 +116,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
||||
sb.append(scvStream.getId());
|
||||
resultSet = statement.executeQuery(sb.toString());
|
||||
while (resultSet.next()) {
|
||||
if(maxConcurrency==null) maxConcurrency=0;
|
||||
Object value = resultSet.getObject("concurrencyLevel");
|
||||
if(value!=null)
|
||||
maxConcurrency=(Integer) value;
|
||||
@ -192,7 +192,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
|
||||
public Boolean equals(IWaveform other) {
|
||||
return(other instanceof TxStream && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
|
@ -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.7"/>
|
||||
<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.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src/"/>
|
||||
<classpathentry kind="src" path="src/">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
@ -1,3 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/com/minres/scviewer/database/test/DatabaseServicesTest.java=UTF-8
|
||||
encoding/<project>=UTF-8
|
@ -1,8 +1,8 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
@ -11,32 +11,32 @@
|
||||
<booleanAttribute key="clearws" value="true"/>
|
||||
<booleanAttribute key="clearwslog" value="false"/>
|
||||
<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>
|
||||
<booleanAttribute key="default" value="false"/>
|
||||
<stringAttribute key="deselected_workspace_plugins" value="com.minres.scviewer.database.swt,com.minres.scviewer.e4.application,com.minres.scviewer.ui"/>
|
||||
<booleanAttribute key="default" value="true"/>
|
||||
<stringAttribute key="deselected_workspace_plugins" value="com.minres.scviewer.e4.application,com.minres.scviewer.ui"/>
|
||||
<booleanAttribute key="includeOptional" value="true"/>
|
||||
<stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/DatabaseServicesTest.java"/>
|
||||
<listEntry value="/com.minres.scviewer.database.test"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=com.minres.scviewer.database.test"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.minres.scviewer.database.test.DatabaseServicesTest"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.minres.scviewer.database.test"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx512m -Xdock:icon=../Resources/Eclipse.icns -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx512m"/>
|
||||
<stringAttribute key="pde.version" value="3.3"/>
|
||||
<stringAttribute key="product" value="com.minres.scviewer.e4.product"/>
|
||||
<booleanAttribute key="run_in_ui_thread" value="true"/>
|
||||
<stringAttribute key="selected_target_plugins" value="com.google.guava*10.0.1.v201203051515@default:default,com.google.guava*15.0.0.v201403281430@default:default,com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet*3.0.0.v201112011016@default:default,javax.servlet*3.1.0.v201410161800@default:default,javax.xml@default:default,org.apache.ant@default:default,org.apache.batik.css@default:default,org.apache.batik.util.gui@default:default,org.apache.batik.util@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.codehaus.groovy*2.4.3.xx-201508121448-e45@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.java7@default:false,org.eclipse.core.filesystem.macosx@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt.cocoa@default:false,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.util@default:default,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.cocoa.macosx.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.ui.cocoa@default:false,org.eclipse.ui.trace@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.hamcrest.core@default:default,org.junit@default:default,org.mozilla.javascript@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>
|
||||
<stringAttribute key="selected_workspace_plugins" value="com.minres.scviewer.database.sqlite@default:true,com.minres.scviewer.database.test@default:default,com.minres.scviewer.database.text@default:true,com.minres.scviewer.database.vcd@default:default,com.minres.scviewer.database@default:true"/>
|
||||
<stringAttribute key="selected_target_plugins" value="com.google.guava@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet@default:default,org.apache.ant@default:default,org.apache.commons.jxpath@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.codehaus.groovy@default:default,org.eclipse.ant.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.macosx@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.util@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.cocoa.macosx.x86_64@default:false,org.eclipse.swt@default:default,org.hamcrest.core@default:default,org.junit@default:default"/>
|
||||
<stringAttribute key="selected_workspace_plugins" value="com.minres.scviewer.database.sqlite@default:true,com.minres.scviewer.database.test@default:default,com.minres.scviewer.database.text@default:true,com.minres.scviewer.database.ui.swt@default:default,com.minres.scviewer.database.ui@default:default,com.minres.scviewer.database.vcd@default:default,com.minres.scviewer.database@default:true,com.opcoach.e4.preferences@default:default"/>
|
||||
<booleanAttribute key="show_selected_only" value="false"/>
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
<booleanAttribute key="useCustomFeatures" value="false"/>
|
||||
|
@ -4,7 +4,7 @@ Bundle-Name: SCViewer database tests
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GnbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.junit,
|
||||
com.minres.scviewer.database,
|
||||
com.minres.scviewer.database.sqlite;bundle-version="1.0.0",
|
||||
@ -12,3 +12,4 @@ Require-Bundle: org.junit,
|
||||
com.minres.scviewer.database.vcd;bundle-version="1.0.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Service-Component: OSGI-INF/component.xml
|
||||
Automatic-Module-Name: com.minres.scviewer.database.test
|
||||
|
2
com.minres.scviewer.database.test/inputs/.gitignore
vendored
Normal file
2
com.minres.scviewer.database.test/inputs/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/.scviewer.*
|
||||
/.my_db.txlog*
|
BIN
com.minres.scviewer.database.test/inputs/my_ldb.txldb/000005.sst
Normal file
BIN
com.minres.scviewer.database.test/inputs/my_ldb.txldb/000005.sst
Normal file
Binary file not shown.
BIN
com.minres.scviewer.database.test/inputs/my_ldb.txldb/000046.log
Normal file
BIN
com.minres.scviewer.database.test/inputs/my_ldb.txldb/000046.log
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
||||
MANIFEST-000045
|
@ -0,0 +1 @@
|
||||
2018/11/03-15:38:59.715484 139851522529088Delete type=3 #1
|
Binary file not shown.
400319
com.minres.scviewer.database.test/inputs/my_ldb.vcd
Normal file
400319
com.minres.scviewer.database.test/inputs/my_ldb.vcd
Normal file
File diff suppressed because it is too large
Load Diff
3915
com.minres.scviewer.database.test/inputs/simple_system.vcd
Executable file
3915
com.minres.scviewer.database.test/inputs/simple_system.vcd
Executable file
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<relativePath>../com.minres.scviewer.parent</relativePath>
|
||||
</parent>
|
||||
<packaging>eclipse-test-plugin</packaging>
|
||||
@ -14,6 +14,7 @@
|
||||
<plugin>
|
||||
<groupId>org.eclipse.tycho</groupId>
|
||||
<artifactId>tycho-surefire-plugin</artifactId>
|
||||
<version>0.23.1</version>
|
||||
<configuration>
|
||||
<!-- <bundleStartLevel /> -->
|
||||
<dependencies>
|
||||
@ -26,6 +27,5 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</project>
|
@ -15,11 +15,23 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.minres.scviewer.database.AssociationType;
|
||||
import com.minres.scviewer.database.DataType;
|
||||
import com.minres.scviewer.database.ISignal;
|
||||
import com.minres.scviewer.database.ITx;
|
||||
import com.minres.scviewer.database.ITxAttribute;
|
||||
import com.minres.scviewer.database.ITxEvent;
|
||||
import com.minres.scviewer.database.ITxEvent.Type;
|
||||
import com.minres.scviewer.database.ITxStream;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformDbFactory;
|
||||
|
||||
@ -43,13 +55,6 @@ public class DatabaseServicesTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
waveformDb=waveformDbFactory.getDatabase();
|
||||
// Wait for OSGi dependencies
|
||||
// for (int i = 0; i < 10; i++) {
|
||||
// if (waveformDb.size() == 3) // Dependencies fulfilled
|
||||
// return;
|
||||
// Thread.sleep(1000);
|
||||
// }
|
||||
// assertEquals("OSGi dependencies unfulfilled", 3, WaveformDb.getLoaders().size());
|
||||
}
|
||||
|
||||
@After
|
||||
@ -62,13 +67,22 @@ public class DatabaseServicesTest {
|
||||
assertTrue(f.exists());
|
||||
waveformDb.load(f);
|
||||
assertNotNull(waveformDb);
|
||||
assertEquals(14, waveformDb.getAllWaves().size());
|
||||
List<IWaveform> waves= waveformDb.getAllWaves();
|
||||
assertEquals(14, waves.size());
|
||||
assertEquals(2, waveformDb.getChildNodes().size());
|
||||
IWaveform bus_data_wave = waves.get(0);
|
||||
ISignal<?> bus_data_sig = (ISignal<?>) bus_data_wave;
|
||||
Entry<Long, ?> bus_data_entry = bus_data_sig.getEvents().floorEntry(1400000000L);
|
||||
assertTrue("01111000".equals(bus_data_entry.getValue().toString()));
|
||||
IWaveform rw_wave = waves.get(2);
|
||||
ISignal<?> rw_sig = (ISignal<?>) rw_wave;
|
||||
Entry<Long, ?> rw_entry = rw_sig.getEvents().floorEntry(2360000000L);
|
||||
assertTrue("1".equals(rw_entry.getValue().toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTxSQLite() throws Exception {
|
||||
File f = new File("inputs/my_db.txdb").getAbsoluteFile();
|
||||
File f = new File("inputs/my_sqldb.txdb").getAbsoluteFile();
|
||||
assertTrue(f.exists());
|
||||
waveformDb.load(f);
|
||||
assertNotNull(waveformDb);
|
||||
@ -86,5 +100,48 @@ public class DatabaseServicesTest {
|
||||
assertEquals(1, waveformDb.getChildNodes().size());
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void testTxLDb() throws Exception {
|
||||
File f = new File("inputs/my_ldb.txldb").getAbsoluteFile();
|
||||
assertTrue(f.exists());
|
||||
waveformDb.load(f);
|
||||
assertNotNull(waveformDb);
|
||||
assertEquals(1, waveformDb.getChildNodes().size());
|
||||
List<IWaveform> waves = waveformDb.getAllWaves();
|
||||
assertEquals(3, waves.size());
|
||||
IWaveform wave = waves.get(0);
|
||||
assertTrue(wave instanceof ITxStream<?>);
|
||||
ITxStream<?> stream = (ITxStream<?>) wave;
|
||||
assertEquals(2, stream.getGenerators().size());
|
||||
NavigableMap<Long, List<ITxEvent>> eventsList = stream.getEvents();
|
||||
assertEquals(27, eventsList.size());
|
||||
Entry<Long, List<ITxEvent>> eventEntry = eventsList.firstEntry();
|
||||
assertEquals(100000000L, (long) eventEntry.getKey());
|
||||
List<ITxEvent> events = eventEntry.getValue();
|
||||
assertEquals(1, events.size());
|
||||
ITxEvent event = events.get(0);
|
||||
assertEquals(Type.BEGIN, event.getType());
|
||||
ITx tx = event.getTransaction();
|
||||
assertEquals(3L, (long) tx.getId());
|
||||
List<ITxAttribute> attrs = tx.getAttributes();
|
||||
assertEquals(1, attrs.size());
|
||||
ITxAttribute attr = attrs.get(0);
|
||||
assertEquals("data", attr.getName());
|
||||
assertEquals(DataType.UNSIGNED, attr.getDataType());
|
||||
assertEquals(AssociationType.END, attr.getType());
|
||||
assertTrue(attr.getValue() instanceof Integer);
|
||||
assertEquals(0, (int) attr.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalVCD() throws Exception {
|
||||
File f = new File("inputs/simple_system.vcd").getAbsoluteFile();
|
||||
assertTrue(f.exists());
|
||||
waveformDb.load(f);
|
||||
assertNotNull(waveformDb);
|
||||
assertEquals(779, waveformDb.getAllWaves().size());
|
||||
assertEquals(1, waveformDb.getChildNodes().size());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,22 @@
|
||||
<?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.7"/>
|
||||
<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.pde.core.requiredPlugins"/>
|
||||
<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/eclipse-collections-9.2.0.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/eclipse-collections-api-9.2.0.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/eclipse-collections-forkjoin-9.2.0.jar"/>
|
||||
<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"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
@ -1,8 +1,9 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
@ -1,2 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
groovy.compiler.level=23
|
||||
groovy.compiler.level=26
|
||||
|
@ -2,11 +2,10 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Textual transaction database
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.text
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Version: 2.0.0.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Import-Package: com.minres.scviewer.database,
|
||||
org.osgi.framework;version="1.3.0"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Import-Package: org.osgi.framework;version="1.3.0"
|
||||
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||
org.codehaus.groovy;bundle-version="1.8.6",
|
||||
org.eclipse.equinox.util;bundle-version="1.0.500",
|
||||
@ -15,3 +14,12 @@ Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||
com.google.guava;bundle-version="15.0.0"
|
||||
Service-Component: OSGI-INF/component.xml
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Automatic-Module-Name: com.minres.scviewer.database.text
|
||||
Bundle-ClassPath: lib/mapdb-3.0.7.jar,
|
||||
.,
|
||||
lib/eclipse-collections-9.2.0.jar,
|
||||
lib/eclipse-collections-api-9.2.0.jar,
|
||||
lib/eclipse-collections-forkjoin-9.2.0.jar,
|
||||
lib/kotlin-stdlib-1.2.42.jar,
|
||||
lib/lz4-1.3.0.jar,
|
||||
lib/elsa-3.0.0-M5.jar
|
||||
|
@ -10,6 +10,16 @@
|
||||
###############################################################################
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
OSGI-INF/
|
||||
bin.excludes = **/*.groovy
|
||||
OSGI-INF/,\
|
||||
lib/,\
|
||||
lib/mapdb-3.0.7.jar,\
|
||||
lib/eclipse-collections-9.2.0.jar,\
|
||||
lib/eclipse-collections-api-9.2.0.jar,\
|
||||
lib/eclipse-collections-forkjoin-9.2.0.jar,\
|
||||
lib/kotlin-stdlib-1.2.42.jar,\
|
||||
lib/lz4-1.3.0.jar,\
|
||||
lib/elsa-3.0.0-M5.jar
|
||||
bin.excludes = **/*.groovy,\
|
||||
lib/mapdb-3.0.7-sources.jar,\
|
||||
lib/mapdb-3.0.7-javadoc.jar
|
||||
source.. = src/
|
||||
|
BIN
com.minres.scviewer.database.text/lib/eclipse-collections-9.2.0.jar
Executable file
BIN
com.minres.scviewer.database.text/lib/eclipse-collections-9.2.0.jar
Executable file
Binary file not shown.
BIN
com.minres.scviewer.database.text/lib/eclipse-collections-api-9.2.0.jar
Executable file
BIN
com.minres.scviewer.database.text/lib/eclipse-collections-api-9.2.0.jar
Executable file
Binary file not shown.
BIN
com.minres.scviewer.database.text/lib/eclipse-collections-forkjoin-9.2.0.jar
Executable file
BIN
com.minres.scviewer.database.text/lib/eclipse-collections-forkjoin-9.2.0.jar
Executable file
Binary file not shown.
BIN
com.minres.scviewer.database.text/lib/elsa-3.0.0-M5.jar
Executable file
BIN
com.minres.scviewer.database.text/lib/elsa-3.0.0-M5.jar
Executable file
Binary file not shown.
BIN
com.minres.scviewer.database.text/lib/kotlin-stdlib-1.2.42.jar
Executable file
BIN
com.minres.scviewer.database.text/lib/kotlin-stdlib-1.2.42.jar
Executable file
Binary file not shown.
BIN
com.minres.scviewer.database.text/lib/lz4-1.3.0.jar
Executable file
BIN
com.minres.scviewer.database.text/lib/lz4-1.3.0.jar
Executable file
Binary file not shown.
BIN
com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar
Normal file
BIN
com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar
Normal file
Binary file not shown.
BIN
com.minres.scviewer.database.text/lib/mapdb-3.0.7-sources.jar
Normal file
BIN
com.minres.scviewer.database.text/lib/mapdb-3.0.7-sources.jar
Normal file
Binary file not shown.
BIN
com.minres.scviewer.database.text/lib/mapdb-3.0.7.jar
Normal file
BIN
com.minres.scviewer.database.text/lib/mapdb-3.0.7.jar
Normal file
Binary file not shown.
@ -2,18 +2,21 @@
|
||||
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>2.0.0-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<relativePath>../com.minres.scviewer.parent</relativePath>
|
||||
</parent>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.tycho</groupId>
|
||||
<artifactId>tycho-compiler-plugin</artifactId>
|
||||
<version>0.23.1</version>
|
||||
<configuration>
|
||||
<compilerId>groovy-eclipse-compiler</compilerId>
|
||||
<!-- set verbose to be true if you want lots of uninteresting messages -->
|
||||
@ -36,8 +39,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</plugins>
|
||||
</build>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</project>
|
@ -10,7 +10,15 @@
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.text;
|
||||
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.util.Collection;
|
||||
import java.util.zip.GZIPInputStream
|
||||
|
||||
import org.codehaus.groovy.ast.stmt.CatchStatement
|
||||
import org.mapdb.DB
|
||||
import org.mapdb.DBMaker
|
||||
|
||||
import groovy.io.FileType
|
||||
|
||||
import com.minres.scviewer.database.AssociationType
|
||||
import com.minres.scviewer.database.DataType
|
||||
@ -26,10 +34,12 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||
private Long maxTime;
|
||||
|
||||
IWaveformDb db;
|
||||
|
||||
|
||||
def streams = []
|
||||
|
||||
|
||||
def relationTypes=[:]
|
||||
|
||||
DB mapDb
|
||||
|
||||
public TextDbLoader() {
|
||||
}
|
||||
@ -56,18 +66,57 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||
boolean load(IWaveformDb db, File file) throws Exception {
|
||||
this.db=db
|
||||
this.streams=[]
|
||||
FileInputStream fis = new FileInputStream(file)
|
||||
byte[] buffer = new byte[x.size()]
|
||||
def readCnt = fis.read(buffer, 0, x.size())
|
||||
fis.close()
|
||||
if(readCnt==x.size())
|
||||
for(int i=0; i<x.size(); i++)
|
||||
if(buffer[i]!=x[i]) return false
|
||||
parseInput(file)
|
||||
calculateConcurrencyIndicees()
|
||||
try {
|
||||
def gzipped = isGzipped(file)
|
||||
if(isTxfile(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))){
|
||||
def mapDbFile = File.createTempFile("."+file.name, "tmp", file.parentFile)
|
||||
mapDbFile.delete()
|
||||
mapDbFile.deleteOnExit()
|
||||
this.mapDb = DBMaker
|
||||
.fileDB(mapDbFile)
|
||||
.fileMmapEnableIfSupported()
|
||||
.fileMmapPreclearDisable()
|
||||
.cleanerHackEnable()
|
||||
.allocateStartSize(64*1024*1024)
|
||||
.allocateIncrement(64*1024*1024)
|
||||
.make()
|
||||
parseInput(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))
|
||||
calculateConcurrencyIndicees()
|
||||
return true
|
||||
}
|
||||
} catch(EOFException e) {
|
||||
return true;
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isTxfile(InputStream istream) {
|
||||
byte[] buffer = new byte[x.size()]
|
||||
def readCnt = istream.read(buffer, 0, x.size())
|
||||
istream.close()
|
||||
if(readCnt==x.size()){
|
||||
for(int i=0; i<x.size(); i++)
|
||||
if(buffer[i]!=x[i]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private static boolean isGzipped(File f) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
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;
|
||||
} finally {
|
||||
is.close()
|
||||
}
|
||||
}
|
||||
|
||||
private stringToScale(String scale){
|
||||
switch(scale.trim()){
|
||||
case "fs":return 1L
|
||||
@ -78,7 +127,7 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||
case "s": return 1000000000000000L
|
||||
}
|
||||
}
|
||||
private def parseInput(File input){
|
||||
private def parseInput(InputStream inputStream){
|
||||
def streamsById = [:]
|
||||
def generatorsById = [:]
|
||||
def transactionsById = [:]
|
||||
@ -86,7 +135,9 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||
Tx transaction
|
||||
boolean endTransaction=false
|
||||
def matcher
|
||||
input.eachLine { line ->
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
|
||||
long lineCnt=0;
|
||||
reader.eachLine { line ->
|
||||
def tokens = line.split(/\s+/)
|
||||
switch(tokens[0]){
|
||||
case "scv_tr_stream":
|
||||
@ -95,7 +146,7 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||
case "end_attribute":
|
||||
if ((matcher = line =~ /^scv_tr_stream\s+\(ID (\d+),\s+name\s+"([^"]+)",\s+kind\s+"([^"]+)"\)$/)) {
|
||||
def id = Integer.parseInt(matcher[0][1])
|
||||
def stream = new TxStream(db, id, matcher[0][2], matcher[0][3])
|
||||
def stream = new TxStream(this, id, matcher[0][2], matcher[0][3])
|
||||
streams<<stream
|
||||
streamsById[id]=stream
|
||||
} else if ((matcher = line =~ /^scv_tr_generator\s+\(ID\s+(\d+),\s+name\s+"([^"]+)",\s+scv_tr_stream\s+(\d+),$/)) {
|
||||
@ -138,9 +189,11 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||
break
|
||||
case "a"://matcher = line =~ /^a\s+(.+)$/
|
||||
if(endTransaction){
|
||||
transaction.attributes << new TxAttribute(transaction.generator.end_attrs[0], tokens[1])
|
||||
transaction.attributes << new TxAttribute(transaction.generator.end_attrs[transaction.generator.end_attrs_idx], tokens[1])
|
||||
transaction.generator.end_attrs_idx++
|
||||
} else {
|
||||
transaction.attributes << new TxAttribute(transaction.generator.begin_attrs[0], tokens[1])
|
||||
transaction.attributes << new TxAttribute(transaction.generator.begin_attrs[transaction.generator.begin_attrs_idx], tokens[1])
|
||||
transaction.generator.begin_attrs_idx++
|
||||
}
|
||||
break
|
||||
case "tx_relation"://matcher = line =~ /^tx_relation\s+\"(\S+)\"\s+(\d+)\s+(\d+)$/
|
||||
@ -156,16 +209,18 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||
println "Don't know what to do with: '$line'"
|
||||
|
||||
}
|
||||
lineCnt++
|
||||
}
|
||||
}
|
||||
|
||||
private def calculateConcurrencyIndicees(){
|
||||
streams.each{ TxStream stream -> stream.getMaxConcurrency() }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Collection<RelationType> getAllRelationTypes(){
|
||||
return relationTypes.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
|
||||
import com.google.common.collect.TreeMultimap
|
||||
import org.mapdb.Serializer
|
||||
|
||||
import com.minres.scviewer.database.ITxEvent;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb
|
||||
@ -44,14 +45,15 @@ class TxStream extends HierNode implements ITxStream {
|
||||
|
||||
private TreeMap<Long, List<ITxEvent>> events
|
||||
|
||||
TxStream(IWaveformDb db, int id, String name, String kind){
|
||||
TxStream(TextDbLoader loader, int id, String name, String kind){
|
||||
super(name)
|
||||
this.id=id
|
||||
this.database=db
|
||||
this.database=loader.db
|
||||
this.fullName=name
|
||||
this.kind=kind
|
||||
this.maxConcurrency=0
|
||||
events = new TreeMap<Long, List<ITxEvent>>()
|
||||
//events = new TreeMap<Long, List<ITxEvent>>()
|
||||
events = loader.mapDb.treeMap(name).keySerializer(Serializer.LONG).createOrOpen();
|
||||
}
|
||||
|
||||
List<ITxGenerator> getGenerators(){
|
||||
@ -110,7 +112,7 @@ class TxStream extends HierNode implements ITxStream {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
|
||||
public Boolean equals(IWaveform other) {
|
||||
return(other instanceof TxStream && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?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.7"/>
|
||||
<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.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src/"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
@ -1,2 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
@ -1,7 +1,101 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
|
||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
|
||||
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
|
||||
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.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||
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.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
|
||||
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.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
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.source=1.8
|
||||
|
@ -2,9 +2,9 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: SWT widget
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.ui.swt
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Version: 2.0.1.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
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",
|
||||
@ -17,3 +17,4 @@ Export-Package: com.minres.scviewer.database.swt
|
||||
Bundle-ClassPath: .
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Activator: com.minres.scviewer.database.swt.DatabaseUiPlugin
|
||||
Automatic-Module-Name: com.minres.scviewer.database.ui.swt
|
||||
|
@ -5,7 +5,8 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<relativePath>../com.minres.scviewer.parent</relativePath>
|
||||
</parent>
|
||||
</project>
|
||||
<version>2.0.1-SNAPSHOT</version>
|
||||
</project>
|
@ -0,0 +1,9 @@
|
||||
package com.minres.scviewer.database.swt;
|
||||
|
||||
public class Constants {
|
||||
|
||||
public final static String[] unitString={"fs", "ps", "ns", "us", "ms"};//, "s"};
|
||||
|
||||
public final static int[] unitMultiplier={1, 3, 10, 30, 100, 300};
|
||||
|
||||
}
|
@ -46,6 +46,8 @@ public class ArrowPainter implements IPainter {
|
||||
|
||||
private RelationType highlightType;
|
||||
|
||||
private long selectionOffset;
|
||||
|
||||
long scaleFactor;
|
||||
|
||||
boolean deferredUpdate;
|
||||
@ -87,8 +89,9 @@ public class ArrowPainter implements IPainter {
|
||||
deferredUpdate = true;
|
||||
return;
|
||||
}
|
||||
selectionOffset = waveCanvas.getXOffset();
|
||||
int laneHeight = painter.getHeight() / stream.getMaxConcurrency();
|
||||
txRectangle = new Rectangle((int) (tx.getBeginTime() / scaleFactor),
|
||||
txRectangle = new Rectangle((int) (tx.getBeginTime() / scaleFactor-waveCanvas.getXOffset()),
|
||||
waveCanvas.rulerHeight + painter.getVerticalOffset() + laneHeight * tx.getConcurrencyIndex(),
|
||||
(int) ((tx.getEndTime() - tx.getBeginTime()) / scaleFactor), laneHeight);
|
||||
deriveGeom(tx.getIncomingRelations(), iRect, false);
|
||||
@ -102,7 +105,7 @@ public class ArrowPainter implements IPainter {
|
||||
ITxStream<?> stream = otherTx.getStream();
|
||||
IWaveformPainter painter = waveCanvas.wave2painterMap.get(stream);
|
||||
int laneHeight = painter.getHeight() / stream.getMaxConcurrency();
|
||||
Rectangle bb = new Rectangle((int) (otherTx.getBeginTime() / scaleFactor),
|
||||
Rectangle bb = new Rectangle((int) (otherTx.getBeginTime() / scaleFactor-waveCanvas.getXOffset()),
|
||||
waveCanvas.rulerHeight + painter.getVerticalOffset()
|
||||
+ laneHeight * otherTx.getConcurrencyIndex(),
|
||||
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor), laneHeight);
|
||||
@ -120,14 +123,19 @@ public class ArrowPainter implements IPainter {
|
||||
scaleFactor = waveCanvas.getScaleFactor();
|
||||
calculateGeometries();
|
||||
}
|
||||
if(txRectangle == null) return;
|
||||
int correctionValue = (int)(selectionOffset - waveCanvas.getXOffset());
|
||||
Rectangle correctedTargetRectangle = new Rectangle(txRectangle.x+correctionValue, txRectangle.y, txRectangle.width, txRectangle.height);
|
||||
for (LinkEntry entry : iRect) {
|
||||
Rectangle correctedRectangle = new Rectangle(entry.rectangle.x+correctionValue, entry.rectangle.y, entry.rectangle.width, entry.rectangle.height);
|
||||
Point target = drawPath(gc, highlightType.equals(entry.relationType) ? highliteColor : fgColor,
|
||||
entry.rectangle, txRectangle);
|
||||
correctedRectangle, correctedTargetRectangle);
|
||||
drawArrow(gc, target);
|
||||
}
|
||||
for (LinkEntry entry : oRect) {
|
||||
Point target = drawPath(gc, highlightType.equals(entry.relationType) ? highliteColor : fgColor, txRectangle,
|
||||
entry.rectangle);
|
||||
Rectangle correctedRectangle = new Rectangle(entry.rectangle.x+correctionValue, entry.rectangle.y, entry.rectangle.width, entry.rectangle.height);
|
||||
Point target = drawPath(gc, highlightType.equals(entry.relationType) ? highliteColor : fgColor, correctedTargetRectangle,
|
||||
correctedRectangle);
|
||||
drawArrow(gc, target);
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,11 @@ public class CursorPainter implements IPainter, ICursor {
|
||||
|
||||
public final int id;
|
||||
|
||||
/// maximum visible canvas position in canvas coordinates
|
||||
int maxPosX;
|
||||
/// maximum visible position in waveform coordinates
|
||||
int maxValX;
|
||||
|
||||
/**
|
||||
* @param i
|
||||
* @param txDisplay
|
||||
@ -56,23 +61,32 @@ public class CursorPainter implements IPainter, ICursor {
|
||||
this.isDragging = isDragging;
|
||||
}
|
||||
|
||||
|
||||
public void paintArea(GC gc, Rectangle area) {
|
||||
if(this.waveCanvas.painterList.size()>0){
|
||||
|
||||
long scaleFactor=waveCanvas.getScaleFactor();
|
||||
long beginPos = area.x;
|
||||
|
||||
maxPosX = area.x + area.width;
|
||||
maxValX = maxPosX + (int)waveCanvas.getXOffset();
|
||||
|
||||
// x position of marker in pixels on canvas
|
||||
int x = (int) (time/scaleFactor);
|
||||
// distance of marker from the top of Canvas' painting area
|
||||
int top = id<0?area.y:area.y+15;
|
||||
|
||||
Color drawColor=waveCanvas.colors[id<0?WaveformColors.CURSOR.ordinal():WaveformColors.MARKER.ordinal()];
|
||||
Color dragColor = waveCanvas.colors[WaveformColors.CURSOR_DRAG.ordinal()];
|
||||
Color textColor=waveCanvas.colors[id<0?WaveformColors.CURSOR_TEXT.ordinal():WaveformColors.MARKER_TEXT.ordinal()];
|
||||
if(x>=area.x && x<=(area.x+area.width)){
|
||||
if(x>=beginPos && x<=maxValX){
|
||||
gc.setForeground(isDragging?dragColor:drawColor);
|
||||
gc.drawLine(x, top, x, area.y+area.height);
|
||||
gc.drawLine(x-(int)waveCanvas.getXOffset(), top, x-(int)waveCanvas.getXOffset(), area.y+area.height);
|
||||
gc.setBackground(drawColor);
|
||||
gc.setForeground(textColor);
|
||||
Double dTime=new Double(time);
|
||||
gc.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top);
|
||||
gc.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1-(int)waveCanvas.getXOffset(), top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.swt.internal;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
@ -22,12 +24,15 @@ public class RulerPainter implements IPainter {
|
||||
static final int rulerTickMinorC = 10;
|
||||
static final int rulerTickMajorC = 100;
|
||||
|
||||
static final DecimalFormat df = new DecimalFormat("#.00####");
|
||||
|
||||
public RulerPainter(WaveformCanvas waveCanvas) {
|
||||
this.waveCanvas=waveCanvas;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintArea(GC gc, Rectangle area) {
|
||||
|
||||
Color headerFgColor=waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
|
||||
if(headerFgColor.isDisposed())
|
||||
headerFgColor=SWTResourceManager.getColor(0,0,0);
|
||||
@ -37,25 +42,24 @@ public class RulerPainter implements IPainter {
|
||||
String unit=waveCanvas.getUnitStr();
|
||||
int unitMultiplier=waveCanvas.getUnitMultiplier();
|
||||
long scaleFactor=waveCanvas.getScaleFactor();
|
||||
long zoomLevel = waveCanvas.getZoomLevel();
|
||||
long start=area.x*scaleFactor;
|
||||
long end=start+area.width*scaleFactor;
|
||||
|
||||
long startPos=area.x*scaleFactor;
|
||||
long startVal=startPos + waveCanvas.getXOffset()*scaleFactor;
|
||||
long endPos=startPos+area.width*scaleFactor;
|
||||
long endVal=startVal+area.width*scaleFactor;
|
||||
|
||||
long rulerTickMinor = rulerTickMinorC*scaleFactor;
|
||||
long rulerTickMajor = rulerTickMajorC*scaleFactor;
|
||||
if(zoomLevel%3==1){
|
||||
rulerTickMinor/=3;
|
||||
rulerTickMajor/=3;
|
||||
}
|
||||
|
||||
int minorTickY = waveCanvas.rulerHeight-5;
|
||||
int majorTickY = waveCanvas.rulerHeight-15;
|
||||
int textY=waveCanvas.rulerHeight-20;
|
||||
int baselineY=waveCanvas.rulerHeight - 1;
|
||||
int bottom=waveCanvas.rulerHeight - 2;
|
||||
|
||||
long startMinorIncr = start;
|
||||
long modulo = start % rulerTickMinor;
|
||||
startMinorIncr+=rulerTickMinor-modulo;
|
||||
long modulo = startVal % rulerTickMinor;
|
||||
long startMinorIncrPos = startPos+rulerTickMinor-modulo;
|
||||
long startMinorIncrVal = startVal+rulerTickMinor-modulo;
|
||||
|
||||
gc.setBackground(waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
|
||||
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, waveCanvas.rulerHeight));
|
||||
@ -64,15 +68,18 @@ public class RulerPainter implements IPainter {
|
||||
gc.setForeground(headerFgColor);
|
||||
gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom);
|
||||
|
||||
for (long tick = startMinorIncr; tick < end; tick += rulerTickMinor) {
|
||||
int x0 = (int) (tick/scaleFactor);
|
||||
int x0_max = 0;
|
||||
|
||||
for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) {
|
||||
int x0_pos = (int) (pos/scaleFactor);
|
||||
long x0_val = tick/scaleFactor;
|
||||
x0_max = x0_pos;
|
||||
if ((tick % rulerTickMajor) == 0) {
|
||||
gc.drawText(Double.toString(tick/scaleFactor*unitMultiplier)+unit, x0, area.y+textY);
|
||||
gc.drawLine(x0, area.y+majorTickY, x0,area.y+ bottom);
|
||||
gc.drawText(df.format(x0_val*unitMultiplier)+unit, x0_pos, area.y+textY);
|
||||
gc.drawLine(x0_pos, area.y+majorTickY, x0_pos,area.y+ bottom);
|
||||
} else {
|
||||
gc.drawLine(x0, area.y+minorTickY, x0, area.y+bottom);
|
||||
gc.drawLine(x0_pos, area.y+minorTickY, x0_pos, area.y+bottom);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -10,136 +10,429 @@
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.swt.internal;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
|
||||
import com.minres.scviewer.database.BitVector;
|
||||
import com.minres.scviewer.database.ISignal;
|
||||
import com.minres.scviewer.database.ISignalChange;
|
||||
import com.minres.scviewer.database.ISignalChangeMulti;
|
||||
import com.minres.scviewer.database.ISignalChangeSingle;
|
||||
import com.minres.scviewer.database.ui.TrackEntry;
|
||||
import com.minres.scviewer.database.ui.WaveformColors;
|
||||
|
||||
public class SignalPainter extends TrackPainter {
|
||||
|
||||
public class SignalPainter extends TrackPainter {
|
||||
private class SignalChange {
|
||||
long time;
|
||||
Object value;
|
||||
boolean fromMap;
|
||||
|
||||
public SignalChange(Entry<Long, ?> entry) {
|
||||
time = entry.getKey();
|
||||
value = entry.getValue();
|
||||
fromMap = true;
|
||||
}
|
||||
|
||||
public void set(Entry<Long, ?> entry, Long actTime) {
|
||||
if (entry != null) {
|
||||
time = entry.getKey();
|
||||
value = entry.getValue();
|
||||
fromMap = true;
|
||||
} else {
|
||||
time = actTime;
|
||||
fromMap = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void assign(SignalChange other) {
|
||||
time = other.time;
|
||||
value = other.value;
|
||||
fromMap = other.fromMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final JPanel DUMMY_PANEL = new JPanel();
|
||||
|
||||
private final WaveformCanvas waveCanvas;
|
||||
private ISignal<? extends ISignalChange> signal;
|
||||
|
||||
int yOffsetT;
|
||||
int yOffsetM;
|
||||
int yOffsetB;
|
||||
/// maximum visible canvas position in canvas coordinates
|
||||
int maxPosX;
|
||||
/// maximum visible position in waveform coordinates
|
||||
int maxValX;
|
||||
|
||||
public SignalPainter(WaveformCanvas txDisplay, boolean even, TrackEntry trackEntry) {
|
||||
super(trackEntry, even);
|
||||
this.waveCanvas = txDisplay;
|
||||
this.signal=trackEntry.getSignal();
|
||||
}
|
||||
|
||||
public void paintArea(GC gc, Rectangle area) {
|
||||
if(trackEntry.selected)
|
||||
private int getXValEnd(long time) {
|
||||
long ltmp = time / this.waveCanvas.getScaleFactor();
|
||||
return ltmp > maxValX ? maxValX : (int) ltmp;
|
||||
}
|
||||
|
||||
private int getXPosEnd(long time) {
|
||||
long ltmp = time / this.waveCanvas.getScaleFactor() - waveCanvas.getXOffset();
|
||||
return ltmp > maxPosX ? maxPosX : (int) ltmp;
|
||||
}
|
||||
|
||||
public void paintArea(GC gc, Rectangle area) {
|
||||
ISignal<?> signal = trackEntry.getSignal();
|
||||
if (trackEntry.selected)
|
||||
gc.setBackground(this.waveCanvas.colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()]);
|
||||
else
|
||||
gc.setBackground(this.waveCanvas.colors[even?WaveformColors.TRACK_BG_EVEN.ordinal():WaveformColors.TRACK_BG_ODD.ordinal()]);
|
||||
gc.setBackground(this.waveCanvas.colors[even ? WaveformColors.TRACK_BG_EVEN.ordinal() : WaveformColors.TRACK_BG_ODD.ordinal()]);
|
||||
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
||||
gc.fillRectangle(area);
|
||||
Entry<Long, ? extends ISignalChange> firstChange=signal.getEvents().floorEntry(area.x*this.waveCanvas.getScaleFactor());
|
||||
Entry<Long, ? extends ISignalChange> lastTx=signal.getEvents().ceilingEntry((area.x+area.width)*this.waveCanvas.getScaleFactor());
|
||||
if(firstChange==null){
|
||||
if(lastTx==null) return;
|
||||
firstChange = signal.getEvents().firstEntry();
|
||||
} else if(lastTx==null){
|
||||
lastTx=signal.getEvents().lastEntry();
|
||||
|
||||
long scaleFactor = this.waveCanvas.getScaleFactor();
|
||||
long beginPos = area.x;
|
||||
long beginTime = (beginPos + waveCanvas.getXOffset())*scaleFactor;
|
||||
long endPos = beginPos + area.width;
|
||||
long endTime = beginTime + area.width*scaleFactor;
|
||||
|
||||
Entry<Long, ?> first = signal.getEvents().floorEntry(beginTime);
|
||||
Entry<Long, ?> last = signal.getEvents().floorEntry(endTime);
|
||||
if (first == null) {
|
||||
if (last == null)
|
||||
return;
|
||||
first = signal.getEvents().firstEntry();
|
||||
} else if (last == null) {
|
||||
last = signal.getEvents().lastEntry();
|
||||
}
|
||||
gc.setForeground(this.waveCanvas.colors[WaveformColors.LINE.ordinal()]);
|
||||
gc.setLineStyle(SWT.LINE_SOLID);
|
||||
gc.setLineWidth(1);
|
||||
Entry<Long, ? extends ISignalChange> left=firstChange;
|
||||
if(left.getValue() instanceof ISignalChangeSingle){
|
||||
NavigableMap<Long, ? extends ISignalChange> entries=signal.getEvents().subMap(firstChange.getKey(), false, lastTx.getKey(), true);
|
||||
for(Entry<Long, ? extends ISignalChange> right:entries.entrySet()){
|
||||
int xEnd= (int)(right.getKey()/this.waveCanvas.getScaleFactor());
|
||||
int xBegin= (int)(left.getKey()/this.waveCanvas.getScaleFactor());
|
||||
if(xEnd>xBegin){
|
||||
int yOffset = this.waveCanvas.getTrackHeight()/2;
|
||||
Color color = this.waveCanvas.colors[WaveformColors.SIGNALX.ordinal()];
|
||||
switch(((ISignalChangeSingle) left.getValue()).getValue()){
|
||||
case '1':
|
||||
color=this.waveCanvas.colors[WaveformColors.SIGNAL1.ordinal()];
|
||||
yOffset = this.waveCanvas.getTrackHeight()/5;
|
||||
break;
|
||||
case '0':
|
||||
color=this.waveCanvas.colors[WaveformColors.SIGNAL0.ordinal()];
|
||||
yOffset = 4*this.waveCanvas.getTrackHeight()/5;
|
||||
break;
|
||||
case 'Z':
|
||||
color=this.waveCanvas.colors[WaveformColors.SIGNALZ.ordinal()];
|
||||
break;
|
||||
default:
|
||||
}
|
||||
yOffset+=area.y;
|
||||
gc.setForeground(color);
|
||||
gc.drawLine(xBegin, yOffset, xEnd, yOffset);
|
||||
int yNext = this.waveCanvas.getTrackHeight()/2;
|
||||
switch(((ISignalChangeSingle) right.getValue()).getValue()){
|
||||
case '1':
|
||||
yNext = this.waveCanvas.getTrackHeight()/5+area.y;
|
||||
break;
|
||||
case '0':
|
||||
yNext = 4*this.waveCanvas.getTrackHeight()/5+area.y;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
gc.drawLine(xEnd, yOffset, xEnd, yNext);
|
||||
}
|
||||
left=right;
|
||||
NavigableMap<Long, ?> 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);
|
||||
maxPosX = area.x + area.width;
|
||||
maxValX = maxPosX + (int)waveCanvas.getXOffset();
|
||||
yOffsetT = this.waveCanvas.getTrackHeight() / 5 + area.y;
|
||||
yOffsetM = this.waveCanvas.getTrackHeight() / 2 + area.y;
|
||||
yOffsetB = 4 * this.waveCanvas.getTrackHeight() / 5 + area.y;
|
||||
int xSigChangeBeginVal = Math.max(area.x + (int)waveCanvas.getXOffset(), (int) (left.time / this.waveCanvas.getScaleFactor()));
|
||||
int xSigChangeBeginPos = area.x;
|
||||
int xSigChangeEndVal = Math.max(area.x + (int)waveCanvas.getXOffset(), getXValEnd(right.time));
|
||||
int xSigChangeEndPos = Math.max(area.x, getXPosEnd(right.time));
|
||||
|
||||
boolean multiple = false;
|
||||
if (xSigChangeEndPos == xSigChangeBeginPos) {
|
||||
// this can trigger if
|
||||
// a) left == right
|
||||
// b) left to close to right
|
||||
if (left.time == right.time) {
|
||||
right.time = endTime;
|
||||
} else {
|
||||
multiple = true;
|
||||
long eTime = (xSigChangeBeginVal + 1) * this.waveCanvas.getScaleFactor();
|
||||
right.set(entries.floorEntry(eTime), endTime);
|
||||
right.time = eTime;
|
||||
}
|
||||
} else if(left.getValue() instanceof ISignalChangeMulti){
|
||||
NavigableMap<Long,? extends ISignalChange> entries=signal.getEvents().subMap(firstChange.getKey(), false, lastTx.getKey(), true);
|
||||
for(Entry<Long, ? extends ISignalChange> right:entries.entrySet()){
|
||||
int yOffsetT = this.waveCanvas.getTrackHeight()/5+area.y;
|
||||
int yOffsetM = this.waveCanvas.getTrackHeight()/2+area.y;
|
||||
int yOffsetB = 4*this.waveCanvas.getTrackHeight()/5+area.y;
|
||||
Color colorBorder = this.waveCanvas.colors[WaveformColors.SIGNAL0.ordinal()];
|
||||
ISignalChangeMulti last = (ISignalChangeMulti) left.getValue();
|
||||
if(last.getValue().toString().contains("X")){
|
||||
colorBorder=this.waveCanvas.colors[WaveformColors.SIGNALX.ordinal()];
|
||||
}else if(last.getValue().toString().contains("Z")){
|
||||
colorBorder=this.waveCanvas.colors[WaveformColors.SIGNALZ.ordinal()];
|
||||
}
|
||||
int beginTime= (int)(left.getKey()/this.waveCanvas.getScaleFactor());
|
||||
int endTime= (int)(right.getKey()/this.waveCanvas.getScaleFactor());
|
||||
int[] points = {
|
||||
beginTime,yOffsetM,
|
||||
beginTime+1,yOffsetT,
|
||||
endTime-1,yOffsetT,
|
||||
endTime,yOffsetM,
|
||||
endTime-1,yOffsetB,
|
||||
beginTime+1,yOffsetB
|
||||
xSigChangeEndPos = getXPosEnd(right.time);
|
||||
}
|
||||
|
||||
|
||||
SignalStencil stencil = getStencil(gc, left, entries);
|
||||
do {
|
||||
stencil.draw(gc, area, left.value, right.value, xSigChangeBeginPos, xSigChangeEndPos, multiple);
|
||||
if (right.time >= endTime)
|
||||
break;
|
||||
left.assign(right);
|
||||
xSigChangeBeginPos = xSigChangeEndPos;
|
||||
right.set(entries.higherEntry(left.time), endTime);
|
||||
xSigChangeEndPos = getXPosEnd(right.time);
|
||||
multiple = false;
|
||||
if (xSigChangeEndPos == xSigChangeBeginPos) {
|
||||
multiple = true;
|
||||
long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScaleFactor();
|
||||
Entry<Long, ?> entry = entries.floorEntry(eTime);
|
||||
if(entry!=null && entry.getKey()> right.time)
|
||||
right.set(entry, endTime);
|
||||
xSigChangeEndPos = getXPosEnd(eTime);
|
||||
}
|
||||
} while (left.time < endTime);
|
||||
}
|
||||
|
||||
private SignalStencil getStencil(GC gc, SignalChange left, NavigableMap<Long, ?> entries) {
|
||||
Object val = left.value;
|
||||
if(val instanceof BitVector) {
|
||||
BitVector bv = (BitVector) val;
|
||||
if(bv.getWidth()==1)
|
||||
return new SingleBitStencil();
|
||||
if(trackEntry.waveDisplay==TrackEntry.WaveDisplay.DEFAULT)
|
||||
return new MultiBitStencil(gc);
|
||||
else
|
||||
return new MultiBitStencilAnalog(entries, left.value,
|
||||
trackEntry.waveDisplay==TrackEntry.WaveDisplay.CONTINOUS,
|
||||
trackEntry.valueDisplay==TrackEntry.ValueDisplay.SIGNED);
|
||||
} else if (val instanceof Double)
|
||||
return new RealStencil(entries, left.value, trackEntry.waveDisplay==TrackEntry.WaveDisplay.CONTINOUS);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private interface SignalStencil {
|
||||
|
||||
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple);
|
||||
}
|
||||
|
||||
private class MultiBitStencil implements SignalStencil {
|
||||
|
||||
private java.awt.Font tmpAwtFont;
|
||||
private int height;
|
||||
|
||||
public MultiBitStencil(GC gc) {
|
||||
FontData fd = gc.getFont().getFontData()[0];
|
||||
height = gc.getDevice().getDPI().y * fd.getHeight() / 72;
|
||||
tmpAwtFont = new java.awt.Font(fd.getName(), fd.getStyle(), height);
|
||||
}
|
||||
|
||||
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple) {
|
||||
Color colorBorder = waveCanvas.colors[WaveformColors.SIGNAL0.ordinal()];
|
||||
BitVector last = (BitVector) left;
|
||||
if (last.getValue().toString().contains("X")) {
|
||||
colorBorder = waveCanvas.colors[WaveformColors.SIGNALX.ordinal()];
|
||||
} else if (last.getValue().toString().contains("Z")) {
|
||||
colorBorder = waveCanvas.colors[WaveformColors.SIGNALZ.ordinal()];
|
||||
}
|
||||
int width = xEnd - xBegin;
|
||||
if (width > 1) {
|
||||
int[] points = {
|
||||
xBegin, yOffsetM,
|
||||
xBegin + 1, yOffsetT,
|
||||
xEnd - 1, yOffsetT,
|
||||
xEnd, yOffsetM,
|
||||
xEnd - 1, yOffsetB,
|
||||
xBegin + 1, yOffsetB
|
||||
};
|
||||
gc.setForeground(colorBorder);
|
||||
gc.drawPolygon(points);
|
||||
gc.setForeground(this.waveCanvas.colors[WaveformColors.SIGNAL_TEXT.ordinal()]);
|
||||
int size = gc.getDevice().getDPI().y * gc.getFont().getFontData()[0].getHeight()/72;
|
||||
if(beginTime<area.x) beginTime=area.x;
|
||||
int width=endTime-beginTime;
|
||||
if(width>6) {
|
||||
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_TEXT.ordinal()]);
|
||||
//TODO: this code should be provided from a central location
|
||||
String label = null;
|
||||
switch(trackEntry.valueDisplay) {
|
||||
case SIGNED:
|
||||
label=Long.toString(last.toSignedValue());
|
||||
break;
|
||||
case UNSIGNED:
|
||||
label=Long.toString(last.toUnsignedValue());
|
||||
break;
|
||||
default:
|
||||
label="h'"+last.toHexString();
|
||||
}
|
||||
Point bb = getBoxWidth(gc, label);
|
||||
if (xBegin < area.x) {
|
||||
xBegin = area.x;
|
||||
width = xEnd - xBegin;
|
||||
}
|
||||
if (width > (bb.x+1)) {
|
||||
Rectangle old = gc.getClipping();
|
||||
gc.setClipping(beginTime+3, yOffsetT, endTime-beginTime-5, yOffsetB-yOffsetT);
|
||||
gc.drawText("h'"+last.getValue().toHexString(), beginTime+3, yOffsetM-size/2-1);
|
||||
gc.setClipping(xBegin + 3, yOffsetT, xEnd - xBegin - 5, yOffsetB - yOffsetT);
|
||||
gc.drawText(label, xBegin + 3, yOffsetM - bb.y / 2 - 1);
|
||||
gc.setClipping(old);
|
||||
}
|
||||
left=right;
|
||||
} else {
|
||||
gc.setForeground(colorBorder);
|
||||
gc.drawLine(xEnd, yOffsetT, xEnd, yOffsetB);
|
||||
}
|
||||
}
|
||||
|
||||
private Point getBoxWidth(GC gc, String label) {
|
||||
return new Point(DUMMY_PANEL.getFontMetrics(tmpAwtFont).stringWidth(label), height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class MultiBitStencilAnalog implements SignalStencil {
|
||||
|
||||
final boolean continous;
|
||||
private long minVal;
|
||||
private long range;
|
||||
|
||||
public MultiBitStencilAnalog(NavigableMap<Long, ?> entries, Object left, boolean continous, boolean signed) {
|
||||
this.continous=continous;
|
||||
Collection<?> values = ((NavigableMap<Long, ?>) entries).values();
|
||||
minVal=((BitVector) left).toUnsignedValue();
|
||||
range=2;
|
||||
if(!values.isEmpty()) {
|
||||
long maxVal=minVal;
|
||||
for (Object e : entries.values()) {
|
||||
long v = ((BitVector)e).toUnsignedValue();
|
||||
maxVal=Math.max(maxVal, v);
|
||||
minVal=Math.min(minVal, v);
|
||||
}
|
||||
if(maxVal==minVal) {
|
||||
maxVal--;
|
||||
minVal++;
|
||||
}
|
||||
range = maxVal-minVal;
|
||||
} else
|
||||
minVal--;
|
||||
|
||||
}
|
||||
|
||||
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple) {
|
||||
long leftVal = ((BitVector) left).toUnsignedValue();
|
||||
long rightVal= ((BitVector) right).toUnsignedValue();
|
||||
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_REAL.ordinal()]);
|
||||
int yOffsetLeft = (int) ((leftVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
int yOffsetRight = (int) ((rightVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
if(continous) {
|
||||
if (xEnd > maxPosX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetRight);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
} else {
|
||||
if (xEnd > maxPosX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetLeft);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetLeft);
|
||||
if(yOffsetRight!=yOffsetLeft) {
|
||||
gc.drawLine(xEnd, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ISignal<? extends ISignalChange> getSignal() {
|
||||
return signal;
|
||||
private class SingleBitStencil implements SignalStencil {
|
||||
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple) {
|
||||
if (multiple) {
|
||||
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNALU.ordinal()]);
|
||||
gc.drawLine(xBegin, yOffsetT, xBegin, yOffsetB);
|
||||
if(xEnd>xBegin)
|
||||
gc.drawLine(xEnd, yOffsetT, xEnd, yOffsetB);
|
||||
} else {
|
||||
Color color = waveCanvas.colors[WaveformColors.SIGNALX.ordinal()];
|
||||
int yOffset = yOffsetM;
|
||||
switch (((BitVector) left).getValue()[0]) {
|
||||
case '1':
|
||||
color = waveCanvas.colors[WaveformColors.SIGNAL1.ordinal()];
|
||||
yOffset = yOffsetT;
|
||||
break;
|
||||
case '0':
|
||||
color = waveCanvas.colors[WaveformColors.SIGNAL0.ordinal()];
|
||||
yOffset = yOffsetB;
|
||||
break;
|
||||
case 'Z':
|
||||
color = waveCanvas.colors[WaveformColors.SIGNALZ.ordinal()];
|
||||
break;
|
||||
default:
|
||||
}
|
||||
gc.setForeground(color);
|
||||
if (xEnd > maxPosX) {
|
||||
gc.drawLine(xBegin, yOffset, maxPosX, yOffset);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffset, xEnd, yOffset);
|
||||
int yNext = yOffsetM;
|
||||
switch (((BitVector) right).getValue()[0]) {
|
||||
case '1':
|
||||
yNext = yOffsetT;
|
||||
break;
|
||||
case '0':
|
||||
yNext = yOffsetB;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
if (yOffset != yNext)
|
||||
gc.drawLine(xEnd, yOffset, xEnd, yNext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private class RealStencil implements SignalStencil {
|
||||
|
||||
double minVal, range;
|
||||
|
||||
final double scaleFactor = 1.05;
|
||||
|
||||
boolean continous=true;
|
||||
|
||||
public RealStencil(NavigableMap<Long, ?> entries, Object left, boolean continous) {
|
||||
this.continous=continous;
|
||||
Collection<?> values = ((NavigableMap<Long, ?>) entries).values();
|
||||
minVal=(Double) left;
|
||||
range=2.0;
|
||||
if(!values.isEmpty()) {
|
||||
double maxVal=minVal;
|
||||
for (Object e : entries.values()) {
|
||||
double v = ((Double)e);
|
||||
if(Double.isNaN(maxVal))
|
||||
maxVal=v;
|
||||
else if(!Double.isNaN(v))
|
||||
maxVal=Math.max(maxVal, v);
|
||||
if(Double.isNaN(minVal))
|
||||
minVal=v;
|
||||
else if(!Double.isNaN(v))
|
||||
minVal=Math.min(minVal, v);
|
||||
}
|
||||
if(Double.isNaN(maxVal)){
|
||||
maxVal=minVal=0.0;
|
||||
}
|
||||
range = (maxVal-minVal)*scaleFactor;
|
||||
double avg = (maxVal+minVal)/2.0;
|
||||
minVal=avg-(avg-minVal)*scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple) {
|
||||
double leftVal = (Double) left;
|
||||
double rightVal= (Double) right;
|
||||
if(Double.isNaN(leftVal)) {
|
||||
Color color = waveCanvas.colors[WaveformColors.SIGNAL_NAN.ordinal()];
|
||||
int width = xEnd - xBegin;
|
||||
if (width > 1) {
|
||||
int[] points = {
|
||||
xBegin, yOffsetT,
|
||||
xEnd, yOffsetT,
|
||||
xEnd, yOffsetB,
|
||||
xBegin, yOffsetB
|
||||
};
|
||||
gc.setForeground(color);
|
||||
gc.drawPolygon(points);
|
||||
gc.setBackground(color);
|
||||
gc.fillPolygon(points);
|
||||
} else {
|
||||
gc.setForeground(color);
|
||||
gc.drawLine(xEnd, yOffsetT, xEnd, yOffsetB);
|
||||
}
|
||||
} else {
|
||||
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_REAL.ordinal()]);
|
||||
int yOffsetLeft = (int) ((leftVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
int yOffsetRight = Double.isNaN(rightVal)?yOffsetLeft:(int) ((rightVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
if(continous) {
|
||||
if (xEnd > maxPosX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetRight);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
} else {
|
||||
if (xEnd > maxPosX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetLeft);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetLeft);
|
||||
if(yOffsetRight!=yOffsetLeft) {
|
||||
gc.drawLine(xEnd, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,6 +44,20 @@ public class StreamPainter extends TrackPainter{
|
||||
this.stream=trackEntry.getStream();
|
||||
this.seenTx=new TreeSet<ITx>();
|
||||
}
|
||||
|
||||
/*
|
||||
* convert java.awt.Color to org.eclipse.swt.graphics.Color
|
||||
*/
|
||||
static org.eclipse.swt.graphics.Color toSwtColor( GC gc, java.awt.Color awtColor ){
|
||||
return new org.eclipse.swt.graphics.Color( gc.getDevice(), awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue() );
|
||||
}
|
||||
|
||||
static org.eclipse.swt.graphics.Color[] toSwtColors( GC gc, java.awt.Color[] awtColors ){
|
||||
org.eclipse.swt.graphics.Color[] swtColors = new org.eclipse.swt.graphics.Color[awtColors.length];
|
||||
for( int i=0; i<awtColors.length; i++ )
|
||||
swtColors[i] = toSwtColor( gc, awtColors[i] );
|
||||
return swtColors;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void paintArea(GC gc, Rectangle area) {
|
||||
@ -51,58 +65,73 @@ public class StreamPainter extends TrackPainter{
|
||||
int trackHeight=trackEntry.height/stream.getMaxConcurrency();
|
||||
txBase=trackHeight/5;
|
||||
txHeight=trackHeight*3/5;
|
||||
if(trackEntry.selected)
|
||||
if(trackEntry.selected) {
|
||||
gc.setBackground(this.waveCanvas.colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()]);
|
||||
}
|
||||
else
|
||||
gc.setBackground(this.waveCanvas.colors[even?WaveformColors.TRACK_BG_EVEN.ordinal():WaveformColors.TRACK_BG_ODD.ordinal()]);
|
||||
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
||||
gc.fillRectangle(area);
|
||||
Entry<Long, ?> firstTx=stream.getEvents().floorEntry(area.x*waveCanvas.getScaleFactor());
|
||||
Entry<Long, ?> lastTx=stream.getEvents().ceilingEntry((area.x+area.width)*waveCanvas.getScaleFactor());
|
||||
|
||||
long scaleFactor = this.waveCanvas.getScaleFactor();
|
||||
long beginPos = area.x;
|
||||
long beginTime = (beginPos + waveCanvas.getXOffset())*scaleFactor;
|
||||
//long endPos = beginPos + area.width;
|
||||
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();
|
||||
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
||||
gc.setLineStyle(SWT.LINE_SOLID);
|
||||
gc.setLineWidth(1);
|
||||
gc.setForeground(this.waveCanvas.colors[WaveformColors.LINE.ordinal()]);
|
||||
for(int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight)
|
||||
|
||||
for( int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight)
|
||||
gc.drawLine(area.x, y1, area.x+area.width, y1);
|
||||
if(firstTx==lastTx)
|
||||
if(firstTx==lastTx) {
|
||||
for(ITxEvent txEvent:(Collection<? extends ITxEvent>)firstTx.getValue())
|
||||
drawTx(gc, area, txEvent.getTransaction());
|
||||
else{
|
||||
drawTx(gc, area, txEvent.getTransaction(), false);
|
||||
}else{
|
||||
seenTx.clear();
|
||||
NavigableMap<Long,?> entries = stream.getEvents().subMap(firstTx.getKey(), true, lastTx.getKey(), true);
|
||||
boolean highlighed=false;
|
||||
gc.setForeground(this.waveCanvas.colors[WaveformColors.LINE.ordinal()]);
|
||||
gc.setBackground(this.waveCanvas.colors[WaveformColors.TX_BG.ordinal()]);
|
||||
for(Entry<Long, ?> entry: entries.entrySet())
|
||||
|
||||
for(Entry<Long, ?> entry: entries.entrySet())
|
||||
for(ITxEvent txEvent:(Collection<? extends ITxEvent>)entry.getValue()){
|
||||
if(txEvent.getType()==ITxEvent.Type.BEGIN)
|
||||
seenTx.add(txEvent.getTransaction());
|
||||
if(txEvent.getType()==ITxEvent.Type.END){
|
||||
ITx tx = txEvent.getTransaction();
|
||||
highlighed|=waveCanvas.currentSelection!=null && waveCanvas.currentSelection.equals(tx);
|
||||
drawTx(gc, area, tx);
|
||||
drawTx(gc, area, tx, false);
|
||||
seenTx.remove(tx);
|
||||
}
|
||||
}
|
||||
for(ITx tx:seenTx){
|
||||
drawTx(gc, area, tx);
|
||||
drawTx(gc, area, tx, false);
|
||||
}
|
||||
if(highlighed){
|
||||
gc.setForeground(this.waveCanvas.colors[WaveformColors.LINE_HIGHLITE.ordinal()]);
|
||||
gc.setBackground(this.waveCanvas.colors[WaveformColors.TX_BG_HIGHLITE.ordinal()]);
|
||||
drawTx(gc, area, waveCanvas.currentSelection);
|
||||
drawTx(gc, area, waveCanvas.currentSelection, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawTx(GC gc, Rectangle area, ITx tx) {
|
||||
|
||||
protected void drawTx(GC gc, Rectangle area, ITx tx, boolean highlighted ) {
|
||||
// compute colors
|
||||
java.awt.Color[] fallbackColors = trackEntry.getColors();
|
||||
java.awt.Color[] transColor = TrackEntry.computeColor( tx.getGenerator().getName(), fallbackColors[0], fallbackColors[1] );
|
||||
|
||||
gc.setBackground( toSwtColor( gc, transColor[highlighted?1:0] ) );
|
||||
|
||||
int offset = tx.getConcurrencyIndex()*this.waveCanvas.getTrackHeight();
|
||||
Rectangle bb = new Rectangle(
|
||||
(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()), area.y+offset+txBase,
|
||||
(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()-waveCanvas.getXOffset()), area.y+offset+txBase,
|
||||
(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScaleFactor()), txHeight);
|
||||
|
||||
if(bb.x+bb.width<area.x || bb.x>area.x+area.width) return;
|
||||
if(bb.width==0){
|
||||
gc.drawLine(bb.x, bb.y, bb.x, bb.y+bb.height);
|
||||
@ -110,7 +139,17 @@ public class StreamPainter extends TrackPainter{
|
||||
gc.fillRectangle(bb);
|
||||
gc.drawRectangle(bb);
|
||||
} else {
|
||||
gc.fillRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
|
||||
if(bb.x < area.x) {
|
||||
bb.width = bb.width-(area.x-bb.x)+5;
|
||||
bb.x=area.x-5;
|
||||
}
|
||||
int bb_x2 = bb.x+bb.width;
|
||||
int area_x2 = area.x+area.width;
|
||||
if(bb_x2>area_x2){
|
||||
bb_x2=area_x2+5;
|
||||
bb.width= bb_x2-bb.x;
|
||||
}
|
||||
gc.fillRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
|
||||
gc.drawRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,13 @@ import org.eclipse.wb.swt.SWTResourceManager;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.minres.scviewer.database.ITx;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.swt.Constants;
|
||||
import com.minres.scviewer.database.ui.IWaveformViewer;
|
||||
import com.minres.scviewer.database.ui.TrackEntry;
|
||||
import com.minres.scviewer.database.ui.WaveformColors;
|
||||
|
||||
public class WaveformCanvas extends Canvas {
|
||||
public class WaveformCanvas extends Canvas{
|
||||
|
||||
Color[] colors = new Color[WaveformColors.values().length];
|
||||
|
||||
@ -55,11 +56,7 @@ public class WaveformCanvas extends Canvas {
|
||||
String unit="ns";
|
||||
|
||||
private int level = 12;
|
||||
|
||||
public final static String[] unitString={"fs", "ps", "ns", "µs", "ms"};//, "s"};
|
||||
|
||||
public final static int[] unitMultiplier={1, 3, 10, 30, 100, 300};
|
||||
|
||||
|
||||
private long maxTime;
|
||||
|
||||
protected Point origin; /* original size */
|
||||
@ -82,18 +79,18 @@ public class WaveformCanvas extends Canvas {
|
||||
|
||||
private List<CursorPainter> cursorPainters;
|
||||
|
||||
HashMap<IWaveform<?>, IWaveformPainter> wave2painterMap;
|
||||
HashMap<IWaveform, IWaveformPainter> wave2painterMap;
|
||||
/**
|
||||
* Constructor for ScrollableCanvas.
|
||||
*
|
||||
* @param parent
|
||||
* the parent of this control.
|
||||
* the parent of this control.super(parent, style | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL);
|
||||
* @param style
|
||||
* the style of this control.
|
||||
*/
|
||||
public WaveformCanvas(final Composite parent, int style) {
|
||||
super(parent, style | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL);
|
||||
addControlListener(new ControlAdapter() { /* resize listener. */
|
||||
addControlListener(new ControlAdapter() { /* resize listener. */
|
||||
public void controlResized(ControlEvent event) {
|
||||
syncScrollBars();
|
||||
}
|
||||
@ -126,8 +123,37 @@ public class WaveformCanvas extends Canvas {
|
||||
painterList.add(marker);
|
||||
cursorPainters.add(marker);
|
||||
wave2painterMap=new HashMap<>();
|
||||
}
|
||||
// fall back initialization
|
||||
colors[WaveformColors.LINE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||
colors[WaveformColors.LINE_HIGHLITE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_CYAN);
|
||||
colors[WaveformColors.TRACK_BG_EVEN.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_BLACK);
|
||||
colors[WaveformColors.TRACK_BG_ODD.ordinal()] = SWTResourceManager.getColor(40, 40, 40);
|
||||
colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()] = SWTResourceManager.getColor(40, 40, 80);
|
||||
colors[WaveformColors.TX_BG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GREEN);
|
||||
colors[WaveformColors.TX_BG_HIGHLITE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
||||
colors[WaveformColors.TX_BORDER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||
colors[WaveformColors.SIGNAL0.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GREEN);
|
||||
colors[WaveformColors.SIGNAL1.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GREEN);
|
||||
colors[WaveformColors.SIGNALZ.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_YELLOW);
|
||||
colors[WaveformColors.SIGNALX.ordinal()] = SWTResourceManager.getColor(255, 51, 51);
|
||||
colors[WaveformColors.SIGNALU.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_YELLOW);
|
||||
colors[WaveformColors.SIGNAL_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
|
||||
colors[WaveformColors.SIGNAL_REAL.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_YELLOW);
|
||||
colors[WaveformColors.SIGNAL_NAN.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||
colors[WaveformColors.CURSOR.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||
colors[WaveformColors.CURSOR_DRAG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY);
|
||||
colors[WaveformColors.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
|
||||
colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY);
|
||||
colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
|
||||
colors[WaveformColors.REL_ARROW.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_MAGENTA);
|
||||
colors[WaveformColors.REL_ARROW_HIGHLITE.ordinal()] = SWTResourceManager.getColor(255, 128, 255);
|
||||
|
||||
}
|
||||
|
||||
public long getXOffset() {
|
||||
return -origin.x;
|
||||
}
|
||||
|
||||
public void addCursoPainter(CursorPainter cursorPainter){
|
||||
painterList.add(cursorPainter);
|
||||
cursorPainters.add(cursorPainter);
|
||||
@ -137,32 +163,10 @@ public class WaveformCanvas extends Canvas {
|
||||
Display d = getDisplay();
|
||||
if (colourMap != null) {
|
||||
for (WaveformColors c : WaveformColors.values()) {
|
||||
if (colourMap.containsKey(c)) {
|
||||
if (colourMap.containsKey(c))
|
||||
colors[c.ordinal()] = new Color(d, colourMap.get(c));
|
||||
}
|
||||
}
|
||||
redraw();
|
||||
} else {
|
||||
colors[WaveformColors.LINE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||
colors[WaveformColors.LINE_HIGHLITE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_CYAN);
|
||||
colors[WaveformColors.TRACK_BG_EVEN.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_BLACK);
|
||||
colors[WaveformColors.TRACK_BG_ODD.ordinal()] = SWTResourceManager.getColor(40, 40, 40);
|
||||
colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()] = SWTResourceManager.getColor(40, 40, 80);
|
||||
colors[WaveformColors.TX_BG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GREEN);
|
||||
colors[WaveformColors.TX_BG_HIGHLITE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
||||
colors[WaveformColors.TX_BORDER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||
colors[WaveformColors.SIGNAL0.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
||||
colors[WaveformColors.SIGNAL1.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
||||
colors[WaveformColors.SIGNALZ.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY);
|
||||
colors[WaveformColors.SIGNALX.ordinal()] = SWTResourceManager.getColor(255, 128, 182);
|
||||
colors[WaveformColors.SIGNAL_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
|
||||
colors[WaveformColors.CURSOR.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||
colors[WaveformColors.CURSOR_DRAG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY);
|
||||
colors[WaveformColors.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
|
||||
colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY);
|
||||
colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
|
||||
colors[WaveformColors.REL_ARROW.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_MAGENTA);
|
||||
colors[WaveformColors.REL_ARROW_HIGHLITE.ordinal()] = SWTResourceManager.getColor(255, 128, 255);
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,6 +182,9 @@ public class WaveformCanvas extends Canvas {
|
||||
return origin;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return getClientArea().width;
|
||||
}
|
||||
public void setOrigin(Point origin) {
|
||||
setOrigin(origin.x, origin.y);
|
||||
}
|
||||
@ -218,20 +225,37 @@ public class WaveformCanvas extends Canvas {
|
||||
}
|
||||
|
||||
public int getMaxZoomLevel(){
|
||||
return unitMultiplier.length*unitString.length-1;
|
||||
return Constants.unitMultiplier.length*Constants.unitString.length-1;
|
||||
}
|
||||
|
||||
public void setZoomLevel(int level) {
|
||||
if(level<unitMultiplier.length*unitString.length){
|
||||
long oldScaleFactor=scaleFactor;
|
||||
if(level<Constants.unitMultiplier.length*Constants.unitString.length){
|
||||
this.level = level;
|
||||
this.scaleFactor = (long) Math.pow(10, level/2);
|
||||
if(level%2==1) this.scaleFactor*=3;
|
||||
ITx tx = arrowPainter.getTx();
|
||||
arrowPainter.setTx(null);
|
||||
/*
|
||||
* xc = tc/oldScaleFactor
|
||||
* xoffs = xc+origin.x
|
||||
* xcn = tc/newScaleFactor
|
||||
* t0n = (xcn-xoffs)*scaleFactor
|
||||
*/
|
||||
long tc=cursorPainters.get(0).getTime(); // cursor time
|
||||
long xc=tc/oldScaleFactor; // cursor total x-offset
|
||||
long xoffs=xc+origin.x; // cursor offset relative to left border
|
||||
long xcn=tc/scaleFactor; // new total x-offset
|
||||
long originX=xcn-xoffs;
|
||||
if(originX>0) {
|
||||
origin.x=(int) -originX; // new cursor time offset relative to left border
|
||||
}else {
|
||||
origin.x=0;
|
||||
}
|
||||
syncScrollBars();
|
||||
arrowPainter.setTx(tx);
|
||||
arrowPainter.setTx(tx);
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getScaleFactor() {
|
||||
@ -239,17 +263,17 @@ public class WaveformCanvas extends Canvas {
|
||||
}
|
||||
|
||||
public long getScaleFactorPow10() {
|
||||
int scale = level/unitMultiplier.length;
|
||||
int scale = level/Constants.unitMultiplier.length;
|
||||
double res = Math.pow(1000, scale);
|
||||
return (long) res;
|
||||
}
|
||||
|
||||
public String getUnitStr(){
|
||||
return unitString[level/unitMultiplier.length];
|
||||
return Constants.unitString[level/Constants.unitMultiplier.length];
|
||||
}
|
||||
|
||||
public int getUnitMultiplier(){
|
||||
return unitMultiplier[level%unitMultiplier.length];
|
||||
return Constants.unitMultiplier[level%Constants.unitMultiplier.length];
|
||||
}
|
||||
|
||||
public long getTimeForOffset(int xOffset){
|
||||
@ -267,15 +291,23 @@ public class WaveformCanvas extends Canvas {
|
||||
}
|
||||
|
||||
public void clearAllWaveformPainter() {
|
||||
clearAllWaveformPainter(true);
|
||||
}
|
||||
|
||||
void clearAllWaveformPainter(boolean update) {
|
||||
trackAreaPainter.getTrackVerticalOffset().clear();
|
||||
wave2painterMap.clear();
|
||||
syncScrollBars();
|
||||
if(update) syncScrollBars();
|
||||
}
|
||||
|
||||
public void addWaveformPainter(IWaveformPainter painter) {
|
||||
addWaveformPainter(painter, true);
|
||||
}
|
||||
|
||||
void addWaveformPainter(IWaveformPainter painter, boolean update) {
|
||||
trackAreaPainter.addTrackPainter(painter);
|
||||
wave2painterMap.put(painter.getTrackEntry().waveform, painter);
|
||||
syncScrollBars();
|
||||
if(update) syncScrollBars();
|
||||
}
|
||||
|
||||
public List<CursorPainter> getCursorPainters() {
|
||||
@ -292,7 +324,7 @@ public class WaveformCanvas extends Canvas {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/* Initalize the scrollbar and register listeners. */
|
||||
/* Initialize the scrollbar and register listeners. */
|
||||
private void initScrollBars() {
|
||||
ScrollBar horizontal = getHorizontalBar();
|
||||
horizontal.setEnabled(false);
|
||||
@ -326,38 +358,43 @@ public class WaveformCanvas extends Canvas {
|
||||
redraw();
|
||||
return;
|
||||
}
|
||||
int height = trackAreaPainter.getHeight();
|
||||
int width = (int) (maxTime / scaleFactor);
|
||||
int height = trackAreaPainter.getHeight(); // incl. Ruler
|
||||
long width = maxTime / scaleFactor;
|
||||
Rectangle clientArea=getClientArea();
|
||||
ScrollBar horizontal = getHorizontalBar();
|
||||
horizontal.setIncrement((int) (getClientArea().width / 100));
|
||||
horizontal.setPageIncrement(getClientArea().width);
|
||||
int cw = getClientArea().width;
|
||||
if (width > cw) { /* image is wider than client area */
|
||||
horizontal.setMaximum(width);
|
||||
int clientWidthw = clientArea.width;
|
||||
if (width > clientWidthw) { /* image is wider than client area */
|
||||
horizontal.setMinimum(0);
|
||||
horizontal.setMaximum((int)width);
|
||||
horizontal.setEnabled(true);
|
||||
if (((int) -origin.x) > horizontal.getMaximum() - cw)
|
||||
origin.x = -horizontal.getMaximum() + cw;
|
||||
if (((int) -origin.x) > horizontal.getMaximum() - clientWidthw) {
|
||||
origin.x = -horizontal.getMaximum() + clientWidthw;
|
||||
}
|
||||
} else { /* image is narrower than client area */
|
||||
horizontal.setEnabled(false);
|
||||
}
|
||||
horizontal.setThumb(clientWidthw);
|
||||
horizontal.setSelection(-origin.x);
|
||||
horizontal.setThumb(cw);
|
||||
|
||||
ScrollBar vertical = getVerticalBar();
|
||||
vertical.setIncrement((int) (getClientArea().height / 100));
|
||||
vertical.setPageIncrement((int) (getClientArea().height));
|
||||
int ch = getClientArea().height;
|
||||
if (height > ch) { /* image is higher than client area */
|
||||
int clientHeighth = clientArea.height;
|
||||
if (height > clientHeighth) { /* image is higher than client area */
|
||||
vertical.setMinimum(0);
|
||||
vertical.setMaximum(height);
|
||||
vertical.setEnabled(true);
|
||||
if (((int) -origin.y) > vertical.getMaximum() - ch)
|
||||
origin.y = -vertical.getMaximum() + ch;
|
||||
if (((int) -origin.y) > vertical.getMaximum() - clientHeighth) {
|
||||
origin.y = -vertical.getMaximum() + clientHeighth;
|
||||
}
|
||||
} else { /* image is less higher than client area */
|
||||
vertical.setMaximum((int) (ch));
|
||||
vertical.setMaximum((int) (clientHeighth));
|
||||
vertical.setEnabled(false);
|
||||
}
|
||||
vertical.setThumb(clientHeighth);
|
||||
vertical.setSelection(-origin.y);
|
||||
vertical.setThumb(ch);
|
||||
redraw();
|
||||
fireSelectionEvent();
|
||||
|
||||
@ -366,12 +403,13 @@ public class WaveformCanvas extends Canvas {
|
||||
/* Paint function */
|
||||
private void paint(GC gc) {
|
||||
Rectangle clientRect = getClientArea(); /* Canvas' painting area */
|
||||
clientRect.x = -origin.x;
|
||||
// clientRect.x = -origin.x;
|
||||
clientRect.y = -origin.y;
|
||||
// reset the transform
|
||||
transform.identity();
|
||||
// shift the content
|
||||
transform.translate(origin.x, origin.y);
|
||||
// DO NOT SHIFT HORIZONTALLY, the range is WAY TOO BIG for float!!!
|
||||
transform.translate(0, origin.y);
|
||||
gc.setTransform(transform);
|
||||
gc.setClipping(clientRect);
|
||||
if (painterList.size() > 0 ) {
|
||||
@ -407,7 +445,7 @@ public class WaveformCanvas extends Canvas {
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<Object> getEntriesAtPosition(IWaveform<? extends IWaveformEvent> iWaveform, int i) {
|
||||
public List<Object> getEntriesAtPosition(IWaveform iWaveform, int i) {
|
||||
LinkedList<Object> result=new LinkedList<>();
|
||||
int x = i - origin.x;
|
||||
for(IPainter p: wave2painterMap.values()){
|
||||
@ -450,6 +488,27 @@ public class WaveformCanvas extends Canvas {
|
||||
}
|
||||
}
|
||||
|
||||
public void reveal(IWaveform waveform) {
|
||||
for (IWaveformPainter painter : wave2painterMap.values()) {
|
||||
TrackEntry te = painter.getTrackEntry();
|
||||
if(te.waveform == waveform) {
|
||||
Point size = getSize();
|
||||
//size.x -= getVerticalBar().getSize().x + 2;
|
||||
size.y -=+rulerHeight;
|
||||
ScrollBar sb = getHorizontalBar();
|
||||
if((sb.getStyle()&SWT.SCROLLBAR_OVERLAY)!=0 && sb.isVisible()) // TODO: check on other platform than MacOSX
|
||||
size.y-= getHorizontalBar().getSize().y;
|
||||
int top = te.vOffset;
|
||||
int bottom = top + trackHeight;
|
||||
if (top < -origin.y) {
|
||||
setOrigin(origin.x, -(top-trackHeight));
|
||||
} else if (bottom > (size.y - origin.y)) {
|
||||
setOrigin(origin.x, size.y - bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void reveal(long time) {
|
||||
int scaledTime = (int) (time / scaleFactor);
|
||||
Point size = getSize();
|
||||
@ -494,4 +553,11 @@ public class WaveformCanvas extends Canvas {
|
||||
}
|
||||
}
|
||||
|
||||
long getMaxVisibleTime() {
|
||||
return (getClientArea().width+origin.x)*scaleFactor;
|
||||
}
|
||||
|
||||
long getOriginTime() {
|
||||
return origin.x * scaleFactor;
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,11 @@
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.swt.internal;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -20,6 +22,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.eclipse.core.runtime.ListenerList;
|
||||
@ -65,20 +68,19 @@ import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.ScrollBar;
|
||||
import org.eclipse.swt.widgets.Widget;
|
||||
import org.eclipse.wb.swt.SWTResourceManager;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.minres.scviewer.database.BitVector;
|
||||
import com.minres.scviewer.database.ISignal;
|
||||
import com.minres.scviewer.database.ISignalChange;
|
||||
import com.minres.scviewer.database.ISignalChangeMulti;
|
||||
import com.minres.scviewer.database.ISignalChangeSingle;
|
||||
import com.minres.scviewer.database.ITx;
|
||||
import com.minres.scviewer.database.ITxEvent;
|
||||
import com.minres.scviewer.database.ITxRelation;
|
||||
import com.minres.scviewer.database.ITxStream;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.swt.Constants;
|
||||
import com.minres.scviewer.database.ui.GotoDirection;
|
||||
import com.minres.scviewer.database.ui.ICursor;
|
||||
import com.minres.scviewer.database.ui.IWaveformViewer;
|
||||
@ -87,10 +89,12 @@ import com.minres.scviewer.database.ui.WaveformColors;
|
||||
|
||||
public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
private ListenerList selectionChangedListeners = new ListenerList();
|
||||
private ListenerList<ISelectionChangedListener> selectionChangedListeners = new ListenerList<ISelectionChangedListener>();
|
||||
|
||||
private PropertyChangeSupport pcs;
|
||||
|
||||
static final DecimalFormat df = new DecimalFormat("#.00####");
|
||||
|
||||
private ITx currentTxSelection;
|
||||
|
||||
private TrackEntry currentWaveformSelection;
|
||||
@ -101,12 +105,14 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
private Control namePaneHeader;
|
||||
|
||||
private Canvas nameList;
|
||||
final private Canvas nameList;
|
||||
|
||||
private Canvas valueList;
|
||||
final private Canvas valueList;
|
||||
|
||||
WaveformCanvas waveformCanvas;
|
||||
final WaveformCanvas waveformCanvas;
|
||||
|
||||
private boolean revealSelected=false;
|
||||
|
||||
private Composite top;
|
||||
|
||||
protected ObservableList<TrackEntry> streams;
|
||||
@ -117,19 +123,16 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
private TreeMap<Integer, TrackEntry> trackVerticalOffset;
|
||||
|
||||
private HashMap<IWaveform<? extends IWaveformEvent>, String> actualValues;
|
||||
|
||||
private Font nameFont, nameFontB;
|
||||
|
||||
protected MouseListener nameValueMouseListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseDown(MouseEvent e) {
|
||||
if ((e.button == 1 || e.button == 3)) {
|
||||
if (e.button == 1) {
|
||||
Entry<Integer, TrackEntry> entry = trackVerticalOffset.floorEntry(e.y);
|
||||
if (entry != null)
|
||||
setSelection(new StructuredSelection(entry.getValue()));
|
||||
}
|
||||
if (e.button == 3) {
|
||||
} else if (e.button == 3) {
|
||||
Menu topMenu= top.getMenu();
|
||||
if(topMenu!=null) topMenu.setVisible(true);
|
||||
}
|
||||
@ -143,12 +146,10 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
@Override
|
||||
public void mouseDown(MouseEvent e) {
|
||||
start=new Point(e.x, e.y);
|
||||
if((e.stateMask&SWT.MODIFIER_MASK)!=0) return; //don't react on modifier
|
||||
if (e.button == 1) {
|
||||
initialSelected = waveformCanvas.getClicked(start);
|
||||
} else if (e.button == 3) {
|
||||
List<Object> hitted = waveformCanvas.getClicked(start);
|
||||
if(hitted!=null && hitted.size()>0)
|
||||
setSelection(new StructuredSelection(hitted));
|
||||
Menu topMenu= top.getMenu();
|
||||
if(topMenu!=null) topMenu.setVisible(true);
|
||||
}
|
||||
@ -156,29 +157,18 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
@Override
|
||||
public void mouseUp(MouseEvent e) {
|
||||
if (e.button == 1) {
|
||||
if((e.stateMask&SWT.MODIFIER_MASK&~SWT.SHIFT)!=0) return; //don't react on modifier
|
||||
if (e.button == 1 && ((e.stateMask&SWT.SHIFT)==0)) {
|
||||
if(Math.abs(e.x-start.x)<3 && Math.abs(e.y-start.y)<3){
|
||||
// first set time
|
||||
// first set cursor time
|
||||
setCursorTime(snapOffsetToEvent(e));
|
||||
// then set selection and reveal
|
||||
setSelection(new StructuredSelection(initialSelected));
|
||||
e.widget.getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
waveformCanvas.redraw();
|
||||
updateValueList();
|
||||
}
|
||||
});
|
||||
asyncUpdate(e.widget);
|
||||
}
|
||||
}else if (e.button == 2) {
|
||||
}else if (e.button == 2 ||(e.button==1 && (e.stateMask&SWT.SHIFT)!=0)) {
|
||||
setMarkerTime(snapOffsetToEvent(e), selectedMarker);
|
||||
e.widget.getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
waveformCanvas.redraw();
|
||||
updateValueList();
|
||||
}
|
||||
});
|
||||
asyncUpdate(e.widget);
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,20 +214,19 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
trackVerticalOffset = new TreeMap<Integer, TrackEntry>();
|
||||
trackVerticalHeight=0;
|
||||
actualValues = new HashMap<IWaveform<? extends IWaveformEvent>, String>();
|
||||
|
||||
nameFont = parent.getDisplay().getSystemFont();
|
||||
nameFontB = SWTResourceManager.getBoldFont(nameFont);
|
||||
|
||||
streams = new ObservableList<>();
|
||||
streams.addPropertyChangeListener(this);
|
||||
streams.addPropertyChangeListener("content", this);
|
||||
|
||||
top = new Composite(parent, SWT.NONE);
|
||||
top.setLayout(new FillLayout(SWT.HORIZONTAL));
|
||||
|
||||
SashForm topSash = new SashForm(top, SWT.SMOOTH);
|
||||
topSash.setBackground(topSash.getDisplay().getSystemColor(SWT.COLOR_GRAY));
|
||||
|
||||
|
||||
Composite composite = new Composite(topSash, SWT.NONE);
|
||||
composite.setLayout(new FillLayout(SWT.HORIZONTAL));
|
||||
|
||||
@ -272,9 +261,11 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
nameList.addListener(SWT.Paint, new Listener() {
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
GC gc = event.gc;
|
||||
Rectangle rect = ((Canvas) event.widget).getClientArea();
|
||||
paintNames(gc, rect);
|
||||
if(!trackVerticalOffset.isEmpty()) {
|
||||
GC gc = event.gc;
|
||||
Rectangle rect = ((Canvas) event.widget).getClientArea();
|
||||
paintNames(gc, rect);
|
||||
}
|
||||
}
|
||||
});
|
||||
nameList.addMouseListener(nameValueMouseListener);
|
||||
@ -304,17 +295,19 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
valueList.addListener(SWT.Paint, new Listener() {
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
GC gc = event.gc;
|
||||
Rectangle rect = ((Canvas) event.widget).getClientArea();
|
||||
paintValues(gc, rect);
|
||||
if(!trackVerticalOffset.isEmpty()) {
|
||||
GC gc = event.gc;
|
||||
Rectangle rect = ((Canvas) event.widget).getClientArea();
|
||||
paintValues(gc, rect);
|
||||
}
|
||||
}
|
||||
});
|
||||
valueList.addMouseListener(nameValueMouseListener);
|
||||
valueListScrolled.setContent(valueList);
|
||||
|
||||
waveformCanvas.setMaxTime(1);
|
||||
waveformCanvas.setMaxTime(1);
|
||||
waveformCanvas.addMouseListener(waveformMouseListener);
|
||||
|
||||
|
||||
nameListScrolled.getVerticalBar().addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
int y = ((ScrollBar) e.widget).getSelection();
|
||||
@ -376,23 +369,33 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent pce) {
|
||||
if ("size".equals(pce.getPropertyName()) || "content".equals(pce.getPropertyName())) {
|
||||
waveformCanvas.getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateTracklist();
|
||||
}
|
||||
});
|
||||
if(revealSelected) {
|
||||
waveformCanvas.getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
update();
|
||||
waveformCanvas.reveal(currentWaveformSelection.waveform);
|
||||
valueList.redraw();
|
||||
nameList.redraw();
|
||||
}
|
||||
});
|
||||
revealSelected=false;
|
||||
} else
|
||||
waveformCanvas.getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
update();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateTracklist() {
|
||||
public void update() {
|
||||
trackVerticalHeight = 0;
|
||||
int nameMaxWidth = 0;
|
||||
int previousHeight = trackVerticalOffset.size() == 0 ? 0 : trackVerticalOffset.lastKey();
|
||||
IWaveformPainter painter = null;
|
||||
trackVerticalOffset.clear();
|
||||
actualValues.clear();
|
||||
waveformCanvas.clearAllWaveformPainter();
|
||||
waveformCanvas.clearAllWaveformPainter(false);
|
||||
boolean even = true;
|
||||
boolean clearSelection = true;
|
||||
TextLayout tl = new TextLayout(waveformCanvas.getDisplay());
|
||||
@ -402,47 +405,39 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
streamEntry.vOffset=trackVerticalHeight;
|
||||
clearSelection &= currentWaveformSelection!=null && (streamEntry.waveform != currentWaveformSelection.waveform);
|
||||
if (streamEntry.isStream()) {
|
||||
streamEntry.currentValue="";
|
||||
streamEntry.height *= streamEntry.getStream().getMaxConcurrency();
|
||||
painter = new StreamPainter(waveformCanvas, even, streamEntry);
|
||||
actualValues.put(streamEntry.waveform, "");
|
||||
} else if (streamEntry.isSignal()) {
|
||||
streamEntry.currentValue="---";
|
||||
painter = new SignalPainter(waveformCanvas, even, streamEntry);
|
||||
actualValues.put(streamEntry.waveform, "---");
|
||||
}
|
||||
waveformCanvas.addWaveformPainter(painter);
|
||||
waveformCanvas.addWaveformPainter(painter, false);
|
||||
trackVerticalOffset.put(trackVerticalHeight, streamEntry);
|
||||
tl.setText(streamEntry.waveform.getFullName());
|
||||
nameMaxWidth = Math.max(nameMaxWidth, tl.getBounds().width);
|
||||
trackVerticalHeight += streamEntry.height;
|
||||
even = !even;
|
||||
}
|
||||
waveformCanvas.syncScrollBars();
|
||||
nameList.setSize(nameMaxWidth + 15, trackVerticalHeight);
|
||||
nameListScrolled.setMinSize(nameMaxWidth + 15, trackVerticalHeight);
|
||||
valueList.setSize(calculateValueWidth(), trackVerticalHeight);
|
||||
valueListScrolled.setMinSize(calculateValueWidth(), trackVerticalHeight);
|
||||
nameList.redraw();
|
||||
updateValueList();
|
||||
waveformCanvas.redraw();
|
||||
top.layout(new Control[] { valueList, nameList, waveformCanvas });
|
||||
if (trackVerticalOffset.isEmpty()){
|
||||
waveformCanvas.setOrigin(0, 0);
|
||||
}else if(previousHeight > trackVerticalOffset.lastKey()){
|
||||
Point o = waveformCanvas.getOrigin();
|
||||
waveformCanvas.setOrigin(o.x, o.y - (previousHeight - trackVerticalOffset.lastKey()));
|
||||
}
|
||||
if(clearSelection) setSelection(new StructuredSelection());
|
||||
/* System.out.println("updateTracklist() state:");
|
||||
for(Entry<Integer, IWaveform<? extends IWaveformEvent>> entry: trackVerticalOffset.entrySet()){
|
||||
System.out.println(" "+entry.getKey()+": " +entry.getValue().getFullName());
|
||||
}
|
||||
*/ }
|
||||
}
|
||||
|
||||
private int calculateValueWidth() {
|
||||
TextLayout tl = new TextLayout(waveformCanvas.getDisplay());
|
||||
tl.setFont(nameFontB);
|
||||
int valueMaxWidth = 0;
|
||||
for (String v : actualValues.values()) {
|
||||
tl.setText(v);
|
||||
for (TrackEntry v : streams) {
|
||||
tl.setText(v.currentValue);
|
||||
valueMaxWidth = Math.max(valueMaxWidth, tl.getBounds().width);
|
||||
}
|
||||
return valueMaxWidth + 15;
|
||||
@ -450,16 +445,36 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
private void updateValueList(){
|
||||
final Long time = getCursorTime();
|
||||
for(Entry<IWaveform<? extends IWaveformEvent>, String> entry:actualValues.entrySet()){
|
||||
if(entry.getKey() instanceof ISignal){
|
||||
ISignalChange event = ((ISignal<?>)entry.getKey()).getWaveformEventsBeforeTime(time);
|
||||
if(event instanceof ISignalChangeSingle){
|
||||
entry.setValue("b'"+((ISignalChangeSingle)event).getValue());
|
||||
} else if(event instanceof ISignalChangeMulti){
|
||||
entry.setValue("h'"+((ISignalChangeMulti)event).getValue().toHexString());
|
||||
for(TrackEntry entry:streams){
|
||||
if(entry.isSignal()){
|
||||
ISignal<?> signal = (ISignal<?>) entry.waveform;
|
||||
Object value = signal.getWaveformValueBeforeTime(time);
|
||||
if(value instanceof BitVector){
|
||||
BitVector bv = (BitVector) value;
|
||||
if(bv.getWidth()==1)
|
||||
entry.currentValue="b'"+bv;
|
||||
else {
|
||||
// TODO: same code resides in SignalPainter, fix it
|
||||
switch(entry.valueDisplay) {
|
||||
case SIGNED:
|
||||
entry.currentValue=Long.toString(bv.toSignedValue());
|
||||
break;
|
||||
case UNSIGNED:
|
||||
entry.currentValue=Long.toString(bv.toUnsignedValue());
|
||||
break;
|
||||
default:
|
||||
entry.currentValue="h'"+bv.toHexString();
|
||||
}
|
||||
}
|
||||
} else if(value instanceof Double){
|
||||
Double val = (Double) value;
|
||||
if(val>0.001)
|
||||
entry.currentValue=String.format("%1$,.3f", val);
|
||||
else
|
||||
entry.currentValue=Double.toString(val);
|
||||
}
|
||||
} else if(entry.getKey() instanceof ITxStream<?>){
|
||||
ITxStream<?> stream = (ITxStream<?>) entry.getKey();
|
||||
} else if(entry.isStream()){
|
||||
ITxStream<?> stream = (ITxStream<?>) entry.waveform;
|
||||
ITx[] resultsList = new ITx[stream.getMaxConcurrency()];
|
||||
Entry<Long, List<ITxEvent>> firstTx=stream.getEvents().floorEntry(time);
|
||||
if(firstTx!=null){
|
||||
@ -471,23 +486,27 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
resultsList[tx.getConcurrencyIndex()]= evt.getTransaction();
|
||||
}
|
||||
}
|
||||
firstTx=stream.getEvents().lowerEntry(firstTx.getKey());
|
||||
firstTx=stream.getEvents().lowerEntry(firstTx.getKey());
|
||||
}while(firstTx!=null && !isArrayFull(resultsList));
|
||||
String value=null;
|
||||
entry.currentValue="";
|
||||
boolean separator=false;
|
||||
|
||||
for(ITx o:resultsList){
|
||||
if(value==null)
|
||||
value=new String();
|
||||
else
|
||||
value+="|";
|
||||
if(o!=null) value+=((ITx)o).getGenerator().getName();
|
||||
if(separator) entry.currentValue+="|";
|
||||
if(o!=null) entry.currentValue+=((ITx)o).getGenerator().getName();
|
||||
|
||||
separator=true;
|
||||
}
|
||||
entry.setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
valueList.redraw();
|
||||
int width = calculateValueWidth();
|
||||
valueList.setSize(width, trackVerticalHeight);
|
||||
valueListScrolled.setMinSize(width, trackVerticalHeight);
|
||||
valueListScrolled.redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean isArrayFull(Object[] array){
|
||||
for(Object o:array){
|
||||
if(o==null) return false;
|
||||
@ -548,11 +567,13 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
*/
|
||||
@Override
|
||||
public ISelection getSelection() {
|
||||
if (currentTxSelection != null)
|
||||
return new StructuredSelection(currentTxSelection);
|
||||
else if (currentWaveformSelection != null)
|
||||
return new StructuredSelection(currentWaveformSelection.waveform);
|
||||
else
|
||||
if (currentTxSelection != null) {
|
||||
Object[] elem = {currentTxSelection, currentWaveformSelection};
|
||||
return new StructuredSelection(elem);
|
||||
} else if (currentWaveformSelection != null) {
|
||||
Object[] elem = {currentWaveformSelection.waveform, currentWaveformSelection};
|
||||
return new StructuredSelection(elem);
|
||||
} else
|
||||
return new StructuredSelection();
|
||||
}
|
||||
|
||||
@ -583,6 +604,9 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
TrackEntry trackEntry = getEntryForStream(txSel.getStream());
|
||||
if(trackEntry==null && addIfNeeded){
|
||||
trackEntry=new TrackEntry(txSel.getStream());
|
||||
// compute fallback colors
|
||||
Color fallbackColors[] = TrackEntry.computeColor(txSel.getStream().getName(), TrackEntry.fallbackColor, TrackEntry.highlightedFallbackColor);
|
||||
trackEntry.setColor(fallbackColors[0], fallbackColors[1]);
|
||||
streams.add(trackEntry);
|
||||
}
|
||||
currentTxSelection = txSel;
|
||||
@ -592,6 +616,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
currentWaveformSelection = (TrackEntry) sel;
|
||||
if(currentTxSelection!=null && currentTxSelection.getStream()!=currentWaveformSelection)
|
||||
currentTxSelection=null;
|
||||
|
||||
selectionChanged = true;
|
||||
}
|
||||
}
|
||||
@ -604,6 +629,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
}
|
||||
if(currentWaveformSelection!=null) currentWaveformSelection.selected=true;
|
||||
if (selectionChanged) {
|
||||
if(currentWaveformSelection!=null) waveformCanvas.reveal(currentWaveformSelection.waveform);
|
||||
waveformCanvas.setSelected(currentTxSelection);
|
||||
valueList.redraw();
|
||||
nameList.redraw();
|
||||
@ -627,7 +653,16 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
*/
|
||||
@Override
|
||||
public void moveSelection(GotoDirection direction) {
|
||||
moveSelection(direction, NEXT_PREV_IN_STREAM) ;
|
||||
if(direction==GotoDirection.NEXT || direction==GotoDirection.PREV)
|
||||
moveSelection(direction, NEXT_PREV_IN_STREAM) ;
|
||||
else {
|
||||
int idx = streams.indexOf(currentWaveformSelection);
|
||||
if(direction==GotoDirection.UP && idx>0) {
|
||||
setSelection(new StructuredSelection(streams.get(idx-1)));
|
||||
} else if(direction==GotoDirection.DOWN && idx<(streams.size()-1)) {
|
||||
setSelection(new StructuredSelection(streams.get(idx+1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -723,10 +758,12 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
public void moveCursor(GotoDirection direction) {
|
||||
long time = getCursorTime();
|
||||
NavigableMap<Long, ?> map=null;
|
||||
if(currentWaveformSelection.isStream()){
|
||||
map=currentWaveformSelection.getStream().getEvents();
|
||||
} else if(currentWaveformSelection.isSignal()){
|
||||
map=currentWaveformSelection.getSignal().getEvents();
|
||||
if(currentWaveformSelection!=null) {
|
||||
if(currentWaveformSelection.isStream()){
|
||||
map=currentWaveformSelection.getStream().getEvents();
|
||||
} else if(currentWaveformSelection.isSignal()){
|
||||
map=currentWaveformSelection.getSignal().getEvents();
|
||||
}
|
||||
}
|
||||
if(map!=null){
|
||||
Entry<Long, ?> entry=direction==GotoDirection.PREV?map.lowerEntry(time):map.higherEntry(time);
|
||||
@ -735,6 +772,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
setCursorTime(time);
|
||||
waveformCanvas.reveal(time);
|
||||
waveformCanvas.redraw();
|
||||
updateValueList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -754,17 +792,21 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
@Override
|
||||
public void moveSelectedTrack(int i) {
|
||||
if(currentWaveformSelection!=null){
|
||||
ITx selectedTx=currentTxSelection;
|
||||
TrackEntry selectedWaveform=currentWaveformSelection;
|
||||
int idx = streams.indexOf(currentWaveformSelection);
|
||||
int newIdx=idx+i;
|
||||
if(newIdx>=0 && newIdx<streams.size()){
|
||||
Collections.swap(streams,idx,newIdx);
|
||||
updateTracklist();
|
||||
if(selectedTx!=null){
|
||||
setSelection(new StructuredSelection(new Object[]{selectedTx, selectedWaveform.waveform}));
|
||||
} else
|
||||
setSelection(new StructuredSelection(selectedWaveform.waveform));
|
||||
revealSelected=true;
|
||||
// update();
|
||||
// ITx selectedTx=currentTxSelection;
|
||||
// if(selectedTx!=null){
|
||||
// setSelection(new StructuredSelection(new Object[]{selectedTx, currentWaveformSelection.waveform}));
|
||||
// } else {
|
||||
// setSelection(new StructuredSelection(currentWaveformSelection.waveform));
|
||||
// }
|
||||
// waveformCanvas.reveal(currentWaveformSelection.waveform);
|
||||
// valueList.redraw();
|
||||
// nameList.redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -772,52 +814,56 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
protected void paintNames(GC gc, Rectangle rect) {
|
||||
if (streams.size() > 0) {
|
||||
Integer firstKey = trackVerticalOffset.floorKey(rect.y);
|
||||
if (firstKey == null)
|
||||
firstKey = trackVerticalOffset.firstKey();
|
||||
Integer lastKey = trackVerticalOffset.floorKey(rect.y + rect.height);
|
||||
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, waveformCanvas.getTrackHeight());
|
||||
if (lastKey == firstKey) {
|
||||
TrackEntry trackEntry=trackVerticalOffset.get(firstKey);
|
||||
IWaveform<? extends IWaveformEvent> w = trackEntry.waveform;
|
||||
if (w instanceof ITxStream<?>)
|
||||
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
|
||||
drawTextFormat(gc, subArea, firstKey, w.getFullName(), trackEntry.selected);
|
||||
} else {
|
||||
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true).entrySet()) {
|
||||
IWaveform<? extends IWaveformEvent> w = entry.getValue().waveform;
|
||||
subArea.height = waveformCanvas.getTrackHeight();
|
||||
try {
|
||||
Integer firstKey = trackVerticalOffset.floorKey(rect.y);
|
||||
if (firstKey == null)
|
||||
firstKey = trackVerticalOffset.firstKey();
|
||||
Integer lastKey = trackVerticalOffset.floorKey(rect.y + rect.height);
|
||||
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, waveformCanvas.getTrackHeight());
|
||||
if (lastKey == firstKey) {
|
||||
TrackEntry trackEntry=trackVerticalOffset.get(firstKey);
|
||||
IWaveform w = trackEntry.waveform;
|
||||
if (w instanceof ITxStream<?>)
|
||||
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
|
||||
drawTextFormat(gc, subArea, entry.getKey(), w.getFullName(), entry.getValue().selected);
|
||||
drawTextFormat(gc, subArea, firstKey, w.getFullName(), trackEntry.selected);
|
||||
} else {
|
||||
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true).entrySet()) {
|
||||
IWaveform w = entry.getValue().waveform;
|
||||
subArea.height = waveformCanvas.getTrackHeight();
|
||||
if (w instanceof ITxStream<?>)
|
||||
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
|
||||
drawTextFormat(gc, subArea, entry.getKey(), w.getFullName(), entry.getValue().selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(NoSuchElementException e){}
|
||||
}
|
||||
}
|
||||
|
||||
protected void paintValues(GC gc, Rectangle rect) {
|
||||
if (streams.size() > 0) {
|
||||
Integer firstKey = trackVerticalOffset.floorKey(rect.y);
|
||||
if (firstKey == null)
|
||||
firstKey = trackVerticalOffset.firstKey();
|
||||
Integer lastKey = trackVerticalOffset.floorKey(rect.y + rect.height);
|
||||
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, waveformCanvas.getTrackHeight());
|
||||
if (lastKey == firstKey) {
|
||||
TrackEntry trackEntry=trackVerticalOffset.get(firstKey);
|
||||
IWaveform<? extends IWaveformEvent> w = trackEntry.waveform;
|
||||
if (w instanceof ITxStream<?>)
|
||||
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
|
||||
drawValue(gc, subArea, firstKey, actualValues.get(w), trackEntry.selected);
|
||||
} else {
|
||||
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
|
||||
.entrySet()) {
|
||||
IWaveform<? extends IWaveformEvent> w = entry.getValue().waveform;
|
||||
subArea.height = waveformCanvas.getTrackHeight();
|
||||
try {
|
||||
Integer firstKey = trackVerticalOffset.floorKey(rect.y);
|
||||
if (firstKey == null)
|
||||
firstKey = trackVerticalOffset.firstKey();
|
||||
Integer lastKey = trackVerticalOffset.floorKey(rect.y + rect.height);
|
||||
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, waveformCanvas.getTrackHeight());
|
||||
if (lastKey == firstKey) {
|
||||
TrackEntry trackEntry=trackVerticalOffset.get(firstKey);
|
||||
IWaveform w = trackEntry.waveform;
|
||||
if (w instanceof ITxStream<?>)
|
||||
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
|
||||
drawValue(gc, subArea, entry.getKey(), actualValues.get(w), entry.getValue().selected);
|
||||
drawValue(gc, subArea, firstKey, trackEntry.currentValue, trackEntry.selected);
|
||||
} else {
|
||||
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
|
||||
.entrySet()) {
|
||||
IWaveform w = entry.getValue().waveform;
|
||||
subArea.height = waveformCanvas.getTrackHeight();
|
||||
if (w instanceof ITxStream<?>)
|
||||
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
|
||||
drawValue(gc, subArea, entry.getKey(), entry.getValue().currentValue, entry.getValue().selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(NoSuchElementException e){}
|
||||
}
|
||||
}
|
||||
|
||||
@ -846,11 +892,11 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
gc.drawText(value, subArea.x + 5, subArea.y + yOffset + (waveformCanvas.getTrackHeight() - size.y) / 2, true);
|
||||
}
|
||||
|
||||
|
||||
public void setHighliteRelation(RelationType relationType){
|
||||
this.waveformCanvas.setHighliteRelation(relationType);
|
||||
}
|
||||
|
||||
|
||||
public void setHighliteRelation(RelationType relationType){
|
||||
this.waveformCanvas.setHighliteRelation(relationType);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.minres.scviewer.database.swt.IWaveformPanel#getMaxTime()
|
||||
*/
|
||||
@ -918,8 +964,8 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
* @see com.minres.scviewer.database.swt.IWaveformPanel#getActMarkerTime()
|
||||
*/
|
||||
@Override
|
||||
public long getSelectedMarkerTime(){
|
||||
return getMarkerTime(selectedMarker);
|
||||
public int getSelectedMarkerId(){
|
||||
return selectedMarker;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -982,7 +1028,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
else
|
||||
streams.add(tgtIdx, srcWave);
|
||||
currentWaveformSelection=srcWave;
|
||||
updateTracklist();
|
||||
update();
|
||||
} else if(source instanceof CursorPainter){
|
||||
((CursorPainter)source).setTime(0);
|
||||
updateValueList();
|
||||
@ -1001,7 +1047,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
});
|
||||
}
|
||||
|
||||
public TrackEntry getEntryForStream(IWaveform<?> source) {
|
||||
public TrackEntry getEntryForStream(IWaveform source) {
|
||||
for(TrackEntry trackEntry:streams)
|
||||
if(trackEntry.waveform.equals(source)) return trackEntry;
|
||||
return null;
|
||||
@ -1141,7 +1187,8 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
public String getScaledTime(long time) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Double dTime=new Double(time);
|
||||
return sb.append(dTime/waveformCanvas.getScaleFactorPow10()).append(waveformCanvas.getUnitStr()).toString();
|
||||
Double scaledTime = dTime/waveformCanvas.getScaleFactorPow10();
|
||||
return sb.append(df.format(scaledTime)).append(waveformCanvas.getUnitStr()).toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -1149,10 +1196,10 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
*/
|
||||
@Override
|
||||
public String[] getZoomLevels(){
|
||||
String[] res = new String[WaveformCanvas.unitMultiplier.length*WaveformCanvas.unitString.length];
|
||||
String[] res = new String[Constants.unitMultiplier.length*Constants.unitString.length];
|
||||
int index=0;
|
||||
for(String unit:WaveformCanvas.unitString){
|
||||
for(int factor:WaveformCanvas.unitMultiplier){
|
||||
for(String unit:Constants.unitString){
|
||||
for(int factor:Constants.unitMultiplier){
|
||||
res[index++]= new Integer(factor).toString()+unit;
|
||||
}
|
||||
}
|
||||
@ -1163,4 +1210,43 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
public void setColors(HashMap<WaveformColors, RGB> colourMap) {
|
||||
waveformCanvas.initColors(colourMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBaselineTime() {
|
||||
return -waveformCanvas.getScaleFactorPow10()*waveformCanvas.getOrigin().x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBaselineTime(Long time) {
|
||||
Point origin = waveformCanvas.getOrigin();
|
||||
origin.x=(int) (-time/waveformCanvas.getScaleFactorPow10());
|
||||
waveformCanvas.setOrigin(origin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrollHorizontal(int percent) {
|
||||
if(percent<-100) percent=-100;
|
||||
if(percent>100) percent=100;
|
||||
int diff = (waveformCanvas.getWidth()*percent)/100;
|
||||
// ScrollBar sb = waveformCanvas.getHorizontalBar();
|
||||
// int x = sb.getSelection();
|
||||
// System.out.println("Setting sb to "+ (x+diff));
|
||||
// if((x+diff)>0)
|
||||
// sb.setSelection(x+diff);
|
||||
// else
|
||||
// sb.setSelection(0);
|
||||
Point o = waveformCanvas.getOrigin();
|
||||
waveformCanvas.setOrigin(o.x-diff, o.y);
|
||||
waveformCanvas.redraw();
|
||||
}
|
||||
|
||||
public void asyncUpdate(Widget widget) {
|
||||
widget.getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
waveformCanvas.redraw();
|
||||
updateValueList();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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.7"/>
|
||||
<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.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
|
@ -1,7 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
@ -2,9 +2,10 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Database UI
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.ui
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Version: 2.0.0.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Export-Package: com.minres.scviewer.database.ui
|
||||
Require-Bundle: com.minres.scviewer.database,
|
||||
org.eclipse.jface
|
||||
Automatic-Module-Name: com.minres.scviewer.database.ui
|
||||
|
@ -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.ui</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<relativePath>../com.minres.scviewer.parent</relativePath>
|
||||
</parent>
|
||||
</project>
|
@ -34,6 +34,8 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
|
||||
public void addSelectionChangedListener(ISelectionChangedListener listener);
|
||||
|
||||
public void removeSelectionChangedListener(ISelectionChangedListener listener);
|
||||
|
||||
public void update();
|
||||
|
||||
public Control getControl();
|
||||
|
||||
@ -57,7 +59,7 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
|
||||
|
||||
public List<TrackEntry> getStreamList();
|
||||
|
||||
public TrackEntry getEntryForStream(IWaveform<?> source);
|
||||
public TrackEntry getEntryForStream(IWaveform source);
|
||||
|
||||
public void moveSelectedTrack(int i);
|
||||
|
||||
@ -77,7 +79,7 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
|
||||
|
||||
public long getCursorTime();
|
||||
|
||||
public long getSelectedMarkerTime();
|
||||
public int getSelectedMarkerId();
|
||||
|
||||
public long getMarkerTime(int index);
|
||||
|
||||
@ -96,4 +98,10 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
|
||||
public List<ICursor> getCursorList();
|
||||
|
||||
public void setColors(HashMap<WaveformColors, RGB> colourMap);
|
||||
|
||||
public long getBaselineTime();
|
||||
|
||||
public void setBaselineTime(Long scale);
|
||||
|
||||
public void scrollHorizontal(int percent);
|
||||
}
|
@ -10,15 +10,97 @@
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import com.minres.scviewer.database.ISignal;
|
||||
import com.minres.scviewer.database.ISignalChange;
|
||||
import com.minres.scviewer.database.ITxEvent;
|
||||
import com.minres.scviewer.database.ITxStream;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
|
||||
public class TrackEntry {
|
||||
final public IWaveform<? extends IWaveformEvent> waveform;
|
||||
|
||||
// color info
|
||||
public static Color fallbackColor = new Color(200,0,0);
|
||||
public static Color highlightedFallbackColor = new Color(255,0,0);
|
||||
private Color[]signalColors;
|
||||
|
||||
// list of random colors
|
||||
private static Color[][] randomColors = {
|
||||
{ new Color( 170, 66, 37 ), new Color ( 190, 66, 37 ) },
|
||||
{ new Color( 96, 74, 110 ), new Color ( 96, 74, 130 ) },
|
||||
{ new Color( 133, 105, 128 ), new Color ( 153, 105, 128 ) },
|
||||
{ new Color( 0, 126, 135 ), new Color ( 0, 126, 155 ) },
|
||||
{ new Color( 243, 146, 75 ), new Color ( 255, 146, 75 ) },
|
||||
{ new Color( 206, 135, 163 ), new Color ( 226, 135, 163 ) },
|
||||
{ new Color( 124, 103, 74 ), new Color ( 144, 103, 74 ) },
|
||||
{ new Color( 194, 187, 169 ), new Color ( 214, 187, 169 ) },
|
||||
{ new Color( 104, 73, 71 ), new Color ( 124, 73, 71 ) },
|
||||
{ new Color( 75, 196, 213 ), new Color ( 75, 196, 233 ) },
|
||||
{ new Color( 206, 232, 229 ), new Color ( 206, 252, 229 ) },
|
||||
{ new Color( 169, 221, 199 ), new Color ( 169, 241, 199 ) },
|
||||
{ new Color( 100, 165, 197 ), new Color ( 100, 165, 217 ) },
|
||||
{ new Color( 150, 147, 178 ), new Color ( 150, 147, 198 ) },
|
||||
{ new Color( 200, 222, 182 ), new Color ( 200, 242, 182 ) },
|
||||
{ new Color( 147, 208, 197 ), new Color ( 147, 228, 197 ) }
|
||||
};
|
||||
|
||||
public static Color[] computeColor (String streamValue, Color fallback, Color highlightedFallback) {
|
||||
|
||||
Color[]result = new Color[2];
|
||||
|
||||
result[0] = fallback;
|
||||
result[1] = highlightedFallback;
|
||||
|
||||
// assign colors to standard values
|
||||
if (streamValue.contains("read")){
|
||||
result[0] = new Color(86,174,53);
|
||||
result[1] = new Color (86,194,53);
|
||||
}else if (streamValue.contains("rdata")){
|
||||
result[0] = new Color(138,151,71);
|
||||
result[1] = new Color (138,171,71);
|
||||
}else if (streamValue.contains("addr")){
|
||||
result[0] = new Color(233,187,68);
|
||||
result[1] = new Color (233,207,68);
|
||||
}else if (streamValue.contains("write")){
|
||||
result[0] = new Color(1,128,191);
|
||||
result[1] = new Color (1,128,211);
|
||||
}else if (streamValue.contains("wdata")){
|
||||
result[0] = new Color(2,181,160);
|
||||
result[1] = new Color (2,201,160);
|
||||
|
||||
}else {
|
||||
// assign "random" color here, one name always results in the same color!
|
||||
if( randomColors.length > 0 ) {
|
||||
int index = streamValue.hashCode() % randomColors.length;
|
||||
result[0] = randomColors[index][0];
|
||||
result[1] = randomColors[index][1];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public void setColor(Color changedColor, Color highlightColor) {
|
||||
signalColors[0] = changedColor;
|
||||
signalColors[1] = highlightColor;
|
||||
}
|
||||
|
||||
public Color[] getColors() {
|
||||
return signalColors;
|
||||
}
|
||||
|
||||
public enum ValueDisplay {
|
||||
DEFAULT, SIGNED, UNSIGNED
|
||||
|
||||
}
|
||||
|
||||
public enum WaveDisplay {
|
||||
DEFAULT, STEP_WISE, CONTINOUS
|
||||
}
|
||||
|
||||
final public IWaveform waveform;
|
||||
|
||||
public int vOffset;
|
||||
|
||||
@ -26,11 +108,20 @@ public class TrackEntry {
|
||||
|
||||
public boolean selected;
|
||||
|
||||
public TrackEntry(IWaveform<? extends IWaveformEvent> waveform) {
|
||||
public String currentValue="";
|
||||
|
||||
public ValueDisplay valueDisplay = ValueDisplay.DEFAULT;
|
||||
|
||||
public WaveDisplay waveDisplay = WaveDisplay.DEFAULT;
|
||||
|
||||
public TrackEntry(IWaveform waveform) {
|
||||
this.waveform = waveform;
|
||||
vOffset=0;
|
||||
height=0;
|
||||
selected=false;
|
||||
signalColors = new Color[2];
|
||||
signalColors[0] = fallbackColor;
|
||||
signalColors[1] = highlightedFallbackColor;
|
||||
}
|
||||
|
||||
public boolean isStream(){
|
||||
@ -45,7 +136,7 @@ public class TrackEntry {
|
||||
return waveform instanceof ISignal<?>;
|
||||
}
|
||||
|
||||
public ISignal<? extends ISignalChange> getSignal(){
|
||||
public ISignal<?> getSignal(){
|
||||
return (ISignal<?>) waveform;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ public enum WaveformColors {
|
||||
LINE, LINE_HIGHLITE,
|
||||
TRACK_BG_EVEN, TRACK_BG_ODD, TRACK_BG_HIGHLITE,
|
||||
TX_BG, TX_BG_HIGHLITE, TX_BORDER,
|
||||
SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNAL_TEXT,
|
||||
SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNALU, SIGNAL_TEXT, SIGNAL_REAL, SIGNAL_NAN,
|
||||
CURSOR, CURSOR_DRAG, CURSOR_TEXT,
|
||||
MARKER, MARKER_TEXT, REL_ARROW, REL_ARROW_HIGHLITE
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?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.7"/>
|
||||
<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.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src/"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
@ -1,2 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
@ -1,7 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
@ -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: 1.0.0.qualifier
|
||||
Bundle-Version: 2.0.2.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||
org.eclipse.equinox.util;bundle-version="1.0.500",
|
||||
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
||||
@ -13,3 +13,4 @@ Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||
Service-Component: OSGI-INF/component.xml
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Import-Package: com.google.common.collect
|
||||
Automatic-Module-Name: com.minres.scviewer.database.vcd
|
||||
|
@ -1,11 +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.0.2-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<relativePath>../com.minres.scviewer.parent</relativePath>
|
||||
</parent>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
</project>
|
@ -12,9 +12,8 @@ package com.minres.scviewer.database.vcd;
|
||||
|
||||
import com.minres.scviewer.database.BitVector;
|
||||
|
||||
// TODO: Auto-generated Javadoc
|
||||
/**
|
||||
* The Interface ITraceBuilder.
|
||||
* The Interface IVCDDatabaseBuilder. It allows to add VCD events into the database
|
||||
*/
|
||||
public interface IVCDDatabaseBuilder {
|
||||
|
||||
@ -35,26 +34,35 @@ public interface IVCDDatabaseBuilder {
|
||||
*
|
||||
* @param netName the net name
|
||||
* @param i the index of the net, -1 if a new one, otherwise the id if the referenced
|
||||
* @param width the width
|
||||
* @return the integer
|
||||
* @param width the width, -1 equals real, 0... is a bit vector
|
||||
* @return the net id
|
||||
*/
|
||||
public Integer newNet(String netName, int i, int width) ;
|
||||
|
||||
/**
|
||||
* Gets the net width.
|
||||
*
|
||||
* @param intValue the int value
|
||||
* @return the net width
|
||||
* @param intValue the net id
|
||||
* @return the net width, -1 means a real-valued net
|
||||
*/
|
||||
public int getNetWidth(int intValue);
|
||||
public int getNetWidth(int netId);
|
||||
|
||||
/**
|
||||
* Append transition.
|
||||
*
|
||||
* @param signalId the int value
|
||||
* @param netId the int value
|
||||
* @param currentTime the current time in ps
|
||||
* @param decodedValues the decoded values
|
||||
*/
|
||||
public void appendTransition(int signalId, long currentTime, BitVector decodedValues);
|
||||
public void appendTransition(int netId, long currentTime, BitVector decodedValue);
|
||||
|
||||
/**
|
||||
* Append transition.
|
||||
*
|
||||
* @param netId the int value
|
||||
* @param currentTime the current time in ps
|
||||
* @param decodedValue the decoded values
|
||||
*/
|
||||
public void appendTransition(int netId, long currentTime, double decodedValue);
|
||||
|
||||
}
|
||||
|
@ -12,53 +12,67 @@ package com.minres.scviewer.database.vcd;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Stack;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Vector;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import com.minres.scviewer.database.BitVector;
|
||||
import com.minres.scviewer.database.ISignal;
|
||||
import com.minres.scviewer.database.ISignalChange;
|
||||
import com.minres.scviewer.database.ISignalChangeMulti;
|
||||
import com.minres.scviewer.database.ISignalChangeSingle;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
import com.minres.scviewer.database.InputFormatException;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
|
||||
// TODO: Auto-generated Javadoc
|
||||
/**
|
||||
* The Class VCDDb.
|
||||
*/
|
||||
public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
|
||||
|
||||
/** The Constant TIME_RES. */
|
||||
private static final Long TIME_RES = 1000L; // ps;
|
||||
|
||||
/** The db. */
|
||||
private IWaveformDb db;
|
||||
|
||||
/** The module stack. */
|
||||
private Stack<String> moduleStack;
|
||||
|
||||
/** The signals. */
|
||||
private List<IWaveform<? extends IWaveformEvent>> signals;
|
||||
private List<IWaveform> signals;
|
||||
|
||||
/** The max time. */
|
||||
private long maxTime;
|
||||
|
||||
/**
|
||||
* Instantiates a new VCD db.
|
||||
*
|
||||
* @param netName the net name
|
||||
*/
|
||||
public VCDDbLoader() {
|
||||
}
|
||||
|
||||
private byte[] x = "$date".getBytes();
|
||||
private static boolean isGzipped(File f) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
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;
|
||||
} finally {
|
||||
try { is.close();} catch (IOException e) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.minres.scviewer.database.ITrDb#load(java.io.File)
|
||||
@ -67,35 +81,36 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
@Override
|
||||
public boolean load(IWaveformDb db, File file) throws Exception {
|
||||
this.db=db;
|
||||
this.maxTime=0;
|
||||
String name = file.getCanonicalFile().getName();
|
||||
if(!(name.endsWith(".vcd") ||
|
||||
name.endsWith(".vcdz") ||
|
||||
name.endsWith(".vcdgz") ||
|
||||
name.endsWith(".vcd.gz")) )
|
||||
return false;
|
||||
signals = new Vector<IWaveform>();
|
||||
moduleStack= new Stack<String>();
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[x.length];
|
||||
int read = fis.read(buffer, 0, x.length);
|
||||
fis.close();
|
||||
if (read == x.length)
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i])
|
||||
return false;
|
||||
|
||||
signals = new Vector<IWaveform<? extends IWaveformEvent>>();
|
||||
moduleStack= new Stack<String>();
|
||||
boolean res = new VCDFileParser(false).load(new FileInputStream(file), this);
|
||||
boolean res = new VCDFileParser(false).load(isGzipped(file)?new GZIPInputStream(fis):fis, this);
|
||||
moduleStack=null;
|
||||
if(!res) throw new InputFormatException();
|
||||
// calculate max time of database
|
||||
for(IWaveform<? extends IWaveformEvent> waveform:signals)
|
||||
maxTime= Math.max(maxTime, ((ISignal<? extends ISignalChange>)waveform).getEvents().lastKey());
|
||||
for(IWaveform waveform:signals) {
|
||||
NavigableMap<Long, ?> events =((ISignal<?>)waveform).getEvents();
|
||||
if(events.size()>0)
|
||||
maxTime= Math.max(maxTime, events.lastKey());
|
||||
}
|
||||
// extend signals to hav a last value set at max time
|
||||
for(IWaveform<? extends IWaveformEvent> waveform:signals){
|
||||
TreeMap<Long,? extends ISignalChange> events = ((VCDSignal<? extends ISignalChange>)waveform).values;
|
||||
if(events.lastKey()<maxTime){
|
||||
ISignalChange x = events.lastEntry().getValue();
|
||||
if(x instanceof ISignalChangeSingle)
|
||||
((VCDSignal<ISignalChangeSingle>)waveform).values.put(maxTime,
|
||||
new VCDSignalChangeSingle(maxTime, ((ISignalChangeSingle)x).getValue()));
|
||||
else
|
||||
if(x instanceof ISignalChangeMulti)
|
||||
((VCDSignal<ISignalChangeMulti>)waveform).values.put(maxTime,
|
||||
new VCDSignalChangeMulti(maxTime, ((ISignalChangeMulti)x).getValue()));
|
||||
for(IWaveform s:signals){
|
||||
if(s instanceof VCDSignal<?>) {
|
||||
TreeMap<Long,?> events = (TreeMap<Long, ?>) ((VCDSignal<?>)s).getEvents();
|
||||
if(events.size()>0 && events.lastKey()<maxTime){
|
||||
Object val = events.lastEntry().getValue();
|
||||
if(val instanceof BitVector) {
|
||||
((VCDSignal<BitVector>)s).addSignalChange(maxTime, (BitVector) val);
|
||||
} else if(val instanceof Double)
|
||||
((VCDSignal<Double>)s).addSignalChange(maxTime, (Double) val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -113,7 +128,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
* @see com.minres.scviewer.database.ITrDb#getAllWaves()
|
||||
*/
|
||||
@Override
|
||||
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
|
||||
public List<IWaveform> getAllWaves() {
|
||||
return signals;
|
||||
}
|
||||
|
||||
@ -122,9 +137,9 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
*/
|
||||
@Override
|
||||
public void enterModule(String tokenString) {
|
||||
if(moduleStack.isEmpty())
|
||||
moduleStack.push(tokenString);
|
||||
else
|
||||
if(moduleStack.isEmpty()) {
|
||||
if("SystemC".compareTo(tokenString)!=0) moduleStack.push(tokenString);
|
||||
} else
|
||||
moduleStack.push(moduleStack.peek()+"."+tokenString);
|
||||
|
||||
}
|
||||
@ -142,17 +157,17 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Integer newNet(String netName, int i, int width) {
|
||||
public Integer newNet(String name, int i, int width) {
|
||||
String netName = moduleStack.empty()? name: moduleStack.lastElement()+"."+name;
|
||||
int id = signals.size();
|
||||
VCDSignal<? extends IWaveformEvent> signal;
|
||||
if(width==1){
|
||||
signal = i<0 ? new VCDSignal<ISignalChangeSingle>(db, id, netName) :
|
||||
new VCDSignal<ISignalChangeSingle>((VCDSignal<ISignalChangeSingle>)signals.get(i), id, netName);
|
||||
} else {
|
||||
signal = i<0 ? new VCDSignal<ISignalChangeMulti>(db, id, netName, width) :
|
||||
new VCDSignal<ISignalChangeMulti>((VCDSignal<VCDSignalChangeMulti>)signals.get(i), id, netName);
|
||||
};
|
||||
signals.add(signal);
|
||||
assert(width>=0);
|
||||
if(width==0) {
|
||||
signals.add( i<0 ? new VCDSignal<Double>(db, id, netName, width) :
|
||||
new VCDSignal<Double>((VCDSignal<Double>)signals.get(i), id, netName));
|
||||
} else if(width>0){
|
||||
signals.add( i<0 ? new VCDSignal<BitVector>(db, id, netName, width) :
|
||||
new VCDSignal<BitVector>((VCDSignal<BitVector>)signals.get(i), id, netName));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -161,7 +176,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
*/
|
||||
@Override
|
||||
public int getNetWidth(int intValue) {
|
||||
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(intValue);
|
||||
VCDSignal<?> signal = (VCDSignal<?>) signals.get(intValue);
|
||||
return signal.getWidth();
|
||||
}
|
||||
|
||||
@ -170,16 +185,28 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void appendTransition(int signalId, long currentTime, BitVector decodedValues) {
|
||||
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId);
|
||||
public void appendTransition(int signalId, long currentTime, BitVector value) {
|
||||
VCDSignal<BitVector> signal = (VCDSignal<BitVector>) signals.get(signalId);
|
||||
Long time = currentTime* TIME_RES;
|
||||
if(signal.getWidth()==1){
|
||||
((VCDSignal<ISignalChangeSingle>)signal).values.put(time, new VCDSignalChangeSingle(time, decodedValues.getValue()[0]));
|
||||
} else {
|
||||
((VCDSignal<VCDSignalChangeMulti>)signal).values.put(time, new VCDSignalChangeMulti(time, decodedValues));
|
||||
signal.getEvents().put(time, value);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.minres.scviewer.database.vcd.ITraceBuilder#appendTransition(int, long, com.minres.scviewer.database.vcd.BitVector)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void appendTransition(int signalId, long currentTime, double value) {
|
||||
VCDSignal<?> signal = (VCDSignal<?>) signals.get(signalId);
|
||||
Long time = currentTime* TIME_RES;
|
||||
if(signal.getWidth()==0){
|
||||
((VCDSignal<Double>)signal).getEvents().put(time, value);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.minres.scviewer.database.IWaveformDbLoader#getAllRelationTypes()
|
||||
*/
|
||||
@Override
|
||||
public Collection<RelationType> getAllRelationTypes(){
|
||||
return Collections.emptyList();
|
||||
|
@ -13,6 +13,7 @@ package com.minres.scviewer.database.vcd;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import com.minres.scviewer.database.BitValue;
|
||||
import com.minres.scviewer.database.BitVector;
|
||||
|
||||
class VCDFileParser {
|
||||
@ -21,10 +22,12 @@ class VCDFileParser {
|
||||
private HashMap<String, Integer> nameToNetMap = new HashMap<String, Integer>();
|
||||
private long picoSecondsPerIncrement;
|
||||
private boolean stripNetWidth;
|
||||
private boolean replaceColon;
|
||||
long currentTime;
|
||||
|
||||
public VCDFileParser(boolean stripNetWidth) {
|
||||
this.stripNetWidth=stripNetWidth;
|
||||
this.replaceColon=false;
|
||||
}
|
||||
|
||||
public boolean load(InputStream is, IVCDDatabaseBuilder builder) {
|
||||
@ -61,9 +64,11 @@ class VCDFileParser {
|
||||
|
||||
private void parseVar() throws Exception {
|
||||
nextToken(); // type
|
||||
String type = tokenizer.sval;
|
||||
nextToken(); // size
|
||||
int width = Integer.parseInt(tokenizer.sval);
|
||||
|
||||
if("real".equals(type))
|
||||
width=0;
|
||||
nextToken();
|
||||
String id = tokenizer.sval;
|
||||
nextToken();
|
||||
@ -73,11 +78,17 @@ class VCDFileParser {
|
||||
}
|
||||
|
||||
Integer net = nameToNetMap.get(id);
|
||||
if (net == null) {
|
||||
// We've never seen this net before
|
||||
if (net == null) { // We've never seen this net before
|
||||
int openBracket = netName.indexOf('[');
|
||||
if(stripNetWidth){
|
||||
int openBracket = netName.indexOf('[');
|
||||
if (openBracket != -1) netName = netName.substring(0, openBracket);
|
||||
openBracket = -1;
|
||||
}
|
||||
if(replaceColon) {
|
||||
if (openBracket != -1) {
|
||||
netName = netName.substring(0, openBracket).replaceAll(":", ".")+netName.substring(openBracket);
|
||||
} else
|
||||
netName=netName.replaceAll(":", ".");
|
||||
}
|
||||
nameToNetMap.put(id, traceBuilder.newNet(netName, -1, width));
|
||||
} else {
|
||||
@ -86,6 +97,17 @@ class VCDFileParser {
|
||||
}
|
||||
}
|
||||
|
||||
private void parseComment() throws Exception {
|
||||
nextToken();
|
||||
String s = tokenizer.sval;
|
||||
nextToken();
|
||||
while(!tokenizer.sval.equals("$end")){
|
||||
s+=" "+tokenizer.sval;
|
||||
nextToken();
|
||||
}
|
||||
replaceColon|=s.contains("ARTERIS Architecture");
|
||||
}
|
||||
|
||||
private void parseTimescale() throws Exception {
|
||||
nextToken();
|
||||
String s = tokenizer.sval;
|
||||
@ -129,6 +151,8 @@ class VCDFileParser {
|
||||
parseUpscope();
|
||||
else if (tokenizer.sval.equals("$timescale"))
|
||||
parseTimescale();
|
||||
else if (tokenizer.sval.equals("$comment"))
|
||||
parseComment();
|
||||
else if (tokenizer.sval.equals("$enddefinitions")) {
|
||||
match("$end");
|
||||
return false;
|
||||
@ -153,7 +177,8 @@ class VCDFileParser {
|
||||
} while (!tokenizer.sval.equals("$end"));
|
||||
return true;
|
||||
}
|
||||
if (tokenizer.sval.equals("$dumpvars") || tokenizer.sval.equals("$end")) return true;
|
||||
if (tokenizer.sval.equals("$dumpvars") || tokenizer.sval.equals("$end"))
|
||||
return true;
|
||||
String value, id;
|
||||
if (tokenizer.sval.charAt(0) == 'b') {
|
||||
// Multiple value net. Value appears first, followed by space,
|
||||
@ -161,6 +186,12 @@ class VCDFileParser {
|
||||
value = tokenizer.sval.substring(1);
|
||||
nextToken();
|
||||
id = tokenizer.sval;
|
||||
}else if (tokenizer.sval.charAt(0) == 'r') {
|
||||
// Multiple value net. Value appears first, followed by space,
|
||||
// then identifier
|
||||
value = tokenizer.sval.substring(1);
|
||||
nextToken();
|
||||
id = tokenizer.sval;
|
||||
} else {
|
||||
// Single value net. identifier first, then value, no space.
|
||||
value = tokenizer.sval.substring(0, 1);
|
||||
@ -174,39 +205,50 @@ class VCDFileParser {
|
||||
}
|
||||
|
||||
int netWidth = traceBuilder.getNetWidth(net);
|
||||
BitVector decodedValues = new BitVector(netWidth);
|
||||
if (value.equals("z") && netWidth > 1) {
|
||||
for (int i = 0; i < netWidth; i++)
|
||||
decodedValues.setValue(i, BitVector.VALUE_Z);
|
||||
} else if (value.equals("x") && netWidth > 1) {
|
||||
for (int i = 0; i < netWidth; i++)
|
||||
decodedValues.setValue(i, BitVector.VALUE_X);
|
||||
if(netWidth==0) {
|
||||
if("nan".equals(value))
|
||||
traceBuilder.appendTransition(net, currentTime, Double.NaN);
|
||||
else
|
||||
traceBuilder.appendTransition(net, currentTime, Double.parseDouble(value));
|
||||
} else {
|
||||
int stringIndex = 0;
|
||||
for (int convertedIndex = netWidth - value.length(); convertedIndex < netWidth; convertedIndex++) {
|
||||
switch (value.charAt(stringIndex++)) {
|
||||
case 'z':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_Z);
|
||||
break;
|
||||
BitVector decodedValues = new BitVector(netWidth);
|
||||
if (value.equals("z") && netWidth > 1) {
|
||||
for (int i = 0; i < netWidth; i++)
|
||||
decodedValues.setValue(i, BitValue.Z);
|
||||
} else if (value.equals("x") && netWidth > 1) {
|
||||
for (int i = 0; i < netWidth; i++)
|
||||
decodedValues.setValue(i, BitValue.X);
|
||||
} else {
|
||||
int stringIndex = 0;
|
||||
for (int convertedIndex = netWidth -1; convertedIndex >=0; convertedIndex--) {
|
||||
if(convertedIndex<value.length()) {
|
||||
switch (value.charAt(stringIndex++)) {
|
||||
case 'z':
|
||||
decodedValues.setValue(convertedIndex, BitValue.Z);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_1);
|
||||
break;
|
||||
case '1':
|
||||
decodedValues.setValue(convertedIndex, BitValue.ONE);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_0);
|
||||
break;
|
||||
case '0':
|
||||
decodedValues.setValue(convertedIndex, BitValue.ZERO);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_X);
|
||||
break;
|
||||
case 'x':
|
||||
decodedValues.setValue(convertedIndex, BitValue.X);
|
||||
break;
|
||||
|
||||
default:
|
||||
decodedValues.setValue(convertedIndex, BitVector.VALUE_X);
|
||||
default:
|
||||
decodedValues.setValue(convertedIndex, BitValue.X);
|
||||
}
|
||||
} else {
|
||||
decodedValues.setValue(convertedIndex, BitValue.ZERO);
|
||||
}
|
||||
}
|
||||
}
|
||||
traceBuilder.appendTransition(net, currentTime, decodedValues);
|
||||
}
|
||||
traceBuilder.appendTransition(net, currentTime, decodedValues);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -10,17 +10,17 @@
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.vcd;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.minres.scviewer.database.HierNode;
|
||||
import com.minres.scviewer.database.ISignal;
|
||||
import com.minres.scviewer.database.ISignalChange;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformEvent;
|
||||
|
||||
public class VCDSignal<T extends ISignalChange> extends HierNode implements ISignal<T> {
|
||||
public class VCDSignal<T> extends HierNode implements ISignal<T> {
|
||||
|
||||
private long id;
|
||||
|
||||
@ -29,10 +29,12 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
private final String kind = "signal";
|
||||
|
||||
private final int width;
|
||||
|
||||
private final T dummy = null;
|
||||
|
||||
private IWaveformDb db;
|
||||
|
||||
TreeMap<Long, T> values;
|
||||
private TreeMap<Long, T> values;
|
||||
|
||||
public VCDSignal(IWaveformDb db, String name) {
|
||||
this(db, 0, name, 1);
|
||||
@ -52,7 +54,7 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public VCDSignal(IWaveform<? extends ISignalChange> other, int id, String name) {
|
||||
public VCDSignal(ISignal<T> other, int id, String name) {
|
||||
super(name);
|
||||
fullName=name;
|
||||
this.id=id;
|
||||
@ -90,8 +92,8 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
return db;
|
||||
}
|
||||
|
||||
public void addSignalChange(T change){
|
||||
values.put(change.getTime(), change);
|
||||
public void addSignalChange(Long time, T value){
|
||||
values.put(time, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,20 +102,29 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getWaveformEventsAtTime(Long time) {
|
||||
public T getWaveformValueAtTime(Long time) {
|
||||
return values.get(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getWaveformEventsBeforeTime(Long time) {
|
||||
return values.floorEntry(time).getValue();
|
||||
public T getWaveformValueBeforeTime(Long time) {
|
||||
Entry<Long, T> e = values.floorEntry(time);
|
||||
if(e==null)
|
||||
return null;
|
||||
else
|
||||
return values.floorEntry(time).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
|
||||
public Boolean equals(IWaveform other) {
|
||||
return(other instanceof VCDSignal<?> && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
return dummy.getClass();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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 com.minres.scviewer.database.BitVector;
|
||||
import com.minres.scviewer.database.ISignalChangeMulti;
|
||||
import com.minres.scviewer.database.SignalChange;
|
||||
|
||||
public class VCDSignalChangeMulti extends SignalChange implements ISignalChangeMulti, Cloneable {
|
||||
|
||||
private BitVector value;
|
||||
|
||||
public VCDSignalChangeMulti(Long time) {
|
||||
super(time);
|
||||
}
|
||||
|
||||
public VCDSignalChangeMulti(Long time, BitVector decodedValues) {
|
||||
super(time);
|
||||
this.value=decodedValues;
|
||||
}
|
||||
|
||||
public BitVector getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(BitVector value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value.toHexString()+"@"+getTime();
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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 com.minres.scviewer.database.ISignalChangeSingle;
|
||||
import com.minres.scviewer.database.SignalChange;
|
||||
|
||||
public class VCDSignalChangeSingle extends SignalChange implements ISignalChangeSingle, Cloneable {
|
||||
|
||||
private char value;
|
||||
|
||||
public VCDSignalChangeSingle(Long time, char value) {
|
||||
super(time);
|
||||
this.value=value;
|
||||
}
|
||||
|
||||
public char getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(char value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value+"@"+getTime();
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?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.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="src" path="src/"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
@ -1,2 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user