Skip to content

Commit

Permalink
18 fr improve pokertable event listener functionality (#22)
Browse files Browse the repository at this point in the history
Implemented AssignRoles and ValidatePlayerChips methods in PokerTable
Class
  • Loading branch information
astitvsingh authored Nov 15, 2024
2 parents 1e4aff4 + 83af847 commit 5620627
Show file tree
Hide file tree
Showing 8 changed files with 528 additions and 238 deletions.
8 changes: 8 additions & 0 deletions src/enums/events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ export * as CasinoEventsEnumModule from "./casino";
export * from "./casino";
export * as DeckEventsEnumModule from "./deck";
export * from "./deck";
export * as PokerGameEventsEnumModule from "./pokerGame";
export * from "./pokerGame";
export * as PokerPhaseEventsEnumModule from "./pokerPhase";
export * from "./pokerPhase";
export * as PokerPlayerEventsEnumModule from "./pokerPlayer";
export * from "./pokerPlayer";
export * as PokerRoomEventsEnumModule from "./pokerRoom";
export * from "./pokerRoom";
export * as PokerSeatEventsEnumModule from "./pokerSeat";
export * from "./pokerSeat";
export * as PokerTableEventsEnumModule from "./pokerTable";
Expand Down
41 changes: 40 additions & 1 deletion src/enums/events/pokerSeat/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

//@collapse

/**
Expand Down Expand Up @@ -66,4 +67,42 @@ enum PokerSeatEvents {
VACATED = "PokerSeat:Vacated",
}

export { PokerSeatEvents };
enum PokerSeatRoles {
/**
* Indicates that the seat has been initialized and is ready for occupancy.
*
* @example
* ```typescript
* const seatEvent: PokerSeatEvents = PokerSeatEvents.INITIALIZED;
* console.log(seatEvent);
* // Console Output: "PokerSeat:Initialized"
* ```
*/
DEALER = "PokerSeat:Dealer",

/**
* Indicates a seat has been occupied by a player.
*
* @example
* ```typescript
* const seatEvent: PokerSeatEvents = PokerSeatEvents.OCCUPIED;
* console.log(seatEvent);
* // Console Output: "PokerSeat:Occupied"
* ```
*/
SMALLBLIND = "PokerSeat:SmallBlind",

/**
* Indicates a seat has been vacated by a player.
*
* @example
* ```typescript
* const seatEvent: PokerSeatEvents = PokerSeatEvents.VACATED;
* console.log(seatEvent);
* // Console Output: "PokerSeat:Vacated"
* ```
*/
BIGBLIND = "PokerSeat:BigBlind",
}

