Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
N
Neos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
love_飞影
Neos
Commits
d2b01b1b
Commit
d2b01b1b
authored
Apr 25, 2023
by
timel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: use class to implement store, with edited prototype chain
parent
c2e315c9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
118 additions
and
94 deletions
+118
-94
src/valtioStores/matStore/store.ts
src/valtioStores/matStore/store.ts
+113
-91
src/valtioStores/matStore/types.ts
src/valtioStores/matStore/types.ts
+5
-3
No files found.
src/valtioStores/matStore/store.ts
View file @
d2b01b1b
...
...
@@ -7,7 +7,7 @@ import { fetchCard } from "@/api/cards";
import
type
{
BothSide
,
CardState
,
DuelFieldState
,
DuelFieldState
as
ArrayCardState
,
InitInfo
,
MatState
,
}
from
"
./types
"
;
...
...
@@ -20,105 +20,113 @@ import { InteractType } from "./types";
const
getWhom
=
(
controller
:
number
):
"
me
"
|
"
op
"
=>
isMe
(
controller
)
?
"
me
"
:
"
op
"
;
/**
* 根据自己的先后手判断是否是自己
* 原本名字叫judgeSelf
*/
const
isMe
=
(
controller
:
number
):
boolean
=>
{
switch
(
matStore
.
selfType
)
{
case
1
:
// 自己是先攻
return
controller
===
0
;
case
2
:
// 自己是后攻
return
controller
===
1
;
default
:
// 目前不可能出现这种情况
console
.
error
(
"
judgeSelf error
"
,
controller
,
matStore
.
selfType
);
return
false
;
}
};
const
genDuel
=
<
T
extends
{}
>
(
meObj
:
T
,
opObj
?:
T
):
BothSide
<
T
>
=>
{
// 提供opObj是为了让meObj和opObj的类型可以不同,避免深拷贝的坑...
const
res
=
proxy
({
me
:
Object
.
assign
(
meObj
,
{
getController
:
()
=>
(
matStore
.
selfType
==
1
?
0
:
1
),
}),
op
:
Object
.
assign
(
opObj
??
meObj
,
{
getController
:
()
=>
(
matStore
.
selfType
==
1
?
0
:
1
),
}),
of
:
(
controller
:
number
)
=>
res
[
getWhom
(
controller
)],
});
return
res
;
};
const
addMethods
=
<
T
extends
CardState
[]
>
(
entity
:
T
,
zone
:
ygopro
.
CardZone
):
DuelFieldState
=>
{
/** 生成一个卡片,根据`id`获取卡片信息 */
const
genCard
=
async
(
controller
:
number
,
id
:
number
)
=>
({
/** 卡的列表,提供了一些方便的方法 */
class
CardArray
extends
Array
<
CardState
>
implements
ArrayCardState
{
public
__proto__
=
CardArray
.
prototype
;
public
zone
:
ygopro
.
CardZone
=
ygopro
.
CardZone
.
MZONE
;
public
getController
:
()
=>
number
=
()
=>
1
;
private
genCard
=
async
(
controller
:
number
,
id
:
number
)
=>
({
occupant
:
await
fetchCard
(
id
,
true
),
location
:
{
controler
:
controller
,
location
:
zone
,
location
:
this
.
zone
,
},
counters
:
{},
idleInteractivities
:
[],
});
const
res
=
proxy
(
entity
)
as
unknown
as
DuelFieldState
;
res
.
remove
=
(
sequence
:
number
)
=>
{
res
.
splice
(
sequence
,
1
);
};
res
.
insert
=
async
(
sequence
:
number
,
id
:
number
)
=>
{
const
card
=
await
genCard
(
res
.
getController
(),
id
);
res
.
splice
(
sequence
,
0
,
card
);
};
res
.
add
=
async
(
ids
:
number
[])
=>
{
// methods
remove
(
sequence
:
number
)
{
this
.
splice
(
sequence
,
1
);
}
async
insert
(
sequence
:
number
,
id
:
number
)
{
const
card
=
await
this
.
genCard
(
this
.
getController
(),
id
);
this
.
splice
(
sequence
,
0
,
card
);
}
async
add
(
ids
:
number
[])
{
const
cards
=
await
Promise
.
all
(
ids
.
map
(
async
(
id
)
=>
genCard
(
re
s
.
getController
(),
id
))
ids
.
map
(
async
(
id
)
=>
this
.
genCard
(
thi
s
.
getController
(),
id
))
);
res
.
splice
(
re
s
.
length
,
0
,
...
cards
);
}
;
res
.
setOccupant
=
async
(
this
.
splice
(
thi
s
.
length
,
0
,
...
cards
);
}
async
setOccupant
(
sequence
:
number
,
id
:
number
,
position
?:
ygopro
.
CardPosition
)
=>
{
)
{
const
meta
=
await
fetchCard
(
id
);
const
target
=
re
s
[
sequence
];
const
target
=
thi
s
[
sequence
];
target
.
occupant
=
meta
;
if
(
position
)
{
target
.
location
.
position
=
position
;
}
};
res
.
addIdleInteractivity
=
(
}
addIdleInteractivity
(
sequence
:
number
,
interactivity
:
CardState
[
"
idleInteractivities
"
][
number
]
)
=>
{
res
[
sequence
].
idleInteractivities
.
push
(
interactivity
);
};
res
.
clearIdleInteractivities
=
()
=>
{
res
.
forEach
((
card
)
=>
(
card
.
idleInteractivities
=
[]));
};
res
.
setPlaceInteractivityType
=
(
sequence
:
number
,
interactType
:
InteractType
)
=>
{
res
[
sequence
].
placeInteractivity
=
{
)
{
this
[
sequence
].
idleInteractivities
.
push
(
interactivity
);
}
clearIdleInteractivities
()
{
this
.
forEach
((
card
)
=>
(
card
.
idleInteractivities
=
[]));
}
setPlaceInteractivityType
(
sequence
:
number
,
interactType
:
InteractType
)
{
this
[
sequence
].
placeInteractivity
=
{
interactType
:
interactType
,
response
:
{
controler
:
re
s
.
getController
(),
zone
,
controler
:
thi
s
.
getController
(),
zone
:
this
.
zone
,
sequence
,
},
};
};
res
.
clearPlaceInteractivity
=
()
=>
{
res
.
forEach
((
card
)
=>
(
card
.
placeInteractivity
=
undefined
));
}
clearPlaceInteractivity
()
{
this
.
forEach
((
card
)
=>
(
card
.
placeInteractivity
=
undefined
));
}
}
const
genDuelCardArray
=
(
cardStates
:
CardState
[],
zone
:
ygopro
.
CardZone
)
=>
{
const
me
=
new
CardArray
(...
cardStates
);
me
.
zone
=
zone
;
me
.
getController
=
()
=>
(
matStore
.
selfType
==
1
?
0
:
1
);
const
op
=
new
CardArray
(...
cardStates
);
op
.
zone
=
zone
;
op
.
getController
=
()
=>
(
matStore
.
selfType
==
1
?
1
:
0
);
const
res
=
proxy
({
me
,
op
,
of
:
(
controller
:
number
)
=>
{
res
[
getWhom
(
controller
)].
__proto__
=
CardArray
.
prototype
;
return
res
[
getWhom
(
controller
)];
},
});
return
res
;
};
/**
* 根据自己的先后手判断是否是自己
* 原本名字叫judgeSelf
*/
const
isMe
=
(
controller
:
number
):
boolean
=>
{
switch
(
matStore
.
selfType
)
{
case
1
:
// 自己是先攻
return
controller
===
0
;
case
2
:
// 自己是后攻
return
controller
===
1
;
default
:
// 目前不可能出现这种情况
console
.
error
(
"
judgeSelf error
"
,
controller
,
matStore
.
selfType
);
return
false
;
}
};
const
genDuelNormal
=
<
T
extends
{}
>
(
meObj
:
T
):
BothSide
<
T
>
=>
{
// 提供opObj是为了让meObj和opObj的类型可以不同,避免深拷贝的坑...
const
res
=
{
me
:
{
...
meObj
},
op
:
{
...
meObj
},
of
:
(
controller
:
number
)
=>
res
[
getWhom
(
controller
)],
};
return
res
;
};
...
...
@@ -138,7 +146,7 @@ const genBlock = (location: ygopro.CardZone, n: number) =>
}));
const
initInfo
:
MatState
[
"
initInfo
"
]
=
proxy
({
...
genDuel
({
...
genDuel
Normal
({
masterRule
:
"
UNKNOWN
"
,
life
:
-
1
,
// 特地设置一个不可能的值
deckSize
:
0
,
...
...
@@ -188,23 +196,18 @@ const { SZONE, MZONE, GRAVE, REMOVED, HAND, DECK, EXTRA } = ygopro.CardZone;
* 具体介绍可以点进`MatState`去看
*/
export
const
matStore
:
MatState
=
proxy
<
MatState
>
({
magics
:
genDuel
(
addMethods
(
genBlock
(
SZONE
,
6
),
SZONE
),
addMethods
(
genBlock
(
SZONE
,
6
),
SZONE
)
),
monsters
:
genDuel
(
addMethods
(
genBlock
(
MZONE
,
7
),
MZONE
),
addMethods
(
genBlock
(
MZONE
,
7
),
MZONE
)
),
graveyards
:
genDuel
(
addMethods
([],
GRAVE
),
addMethods
([],
GRAVE
)),
banishedZones
:
genDuel
(
addMethods
([],
REMOVED
),
addMethods
([],
REMOVED
)),
hands
:
genDuel
(
addMethods
([],
HAND
),
addMethods
([],
HAND
)),
decks
:
genDuel
(
addMethods
([],
DECK
),
addMethods
([],
DECK
)),
extraDecks
:
genDuel
(
addMethods
([],
EXTRA
),
addMethods
([],
EXTRA
)),
magics
:
genDuelCardArray
(
genBlock
(
SZONE
,
6
),
SZONE
),
monsters
:
genDuelCardArray
(
genBlock
(
MZONE
,
7
),
MZONE
),
graveyards
:
genDuelCardArray
([],
GRAVE
),
banishedZones
:
genDuelCardArray
([],
REMOVED
),
hands
:
genDuelCardArray
([],
HAND
),
decks
:
genDuelCardArray
([],
DECK
),
extraDecks
:
genDuelCardArray
([],
EXTRA
),
timeLimits
:
{
// 时间限制
...
genDuel
(
-
1
),
...
genDuelNormal
(
-
1
),
of
:
(
controller
:
number
)
=>
matStore
.
timeLimits
[
getWhom
(
controller
)],
set
:
(
controller
:
number
,
time
:
number
)
=>
{
matStore
.
timeLimits
[
getWhom
(
controller
)]
=
time
;
},
...
...
@@ -229,5 +232,24 @@ export const matStore: MatState = proxy<MatState>({
isMe
,
});
// 以后再来解决这些...
// @ts-ignore
window
.
matStore
=
matStore
;
// 修改原型链,因为valtiol的proxy会把原型链改掉。这应该是valtio的一个bug...有空提issue去改
([
"
me
"
,
"
op
"
]
as
const
).
forEach
((
who
)
=>
{
(
[
"
hands
"
,
"
decks
"
,
"
extraDecks
"
,
"
graveyards
"
,
"
banishedZones
"
,
"
monsters
"
,
"
magics
"
,
]
as
const
).
forEach
((
zone
)
=>
{
matStore
[
zone
][
who
].
__proto__
=
CardArray
.
prototype
;
});
});
src/valtioStores/matStore/types.ts
View file @
d2b01b1b
...
...
@@ -12,8 +12,7 @@ export interface BothSide<T> {
/**
* CardState的顺序index,被称为sequence
*/
export
type
DuelFieldState
=
CardState
[]
&
{
getController
:
()
=>
number
;
export
interface
DuelFieldState
extends
Array
<
CardState
>
{
/** 移除特定位置的卡片 */
remove
:
(
sequence
:
number
)
=>
void
;
/** 在末尾添加卡片 */
...
...
@@ -40,7 +39,10 @@ export type DuelFieldState = CardState[] & {
)
=>
void
;
/** 移除 place 的交互性 */
clearPlaceInteractivity
:
()
=>
void
;
};
// 让原型链不报错
__proto__
?:
DuelFieldState
;
}
type
test
=
DuelFieldState
extends
(
infer
S
)[]
?
S
:
never
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment