Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix avatar marker #721

Merged
merged 10 commits into from
Aug 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion aimmo/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ def connection_parameters(request, game_id):
LOGGER.error(e)
return HttpResponse('Unknown error occurred when getting the current avatar',
status=500)

env_connection_settings.update({'avatar_id': avatar_id})
return JsonResponse(env_connection_settings)

Expand Down
6 changes: 1 addition & 5 deletions game_frontend/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ const initialState = {
},
game: {
connectionParameters: {
id: getGameIDFromURL() || 1,
game_url_base: '',
game_url_path: '',
game_url_port: 0,
game_ssl_flag: false
game_id: getGameIDFromURL() || 1
}
},
consoleLog: {
Expand Down
4 changes: 2 additions & 2 deletions game_frontend/src/redux/api/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { fromEvent } from 'rxjs/observable/fromEvent'
import { pipe } from 'rxjs/Rx'

const connectToGame = () =>
map(response => {
const { game_url_base: gameUrlBase, game_url_path: gameUrlPath, avatar_id: avatarId } = response
map(action => {
const { game_url_base: gameUrlBase, game_url_path: gameUrlPath, avatar_id: avatarId } = action.payload.parameters
return io(gameUrlBase, {
path: gameUrlPath,
query: {
Expand Down
4 changes: 2 additions & 2 deletions game_frontend/src/redux/features/Editor/epics.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const getCodeEpic = (action$, store, { api }) =>
action$.pipe(
ofType(types.GET_CODE_REQUEST),
mergeMap(action =>
api.get(`code/${store.getState().game.connectionParameters.id}/`).pipe(
api.get(`code/${store.getState().game.connectionParameters.game_id}/`).pipe(
map(response => actions.getCodeReceived(response.code)),
catchError(error => Observable.of({
type: types.GET_CODE_FAILURE,
Expand All @@ -26,7 +26,7 @@ const postCodeEpic = (action$, store, { api }) =>
.pipe(
ofType(types.POST_CODE_REQUEST),
api.post(
`/aimmo/api/code/${store.getState().game.connectionParameters.id}/`,
`/aimmo/api/code/${store.getState().game.connectionParameters.game_id}/`,
() => ({ code: store.getState().editor.code })
),
map(response => actions.postCodeReceived()),
Expand Down
26 changes: 25 additions & 1 deletion game_frontend/src/redux/features/Game/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,34 @@ const unityEvent = (unityEvent, unityData, successAction, failAction) => (
}
)

const connectionParametersReceived = parameters => (
{
type: types.CONNECTION_PARAMETERS_RECEIVED,
payload: {
parameters
}
}
)

const unitySendAvatarIDSuccess = () => (
{
type: types.UNITY_SEND_AVATAR_ID_SUCCESS
}
)

const unitySendAvatarIDFail = () => (
{
type: types.UNITY_SEND_AVATAR_ID_FAIL
}
)

export default {
socketConnectToGameRequest,
sendGameStateFail,
sendGameStateSuccess,
socketGameStateReceived,
unityEvent
unityEvent,
connectionParametersReceived,
unitySendAvatarIDSuccess,
unitySendAvatarIDFail
}
40 changes: 29 additions & 11 deletions game_frontend/src/redux/features/Game/epics.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import actions from './actions'
import types from './types'
import { Observable } from 'rxjs'
import { map, mergeMap, catchError } from 'rxjs/operators'
import { map, mergeMap, catchError, delay, tap } from 'rxjs/operators'
import { ofType } from 'redux-observable'

const connectToGameEpic = (action$, store, { api: { get, socket } }) => action$.pipe(
const getConnectionParametersEpic = (action$, store, { api: { get } }) => action$.pipe(
ofType(types.SOCKET_CONNECT_TO_GAME_REQUEST),
mergeMap(action =>
get(`games/${store.getState().game.connectionParameters.id}/connection_parameters/`).pipe(
socket.connectToGame(),
socket.startListeners(),
catchError(error => Observable.of({
type: types.SOCKET_CONNECT_TO_GAME_FAIL,
payload: error,
error: true
}))
get(`games/${store.getState().game.connectionParameters.game_id}/connection_parameters/`).pipe(
map(response => actions.connectionParametersReceived(response))
)
)
)
Expand All @@ -30,7 +24,31 @@ const sendGameStateEpic = (action$, store, { api: { unity } }) => action$.pipe(
unity.sendExternalEvent(unity.emitToUnity)
)

const connectToGameEpic = (action$, store, { api: { socket, unity } }) => action$.pipe(
ofType(types.CONNECTION_PARAMETERS_RECEIVED),
socket.connectToGame(),
socket.startListeners(),
catchError(error => Observable.of({
type: types.SOCKET_CONNECT_TO_GAME_FAIL,
payload: error,
error: true
}))
)

const sendAvatarIDEpic = (action$, store, { api: { unity } }) => action$.pipe(
ofType(types.CONNECTION_PARAMETERS_RECEIVED),
map(action => actions.unityEvent(
'SetCurrentAvatarID',
parseInt(action.payload.parameters['avatar_id']),
actions.unitySendAvatarIDSuccess(),
actions.unitySendAvatarIDFail
)),
unity.sendExternalEvent(unity.emitToUnity)
)

export default {
getConnectionParametersEpic,
connectToGameEpic,
sendGameStateEpic
sendGameStateEpic,
sendAvatarIDEpic
}
190 changes: 131 additions & 59 deletions game_frontend/src/redux/features/Game/epics.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,65 +19,6 @@ const createTestScheduler = (frameTimeFactor = 10) => {
return new TestScheduler(deepEquals)
}

describe('connectToGameEpic', () => {
it('connects to the aimmo-game', () => {
const gameState = {
players: {
id: 1,
location: {
x: 10,
y: 10
}
}
}

const marbles1 = '-a---'
const marbles2 = '--b--'
const values = {
a: actions.socketConnectToGameRequest(),
b: actions.socketGameStateReceived(gameState)
}

const testScheduler = createTestScheduler()
const source$ = ActionsObservable.from(
testScheduler.createColdObservable(marbles1, values)
)
const mockGetJSON = () =>
Observable.of({ id: 1 })

const mockConnectToGame = () =>
mapTo({type: 'socket'})

const mockStartListeners = () =>
pipe(
delay(10, testScheduler),
mapTo(actions.socketGameStateReceived(gameState))
)

const mockAPI = {
api: {
get: mockGetJSON,
socket: {
connectToGame: mockConnectToGame,
startListeners: mockStartListeners
}
}
}

const actual = epics.connectToGameEpic(source$, mockStore({
game: {
connectionParameters:
{
id: 1
}
}
}), mockAPI)

testScheduler.expectObservable(actual).toBe(marbles2, values)
testScheduler.flush()
})
})

describe('ReceiveGameUpdate', () => {
it('sends game update', () => {
const gameState = {
Expand Down Expand Up @@ -174,3 +115,134 @@ describe('ReceiveGameUpdate', () => {
testScheduler.flush()
})
})

describe('sendAvatarIDEpic', () => {
it('sends avatar id', () => {
const parameters = {
avatar_id: 1
}
const marbles1 = '-a--'
const marbles2 = '-b--'
const values = {
a: actions.connectionParametersReceived(parameters),
b: actions.unitySendAvatarIDSuccess()
}

const testScheduler = createTestScheduler()
const source$ = ActionsObservable.from(
testScheduler.createColdObservable(marbles1, values)
)

const mockEmitToUnity = () => {
return Observable.of(values.b)
}

const mockAPI = {
api: {
unity: {
...api.unity,
emitToUnity: mockEmitToUnity

}
}
}

const actual = epics.sendAvatarIDEpic(source$, mockStore({}), mockAPI)

testScheduler.expectObservable(actual).toBe(marbles2, values)
testScheduler.flush()
})
})

describe('connectToGameEpic', () => {
it('connects to the aimmo game', () => {
const gameState = {
players: {
id: 1,
location: {
x: 10,
y: 10
}
}
}

const parameters = {
avatar_id: 1
}

const marbles1 = '-a---'
const marbles2 = '--b--'
const values = {
a: actions.connectionParametersReceived(parameters),
b: actions.socketGameStateReceived(gameState)
}

const testScheduler = createTestScheduler()
const source$ = ActionsObservable.from(
testScheduler.createColdObservable(marbles1, values)
)

const mockConnectToGame = () =>
mapTo({type: 'socket'})

const mockStartListeners = () =>
pipe(
delay(10, testScheduler),
mapTo(actions.socketGameStateReceived(gameState))
)

const mockAPI = {
api: {
socket: {
connectToGame: mockConnectToGame,
startListeners: mockStartListeners
}
}
}

const actual = epics.connectToGameEpic(source$, mockStore({}), mockAPI)

testScheduler.expectObservable(actual).toBe(marbles2, values)
testScheduler.flush()
})
})

describe('getConnectionParametersEpic', () => {
it('gets all the connection parameters', () => {
const parameters = {
avatar_id: 1
}

const marbles1 = '-a--'
const marbles2 = '-b--'
const values = {
a: actions.socketConnectToGameRequest(),
b: actions.connectionParametersReceived(parameters)
}

const testScheduler = createTestScheduler()
const source$ = ActionsObservable.from(
testScheduler.createColdObservable(marbles1, values)
)

const mockGetJSON = () =>
Observable.of({ avatar_id: 1 })

const mockAPI = {
api: {
get: mockGetJSON
}
}

const actual = epics.getConnectionParametersEpic(source$, mockStore({
game: {
connectionParameters: {
game_id: 1
}
}
}), mockAPI)

testScheduler.expectObservable(actual).toBe(marbles2, values)
testScheduler.flush()
})
})
8 changes: 8 additions & 0 deletions game_frontend/src/redux/features/Game/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@ const SEND_GAME_STATE_FAIL = 'features/Game/SOCKET_GAME_STATE_UPDATE_FAIL'

const UNITY_EVENT = 'features/Game/UNITY_EVENT' // check naming

const CONNECTION_PARAMETERS_RECEIVED = 'features/GAME/CONNECTION_PARAMETERS_RECEIVED'

const UNITY_SEND_AVATAR_ID_SUCCESS = 'features/GAME/UNITY_SEND_AVATAR_ID_SUCCESS'
const UNITY_SEND_AVATAR_ID_FAIL = 'features/GAME/UNITY_SEND_AVATAR_ID_FAIL'

export default {
SOCKET_CONNECT_TO_GAME_REQUEST,
SOCKET_CONNECT_TO_GAME_FAIL,
SOCKET_GAME_STATE_RECEIVED,
SEND_GAME_STATE_SUCCESS,
SEND_GAME_STATE_FAIL,
UNITY_EVENT,
CONNECTION_PARAMETERS_RECEIVED,
UNITY_SEND_AVATAR_ID_SUCCESS,
UNITY_SEND_AVATAR_ID_FAIL
}