github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekaerr/class_id.go (about)

     1  // Copyright © 2020. All rights reserved.
     2  // Author: Ilya Stroy.
     3  // Contacts: iyuryevich@pm.me, https://github.com/qioalice
     4  // License: https://opensource.org/licenses/MIT
     5  
     6  package ekaerr
     7  
     8  import (
     9  	"sync/atomic"
    10  )
    11  
    12  type (
    13  	// ClassID is just int32 alias and has been introduced to make it easy
    14  	// to replace underlying type to something other in the future.
    15  	ClassID = int32
    16  )
    17  
    18  //noinspection GoSnakeCaseUsage
    19  const (
    20  	// _ERR_INVALID_CLASS_ID is a special reserved invalid Class ID
    21  	// that is used to mark that some Class is invalid.
    22  	_ERR_INVALID_CLASS_ID = -1
    23  )
    24  
    25  var (
    26  	// classIDPrivateCounter is an internal ClassID counter that is increased
    27  	// at the new error Class creating.
    28  	//
    29  	// DO NOT USE IT DIRECTLY! Use newClassID() instead.
    30  	classIDPrivateCounter ClassID
    31  )
    32  
    33  // newClassID returns new ClassID value that can be used as new Class's ID.
    34  // Thread-safety.
    35  func newClassID() ClassID {
    36  	return atomic.AddInt32(&classIDPrivateCounter, 1)
    37  }
    38  
    39  // isValidClassID reports whether 'classID' is valid Class's ID.
    40  // Remember, it has been done to avoid cases when Class object has been manually
    41  // instantiated (like 'new(Class)' or 'var _ Class') and thus has not been initialized.
    42  func isValidClassID(classID ClassID) bool {
    43  	// Because in the Class object ID is private and can not be accessed
    44  	// from the outside, it's enough to check whether it's not 0 (manually instantiated),
    45  	// but theoretically classID may be equal _ERR_INVALID_CLASS_ID. Check it too.
    46  	return classID > 0 && classID != _ERR_INVALID_CLASS_ID
    47  }
    48  
    49  // classByID returns Class object bases on 'classID' and if Class with provided
    50  // 'classID' stored into the Classes' map, 'lock' indicates whether map's access
    51  // must be protected by its R mutex or not.
    52  //
    53  // WARNING! Make sure you checked whether provided 'classID' is valid using
    54  // isValidClassID() func. UB otherwise (may panic).
    55  func classByID(classID ClassID, lock bool) Class {
    56  	if classID < _ERR_CLASS_ARRAY_CACHE {
    57  		return registeredClassesArr[classID]
    58  	} else {
    59  		if lock {
    60  			registeredClassesMap.RLock()
    61  			defer registeredClassesMap.RUnlock()
    62  		}
    63  		return registeredClassesMap.m[classID]
    64  	}
    65  }