Working streams
This commit is contained in:
@@ -11,6 +11,7 @@ node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
circles-pictures
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Stroke } from "./canvas-state";
|
||||
|
||||
export type ListenCallbackParam = { strokeId: number, stroke: Stroke }
|
||||
export type StrokeStreamElement = { strokeId: number, stroke: Stroke }
|
||||
|
||||
export type OnStrokeCallback = (state: StrokeStreamElement) => void
|
||||
@@ -29,23 +29,19 @@ export class ClientDrawService {
|
||||
private readonly drawer = document.getElementById('drawer')!,
|
||||
private readonly closeButton = document.getElementById('closeButton')!,
|
||||
) {
|
||||
this.resizeCanvas()
|
||||
this.setupCanvasEvents()
|
||||
window.addEventListener("resize", () => this.resizeCanvas());
|
||||
this.cctx = canvas.getContext("2d")!
|
||||
this.currentColor = colorPicker!.getAttribute('value')!
|
||||
this.currentDensity = Number(densitySlider!.getAttribute('value'))!
|
||||
this.currentWidth = Number(widthSlider!.getAttribute('value'))!
|
||||
|
||||
this.cctx = canvas.getContext("2d")!
|
||||
}
|
||||
|
||||
draw() {
|
||||
|
||||
console.log("drawing")
|
||||
const strokes: Stroke[] = this.stateService.getStrokes()
|
||||
|
||||
this.cctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
|
||||
this.cctx.globalAlpha = 1;
|
||||
strokes.forEach(stroke => {
|
||||
this.cctx.fillStyle = stroke.color;
|
||||
this.drawCurve(stroke.points, stroke.density, stroke.width)
|
||||
@@ -132,12 +128,6 @@ export class ClientDrawService {
|
||||
|
||||
}
|
||||
|
||||
private resizeCanvas() {
|
||||
const size = Math.min(window.innerWidth, window.innerHeight) * 0.9;
|
||||
this.canvas.width = size;
|
||||
this.canvas.height = size;
|
||||
}
|
||||
|
||||
private drawCurve(points: Point[], density: number, width: number) {
|
||||
if (points.length < 2) return;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RPCSocket } from "../../../../node_modules/rpclibrary/js/Index";
|
||||
import { CanvasState, Point, Stroke } from "../../model/canvas-state";
|
||||
import { ListenCallbackParam } from "../../model/rpc-callbacks";
|
||||
import { StrokeStreamElement } from "../../model/rpc-callbacks";
|
||||
import { ClientDrawService } from "../draw/draw.client-service";
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ export class ClientStateService {
|
||||
const sock = await new RPCSocket(8080, 'localhost').connect();
|
||||
this.remoteService = sock['StateService']
|
||||
this.canvasState = await this.getState()
|
||||
await this.remoteService.listen((listenDto: ListenCallbackParam) => {
|
||||
if(!this.canvasState.strokes[listenDto.strokeId]){
|
||||
this.canvasState.strokes[listenDto.strokeId] = listenDto.stroke
|
||||
await this.remoteService.onStroke((s: StrokeStreamElement) => {
|
||||
if(!this.canvasState.strokes[s.strokeId]){
|
||||
this.canvasState.strokes[s.strokeId] = s.stroke
|
||||
}else{
|
||||
this.canvasState.strokes[listenDto.strokeId].points = [...this.canvasState.strokes[listenDto.strokeId].points, ...listenDto.stroke.points]
|
||||
this.canvasState.strokes[s.strokeId].points = [...this.canvasState.strokes[s.strokeId].points, ...s.stroke.points]
|
||||
}
|
||||
drawService.draw()
|
||||
})
|
||||
|
||||
@@ -13,6 +13,8 @@ export class ExpressService implements Initializable {
|
||||
@Inject(StateService)
|
||||
private stateService: StateService;
|
||||
|
||||
private connectionCount = 0;
|
||||
|
||||
initialize() {
|
||||
const app = express();
|
||||
const PORT = 8080;
|
||||
@@ -28,7 +30,15 @@ export class ExpressService implements Initializable {
|
||||
const rpcServer = new RPCServer([
|
||||
this.stateService,
|
||||
|
||||
])
|
||||
], {
|
||||
closeHandler: (socket) => {
|
||||
this.connectionCount -= 1
|
||||
if(this.connectionCount === 0){
|
||||
this.stateService.finalizePicture()
|
||||
}
|
||||
},
|
||||
connectionHandler: (socket) => { this.connectionCount += 1 },
|
||||
})
|
||||
rpcServer.attach(httpServer)
|
||||
rpcServer.listen(PORT)
|
||||
|
||||
|
||||
@@ -1,43 +1,59 @@
|
||||
import { Singleton, Initializable } from "depents";
|
||||
import { RPCExporter } from "rpclibrary";
|
||||
import { CanvasState, Point, Stroke } from "../../../client/model/canvas-state";
|
||||
import { ListenCallbackParam } from "../../../client/model/rpc-callbacks";
|
||||
import { OnStrokeCallback } from "../../../client/model/rpc-callbacks";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
@Singleton()
|
||||
export class StateService implements Initializable, RPCExporter {
|
||||
name = 'StateService' as const
|
||||
|
||||
private canvasState: CanvasState = { strokes: [] }
|
||||
private clients: Array<(param: ListenCallbackParam) => void> = []
|
||||
private onStrokeCallbacks: Array<OnStrokeCallback> = []
|
||||
|
||||
initialize() {
|
||||
this.canvasState = { strokes: [] }
|
||||
this.clients = []
|
||||
this.onStrokeCallbacks = []
|
||||
};
|
||||
|
||||
beginStroke = async (stroke: Stroke) => {
|
||||
const strokeId = this.canvasState.strokes.length
|
||||
this.canvasState.strokes.push(stroke)
|
||||
this.updateclients(strokeId, stroke)
|
||||
this.updateStrokeListeners(strokeId, stroke)
|
||||
return strokeId
|
||||
}
|
||||
|
||||
addPoint = async (strokeId: number, point: Point) => {
|
||||
this.canvasState.strokes[strokeId].points.push(point)
|
||||
this.updateclients(strokeId, { ...this.canvasState.strokes[strokeId], points: [point] })
|
||||
this.updateStrokeListeners(strokeId, { ...this.canvasState.strokes[strokeId], points: [point] })
|
||||
}
|
||||
|
||||
listen = async (callback: (state: any) => Promise<void>) => {
|
||||
this.clients = [...this.clients, callback]
|
||||
return this.canvasState
|
||||
onStroke = async (callback: OnStrokeCallback) => {
|
||||
this.onStrokeCallbacks = [...this.onStrokeCallbacks, callback]
|
||||
return
|
||||
}
|
||||
|
||||
getState = async (): Promise<CanvasState> => {
|
||||
return this.canvasState
|
||||
}
|
||||
|
||||
private updateclients = (strokeId: number, stroke: Stroke) => {
|
||||
this.clients.forEach((client) => {
|
||||
finalizePicture = () => {
|
||||
const finalState = { ...this.canvasState }
|
||||
this.canvasState = { strokes: [] }
|
||||
|
||||
const picturedir = path.join(__dirname, `../../../../circles-pictures/`);
|
||||
|
||||
if (!fs.existsSync(picturedir)) {
|
||||
fs.mkdirSync(picturedir);
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(picturedir, `${Date.now()}.json`), JSON.stringify(finalState))
|
||||
console.log(finalState)
|
||||
}
|
||||
|
||||
private updateStrokeListeners = (strokeId: number, stroke: Stroke) => {
|
||||
this.onStrokeCallbacks.forEach((client) => {
|
||||
client({ strokeId, stroke })
|
||||
})
|
||||
}
|
||||
@@ -47,8 +63,8 @@ export class StateService implements Initializable, RPCExporter {
|
||||
this.addPoint,
|
||||
this.getState,
|
||||
{
|
||||
name: 'listen' as const,
|
||||
hook: (cb: any) => { this.listen(cb) }
|
||||
name: 'onStroke' as const,
|
||||
hook: this.onStroke,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user