1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-02-04 15:46:51 -05:00
OpenDiablo2/d2core/d2systems/file_handle_resolver.go

101 lines
2.6 KiB
Go
Raw Normal View History

package d2systems
import (
2020-10-12 17:35:11 -04:00
"github.com/gravestench/akara"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2components"
)
func NewFileHandleResolver() *FileHandleResolutionSystem {
// this filter is for entities that have a file path and file type but no file handle.
2020-10-12 17:35:11 -04:00
filesToSource := akara.NewFilter().
Require(d2components.FilePath).
Require(d2components.FileType).
Forbid(d2components.FileHandle).
Forbid(d2components.FileSource).
Build()
sourcesToUse := akara.NewFilter().
RequireOne(d2components.FileSource).
Build()
return &FileHandleResolutionSystem{
2020-10-12 17:35:11 -04:00
SubscriberSystem: akara.NewSubscriberSystem(filesToSource, sourcesToUse),
}
}
type FileHandleResolutionSystem struct {
2020-10-12 17:35:11 -04:00
*akara.SubscriberSystem
filesToLoad *akara.Subscription
sourcesToUse *akara.Subscription
filePaths *d2components.FilePathMap
fileTypes *d2components.FileTypeMap
fileSources *d2components.FileSourceMap
fileHandles *d2components.FileHandleMap
}
// Init initializes the system with the given world
2020-10-12 17:35:11 -04:00
func (m *FileHandleResolutionSystem) Init(world *akara.World) {
m.World = world
for subIdx := range m.Subscriptions {
m.AddSubscription(m.Subscriptions[subIdx])
}
if world == nil {
m.SetActive(false)
return
}
2020-10-12 17:35:11 -04:00
m.filesToLoad = m.Subscriptions[0]
m.sourcesToUse = m.Subscriptions[1]
testBS := akara.NewBitSet(int(d2components.FileSourceCID), 1)
truth := m.sourcesToUse.Filter.Allow(testBS)
_ = truth
// try to inject the components we require, then cast the returned
// abstract ComponentMap back to the concrete implementation
m.filePaths = m.InjectMap(d2components.FilePath).(*d2components.FilePathMap)
m.fileTypes = m.InjectMap(d2components.FileType).(*d2components.FileTypeMap)
m.fileHandles = m.InjectMap(d2components.FileHandle).(*d2components.FileHandleMap)
m.fileSources = m.InjectMap(d2components.FileSource).(*d2components.FileSourceMap)
}
// Process processes all of the Entities
func (m *FileHandleResolutionSystem) Process() {
2020-10-12 17:35:11 -04:00
filesToLoad := m.filesToLoad.GetEntities()
sourcesToUse := m.sourcesToUse.GetEntities()
for _, fileID := range filesToLoad {
for _, sourceID := range sourcesToUse {
if m.loadFileWithSource(fileID, sourceID) {
break
}
}
}
}
2020-10-12 17:35:11 -04:00
// try to load a file with a source, returns true if loaded
func (m *FileHandleResolutionSystem) loadFileWithSource(fileID, sourceID akara.EID) bool {
fp, found := m.filePaths.GetFilePath(fileID)
if !found {
2020-10-12 17:35:11 -04:00
return false
}
2020-10-12 17:35:11 -04:00
source, found := m.fileSources.GetFileSource(sourceID)
if !found {
return false
}
2020-10-12 17:35:11 -04:00
data, err := source.Open(fp)
if err != nil {
return false
}
2020-10-12 17:35:11 -04:00
dataComponent := m.fileHandles.AddFileHandle(fileID)
dataComponent.Data = data
return true
}