nested-structs/arrays (C)

Aperta
#8 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
28/100
Tipo di issue
Funzionalità
Chiarezza
Da chiarire
Stato di attività
Ferma
Stack tecnologico
c, javascript
Ambito
tooling

Direzione di ricerca

Inizia da tools/gen_lib.js, intorno al ciclo di generazione delle struct, e rivedi i campi delle struct di api.json, in particolare i tipi array e struct annidati attualmente ignorati. Controlla prima l'issue #9, quindi esamina i src/structs.h e src/lib.c generati; il lavoro è completo quando questi campi non vengono più omessi silenziosamente dalle utility generate.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

C enhancement todo

I am currently skipping these in C codegen. They should be addressed, once I figure out #9

https://github.com/konsumer/raylib-pointers/blob/f365325/tools/gen_lib.js#L22


// this will generate raylib-pointers

import { writeFile } from 'fs/promises'
import api from './api.json'

const { structs, wrapped } = api

let out = []

// build utils for structs
for (const { name, description, fields } of structs) {
  out.push(`// ${description}

unsigned int ${name}_size() {
  return sizeof(${name});
}`)
  for (const field of fields) {
    if (field.type.includes('[')) {
      // TODO: add utils for arrays
    } else if (/^[A-Z]/.test(field.type)) {
      // cheap way to detect raylib types
      // TODO: add utils for nested structs
    } else {
      out.push(`${field.type} ${name}_get_${field.name}(${name}* p) {\n  return p->${field.name};\n}`)
      out.push(`void ${name}_set_${field.name}(${name}* p, ${field.type} v) {\n  p->${field.name} = v;\n}`)
    }
  }
  out.push('')
}

await writeFile('src/structs.h', out.join('\n'))

out = [
  `#include <stdlib.h>
#include "raylib.h"

// utils for operating on structs
#include "./structs.h"

// this allows us to free anything that was allocated, last-frame
// max number of allocations you can do, per-frame
#define FRAME_ALLOC_SIZE 1024*512

int _frame_alloc_counter = 0;
void* _frame_allocated[FRAME_ALLOC_SIZE] = {};
bool running = false;

void* wrapped_alloc(size_t s) {
  void* p = RL_MALLOC(s);
  if (running) {
    _frame_allocated[_frame_alloc_counter] = p;
    _frame_alloc_counter = (_frame_alloc_counter + 1) % FRAME_ALLOC_SIZE;
  }
  return p;
}

void wrapped_free(void* p) {
  RL_FREE(p);
}

bool wrapped_WindowShouldClose() {
  running = true;
  for (int i=0;i<_frame_alloc_counter;i++) {
    wrapped_free(_frame_allocated[i]);
  }
  _frame_alloc_counter = 0;
  return WindowShouldClose();
}
`
]

// these will not be ghenerated for
const blocklist = [
  // I will be implementing my own mem-management stuff
  'wrapped_WindowShouldClose',
  'wrapped_free',
  'wrapped_alloc'
]

for (const { name, description, returnType, params, original } of wrapped) {
  if (blocklist.includes(name)) {
    continue
  }
  // does return need to be converted to a pointer?
  const returnPointer = /^[A-Z]/.test(returnType)

  // do any params need to be converted to pointers?
  let paramPointer = false

  const inputParams = params.map((p) => {
    if (/^[A-Z]/.test(p.type)) {
      paramPointer = true
      return `${p.type.trim()} ${p.name}`
    } else {
      return `${p.type} ${p.name}`
    }
  })

  const callParams = params.map((p) => {
    if (/^[A-Z]/.test(p.type)) {
      paramPointer = true
      return `*${p.name}`
    } else {
      return p.name
    }
  })

  out.push(`// ${description}`)
  if (returnPointer) {
    out.push(`${returnType} ${name}(${inputParams.join(', ')}) {`)
    out.push(`  ${returnType} _ret = wrapped_alloc(sizeof(${returnType.replace('*', '')}));`)
    out.push(`  *_ret = ${original}(${callParams.join(', ')});`)
    out.push('  return _ret;')
  } else {
    out.push(`${returnType} ${name}(${inputParams.join(', ')}) {`)
    if (returnType === 'void') {
      out.push(`  ${original}(${callParams.join(', ')});`)
    } else {
      out.push(`  return ${original}(${callParams.join(', ')});`)
    }
  }
  out.push('}\n')
}

await writeFile('src/lib.c', out.join('\n'))

Lingua principale
C
Stelle
0
Fork
1
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di konsumer/raylib-pointers

Tutte le issue di konsumer/raylib-pointers

Issue simili

Altre issue su C

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.