Skip to content

Commit

Permalink
feat: Parse transport info and async transport changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Oct 11, 2018
1 parent ec6e4b1 commit 2bfbd1e
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 134 deletions.
61 changes: 32 additions & 29 deletions src/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,49 @@
export type ResponseCode = ErrorCode | SynchronousCode | AsynchronousCode

export enum ErrorCode {
SyntaxError = 100,
UnsupportedParameter = 101,
InvalidValue = 102,
Unsupported = 103,
DiskFull = 104,
NoDisk = 105,
DiskError = 106,
TimelineEmpty = 107,
InternalError = 108,
OutOfRange = 109,
NoInput = 110,
RemoteControlDisabled = 111,
ConnectionRejected = 120,
InvalidState = 150,
InvalidCodec = 151,
InvalidFormat = 160,
InvalidToken = 161,
FormatNotPrepared = 162,
SyntaxError = 100,
UnsupportedParameter = 101,
InvalidValue = 102,
Unsupported = 103,
DiskFull = 104,
NoDisk = 105,
DiskError = 106,
TimelineEmpty = 107,
InternalError = 108,
OutOfRange = 109,
NoInput = 110,
RemoteControlDisabled = 111,
ConnectionRejected = 120,
InvalidState = 150,
InvalidCodec = 151,
InvalidFormat = 160,
InvalidToken = 161,
FormatNotPrepared = 162
}

export enum SynchronousCode {
OK = 200,
Notify = 209,
OK = 200,
DeviceInfo = 204,
TransportInfo = 208,
Notify = 209
}

export enum AsynchronousCode {
ConnectionInfo = 500,
ConnectionInfo = 500,
TransportInfo = 508
}

export enum ResponseCodeType {
Unknown,
Error,
Synchronous,
Asynchronous,
Unknown,
Error,
Synchronous,
Asynchronous
}

