paradigm-mp / oof Goto Github PK
View Code? Open in Web Editor NEWObject-Oriented Framework for developing with Lua in FiveM and RedM
Home Page: https://discord.gg/XAQ34Td
License: GNU General Public License v3.0
Object-Oriented Framework for developing with Lua in FiveM and RedM
Home Page: https://discord.gg/XAQ34Td
License: GNU General Public License v3.0
For the Events and Network classes, we want a class instance to be able to set-up a subscription like:
Network:Subscribe("EventName", self, self.EventNameHandlerFunction)
Events:Subscribe("EventName", self, self.EventNameHandlerFunction)
Currently we are doing it like:
Events:Subscribe("EventName", function(args) self:EventNameHandlerFunction(args) end)
We would still like to support the (event_name, handler) usage of the Subscribe functions. We just need to check the type and number of the arguments.
Works for FiveM though
For some api stuff we should make iterators that work like:
for player in Players:GetPlayers() do
instead of what we currently have:
for player_uid, player in pairs(Players:GetPlayers()) do
Since iterator code is very unreadable, every place where we make an iterator like this, we should provide an example usage as a comment above the function declaration
I think we could make a special class that would allow you to log errors/warnings with a single style easily. This is certainly not a very important addition, but it is not useless either.
Currently we just see the assert error message, and not the stack trace leading to where the assert happened. We want to use debug.traceback()
to print the stack trace
The timers that are in use now are just their likeness.
IMHO would be nice to make them like this:
-- Creates a simple timer that runs the given function after a specified delay.
function timer.simple(delay, function) end
-- other possible function name - timer.create
-- Creates a new timer that will repeat its function given amount of times.
function timer.repeating(delay, repititions, function)
creates and returnes TimerObject
end
function TimerObject:Pause() end
function TimerObject:Resume() end
function TimerObject:Restart() end
-- Returns amount of repetitions/executions left before the timer destroys itself.
function TimerObject():RespLeft() end
function TimerObject:Adjust(delay, repititions, function) end
function TimerObject:Destroy() end
I think everyone agrees that such timers will save a lot of effort.
Currently we collect class instance initializations of the first frame until all files are loaded, and after that we run the constructors.
However a valid use case would be to initialize a class instance on the first frame and call a function on it, and that doesn't work properly right now because the function would be called before the constructor runs.
Currently the advantage of collecting the constructors is that we can stall the initialization of client-side code until data is fetched. One way we use this is to ensure all Player data is available in constructors on the client, and we don't want to lose that functionality.
Potential solution: Temporarily define __call metatable event on non-initialized class instances and remove this when initialization is complete. In the intercept code, we check if the class instance has initialized, and if not, we immediately run the constructor for that class instance. Also we can add a warning/error message that it's not recommended to use a class instance on the first frame since other constructors have not executed, and that the function call on that instance should be moved inside of a Events:Subscribe("ClientReady", function() end)
block so that it has access to the entire initialized environment
We want to be able to control the order in which inherited class constructors are executed, so we would want something like self.super(BaseClassA)
For file names, we want cFileNamePattern.lua
, or sFileNamePattern.lua
, or shFileNamePattern.lua
depending on if the file is a client, server, or shared file respectively.
For class names, we want want to avoid the c
, s
, and sh
prefixes
Removing an object before it is created can result in the object being created but not destroyed properly because of the asynchronous nature of spawning objects. Should implement some sort of check to prevent issues like this.
Take the MySQL resource and add it directly to NAPI so there is no need to have an external dependency to work with a database.
For the object editor, objects always spawn at 0,0,0
Clientside OOF initialization uses an arbitrary delay to wait for information from the network. Should use a callback + retries instead.
Hello, there is a new type of "identifiers" that could be useful for developers.
These tokens are more clearly explained in this original commit : Commit
This is very low priority because we could very easily get them without the Player class, but exposing them in their specifics methods could expose them to more developers that don't know about this beautiful system.
Natives for references :
Persistent storage for Player class. Will use SQL table with a JSON column. Implement caching value after an update & on PlayerJoin.
It breaks with this error:
InvokeNative: execution failed: No current resource manager.
[ERROR] [MySQL] An critical error happens on MySQL for query "CREATE TABLE IF NOT EXISTS `key_value_store` (`key` VARCHAR(200) NOT NULL PRIMARY KEY, `value_type` VARCHAR(50), `value` TEXT) {=}": No current resource manager. at CitizenFX.Core.ScriptContext.InvokeInternal (CitizenFX.Core.fxScriptContext* cxt, System.UInt64 nativeIdentifier, CitizenFX.Core.IScriptHost scriptHost) [0x00025] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\ScriptContext.cs:358
at CitizenFX.Core.ScriptContext.InvokeInternal (System.UInt64 nativeIdentifier, CitizenFX.Core.IScriptHost scriptHost) [0x00014] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\ScriptContext.cs:336
at CitizenFX.Core.ScriptContext.Invoke (System.UInt64 nativeIdentifier, CitizenFX.Core.IScriptHost scriptHost) [0x00000] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\ScriptContext.cs:327
at CitizenFX.Core.Native.Function.InvokeInternal (CitizenFX.Core.Native.Hash nativeHash, System.Type returnType, CitizenFX.Core.Native.InputArgument[] args) [0x00022] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\Native.cs:28
at CitizenFX.Core.Native.Function.Call[T] (CitizenFX.Core.Native.Hash hash, CitizenFX.Core.Native.InputArgument[] arguments) [0x00000] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\Native.cs:11
at CitizenFX.Core.RemoteFunctionReference._InvokeNative (System.Byte[] argsSerialized) [0x00026] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\RemoteFunctionReference.cs:92
at CitizenFX.Core.RemoteFunctionReference.InvokeNative (System.Byte[] argsSerialized) [0x00000] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\RemoteFunctionReference.cs:72
at CitizenFX.Core.MsgPackDeserializer+<>c__DisplayClass36_0.<CreateRemoteFunctionReference>b__0 (System.Object[] args) [0x00007] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\MsgPackDeserializer.cs:267
at MySQLAsync.Operation`1[TResult].ExecuteAsync (System.String query, System.Collections.Generic.IDictionary`2[TKey,TValue] parameters, CitizenFX.Core.CallbackDelegate callback, System.Boolean debug) [0x001e5] in <25ffe552fd484023b5b41531f38bf148>:0
The MySQL async C# code will likely need to be modified for this to be solved, or a synchronous version will need to be used.
Supposedly adding await BaseScript.Delay(0);
will fix the issue.
Hello,
I would like to suggest supporting more server-side natives in the Player class server-side
There is a lot we can do now server-side that is good practice for security reasons ๐
For reference here is the file containing all the rpc natives for FiveM rpc_spec_natives.lua
You can also search on the Native Reference documentation for server-side natives by filtering for server API-set Image and then search for "Entity" or "Ped" or even "Player".
All of these natives combined can be use to manage peds (perhaps creating a server side Entity class / Ped class)
It would be nice (because changing library core files isn't nice) to make a language module to get phrases accorded to specified language from config. Because English language of course is world-wide, but some owners may prefer that players receive information exclusively in their own language. I can translate the phrases into Russian because I have the necessary knowledge.
Also if you approve the idea, then soon I can close the issue
Just like we did with KeyValueStore
(#18), it would be nice if we could run SQL queries & commands synchronously
I ran into the issue where I needed to grab 3 KeyValueStore values at once and saw two ways to structure my code:
Option 1) is favored because of the low complexity to achieve a block of code that will handle all 3 values, but results in disgusting nesting of KVS requests.
Option 2) has no nesting, but is too complex and verbose to leverage easily because of the need to spin up a thread to wait for the requests.
We need a KeyValueStore Get
solution that uses Option 2) under the hood. It runs all the requests concurrently (or aggregates to 1 request), and returns all the results in a single callback.
Due to the asynchronous nature of KeyValueStore which uses callbacks, there are difficulties with organizing and structuring code that fetches multiple keys at once or certain keys in sequence. We can write simpler and more readable code with a synchronous option that would end up looking like this:
CreateThread(function()
local value1 = KeyValueStore:Get({key = "Key1", synchronous = true})
local value2 = KeyValueStore:Get({key = "Key2", synchronous = true})
if value1 > value2 then
print("my code looks so pretty!")
end
end)
Note: This requires refactoring KVS:Get to use single arg table instead of positional args
Implement through an inheritable Subscribable
class that adds :Subscribe and :Fire functions to a class instance.
Add support for object-oriented callback with :Subscribe
See here on usage. Would be more efficient than the polling that keypress does
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.