Petri Hintukainen pushed to branch master at VideoLAN / libbluray
Commits:
ef4a9b88 by spotter at 2026-01-16T17:18:35+00:00
BD-J: Implement TVTimer and TVTimerSpec
- - - - -
4 changed files:
- src/libbluray/bdj/java/javax/tv/util/TVTimer.java
- + src/libbluray/bdj/java/javax/tv/util/TVTimerImpl.java
- src/libbluray/bdj/java/javax/tv/util/TVTimerSpec.java
- src/libbluray/bdj/java/org/videolan/BDJXletContext.java
Changes:
=====================================
src/libbluray/bdj/java/javax/tv/util/TVTimer.java
=====================================
@@ -20,11 +20,23 @@
package javax.tv.util;
import org.videolan.Logger;
+import org.videolan.BDJXletContext;
public abstract class TVTimer
{
- public static TVTimer getTimer() {
- Logger.unimplemented(TVTimer.class.getName(), "getTimer");
+ public static synchronized TVTimer getTimer() {
+ BDJXletContext context = BDJXletContext.getCurrentContext();
+
+ if (context != null) {
+ if (context.getTVTimer() == null) {
+ context.setTVTimer(new TVTimerImpl());
+ }
+
+ return context.getTVTimer();
+ }
+
+ logger.error("getTimer(): no context at " + Logger.dumpStack());
+
return null;
}
@@ -36,4 +48,6 @@ public abstract class TVTimer
public abstract long getMinRepeatInterval();
public abstract void deschedule(TVTimerSpec paramTVTimerSpec);
+
+ private static final Logger logger =
Logger.getLogger(TVTimer.class.getName());
}
=====================================
src/libbluray/bdj/java/javax/tv/util/TVTimerImpl.java
=====================================
@@ -0,0 +1,110 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2016 VideoLAN
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+package javax.tv.util;
+
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.Hashtable;
+
+public class TVTimerImpl extends TVTimer
+{
+ private Timer timer;
+ private Hashtable scheduledTasks = new Hashtable(); // TVTimerSpec ->
TimerTask
+
+ public TVTimerImpl() {
+ timer = new Timer(true); // daemon thread
+ }
+
+ public TVTimerSpec scheduleTimerSpec(final TVTimerSpec spec)
+ throws TVTimerScheduleFailedException {
+ if (spec == null) {
+ throw new TVTimerScheduleFailedException("TVTimerSpec is null");
+ }
+
+ // Cancel any existing schedule for this spec
+ deschedule(spec);
+
+ final TVTimer self = this;
+ TimerTask task = new TimerTask() {
+ public void run() {
+ try {
+ spec.notifyListeners(self);
+ } catch (Exception e) {
+ System.err.println("TVTimer: Exception in timer callback:
" + e);
+ e.printStackTrace();
+ }
+ if (!spec.isRepeat()) {
+ scheduledTasks.remove(spec);
+ }
+ }
+ };
+
+ scheduledTasks.put(spec, task);
+
+ long delay = spec.getTime();
+ if (spec.isAbsolute()) {
+ // Absolute time - calculate delay from current time
+ long now = System.currentTimeMillis();
+ delay = spec.getTime() - now;
+ if (delay < 0) {
+ delay = 0; // Fire immediately if time has passed
+ }
+ }
+
+ try {
+ if (spec.isRepeat()) {
+ long period = spec.getTime();
+ if (period <= 0) {
+ period = 1; // Minimum 1ms period
+ }
+ timer.scheduleAtFixedRate(task, delay, period);
+ } else {
+ timer.schedule(task, delay);
+ }
+ } catch (Exception e) {
+ scheduledTasks.remove(spec);
+ throw new TVTimerScheduleFailedException("Failed to schedule: " +
e.getMessage());
+ }
+
+ return spec;
+ }
+
+ public long getGranularity() {
+ return 1L; // 1 millisecond granularity
+ }
+
+ public long getMinRepeatInterval() {
+ return 1L; // 1 millisecond minimum repeat
+ }
+
+ public void deschedule(TVTimerSpec spec) {
+ if (spec != null) {
+ TimerTask task = (TimerTask) scheduledTasks.remove(spec);
+ if (task != null) {
+ task.cancel();
+ }
+ }
+ }
+
+ public void shutdown() {
+ timer.cancel();
+ scheduledTasks.clear();
+ }
+}
=====================================
src/libbluray/bdj/java/javax/tv/util/TVTimerSpec.java
=====================================
@@ -23,14 +23,13 @@ import java.util.Enumeration;
import java.io.Serializable;
import java.util.Vector;
-import org.videolan.Logger;
-
public class TVTimerSpec implements Serializable
{
private boolean absolute;
private boolean regular;
private boolean repeat;
private long time;
+ private Vector listeners = new Vector(); // TVTimerWentOffListener
public TVTimerSpec() {
absolute = true;
@@ -56,15 +55,34 @@ public class TVTimerSpec implements Serializable
}
public void addTVTimerWentOffListener(TVTimerWentOffListener l) {
- Logger.unimplemented(TVTimer.class.getName(),
"addTVTimerWentOffListener");
+ if (l != null && !listeners.contains(l)) {
+ listeners.addElement(l);
+ }
}
public void removeTVTimerWentOffListener(TVTimerWentOffListener l) {
- Logger.unimplemented(TVTimer.class.getName(),
"removeTVTimerWentOffListener");
+ if (l != null) {
+ listeners.removeElement(l);
+ }
}
public void notifyListeners(TVTimer source) {
- Logger.unimplemented(TVTimer.class.getName(), "notifyListeners");
+ TVTimerWentOffEvent event = new TVTimerWentOffEvent(source, this);
+ // Copy to avoid ConcurrentModificationException
+ Vector listenersCopy;
+ synchronized (listeners) {
+ listenersCopy = new Vector(listeners);
+ }
+ Enumeration e = listenersCopy.elements();
+ while (e.hasMoreElements()) {
+ TVTimerWentOffListener listener = (TVTimerWentOffListener)
e.nextElement();
+ try {
+ listener.timerWentOff(event);
+ } catch (Exception ex) {
+ System.err.println("TVTimerSpec: Exception in listener: " +
ex);
+ ex.printStackTrace();
+ }
+ }
}
public void setAbsolute(boolean absolute) {
=====================================
src/libbluray/bdj/java/org/videolan/BDJXletContext.java
=====================================
@@ -30,6 +30,8 @@ import java.security.PrivilegedAction;
import javax.microedition.xlet.UnavailableContainerException;
+import javax.tv.util.TVTimerImpl;
+
import org.bluray.ui.FrameAccurateAnimation;
import org.dvb.application.AppID;
import org.dvb.application.AppProxy;
@@ -282,6 +284,14 @@ public class BDJXletContext implements
javax.tv.xlet.XletContext, javax.microedi
return sceneFactory;
}
+ public void setTVTimer(TVTimerImpl tvt) {
+ tvTimer = tvt;
+ }
+
+ public TVTimerImpl getTVTimer() {
+ return tvTimer;
+ }
+
public static Object getXletDefaultLook(String key, Class defClass) {
BDJXletContext ctx = BDJXletContext.getCurrentContext();
if (ctx == null) {
@@ -492,6 +502,9 @@ public class BDJXletContext implements
javax.tv.xlet.XletContext, javax.microedi
callbackQueue.shutdown();
userEventQueue.shutdown();
mediaQueue.shutdown();
+ if (tvTimer != null) {
+ tvTimer.shutdown();
+ }
}
EventQueue eq = eventQueue;
@@ -516,6 +529,7 @@ public class BDJXletContext implements
javax.tv.xlet.XletContext, javax.microedi
callbackQueue = null;
userEventQueue = null;
mediaQueue = null;
+ tvTimer = null;
}
synchronized (this) {
threadGroup = null;
@@ -546,5 +560,6 @@ public class BDJXletContext implements
javax.tv.xlet.XletContext, javax.microedi
private BDJActionQueue callbackQueue;
private BDJActionQueue userEventQueue;
private BDJActionQueue mediaQueue;
+ private TVTimerImpl tvTimer = null;
private static final Logger logger =
Logger.getLogger(BDJXletContext.class.getName());
}
View it on GitLab:
https://code.videolan.org/videolan/libbluray/-/commit/ef4a9b88a263b66ffd7b82e8c1d1efb253852daa
--
View it on GitLab:
https://code.videolan.org/videolan/libbluray/-/commit/ef4a9b88a263b66ffd7b82e8c1d1efb253852daa
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance_______________________________________________
libbluray-devel mailing list
[email protected]
https://mailman.videolan.org/listinfo/libbluray-devel