Skip to content

Commit

Permalink
feat: work towards drawables
Browse files Browse the repository at this point in the history
  • Loading branch information
micahg committed Jan 22, 2025
1 parent 736a978 commit f09c196
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 17 deletions.
5 changes: 3 additions & 2 deletions packages/common/src/tokeninstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* IMPORTANT: Do not change the interfaces in this file without also reviewing the corresponding
* mongoose models and (if applicable) omitting/redefining the types.
*/
import { Token } from "./token";
import { HydratedToken, Token } from "./token";

/**
* Token placement properties without knowing the scene details
Expand All @@ -18,6 +18,7 @@ export interface TokenInstance extends ScenelessTokenInstance{
scene: string;
}

// TODO remove "scene" from this interface since once hydrated we know which scene its from
export interface HydratedTokenInstance extends Omit<TokenInstance, "token"> {
"token": string;
"token": string; // technically an url not an object id
}
5 changes: 5 additions & 0 deletions packages/mui/src/middleware/ContentMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ export const ContentMiddleware: Middleware =
return next(action);
}

if (!state.content.mediaPrefix) {
// I suppose when we use R2 or S3, this will be different (and likely from the environment config)
next({ type: "content/mediaprefix", payload: state.environment.api });
}

switch (action.type) {
case "content/updatetoken": {
operate(state, store, next, "put", "token", action);
Expand Down
8 changes: 7 additions & 1 deletion packages/mui/src/reducers/ContentReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type ContentReducerError = {
};

export type ContentReducerState = {
readonly mediaPrefix?: string;
readonly pushTime: number | undefined;
readonly currentScene?: Scene;
readonly scenes: Scene[];
Expand All @@ -39,6 +40,8 @@ const initialState: ContentReducerState = {

export const ContentReducer = (state = initialState, action: PayloadAction) => {
switch (action.type) {
case "content/mediaprefix":
return { ...state, mediaPrefix: action.payload as unknown as string };
case "content/push":
return { ...state, pushTime: new Date().getTime() };
case "content/pull": {
Expand Down Expand Up @@ -169,7 +172,10 @@ export const ContentReducer = (state = initialState, action: PayloadAction) => {
);
continue;
}
hydrated.push({ ...instance, token: asset.location });
hydrated.push({
...instance,
token: `${state.mediaPrefix}/${asset.location}`,
});
}

scenes[idx] = { ...scenes[idx], tokens: hydrated };
Expand Down
20 changes: 15 additions & 5 deletions packages/mui/src/utils/contentworker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import {
adjustTokenDimensions,
} from "./geometry";
import {
HydratedToken,
HydratedTokenInstance,
Rect,
ScenelessTokenInstance,
} from "@micahg/tbltp-common";
import { fromHydratedToken } from "./tokens";

/**
* Worker for offscreen drawing in the content editor.
Expand All @@ -47,7 +48,7 @@ let _max_zoom: number;
let _first_zoom_step: number;
let _things_on_top_of_overlay = false;
let _default_token: ImageBitmap;
let _token: HydratedToken | undefined = undefined;
let _token: HydratedTokenInstance | undefined = undefined;

// canvas width and height (sent from main thread)
const _canvas: Rect = { x: 0, y: 0, width: 0, height: 0 };
Expand Down Expand Up @@ -331,6 +332,8 @@ function eraseBrush(x: number, y: number, radius: number) {
function renderToken(x: number, y: number, full = true) {
if (!full) {
overlayCtx.save();
if (_token) [_token.x, _token.y] = [x, y];

// may be best to not translate since we're scaling
overlayCtx.translate(-_token_dw / 2, -_token_dh / 2);
overlayCtx.drawImage(
Expand Down Expand Up @@ -559,7 +562,7 @@ async function updateThings(

const promises: Promise<Drawable>[] = [];
for (const thing of things.filter((thing) => thing)) {
promises.push(createDrawable(thing, apiUrl, bearer));
promises.push(createDrawable(thing, bearer));
}
let drawables: Drawable[];
try {
Expand Down Expand Up @@ -771,8 +774,15 @@ self.onmessage = async (evt) => {
}
case "set_token": {
if ("token" in evt.data && "bearer" in evt.data) {
_token = evt.data.token;
const location = _token?.asset?.location;
// hiMicah();
// _token = evt.data.token; // HydratedToken
// const hydrated = fromHydratedToken(evt.data.token);
// console.log(hydrated);
_token = fromHydratedToken(evt.data.token);
const dt = await createDrawable(_token, evt.data.bearer);
console.log(dt);
// const d = createDrawable(_token, evt.data.bearer);
const location = _token.token;
if (location) {
loadImage(location, evt.data.bearer)
.then((img) => setToken(img))
Expand Down
40 changes: 31 additions & 9 deletions packages/mui/src/utils/drawing.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* FOR TESTING THE MAIN SCENE IS 66106a4b867826e1074c9476
* to remove from the other scene:
* db.tokeninstances.remove({scene: ObjectId("66106a6e867826e1074c9484")})
*/

