Skip to content

refactor: 机器内存卡改用统一的 IConfigCopyable 协议 - #54

Open
alcox233 wants to merge 5 commits into
gtofrom
feat/machine-memory-card-extended-copy
Open

refactor: 机器内存卡改用统一的 IConfigCopyable 协议#54
alcox233 wants to merge 5 commits into
gtofrom
feat/machine-memory-card-extended-copy

Conversation

@alcox233

@alcox233 alcox233 commented Jul 17, 2026

Copy link
Copy Markdown

概述

@nutant233 的批语重构:机器实现 IConfigCopyable 接口,复制卡只操作这个接口

复制卡不再认识任何单项配置。新增可复制设置只需改拥有它的机器,永远不用再动卡。

// copy
if (machine instanceof IConfigCopyable copyable) copyable.writeConfigTo(configData);
// paste
if (machine instanceof IConfigCopyable copyable) copyable.readConfigFrom(configData);

MetaMachineConfigCopyBehaviour 因此瘦身 -215 行,只剩 NBT 容器、交互、ORIGINAL_FRONT 与一处 instanceof

设计

新增 IConfigCopyable — 唯一的复制协议,卡的唯一入口:

public interface IConfigCopyable extends IMachineFeature {
    void writeConfigTo(CompoundTag tag);
    void readConfigFrom(CompoundTag tag);
}

新增 ConfigCopySupport — NBT key、读写积木(内建 hasXxxConfig() 守卫)、以及 tooltip 注册表。

注册表是必要的:渲染物品 tooltip 时卡手里只有 NBT,没有机器实例,所以 appendConfigTooltips(tag, tooltip) 这种实例方法定义了也调不到。改为按 NBT key 注册的自描述渲染器,卡仍不认识任何单项配置,addon 注册自己的 key 即可。

胶水层的放置原则:谁真正拥有该状态,谁实现协议。

配置项 实现位置 理由
自动输出(物品/流体) IAutoOutputItem / IAutoOutputFluid 的 default 语义完全由接口自身的存取器定义,实现类多且一致
消音 IMufflableMachine 的 default 同上
输入限制 WorkableTieredMachine 状态在类里
销毁模式、电路 SimpleTieredMachine 状态在类里
电路、隔离 ItemBusPartMachine / FluidHatchPartMachine 状态在类里

IVoidable / IInputLimitableMachine / ICircuitConfigurable 保持原样,不继承 IConfigCopyable——它们是能力语义,不是复制协议。

修复的原实现缺陷

重构过程中发现两个此前未暴露的问题:

1. 电路恒读为「无」,粘贴反而清空目标电路

CircuitHandler 有意让外部视图为空,以便非消耗性电路不参与物品传输:

@Override
public ItemStack getStackInSlot(int slot) {
    return ItemStack.EMPTY;
}

真实电路存于 storage.stacks[0]——也正是 CircuitFancyConfigurator(circuitInventory.storage) 编辑的视图。原实现读的是外层 handler,因此 getCircuitConfiguration() 恒返回 CIRCUIT_EMPTY。三处(SimpleTieredMachineItemBusPartMachineFluidHatchPartMachine)已全部改走 .storage

2. 隔离总线未纳入复制

IDistinctPart 补上,并新增 hasDistinctConfig() 守卫(导出侧返回 false,与 hasCircuitConfig() 同构)。

:复制/粘贴改为服务端权威。并非所有可复制设置都同步到客户端(电路槽只有 @SaveToDisk),双端执行会导致客户端读到空值并写回。

兼容性

NBT key 一字未改,存档里已写好的内存卡继续有效。

⚠️ 对 addon 是编译期 API 变更IMufflableMachineIAutoOutputBoth 现各带一份 default 实现,同时实现两者的类必须显式解冲突(约 6 行)。

选它而非纯类实现的理由:纯类实现下,任何未显式实现 IConfigCopyable 的下游机器会静默失去复制能力;接口 default 则是编译期报错,一眼可见、一次修好。本组织内仅 GTOLib 的 SimpleNoEnergyMachine 命中,改后其 9 个 gtocore 子类全部恢复。

改动文件

新增 IConfigCopyableConfigCopySupport;修改复制卡、IAutoOutputItem/Fluid/BothIMufflableMachineIDistinctPartSimpleTieredMachineWorkableTieredMachineMinerMachineItemBusPartMachineFluidHatchPartMachine,以及 LangHandler 与中/英/繁三份语言文件(新增 behaviour.setting.distinct.tooltip)。

测试

已在 GTOCore 开发环境 runClient 实测通过:

  • 输入总线:电路 + 输入限制 + 隔离,复制 → 预览 → 粘贴全部正确
  • 输出侧:hasCircuitConfig() / hasDistinctConfig() 为 false,不写入、不崩
  • 跨类型粘贴只生效交集,未知 key 静默忽略
  • 目标机器转向后粘贴,输出面按相对朝向重映射

