Skip to content

Commit 46c3b0f

Browse files
committed
Added base for song events
1 parent 6cceb22 commit 46c3b0f

2 files changed

Lines changed: 137 additions & 0 deletions

File tree

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* This file is part of NoteBlockLib - https://github.com/RaphiMC/NoteBlockLib
3+
* Copyright (C) 2022-2025 RK_01/RaphiMC and contributors
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 3 of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package net.raphimc.noteblocklib.model.event;
19+
20+
import java.util.*;
21+
import java.util.function.Consumer;
22+
import java.util.function.Predicate;
23+
24+
public class Events {
25+
26+
private final Map<Integer, List<Event>> events = new HashMap<>();
27+
28+
public List<Event> get(final int tick) {
29+
return this.events.get(tick);
30+
}
31+
32+
public List<Event> getOrEmpty(final int tick) {
33+
return this.events.getOrDefault(tick, new ArrayList<>());
34+
}
35+
36+
public void set(final int tick, final List<Event> events) {
37+
if (events != null) {
38+
this.events.put(tick, events);
39+
} else {
40+
this.events.remove(tick);
41+
}
42+
}
43+
44+
public void add(final int tick, final Event event) {
45+
this.events.computeIfAbsent(tick, k -> new ArrayList<>()).add(event);
46+
}
47+
48+
public void add(final int tick, final List<Event> events) {
49+
this.events.computeIfAbsent(tick, k -> new ArrayList<>()).addAll(events);
50+
}
51+
52+
public Set<Integer> getTicks() {
53+
return Collections.unmodifiableSet(this.events.keySet());
54+
}
55+
56+
public void clearTick(final int tick) {
57+
this.events.remove(tick);
58+
}
59+
60+
public void clear() {
61+
this.events.clear();
62+
}
63+
64+
/**
65+
* Applies the given consumer to all events.
66+
*
67+
* @param eventConsumer The consumer
68+
*/
69+
public void forEach(final Consumer<Event> eventConsumer) {
70+
this.events.values().stream().flatMap(Collection::stream).forEach(eventConsumer);
71+
}
72+
73+
/**
74+
* Applies the given predicate to all events.<br>
75+
* The predicate can return true to break the iteration.<br>
76+
* Use cases for this method can be for example to check if the song contains any specific event.
77+
*
78+
* @param eventPredicate The predicate
79+
* @return True if the predicate returned true for any event
80+
*/
81+
public boolean testEach(final Predicate<Event> eventPredicate) {
82+
for (List<Event> list : this.events.values()) {
83+
for (Event event : list) {
84+
if (eventPredicate.test(event)) {
85+
return true;
86+
}
87+
}
88+
}
89+
return false;
90+
}
91+
92+
/**
93+
* Removes all events which match the given predicate.
94+
*
95+
* @param eventPredicate The predicate
96+
*/
97+
public void removeIf(final Predicate<Event> eventPredicate) {
98+
for (List<Event> list : this.events.values()) {
99+
list.removeIf(eventPredicate);
100+
}
101+
this.compact();
102+
}
103+
104+
/**
105+
* Removes empty event lists from the events map.
106+
*/
107+
public void compact() {
108+
this.events.entrySet().removeIf(entry -> entry.getValue().isEmpty());
109+
}
110+
111+
/**
112+
* @return The total amount of events in a song.
113+
*/
114+
public int getEventCount() {
115+
return this.events.values().stream().mapToInt(List::size).sum();
116+
}
117+
118+
public Events copy() {
119+
final Events copyEvents = new Events();
120+
for (Map.Entry<Integer, List<Event>> entry : this.events.entrySet()) {
121+
final List<Event> eventList = new ArrayList<>();
122+
for (Event event : entry.getValue()) {
123+
eventList.add(event.copy());
124+
}
125+
copyEvents.events.put(entry.getKey(), eventList);
126+
}
127+
return copyEvents;
128+
}
129+
130+
}

src/main/java/net/raphimc/noteblocklib/model/song/Song.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package net.raphimc.noteblocklib.model.song;
1919

2020
import net.raphimc.noteblocklib.format.SongFormat;
21+
import net.raphimc.noteblocklib.model.event.Events;
2122
import net.raphimc.noteblocklib.model.event.TempoEvents;
2223
import net.raphimc.noteblocklib.model.note.Notes;
2324

@@ -28,6 +29,7 @@ public abstract class Song {
2829

2930
private final SongFormat format;
3031
private Notes notes = new Notes();
32+
private Events events = new Events();
3133
private TempoEvents tempoEvents = new TempoEvents();
3234
private final String fileName;
3335
private String title;
@@ -106,6 +108,10 @@ public Notes getNotes() {
106108
return this.notes;
107109
}
108110

111+
public Events getEvents() {
112+
return this.events;
113+
}
114+
109115
public TempoEvents getTempoEvents() {
110116
return this.tempoEvents;
111117
}
@@ -196,6 +202,7 @@ public String getTitleOrFileNameOr(final String fallback) {
196202

197203
public void copyGeneralData(final Song song) {
198204
this.notes = song.getNotes().copy();
205+
this.events = song.getEvents().copy();
199206
this.tempoEvents = song.getTempoEvents().copy();
200207
this.setTitle(song.getTitle());
201208
this.setAuthor(song.getAuthor());

0 commit comments

Comments
 (0)