import { Rect, HydratedTokenInstance } from "@micahg/tbltp-common";
import { loadImage } from "./content";

Expand All @@ -18,6 +24,8 @@ type BitmapCache = {
[key: string]: ImageBitmap;
};

let DEFAULT_TOIKEN: ImageBitmap;

Check failure on line 27 in packages/mui/src/utils/drawing.ts

View workflow job for this annotation

GitHub Actions / test_mui

'DEFAULT_TOIKEN' is defined but never used

const cache: BitmapCache = {};

export function isRect(d: unknown): d is Rect {
Expand Down Expand Up @@ -55,12 +63,11 @@ export type Marker = {

export async function createDrawable<T = Rect>(
d: T,
apiUrl: string,
bearer: string,
): Promise<Drawable> {
if (isRect(d)) return new DrawableSelectedRegion(d);
if (isHydratedTokenInstnace(d)) {
const img = await cacheTokenImage(apiUrl, d.token, bearer);
const img = await cacheTokenImage(d.token, bearer);
return new DrawableToken(d, img);
}
throw new TypeError("Invalid Drawable");
Expand Down Expand Up @@ -96,15 +103,11 @@ class DrawableSelectedRegion implements Drawable {
}

// TODO try with bad link and see what happens before merging - ideally fallack to X
async function cacheTokenImage(
apiUrl: string,
location: string,
bearer: string,
) {
async function cacheTokenImage(location: string, bearer: string) {
if (location in cache) return cache[location];
console.warn(`Cache miss for token ${location}`);
const url = `${apiUrl}/${location}`;
const img = await loadImage(url, bearer);

const img = await loadImage(location || "/x.webp", bearer);
cache[location] = img;
return img;
}
Expand All @@ -116,6 +119,25 @@ class DrawableToken implements Drawable {
this.token = token;
this.img = img;
}
place(ctx: DrawContext) {
// TODO: don't draw if not in region
const [_token_dw, _token_dh] = [this.img.width, this.img.height];
ctx.translate(-_token_dw / 2, -_token_dh / 2);
ctx.drawImage(
this.img,
// source (should always just be source dimensions)
0,
0,
this.img.width,
this.img.height,
// destination (adjust according to scale)
this.token.x,
this.token.y,
_token_dw,
_token_dh,
);
}

draw(ctx: DrawContext) {
// TODO: don't draw if not in region
const [_token_dw, _token_dh] = [this.img.width, this.img.height];
Expand Down
13 changes: 13 additions & 0 deletions packages/mui/src/utils/tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { HydratedToken, HydratedTokenInstance } from "@micahg/tbltp-common";

export function fromHydratedToken(d: HydratedToken): HydratedTokenInstance {
return {
name: d.name,
visible: false,
token: d.asset?.location || "",
scene: "",
x: 0,
y: 0,
scale: 1,
};
}

0 comments on commit f09c196

Please sign in to comment.