Comments (5)
@gravestench Thanks for the time for writing such a detailed explanation. It was very helpful!
I'm currently implementing the interfaces to form the animation widget.
I hope to have some news about the PR soon!
Again, thanks!
from hellspawner.
also, I think that it should be done before a serious llook at #298
from hellspawner.
Hey 👋, I'm new to the project and I'd like to contribute.
Could you assign me this issue?
from hellspawner.
Hey @gucio321,
I've been working on an approach to this issue and I believe that the merging would be difficult because the DCC and DC6 widgets access different properties of their respective structures.
Their structures on the OpenDiablo2 look like this
type DC6 struct {
Version int32
Flags uint32
Encoding uint32
Termination []byte // 4 bytes
Directions uint32
FramesPerDirection uint32
FramePointers []uint32 // size is Directions*FramesPerDirection
Frames []*DC6Frame // size is Directions*FramesPerDirection
}
type DCC struct {
Signature int
Version int
NumberOfDirections int
FramesPerDirection int
Directions []*DCCDirection
directionOffsets []int
fileData []byte
}
What I've been thinking is to avoid code repetition, as some tasks between the creation of both widgets are the same. So, I think it would be a good solution to add a new layer of abstraction in the new animationwidget package, widget, and widgetstate, that would hold DCC and DC6 structures. The widget, Dc6Widget, and DccWidget structures would look like this:
type Widget struct {
id string
palette *[256]d2interface.Color
textureLoader hscommon.TextureLoader
}
type Dc6Widget struct {
widget *Widget
dc6 *d2dc6.DC6
}
type DccWidget struct {
widget *Widget
dcc *d2dcc.DCC
}
Comparing to the current structures:
// DC6 widget
type widget struct {
id string
dc6 *d2dc6.DC6
textureLoader hscommon.TextureLoader
palette *[256]d2interface.Color
}
// DCC Widget
type widget struct {
id string
dcc *d2dcc.DCC
palette *[256]d2interface.Color
textureLoader hscommon.TextureLoader
}
Do you think that adding a new abstraction would help instead of merging both widgets?
from hellspawner.
@GibranHL0 This is a good scenario for using an interface.
IIRC, giu.Widget
is an interface that only needs a Build()
method:
type Widget interface {
Build()
}
There are a few things in common between the DCC and DC6 image files:
- They both have directions, which are ordered sequences of images
- They both are paletted images, so require a palette to be drawn.
with this information, we can define some interfaces to describe these commonalities:
type hasDirection interface {
Direction() int
SetDirection(int)
}
type hasFrames interface {
Frame() int
SetFrame(int)
}
type hasPalette interface {
Palette() color.Palette
SetPalette(color.Palette) error
}
Altogether, an AnimationWidget
might look something like this:
type AnimationWidget interface {
giu.Widget
hasPalette
hasDirection
hasFrames
}
Exactly how you go about implementing is up to you, but I would try to separate the common stuff like this:
type state struct {
currentDirection, currentFrame int
palette color.Palette
}
type Widget struct {
id string
*state
}
func (w *Widget) Build() {
/*
could do common stuff here,
called from dcc or dc6 widget Build method
*/
}
func (w *Widget) Palette() color.Palette {
return w.state.palette
}
func (w *Widget) SetPalette(p color.Palette) error {
if len(p) != colorsPerPalette {
return fmt.Errorf("expected %v colors, but palette has %v colors", colorsPerPalette, len(p))
}
w.state.palette = p
return nil
}
func (w *Widget) Frame() int {
return w.state.currentFrame
}
func (w *Widget) SetFrame(n int) {
w.state.currentFrame = n
}
func (w *Widget) Direction() int {
return w.state.currentDirection
}
func (w *Widget) SetDirection(n int) {
w.state.currentDirection = n
}
Then, the concrete animation widget implementations could look like this:
type Dc6Widget struct {
*Widget
dc6 *d2dc6.DC6
}
func (w *Dc6Widget) Build() {
w.Widget.Build() // call the generic one
// do DC6 specific stuff
}
type DccWidget struct {
*Widget
dcc *d2dcc.DCC
}
func (w *DccWidget) Build() {
w.Widget.Build() // call the generic one
// do DCC specific stuff
}
EDIT:
It's also important to note that because *Widget
is embedded inside of the DccWidget
and Dc6Widget
, the methods of Widget
are also embedded! This means that Dc6Widget
and DccWidget
would implement the AnimationWidget
interface. :)
You could check for this by adding the following code at the top of your file after the imports:
var _ AnimationWidget = &DccWidget{}
var _ AnimationWidget = &Dc6Widget{}
Those two lines will prevent the code from compiling if DccWidget
or Dc6Widget
do not implement AnimationWidget
from hellspawner.
Related Issues (20)
- animation data editor is displayed incorrectly
- add support for non-english fonts (string table editor)
- DCC Widget: GIF export should be an editor feature
- DCC Editor "Change Palette" cannot be closed by the window's X button HOT 1
- need to merge DT1 sub-tile flags edit/preview UI
- refactor logging throughout the app HOT 1
- DT1 widget: subtitle type scrollbar should be a drop-down HOT 3
- Unexpected behavior when double/triple/N clicking a file in the MPQ Explorer HOT 3
- Fix broken build
- Redundant helpers functions in hswidget
- hsdialog: handle keyboard shortcuts inside of popup modal widget
- DAT palette editor needs a refactor
- hswidget/dt1widget: add keyboard shortcuts for switching tile groups
- hswidget: widgetState encoder needs refactor
- remove `giu.Texture` example; use image.RGBA instead HOT 7
- DT1 editor: setting palette does not work HOT 2
- dependencies: back to giu upstream HOT 7
- Creating a new project appends the extension again HOT 1
- Ubuntu 20 - go.sub "malformed module path "embed": missing dot in first path element HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hellspawner.