-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
74ddb0e
commit 3aaea78
Showing
7 changed files
with
205 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { Commands, Enums } from '..' | ||
|
||
import DataTransfer from './dataTransfer' | ||
|
||
/** | ||
* Macros don't have a lock so this is just a queue with the API of a lock. | ||
*/ | ||
export default class MacroLock { | ||
private taskQueue: Array<DataTransfer> = [] | ||
|
||
public activeTransfer: DataTransfer | undefined | ||
|
||
private queueCommand: (cmd: Commands.ISerializableCommand) => void | ||
|
||
constructor(queueCommand: (cmd: Commands.ISerializableCommand) => void) { | ||
this.queueCommand = queueCommand | ||
} | ||
|
||
public enqueue(transfer: DataTransfer): Promise<DataTransfer> { | ||
this.taskQueue.push(transfer) | ||
if (!this.activeTransfer || this.activeTransfer.state === Enums.TransferState.Finished) { | ||
this.dequeueAndRun() | ||
} | ||
|
||
return transfer.promise | ||
} | ||
|
||
private dequeueAndRun(): void { | ||
if ( | ||
(this.activeTransfer === undefined || this.activeTransfer.state === Enums.TransferState.Finished) && | ||
this.taskQueue.length > 0 | ||
) { | ||
this.activeTransfer = this.taskQueue.shift() | ||
this.activeTransfer?.gotLock().forEach((cmd) => this.queueCommand(cmd)) | ||
} | ||
} | ||
|
||
public lockObtained(): void { | ||
// I don't know what this means, let's hope it never happens | ||
} | ||
|
||
public lostLock(): void { | ||
// can't lose a lock if you don't have a lock | ||
} | ||
|
||
public updateLock(): void { | ||
// | ||
} | ||
|
||
public transferFinished(): void { | ||
// great, no need to do anything, the transfer will have ack'ed already | ||
} | ||
|
||
public transferErrored(code: number): void { | ||
if (this.activeTransfer) { | ||
switch (code) { | ||
case 1: // Probably means "retry". | ||
this.activeTransfer.start().forEach((cmd) => this.queueCommand(cmd)) | ||
break | ||
case 2: // Unknown: looks like macro not found | ||
case 3: // Unknown. | ||
case 4: // Unknown. | ||
case 5: // Might mean "You don't have the lock"? | ||
default: | ||
// Abort the transfer. | ||
// @todo: dequeue any old commands | ||
this.activeTransfer.rejectPromise(new Error(`Code ${code}`)) | ||
this.activeTransfer = undefined | ||
this.dequeueAndRun() | ||
} | ||
} else { | ||
this.activeTransfer = undefined | ||
this.dequeueAndRun() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { DownloadRequestType, TransferMode, TransferState } from '../enums' | ||
import { Commands } from '..' | ||
|
||
import DataTransfer from './dataTransfer' | ||
import DataTransferFrame from './dataTransferFrame' | ||
|
||
export class DataDownloadMacro extends DataTransfer { | ||
public data = Buffer.from([]) | ||
public curFrame = 0 | ||
|
||
constructor(transferId: number, public readonly macroIndex: number) { | ||
super(transferId, 255) | ||
} | ||
|
||
public start(): Commands.ISerializableCommand[] { | ||
const commands: Commands.ISerializableCommand[] = [ | ||
new Commands.DataTransferDownloadRequestCommand({ | ||
transferId: this.transferId, | ||
transferStoreId: 0xffff, | ||
transferIndex: this.macroIndex, | ||
transferType: DownloadRequestType.Macro, | ||
}) | ||
] | ||
return commands | ||
} | ||
|
||
public handleCommand(command: Commands.IDeserializedCommand): Commands.ISerializableCommand[] { | ||
const commands: Commands.ISerializableCommand[] = [] | ||
|
||
if (command.constructor.name === Commands.DataTransferDataCommand.name) { | ||
this.data = (command as Commands.DataTransferDataCommand).properties.body | ||
|
||
// todo - have we received all data? maybe check if the command.body < max_len | ||
|
||
commands.push(new Commands.DataTransferAckCommand({ | ||
transferId: this.transferId, | ||
transferIndex: this.macroIndex | ||
})) | ||
this.state = TransferState.Finished | ||
this.resolvePromise(this) | ||
} | ||
|
||
return commands | ||
} | ||
|
||
public gotLock(): Commands.ISerializableCommand[] { | ||
// yeah so locks don't exist here... | ||
return this.start() | ||
} | ||
} | ||
|
||
|
||
export class DataUploadMacro extends DataTransferFrame { | ||
|
||
constructor(transferId: number, public readonly macroIndex: number, public readonly data: Buffer, private name: string) { | ||
super(transferId, 255, 0, data) | ||
} | ||
|
||
public start(): Commands.ISerializableCommand[] { | ||
const commands: Commands.ISerializableCommand[] = [ | ||
new Commands.DataTransferUploadRequestCommand({ | ||
transferId: this.transferId, | ||
transferStoreId: 0xffff, | ||
transferIndex: this.macroIndex, | ||
size: this.data.length, | ||
mode: TransferMode.Write2 | TransferMode.Clear2, | ||
}) | ||
] | ||
return commands | ||
} | ||
|
||
public handleCommand (command: Commands.IDeserializedCommand): Commands.ISerializableCommand[] { | ||
const res = super.handleCommand(command) | ||
|
||
if (this.state === TransferState.Finished) { | ||
this.resolvePromise(this) | ||
} | ||
|
||
return res | ||
} | ||
|
||
public sendDescription(): Commands.ISerializableCommand { | ||
return new Commands.DataTransferFileDescriptionCommand({ | ||
name: this.name, | ||
fileHash: '', | ||
transferId: this.transferId, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters