Skip to content

Commit

Permalink
feat: add optional system hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
dhvanipa committed Mar 18, 2024
1 parent 9055202 commit ddd84f2
Show file tree
Hide file tree
Showing 9 changed files with 800 additions and 0 deletions.
10 changes: 10 additions & 0 deletions packages/world/mud.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ export default mudConfig({
},
valueSchema: "bytes21[]",
},
OptionalSystemHooks: {
keySchema: {
player: "address",
systemId: "ResourceId",
callDataHash: "bytes32",
},
valueSchema: {
hooks: "bytes21[]",
},
},
FunctionSelectors: {
keySchema: {
worldFunctionSelector: "bytes4",
Expand Down
24 changes: 24 additions & 0 deletions packages/world/src/IOptionalSystemHook.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.24;

import { ISystemHook } from "./ISystemHook.sol";

/**
* @title IOptionalSystemHook
* @dev Interface defining optional hooks for external functionality.
* Provides pre and post hooks that can be triggered before and after a system call respectively.
* This interface adheres to the ERC-165 standard for determining interface support.
*/
interface IOptionalSystemHook is ISystemHook {
/**
* @notice Executes when a system hook is registered by the user.
* @dev Provides the ability to add custom logic or checks when a system hook is registered.
*/
function onRegisterHook() external;

/**
* @notice Executes when a system hook is unregistered by the user.
* @dev Provides the ability to add custom logic or checks when a system hook is unregistered.
*/
function onUnregisterHook() external;
}
34 changes: 34 additions & 0 deletions packages/world/src/SystemCall.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import { BEFORE_CALL_SYSTEM, AFTER_CALL_SYSTEM } from "./systemHookTypes.sol";

import { IWorldErrors } from "./IWorldErrors.sol";
import { ISystemHook } from "./ISystemHook.sol";
import { IOptionalSystemHook } from "./IOptionalSystemHook.sol";

import { Systems } from "./codegen/tables/Systems.sol";
import { SystemHooks } from "./codegen/tables/SystemHooks.sol";
import { OptionalSystemHooks } from "./codegen/tables/OptionalSystemHooks.sol";
import { Balances } from "./codegen/tables/Balances.sol";

/**
Expand Down Expand Up @@ -93,6 +95,10 @@ library SystemCall {
// Get system hooks
bytes21[] memory hooks = SystemHooks._get(systemId);

// Get optional hooks specified by the caller
bytes21[] memory optionalSystemHooks = OptionalSystemHooks._get(caller, systemId, bytes32(0));
bytes21[] memory optionalSystemHooksWithCallData = OptionalSystemHooks._get(caller, systemId, keccak256(callData));

// Call onBeforeCallSystem hooks (before calling the system)
for (uint256 i; i < hooks.length; i++) {
Hook hook = Hook.wrap(hooks[i]);
Expand All @@ -101,6 +107,20 @@ library SystemCall {
}
}

// Call optional onBeforeCallSystem hooks (before calling the system)
for (uint256 i; i < optionalSystemHooks.length; i++) {
Hook hook = Hook.wrap(optionalSystemHooks[i]);
if (hook.isEnabled(BEFORE_CALL_SYSTEM)) {
IOptionalSystemHook(hook.getAddress()).onBeforeCallSystem(caller, systemId, callData);
}
}
for (uint256 i; i < optionalSystemHooksWithCallData.length; i++) {
Hook hook = Hook.wrap(optionalSystemHooksWithCallData[i]);
if (hook.isEnabled(BEFORE_CALL_SYSTEM)) {
IOptionalSystemHook(hook.getAddress()).onBeforeCallSystem(caller, systemId, callData);
}
}

// Call the system and forward any return data
(success, data) = call({ caller: caller, value: value, systemId: systemId, callData: callData });

Expand All @@ -111,6 +131,20 @@ library SystemCall {
ISystemHook(hook.getAddress()).onAfterCallSystem(caller, systemId, callData);
}
}

// Call optional onAfterCallSystem hooks (after calling the system)
for (uint256 i; i < optionalSystemHooks.length; i++) {
Hook hook = Hook.wrap(optionalSystemHooks[i]);
if (hook.isEnabled(AFTER_CALL_SYSTEM)) {
IOptionalSystemHook(hook.getAddress()).onAfterCallSystem(caller, systemId, callData);
}
}
for (uint256 i; i < optionalSystemHooksWithCallData.length; i++) {
Hook hook = Hook.wrap(optionalSystemHooksWithCallData[i]);
if (hook.isEnabled(AFTER_CALL_SYSTEM)) {
IOptionalSystemHook(hook.getAddress()).onAfterCallSystem(caller, systemId, callData);
}
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/world/src/codegen/index.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/world/src/codegen/interfaces/IBaseWorld.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ddd84f2

Please sign in to comment.