Skip to content

Commit

Permalink
This commit took about three hours
Browse files Browse the repository at this point in the history
  • Loading branch information
henrycatalinismith committed Oct 9, 2017
1 parent 3c628ad commit 77fe402
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 182 deletions.
32 changes: 32 additions & 0 deletions actions/connections.js
@@ -1,6 +1,10 @@
export const CREATE_CONNECTION = "CREATE_CONNECTION";
export const UPDATE_CONNECTION = "UPDATE_CONNECTION";

export const IMAGINE_CONNECTION = "IMAGINE_CONNECTION";
export const REALIZE_CONNECTION = "REALIZE_CONNECTION";
export const ABANDON_CONNECTION = "ABANDON_CONNECTION";

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 9, 2017

Author Owner

Okay so I think Redux work is shitloads more fun and vivid if you work super hard on the action type naming. I like making little repeatable clusters of cool descriptive names like these cos it feels like a really nice lightweight kind of architecture work.

IMAGINE_CONNECTION

This is when you start dragging a terminal around and you're kind of plotting a hypothetical new connection. The normal zero-imagination way of doing this would be like dispatch(action.createConnection()) with a bunch of props that implicitly mark out the new connection object as kind of imaginary in the sense that it lacks a solid destinationId yet. I think it's loads nicer to have that just be a separate action type altogether.

REALIZE_CONNECTION

This is when you drag the terminal to a new station, thus indicating which two stations you want to connect. It "makes the connection real". I'm a bit of a weirdo about the action type names having the same length as their little siblings in the cluster lol.

ABANDON_CONNECTION

This is if you drop the terminal before connecting to a destination station. It triggers all the cleanup i.e. deleting the connection and the tracks.


