Open GoogleCodeExporter opened 8 years ago
This is similar to the teamlib and team managers, where the teamlib acts like
the interface. Core modules just handle events and do stuff, they usually won't
get any API functions for other modules.
Original comment by richard.helgeby@gmail.com
on 29 May 2011 at 5:35
To solve this elegantly, I think we need to implement some sort of primitive
OOP-like inheritance and polymorphism mechanism.
Speaking of modularity in ZR, I think that each module should be different
plugin that provide its own related natives. I *do* know that UMC
(http://code.google.com/p/sourcemod-ultimate-mapchooser/) has recently started
to implement this technique.
Original comment by alon.gub...@gmail.com
on 29 May 2011 at 6:17
We can sort of do polymorphism with these interface modules, but I have no idea
how to make inheritance - or objects in SoucePawn possible. That would need an
extension anyways. Unless you have some ideas?
We just have to keep this simple. Otherwise we'd just write the plugin in C++
as a SM extension or MM plugin.
Separating ZR into small plugins will work, but we're going to give this base
framework a try. Separate plugins can't get event filters unless they hook all
events through a event manager plugin. In addition the base is more than just
module management. It has several utilities and helpers too, like logging (with
filters), a common menu, helper for config parsing and translation wrappers.
The easiest solution to this problem might be to make interface modules.
Original comment by richard.helgeby@gmail.com
on 29 May 2011 at 7:42
In my opinion, the base plugin should export natives to its utilities and
helpers (logging, menu, event management, etc). This method will not only solve
the first issue - it is going to make ZR much, much more simple. Using this
method we will *automatically* create an API for about everything in ZR.
About inheritance - I do have some ideas how to implement it but they're all
really complex and requires SM extension.
Original comment by alon.gub...@gmail.com
on 29 May 2011 at 9:56
This is a bit off-topic, but we've actually had this in mind too. A long time
ago someone called mbalex tried to spend time redesign ZR this way. He was too
busy with other stuff that time, so nothing really happened. But this time
we're actually going for Greyscale's base framework. A new release is already
delayed too much. It seems to be working pretty well so far.
Not to trash your idea, but separating features into separate plugins require
natives to access "private" data within those features (and allow others to
read/modify it too) - unless there's some sort of authentication that only
allow certain plugins to use the native. By compiling it all into a single
plugin we can choose exactly what to expose.
Also there will be a lot redundancy so the total binary size will be a lot
bigger than usual. An example is the war3source plugin with ~90 plugins. Their
code is pretty short, but compiled it's above 1 MB. Space really isn't an
issue, though.
Doing object oriented programming layouts in SourcePawn is cool as long as it's
an easy and simple implementation. I like OOP, but it doesn't need it has to be
used everywhere. SourcePawn is procedural, so we do most stuff that way. Even
if we made a OOP framework for SourcePawn we'll just end up rewriting something
similar to C++. :P
We can protect global variables and functions already, by declaring them static
and writing get/set functions in modules. And instead of creating objects we
use arrays and enumerations.
With this new interface module idea, along with game cores and other modules I
think we have what we need now.
Original comment by richard.helgeby@gmail.com
on 31 May 2011 at 4:58
As far as automatically creating the API, this is also happening with the base
as we create internal events that will later become forwards.
I think the interface module thing will work. These modules would be specific
to certain game modes, so we should have a naming convention.
(zr.zriot.interface.inc) or somethin' like that? I will put more thought into
this later.
Original comment by andrewbo...@gmail.com
on 31 May 2011 at 7:38
It's exactly the opposite, where module interfaces are NOT specific to a game
mode. We need these interfaces to avoid being dependent on core modules.
Interface module just adds a layer of abstraction.
If a feature is specific to a game mode it will simply use features in the
cores directly.
Original comment by richard.helgeby@gmail.com
on 31 May 2011 at 11:48
Okay, lets go on your way. How can I help?
Original comment by alon.gub...@gmail.com
on 31 May 2011 at 8:24
One thing I didn't mention about interface modules is functions (like a
function for infecting a human).
Modules don't know which core module's infection function to use, so we can do
the same thing with functions. The interface module will have functions that
dynamically calls functions in the core module. Core modules register each of
their functions in the interface module.
When a module need to call a core API function it calls the interface's
function instead. The interface will dynamically call the correct function
(that the active core module has set).
The interface modules will be an abstraction layer above core modules. It does
nothing else but storing data and forwarding calls to the correct place.
Modules don't need to know about core modules at all because everything they
need is available through interface modules. Only in special cases they might
directly use a core module, if a feature is for certain game mode(s) only.
Also note that we're not supposed to make just one interface, but many. One for
each feature that's common between core modules. So far it looks like we only
need a infection interface, and maybe a team interface (but that's done in the
teamlib).
The infection interface could have:
* A boolean array to store who's zombie and not, with get/set functions so core
infection modules can update the state and other modules read it back.
* A boolean variable to store whether zombies are present (again, with similar
get/set functions).
* HumanToZombie and ZombieToHuman functions that dynamically calls the correct
function in the active core module. Core modules sets function IDs when loading.
Original comment by richard.helgeby@gmail.com
on 5 Jun 2011 at 8:35
When a game mode is changed or functions that aren't supported in the core,
should be reset to not forward (INVALID_FUNCTION).
Core modules will be responsible for initializing and resetting interfaces when
they are enabled and disabled so that old function pointers doesn't remain in
the interface.
Each function in the interface will need:
* A private (static) handle to store the function to call.
* A set function to set the function handle.
* A function that calls the stored function (modules call this function).
* Optional: Private (static) variables to store common data between cores. They
are retrieved through public interface functions.
Original comment by richard.helgeby@gmail.com
on 7 Jun 2011 at 10:40
Interface functions will have the same function signature as functions in the
cores. This also implies that common core functions must have identical
signatures in each core.
Original comment by richard.helgeby@gmail.com
on 7 Jun 2011 at 10:44
Original issue reported on code.google.com by
richard.helgeby@gmail.com
on 29 May 2011 at 5:26