export function GetResponseCodeType (val: ResponseCode): ResponseCodeType {
if (val >= 100 && val <= 199) return ResponseCodeType.Error
if (val >= 200 && val <= 299) return ResponseCodeType.Synchronous
if (val >= 500 && val <= 599) return ResponseCodeType.Asynchronous
if (val >= 100 && val <= 199) return ResponseCodeType.Error
if (val >= 200 && val <= 299) return ResponseCodeType.Synchronous
if (val >= 500 && val <= 599) return ResponseCodeType.Asynchronous

return ResponseCodeType.Unknown
return ResponseCodeType.Unknown
}
108 changes: 54 additions & 54 deletions src/commands/abstractCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,68 +8,68 @@ export interface ErrorResponse extends ResponseMessage {
// }

export interface AbstractCommand {
expectedResponseCode: ResponseCode
expectedResponseCode: ResponseCode

handle(msg: ResponseMessage)
handle (msg: ResponseMessage)

//deserialize(msg: ResponseMessage): IResponse
serialize(): NamedMessage | null
// deserialize(msg: ResponseMessage): IResponse
serialize (): NamedMessage | null

markSent()
markSent ()
}

export abstract class AbstractCommandBase<T> implements Promise<T>, AbstractCommand {
abstract expectedResponseCode: ResponseCode

handle(msg: ResponseMessage) {
if (msg.Code === this.expectedResponseCode) {
this.resolve(this.deserialize(msg))
} else {
this.reject(msg)
}
}

abstract deserialize(msg: ResponseMessage): T
abstract serialize(): NamedMessage | null

private _promise: Promise<T>
protected resolve: (res: T) => void
protected reject: (res: ErrorResponse) => void

constructor() {
// TODO - can this be done any cleaner?
this._promise = new Promise<T>((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
}

then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2> {
return this._promise.then(onfulfilled, onrejected)
}

catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult> {
return this._promise.catch(onrejected)
}

[Symbol.toStringTag] // TODO what is this??

markSent() {
// TODO - track time sent
}
abstract expectedResponseCode: ResponseCode

handle (msg: ResponseMessage) {
if (msg.Code === this.expectedResponseCode) {
this.resolve(this.deserialize(msg))
} else {
this.reject(msg)
}
}

abstract deserialize (msg: ResponseMessage): T
abstract serialize (): NamedMessage | null

private _promise: Promise<T>
protected resolve: (res: T) => void
protected reject: (res: ErrorResponse) => void

constructor () {
// TODO - can this be done any cleaner?
this._promise = new Promise<T>((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
}

export abstract class AbstractCommandBaseNoResponse extends AbstractCommandBase<boolean>{
expectedResponseCode = SynchronousCode.OK
then<TResult1 = T, TResult2 = never> (onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2> {
return this._promise.then(onfulfilled, onrejected)
}

// markSent() {
// super.markSent()
// // No response will be received, so resolve the promise now
// this.resolve(true)
// }
catch<TResult = never> (onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult> {
return this._promise.catch(onrejected)
}

deserialize(msg: ResponseMessage) {
msg.Code
return true
}
[Symbol.toStringTag] // TODO what is this??

markSent () {
// TODO - track time sent
}
}

export abstract class AbstractCommandBaseNoResponse extends AbstractCommandBase<boolean> {
expectedResponseCode = SynchronousCode.OK

// markSent() {
// super.markSent()
// // No response will be received, so resolve the promise now
// this.resolve(true)
// }

deserialize (msg: ResponseMessage) {
msg.Code
return true
}
}
30 changes: 15 additions & 15 deletions src/commands/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ import { ResponseMessage } from '../message'
import { AbstractCommandBase } from './abstractCommand'

export interface ConnectionInfoResponse {
ProtocolVersion: number
Model: string
ProtocolVersion: number
Model: string
}

// Purpose of this is to emit the connect event with the connectionInfo
export class DummyConnectCommand extends AbstractCommandBase<ConnectionInfoResponse> {
expectedResponseCode = AsynchronousCode.ConnectionInfo
expectedResponseCode = AsynchronousCode.ConnectionInfo

deserialize (msg: ResponseMessage) {
const res: ConnectionInfoResponse = {
ProtocolVersion: parseFloat(msg.Params['protocol version']),
Model: msg.Params['model'],
}
return res
}
serialize () {
// Nothing to send
return null
}
}
deserialize (msg: ResponseMessage) {
const res: ConnectionInfoResponse = {
ProtocolVersion: parseFloat(msg.Params['protocol version']),
Model: msg.Params['model']
}
return res
}
serialize () {
// Nothing to send
return null
}
}
38 changes: 19 additions & 19 deletions src/commands/deviceInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@ import { ResponseMessage, NamedMessage } from '../message'
import { AbstractCommandBase } from './abstractCommand'

export interface DeviceInfoCommandResponse {
ProtocolVersion: number
Model: string
UniqueId: string
ProtocolVersion: number
Model: string
UniqueId: string
}

export class DeviceInfoCommand extends AbstractCommandBase<DeviceInfoCommandResponse> {
expectedResponseCode = SynchronousCode.Notify
expectedResponseCode = SynchronousCode.DeviceInfo

deserialize (msg: ResponseMessage) {
const res: DeviceInfoCommandResponse = {
ProtocolVersion: parseFloat(msg.Params['protocol version']),
Model: msg.Params['model'],
UniqueId: msg.Params['unique id'],
}
return res
}
serialize () {
const res: NamedMessage = {
Name: 'device info',
Params: {}
}
deserialize (msg: ResponseMessage) {
const res: DeviceInfoCommandResponse = {
ProtocolVersion: parseFloat(msg.Params['protocol version']),
Model: msg.Params['model'],
UniqueId: msg.Params['unique id']
}
return res
}
serialize () {
const res: NamedMessage = {
Name: 'device info',
Params: {}
}

return res
}
return res
}
}
1 change: 1 addition & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './deviceInfo'
export * from './notify'
export * from './record'
export * from './stop'
export * from './transportInfo'
2 changes: 1 addition & 1 deletion src/commands/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class RecordCommand extends AbstractCommandBaseNoResponse {
Params: {}
}

if (this.Filename) res.Params.Name = this.Filename
if (this.Filename) res.Params.name = this.Filename

return res
}
Expand Down
74 changes: 74 additions & 0 deletions src/commands/transportInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { SynchronousCode } from '../codes'
import { TransportStatus, SlotId, VideoFormat } from '../enums'
import { ResponseMessage, NamedMessage } from '../message'
import { AbstractCommandBase } from './abstractCommand'
import { parseIdOrNone, parseIntIfDefined, parseBool } from './util'

export interface TransportInfoCommandResponse {
Status: TransportStatus
Speed: number
SlotId: SlotId | null
ClipId: number | null
SingleClip: boolean
DisplayTimecode: string
Timecode: string
VideoFormat: VideoFormat
Loop: boolean
}

export class TransportInfoCommand extends AbstractCommandBase<TransportInfoCommandResponse> {
expectedResponseCode = SynchronousCode.TransportInfo

deserialize (msg: ResponseMessage) {
const res: TransportInfoCommandResponse = {
Status: msg.Params['status'] as TransportStatus,
Speed: parseInt(msg.Params['speed']),
SlotId: parseIdOrNone(msg.Params['slot id']) || null,
ClipId: parseIdOrNone(msg.Params['clip id']) || null,
SingleClip: parseBool(msg.Params['single clip']) || false,
DisplayTimecode: msg.Params['display timecode'],
Timecode: msg.Params['timecode'],
VideoFormat: msg.Params['video format'] as VideoFormat,
Loop: parseBool(msg.Params['loop']) || false,
}
return res
}
serialize () {
const res: NamedMessage = {
Name: 'transport info',
Params: {}
}

return res
}
}

export interface TransportInfoChangeResponse {
Status: TransportStatus | undefined
Speed: number | undefined
SlotId: SlotId | null | undefined
ClipId: number | null | undefined
SingleClip: boolean | undefined
DisplayTimecode: string | undefined
Timecode: string | undefined
VideoFormat: VideoFormat | undefined
Loop: boolean | undefined
}

export class TransportInfoChange {

deserialize (msg: ResponseMessage) {
const res: TransportInfoChangeResponse = {
Status: msg.Params['status'] as TransportStatus,
Speed: parseIntIfDefined(msg.Params['speed']),
SlotId: parseIdOrNone(msg.Params['slot id']),
ClipId: parseIdOrNone(msg.Params['clip id']),
SingleClip: parseBool(msg.Params['single clip']),
DisplayTimecode: msg.Params['display timecode'],
Timecode: msg.Params['timecode'],
VideoFormat: msg.Params['video format'] as VideoFormat,
Loop: parseBool(msg.Params['loop']),
}
return res
}
}
Loading

0 comments on commit 2bfbd1e

Please sign in to comment.