后续

需配套的 GTOLib 改动(SimpleNoEnergyMachine 解冲突),待本 PR 发布后再推,否则 gtocore CI 会因已发布的 gtceu 尚无 IConfigCopyable 而编译失败。

扩展 MetaMachineConfigCopyBehaviour,使机器内存卡除原有自动输出/消音等配置外,
还可复制与粘贴:
- 销毁模式(单方块 SimpleTieredMachine / 电动多方块主机)
- 输入限制(IInputLimitableMachine 且 hasInputLimitConfig)
- 编程电路(CircuitHandler)

并补充 Shift 预览提示与中英繁语言条目。
@nutant233

Copy link
Copy Markdown

建议改成机器实现接口,复制卡仅读写接口,更好扩展

@alcox233

Copy link
Copy Markdown
Author

已按批语重构:

  • 新增 \ICircuitConfigurable\(\hasCircuitConfig\ / get/set 电路配置)
  • \IVoidable.hasVoidingModeConfig()\:仅真正支持销毁模式的机器返回 true(\SimpleTieredMachine\)
  • 机器内存卡 只通过接口 读写:\IVoidable\ / \IInputLimitableMachine\ / \ICircuitConfigurable\,去掉对具体类与 trait 扫描
  • \ItemBusPartMachine\、\FluidHatchPartMachine\(输入侧)、\SimpleTieredMachine\ 已实现接口

后续扩展新配置项只需机器实现接口即可,无需改复制卡内部逻辑。

@nutant233

Copy link
Copy Markdown

你这样写还是只能复制IVoidable\ / \IInputLimitableMachine\ / \ICircuitConfigurable,我指机器实现IConfigCopyable接口,复制卡只需要操作这个接口

The copy card no longer knows about individual settings. It talks to machines
through one interface and adding a copyable setting never touches the card again.

- IConfigCopyable: writeConfigTo / readConfigFrom, the card's only entry point
- ConfigCopySupport: NBT keys, read/write building blocks and a tooltip registry
  (the card has no machine instance while rendering an item tooltip, so previews
  go through a self-describing registry addons can extend)
- auto output and muffling move to defaults on their own feature interfaces,
  with IAutoOutputBoth resolving the two-parent conflict; voiding mode, input
  limit and circuit stay class-side where the machine actually owns the state
- IVoidable / IInputLimitableMachine / ICircuitConfigurable are untouched: they
  are capability semantics, not a copy protocol

NBT keys are unchanged, so memory cards already written in a world stay valid.

Fixes two defects in the original implementation:

- the circuit was always read as empty. CircuitHandler.getStackInSlot returns
  EMPTY by design to keep the non-consumable circuit out of item transfer, so
  the configured value has to be read from storage — the same view the
  CircuitFancyConfigurator edits. Copying stored "none" and pasting therefore
  cleared the target's circuit.
- distinct buses were not copyable at all; added via IDistinctPart with a
  hasDistinctConfig() guard so export parts are skipped.

Copy and paste are now server-side only. Not every copyable setting is synced to
the client (the circuit slot is @savetodisk only), so a client-side copy read a
blank value and a client-side paste wrote one back.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@alcox233 alcox233 changed the title feat: 机器内存卡支持复制销毁模式、输入限制与电路配置 refactor: 机器内存卡改用统一的 IConfigCopyable 协议 Jul 26, 2026
alcox233 and others added 2 commits July 26, 2026 21:22
- align the distinct-part preview line with the existing GUI term in all three
  languages ("Distinct Part:" / 仓室隔离 / 匯流排隔離) instead of coining a new one
- ItemBusPartMachine.hasInputLimitConfig now also requires IO.IN: export buses
  never show the toggle, so a card copied from one must not carry input_limit
  and silently disable it on the paste target
- copying a machine that contributes nothing (or is not copyable) now clears the
  card instead of keeping a previous machine's config around to be pasted later
- auto-output copy respects hasAutoOutputItem()/hasAutoOutputFluid(), the same
  guards the directional config UI uses
- restore import order in SimpleTieredMachine, unify the section banners, and
  document that tooltip renderers must be registered during mod setup

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
物品 tooltip 首行新增说明:可复制输入总线、输入仓、单方块机器等
机器的配置,让玩家不用查文档就知道这张卡对哪些机器有效。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
alcox233 added a commit that referenced this pull request Jul 26, 2026
behaviour.setting.voiding_mode/input_limit/circuit 四个键属于
机器内存卡 PR(#54),从本 PR 移除以避免合并冲突。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants