CAN FD support (#85)
* variable length AddSignal matrix * nicer matrix rendering * fix selecting signal * correct size of new frame * MessageBytes canvas wider * multi line MessageBytes * fix tests * can log multirow * rebase fixesmain
parent
976c1652ce
commit
7909d33aea
|
@ -966,7 +966,8 @@ export default class CanExplorer extends Component {
|
|||
|
||||
onConfirmedSignalChange(message, signals) {
|
||||
const { dbc, dbcFilename } = this.state;
|
||||
dbc.setSignals(message.address, { ...signals });
|
||||
const frameSize = DbcUtils.maxMessageSize(message);
|
||||
dbc.setSignals(message.address, { ...signals }, frameSize);
|
||||
|
||||
this.persistDbc({ dbcFilename, dbc });
|
||||
|
||||
|
@ -1015,8 +1016,9 @@ export default class CanExplorer extends Component {
|
|||
|
||||
showEditMessageModal(msgKey) {
|
||||
const msg = this.state.messages[msgKey];
|
||||
console.log(msg);
|
||||
if (!msg.frame) {
|
||||
msg.frame = this.state.dbc.createFrame(msg.address);
|
||||
msg.frame = this.state.dbc.createFrame(msg.address); // TODO frameSize
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
|
|
@ -59,7 +59,7 @@ test('addCanMessage should add parsed can message with dbc containing message sp
|
|||
const messages = {};
|
||||
// create dbc with message spec and signal for sample_message
|
||||
const dbc = new DBC();
|
||||
dbc.createFrame(SAMPLE_MESSAGE.address);
|
||||
dbc.createFrame(SAMPLE_MESSAGE.address, 8);
|
||||
const signal = new Signal({ name: 'NEW_SIGNAL', startBit: 0, size: 8 });
|
||||
dbc.addSignal(SAMPLE_MESSAGE.address, signal);
|
||||
|
||||
|
|
|
@ -67,7 +67,8 @@ export default class AddSignals extends Component {
|
|||
highlightedSignal: null,
|
||||
dragStartBit: null,
|
||||
dragSignal: null,
|
||||
dragCurrentBit: null
|
||||
dragCurrentBit: null,
|
||||
maxMessageBytes: 8,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -81,6 +82,22 @@ export default class AddSignals extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.message !== this.props.message) {
|
||||
this.setState({
|
||||
maxMessageBytes: DbcUtils.maxMessageSize(this.props.message),
|
||||
});
|
||||
}
|
||||
|
||||
if (prevProps.message.address !== this.props.message.address ||
|
||||
prevProps.selectedMessageKey !== this.props.selectedMessageKey)
|
||||
{
|
||||
const signals = this.props.message.frame ? this.props.message.frame.signals : {};
|
||||
|
||||
this.setState({ signals: this.copySignals(signals) }, this.updateSignalStyles);
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
return (
|
||||
nextProps.message.hexData !== this.props.message.hexData
|
||||
|
@ -131,16 +148,6 @@ export default class AddSignals extends Component {
|
|||
return signalStyles;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.message.address !== this.props.message.address ||
|
||||
prevProps.selectedMessageKey !== this.props.selectedMessageKey)
|
||||
{
|
||||
const signals = this.props.message.frame ? this.props.message.frame.signals : {};
|
||||
|
||||
this.setState({ signals: this.copySignals(signals) }, this.updateSignalStyles);
|
||||
}
|
||||
}
|
||||
|
||||
signalForBit(bitIdx) {
|
||||
// bitIdx in [0,64)
|
||||
// returns instance of Signal
|
||||
|
@ -426,7 +433,7 @@ export default class AddSignals extends Component {
|
|||
if (message.frame && message.frame.size) {
|
||||
rowCount = Math.floor((message.frame.size * 8) / 8);
|
||||
} else {
|
||||
rowCount = 8;
|
||||
rowCount = this.state.maxMessageBytes;
|
||||
}
|
||||
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
|
|
|
@ -191,6 +191,12 @@ export default class CanLog extends Component {
|
|||
const msgHasSignals = Object.keys(msgEntry.signals).length > 0;
|
||||
const hasSignalsClass = msgHasSignals ? 'has-signals' : null;
|
||||
const expandedClass = msgIsExpanded ? 'is-expanded' : null;
|
||||
|
||||
const msgHexs = [];
|
||||
for (let i = 0; i < msgEntry.data.length; i += 8) {
|
||||
msgHexs.push(msgEntry.hexData.substring(i, Math.min(i + 8, msgEntry.data.length)));
|
||||
}
|
||||
|
||||
const row = (
|
||||
<div
|
||||
key={key}
|
||||
|
@ -208,14 +214,10 @@ export default class CanLog extends Component {
|
|||
</strong>
|
||||
</div>
|
||||
<div className="signals-log-list-time">
|
||||
<span>
|
||||
[
|
||||
{msgEntry.relTime.toFixed(3)}
|
||||
]
|
||||
</span>
|
||||
<span>[{msgEntry.relTime.toFixed(3)}]</span>
|
||||
</div>
|
||||
<div className="signals-log-list-bytes">
|
||||
<span className="t-mono">{msgEntry.hexData}</span>
|
||||
{ msgHexs.map((hx, i) => <span key={ i } className="t-mono">{ hx }</span> )}
|
||||
</div>
|
||||
</div>
|
||||
<div className="signals-log-list-item-body">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import DbcUtils from '../utils/dbc';
|
||||
|
||||
export default class MessageBytes extends Component {
|
||||
static propTypes = {
|
||||
seekTime: PropTypes.number.isRequired,
|
||||
|
@ -14,7 +16,8 @@ export default class MessageBytes extends Component {
|
|||
this.state = {
|
||||
isVisible: true,
|
||||
lastMessageIndex: 0,
|
||||
lastSeekTime: 0
|
||||
lastSeekTime: 0,
|
||||
maxMessageBytes: 8,
|
||||
};
|
||||
|
||||
this.onVisibilityChange = this.onVisibilityChange.bind(this);
|
||||
|
@ -22,8 +25,28 @@ export default class MessageBytes extends Component {
|
|||
this.updateCanvas = this.updateCanvas.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.componentDidUpdate({}, {});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.message !== this.props.message) {
|
||||
const maxMessageBytes = DbcUtils.maxMessageSize(this.props.message, this.state.maxMessageBytes);
|
||||
this.setState({ maxMessageBytes: maxMessageBytes });
|
||||
if (this.canvas) {
|
||||
this.canvas.height = Math.ceil(maxMessageBytes / 8) * 15 * window.devicePixelRatio;
|
||||
}
|
||||
}
|
||||
|
||||
if (prevProps.seekIndex !== this.props.seekIndex ||
|
||||
Math.floor(prevProps.seekTime * 60) !== Math.floor(this.props.seekTime * 60))
|
||||
{
|
||||
this.updateCanvas();
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (nextProps.live) {
|
||||
if (nextProps.live && nextProps.message.entries.length) {
|
||||
const nextLastEntry = nextProps.message.entries[nextProps.message.entries.length - 1];
|
||||
const curLastEntry = this.props.message.entries[
|
||||
this.props.message.entries.length - 1
|
||||
|
@ -34,14 +57,6 @@ export default class MessageBytes extends Component {
|
|||
return nextProps.seekTime !== this.props.seekTime;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.seekIndex !== this.props.seekIndex ||
|
||||
Math.floor(prevProps.seekTime * 60) !== Math.floor(this.props.seekTime * 60))
|
||||
{
|
||||
this.updateCanvas();
|
||||
}
|
||||
}
|
||||
|
||||
findMostRecentMessage(seekTime) {
|
||||
const { message } = this.props;
|
||||
const { lastMessageIndex, lastSeekTime } = this.state;
|
||||
|
@ -91,17 +106,16 @@ export default class MessageBytes extends Component {
|
|||
|
||||
for (let i = 0; i < message.byteStateChangeCounts.length; ++i) {
|
||||
const hexData = mostRecentMsg.hexData.substr(i * 2, 2);
|
||||
ctx.fillStyle = message.byteColors[i];
|
||||
|
||||
ctx.fillRect(i * 20, 0, 20, 15);
|
||||
const x = (i % 8) * 20;
|
||||
const y = Math.floor(i / 8) * 15;
|
||||
|
||||
ctx.fillStyle = message.byteColors[i];
|
||||
ctx.fillRect(x, y, 20, 15);
|
||||
|
||||
ctx.font = '12px Courier';
|
||||
ctx.fillStyle = 'white';
|
||||
if (hexData) {
|
||||
ctx.fillText(hexData, i * 20 + 2, 12);
|
||||
} else {
|
||||
ctx.fillText('-', i * 20 + 7, 12);
|
||||
}
|
||||
ctx.fillText(hexData ? hexData : '-', x + 2, y + 12);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +130,7 @@ export default class MessageBytes extends Component {
|
|||
|
||||
this.canvas = ref;
|
||||
this.canvas.width = 160 * window.devicePixelRatio;
|
||||
this.canvas.height = 15 * window.devicePixelRatio;
|
||||
this.canvas.height = Math.ceil(this.state.maxMessageBytes / 8) * 15 * window.devicePixelRatio;
|
||||
const ctx = this.canvas.getContext('2d');
|
||||
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
width: 160px;
|
||||
&-canvas {
|
||||
width: 160px;
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
&:not(.is-selected):hover {
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
}
|
||||
&-bytes {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
&-header {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
|
|
|
@ -174,25 +174,26 @@ export default class DBC {
|
|||
return {};
|
||||
}
|
||||
|
||||
createFrame(msgId) {
|
||||
createFrame(msgId, size=64) {
|
||||
console.log(this.messages, msgId);
|
||||
const msg = new Frame({
|
||||
name: this.nextNewFrameName(),
|
||||
id: msgId,
|
||||
size: 8
|
||||
size: size,
|
||||
});
|
||||
|
||||
this.messages.set(msgId, msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
setSignals(msgId, signals) {
|
||||
const msg = this.getMessageFrame(msgId);
|
||||
setSignals(msgId, signals, frameSize) {
|
||||
const msg = this.getMessageFrame(msgId); // TODO conform frameSize
|
||||
if (msg) {
|
||||
const newMsg = Object.assign(Object.create(msg), msg);
|
||||
newMsg.signals = signals;
|
||||
this.messages.set(msgId, newMsg);
|
||||
} else {
|
||||
const msg = this.createFrame(msgId);
|
||||
const msg = this.createFrame(msgId, frameSize);
|
||||
msg.signals = signals;
|
||||
|
||||
this.messages.set(msgId, msg);
|
||||
|
|
|
@ -146,7 +146,7 @@ function parseMessage(dbc, time, address, data, timeStart, lastParsedMessage) {
|
|||
hexData = Buffer.from(data).toString('hex');
|
||||
}
|
||||
const msgSpec = dbc.getMessageFrame(address);
|
||||
const msgSize = msgSpec ? msgSpec.size : 8;
|
||||
const msgSize = msgSpec ? msgSpec.size : Math.max(8, data.length);
|
||||
const relTime = time - timeStart;
|
||||
|
||||
const {
|
||||
|
@ -171,7 +171,7 @@ function parseMessage(dbc, time, address, data, timeStart, lastParsedMessage) {
|
|||
}
|
||||
|
||||
const BIG_ENDIAN_START_BITS = [];
|
||||
for (let i = 0; i < 64; i += 8) {
|
||||
for (let i = 0; i < 8 * 64; i += 8) {
|
||||
for (let j = 7; j > -1; j--) {
|
||||
BIG_ENDIAN_START_BITS.push(i + j);
|
||||
}
|
||||
|
@ -195,6 +195,17 @@ function setMessageByteColors(message, maxByteStateChangeCount) {
|
|||
return message;
|
||||
}
|
||||
|
||||
function maxMessageSize(message, initial = 8) {
|
||||
let max = initial;
|
||||
for (const entry of message.entries) {
|
||||
const data = Buffer.from(entry.hexData, 'hex');
|
||||
if (data.length > max) {
|
||||
max = data.length;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
export default {
|
||||
bigEndianBitIndex,
|
||||
addCanMessage,
|
||||
|
@ -204,5 +215,6 @@ export default {
|
|||
reparseMessage,
|
||||
findMaxByteStateChangeCount,
|
||||
setMessageByteColors,
|
||||
createMessageEntry
|
||||
createMessageEntry,
|
||||
maxMessageSize,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue