import { ActionCreatorsMapObject } from "redux" ; import { PropsPicker , StateDict , ActionsDict } from "../types" ; import { CurtainReduxInfo , CurtainMutableObj , RootState } from "../reducers/types" ; function getRelativeLevel ( name ) { let result = name . match ( /^\$(\d+)$/ ) ; return result && parseInt ( result [ 1 ] ) ; } function getLevelKey ( rootState , reducerKey , levelNum ) { if ( levelNum === 0 ) return reducerKey ; let { stateTree , stateTreeDict } = rootState . arena ; let path = stateTreeDict . getIn ( [ reducerKey , "path" ] ) ; return path . get ( path . count ( ) - 1 - 2 * levelNum ) ; } export default function createPropsPicker < S , A extends ActionCreatorsMapObject , P > ( propsPicker , reduxInfo , mutableObj ) { let { arenaReducerDict } = reduxInfo ; let sceneReducerKey = arenaReducerDict . _arenaScene . reducerKey ; let latestProps ; let stateHandler = { get : function ( target , name ) { let levelNum = getRelativeLevel ( name ) ; if ( levelNum != null ) { name = getLevelKey ( target . state , sceneReducerKey , levelNum ) ; } let dictItem = arenaReducerDict [ name ] ; if ( dictItem == null ) return null ; return target . state [ dictItem . reducerKey ] ; } } ; let actionsHandler = { get : function ( target , name ) { let levelNum = getRelativeLevel ( name ) ; if ( levelNum != null ) { name = getLevelKey ( target . state , sceneReducerKey , levelNum ) ; } let dictItem = arenaReducerDict [ name ] ; if ( dictItem == null ) return null ; return dictItem . actions ; } } ; let stateObj = { state : null } ; let stateDict = new Proxy ( stateObj , stateHandler ) as any ; let actionsDict = new Proxy ( stateObj , actionsHandler ) as any ; return ( state ) => { stateObj . state = state ; if ( mutableObj . isObsolete === true || state . arena . propsLock !== false || state . arena . stateTreeDict . getIn ( [ sceneReducerKey , "isObsolete" ] ) === true ) { return latestProps ; } else { latestProps = propsPicker ( stateDict , actionsDict ) ; return latestProps ; } } ; }