/* * NodeIDAllocator.java * JCollider * * Copyright (c) 2004-2010 Hanns Holger Rutz. All rights reserved. * * This software is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either * version 2, june 1991 of the License, or (at your option) any later version. * * This software 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 * General Public License for more details. * * You should have received a copy of the GNU General Public * License (gpl.txt) along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * For further information, please contact Hanns Holger Rutz at * contact@sciss.de , or visit http://www.sciss.de/jcollider * * * JCollider is closely modelled after SuperCollider Language, * often exhibiting a direct translation from Smalltalk to Java. * SCLang is a software originally developed by James McCartney, * which has become an Open Source project. * See http://www.audiosynth.com/ for details. * * * Changelog: * 04-Aug-05 created */ package de.sciss.jcollider; /** * Quite a 1:1 translation from SClang, this * is used as the default node allocator by the server. * * @todo allocPerm should be more generally available * from other classes such as Synth and Group, * because it can be vital to sound installation * programming where the non-perm node count * might well end up at the maximum value(?) * * @todo should check if user-max should be one less * because java ints are signed?! * * @author Hanns Holger Rutz * @version 0.31, 08-Oct-07 */ public class NodeIDAllocator { private final int user; private int mask; private int temp; private int perm; private static final int MASK_SHIFT = 26; private static final int USER_MAX = (1 << (32 - MASK_SHIFT)) - 1; // := 31 private static final int TEMP_MIN = 1000; private static final int TEMP_MAX = (1 << 26) - 1; private static final int PERM_MIN = 2; private static final int PERM_MAX = TEMP_MIN - 1; public NodeIDAllocator() { this( 0 ); } public NodeIDAllocator( int user ) { if( user > USER_MAX ) throw new IllegalArgumentException( "NodeIDAllocator user ID > " + USER_MAX ); this.user = user; reset(); } public void reset() { synchronized( this ) { mask = user << MASK_SHIFT; temp = TEMP_MIN; perm = PERM_MIN; } } public int alloc() { synchronized( this ) { final int result = temp | mask; if( ++temp > TEMP_MAX ) { temp = TEMP_MIN; System.err.println( "Warning: NodeIDAllocator exceeded maximum node ID!" ); } return result; } } public int allocPerm() { synchronized( this ) { final int result = perm | mask; if( ++perm > PERM_MAX ) { perm = PERM_MAX; System.err.println( "Warning: NodeIDAllocator exceeded maximum permanent node ID!\n" + "Assigning temporary ID!" ); return alloc(); } return result; } } public static int getUserMax() { return USER_MAX; } }