Record Class ModAccessWidenerEntry
java.lang.Object
java.lang.Record
net.fabricmc.loom.configuration.accesswidener.ModAccessWidenerEntry
- Record Components:
modId- mod 的 id(原FabricModJson.getId())modSchemaVersion- mod 元数据的 schema 版本(原FabricModJson.getVersion(),只参与身份)path- 规则文件在 mod 内的路径environment- 规则适用的环境transitiveOnly- 是否只取transitive-规则data- 规则文件内容
- All Implemented Interfaces:
AccessWidenerEntry
public record ModAccessWidenerEntry(String modId, int modSchemaVersion, String path, ModEnvironment environment, boolean transitiveOnly, byte[] data)
extends Record
implements AccessWidenerEntry
AccessWidenerEntry implementation for a FabricModJson.
为什么这里不持有 FabricModJson
本 record 的实例会随 AccessWidenerJarProcessor.Spec 进入
ProcessMinecraftJarTask 的任务状态(spec 是该任务的 @Internal 属性,但 @Internal
只免掉指纹,不免掉序列化)。任务状态整体必须能写进配置缓存,而 FabricModJson 持有的东西
恰恰都不是配置缓存能序列化的值:
- 元数据本体是 Gson 的
JsonObject,其内部映射类型是com.google.gson.internal.LinkedTreeMap; - 资源来源形状不定——jar 路径、源码集,甚至跨项目数据重建出来的 lambda 闭包。
org.gradle.configuration-cache=true 且 problems=fail):
带着依赖 mod 的 access widener 构建时,存储阶段直接以
value '{...}' is not assignable to 'com.google.gson.internal.LinkedTreeMap' 失败,
整个构建无法通过配置缓存。因此这里只保留链真正需要的纯值:元数据身份(id 与 schema 版本)、
规则文件路径、环境、以及「是否只取 transitive 规则」标志,外加**规则文件本身的字节**。
为什么规则文件字节可以在配置期读
依赖 mod 的元数据本来就是从同一份来源读出来的(jar 依赖读 jar 条目,项目依赖读LoomProjectData 已复制的资源),所以「配置期读不到、只有执行期才读得到」的情形不存在;
本包的 LocalAccessWidenerEntry 也早就在建 spec 时读文件并在缺失时直接失败。
把字节在配置期取出来,链在执行期就不需要再碰任何一句「怎么读」的上下文。
为什么身份是显式写出来的
spec.hashCode() 是 loom 既有协议里的链身份(缓存值与产物路径都由它派生,
见 MinecraftJarProcessorManager.getCacheValue()),所以改造不能让它漂移。
改造前的身份是
Objects.hash(FabricModJson.hashCode() = Objects.hash(id, schemaVersion), path, environment, transitiveOnly),
下面的 hashCode() 逐位复现这一串。规则文件字节只是载荷、不进身份:把它算进去会让
「同一个 mod 的同一份规则文件、内容不同」被当成两条链,而既有协议只看 mod 身份。-
Constructor Summary
ConstructorsConstructorDescriptionModAccessWidenerEntry(String modId, int modSchemaVersion, String path, ModEnvironment environment, boolean transitiveOnly, byte[] data) Creates an instance of aModAccessWidenerEntryrecord class. -
Method Summary
Modifier and TypeMethodDescriptionbyte[]data()Returns the value of thedatarecord component.Returns the value of theenvironmentrecord component.boolean与hashCode()同源的等值判定:只比身份,不比规则文件字节.inthashCode()身份与改造前逐位一致.@Nullable StringmodId()Returns the value of themodIdrecord component.intReturns the value of themodSchemaVersionrecord component.path()Returns the value of thepathrecord component.voidread(net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor visitor, LazyCloseable<net.fabricmc.tinyremapper.TinyRemapper> remapper, MappingsNamespace productionNamespace) static List<ModAccessWidenerEntry> readAll(FabricModJson modJson, boolean transitiveOnly) voidreadOfficial(net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor visitor) toString()Returns a string representation of this record class.booleanReturns the value of thetransitiveOnlyrecord component.
-
Constructor Details
-
ModAccessWidenerEntry
public ModAccessWidenerEntry(String modId, int modSchemaVersion, String path, ModEnvironment environment, boolean transitiveOnly, byte[] data) Creates an instance of aModAccessWidenerEntryrecord class.- Parameters:
modId- the value for themodIdrecord componentmodSchemaVersion- the value for themodSchemaVersionrecord componentpath- the value for thepathrecord componentenvironment- the value for theenvironmentrecord componenttransitiveOnly- the value for thetransitiveOnlyrecord componentdata- the value for thedatarecord component
-
-
Method Details
-
readAll
-
hashCode
public int hashCode()身份与改造前逐位一致.改造前的身份来自 record 自动生成的实现,合并方式是从 0 开始的 31 折:
result = 0; result = 31 * result + h(i),与Objects.hash(...)的从 1 开始 (result = 1; ...)差着最前面一个 ×31。这里必须按前者的写法显式复现: 用Objects.hash(第一个组件, 第二个, ...)铺开整条链会得到另一个数, 而spec.hashCode()是产物路径与缓存值的来源(见类注释),差一个数就意味着所有工作区 都要重新处理一遍 Minecraft jar。 -
equals
与hashCode()同源的等值判定:只比身份,不比规则文件字节.刻意与
hashCode()用同一组字段:record 自动生成的实现会把data按引用比较, 那既与身份不一致,又让两条内容相同的链永远不相等。 -
toString
Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components. -
mappingId
- Specified by:
mappingIdin interfaceAccessWidenerEntry- Returns:
- The mod id to be used in
TransitiveAccessWidenerMappingsProcessoror null when this entry does not contain transitive entries.
-
getSortKey
- Specified by:
getSortKeyin interfaceAccessWidenerEntry
-
read
public void read(net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor visitor, LazyCloseable<net.fabricmc.tinyremapper.TinyRemapper> remapper, MappingsNamespace productionNamespace) throws IOException - Specified by:
readin interfaceAccessWidenerEntry- Throws:
IOException
-
readOfficial
public void readOfficial(net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor visitor) throws IOException - Specified by:
readOfficialin interfaceAccessWidenerEntry- Throws:
IOException
-
modId
Returns the value of themodIdrecord component.- Returns:
- the value of the
modIdrecord component
-
modSchemaVersion
public int modSchemaVersion()Returns the value of themodSchemaVersionrecord component.- Returns:
- the value of the
modSchemaVersionrecord component
-
path
Returns the value of thepathrecord component.- Returns:
- the value of the
pathrecord component
-
environment
Returns the value of theenvironmentrecord component.- Specified by:
environmentin interfaceAccessWidenerEntry- Returns:
- the value of the
environmentrecord component
-
transitiveOnly
public boolean transitiveOnly()Returns the value of thetransitiveOnlyrecord component.- Returns:
- the value of the
transitiveOnlyrecord component
-
data
public byte[] data()Returns the value of thedatarecord component.- Returns:
- the value of the
datarecord component
-