123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /** @format */
- import {autorun, IReactionDisposer, spy} from 'mobx'
- import * as mobx from 'mobx'
- if (cc.sys.isBrowser) {
- ;(window as any).mobx = mobx
- }
- const getComponentOrNode = <T extends cc.Component>(
- target: cc.Component,
- kv: Map<string, string>,
- component: {prototype: T} | null,
- componentStr?: string,
- componentCb?: Function,
- ) => {
- let lastV: string
- kv.forEach((v, k) => {
- if (lastV && lastV == v) {
- console.error(component ? component.prototype.constructor.name : 'node', '注解错误有相同的url', lastV)
- }
- lastV = v
- if (component) {
- target[k] = cc.find(v, target.node)?.getComponent(component)
- } else if (componentStr) {
- target[k] = cc.find(v, target.node)?.getComponent(componentStr)
- } else {
- target[k] = cc.find(v, target.node)
- }
- componentCb && componentCb(target[k])
- })
- }
- export const observer = <T extends {new (...args: any[]): cc.Component}>(constructor: T) => {
- return class extends constructor {
- _disposer: IReactionDisposer[] = []
- _reaction?: string[]
- _autorun?: string[]
- _nodes?: Map<string, string>
- _labels?: Map<string, string>
- _editBoxes?: Map<string, string>
- _lists?: Map<string, string>
- _toggles?: Map<string, string>
- onLoad() {
- if (this._nodes) {
- getComponentOrNode(this, this._nodes, null)
- }
- if (this._labels) {
- getComponentOrNode(this, this._labels, cc.Label)
- }
- if (this._editBoxes) {
- getComponentOrNode(this, this._editBoxes, cc.EditBox)
- }
- if (this._lists) {
- getComponentOrNode(this, this._lists, null, 'List', component => {
- component._init()
- })
- }
- if (this._toggles) {
- getComponentOrNode(this, this._toggles, cc.Toggle)
- }
- super.onLoad && super.onLoad()
- if (this._autorun) {
- let callback = x => {
- this[x]()
- }
- this._disposer.push(
- ...this._autorun.map(x =>
- autorun(() => {
- callback(x)
- }),
- ),
- )
- }
- if (this._reaction) {
- this._disposer.push(
- ...this._reaction.map(x => {
- return (this as any)[x]()
- }),
- )
- }
- }
- onEnable() {
- super.onEnable && super.onEnable()
- if (this._autorun) {
- let callback = x => {
- this[x]()
- }
- this._autorun.forEach(x => callback(x))
- }
- }
- onDestroy() {
- super.onDestroy && super.onDestroy()
- if (this._disposer) this._disposer.forEach(x => x())
- this._disposer.length = 0
- }
- }
- }
- export const render = (target: any, key: string, descriptor: TypedPropertyDescriptor<() => void>) => {
- let obs: string[] = target['_autorun']
- if (!obs) {
- obs = target['_autorun'] = []
- }
- obs.push(key)
- }
- interface Reactor {
- (target: any, key: string, descriptor: TypedPropertyDescriptor<() => IReactionDisposer>): void
- <T>(expression: (r: mobx.IReactionPublic) => T): (
- target: any,
- key: string,
- descriptor: TypedPropertyDescriptor<(arg: T) => void>,
- ) => void
- }
- export const reactor: Reactor = function () {
- if (arguments.length === 3) {
- return reactor1(arguments[0], arguments[1], arguments[2])
- } else {
- return reactor2(arguments[0])
- }
- } as any
- const reactor1 = (target: any, key: string, descriptor: TypedPropertyDescriptor<() => IReactionDisposer>) => {
- let obs: string[] = target['_reaction']
- if (!obs) {
- obs = target['_reaction'] = []
- }
- obs.push(key)
- }
- const reactor2 = <T, O extends cc.Component & {_reaction?: string[]}>(expression: (r: mobx.IReactionPublic) => T) => {
- return (target: O, key: string, descriptor: TypedPropertyDescriptor<(arg: T) => void>) => {
- let obs = target['_reaction']
- if (!obs) {
- obs = target['_reaction'] = []
- }
- obs.push(key)
- const _value = descriptor.value as (arg: T) => void
- descriptor.value = function (this: O) {
- return mobx.reaction(expression.bind(this), _value.bind(this))
- }
- }
- }
- /**
- * 和reactor搭配进行副作用操作
- */
- export const react = <T>(
- expression: (r: mobx.IReactionPublic) => T,
- effect: (arg: T, r: mobx.IReactionPublic) => void,
- ) => {
- return mobx.reaction(expression, effect, {fireImmediately: true})
- }
- export const node = (arg: string) => {
- return (target: any, propertyKey: string) => {
- let nodes: Map<string, string> = target['_nodes']
- if (!nodes) {
- nodes = target['_nodes'] = new Map<string, string>()
- }
- nodes.set(propertyKey, arg)
- }
- }
- export const label = (arg: string) => {
- return (target: any, propertyKey: string) => {
- let labels: Map<string, string> = target['_labels']
- if (!labels) {
- labels = target['_labels'] = new Map<string, string>()
- }
- labels.set(propertyKey, arg)
- }
- }
- export const editBox = (arg: string) => {
- return (target: any, propertyKey: string) => {
- let editBoxes: Map<string, string> = target['_editBoxes']
- if (!editBoxes) {
- editBoxes = target['_editBoxes'] = new Map<string, string>()
- }
- editBoxes.set(propertyKey, arg)
- }
- }
- export const list = (arg: string) => {
- return (target: any, propertyKey: string) => {
- let list: Map<string, string> = target['_lists']
- if (!list) {
- list = target['_lists'] = new Map<string, string>()
- }
- list.set(propertyKey, arg)
- }
- }
- export const toggle = (arg: string) => {
- return (target: any, propertyKey: string) => {
- let toggle: Map<string, string> = target['_toggles']
- if (!toggle) {
- toggle = target['_toggles'] = new Map<string, string>()
- }
- toggle.set(propertyKey, arg)
- }
- }
|