export { PokerSeatEvents , PokerSeatRoles};
12 changes: 12 additions & 0 deletions src/enums/events/pokerTable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ enum PokerTableEvents {
* ```
*/
INITIALIZED = "PokerTable:Initialized",

/**
* Indicates that the seat has been initialized and is ready for occupancy.
*
* @example
* ```typescript
* const seatEvent: PokerTableEvents = PokerTableEvents.INITIALIZED;
* console.log(seatEvent);
* // Console Output: "PokerTable:Initialized"
* ```
*/
NEW_GAME = "PokerTable:NewGame",
}

export { PokerTableEvents };
3 changes: 3 additions & 0 deletions src/interfaces/pokerPlayer/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

//@collapse

import { BaseEventEmitterInterface } from "../_base";
Expand Down Expand Up @@ -66,6 +67,8 @@ interface PokerPlayerInterface extends BaseEventEmitterInterface {
*/
getId(): string;

getChips():number;

bet(amount: number): boolean;

setIsFolded(bool: boolean): boolean;
Expand Down
11 changes: 10 additions & 1 deletion src/interfaces/pokerSeat/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@



//@collapse

import { BaseEventEmitterInterface } from "../_base";
Expand All @@ -18,7 +21,7 @@ interface PokerSeatConfig {
* @property {number} position
* The maximum number of players that can be seated at the PokerTable[2-14].
*/
position: number;
position?: number;

/**
* @property {boolean} isDealer
Expand All @@ -31,6 +34,8 @@ interface PokerSeatConfig {
* The maximum number of players that can be seated at the PokerTable[2-14].
*/
player?: PokerPlayerInterface;

role?:string[];
}

/**
Expand Down Expand Up @@ -110,6 +115,10 @@ interface PokerSeatInterface extends BaseEventEmitterInterface {
*/
getPlayer(): PokerPlayerInterface | undefined;

getRoles(): string[];

addRole(role:string): string[];

/**************************************************************************************************************
* UPDATE METHODS (MODIFYING EXISTING OBJECTS)
**************************************************************************************************************/
Expand Down
153 changes: 14 additions & 139 deletions src/models/_base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { EventEmitter } from "events";
import { LogLevel } from "../../enums";

// Import Interfaces
import { BaseEventEmitterInterface, BaseEventInterface } from "../../interfaces";
import {
BaseEventEmitterInterface,
BaseEventInterface,
} from "../../interfaces";

// Import Utils
import { generateUniqueId, logger } from "../../utils";
Expand Down Expand Up @@ -147,71 +150,14 @@ class BaseEventEmitter
data: { [key: string]: any };
[key: string]: any;
};
middlewares?: Array<(event: BaseEventInterface, next: () => void) => void | false>;
middlewares?: Array<
(event: BaseEventInterface, next: () => void) => void | false
>;
}
): void {
this.__emitEvent(eventName, options);
}

/**
* #### Description
* The `emitEvent` method is a public method for emitting events, with an optional configuration that allows
* middleware processing. Middleware functions can intercept and transform the event before it reaches the listeners,
* allowing custom validation or data modifications.
*
* #### Purpose
* This method enables flexible event emission with support for middleware, providing a robust event processing
* mechanism in the `BaseEventEmitter`. It’s useful for customizing event behavior based on application-specific needs.
*
* #### Implements
* N/A
*
* #### Overrides
* N/A
*
* #### Events
* This method can emit any event specified by `eventName`, which can then be processed by middleware functions if defined.
*
* #### Parameters
* - `eventName: string` - The name of the event to emit.
* - `options: { event: { data: { [key: string]: any }; [key: string]: any; }, middlewares?: Array<(event: BaseEventInterface, next: () => void) => void | false> }`
* - **event** - The primary event data to emit, containing specific details.
* - **middlewares** - An optional array of middleware functions that process the event before emission.
*
* #### Requirements
* - `eventName` must be a valid string.
* - `options.event` should include relevant data for the event. If `middlewares` are provided, they should be functions with an event and next parameter.
*
* #### Returns
* - `void` - This method does not return a value.
*
* #### Usage
* Use this method to emit events with middleware-based customization, which allows for specific processing
* logic or transformations before the event reaches listeners.
*
* @param {string} eventName - The name of the event to emit.
* @param {object} options - Configuration for the event and optional middleware functions.
*
* @example
* ```typescript
* emitter.emitEvent("game:started", {
* event: { data: { gameId: "001", status: "active" } },
* middlewares: [
* (event, next) => { console.log("Processing event:", event); next(); },
* (event, next) => { event.data.processed = true; next(); }
* ]
* });
* ```
*/
public listenToEvent(
eventName: string,
options: {
handler: (event: BaseEventInterface) => void;
middlewares?: Array<(event: BaseEventInterface, next: () => void) => void | false>;
}
): void {
this.__listenToEvent(eventName, options);
}
/**************************************************************************************************************
* WRAPPER METHODS (UTILITY & CONVENIENCE)
**************************************************************************************************************/
Expand Down Expand Up @@ -274,10 +220,15 @@ class BaseEventEmitter
data: { [key: string]: any };
[key: string]: any;
};
middlewares?: Array<(event: BaseEventInterface, next: () => void) => void | false>;
middlewares?: Array<
(event: BaseEventInterface, next: () => void) => void | false
>;
}
): void {
const event: BaseEventInterface = this.__initializeEventObj(eventName, options);
const event: BaseEventInterface = this.__initializeEventObj(
eventName,
options
);
const middlewares = options.middlewares ?? [];

if (middlewares.length > 0) {
Expand Down Expand Up @@ -349,82 +300,6 @@ class BaseEventEmitter
logger.log(LogLevel.INFO, `Event initialized: "${eventName}"`, baseEvent);
return baseEvent;
}


/**
* #### Description
* The `__listenToEvent` method is a private listener method within the `BaseEventListener` class that listens to
* a specified event and allows middleware processing before handling the event data.
*
* #### Purpose
* This method enables event listening within `BaseEventListener`, supporting middleware-based pre-processing
* of events before they reach the main handler.
*
* #### Events
* Subscribes to the specified event and applies middleware before handling.
*
* #### Parameters
* - `eventName: string` - The event name to listen for.
* - `options: { handler: (event: BaseEventInterface) => void, middlewares?: Array<(event: BaseEventInterface, next: () => void) => void | false> }`
* - **handler** - Function that handles the processed event.
* - **middlewares** - Optional array of middleware functions for processing the event before it reaches the handler.
*
* #### Requirements
* - `eventName` must be a valid string.
* - `handler` must be a function that processes the event data.
* - If `middlewares` are provided, they should be functions that accept an event and a `next` function.
*
* #### Returns
* - `void` - This method does not return a value.
*
* #### Usage
* Use this method to listen to events within the `BaseEventListener` and apply middleware before passing them
* to the handler.
*
* @param {string} eventName - The event name to listen for.
* @param {object} options - Configuration object containing the handler and optional middleware functions.
*
* @example
* ```typescript
* listener.__listenToEvent("room:updated", {
* handler: (event) => { console.log("Event received:", event); },
* middlewares: [
* (event, next) => { event.data.timestamp = Date.now(); next(); },
* (event, next) => { if (event.data.isValid) next(); else console.log("Invalid event data"); }
* ]
* });
* ```
*/
private __listenToEvent(
eventName: string,
options: {
handler: (event: BaseEventInterface) => void;
middlewares?: Array<(event: BaseEventInterface, next: () => void) => void | false>;
}
): void {
const middlewares = options.middlewares ?? [];
const handler = options.handler;

// Register the event listener
this.on(eventName, (event: BaseEventInterface) => {
if (middlewares.length > 0) {
// Middleware processing
const processMiddlewares = (index: number) => {
if (index < middlewares.length) {
middlewares[index](event, () => processMiddlewares(index + 1));
} else {
handler(event);
logger.log(LogLevel.INFO, `Event handled: "${eventName}"`, event);
}
};
processMiddlewares(0);
} else {
// Directly invoke handler if no middleware
handler(event);
logger.log(LogLevel.INFO, `Event handled: "${eventName}"`, event);
}
});
}
}

export { BaseEventEmitter };
Loading

0 comments on commit 5620627

Please sign in to comment.