export function createConnection(connection) {
return {
type: CREATE_CONNECTION,
Expand All @@ -14,3 +18,31 @@ export function updateConnection(connection) {
connection
};
}

export function imagineConnection({
connectionId,
lineId,
sourceId,
terminalId
}) {
return {
type: IMAGINE_CONNECTION,
connection: { id: connectionId },
line: { id: lineId },
source: { id: sourceId },
terminal: { id: terminalId }
};

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 9, 2017

Author Owner

ive started doing lots of precomputing of "business logic" in middlewares, so that one action can update multiple bits of the store without having to redispatch shitloads of sub-actions for one user interaction. maybe this is more of a gamedev optimization, but it resonates a lot with this other thing i read the other day about doing very little in reducers.

Do more in action-creators and less in reducers
I think this one is very important although it may not be immediately obvious. Business logic belongs in action creators. Reducers should be simple. In many individual cases it does not matter- but consistency is good and so it's best to consistently do this

that person's probably using redux-thunk which is why they say do it in action creators. in this app that stuff's going in the middlewares. anyway this little schema in the action creators helps a shitload with that cos it's so consistent and repeatable and it means things are always where you expect them and you never have to wonder if they're in action.connection.lineId or action.lineId or action.id depending on what "type" of action it is

}

export function realizeConnection({ destinationId }) {
return {
type: REALIZE_CONNECTION,
destination: { id: destinationId }
};
}

export function abandonConnection() {
return {
type: ABANDON_CONNECTION
};
}
37 changes: 0 additions & 37 deletions actions/dragon.js
@@ -1,14 +1,7 @@
// keep
export const DRAGON_DROP = "DRAGON_DROP";
export const DRAGON_GRAB = "DRAGON_GRAB";
export const DRAGON_MOVE = "DRAGON_MOVE";

// deprecate
export const DRAGON_DRAG_TERMINAL = "DRAGON_DRAG_TERMINAL";
export const DRAGON_GRAB_TERMINAL = "DRAGON_GRAB_TERMINAL";
export const DRAGON_DROP_TERMINAL = "DRAGON_DROP_TERMINAL";
export const DRAGON_CREATE_CONNECTION = "DRAGON_CREATE_CONNECTION";

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 9, 2017

Author Owner

hahaha these // keep and // deprecate comments were the entire notes i left to myself from yesterday and i had to fuckin rebuild the entire thought process behind this commit from scratch tonight so that i could actually type in all the code changes, which is why im making really fuckin sure to leave myself better notes tonight 😂

export function dragonDrop(entity, id) {
return {
type: DRAGON_DROP,
Expand All @@ -29,33 +22,3 @@ export function dragonMove(x, y) {
dragon: { x, y }
};
}

export function dragonGrabTerminal(id) {
return {
type: DRAGON_GRAB_TERMINAL,
terminal: { id }
};
}

export function dragonMoveTerminal(x, y, id) {
return {
type: DRAGON_DRAG_TERMINAL,
x,
y,
id
};
}

export function dragonDropTerminal(id) {
return {
type: DRAGON_DROP_TERMINAL,
terminal: { id }
};
}

export function dragonCreateConnection(destinationId) {
return {
type: DRAGON_CREATE_CONNECTION,
connection: { destinationId }
};

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 9, 2017

Author Owner

look what a horrible mess all these action creators were. it was like a custom snowflake schema for every single one. nonononono stop this forever

}
4 changes: 1 addition & 3 deletions actions/terminals.js
Expand Up @@ -37,9 +37,7 @@ export function dropTerminal(selection) {
export function dragTerminal(terminalId, x, y) {
return {
type: DRAG_TERMINAL,
terminalId,
x,
y
terminal: { id: terminalId, x, y }
};
}

Expand Down
7 changes: 4 additions & 3 deletions components/Station.js
Expand Up @@ -15,7 +15,7 @@ export class Station extends React.Component {

selectStation: PropTypes.func,
deselectStation: PropTypes.func,
createConnection: PropTypes.func
realizeConnection: PropTypes.func
};

constructor() {
Expand All @@ -33,7 +33,7 @@ export class Station extends React.Component {
if (dragon.entity !== "terminal") {
return;
}
this.props.createConnection(this.props.id);
this.props.realizeConnection(this.props.id);
}

render() {
Expand Down Expand Up @@ -86,7 +86,8 @@ const mapDispatchToProps = dispatch => {
return {
selectStation: id => dispatch(actions.grabStation(id)),
deselectStation: id => dispatch(actions.dragonDrop("station", id)),
createConnection: id => dispatch(actions.dragonCreateConnection(id))
realizeConnection: id =>
dispatch(actions.realizeConnection({ destinationId: id }))
};
};

Expand Down
62 changes: 62 additions & 0 deletions middlewares/connections.js
@@ -1,6 +1,7 @@
import { createMiddleware } from "signalbox";
import uuid from "uuid/v1";
import actions from "../actions";
import { select } from "../reducers";

export const middleware = createMiddleware((before, after, cancel) => ({
[before(actions.CREATE_CONNECTION)]: function inferConnectionProperties(
Expand All @@ -10,5 +11,66 @@ export const middleware = createMiddleware((before, after, cancel) => ({
if (!action.connection.id) {
action.connection.id = uuid();
}
},

[before(actions.IMAGINE_CONNECTION)]: function inferConnectionProperties(

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 9, 2017

Author Owner

wait wtf this has the same name as the one on line 6 why does this work

store,
action
) {
if (!action.connection.id) {
action.connection.id = uuid();
}

action.sourceTerminal = {
id: uuid(),
connectionId: action.connection.id,
stationId: action.source.id,
lineId: "Riverside" // todo: pick 1st empty line for this

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 9, 2017

Author Owner

ugh i really need to sort out this todo soon dont i

};

action.destinationTerminal = {
id: uuid(),
connectionId: action.connection.id,
lineId: "Riverside"
};
},

[before(actions.REALIZE_CONNECTION)]: function hydrateNewlyRealizedConnection(
store,
action
) {
const state = store.getState();
const connection = select("connections")
.from(state)
.imaginary()
.toJS();
action.connection = { id: connection.id };
action.line = { id: connection.lineId };
action.source = { id: connection.sourceId };
},

[after(actions.REALIZE_CONNECTION)]: function imagineNextConnection(
store,
action
) {
const imagineConnection = actions.imagineConnection({
sourceId: action.destination.id,
lineId: "Riverside" // todo: pick 1st empty line for this
});
store.dispatch(imagineConnection);
},

[before(actions.ABANDON_CONNECTION)]: function hydrateNewlyRealizedConnection(
store,
action
) {
const state = store.getState();
const connection = select("connections")
.from(state)
.imaginary()
.toJS();
action.connection = { id: connection.id };
action.line = { id: connection.lineId };
action.source = { id: connection.sourceId };
}
}));
95 changes: 7 additions & 88 deletions middlewares/dragon.js
Expand Up @@ -9,7 +9,7 @@ export const middleware = createMiddleware((before, after, cancel) => ({
action
) {
if (action.dragon.entity === "terminal" && !!action.dragon.id) {
store.dispatch(actions.dragonDropTerminal(action.dragon.id));
store.dispatch(actions.abandonConnection());
return true;
}
},
Expand All @@ -24,7 +24,7 @@ export const middleware = createMiddleware((before, after, cancel) => ({

if (entity === "terminal" && !!id) {
store.dispatch(
actions.dragonMoveTerminal(action.dragon.x, action.dragon.y, id)
actions.dragTerminal(id, action.dragon.x, action.dragon.y)
);
return true;
}
Expand All @@ -37,93 +37,12 @@ export const middleware = createMiddleware((before, after, cancel) => ({
action
) {
const stationId = action.station.id;
const connectionId = uuid();
const terminalId = uuid();

store.dispatch(
actions.createConnection({
id: connectionId,
sourceId: stationId,
lineId: "Riverside" // todo: pick 1st empty line for this
})
);

store.dispatch(
actions.createTerminal({
id: uuid(),
connectionId,
stationId,
lineId: "Riverside" // todo: pick 1st empty line for this
})
);

store.dispatch(
actions.createTerminal({
id: terminalId,
connectionId,
lineId: "Riverside" // todo: pick 1st empty line for this
})
);

store.dispatch(actions.dragonGrabTerminal(terminalId));

return true;
},

[cancel(actions.DRAGON_CREATE_CONNECTION)]: function finishCreatingConnection(
store,
action
) {
const state = store.getState();

const dragon = store
.getState()
.get("dragon")
.toJS();

const terminal = select("terminals")
.from(state)
.byId(dragon.id)
.toJS();

const connection = select("connections")
.from(state)
.byId(terminal.connectionId)
.toJS();

const lineId = connection.lineId;
const sourceId = connection.sourceId;
const destinationId = action.connection.destinationId;

if (sourceId === destinationId) {
// this has only fired because the mouse has re-entered the origin
// station and obviously we don't want to connect the station to itself
// so just cancel this completely
return true;
}

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 9, 2017

Author Owner

oops this check seems to be gone from the new version lol TODO: add TODO comment about fixing this again


store.dispatch(
actions.updateConnection({
id: connection.id,
destinationId
})
);

const newId = uuid();
store.dispatch(
actions.createConnection({
id: newId,
sourceId: destinationId,
lineId: "Riverside" // todo: pick 1st empty line for this
})
);

store.dispatch(
actions.updateTerminal({
id: terminal.id,
connectionId: newId
})
);
const imagineConnection = actions.imagineConnection({
sourceId: action.station.id,
lineId: "Riverside" // todo: pick 1st empty line for this
});
store.dispatch(imagineConnection);

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 9, 2017

Author Owner

probably ought to transition all the store.dispatch(actions.whatever()) calls over to this pattern cos it can be bloody useful for debugging this way sometimes

This comment has been minimized.

Copy link
@henrycatalinismith

henrycatalinismith Oct 10, 2017

Author Owner

noooooooooooooo

screen shot 2017-10-10 at 19 13 46


return true;
}
Expand Down
33 changes: 0 additions & 33 deletions middlewares/terminals.js
Expand Up @@ -62,38 +62,5 @@ export const middleware = createMiddleware((before, after, cancel) => ({
})
);
}
},

[after(actions.DRAGON_DROP_TERMINAL)](store, action) {
const { id: terminalId } = action.terminal;
const state = store.getState();

const terminal = select("terminals")
.from(state)
.byId(terminalId)
.toJS();

const lineId = terminal.lineId;
const connection = select("connections")
.from(state)
.byId(terminal.connectionId)
.toJS();

const tracks = select("tracks")
.from(state)
.byConnectionId(connection.id)
.toJS();

const otherTerminal = select("terminals")
.from(state)
.byLineAndStation(lineId, connection.sourceId);

store.dispatch(actions.deleteTerminal(terminal.id));

if (otherTerminal) {
store.dispatch(actions.deleteTerminal(otherTerminal.get("id")));
}

tracks.forEach(track => store.dispatch(actions.deleteTrack(track.id)));
}
}));

0 comments on commit 77fe402

Please sign in to comment.